summaryrefslogtreecommitdiff
path: root/usr/src/ucbcmd/ucblinks/ucblinks.sh
blob: 974b542d82de8a89a8f1ebc11733a8392546e557 (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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
#!/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 (c) 1991 by Sun Microsystems, Inc.
#
#ident	"%Z%%M%	%I%	%E% SMI"
#

PATH=/sbin:/usr/sbin:/usr/bin:/etc
export PATH

RULEBASE=/usr/ucblib/ucblinks.awk

# Name of device-type list produced by "devlinks"
DEVTYPES=/etc/.obp_devices

USAGE="Usage: `basename $0` [-r rootdir] [-e rulebase] [-d]"
DOIT_CMD="sh -s"

while getopts 'de:r:' flag
do
	case $flag in
	d)	DOIT_CMD="cat -"
		;;
	e)
		RULEBASE=$OPTARG;
		case "$RULEBASE" in
		/*)	;;
		*)	RULEBASE="`pwd`/$RULEBASE";;
		esac
		;;
	r)	ROOTDIR=$OPTARG;
		;;
	\?)	echo "$USAGE" >&2
		exit 2;
		;;
	esac
done

shift `expr $OPTIND - 1`

#
# The rest of this script looks a mess.  But in fact underneath all the
# 'sed's and 'awk's it is quite simple.
#
# First it creates a list of all the device nodes in the /devices directory
# (by cd'ing to /dev, then doing a 'find' of all special files in ../devices
# doing an 'ls -l' of these files, and sedding the output to produce a list
# of the form 'major minor type name').
#
# As an added wrinkle it changes 'major' from a number to a driver-name using
# sed rules produced from the "/etc/name_to_major file.
#
# Then it runs the awk rules in the rule-base on this list to produce a list
# of compatability-links that must be created.  However, this does not produce
# the links themselves because of the next stage:
#
# Finally this list of compatability-links is inspected and where possible links
# to the SunOS5 names are created instead of links directly to the /devices
# directory
# (by 'find'ing all the symbolic links under /dev, ancomparing the
# subdirectory they occur in, and the file to which they point, to
# the comaptability-link information built above. If a match is found
# a command to make a link to the 5.0 link, rather than to the /devices
# entry, is created.  If not, a direct link is created)
# And then the list of link command is executed by a shell, or printed on stdout
# (in debugging mode)
#
# See -- not so complicated!  However the syntax of all these rules makes
# the code below nearly incomprehensible.  Fear not; the only part you need
# to change for extra devices is located in the 'RULEBASE' file.

cd $ROOTDIR/dev

GENSED=/tmp/mkcompat.sed$$
GENAWK=/tmp/mkcompat.awk$$
GENRULE=/tmp/mkcompat.rule$$

rm -f $GENSED $GENAWK $GENRULE

trap "rm -f $GENSED $GENAWK $GENRULE" 0

#
# First generate full rulebase.  This is done to keep common functions
# out of the rulebase


cat - >$GENRULE <<\!EOD
function out(dev, dir, extraname)	{
	c = split(dir, junk, "/") - 1;

	if (junk[1] == ".")
		c--;

	fulldevfs = "";

	while ( c > 0) {
		fulldevfs = "../" fulldevfs;
		c--;
	}
	fulldevfs = fulldevfs $4;

	printf "devname[\"" fulldevfs "\"] = \"" dev "\";";

	if (length(dir) > 0)
		printf " devdir[\"" fulldevfs "\"] = \"" dir "\";";

	if (length(extraname) > 0)
		printf " devextra[\"" fulldevfs "\"] = \"" extraname "\";";
	printf "\n";
	} 

!EOD

#
# Now see if we need to do CD drive special handling.  The SCSI CD and disk
# drivers have been merged in SunOS5, so we cannot do the normal differentiation
# on major number with these devices.  However the "disks" program does write
# a list of all OBP cd device names in a pecial file; by massaging this file
# we are able to construct rules which correctly differentiate between sd and sr
# devices.

if [ -s $DEVTYPES ]
then
	echo "BEGIN	{" >>$GENRULE
	sed -ne '/^ddi_block:cdrom[:	]/s-^[^	 ]*[ 	]\{1,\}\(.*\)$-	cddev["../devices/\1"] = 1;-p' <$DEVTYPES >>$GENRULE
	echo "	}" >>$GENRULE
fi

cat $RULEBASE >>$GENRULE


#
#----------------------------------------------------------------------
#
# Construct sedscr ... a script to massage the output of an 'ls -l'
# of all the special files in the '../devices' directory.
#
# First 3 lines of scr change line to format "maj	min	[b|c]	name
#
cat <<\!EOD >$GENSED
1,$s/^\(.\).*[ 	]\([0-9][0-9]*\), *\([0-9][0-9]*\)[ 	].*[ 	]\([^ 	][^ 	]*\)$/\2	\3	\1	\4/
/:[^	,][^ 	,]*$/s/^\(.*\):\([^	,]*\)$/\1:\2	\2/
/:[^	,][^	,]*,[^ ]*$/s/^\(.*\):\([^	,]*\),\([^ ]*\)$/\1:\2,\3	\2/
!EOD

# Next lines are generated from the "/etc/name_to_major file; they change the
# "major number" field into its corresponding 'name'.  This is so that
# the difference in major-numbers among different machines can be hidden.
#
grep -v '^#' /etc/name_to_major | sed -e '1,$s-^\([^ 	]*\)[ 	][ 	]*\([^ 	][^ 	]*\)$-/^\2	/s/^\2	/\1	/-' >>$GENSED

#
#----------------------------------------------------------------------
#
# Have finished generating sedscr.  Now we generate 'nawkscr'; first we insert
# the header ...

cat >$GENAWK <<\!EOD
BEGIN	{
!EOD

# and then we find all the symbolic-links under /dev, massage the output of
# an 'ls -l' with the sed script we generated above, and then 'nawk' the output
# using the actual link data table script.  This generates the heart of our
# link-creating 'nawk' script.

echo "Scanning /devices/ directory tree..." >&2

ls -l `find ../devices \( -type b -o -type c \) -print` |  sed -f $GENSED |\
sort -b +0 -1 +1n -2 +4 -5 | nawk -f $GENRULE >>$GENAWK

cat >>$GENAWK <<\!EOD
	}
$2 in devname	{
	if (length(devdir[$2]) <= 0)
		next;
	if (devdir[$2] == "./") {
		if ($1 == devname[$2])
			next;
	}
	else if (match($1, "^" devdir[$2] "[^/]*$") == 0)
		next;

	printf "rm -f %s; ln -s %s %s\n", devname[$2], $1, devname[$2];
	if (length(devextra[$2]) > 0) {
		printf "rm -f %s; ln -s %s %s\n", devextra[$2],
			devname[$2], devextra[$2];
		delete devextra[$2];
	}
	delete devname[$2];
	delete devdir[$2];
	}
END	{
	for (dev in devname) {
		printf "rm -f %s; ln -s %s %s\n", devname[dev],
		   substr(dev, match(dev, "\.\./devices/"), 999),
		   devname[dev];
		if (length(devextra[dev]) > 0)
			printf "rm -f %s; ln -s %s %s\n", devextra[dev],
				devname[dev], devextra[dev];
	}
	}
!EOD

#
#----------------------------------------------------------------------
#
echo "Scanning /dev/ directory tree..." >&2

ls -l `find . -type l -print` |\
	sed -e '1,$s/^.* \.\/\([^ ][^ ]*\) -> \([^ ][^ ]*\)$/\1	\2/' |\
	nawk -f $GENAWK |\
	$DOIT_CMD