This is gzip_package.sh in view mode; [Download] [Up]
#!/bin/sh #+++ # RCS $Id: gzip_package.sh,v 2.3 1996/02/28 20:29:45 tom Exp $ # title: gzip_package # abstract: convert NS Installer.app package to use gzipped archive. # author: T.R.Hageman <tom@basil.icce.rug.nl> # created: September 1994 # modified: (see RCS Log at end) # copyleft: # # Copyright (C) 1994--1996 Tom R. Hageman. # # This is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This software is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this software; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # # description: # #--- Revision=; Date= Clean() { expr "$1" : ':* *\(.*[^ $]\) *$*'; } Revision=`Clean "$Revision: 2.3 $"` Date=`Clean "$Date: 1996/02/28 20:29:45 $"` prog=`basename $0` USAGE="Usage: $prog [options] package... -d --debug Debug mode (don't remove tmp files.) -i --info Show package's compression status. -k --keep Keep original package around. -q --quiet Shut up completely. -s --save=* How much gzip should save at least (in kbytes, or \`nn%'). -u --unzip Expand gzip'ed package archive to normal (compressed). -v --verbose Talkative mode. -h --help Show help text. -V --version Show version." tar=gnutar verbose= debug= keep= quiet= unzip= info= # XXX TODO minsavings="5%" # Determine default action from program name, a la gzip <-> gunzip. case "$prog" in #( gunzip*) unzip=yes esac StdErr() { echo "$@" >&2; } # Handle options. while true; do { case "$1" in #(((((((((( -V | --version | --versio | --versi | --vers | --ver | --ve | --v ) echo $prog Version $Revision of $Date. exit 0 ;; -d | --debug | --debu | --deb | --de | --d ) debug=yes # set -x shift ;; -i | --info | --inf | --in | --i ) info=yes shift ;; -k | --keep | --kee | --ke | --k ) keep=yes shift ;; -q | --quiet | --quie | --qui | --qu | --q ) quiet=yes verbose= shift ;; -s=* | --save=* | --sav=* | --sa=* | --s=* ) minsavings=`expr "$1" : '[^=]*=\([0-9][0-9]*%*\)` [ "$minsavings" ] || { Stderr "$prog: value for \`$1' should be number or percentage." exit 2 } shift ;; -s | --save | --sav | --sa | --s ) minsavings=`expr "$2" : '\([0-9[0-9]*%*\)'` [ "$minsavings" ] || { Stderr "$prog: value for \`$1 $2' should be number or percentage." exit 2 } shift shift ;; -u | --unzip |--unzi | --unz | --un | --u ) unzip=yes shift ;; -v | --verbose | --verbos | --verbo | --verb ) verbose=yes quiet= # set -v shift ;; -h | --help | --hel | --he | --h ) echo "$USAGE" exit 0 ;; -- ) # option delimiter. shift break ;; -* ) StdErr "$prog: invalid option \`$1'" StdErr "$USAGE" exit 2 ;; "" ) case "$#" in #( 0) StdErr "$USAGE" exit 2 esac # silently ignore empty argument. shift ;; * ) break ;; esac } done status=0 tmpprefix="##$prog##" # Error handling. ###NOTYET### # Unfortunately `continue' does not seem to work from within a shell function, # So don't forget to add it explicitly after each occurrence of BailOut. BailOut() { [ "$debug" ] || eval "$onexit"; onexit=; [ "$1" -gt "$status" ] && status=$1; } ###BailOut() { status=$1; exit $status; } Error() { StdErr "$prog:" "$@" BailOut 1 } # Support function to yield free space (in kbytes) available in dir. DiskFreeSpace() { # $1: <in-directory> # Filesystem kbytes used avail df "$1" | sed -n 's|^[^ ]*:*/[^ ]* *[0-9]* *[0-9]* *\([0-9]*\).*|\1|p' } # Support function to yield size of package. DirUsage() { # $1 <in-directory> du -s -l "$1" | sed 's:^\([0-9][0-9]*\).*:\1:' } # Function to replace target package with newly-built one. ReplaceTarget() { if [ "$inplace" ]; then { # in-place is relatively simple. backup="$pkgdir~" rm -rf "$backup" mv "$pkgdir" "$backup" 2>/dev/null || { Error "Cannot move original package to \`$backup'"; return; } onexit='mv "$backup" "$pkgdir" 2>/dev/null || Stderr "(original package is now named \`$backup'\'') '"$onexit" mv "$builddir" "$pkgdir" 2>/dev/null || { Error "Cannot move new package to \`$pkgdir'"; return; } onexit= [ "$keep" ] || onexit='rm -rf "$backup"' } else { # Not in-place; either because there was not enough space on the disk, # or because the directory in which the package resides is not # writeable. Anyway, it's a lot harder. # Make backup of package in $HOME. suffix= while [ "$suffix" != "~~~~~~~~" ] do backup="$HOME/$pkgname.pkg~$suffix" rm -rf "$backup" [ ! -d "$backup" -a ! -f "$backup" ] && break suffix="$suffix~" done mkdir "$backup" 2>/dev/null || { Error "Cannot create backup package \`$backup'"; return; } (cd "$pkgdir" && $tar -cf - . ) | ( cd "$backup" && $tar -xf - ) || { Error "copy to backup package \`$backup' failed."; return; } onexit='{ rm -rf "$pkgdir/." (cd "$backup" && $tar -cf - . ) | ( cd "$pkgdir" && $tar -xf - ) } || Stderr "(original package is now in \`$backup'\'') '"$onexit" rm -rf "$pkgdir/." (cd "$builddir" && $tar -cf - . ) | ( cd "$pkgdir" && $tar -xf - ) || { Error "Cannot copy new package to \`$pkgdir'"; return; } onexit= [ "$keep" ] || onexit='rm -rf "$backup"' rm -rf "$builddir" } fi } # Catch signals. onexit= trap '[ "$debug" ] || eval "$onexit"; exit $status' 0 trap 'StdErr "***signalled***"; status=2; exit $status' 1 2 3 15 ###NOTYET### for arg in "$@"; do ###arg="$1" # Strip off trailing slashes. pkgdir=`expr "$arg" : '\(.*[^/]\)/*'` shift if [ -d "$pkgdir.pkg" ]; then { pkgdir="$pkgdir.pkg" } elif [ ! -d "$pkgdir" ]; then { [ -f "$pkgdir" ] || Error "package \`$pkgdir' does not exist." Error "\`$pkgdir' is not a directory." continue } fi # More sanity checks. [ "$info" ] || [ -w "$pkgdir" ] || { Error "package \`$pkgdir' is read-only."; continue; } # Get the root of the package, sans .pkg extension. pkgname=`basename "$pkgdir" .pkg` packagesize=`DirUsage "$pkgdir"` # Load size definitions in *.sizes into shell variables. CompressedSize=`sed -n 's/^CompressedSize \(.*\)/\1/p' "$pkgdir/$pkgname.sizes"` # Check if this is already gzipped. if [ -f "$pkgdir/$pkgname.tar.gz" -a -h "$pkgdir/$pkgname.tar.Z" ] then realCompressedSize=`sed -n 's/^realCompressedSize \(.*\)/\1/p' "$pkgdir/$pkgname.sizes"` expands=`expr $realCompressedSize - $CompressedSize` sizeneeded=`expr $packagesize + $expands` if [ "$info" ] then mesg= [ "$verbose" ] && mesg=" [${packagesize} kbytes, saves ${expands} (`expr $expands \* 100 / $sizeneeded`%)]" echo "$pkgdir: gzipped$mesg" BailOut 0; continue else [ "$unzip" ] || { [ "$quiet" ] || StdErr "$prog: \`$pkgdir' is already gzipped; unchanged" BailOut 0; continue } fi else if [ "$info" ] then if [ -f "$pkgdir/$pkgname.tar.Z" ] then mesg=compressed [ "$verbose" ] && mesg="$mesg [${packagesize} kbytes]" else mesg=installed [ "$verbose" ] && mesg="$mesg [at "`cat "$pkgdir/$pkgname.location"`"]" fi echo "$pkgdir: $mesg" BailOut 0; continue else [ "$unzip" ] && { [ "$quiet" ] || StdErr "$prog: \`$pkgdir' is already gunzipped; unchanged" BailOut 0; continue } fi sizeneeded=$packagesize fi # Get the directory in which the package resides. unset parentdir [ "${parentdir=`expr \"$pkgdir\" : '\(.*\)/[^/][^/]*'`}" ] || parentdir="." [ "$quiet" -o "$verbose" ] || echo -n "$pkgdir: " # We need a temporary work directory which will contain the updated package. # See where we can create it. inplace= # overestimate size about 10 percent to be on the safe side... [ `expr $sizeneeded \* 11 / 10` -le `DiskFreeSpace "$parentdir"` ] && { inplace=yes builddir="$parentdir/$tmpprefix$$" mkdir "$builddir" 2>/dev/null || inplace= # If this fails, this is probably due to parent-dir being write-protected, # so build the new package in /tmp instead } [ "$inplace" ] || { builddir="/tmp/$tmpprefix$$" mkdir "$builddir" 2>/dev/null || { Error "Cannot create build-directory for \`$pkgdir'."; continue; } } # Cleanup. onexit="rm -rf \"$builddir\"" # Transfer the contents of the original package, except the archive ( cd "$pkgdir" && $tar -cf - `ls -A | fgrep -v "\ $pkgname.tar.Z $pkgname.tar.gz"` ) | ( cd "$builddir" && $tar -xf - ) || { Error "copy to build-directory of \`$pkgdir' failed."; continue; } if [ "$unzip" ] then # Handle gzipped -> compressed package # Remove the symbolic .Z link and other junk stuff. rm -f $builddir/$pkgname.tar.Z $builddir/funzip # Restore original values in *.sizes sed 's/^\(CompressedSize\).*/\1 '"$realCompressedSize"'/ /^realCompressedSize/d' "$builddir/$pkgname.sizes" >"$builddir/real_sizes" # Move the real scripts back. for i in pre_install post_install sizes; do { [ -f "$builddir/real_$i" ] && { rm -f "$builddir/$pkgname.$i" mv "$builddir/real_$i" "$builddir/$pkgname.$i" 2>/dev/null || { Error "Cannot move $i script for \`$pkgdir'."; continue 2; } } } done # Now re-expand the contents of the package using compress. gunzip < "$pkgdir/$pkgname.tar.gz" | compress > "$builddir/$pkgname.tar.Z" || { Error "Cannot re-gunzip contents of \`$pkgdir'."; continue; } [ "$quiet" ] || { [ "$verbose" ] && echo -n "$pkgdir: " echo "expands $expands kbytes (`expr $expands \* 100 / $packagesize`%)" } # Now, finally, replace the target package with the compressed one. ReplaceTarget BailOut 0; continue fi # Handle compressed -> gzipped package # Now recompress the contents of the package using gzip. gunzip < "$pkgdir/$pkgname.tar.Z" | gzip -9 > "$builddir/$pkgname.tar.gz" || { Error "Cannot re-gzip contents of \`$pkgdir'."; continue; } # Copy a tiny ungzipper (funzip [m68k]) to the new package, # for NS < 3.1 compatibility. (cd $builddir; sed -n '/^begin .* funzip/,/^end/p' | uudecode) <"$0" || { Error "Cannot add funzip to \`$pkgdir'."; continue; } # Create a symbolic link to a temporary location for the original contents. ln -s "/tmp/$tmpprefix$pkgname.tar.Z" "$builddir/$pkgname.tar.Z" || { Error "cannot create symbolic link for \`$pkgname.tar.Z"; continue; } # Now add a pre_install script to unpack the .gz archive to the temp. location, # and a post_install script to do the necessary cleanup. # Move the real scripts out of the way. for i in pre_install post_install sizes; do { [ -f "$builddir/$pkgname.$i" ] && { mv "$builddir/$pkgname.$i" "$builddir/real_$i" 2>/dev/null || { Error "Cannot move $i script for \`$pkgdir'."; continue 2; } } } done # Now create replacement scripts. SUBSTS='1i\ #!/bin/sh\ # AUTOMATICALLY GENERATED BY '"$prog $Revision of $Date"'.\ \ d="$1"\ n=`basename "$d" .pkg`\ p="$d/$n"\ t="/tmp/'"$tmpprefix"'$n.tar.Z" ' #NO#/^[ ]*#/d' #NO## (Remove comment lines to keep the installed scripts lean.) sed "$SUBSTS" >"$builddir/$pkgname.pre_install" <<\!!!pre r="$d/real_pre_install" E=echo B='[ -f "$r" ] && exec "$r" "$@"; $E OK.' # Bail out if there is no gzipped archive. (assume regular package) [ -f "$p.tar.gz" ] || eval "$B" # Make sure symlink to work file is in place. [ -h "$p.tar.Z" ] || { # No link. Bail out if looks like regular package after all. [ -f "$p.tar.Z" ] && eval "$B" # Last-ditch effort: try to create link. ln -s "$t" "$p.tar.Z" || { $E FAILED.; exit 1; } } # Execute real pre_install script, if it exists, first. [ -r "$r" ] && { "$r" "$@" || exit 1; } || $E # Remove work file for good measure. rm -f "$t" $E -n " Gunzipping package ... " # Try resident gunzip first; if this fails try ungzipper in package. for u in gunzip "$d/funzip" "$d/gunzip";do e=`"$u" <"$p.tar.gz" | compress -f >"$p.tar.Z"` [ -z "$e" ] && break done [ -z "$e" ] || { $E "FAILED -- $e."; exit 1; } $E OK. !!!pre sed "$SUBSTS" >"$builddir/$pkgname.post_install" <<\!!!post # Determine working directory used by Installer. # (Its contents are copied to /NextLibrary/Receipts) wd=`echo "$0"|sed 's:[^/]*$::;s://*$::'` case "$wd" in #(( /tmp/*|/private/tmp/*) ;; *) wd=/tmp esac wp="$wd/$n" # Go cleanup the temporary compressed archive. rm -f "$t" size=`sed -n 's/^realCompressedSize \(.*\)/\1/p' "$wp.sizes"` [ -n "$size" ] && { rm -f "$wp.sizes" # Restore original values in *.sizes sed 's/^\(CompressedSize\).*/\1 '"$size"'/ /^realCompressedSize/d' "$p.sizes" >"$wp.sizes" } # Replace gzip_package pre_ and post_install with the real scripts. for i in pre_install post_install do rm -f "$wp.$i" [ -f "$d/real_$i" ] && cp -p "$d/real_$i" "$wp.$i" done # Now continue with the real post_install script if there is any. [ -f "$wp.post_install" ] && exec "$wp.post_install" "$@" echo OK. !!!post chmod 555 "$builddir/$pkgname.pre_install" "$builddir/$pkgname.post_install" # We're finished building the gzipped package. # Check if it's worth replacing the original package with it. gzpackagesize=`DirUsage "$builddir"` case "$minsavings" in #((( [0-9]% | [1-9][0-9]% ) i=`expr $minsavings : '\(.*\)%'` scaledpackagesize=`expr \( 100 - $i \) \* $packagesize / 100` ;; 0 | "" ) scaledpackagesize=$packagesize ;; * ) scaledpackagesize=`expr $packagesize - $minsavings` esac saves=`expr $packagesize - $gzpackagesize` case "$saves" in #(( -*) expands=`expr "$saves" : "-\(.*\)"` mesg="would expand $expands kbytes (`expr $expands \* 100 / $packagesize`%)" ;; *) mesg=" $saves kbytes (`expr $saves \* 100 / $packagesize`%)" if [ $gzpackagesize -lt $scaledpackagesize ]; then mesg="saves $mesg" else mesg="would save $mesg, if not for --save=$minsavings" fi esac [ "$quiet" ] || { [ "$verbose" ] && echo -n "$pkgdir: " echo "$mesg" } [ $gzpackagesize -lt $scaledpackagesize ] || { BailOut 0; continue; } # Update *.sizes, store original CompressedSize with key `realCompressedSize' sed 's/^\(CompressedSize\).*/\1 '`expr $CompressedSize - $saves`'/ $a\ realCompressedSize '$CompressedSize \ "$builddir/real_sizes" >"$builddir/$pkgname.sizes" rm -f $builddir/real_sizes # Now, finally, replace the target package with the gzipped one. ReplaceTarget BailOut 0 ###NOTYET### done exit $status #====================================================================== # $Log: gzip_package.sh,v $ # Revision 2.3 1996/02/28 20:29:45 tom # (SUBSTS): add trailing newline to make it work with GNU sed v?.?? # [as reported by Gregor Hoffleit <flight@mathi.uni-heidelberg.de>] # # Revision 2.2 1995/12/15 14:32:51 tom # Added -i, --info option and functionality; # Fixed bug that crashed gzip_package when the package it worked on # was located on an NFS-mounted volume. # # Revision 2.1 1995/07/31 12:14:59 tom # Fix bug in package expansion message. # # Revision 2.0 1995/07/16 12:30:23 tom # date: 1995/07/16 12:01:36; author: tom; state: Exp; lines: +103 -96 # (options): added -h --help; allow multiple package arguments; # (pre_install): improved error detection, preserve comments; # (post_install): preserve comments. # # Revision 2.0 1995/07/16 12:01:36 tom # (options): added -h --help; allow multiple package arguments; # (pre_install): improved error detection, preserve comments; # (post_install): preserve comments. # # Revision 1.7 1995/03/31 15:11:21 tom # First public release. # # Revision 1.6 1995/01/19 23:10:58 tom # fix bug in funzip uuextraction. # # Revision 1.5 1995/01/01 15:07:24 tom # rename to gzip_package.sh; extract funzip from uuencoded version appended # to the final gzip_package script. # # Revision 1.4 1994/12/30 20:09:39 tom # fix typos: s/strip gunzip/strip funzip/; s/work_prefix/workprefix/. # # Revision 1.3 1994/12/23 14:18:01 tom # (USAGE): add -u --unzip option, determine its default value from $0; # (ReplaceTarget): new function, handles final update of target package; # adjust *.sizes table to reflect new archive size, store original size with # realCompressedSize key; NEW: handle uncompression; # (proto post_install): carefully restore original package state, i.e., replace # gzip_package generated *_install scripts with the real ones (if any) in the # work directory, also restore *.sizes table to its original pre-gzip_packaged # state. # # Revision 1.2 1994/09/23 10:09:05 tom # hammer out the bugs in installer script prototypes. # # Revision 1.1 1994/09/23 08:07:43 tom # Initial revision # #======================================================================
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.