Home | History | Annotate | Download | only in common_files
      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 (the "License").
      7 # You may not use this file except in compliance with the License.
      8 #
      9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10 # or http://www.opensolaris.org/os/licensing.
     11 # See the License for the specific language governing permissions
     12 # and limitations under the License.
     13 #
     14 # When distributing Covered Code, include this CDDL HEADER in each
     15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16 # If applicable, add the following below this CDDL HEADER, with the
     17 # fields enclosed by brackets "[]" replaced with your own identifying
     18 # information: Portions Copyright [yyyy] [name of copyright owner]
     19 #
     20 # CDDL HEADER END
     21 #
     22 
     23 #
     24 # Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     25 # Use is subject to license terms.
     26 #
     27 
     28 #
     29 #  NOTE:  When a change is made to the source file for
     30 #  /etc/minor_perm, a corresponding change must be made to
     31 #  this class-action script.
     32 #
     33 #  -	If an existing entry in minor_perm is having its
     34 #	attributes e.g. permissions, ownership changed,
     35 #	add it to the list produced by make_chattr_list below.
     36 #
     37 #  -	If an existing entry must be deleted, add it to
     38 #	the list produced by make_delete_list below.
     39 #
     40 #  -	If a new entry must be added to the file, add it to the
     41 #	list produced by make_add_list.
     42 #
     43 #  -	If a new entry is being added to minor_perm, but there
     44 #	may already be devices of that name on the system (e.g.
     45 #	we used the system default permissions in a previous release),
     46 #	and those old devices now need to have their attributes changed,
     47 #	add it to the make_chattr_list AND the make_add_list lists
     48 #
     49 
     50 #
     51 #  If an entry in /etc/minor_perm needs to have its attributes
     52 #  changed, identify the entry in the list copied to /etc/chattr.$$
     53 #  by this function.   The fields are:
     54 #
     55 #  <device>:<minor> <old_attrs> <new_attrs> <optional list of logical
     56 #					      devices whose attributes
     57 #					      will need to be changed>
     58 #
     59 #  where an <attribute list> := <perm> <user> <group>
     60 #					
     61 
     62 make_chattr_list() {
     63 cat > /tmp/chattr.$$ << EOF
     64 audio:*				0666 root sys 0600 root sys	/dev/sound/*
     65 vol:volctl			0600 root sys 0666 root sys	/dev/volctl
     66 sad:user			0600 root sys 0666 root sys	/dev/sad/user
     67 se:*				0666 root sys 0600 uucp uucp	/dev/cua/*
     68 zs:*				0666 root sys 0600 uucp uucp	/dev/cua/*
     69 su:*				0666 root sys 0600 uucp uucp	/dev/cua/*
     70 ssd:*			0666 root sys 0640 root sys	/dev/dsk/* /dev/rdsk/*
     71 dad:*			0600 root sys 0640 root sys	/dev/dsk/* /dev/rdsk/*
     72 cpc:*			0600 root sys 0666 root sys	/devices/pseudo/cpc*
     73 log:conslog			0622 root sys 0666 root sys	/dev/conslog
     74 sy:tty				0666 root sys 0666 root tty	/dev/tty
     75 cvc:*				0666 root sys 0600 root sys
     76 cvcredir:*			0666 root sys 0600 root sys
     77 ssm:*				0600 root sys 0640 root sys	/devices/ssm*:*
     78 icmp:icmp			0600 root sys 0666 root sys	/dev/rawip
     79 icmp6:icmp6			0600 root sys 0666 root sys	/dev/rawip6
     80 ip:ip				0660 root sys 0666 root sys	/dev/ip
     81 ip6:ip6				0660 root sys 0666 root sys	/dev/ip6
     82 rts:rts				0660 root sys 0666 root sys	/dev/rts
     83 keysock:keysock			0600 root sys 0666 root sys	/dev/keysock
     84 ipsecah:ipsecah			0600 root sys 0666 root sys	/dev/ipsecah
     85 ipsecesp:ipsecesp		0600 root sys 0666 root sys	/dev/ipsecesp
     86 spdsock:spdsock			0600 root sys 0666 root sys	/dev/spdsock
     87 sad:admin			0600 root sys 0666 root sys	/dev/sad/admin
     88 fssnap:ctl			0600 root sys 0666 root sys	/dev/fssnapctl
     89 fssnap:*			0600 root sys 0640 root sys	/dev/fssnap/*
     90 clone:ce			0600 root sys 0666 root sys	/dev/ce
     91 clone:eri			0600 root sys 0666 root sys	/dev/eri
     92 clone:ge			0600 root sys 0666 root sys	/dev/ge
     93 clone:hme			0600 root sys 0666 root sys	/dev/hme
     94 clone:qfe			0600 root sys 0666 root sys	/dev/qfe
     95 clone:bge			0600 root sys 0666 root sys	/dev/bge
     96 clone:igb			0600 root sys 0666 root sys	/dev/igb
     97 clone:ixgbe			0600 root sys 0666 root sys	/dev/ixgbe
     98 clone:rge			0600 root sys 0666 root sys	/dev/rge
     99 clone:xge			0600 root sys 0666 root sys	/dev/xge
    100 clone:nge			0600 root sys 0666 root sys	/dev/nge
    101 clone:e1000g			0666 root root 0666 root sys	/dev/e1000g
    102 clone:chxge			0600 root sys 0666 root sys	/dev/chxge
    103 clone:vsw			0600 root sys 0666 root sys	/dev/vsw
    104 clone:vnet			0600 root sys 0666 root sys	/dev/vnet
    105 clone:pcwl                      0600 root sys 0666 root sys     /dev/pcwl
    106 clone:pcan			0600 root sys 0666 root sys     /dev/pcan
    107 clone:afe			0600 root sys 0666 root sys     /dev/afe
    108 clone:mxfe			0600 root sys 0666 root sys     /dev/mxfe
    109 clone:rtls			0600 root sys 0666 root sys     /dev/rtls
    110 bge:*				0600 root sys 0666 root sys	/dev/bge*
    111 igb:*				0600 root sys 0666 root sys	/dev/igb*
    112 ixgbe:*				0600 root sys 0666 root sys	/dev/ixgbe*
    113 rge:*				0600 root sys 0666 root sys	/dev/rge*
    114 xge:*				0600 root sys 0666 root sys	/dev/xge*
    115 nge:*				0600 root sys 0666 root sys	/dev/nge*
    116 e1000g:*			0666 root root 0666 root sys	/dev/e1000g*
    117 chxge:*				0600 root sys 0666 root sys	/dev/chxge*
    118 vsw:*				0600 root sys 0666 root sys	/dev/vsw*
    119 vnet:*				0600 root sys 0666 root sys	/dev/vnet*
    120 pcwl:*                          0600 root sys 0666 root sys     /dev/pcwl*
    121 pcan:*                          0600 root sys 0666 root sys     /dev/pcan*
    122 clone:dmfe			0600 root sys 0666 root sys	/dev/dmfe
    123 dmfe:*				0600 root sys 0666 root sys	/dev/dmfe*
    124 clone:pcelx			0600 root sys 0666 root sys	/dev/pcelx
    125 pcelx:*				0600 root sys 0666 root sys	/dev/pcelx*
    126 afe:*				0600 root sys 0666 root sys	/dev/afe*
    127 mxfe:*				0600 root sys 0666 root sys	/dev/mxfe*
    128 rtls:*				0600 root sys 0666 root sys	/dev/rtls*
    129 ipf:*				0600 root sys 0666 root sys	/dev/ipf
    130 pfil:*				0600 root sys 0666 root sys	/dev/pfil
    131 scsi_vhci:devctl	0600 root sys 0666 root sys /devices/scsi_vhci:devctl
    132 fbt:fbt			0600 root sys 0644 root sys /dev/dtrace/provider/fbt
    133 lockstat:*		0600 root sys 0644 root sys /dev/dtrace/provider/lockstat
    134 profile:profile		0600 root sys 0644 root sys /dev/dtrace/provider/profile
    135 sdt:sdt			0600 root sys 0644 root sys /dev/dtrace/provider/sdt
    136 systrace:systrace	0600 root sys 0644 root sys /dev/dtrace/provider/systrace
    137 EOF
    138 }
    139 
    140 
    141 #
    142 #  If an entry in /etc/minor_perm needs to be deleted, identify
    143 #  the entry in the list copied to /etc/delete.$$ by this function.
    144 #  The fields are:
    145 #
    146 #  <device>:<minor>  <optional list of logical devices to be deleted>
    147 #					
    148 
    149 make_delete_list() {
    150 cat > /tmp/delete.$$ << EOF
    151 mm:mbio /dev/mbio /devices/pseudo/mm:mbio
    152 mm:mbmem /dev/mbmem /devices/pseudo/mm:mbmem
    153 clone:amd,0,aux,audio
    154 sw:drum
    155 rip:rawip
    156 zs:*
    157 consfb:consfb
    158 win:*
    159 rtvc:*
    160 gt:*
    161 mic:*
    162 cgeight-p4:*
    163 cgfour:*
    164 cgtwo:*
    165 id:*
    166 xd:*
    167 xt:*
    168 xy:*
    169 ie:*
    170 be:*
    171 se:ucm
    172 se:ucmctl
    173 clone:arp
    174 clone:icmp
    175 clone:ip
    176 clone:tcp
    177 clone:udp
    178 clone:rts
    179 clone:ipsecah
    180 clone:ipsecesp
    181 clone:keysock
    182 clone:le
    183 su:*
    184 profile:profile
    185 clone:qe
    186 cgfourteen:*
    187 cgeight:*
    188 SUNW,sx:*
    189 sx_cmem:*
    190 stc:*
    191 dbri:*
    192 SUNW,DBRId:*
    193 SUNW,DBRIe:*
    194 SUNW,DBRIf:*
    195 EOF
    196 }
    197 
    198 #
    199 #  If an entry needs to be added to /etc/minor_perm, add the first
    200 #  field of the entry to the list created by this function.  The
    201 #  remainder of the entry will be extracted from the /etc/minor_perm
    202 #  in the package being installed, so it is not necessary to supply
    203 #  it here.
    204 #
    205 
    206 make_add_list() {
    207 cat > /tmp/add.$$ << EOF
    208 clone:llc1
    209 stc:*
    210 mcpzsa:*
    211 mcpp:*
    212 vol:volctl
    213 tl:*
    214 tnf:tnfctl
    215 tnf:tnfmap
    216 zs:[a-z]
    217 zs:[a-z],cu
    218 sad:user
    219 se:*
    220 su:[a-z]
    221 su:[a-z],cu
    222 su:ssp
    223 su:sspctl
    224 fdthree:*
    225 ssd:*
    226 dad:*
    227 pm:*
    228 tod:*
    229 SUNW,pmc:*
    230 SUNW,mic:*
    231 SUNW,fas:devctl
    232 cvc:*
    233 cvcredir:*
    234 devinfo:devinfo
    235 envctrltwo:*
    236 se:[a-h]
    237 se:[a-h],cu
    238 se:[0-7],hdlc
    239 se:ssp
    240 se:sspctl
    241 clone:hme
    242 clone:eri
    243 wc:*
    244 arp:arp
    245 icmp:icmp
    246 icmp6:icmp6
    247 ip:ip
    248 ip6:ip6
    249 tcp:tcp
    250 tcp6:tcp6
    251 udp:udp
    252 udp6:udp6
    253 rts:rts
    254 poll:*
    255 pool:pool
    256 pool:poolctl
    257 cpc:shared
    258 sysmsg:msglog
    259 sysmsg:sysmsg
    260 ipsecah:ipsecah
    261 ipsecesp:ipsecesp
    262 keysock:keysock
    263 spdsock:spdsock
    264 devinfo:devinfo,ro
    265 lofi:*
    266 lofi:ctl
    267 sgen:*
    268 fssnap:*
    269 fssnap:ctl
    270 pcf8574:*
    271 pcf8591:*
    272 gpio_87317:*
    273 rsm:*
    274 random:*
    275 mm:allkmem
    276 ssm:*
    277 bscv:*
    278 clone:bge
    279 clone:igb
    280 clone:ixgbe
    281 clone:rge
    282 clone:xge
    283 clone:nge
    284 clone:e1000g
    285 clone:chxge
    286 clone:vsw
    287 clone:vnet
    288 clone:pcwl
    289 clone:pcan
    290 clone:afe
    291 clone:mxfe
    292 clone:rtls
    293 bge:*
    294 igb:*
    295 ixgbe:*
    296 rge:*
    297 xge:*
    298 nge:*
    299 e1000g:*
    300 chxge:*
    301 vsw:*
    302 vnet:*
    303 pcwl:*
    304 pcan:*
    305 afe:*
    306 mxfe:*
    307 rtls:*
    308 clone:dmfe
    309 dmfe:*
    310 clone:pcelx
    311 pcelx:*
    312 clone:ibd
    313 ibd:*
    314 sysevent:*
    315 ramdisk:*
    316 ramdisk:ctl
    317 cryptoadm:cryptoadm
    318 crypto:crypto
    319 dtrace:*
    320 fasttrap:fasttrap
    321 ipf:*
    322 pfil:*
    323 bl:*
    324 sctp:*
    325 sctp6:*
    326 vni:*
    327 cpuid:self
    328 ntwdt:*
    329 dld:*
    330 aggr:*
    331 mdesc:*
    332 zfs:*
    333 zfs:zfs
    334 scsi_vhci:*
    335 kssl:*
    336 fbt:fbt
    337 profile:profile
    338 sdt:sdt
    339 softmac:*
    340 systrace:systrace
    341 physmem:*
    342 smbsrv:*
    343 vscan:*
    344 nsmb:*
    345 bmc:bmc
    346 fm:*
    347 EOF
    348 }
    349 
    350 PATH="/sbin:/usr/sbin:/usr/bin:/usr/sadm/install/bin"
    351 export PATH
    352 
    353 # Internal routine to create a sed script which can be used to
    354 # escape all shell globbing metacharacters in a path.
    355 
    356 create_esc_sedscript()
    357 {
    358 cat > /tmp/esc.sed.$$ << EOF
    359 s/\*/\\\\*/g
    360 s/\?/\\\\?/g
    361 s/\[/\\\\[/g
    362 s/\]/\\\\]/g
    363 EOF
    364 }
    365 
    366 # Internal routine to convert an entry in a /tmp/chwhatever.$$ file to
    367 # an appropriately escaped pattern which can be used to grep into minor_perm.
    368 
    369 entry2pattern()
    370 {
    371 	# the first argument is the 'key' field from the change file.
    372 	# entries can contain shell globbing characters to match
    373 	# several devices - hence all the palaver below.
    374 
    375 	printf '%s' `echo "$1" | sed \
    376 		-e 's/\*/\\\\*/g'	-e 's/\?/\\\\?/g'	\
    377 		-e 's/\./\\\\./g'	-e 's/\[/\\\\[/g'	\
    378 		-e 's/\]/\\\\]/g'`
    379 	shift
    380 
    381 	# the remaining optional arguments are tokens separated by white-space
    382 
    383 	if [ $# = 0 ] ; then
    384 		printf '[ \t]'
    385 	else
    386 		while [ -n "$1" ]
    387 		do
    388 			printf '[ \t][ \t]*%s' $1
    389 			shift
    390 		done
    391 		printf '[ \t]*$'
    392 	fi
    393 }
    394 
    395 while read src dest
    396 do
    397 	if [ ! -f $dest ] ; then
    398 		cp $src $dest
    399 	else
    400 		rm -f /tmp/*.$$
    401 		create_esc_sedscript
    402 		make_chattr_list
    403 		make_delete_list
    404 		make_add_list
    405 
    406 		#
    407 		#  Process the list of devices whose attributes are to be
    408 		#  changed.  Find those that actually need to be
    409 		#  applied to the file.  For each change that needs
    410 		#  to be applied, add an entry for it to the sed
    411 		#  script that will eventually be applied to the
    412 		#  currently-installed /etc/minor_perm file.  Also,
    413 		#  add an entry to the /tmp/chdevs.$$ file, which
    414 		#  contains the list of logical names of devices
    415 		#  whose permissions need to be changed.
    416 		#
    417 
    418 		cat /tmp/chattr.$$ | \
    419 		while read key oldp oldu oldg newp newu newg chdevs
    420 		do
    421 			do_chdevs=no
    422 
    423 			#
    424 			#  First determine whether the device entry
    425 			#  is already in the file, but with the old
    426 			#  permissions.  If so, the entry needs to be
    427 			#  modified and the devices in the chdevs list
    428 			#  need to have their permissions and ownerships
    429 			#  changed.
    430 			#
    431 			grepstr=`entry2pattern "${key}" $oldp $oldu $oldg`
    432 			if grep "$grepstr" $dest > /dev/null 2>&1; then
    433 				echo "s/${grepstr}/$key $newp $newu $newg/" \
    434 				    >> /tmp/sedscript.$$
    435 				do_chdevs=yes
    436 			fi
    437 
    438 			#
    439 			#  Now determine whether the device entry is
    440 			#  in the file at all.  If not, it is a new
    441 			#  entry, but there may already be devices
    442 			#  on the system whose permissions need to
    443 			#  be changed.
    444 			#
    445 			grepstr=`entry2pattern "${key}"`
    446 			grep "${grepstr}" $dest > /dev/null 2>&1
    447 			if [ $? != 0 ] ; then
    448 				do_chdevs=yes
    449 			fi
    450 
    451 			if [ $do_chdevs = yes -a "$chdevs" != "" ] ; then
    452 				xchdevs=`echo "$chdevs" | \
    453 				    sed -f /tmp/esc.sed.$$`
    454 				for m in $xchdevs ; do
    455 					echo "$m" $oldp $oldu $oldg \
    456 					    $newp $newu $newg >> /tmp/chdevs.$$
    457 				done
    458 			fi
    459 		done
    460 
    461 		#
    462 		#  Make sure /dev/volctl gets its permissions corrected.
    463 		#  (systems upgraded from 2.2 to 2.3 may have a correct
    464 		#  entry for /dev/volctl in the /etc/minor_perm file
    465 		#  but the actual /dev/volctl node may have the wrong
    466 		#  permissions.)
    467 		#
    468 
    469 		echo /dev/volctl 0600 root sys 0666 root sys >> /tmp/chdevs.$$
    470 
    471 		if [ -s /tmp/chdevs.$$ ] ; then
    472 			sort -u /tmp/chdevs.$$ > /tmp/tmp.$$
    473 			mv /tmp/tmp.$$ /tmp/chdevs.$$
    474 		fi
    475 
    476 		#
    477 		#  Process the list of devices to be deleted.
    478 		#  Find those that actually need to be deleted
    479 		#  from the file.  For each entry to be deleted,
    480 		#  add an entry for it to the sed script that will
    481 		#  eventually be applied to the  currently-installed
    482 		#  /etc/minor_perm file.  Also, add an entry to the
    483 		#  /tmp/deldevs.$$ file, which contains the list of
    484 		#  logical names of devices to be deleted.
    485 		#
    486 
    487 		cat /tmp/delete.$$ | while read key deldevs
    488 		do
    489 			grepstr=`entry2pattern "${key}"`
    490 			if grep "$grepstr" $dest > /dev/null 2>&1; then
    491 				echo "/${grepstr}/d" >> /tmp/sedscript.$$
    492 				if [ "$deldevs" != "" ] ; then
    493 					xdeldevs=`echo "$deldevs" | \
    494 					    sed -f /tmp/esc.sed.$$`
    495 					for m in $xdeldevs ; do
    496 						echo "$m" >> /tmp/deldevs.$$
    497 					done
    498 				fi
    499 			fi
    500 		done
    501 		if [ -s /tmp/deldevs.$$ ] ; then
    502 			sort -u /tmp/deldevs.$$ > /tmp/tmp.$$
    503 			mv /tmp/tmp.$$ /tmp/deldevs.$$
    504 		fi
    505 
    506 		#
    507 		#  Apply the sed script built above to the
    508 		#  currently-installed /etc/minor_perm file.
    509 		#
    510 
    511 		if [ -s /tmp/sedscript.$$ ] ; then
    512 			sed -f /tmp/sedscript.$$ $dest > /tmp/tmp.$$
    513 			cp /tmp/tmp.$$ $dest
    514 		fi
    515 
    516 		#
    517 		#  Special case code to handle bug in 2.1, 2.2, and
    518 		#  early 2.3 releases:  the link from /dev/sound/*
    519 		#  has one extra set of "../"'s in the link.  This
    520 		#  doesn't cause problems in normal operation 
    521 		#  because ".."'s that would take the search path
    522 		#  higher than the real root are ignored.  However,
    523 		#  during upgrade, when the system being upgraded is
    524 		#  mounted at /a, the extra ".." in the link causes
    525 		#  the link to be unresolvable.  The link must be
    526 		#  corrected so that the chmod of /dev/sound/*
    527 		#  works.
    528 		#
    529 
    530 		if [ "$PKG_INSTALL_ROOT" != "" -a "$PKG_INSTALL_ROOT" != "/" ]
    531 		then
    532 			for i in $PKG_INSTALL_ROOT/dev/sound/* ; do
    533 				if [ "$i" = "$PKG_INSTALL_ROOT/dev/sound/*" ]
    534 				then
    535 					break;
    536 				fi
    537 
    538 				# if it's not a symlink, continue
    539 				if [ ! -h $i ] ; then
    540 					continue
    541 				fi
    542 
    543 				ls -L $i >/dev/null 2>&1
    544 				if [ $? = 0 ] ; then
    545 					#  link is already OK
    546 					continue
    547 				fi
    548 
    549 				# otherwise, link can't be followed
    550 
    551 				# build the correct link
    552 				link=`ls -l $i | sed 's,.* ,,'`
    553 				link=`expr $link : '\.\.\/\(.*\)'`
    554 				if [ "$link" = "" ] ; then
    555 					continue;
    556 				fi
    557 
    558 				# build a test link
    559 				rm -f $PKG_INSTALL_ROOT/dev/sound/test.$$
    560 				ln -s $link $PKG_INSTALL_ROOT/dev/sound/test.$$
    561 
    562 				# test the link
    563 				ls -L $PKG_INSTALL_ROOT/dev/sound/test.$$ \
    564 					>/dev/null 2>&1
    565 
    566 				# it worked, so replace old link with new
    567 				if [ $? = 0 ] ; then
    568 					rm -f $i
    569 					ln -s $link $i
    570 				fi
    571 				rm -f $PKG_INSTALL_ROOT/dev/sound/test.$$
    572 			done
    573 		fi
    574 
    575 		#  For all entries in minor_perm whose attributes had
    576 		#  to be corrected, correct the relevant attributes of the
    577 		#  already-existing devices that correspond to those
    578 		#  entries.
    579 		#
    580 		if [ -s /tmp/chdevs.$$ -a "$PKG_INSTALL_ROOT" != ""  -a \
    581 		     "$PKG_INSTALL_ROOT" != "/" ] ; then
    582 			cat /tmp/chdevs.$$ |\
    583 			while read device oldp oldu oldg newp newu newg
    584 			do
    585 				#
    586 				# Note that we take pains -only- to change
    587 				# the permission/ownership of devices that
    588 				# have kept their original permissions.
    589 				#
    590 				for dev in $PKG_INSTALL_ROOT/$device; do
    591 					find $dev -follow -perm $oldp -exec \
    592 					    chmod $newp $dev \; >/dev/null 2>&1
    593 					find $dev -follow -user $oldu -exec \
    594 					    chown $newu $dev \; >/dev/null 2>&1
    595 					find $dev -follow -group $oldg -exec \
    596 					    chgrp $newg $dev \; >/dev/null 2>&1
    597 				done
    598 			done
    599 		fi
    600 
    601 		#
    602 		#  For all entries in minor_perm that were deleted,
    603 		#  remove the /dev entries that point to device nodes
    604 		#  that correspond to those entries.
    605 		#
    606 		if [ -s /tmp/deldevs.$$ -a "$PKG_INSTALL_ROOT" != ""  -a \
    607 		     "$PKG_INSTALL_ROOT" != "/" ] ; then
    608 			cat /tmp/deldevs.$$ | while read device
    609 			do
    610 				rm -f $PKG_INSTALL_ROOT/$device
    611 			done
    612 		fi
    613 
    614 
    615 		cat /tmp/add.$$ | while read key
    616 		do
    617 			grepstr=`entry2pattern "${key}"`
    618 			grep "$grepstr" $dest > /dev/null 2>&1
    619 			if [ $? != 0 ] ; then
    620 				grep "$grepstr" $src >> $dest
    621 			fi
    622 		done
    623 
    624 		rm -f /tmp/*.$$
    625 	fi
    626 done
    627 
    628 exit 0
    629 
    630