i.initd revision 7c478bd95313f5f23a4c958a745db2134aa03244
#!/bin/sh
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License, Version 1.0 only
# (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
#
#
# Copyright 1997-1998, 2003 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
#
# i.initd - Class action script for /etc/init.d script files.
#
# This class action script handles the issue of delivering a new version of
# an /etc/init.d script with a new set of [SK][0-9][0-9] links (or in non-glob
# terms, a new set of start and/or kill number links). It assumes that
# the package prototype file has been set up so that we have a set of
# entries similar to the following:
#
# e initd etc/init.d/syslog 744 root sys
# l initd etc/rc0.d/K40syslog=../../etc/init.d/syslog
# l initd etc/rc1.d/K40syslog=../../etc/init.d/syslog
# l initd etc/rc2.d/S74syslog=../../etc/init.d/syslog
# l initd etc/rcS.d/K40syslog=../../etc/init.d/syslog
#
# Note that the script file (/etc/init.d/syslog) is marked as type 'e' for
# editable so that this script is invoked during both install and upgrade.
# The S and K scripts are installed as hard links to the /etc/init.d/ file.
# Since all the files are specified as class 'initd', we know that this
# script will first be invoked for all the 'e' files, and then for the links.
# We are responsible for copying over the 'e' files, and installf creates
# the hard links for us.
#
# Since we know that pkgadd will call installf to add the 'l' links last,
# our goal is to remove all existing or likely links to each /etc/init.d/ file
# we are asked to install. In order to locate existing S and K links, we use
# two algorithms: (1) If the destination file exists and has a > 1 link count,
# we scan the /etc directory (relative to the destination file) for files with
# the same inode number whose names begin with [SK][0-9][0-9] and remove them.
# (2) If the the destination file exists, we remove all files in /etc/rc?.d
# whose names are [SK][0-9][0-9] followed by the basename of the destination
# file. Step (2) is needed because we may have mistakenly delivered the file
# earlier as a symbolic link, or because a system administrator may have
# mistakenly unlinked the /etc/init.d script from its S or K counterpart.
#
# For each file we wish to remove, we need to first ask removef if it's ok
# to remove, and then remove it, and finally call removef -f to update the
# software database. With that complete, we then invoke installf to
# install all of the 'l' links in the 'initd' class specified in the pkgmap
# file. This step is necessary because during upgrade, pkgadd will not
# invoke this script for 'l' links, since it has no concept of an 'editable'
# link which is changing during an upgrade.
#
# Execution of the checkinstall script will have determined, which, if any of
# the scripts were modified by a system administrator. This list of scripts
# was preserved in the MODIFIED_AFTER_INSTALLED variable. We iterate through
# the modified scripts, saving the system administrator's old version and
# echoing a magic token out to the /tmp/CLEANUP file. This will result in an
# internationalized message being written to the upgrade log
# /var/sadm/install_data/upgrade_cleanup. For more on the details of
# /tmp/CLEANUP, refer back to PSARC 1992/118.
REMOVEF=removef
INSTALLF=installf
CLEANUP=/tmp/CLEANUP
case "$ARCH" in
sparc.sun4m) EXT=.m;;
sparc.sun4u) EXT=.u;;
i386.i86pc) EXT=.i;;
*) EXT="";;
esac
PKGMAP=$INST_DATADIR/$PKG$EXT/pkgmap
if [ "x$UPDATE" = xyes ]; then
for ofile in $MODIFIED_AFTER_INSTALLED; do
case "`basename $ofile`" in
[SK][0-9]*)
nfile="`dirname $ofile`/_`basename $ofile`.old" ;;
*)
nfile="${ofile}.old" ;;
esac
if [ -f $ofile ]; then
cp -p $ofile $nfile
echo "EXISTING_FILE_RENAMED: $ofile $nfile" >>$CLEANUP
fi
done
fi
# Now read the standard input to the class-action script (this will be
# the list of 'e' editable files corresponding to the /etc/init.d/scripts),
# remove the corresponding hard links in the /etc/rc?.d directories, and
# install the new version of each init.d script.
while read src dst; do
dstname=`basename $dst`
case "$dstname" in
[SK][0-9]*)
# If this item is the link, the additional hard link to the
# /etc/init.d file will be created by installf so we do not
# need to do anything here.
;;
acct)
# By default (the '*' case below) we're going to remove all
# links to each /etc/init.d script. There is one exception
# to this rule: links to /etc/init.d/acct. We don't ship any
# links to this script; if links are present, the administrator
# has created them in order to enable accounting, and we want
# to leave them enabled.
cp -p $src $dst
;;
*)
# If this item is the script, then remove any existing links
# and then copy the contents from $src to $dst
if [ -f $dst ]; then
shift $#
set -- `ls -li $dst 2>/dev/null`
inode=${1:-0}; nlink=${3:-0}
(
if [ $nlink -gt 1 ]; then
find $PKG_INSTALL_ROOT/etc/rc?.d -mount \
-type f -inum $inode \
-name '[SK][0-9][0-9]*' -print
fi
echo $PKG_INSTALL_ROOT/etc/rc?.d/[SK][0-9][0-9]$dstname
) | xargs $REMOVEF $PKGINST 2>/dev/null | xargs rm -f
fi
cp -p $src $dst
;;
esac
done
# Complete the removal operations specified in the loop above
$REMOVEF -f $PKGINST || exit 2
# Now find all the hard links for the initd class in the package map
# and make sure they get recreated. In the case of hard links, installf
# takes care of updating the database *and* creating the links. We need
# to tweak the source and destination of the link to be absolute paths.
# Installf will convert these to be relative to $PKG_INSTALL_ROOT, which
# it inherits through the environment.
awk '$2 == "l" && $3 =="initd" {print $4, $2}' $PKGMAP | \
sed -e 's:^etc/:/etc/:' | \
$INSTALLF -c initd $PKGINST - && exit 0 || exit 2