#!/bin/sh # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # #ident "%Z%%M% %I% %E% SMI" # # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # class action script for devalloc_defaults installed by pkgadd # # Files in "devallocdefs" class: # # /etc/security/tsol/devallloc_defs # # Allowable exit codes # # 0 - success # 2 - warning or possible error condition. Installation continues. A warning # message is displayed at the time of completion. # tmp_dir=/tmp cp_cmd=/usr/bin/cp egrep_cmd=/usr/bin/egrep mv_cmd=/usr/bin/mv nawk_cmd=/usr/bin/nawk rm_cmd=/usr/bin/rm sed_cmd=/usr/bin/sed sort_cmd=/usr/bin/sort # $1 is the "old/existing file" # $2 is the "new (to be merged)" file # $3 is the output file # returns 0 on success # returns 2 on failure if nawk fails with non-zero exit status # dbmerge() { # # If the new file has a Sun copyright, remove the Sun copyright from the old # file. # newcr=`${egrep_cmd} '^# Copyright.*Sun Microsystems, Inc.' $2 \ 2>/dev/null` if [ -n "${newcr}" ]; then $sed_cmd -e '/^# Copyright.*Sun Microsystems, Inc./d' \ -e '/^# All rights reserved./d' \ -e '/^# Use is subject to license terms./d' \ $1 > $3.old 2>/dev/null else $cp_cmd $1 $3.old fi # # Remove empty lines and multiple instances of these comments: # $sed_cmd \ -e '/^#$/d' \ -e '/^# Default device allocation attributes for device types./d' \ -e '/^# Currently recognized types -/d' \ -e '/^# audio (audio), fd (floppy drives),/d' \ -e '/^# sr (CDROM drives), st (tape drives),/d' \ -e '/^# rdsk (removable disks, like JAZ)/d' \ -e '/^# Syntax -/d' \ -e '/^# device-type:/d' \ -e '/^# auths=comma separated device authorizations;/d' \ -e '/^# cleanscript=full path to clean script for this type/d' \ $3.old > $3.$$ $mv_cmd $3.$$ $3.old # # Retain old and new header comments. # $sed_cmd -n -e '/^[^#]/,$d' -e '/^##/,$d' -e p $3.old > $3 $rm_cmd $3.old $sed_cmd -n -e '/^[^#]/,$d' -e '/^##/,$d' -e p $2 >> $3 # # Handle line continuations (trailing \) # $sed_cmd \ -e '/\\$/{N;s/\\\n//;}' -e '/\\$/{N;s/\\\n//;}' \ -e '/\\$/{N;s/\\\n//;}' -e '/\\$/{N;s/\\\n//;}' \ -e '/\\$/{N;s/\\\n//;}' -e '/\\$/{N;s/\\\n//;}' \ $1 > $3.old $sed_cmd \ -e '/\\$/{N;s/\\\n//;}' -e '/\\$/{N;s/\\\n//;}' \ -e '/\\$/{N;s/\\\n//;}' -e '/\\$/{N;s/\\\n//;}' \ -e '/\\$/{N;s/\\\n//;}' -e '/\\$/{N;s/\\\n//;}' \ $2 > $3.new # #!/usr/bin/nawk -f # # dbmerge old-file new-file # # Merge two versions of devalloc_defaults file. The output # consists of the lines from the new-file, while preserving # user customizations in the old-file. Specifically, the # keyword/value section of each record contains the union # of the entries found in both files. The value for each # keyword is the value from the new-file, except for "auths", # where the values from the old and new files are merged. # # The output is run through sort except for the comments # which will appear first in the output. # # $nawk_cmd ' BEGIN { FS=":" \ } /^#/ { continue; } { key = $1 ; if (NR == FNR) record[key] = $2; else { print key ":" merge_attrs(record[key], $2); delete record[key]; } } END { for (key in record) { print key ":" record[key]; } } function merge_attrs(old, new, cnt, new_cnt, i, j, list, new_list, keyword) { cnt = split(old, list, ";"); new_cnt = split(new, new_list, ";"); for (i = 1; i <= new_cnt; i++) { keyword = substr(new_list[i], 1, index(new_list[i], "=")-1); for (j = 1; j <= cnt; j++) { if (match(list[j], "^" keyword "=")) { list[j] = merge_values(keyword, list[j], new_list[i]); break; } } if (j > cnt) list[++cnt] = new_list[i]; } return unsplit(list, cnt, ";"); \ } function merge_values(keyword, old, new, cnt, new_cnt, i, j, list, new_list, d) { if (keyword != "auths" && keyword != "profiles") return new; cnt = split(substr(old, length(keyword)+2), list, ","); new_cnt = split(substr(new, length(keyword)+2), new_list, ","); for (i = 1; i <= new_cnt; i++) { for (j = 1; j <= cnt; j++) { if (list[j] == new_list[i]) break; } if (j > cnt) list[++cnt] = new_list[i]; } return keyword "=" unsplit(list, cnt, ","); } function unsplit(list, cnt, delim, str) { str = list[1]; for (i = 2; i <= cnt; i++) str = str delim list[i]; return str; }' \ $3.old $3.new > $3.unsorted rc=$? $sort_cmd < $3.unsorted >> $3 return $rc } # $1 is the merged file # $2 is the target file # commit() { $mv_cmd $1 $2 return $? } outfile="" set_outfile() { outfile=$tmp_dir/devalloc_defaults_merge return 0 } cleanup() { $rm_cmd -f $outfile $outfile.old $outfile.new $outfile.unsorted return 0 } exit_status=0 # main while read newfile oldfile ; do if [ ! -f $oldfile ]; then cp $newfile $oldfile else set_outfile $newfile dbmerge $oldfile $newfile $outfile if [ $? -ne 0 ]; then echo "$0 : failed to merge $newfile with $oldfile" cleanup exit_status=2 continue fi commit $outfile $oldfile if [ $? -ne 0 ]; then echo "$0 : failed to mv $outfile to $2" cleanup exit_status=2 continue fi cleanup fi done exit $exit_status