12089860delphij#!/bin/sh -
22089860delphij#
32089860delphij# $NetBSD: gzexe,v 1.3 2004/05/01 08:22:41 wiz Exp $
42089860delphij# $OpenBSD: gzexe,v 1.3 2003/08/05 18:22:17 deraadt Exp $
52089860delphij#
62089860delphij#-
72089860delphij#  Copyright (c) 2003 Otto Moerbeek <otto@drijf.net>
82089860delphij#
92089860delphij#  Permission to use, copy, modify, and distribute this software for any
102089860delphij#  purpose with or without fee is hereby granted, provided that the above
112089860delphij#  copyright notice and this permission notice appear in all copies.
122089860delphij#
132089860delphij#  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
142089860delphij#  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
152089860delphij#  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
162089860delphij#  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
172089860delphij#  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
182089860delphij#  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
192089860delphij#  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
202089860delphij#
212089860delphij# $FreeBSD$
222089860delphij
232089860delphij# The number of lines plus one in the on-the-fly decompression script
242089860delphijlines=19
252089860delphij
262089860delphij# A simple string to recognize already compressed files
272089860delphijmagic="# compressed by gzexe"
282089860delphij
292089860delphij# Write the decompression script to stdout
302089860delphijheader () {
312089860delphij	# first section needs variable expansion, second not
322089860delphij	cat <<- EOF
332089860delphij		#!/bin/sh -
342089860delphij		$magic
352089860delphij		lines=$lines
362089860delphij	EOF
372089860delphij	cat <<- 'EOF'
382089860delphij		prog=`/usr/bin/basename "$0"`
392089860delphij		tmp=`/usr/bin/mktemp -d /tmp/gzexeXXXXXXXXXX` || {
402089860delphij			/bin/echo "$prog: cannot create tmp dir"; exit 1
412089860delphij		}
422089860delphij		trap '/bin/rm -rf "$tmp"' 0
432089860delphij		if /usr/bin/tail +$lines "$0" |
442089860delphij		    /usr/bin/gzip -dc > "$tmp/$prog" 2> /dev/null; then
452089860delphij			/bin/chmod u+x "$tmp/$prog"
462089860delphij			"$tmp/$prog" ${1+"$@"}
472089860delphij			ret=$?
482089860delphij		else
492089860delphij			/bin/echo "$prog: cannot decompress $0"
502089860delphij			ret=1
512089860delphij		fi
522089860delphij		exit $ret
532089860delphij	EOF
542089860delphij}
552089860delphij
562089860delphij# Test if a file is compressed by checking the magic line
572089860delphijcompressed () {
582089860delphij	test "X`sed -n 2p "$1" 2> /dev/null`" = "X$magic"
592089860delphij}
602089860delphij
612089860delphij# Decompress a file
622089860delphijdecompress () {
632089860delphij	tmp=`mktemp /tmp/gzexeXXXXXXXXXX` || {
642089860delphij		echo "$prog: cannot create tmp file"
652089860delphij		return 1
662089860delphij	}
672089860delphij	if ! cp "$1" "$tmp"; then
682089860delphij		echo "$prog: cannot copy $1 to $tmp"
692089860delphij		rm -f "$tmp"
702089860delphij		return 1
712089860delphij	fi
722089860delphij	if ! tail +$lines "$tmp" | gzip -vdc > "$1"; then
732089860delphij		echo "$prog: cannot decompress $1"
742089860delphij		cp "$tmp" "$1"
752089860delphij		rm -f "$tmp"
762089860delphij		return 1
772089860delphij	fi
782089860delphij}
792089860delphij
802089860delphij# Perform some sanity checks on the file
812089860delphijcheck () {
822089860delphij	if test ! -e "$1"; then
832089860delphij		echo "$prog: cannot compress non-existing file $1"
842089860delphij		return 1
852089860delphij	fi
862089860delphij
872089860delphij	if test ! -f "$1"; then
882089860delphij		echo "$prog: cannot compress non-regular file $1"
892089860delphij		return 1
902089860delphij	fi
912089860delphij
922089860delphij	case `basename "$1"` in
932089860delphij		sh | mktemp | rm | echo | tail | gzip | chmod)
942089860delphij			echo "$prog: cannot compress $1, I depend on it"
952089860delphij			return 1
962089860delphij	esac
972089860delphij
982089860delphij	if test ! -x "$1"; then
992089860delphij		echo "$prog: cannot compress $1, it is not executable"
1002089860delphij		return 1
1012089860delphij	fi
1022089860delphij
1032089860delphij	if test -u "$1" -o -g "$1"; then
1042089860delphij		echo "$prog: cannot compress $1, it has an s bit set"
1052089860delphij		return 1
1062089860delphij	fi
1072089860delphij}
1082089860delphij
1092089860delphij# Compress a file
1102089860delphijcompress () {
1112089860delphij	tmp=`mktemp /tmp/gzexeXXXXXXXXXX` || {
1122089860delphij		echo "$prog: cannot create tmp file"
1132089860delphij		return 1
1142089860delphij	}
1152089860delphij	if ! cp "$1" "$tmp"; then
1162089860delphij		echo "$prog: cannot copy $1 to $tmp"
1172089860delphij		rm -f "$tmp"
1182089860delphij		return 1
1192089860delphij	fi
1202089860delphij	if ! cp "$1" "$1"~; then
1212089860delphij		echo "$prog: cannot create backup copy $1~"
1222089860delphij		rm -f "$1"~ "$tmp"
1232089860delphij		return 1
1242089860delphij	fi
1252089860delphij
1262089860delphij	# Use cp to overwrite the existing file preserving mode and owner
1272089860delphij	# if possible. If the file is not writable, this will produce an
1282089860delphij	# error.
1292089860delphij
1302089860delphij	if header "$1" > "$tmp" && gzip -vc "$1" >> "$tmp"; then
1312089860delphij		if ! cp "$tmp" "$1"; then
1322089860delphij			echo "$prog: cannot copy $tmp to $1"
1332089860delphij			rm -f "$tmp"
1342089860delphij			return 1
1352089860delphij		fi
1362089860delphij	else
1372089860delphij		echo "$prog: cannot compress $1"
1382089860delphij		rm -f "$1"~ "$tmp"
1392089860delphij		return 1
1402089860delphij	fi
1412089860delphij}
1422089860delphij
1432089860delphij# Is the -d flag specified?
1442089860delphijdflag=
1452089860delphij
1462089860delphij# Return value
1472089860delphijrc=0
1482089860delphij
1492089860delphijif test "X$1" = X-d; then
1502089860delphij	dflag=1
1512089860delphij	shift
1522089860delphijfi
1532089860delphij
1542089860delphijprog=`basename "$0"`
1552089860delphijUSAGE="usage: $prog [-d] file ..."
1562089860delphijif test $# -eq 0; then
1572089860delphij	echo $USAGE
1582089860delphij	exit 1
1592089860delphijfi
1602089860delphij
1612089860delphijwhile test $# -ne 0; do
1622089860delphij	if test $dflag; then
1632089860delphij		if ! compressed "$1"; then
1642089860delphij			echo "$prog: $1 is not compressed"
1652089860delphij			rc=1;
1662089860delphij		elif ! decompress "$1"; then
1672089860delphij			rc=$?
1682089860delphij		fi
1692089860delphij	else
1702089860delphij		if compressed "$1"; then
1712089860delphij			echo "$prog: $1 is already compressed"
1722089860delphij			rc=1;
1732089860delphij		elif ! check "$1" || ! compress "$1"; then
1742089860delphij			rc=$?
1752089860delphij		fi
1762089860delphij	fi
1772089860delphij	shift
1782089860delphijdone
1792089860delphijexit $rc
180