1166255Sdelphij#!/bin/sh -
2166255Sdelphij#
3166255Sdelphij# $NetBSD: gzexe,v 1.3 2004/05/01 08:22:41 wiz Exp $
4166255Sdelphij# $OpenBSD: gzexe,v 1.3 2003/08/05 18:22:17 deraadt Exp $
5166255Sdelphij#
6166255Sdelphij#-
7166255Sdelphij#  Copyright (c) 2003 Otto Moerbeek <otto@drijf.net>
8166255Sdelphij#
9166255Sdelphij#  Permission to use, copy, modify, and distribute this software for any
10166255Sdelphij#  purpose with or without fee is hereby granted, provided that the above
11166255Sdelphij#  copyright notice and this permission notice appear in all copies.
12166255Sdelphij#
13166255Sdelphij#  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14166255Sdelphij#  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15166255Sdelphij#  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16166255Sdelphij#  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17166255Sdelphij#  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18166255Sdelphij#  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19166255Sdelphij#  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20166255Sdelphij#
21166255Sdelphij# $FreeBSD$
22166255Sdelphij
23166255Sdelphij# The number of lines plus one in the on-the-fly decompression script
24166255Sdelphijlines=19
25166255Sdelphij
26166255Sdelphij# A simple string to recognize already compressed files
27166255Sdelphijmagic="# compressed by gzexe"
28166255Sdelphij
29166255Sdelphij# Write the decompression script to stdout
30166255Sdelphijheader () {
31166255Sdelphij	# first section needs variable expansion, second not
32166255Sdelphij	cat <<- EOF
33166255Sdelphij		#!/bin/sh -
34166255Sdelphij		$magic
35166255Sdelphij		lines=$lines
36166255Sdelphij	EOF
37166255Sdelphij	cat <<- 'EOF'
38166255Sdelphij		prog=`/usr/bin/basename "$0"`
39166255Sdelphij		tmp=`/usr/bin/mktemp -d /tmp/gzexeXXXXXXXXXX` || {
40166255Sdelphij			/bin/echo "$prog: cannot create tmp dir"; exit 1
41166255Sdelphij		}
42166255Sdelphij		trap '/bin/rm -rf "$tmp"' 0
43166255Sdelphij		if /usr/bin/tail +$lines "$0" |
44166255Sdelphij		    /usr/bin/gzip -dc > "$tmp/$prog" 2> /dev/null; then
45166255Sdelphij			/bin/chmod u+x "$tmp/$prog"
46166255Sdelphij			"$tmp/$prog" ${1+"$@"}
47166255Sdelphij			ret=$?
48166255Sdelphij		else
49166255Sdelphij			/bin/echo "$prog: cannot decompress $0"
50166255Sdelphij			ret=1
51166255Sdelphij		fi
52166255Sdelphij		exit $ret
53166255Sdelphij	EOF
54166255Sdelphij}
55166255Sdelphij
56166255Sdelphij# Test if a file is compressed by checking the magic line
57166255Sdelphijcompressed () {
58166255Sdelphij	test "X`sed -n 2p "$1" 2> /dev/null`" = "X$magic"
59166255Sdelphij}
60166255Sdelphij
61166255Sdelphij# Decompress a file
62166255Sdelphijdecompress () {
63166255Sdelphij	tmp=`mktemp /tmp/gzexeXXXXXXXXXX` || {
64166255Sdelphij		echo "$prog: cannot create tmp file"
65166255Sdelphij		return 1
66166255Sdelphij	}
67166255Sdelphij	if ! cp "$1" "$tmp"; then
68166255Sdelphij		echo "$prog: cannot copy $1 to $tmp"
69166255Sdelphij		rm -f "$tmp"
70166255Sdelphij		return 1
71166255Sdelphij	fi
72166255Sdelphij	if ! tail +$lines "$tmp" | gzip -vdc > "$1"; then
73166255Sdelphij		echo "$prog: cannot decompress $1"
74166255Sdelphij		cp "$tmp" "$1"
75166255Sdelphij		rm -f "$tmp"
76166255Sdelphij		return 1
77166255Sdelphij	fi
78166255Sdelphij}
79166255Sdelphij
80166255Sdelphij# Perform some sanity checks on the file
81166255Sdelphijcheck () {
82166255Sdelphij	if test ! -e "$1"; then
83166255Sdelphij		echo "$prog: cannot compress non-existing file $1"
84166255Sdelphij		return 1
85166255Sdelphij	fi
86166255Sdelphij
87166255Sdelphij	if test ! -f "$1"; then
88166255Sdelphij		echo "$prog: cannot compress non-regular file $1"
89166255Sdelphij		return 1
90166255Sdelphij	fi
91166255Sdelphij
92166255Sdelphij	case `basename "$1"` in
93166255Sdelphij		sh | mktemp | rm | echo | tail | gzip | chmod)
94166255Sdelphij			echo "$prog: cannot compress $1, I depend on it"
95166255Sdelphij			return 1
96166255Sdelphij	esac
97166255Sdelphij
98166255Sdelphij	if test ! -x "$1"; then
99166255Sdelphij		echo "$prog: cannot compress $1, it is not executable"
100166255Sdelphij		return 1
101166255Sdelphij	fi
102166255Sdelphij
103166255Sdelphij	if test -u "$1" -o -g "$1"; then
104166255Sdelphij		echo "$prog: cannot compress $1, it has an s bit set"
105166255Sdelphij		return 1
106166255Sdelphij	fi
107166255Sdelphij}
108166255Sdelphij
109166255Sdelphij# Compress a file
110166255Sdelphijcompress () {
111166255Sdelphij	tmp=`mktemp /tmp/gzexeXXXXXXXXXX` || {
112166255Sdelphij		echo "$prog: cannot create tmp file"
113166255Sdelphij		return 1
114166255Sdelphij	}
115166255Sdelphij	if ! cp "$1" "$tmp"; then
116166255Sdelphij		echo "$prog: cannot copy $1 to $tmp"
117166255Sdelphij		rm -f "$tmp"
118166255Sdelphij		return 1
119166255Sdelphij	fi
120166255Sdelphij	if ! cp "$1" "$1"~; then
121166255Sdelphij		echo "$prog: cannot create backup copy $1~"
122166255Sdelphij		rm -f "$1"~ "$tmp"
123166255Sdelphij		return 1
124166255Sdelphij	fi
125166255Sdelphij
126166255Sdelphij	# Use cp to overwrite the existing file preserving mode and owner
127166255Sdelphij	# if possible. If the file is not writable, this will produce an
128166255Sdelphij	# error.
129166255Sdelphij
130166255Sdelphij	if header "$1" > "$tmp" && gzip -vc "$1" >> "$tmp"; then
131166255Sdelphij		if ! cp "$tmp" "$1"; then
132166255Sdelphij			echo "$prog: cannot copy $tmp to $1"
133166255Sdelphij			rm -f "$tmp"
134166255Sdelphij			return 1
135166255Sdelphij		fi
136166255Sdelphij	else
137166255Sdelphij		echo "$prog: cannot compress $1"
138166255Sdelphij		rm -f "$1"~ "$tmp"
139166255Sdelphij		return 1
140166255Sdelphij	fi
141166255Sdelphij}
142166255Sdelphij
143166255Sdelphij# Is the -d flag specified?
144166255Sdelphijdflag=
145166255Sdelphij
146166255Sdelphij# Return value
147166255Sdelphijrc=0
148166255Sdelphij
149166255Sdelphijif test "X$1" = X-d; then
150166255Sdelphij	dflag=1
151166255Sdelphij	shift
152166255Sdelphijfi
153166255Sdelphij
154166255Sdelphijprog=`basename "$0"`
155166255SdelphijUSAGE="usage: $prog [-d] file ..."
156166255Sdelphijif test $# -eq 0; then
157166255Sdelphij	echo $USAGE
158166255Sdelphij	exit 1
159166255Sdelphijfi
160166255Sdelphij
161166255Sdelphijwhile test $# -ne 0; do
162166255Sdelphij	if test $dflag; then
163166255Sdelphij		if ! compressed "$1"; then
164166255Sdelphij			echo "$prog: $1 is not compressed"
165166255Sdelphij			rc=1;
166166255Sdelphij		elif ! decompress "$1"; then
167166255Sdelphij			rc=$?
168166255Sdelphij		fi
169166255Sdelphij	else
170166255Sdelphij		if compressed "$1"; then
171166255Sdelphij			echo "$prog: $1 is already compressed"
172166255Sdelphij			rc=1;
173166255Sdelphij		elif ! check "$1" || ! compress "$1"; then
174166255Sdelphij			rc=$?
175166255Sdelphij		fi
176166255Sdelphij	fi
177166255Sdelphij	shift
178166255Sdelphijdone
179166255Sdelphijexit $rc
180