gzexe revision 1.1 1 #!/bin/sh -
2 #
3 # $OpenBSD: gzexe,v 1.3 2003/08/05 18:22:17 deraadt Exp $
4 #
5 # Copyright (c) 2003 Otto Moerbeek <otto (at] drijf.net>
6 #
7 # Permission to use, copy, modify, and distribute this software for any
8 # purpose with or without fee is hereby granted, provided that the above
9 # copyright notice and this permission notice appear in all copies.
10 #
11 # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 #
19
20 # The number of lines plus one in the on-the-fly decompression script
21 lines=19
22
23 # A simple string to recognize already compressed files
24 magic="# compressed by gzexe"
25
26 # Write the decompression script to stdout
27 header () {
28 typeset prog tmp
29 # first section needs variable expansion, second not
30 cat <<- EOF
31 #!/bin/sh -
32 $magic
33 lines=$lines
34 EOF
35 cat <<- 'EOF'
36 prog=`/usr/bin/basename "$0"`
37 tmp=`/usr/bin/mktemp -d /tmp/gzexeXXXXXXXXXX` || {
38 /bin/echo "$prog: cannot create tmp dir"; exit 1
39 }
40 trap '/bin/rm -rf "$tmp"' 0
41 if /usr/bin/tail +$lines "$0" |
42 /usr/bin/gzip -dc > "$tmp/$prog" 2> /dev/null; then
43 /bin/chmod u+x "$tmp/$prog"
44 "$tmp/$prog" ${1+"$@"}
45 ret=$?
46 else
47 /bin/echo "$prog: cannot decompress $0"
48 ret=1
49 fi
50 exit $ret
51 EOF
52 }
53
54 # Test if a file is compressed by checking the magic line
55 compressed () {
56 test "X`sed -n 2p "$1" 2> /dev/null`" = "X$magic"
57 }
58
59 # Decompress a file
60 decompress () {
61 tmp=`mktemp /tmp/gzexeXXXXXXXXXX` || {
62 echo "$prog: cannot create tmp file"
63 return 1
64 }
65 if ! cp "$1" "$tmp"; then
66 echo "$prog: cannot copy $1 to $tmp"
67 rm -f "$tmp"
68 return 1
69 fi
70 if ! tail +$lines "$tmp" | gzip -vdc > "$1"; then
71 echo "$prog: cannot decompress $1"
72 cp "$tmp" "$1"
73 rm -f "$tmp"
74 return 1
75 fi
76 }
77
78 # Perform some sanity checks on the file
79 check () {
80 if test ! -e "$1"; then
81 echo "$prog: cannot compress non-existing file $1"
82 return 1
83 fi
84
85 if test ! -f "$1"; then
86 echo "$prog: cannot compress non-regular file $1"
87 return 1
88 fi
89
90 case `basename "$1"` in
91 sh | mktemp | rm | echo | tail | gzip | chmod)
92 echo "$prog: cannot compress $1, I depend on it"
93 return 1
94 esac
95
96 if test ! -x "$1"; then
97 echo "$prog: cannot compress $1, it is not executable"
98 return 1
99 fi
100
101 if test -u "$1" -o -g "$1"; then
102 echo "$prog: cannot compress $1, it has an s bit set"
103 return 1
104 fi
105 }
106
107 # Compress a file
108 compress () {
109 tmp=`mktemp /tmp/gzexeXXXXXXXXXX` || {
110 echo "$prog: cannot create tmp file"
111 return 1
112 }
113 if ! cp "$1" "$tmp"; then
114 echo "$prog: cannot copy $1 to $tmp"
115 rm -f "$tmp"
116 return 1
117 fi
118 if ! cp "$1" "$1"~; then
119 echo "$prog: cannot create backup copy $1~"
120 rm -f "$1"~ "$tmp"
121 return 1
122 fi
123
124 # Use cp to overwrite the existing file preserving mode and owner
125 # if possible. If the file is not writable, this will produce an
126 # error.
127
128 if header "$1" > "$tmp" && gzip -vc "$1" >> "$tmp"; then
129 if ! cp "$tmp" "$1"; then
130 echo "$prog: cannot copy $tmp to $1"
131 rm -f "$tmp"
132 return 1
133 fi
134 else
135 echo "$prog: cannot compress $1"
136 rm -f "$1"~ "$tmp"
137 return 1
138 fi
139 }
140
141 # Is the -d flag specified?
142 dflag=
143
144 # Return value
145 rc=0
146
147 if test "X$1" = X-d; then
148 dflag=1
149 shift
150 fi
151
152 prog=`basename "$0"`
153 USAGE="usage: $prog [-d] file ..."
154 if test $# -eq 0; then
155 echo $USAGE
156 exit 1
157 fi
158
159 while test $# -ne 0; do
160 if test $dflag; then
161 if ! compressed "$1"; then
162 echo "$prog: $1 is not compressed"
163 rc=1;
164 elif ! decompress "$1"; then
165 rc=$?
166 fi
167 else
168 if compressed "$1"; then
169 echo "$prog: $1 is already compressed"
170 rc=1;
171 elif ! check "$1" || ! compress "$1"; then
172 rc=$?
173 fi
174 fi
175 shift
176 done
177 exit $rc
178