summaryrefslogtreecommitdiff
path: root/usr/src/pkgdefs/common_files/i.initd
blob: f629f7ff3ae25580c4811580e553109b07bcf7cc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#!/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