1 #!/bin/sh 2 # 3 # CDDL HEADER START 4 # 5 # The contents of this file are subject to the terms of the 6 # Common Development and Distribution License (the "License"). 7 # You may not use this file except in compliance with the License. 8 # 9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 # or http://www.opensolaris.org/os/licensing. 11 # See the License for the specific language governing permissions 12 # and limitations under the License. 13 # 14 # When distributing Covered Code, include this CDDL HEADER in each 15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 # If applicable, add the following below this CDDL HEADER, with the 17 # fields enclosed by brackets "[]" replaced with your own identifying 18 # information: Portions Copyright [yyyy] [name of copyright owner] 19 # 20 # CDDL HEADER END 21 # 22 #ident "%Z%%M% %I% %E% SMI" 23 # 24 # Copyright 2008 Sun Microsystems, Inc. All rights reserved. 25 # Use is subject to license terms. 26 # 27 # class action script for devalloc_defaults installed by pkgadd 28 # 29 # Files in "devallocdefs" class: 30 # 31 # /etc/security/tsol/devallloc_defs 32 # 33 # Allowable exit codes 34 # 35 # 0 - success 36 # 2 - warning or possible error condition. Installation continues. A warning 37 # message is displayed at the time of completion. 38 # 39 40 tmp_dir=/tmp 41 42 cp_cmd=/usr/bin/cp 43 egrep_cmd=/usr/bin/egrep 44 mv_cmd=/usr/bin/mv 45 nawk_cmd=/usr/bin/nawk 46 rm_cmd=/usr/bin/rm 47 sed_cmd=/usr/bin/sed 48 sort_cmd=/usr/bin/sort 49 50 # $1 is the "old/existing file" 51 # $2 is the "new (to be merged)" file 52 # $3 is the output file 53 # returns 0 on success 54 # returns 2 on failure if nawk fails with non-zero exit status 55 # 56 dbmerge() { 57 # 58 # If the new file has a Sun copyright, remove the Sun copyright from the old 59 # file. 60 # 61 newcr=`${egrep_cmd} '^# Copyright.*Sun Microsystems, Inc.' $2 \ 62 2>/dev/null` 63 if [ -n "${newcr}" ]; then 64 $sed_cmd -e '/^# Copyright.*Sun Microsystems, Inc./d' \ 65 -e '/^# All rights reserved./d' \ 66 -e '/^# Use is subject to license terms./d' \ 67 $1 > $3.old 2>/dev/null 68 else 69 $cp_cmd $1 $3.old 70 fi 71 # 72 # Remove empty lines and multiple instances of these comments: 73 # 74 $sed_cmd \ 75 -e '/^#$/d' \ 76 -e '/^# Default device allocation attributes for device types./d' \ 77 -e '/^# Currently recognized types -/d' \ 78 -e '/^# audio (audio), fd (floppy drives),/d' \ 79 -e '/^# sr (CDROM drives), st (tape drives),/d' \ 80 -e '/^# rdsk (removable disks, like JAZ)/d' \ 81 -e '/^# Syntax -/d' \ 82 -e '/^# device-type:/d' \ 83 -e '/^# auths=comma separated device authorizations;/d' \ 84 -e '/^# cleanscript=full path to clean script for this type/d' \ 85 $3.old > $3.$$ 86 $mv_cmd $3.$$ $3.old 87 # 88 # Retain old and new header comments. 89 # 90 $sed_cmd -n -e '/^[^#]/,$d' -e '/^##/,$d' -e p $3.old > $3 91 $rm_cmd $3.old 92 $sed_cmd -n -e '/^[^#]/,$d' -e '/^##/,$d' -e p $2 >> $3 93 # 94 # Handle line continuations (trailing \) 95 # 96 $sed_cmd \ 97 -e '/\\$/{N;s/\\\n//;}' -e '/\\$/{N;s/\\\n//;}' \ 98 -e '/\\$/{N;s/\\\n//;}' -e '/\\$/{N;s/\\\n//;}' \ 99 -e '/\\$/{N;s/\\\n//;}' -e '/\\$/{N;s/\\\n//;}' \ 100 $1 > $3.old 101 $sed_cmd \ 102 -e '/\\$/{N;s/\\\n//;}' -e '/\\$/{N;s/\\\n//;}' \ 103 -e '/\\$/{N;s/\\\n//;}' -e '/\\$/{N;s/\\\n//;}' \ 104 -e '/\\$/{N;s/\\\n//;}' -e '/\\$/{N;s/\\\n//;}' \ 105 $2 > $3.new 106 # 107 #!/usr/bin/nawk -f 108 # 109 # dbmerge old-file new-file 110 # 111 # Merge two versions of devalloc_defaults file. The output 112 # consists of the lines from the new-file, while preserving 113 # user customizations in the old-file. Specifically, the 114 # keyword/value section of each record contains the union 115 # of the entries found in both files. The value for each 116 # keyword is the value from the new-file, except for "auths", 117 # where the values from the old and new files are merged. 118 # 119 # The output is run through sort except for the comments 120 # which will appear first in the output. 121 # 122 # 123 $nawk_cmd ' 124 125 BEGIN { 126 FS=":" \ 127 } 128 129 /^#/ { 130 continue; 131 } 132 133 { 134 key = $1 ; 135 if (NR == FNR) 136 record[key] = $2; 137 else { 138 print key ":" merge_attrs(record[key], $2); 139 delete record[key]; 140 } 141 } 142 143 END { 144 for (key in record) { 145 print key ":" record[key]; 146 } 147 } 148 149 function merge_attrs(old, new, cnt, new_cnt, i, j, list, new_list, keyword) 150 { 151 cnt = split(old, list, ";"); 152 new_cnt = split(new, new_list, ";"); 153 for (i = 1; i <= new_cnt; i++) { 154 keyword = substr(new_list[i], 1, index(new_list[i], "=")-1); 155 for (j = 1; j <= cnt; j++) { 156 if (match(list[j], "^" keyword "=")) { 157 list[j] = merge_values(keyword, list[j], 158 new_list[i]); 159 break; 160 } 161 } 162 if (j > cnt) 163 list[++cnt] = new_list[i]; 164 } 165 166 return unsplit(list, cnt, ";"); \ 167 } 168 169 function merge_values(keyword, old, new, cnt, new_cnt, i, j, list, new_list, d) 170 { 171 if (keyword != "auths" && keyword != "profiles") 172 return new; 173 174 cnt = split(substr(old, length(keyword)+2), list, ","); 175 new_cnt = split(substr(new, length(keyword)+2), new_list, ","); 176 177 for (i = 1; i <= new_cnt; i++) { 178 for (j = 1; j <= cnt; j++) { 179 if (list[j] == new_list[i]) 180 break; 181 } 182 if (j > cnt) 183 list[++cnt] = new_list[i]; 184 } 185 186 return keyword "=" unsplit(list, cnt, ","); 187 } 188 189 function unsplit(list, cnt, delim, str) 190 { 191 str = list[1]; 192 for (i = 2; i <= cnt; i++) 193 str = str delim list[i]; 194 return str; 195 }' \ 196 $3.old $3.new > $3.unsorted 197 rc=$? 198 $sort_cmd < $3.unsorted >> $3 199 return $rc 200 } 201 202 # $1 is the merged file 203 # $2 is the target file 204 # 205 commit() { 206 $mv_cmd $1 $2 207 return $? 208 } 209 210 outfile="" 211 set_outfile() { 212 213 outfile=$tmp_dir/devalloc_defaults_merge 214 215 return 0 216 } 217 218 cleanup() { 219 $rm_cmd -f $outfile $outfile.old $outfile.new $outfile.unsorted 220 221 return 0 222 } 223 224 exit_status=0 225 226 # main 227 228 while read newfile oldfile ; do 229 if [ ! -f $oldfile ]; then 230 cp $newfile $oldfile 231 else 232 set_outfile $newfile 233 dbmerge $oldfile $newfile $outfile 234 if [ $? -ne 0 ]; then 235 echo "$0 : failed to merge $newfile with $oldfile" 236 cleanup 237 exit_status=2 238 continue 239 fi 240 241 commit $outfile $oldfile 242 if [ $? -ne 0 ]; then 243 echo "$0 : failed to mv $outfile to $2" 244 cleanup 245 exit_status=2 246 continue 247 fi 248 249 cleanup 250 fi 251 done 252 253 exit $exit_status 254