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 2005 Sun Microsystems, Inc.  All rights reserved.
25# Use is subject to license terms.
26#
27
28# i.CompCpio
29#
30# This shell script uncompresses and installs files archived in
31# old-style WOS packages using the utilities cpio and compress. It
32# looks in the PKGSRC directory for the archives which may be called
33# out in one of eight ways :
34#
35#	reloc.cpio.Z	relocatable paths, less old style
36#	root.cpio.Z	absolute paths, less old style
37#	reloc.cpio	relocatable paths less old style, not compressed
38#	root.cpio	absolute paths, less old style, not compressed
39#	reloc.Z		relocatable paths, old style, compressed
40#	root.Z		absolute paths, old style, compressed
41#	reloc		relocatable paths, old style, not compressed
42#	root		absolute paths, old style, not compressed
43#
44# stdin carries the source directory as the first entry followed by the
45# paths of the files to be installed as indicated in the pkgmap. Since
46# all operations take place from the declared base directory, both relative
47# and absolute paths will install correctly. There are three methods and
48# since speed is of the essence, we skip straight to the right one :
49#
50#	If it's an initial install
51#		do a full cpio for each archive
52#	else
53#		If there's only the reloc archive
54#			make a file list, rm executables, do a selective cpio
55#		else
56#			rm executables, do a full cpio for each archive
57#
58# Since the old-style archives contain no execute permissions, this
59# script saves the executables it requires so it can clean up after
60# unloading the archive. If /usr/lib/ld.so or .so.1 is included in the
61# package, no cleanup will be possible (nothing will run) so we clean
62# up first and then unload the entire archive without a file list.
63#
64NAME="i.CompCpio"
65FILELIST=${PKGSAV:?undefined}/filelist
66BD=${BASEDIR:-/}
67IR=${PKG_INSTALL_ROOT:-/}
68MAXLIST=550	# This is arbitrary based upon 2.4 cpio
69count=0
70
71reloc_cpio_Z=0
72root_cpio_Z=0
73reloc_cpio=0
74root_cpio=0
75Reloc_Arch=""
76Root_Arch=""
77is_an_archive=0
78is_a_filelist=0
79mk_filelist=0
80list_empty=1
81local_install=0
82Spcl_init=0
83Rm_alt_sav=0
84
85# critical archived dynamic libraries and executables
86Spcl_lib=0
87Spcl_exec=0
88Movelist=""
89Ld_Preload=""
90Ld1=usr/lib/ld.so.1
91Ld=usr/lib/ld.so
92Libintl=usr/lib/libintl.so.1
93Libmalloc=usr/lib/libmapmalloc.so.1
94Libc=usr/lib/libc.so.1
95Libw=usr/lib/libw.so.1
96Libdl=usr/lib/libdl.so.1
97Cpio=usr/bin/cpio
98Rm=usr/bin/rm
99Ln=usr/bin/ln
100Mv=usr/bin/mv
101Nawk=usr/bin/nawk
102Zcat=usr/bin/zcat
103
104# Set up the default paths
105MV_xpath=/usr/bin
106MV_cmd=$MV_xpath/mv
107CPIO_xpath=/usr/bin
108CPIO_cmd=$CPIO_xpath/cpio
109ZCAT_xpath=/usr/bin
110ZCAT_cmd=$ZCAT_xpath/zcat
111LN_xpath=/usr/bin
112LN_cmd=$LN_xpath/ln
113NAWK_xpath=/usr/bin
114NAWK_cmd=$NAWK_xpath/nawk
115RM_xpath=/usr/bin
116RM_cmd=$RM_xpath/rm
117Tmp_xpath=/usr/tmp$$dir
118Tmp_Creat=0
119rm_cpio=0
120rm_ln=0
121rm_zcat=0
122rm_nawk=0
123rm_rm=0
124rm_mv=0
125no_select=0
126
127# Functions
128
129#
130# This creates the temporary directory for holding the old dynamic
131# libraries and executables.
132#
133mktempdir() {
134	if [ ! -d $Tmp_xpath ]; then
135		mkdir $Tmp_xpath
136		if [ $? -ne 0 ]; then
137			echo `gettext "ERROR : $NAME cannot create $Tmp_xpath."`
138			exit 1
139		fi
140	fi
141	Tmp_Creat=1
142}
143
144#
145# Test a path to see if it represents a dynamic library or executable that
146# we use in this script. If it is, deal with the special case.
147#
148spclcase() {	# $1 is the pathname to special case
149	if [ $local_install -eq 1 ]; then
150		case $1 in
151			$Ld)		no_select=1;;
152			$Ld1)		no_select=1;;
153			$Libintl)	Spcl_lib=1; file=libintl.so.1;;
154			$Libmalloc)	Spcl_lib=1; file=libmapmalloc.so.1;;
155			$Libc)		Spcl_lib=1; file=libc.so.1;;
156			$Libw)		Spcl_lib=1; file=libw.so.1;;
157			$Libdl)		Spcl_lib=1; file=libdl.so.1;;
158			$Cpio)		rm_cpio=1; Spcl_exec=1;;
159			$Ln)		rm_ln=1; Spcl_exec=1;;
160			$Zcat)		rm_zcat=1; Spcl_exec=1;;
161			$Nawk)		rm_nawk=1; Spcl_exec=1;;
162			$Rm)		rm_rm=1; Spcl_exec=1;;
163			$Mv)		rm_mv=1; Spcl_exec=1;;
164		esac
165
166		if [ $no_select -eq 1 ]; then
167			is_a_filelist=0
168			list_empty=1
169			$RM_cmd $FILELIST
170			if [ $Rm_alt_sav -eq 1 ]; then
171				$RM_cmd -r $PKGSAV
172				Rm_alt_sav=0
173			fi
174			exec_clean 1
175			return 1
176		elif [ $Spcl_lib -eq 1 ]; then
177			if [ $Tmp_Creat -eq 0 ]; then
178				mktempdir
179			fi
180
181			if [ $Spcl_init -eq 0 ]; then
182				Org_LD_LIBRARY_PATH=${LD_LIBRARY_PATH}
183				LD_LIBRARY_PATH="$Org_LD_LIBRARY_PATH $Tmp_xpath"
184				export LD_LIBRARY_PATH
185				Spcl_init=1
186			fi
187			Ld_Preload="$Ld_Preload $Tmp_xpath/$file"
188			LD_PRELOAD=$Ld_Preload
189			export LD_PRELOAD
190			Movelist="$1 $file $Movelist"
191			$MV_cmd $1 $Tmp_xpath
192			$LN_cmd -s ../..$Tmp_xpath/$file $1
193			Spcl_lib=0
194		elif [ $Spcl_exec -eq 1 ]; then
195			if [ $Tmp_Creat -eq 0 ]; then
196				mktempdir
197			fi
198
199			$MV_cmd $1 $Tmp_xpath
200			if [ $rm_cpio -eq 1 ]; then
201				$LN_cmd -s ../..$Tmp_xpath/cpio $1
202				CPIO_cmd="$Tmp_xpath/cpio"
203				Movelist="$1 cpio $Movelist"
204				rm_cpio=0
205			elif [ $rm_ln -eq 1 ]; then
206				$Tmp_xpath/ln -s ../..$Tmp_xpath/ln $1
207				LN_cmd="$Tmp_xpath/ln"
208				Movelist="$1 ln $Movelist"
209				rm_ln=0
210			elif [ $rm_nawk -eq 1 ]; then
211				$LN_cmd -s ../..$Tmp_xpath/nawk $1
212				NAWK_cmd="$Tmp_xpath/nawk"
213				Movelist="$1 nawk $Movelist"
214				rm_nawk=0
215			elif [ $rm_zcat -eq 1 ]; then
216				$LN_cmd -s ../..$Tmp_xpath/zcat $1
217				ZCAT_cmd="$Tmp_xpath/zcat"
218				Movelist="$1 zcat $Movelist"
219				rm_zcat=0
220			elif [ $rm_rm -eq 1 ]; then
221				$LN_cmd -s ../..$Tmp_xpath/rm $1
222				RM_cmd="$Tmp_xpath/rm"
223				Movelist="$Movelist $1 rm"
224				rm_rm=0
225			elif [ $rm_mv -eq 1 ]; then
226				$LN_cmd -s ../..$Tmp_xpath/mv $1
227				MV_cmd="$Tmp_xpath/mv"
228				Movelist="$Movelist $1 mv"
229				rm_mv=0
230			fi
231			Spcl_exec=0
232		fi
233	fi
234
235	return 0
236}
237
238#
239# Clean up the libraries and executables that were moved.
240#
241exec_clean() {	# $1 =1 means be quiet
242	if [ ! -z "${Movelist}" ]; then
243		echo $Movelist | $NAWK_cmd '
244			{ split ($0, line)
245			for (n=1; n <= NF; n++) {
246				print line[n]
247			}
248		}' | while read path; do
249			read file
250			if [ -h $path ]; then	# If it's our slink
251				# then put the original back
252				if [ $1 -eq 0 ]; then
253					echo `gettext "WARNING : $path not found in archive."`
254				fi
255				$MV_cmd $Tmp_xpath/$file $path
256			else	# if the archive put something down
257				# remove the temporary copy
258				$RM_cmd $Tmp_xpath/$file
259			fi
260		done
261		for path in $Movelist; do
262			if [ -x $path ]; then
263				case $path in
264					$Cpio)	CPIO_cmd="$CPIO_xpath/cpio";;
265					$Ln)	LN_cmd="$LN_xpath/ln";;
266					$Zcat)	ZCAT_cmd="$ZCAT_xpath/zcat";;
267					$Nawk)	NAWK_cmd="$NAWK_xpath/nawk";;
268					$Rm)	RM_cmd="$RM_xpath/rm";;
269					$Mv)	MV_cmd="$MV_xpath/mv";;
270				esac
271			fi
272		done
273		Movelist=""
274
275		if [ $Tmp_Creat -eq 1 ]; then
276			$RM_cmd -r $Tmp_xpath
277			Tmp_Creat=0
278		fi
279	fi
280}
281
282#
283# Figure out what kind of package this is
284#
285eval_pkg() {
286
287	# Any archive, whether compressed or not needs to be handled
288	# the same. i.e. reloc.cpio.Z and root.cpio.Z should cause
289	# the global is_an_archive to be set to 1.
290
291	read path
292	if [ ${path:-NULL} != NULL ]; then # get the package source directory
293		PKGSRC=${path:?undefined}
294
295		if [ ${PKG_INSTALL_ROOT:-/} = "/" ]; then
296			local_install=1
297		fi
298
299		if [ -r $PKGSRC/reloc.cpio.Z ]; then
300			reloc_cpio_Z=1
301			Reloc_Arch=$PKGSRC/reloc.cpio.Z
302			is_an_archive=1
303		fi
304
305		if [ -r $PKGSRC/root.cpio.Z ]; then
306			root_cpio_Z=1
307			Root_Arch=$PKGSRC/root.cpio.Z
308			is_an_archive=1
309		fi
310
311		if [ -r $PKGSRC/reloc.cpio ]; then
312			reloc_cpio=1
313			Reloc_Arch=$PKGSRC/reloc.cpio
314			is_an_archive=1
315		fi
316
317		if [ -r $PKGSRC/root.cpio ]; then
318			root_cpio=1
319			Root_Arch=$PKGSRC/root.cpio
320			is_an_archive=1
321		fi
322
323		if [ -r $PKGSRC/reloc.Z ]; then
324			reloc_cpio_Z=1
325			Reloc_Arch=$PKGSRC/reloc.Z
326			is_an_archive=2
327		fi
328
329		if [ -r $PKGSRC/root.Z ]; then
330			root_cpio_Z=1
331			Root_Arch=$PKGSRC/root.Z
332			is_an_archive=2
333		fi
334
335		if [ -f $PKGSRC/reloc ]; then
336			reloc_cpio=1
337			Reloc_Arch=$PKGSRC/reloc
338			is_an_archive=2
339		fi
340
341		if [ -f $PKGSRC/root ]; then
342			root_cpio=1
343			Root_Arch=$PKGSRC/root
344			is_an_archive=2
345		fi
346	else
347		exit 0	# empty pipe, we're done
348	fi
349}
350
351#
352# main
353#
354
355eval_pkg
356
357if [ $BD = "/" ]; then
358	Client_BD=""
359else
360	Client_BD=`echo $BD | sed s@/@@`
361fi
362
363if [ $is_an_archive -eq 0 ]; then
364	echo `gettext "ERROR : $NAME cannot find archived files in $PKGSRC."`
365	exit 1
366fi
367
368if [ ! -d $PKGSAV ]; then
369	echo `gettext "WARNING : $NAME cannot find save directory $PKGSAV."`
370	PKGSAV=/tmp/$PKG.sav
371
372	if [ ! -d $PKGSAV ]; then
373		/usr/bin/mkdir $PKGSAV
374	fi
375
376	if [ $? -eq 0 ]; then
377		echo `gettext "  Using alternate save directory" $PKGSAV`
378		FILELIST=$PKGSAV/filelist
379		Rm_alt_sav=1
380	else
381		echo `gettext "ERROR : cannot create alternate save directory"` $PKGSAV
382		exit 1
383	fi
384fi
385
386if [ -f $FILELIST ]; then
387	rm $FILELIST
388fi
389
390cd $BD
391
392# If there's one old-style archive and it is relocatable and this is
393# not an initial install then make a file list for extraction.
394if [ $is_an_archive -eq 1 -a ${PKG_INIT_INSTALL:-null} = null ]; then
395	mk_filelist=1
396fi
397
398# If this is not an initial install then clear out potentially executing
399# files and libraries for cpio and create an extraction list if necessary
400if [ ${PKG_INIT_INSTALL:-null} = null ]; then
401	if [ $local_install -eq 1 ]; then
402		# If extraction list is desired, create it
403		if [ $mk_filelist -eq 1 ]; then
404			is_a_filelist=1
405			while	read path
406			do
407				echo $path >> $FILELIST
408				list_empty=0
409				if [ -x ${path:-NULL} ]; then
410					full_path=`echo $Client_BD/$path | sed s@//@/@g`
411					spclcase $full_path
412					if [ $? -eq 1 ]; then
413						break
414					fi
415				fi
416			done
417
418			# If there's a path containing a '$' then we can't
419			# use the extraction list because of the shell
420			if [ $list_empty -eq 0 ]; then
421				s=`LD_PRELOAD="$Ld_Preload" $NAWK_cmd ' /\\$/ { print } ' $FILELIST`
422
423				if [ ! -z "${s}" ]; then
424					is_a_filelist=0
425				fi
426			fi
427		else	# No extraction list is desired
428			while	read  path
429			do
430				if [ -x ${path:-NULL} ]; then
431					full_path=`echo $Client_BD/$path | sed s@//@/@g`
432					spclcase $full_path
433					if [ $? -eq 1 ]; then
434						break
435					fi
436				fi
437			done
438		fi	# $mk_filelist -eq 1
439	else	# ! ($local_install -eq 1)
440		# If extraction list is desired, create it
441		if [ $mk_filelist -eq 1 ]; then
442			is_a_filelist=1
443			while	read path
444			do
445				echo $path >> $FILELIST
446				list_empty=0
447			done
448
449			# If there's a path containing a '$' then we can't
450			# use the extraction list because of the shell
451			if [ $list_empty -eq 0 ]; then
452				s=`LD_PRELOAD="$Ld_Preload" $NAWK_cmd ' /\\$/ { print } ' $FILELIST`
453
454				if [ ! -z "${s}" ]; then
455					is_a_filelist=0
456				fi
457			fi
458		fi	# $mk_filelist -eq 1
459	fi	# $local_install -eq 1
460fi	# ${PKG_INIT_INSTALL:-null} = null
461
462# Now extract the data from the archive(s)
463# extract compressed cpio relocatable archive
464if [ $reloc_cpio_Z -eq 1 ]; then
465	cd $BD
466	if [ $is_a_filelist -eq 1 ]; then
467		if [ $list_empty -eq 0 ]; then
468			$ZCAT_cmd $Reloc_Arch | $CPIO_cmd -idukm -E $FILELIST
469			if [ $? -ne 0 ]; then
470				echo `gettext "cpio of $Reloc_Arch failed with error $?."`
471				exit 1
472		   	 fi
473
474		fi
475	else
476		$ZCAT_cmd $Reloc_Arch | $CPIO_cmd -idukm
477	fi
478fi
479
480# extract compressed cpio absolute archive
481if [ $root_cpio_Z -eq 1 ]; then
482	cd $IR
483	$ZCAT_cmd $Root_Arch | $CPIO_cmd -idukm
484		if [ $? -ne 0 ]; then
485			echo `gettext "cpio of $Root_Arch failed with error $?."`
486			exit 1
487		fi
488fi
489
490# extract cpio relocatable archive
491if [ $reloc_cpio -eq 1 ]; then
492	cd $BD
493	if [ $is_a_filelist -eq 1 ]; then
494		if [ $list_empty -eq 0 ]; then
495			$CPIO_cmd -idukm -I $Reloc_Arch -E $FILELIST
496
497			if [ $? -ne 0 ]; then
498				echo `gettext "cpio of $Reloc_Arch failed with error $?."`
499				exit 1
500			fi
501		fi
502	else
503		$CPIO_cmd -idukm -I $Reloc_Arch
504	fi
505fi
506
507# extract cpio absolute archive
508if [ $root_cpio -eq 1 ]; then
509	cd $IR
510	$CPIO_cmd -idukm -I $Root_Arch
511		if [ $? -ne 0 ]; then
512			echo `gettext "cpio of $Root_Arch failed with error $?."`
513			exit 1
514		fi
515fi
516
517if [ -f $FILELIST ]; then
518	$RM_cmd $FILELIST
519fi
520
521if [ $Rm_alt_sav -eq 1 ]; then
522	$RM_cmd -r $PKGSAV
523	Rm_alt_sav=0
524fi
525
526exec_clean 0
527
528if [ $Tmp_Creat -eq 1 ]; then
529	$RM_cmd -r $Tmp_xpath
530fi
531
532if [ $Spcl_init -eq 1 ]; then
533	LD_LIBRARY_PATH=$Org_LD_LIBRARY_PATH
534	export LD_LIBRARY_PATH
535	Spcl_init=0
536fi
537
538exit 0
539