gzexe revision 1.1
11.1Smrg#!/bin/sh -
21.1Smrg#
31.1Smrg# $OpenBSD: gzexe,v 1.3 2003/08/05 18:22:17 deraadt Exp $
41.1Smrg#
51.1Smrg#  Copyright (c) 2003 Otto Moerbeek <otto@drijf.net>
61.1Smrg#
71.1Smrg#  Permission to use, copy, modify, and distribute this software for any
81.1Smrg#  purpose with or without fee is hereby granted, provided that the above
91.1Smrg#  copyright notice and this permission notice appear in all copies.
101.1Smrg#
111.1Smrg#  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
121.1Smrg#  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
131.1Smrg#  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
141.1Smrg#  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
151.1Smrg#  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
161.1Smrg#  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
171.1Smrg#  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
181.1Smrg#
191.1Smrg
201.1Smrg# The number of lines plus one in the on-the-fly decompression script
211.1Smrglines=19
221.1Smrg
231.1Smrg# A simple string to recognize already compressed files
241.1Smrgmagic="# compressed by gzexe"
251.1Smrg
261.1Smrg# Write the decompression script to stdout
271.1Smrgheader () {
281.1Smrg	typeset prog tmp
291.1Smrg	# first section needs variable expansion, second not
301.1Smrg	cat <<- EOF
311.1Smrg		#!/bin/sh -
321.1Smrg		$magic
331.1Smrg		lines=$lines
341.1Smrg	EOF
351.1Smrg	cat <<- 'EOF'
361.1Smrg		prog=`/usr/bin/basename "$0"`
371.1Smrg		tmp=`/usr/bin/mktemp -d /tmp/gzexeXXXXXXXXXX` || {
381.1Smrg			/bin/echo "$prog: cannot create tmp dir"; exit 1
391.1Smrg		}
401.1Smrg		trap '/bin/rm -rf "$tmp"' 0
411.1Smrg		if /usr/bin/tail +$lines "$0" |
421.1Smrg		    /usr/bin/gzip -dc > "$tmp/$prog" 2> /dev/null; then
431.1Smrg			/bin/chmod u+x "$tmp/$prog"
441.1Smrg			"$tmp/$prog" ${1+"$@"}
451.1Smrg			ret=$?
461.1Smrg		else
471.1Smrg			/bin/echo "$prog: cannot decompress $0"
481.1Smrg			ret=1
491.1Smrg		fi
501.1Smrg		exit $ret
511.1Smrg	EOF
521.1Smrg}
531.1Smrg
541.1Smrg# Test if a file is compressed by checking the magic line
551.1Smrgcompressed () {
561.1Smrg	test "X`sed -n 2p "$1" 2> /dev/null`" = "X$magic"
571.1Smrg}
581.1Smrg
591.1Smrg# Decompress a file
601.1Smrgdecompress () {
611.1Smrg	tmp=`mktemp /tmp/gzexeXXXXXXXXXX` || {
621.1Smrg		echo "$prog: cannot create tmp file"
631.1Smrg		return 1
641.1Smrg	}
651.1Smrg	if ! cp "$1" "$tmp"; then
661.1Smrg		echo "$prog: cannot copy $1 to $tmp"
671.1Smrg		rm -f "$tmp"
681.1Smrg		return 1
691.1Smrg	fi
701.1Smrg	if ! tail +$lines "$tmp" | gzip -vdc > "$1"; then
711.1Smrg		echo "$prog: cannot decompress $1"
721.1Smrg		cp "$tmp" "$1"
731.1Smrg		rm -f "$tmp"
741.1Smrg		return 1
751.1Smrg	fi
761.1Smrg}
771.1Smrg
781.1Smrg# Perform some sanity checks on the file
791.1Smrgcheck () {
801.1Smrg	if test ! -e "$1"; then
811.1Smrg		echo "$prog: cannot compress non-existing file $1"
821.1Smrg		return 1
831.1Smrg	fi
841.1Smrg
851.1Smrg	if test ! -f "$1"; then
861.1Smrg		echo "$prog: cannot compress non-regular file $1"
871.1Smrg		return 1
881.1Smrg	fi
891.1Smrg
901.1Smrg	case `basename "$1"` in
911.1Smrg		sh | mktemp | rm | echo | tail | gzip | chmod)
921.1Smrg			echo "$prog: cannot compress $1, I depend on it"
931.1Smrg			return 1
941.1Smrg	esac
951.1Smrg
961.1Smrg	if test ! -x "$1"; then
971.1Smrg		echo "$prog: cannot compress $1, it is not executable"
981.1Smrg		return 1
991.1Smrg	fi
1001.1Smrg
1011.1Smrg	if test -u "$1" -o -g "$1"; then
1021.1Smrg		echo "$prog: cannot compress $1, it has an s bit set"
1031.1Smrg		return 1
1041.1Smrg	fi
1051.1Smrg}
1061.1Smrg
1071.1Smrg# Compress a file
1081.1Smrgcompress () {
1091.1Smrg	tmp=`mktemp /tmp/gzexeXXXXXXXXXX` || {
1101.1Smrg		echo "$prog: cannot create tmp file"
1111.1Smrg		return 1
1121.1Smrg	}
1131.1Smrg	if ! cp "$1" "$tmp"; then
1141.1Smrg		echo "$prog: cannot copy $1 to $tmp"
1151.1Smrg		rm -f "$tmp"
1161.1Smrg		return 1
1171.1Smrg	fi
1181.1Smrg	if ! cp "$1" "$1"~; then
1191.1Smrg		echo "$prog: cannot create backup copy $1~"
1201.1Smrg		rm -f "$1"~ "$tmp"
1211.1Smrg		return 1
1221.1Smrg	fi
1231.1Smrg
1241.1Smrg	# Use cp to overwrite the existing file preserving mode and owner
1251.1Smrg	# if possible. If the file is not writable, this will produce an
1261.1Smrg	# error.
1271.1Smrg
1281.1Smrg	if header "$1" > "$tmp" && gzip -vc "$1" >> "$tmp"; then
1291.1Smrg		if ! cp "$tmp" "$1"; then
1301.1Smrg			echo "$prog: cannot copy $tmp to $1"
1311.1Smrg			rm -f "$tmp"
1321.1Smrg			return 1
1331.1Smrg		fi
1341.1Smrg	else
1351.1Smrg		echo "$prog: cannot compress $1"
1361.1Smrg		rm -f "$1"~ "$tmp"
1371.1Smrg		return 1
1381.1Smrg	fi
1391.1Smrg}
1401.1Smrg
1411.1Smrg# Is the -d flag specified?
1421.1Smrgdflag=
1431.1Smrg
1441.1Smrg# Return value
1451.1Smrgrc=0
1461.1Smrg
1471.1Smrgif test "X$1" = X-d; then
1481.1Smrg	dflag=1
1491.1Smrg	shift
1501.1Smrgfi
1511.1Smrg
1521.1Smrgprog=`basename "$0"`
1531.1SmrgUSAGE="usage: $prog [-d] file ..."
1541.1Smrgif test $# -eq 0; then
1551.1Smrg	echo $USAGE
1561.1Smrg	exit 1
1571.1Smrgfi
1581.1Smrg
1591.1Smrgwhile test $# -ne 0; do
1601.1Smrg	if test $dflag; then
1611.1Smrg		if ! compressed "$1"; then
1621.1Smrg			echo "$prog: $1 is not compressed"
1631.1Smrg			rc=1;
1641.1Smrg		elif ! decompress "$1"; then
1651.1Smrg			rc=$?
1661.1Smrg		fi
1671.1Smrg	else
1681.1Smrg		if compressed "$1"; then
1691.1Smrg			echo "$prog: $1 is already compressed"
1701.1Smrg			rc=1;
1711.1Smrg		elif ! check "$1" || ! compress "$1"; then
1721.1Smrg			rc=$?
1731.1Smrg		fi
1741.1Smrg	fi
1751.1Smrg	shift
1761.1Smrgdone
1771.1Smrgexit $rc
178