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, Version 1.0 only 7 # (the "License"). You may not use this file except in compliance 8 # with the License. 9 # 10 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 11 # or http://www.opensolaris.org/os/licensing. 12 # See the License for the specific language governing permissions 13 # and limitations under the License. 14 # 15 # When distributing Covered Code, include this CDDL HEADER in each 16 # file and include the License file at usr/src/OPENSOLARIS.LICENSE. 17 # If applicable, add the following below this CDDL HEADER, with the 18 # fields enclosed by brackets "[]" replaced with your own identifying 19 # information: Portions Copyright [yyyy] [name of copyright owner] 20 # 21 # CDDL HEADER END 22 # 23 # 24 # Copyright 1997-1998, 2003 Sun Microsystems, Inc. All rights reserved. 25 # Use is subject to license terms. 26 # 27 #ident "%Z%%M% %I% %E% SMI" 28 # 29 # i.initd - Class action script for /etc/init.d script files. 30 # 31 # This class action script handles the issue of delivering a new version of 32 # an /etc/init.d script with a new set of [SK][0-9][0-9] links (or in non-glob 33 # terms, a new set of start and/or kill number links). It assumes that 34 # the package prototype file has been set up so that we have a set of 35 # entries similar to the following: 36 # 37 # e initd etc/init.d/syslog 744 root sys 38 # l initd etc/rc0.d/K40syslog=../../etc/init.d/syslog 39 # l initd etc/rc1.d/K40syslog=../../etc/init.d/syslog 40 # l initd etc/rc2.d/S74syslog=../../etc/init.d/syslog 41 # l initd etc/rcS.d/K40syslog=../../etc/init.d/syslog 42 # 43 # Note that the script file (/etc/init.d/syslog) is marked as type 'e' for 44 # editable so that this script is invoked during both install and upgrade. 45 # The S and K scripts are installed as hard links to the /etc/init.d/ file. 46 # Since all the files are specified as class 'initd', we know that this 47 # script will first be invoked for all the 'e' files, and then for the links. 48 # We are responsible for copying over the 'e' files, and installf creates 49 # the hard links for us. 50 # 51 # Since we know that pkgadd will call installf to add the 'l' links last, 52 # our goal is to remove all existing or likely links to each /etc/init.d/ file 53 # we are asked to install. In order to locate existing S and K links, we use 54 # two algorithms: (1) If the destination file exists and has a > 1 link count, 55 # we scan the /etc directory (relative to the destination file) for files with 56 # the same inode number whose names begin with [SK][0-9][0-9] and remove them. 57 # (2) If the the destination file exists, we remove all files in /etc/rc?.d 58 # whose names are [SK][0-9][0-9] followed by the basename of the destination 59 # file. Step (2) is needed because we may have mistakenly delivered the file 60 # earlier as a symbolic link, or because a system administrator may have 61 # mistakenly unlinked the /etc/init.d script from its S or K counterpart. 62 # 63 # For each file we wish to remove, we need to first ask removef if it's ok 64 # to remove, and then remove it, and finally call removef -f to update the 65 # software database. With that complete, we then invoke installf to 66 # install all of the 'l' links in the 'initd' class specified in the pkgmap 67 # file. This step is necessary because during upgrade, pkgadd will not 68 # invoke this script for 'l' links, since it has no concept of an 'editable' 69 # link which is changing during an upgrade. 70 # 71 # Execution of the checkinstall script will have determined, which, if any of 72 # the scripts were modified by a system administrator. This list of scripts 73 # was preserved in the MODIFIED_AFTER_INSTALLED variable. We iterate through 74 # the modified scripts, saving the system administrator's old version and 75 # echoing a magic token out to the /tmp/CLEANUP file. This will result in an 76 # internationalized message being written to the upgrade log 77 # /var/sadm/install_data/upgrade_cleanup. For more on the details of 78 # /tmp/CLEANUP, refer back to PSARC 1992/118. 79 80 REMOVEF=removef 81 INSTALLF=installf 82 CLEANUP=/tmp/CLEANUP 83 84 case "$ARCH" in 85 sparc.sun4m) EXT=.m;; 86 sparc.sun4u) EXT=.u;; 87 i386.i86pc) EXT=.i;; 88 *) EXT="";; 89 esac 90 PKGMAP=$INST_DATADIR/$PKG$EXT/pkgmap 91 92 if [ "x$UPDATE" = xyes ]; then 93 for ofile in $MODIFIED_AFTER_INSTALLED; do 94 case "`basename $ofile`" in 95 [SK][0-9]*) 96 nfile="`dirname $ofile`/_`basename $ofile`.old" ;; 97 *) 98 nfile="${ofile}.old" ;; 99 esac 100 if [ -f $ofile ]; then 101 cp -p $ofile $nfile 102 echo "EXISTING_FILE_RENAMED: $ofile $nfile" >>$CLEANUP 103 fi 104 done 105 fi 106 107 # Now read the standard input to the class-action script (this will be 108 # the list of 'e' editable files corresponding to the /etc/init.d/scripts), 109 # remove the corresponding hard links in the /etc/rc?.d directories, and 110 # install the new version of each init.d script. 111 112 while read src dst; do 113 dstname=`basename $dst` 114 case "$dstname" in 115 116 [SK][0-9]*) 117 # If this item is the link, the additional hard link to the 118 # /etc/init.d file will be created by installf so we do not 119 # need to do anything here. 120 ;; 121 122 acct) 123 # By default (the '*' case below) we're going to remove all 124 # links to each /etc/init.d script. There is one exception 125 # to this rule: links to /etc/init.d/acct. We don't ship any 126 # links to this script; if links are present, the administrator 127 # has created them in order to enable accounting, and we want 128 # to leave them enabled. 129 130 cp -p $src $dst 131 ;; 132 133 *) 134 # If this item is the script, then remove any existing links 135 # and then copy the contents from $src to $dst 136 137 if [ -f $dst ]; then 138 shift $# 139 set -- `ls -li $dst 2>/dev/null` 140 inode=${1:-0}; nlink=${3:-0} 141 142 ( 143 144 if [ $nlink -gt 1 ]; then 145 find $PKG_INSTALL_ROOT/etc/rc?.d -mount \ 146 -type f -inum $inode \ 147 -name '[SK][0-9][0-9]*' -print 148 fi 149 echo $PKG_INSTALL_ROOT/etc/rc?.d/[SK][0-9][0-9]$dstname 150 151 ) | xargs $REMOVEF $PKGINST 2>/dev/null | xargs rm -f 152 fi 153 154 cp -p $src $dst 155 ;; 156 esac 157 done 158 159 # Complete the removal operations specified in the loop above 160 161 $REMOVEF -f $PKGINST || exit 2 162 163 # Now find all the hard links for the initd class in the package map 164 # and make sure they get recreated. In the case of hard links, installf 165 # takes care of updating the database *and* creating the links. We need 166 # to tweak the source and destination of the link to be absolute paths. 167 # Installf will convert these to be relative to $PKG_INSTALL_ROOT, which 168 # it inherits through the environment. 169 170 awk '$2 == "l" && $3 =="initd" {print $4, $2}' $PKGMAP | \ 171 sed -e 's:^etc/:/etc/:' | \ 172 $INSTALLF -c initd $PKGINST - && exit 0 || exit 2 173