xref: /freebsd/usr.bin/gzip/gzexe (revision d0b2dbfa0ecf2bbc9709efc5e20baf8e4b44bbbf)
19a9ea25fSXin LI#!/bin/sh -
29a9ea25fSXin LI#
39a9ea25fSXin LI# $NetBSD: gzexe,v 1.3 2004/05/01 08:22:41 wiz Exp $
49a9ea25fSXin LI# $OpenBSD: gzexe,v 1.3 2003/08/05 18:22:17 deraadt Exp $
59a9ea25fSXin LI#
69a9ea25fSXin LI#-
79a9ea25fSXin LI#  Copyright (c) 2003 Otto Moerbeek <otto@drijf.net>
89a9ea25fSXin LI#
99a9ea25fSXin LI#  Permission to use, copy, modify, and distribute this software for any
109a9ea25fSXin LI#  purpose with or without fee is hereby granted, provided that the above
119a9ea25fSXin LI#  copyright notice and this permission notice appear in all copies.
129a9ea25fSXin LI#
139a9ea25fSXin LI#  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
149a9ea25fSXin LI#  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
159a9ea25fSXin LI#  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
169a9ea25fSXin LI#  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
179a9ea25fSXin LI#  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
189a9ea25fSXin LI#  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
199a9ea25fSXin LI#  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
209a9ea25fSXin LI#
219a9ea25fSXin LI
229a9ea25fSXin LI# The number of lines plus one in the on-the-fly decompression script
239a9ea25fSXin LIlines=19
249a9ea25fSXin LI
259a9ea25fSXin LI# A simple string to recognize already compressed files
269a9ea25fSXin LImagic="# compressed by gzexe"
279a9ea25fSXin LI
289a9ea25fSXin LI# Write the decompression script to stdout
299a9ea25fSXin LIheader () {
309a9ea25fSXin LI	# first section needs variable expansion, second not
319a9ea25fSXin LI	cat <<- EOF
329a9ea25fSXin LI		#!/bin/sh -
339a9ea25fSXin LI		$magic
349a9ea25fSXin LI		lines=$lines
359a9ea25fSXin LI	EOF
369a9ea25fSXin LI	cat <<- 'EOF'
379a9ea25fSXin LI		prog=`/usr/bin/basename "$0"`
389a9ea25fSXin LI		tmp=`/usr/bin/mktemp -d /tmp/gzexeXXXXXXXXXX` || {
399a9ea25fSXin LI			/bin/echo "$prog: cannot create tmp dir"; exit 1
409a9ea25fSXin LI		}
419a9ea25fSXin LI		trap '/bin/rm -rf "$tmp"' 0
429a9ea25fSXin LI		if /usr/bin/tail +$lines "$0" |
439a9ea25fSXin LI		    /usr/bin/gzip -dc > "$tmp/$prog" 2> /dev/null; then
449a9ea25fSXin LI			/bin/chmod u+x "$tmp/$prog"
459a9ea25fSXin LI			"$tmp/$prog" ${1+"$@"}
469a9ea25fSXin LI			ret=$?
479a9ea25fSXin LI		else
489a9ea25fSXin LI			/bin/echo "$prog: cannot decompress $0"
499a9ea25fSXin LI			ret=1
509a9ea25fSXin LI		fi
519a9ea25fSXin LI		exit $ret
529a9ea25fSXin LI	EOF
539a9ea25fSXin LI}
549a9ea25fSXin LI
559a9ea25fSXin LI# Test if a file is compressed by checking the magic line
569a9ea25fSXin LIcompressed () {
579a9ea25fSXin LI	test "X`sed -n 2p "$1" 2> /dev/null`" = "X$magic"
589a9ea25fSXin LI}
599a9ea25fSXin LI
609a9ea25fSXin LI# Decompress a file
619a9ea25fSXin LIdecompress () {
629a9ea25fSXin LI	tmp=`mktemp /tmp/gzexeXXXXXXXXXX` || {
639a9ea25fSXin LI		echo "$prog: cannot create tmp file"
649a9ea25fSXin LI		return 1
659a9ea25fSXin LI	}
669a9ea25fSXin LI	if ! cp "$1" "$tmp"; then
679a9ea25fSXin LI		echo "$prog: cannot copy $1 to $tmp"
689a9ea25fSXin LI		rm -f "$tmp"
699a9ea25fSXin LI		return 1
709a9ea25fSXin LI	fi
719a9ea25fSXin LI	if ! tail +$lines "$tmp" | gzip -vdc > "$1"; then
729a9ea25fSXin LI		echo "$prog: cannot decompress $1"
739a9ea25fSXin LI		cp "$tmp" "$1"
749a9ea25fSXin LI		rm -f "$tmp"
759a9ea25fSXin LI		return 1
769a9ea25fSXin LI	fi
779a9ea25fSXin LI}
789a9ea25fSXin LI
799a9ea25fSXin LI# Perform some sanity checks on the file
809a9ea25fSXin LIcheck () {
819a9ea25fSXin LI	if test ! -e "$1"; then
829a9ea25fSXin LI		echo "$prog: cannot compress non-existing file $1"
839a9ea25fSXin LI		return 1
849a9ea25fSXin LI	fi
859a9ea25fSXin LI
869a9ea25fSXin LI	if test ! -f "$1"; then
879a9ea25fSXin LI		echo "$prog: cannot compress non-regular file $1"
889a9ea25fSXin LI		return 1
899a9ea25fSXin LI	fi
909a9ea25fSXin LI
919a9ea25fSXin LI	case `basename "$1"` in
929a9ea25fSXin LI		sh | mktemp | rm | echo | tail | gzip | chmod)
939a9ea25fSXin LI			echo "$prog: cannot compress $1, I depend on it"
949a9ea25fSXin LI			return 1
959a9ea25fSXin LI	esac
969a9ea25fSXin LI
979a9ea25fSXin LI	if test ! -x "$1"; then
989a9ea25fSXin LI		echo "$prog: cannot compress $1, it is not executable"
999a9ea25fSXin LI		return 1
1009a9ea25fSXin LI	fi
1019a9ea25fSXin LI
1029a9ea25fSXin LI	if test -u "$1" -o -g "$1"; then
1039a9ea25fSXin LI		echo "$prog: cannot compress $1, it has an s bit set"
1049a9ea25fSXin LI		return 1
1059a9ea25fSXin LI	fi
1069a9ea25fSXin LI}
1079a9ea25fSXin LI
1089a9ea25fSXin LI# Compress a file
1099a9ea25fSXin LIcompress () {
1109a9ea25fSXin LI	tmp=`mktemp /tmp/gzexeXXXXXXXXXX` || {
1119a9ea25fSXin LI		echo "$prog: cannot create tmp file"
1129a9ea25fSXin LI		return 1
1139a9ea25fSXin LI	}
1149a9ea25fSXin LI	if ! cp "$1" "$tmp"; then
1159a9ea25fSXin LI		echo "$prog: cannot copy $1 to $tmp"
1169a9ea25fSXin LI		rm -f "$tmp"
1179a9ea25fSXin LI		return 1
1189a9ea25fSXin LI	fi
1199a9ea25fSXin LI	if ! cp "$1" "$1"~; then
1209a9ea25fSXin LI		echo "$prog: cannot create backup copy $1~"
1219a9ea25fSXin LI		rm -f "$1"~ "$tmp"
1229a9ea25fSXin LI		return 1
1239a9ea25fSXin LI	fi
1249a9ea25fSXin LI
1259a9ea25fSXin LI	# Use cp to overwrite the existing file preserving mode and owner
1269a9ea25fSXin LI	# if possible. If the file is not writable, this will produce an
1279a9ea25fSXin LI	# error.
1289a9ea25fSXin LI
1299a9ea25fSXin LI	if header "$1" > "$tmp" && gzip -vc "$1" >> "$tmp"; then
1309a9ea25fSXin LI		if ! cp "$tmp" "$1"; then
1319a9ea25fSXin LI			echo "$prog: cannot copy $tmp to $1"
1329a9ea25fSXin LI			rm -f "$tmp"
1339a9ea25fSXin LI			return 1
1349a9ea25fSXin LI		fi
1359a9ea25fSXin LI	else
1369a9ea25fSXin LI		echo "$prog: cannot compress $1"
1379a9ea25fSXin LI		rm -f "$1"~ "$tmp"
1389a9ea25fSXin LI		return 1
1399a9ea25fSXin LI	fi
1409a9ea25fSXin LI}
1419a9ea25fSXin LI
1429a9ea25fSXin LI# Is the -d flag specified?
1439a9ea25fSXin LIdflag=
1449a9ea25fSXin LI
1459a9ea25fSXin LI# Return value
1469a9ea25fSXin LIrc=0
1479a9ea25fSXin LI
1489a9ea25fSXin LIif test "X$1" = X-d; then
1499a9ea25fSXin LI	dflag=1
1509a9ea25fSXin LI	shift
1519a9ea25fSXin LIfi
1529a9ea25fSXin LI
1539a9ea25fSXin LIprog=`basename "$0"`
1549a9ea25fSXin LIUSAGE="usage: $prog [-d] file ..."
1559a9ea25fSXin LIif test $# -eq 0; then
1569a9ea25fSXin LI	echo $USAGE
1579a9ea25fSXin LI	exit 1
1589a9ea25fSXin LIfi
1599a9ea25fSXin LI
1609a9ea25fSXin LIwhile test $# -ne 0; do
1619a9ea25fSXin LI	if test $dflag; then
1629a9ea25fSXin LI		if ! compressed "$1"; then
1639a9ea25fSXin LI			echo "$prog: $1 is not compressed"
1649a9ea25fSXin LI			rc=1;
1659a9ea25fSXin LI		elif ! decompress "$1"; then
1669a9ea25fSXin LI			rc=$?
1679a9ea25fSXin LI		fi
1689a9ea25fSXin LI	else
1699a9ea25fSXin LI		if compressed "$1"; then
1709a9ea25fSXin LI			echo "$prog: $1 is already compressed"
1719a9ea25fSXin LI			rc=1;
1729a9ea25fSXin LI		elif ! check "$1" || ! compress "$1"; then
1739a9ea25fSXin LI			rc=$?
1749a9ea25fSXin LI		fi
1759a9ea25fSXin LI	fi
1769a9ea25fSXin LI	shift
1779a9ea25fSXin LIdone
1789a9ea25fSXin LIexit $rc
179