6b61ec41c3f813b7e739e67f31d1dad9ec25c095
[debian/gzip] / gzexe.in
1 #!/bin/sh
2 # gzexe: compressor for Unix executables.
3 # Use this only for binaries that you do not use frequently.
4 #
5 # The compressed version is a shell script which decompresses itself after
6 # skipping $skip lines of shell commands.  We try invoking the compressed
7 # executable with the original name (for programs looking at their name).
8 # We also try to retain the original file permissions on the compressed file.
9 # For safety reasons, gzexe will not create setuid or setgid shell scripts.
10
11 # WARNING: the first line of this file must be either : or #!/bin/sh
12 # The : is required for some old versions of csh.
13 # On Ultrix, /bin/sh is too buggy, change the first line to: #!/bin/sh5
14
15
16 # Copyright (C) 1998, 2002, 2004, 2006-2007, 2010-2016 Free Software
17 # Foundation, Inc.
18 # Copyright (C) 1993 Jean-loup Gailly
19
20 # This program is free software; you can redistribute it and/or modify
21 # it under the terms of the GNU General Public License as published by
22 # the Free Software Foundation; either version 3 of the License, or
23 # (at your option) any later version.
24
25 # This program is distributed in the hope that it will be useful,
26 # but WITHOUT ANY WARRANTY; without even the implied warranty of
27 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28 # GNU General Public License for more details.
29
30 # You should have received a copy of the GNU General Public License along
31 # with this program; if not, write to the Free Software Foundation, Inc.,
32 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33
34 tab='   '
35 nl='
36 '
37 IFS=" $tab$nl"
38
39 version='gzexe (gzip) @VERSION@
40 Copyright (C) 2007, 2011-2016 Free Software Foundation, Inc.
41 This is free software.  You may redistribute copies of it under the terms of
42 the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.
43 There is NO WARRANTY, to the extent permitted by law.
44
45 Written by Jean-loup Gailly.'
46
47 usage="Usage: $0 [OPTION] FILE...
48 Rename each FILE with a compressed version of itself, renaming FILE to FILE~.
49
50   -d             Decompress each FILE instead of compressing it.
51       --help     display this help and exit
52       --version  output version information and exit
53
54 Report bugs to <bug-gzip@gnu.org>."
55
56
57 bindir=@bindir@
58 case $1 in
59 --__bindir) bindir=${2?}; shift; shift;;
60 esac
61 PATH=$bindir:$PATH
62
63 decomp=0
64 res=0
65 while :; do
66   case $1 in
67   -d) decomp=1; shift;;
68   --h*) exec echo "$usage";;
69   --v*) exec echo "$version";;
70   --) shift; break;;
71   *) break;;
72   esac
73 done
74
75 if test $# -eq 0; then
76   echo >&2 "$0: missing operand
77 Try \`$0 --help' for more information."
78   exit 1
79 fi
80
81 tmp=
82 trap 'res=$?
83   test -n "$tmp" && rm -f "$tmp"
84   (exit $res); exit $res
85 ' 0 1 2 3 5 10 13 15
86
87 mktemp_status=
88
89 for i do
90   case $i in
91   -*) file=./$i;;
92   *)  file=$i;;
93   esac
94   if test ! -f "$file" || test ! -r "$file"; then
95     res=$?
96     echo >&2 "$0: $i is not a readable regular file"
97     continue
98   fi
99   if test $decomp -eq 0; then
100     if sed -e 1d -e 2q "$file" | grep "^skip=[0-9][0-9]*$" >/dev/null; then
101       echo >&2 "$0: $i is already gzexe'd"
102       continue
103     fi
104   fi
105   if test -u "$file"; then
106     echo >&2 "$0: $i has setuid permission, unchanged"
107     continue
108   fi
109   if test -g "$file"; then
110     echo >&2 "$0: $i has setgid permission, unchanged"
111     continue
112   fi
113   case /$file in
114   */basename | */bash | */cat | */chmod | */cp | \
115   */dirname | */echo | */expr | */gzip | \
116   */ln | */mkdir | */mktemp | */mv | */rm | \
117   */sed | */sh | */sleep | */test | */tail)
118     echo >&2 "$0: $i might depend on itself"; continue;;
119   esac
120
121   dir=`dirname "$file"` || dir=$TMPDIR
122   test -d "$dir" && test -w "$dir" && test -x "$dir" || dir=/tmp
123   test -n "$tmp" && rm -f "$tmp"
124   if test -z "$mktemp_status"; then
125     type mktemp >/dev/null 2>&1
126     mktemp_status=$?
127   fi
128   if test $mktemp_status -eq 0; then
129     tmp=`TMPDIR=$dir mktemp -t gzexeXXXXXX`
130   else
131     tmp=$dir/gzexe$$
132   fi && { cp -p "$file" "$tmp" 2>/dev/null || cp "$file" "$tmp"; } || {
133     res=$?
134     echo >&2 "$0: cannot copy $file"
135     continue
136   }
137   if test -w "$tmp"; then
138     writable=1
139   else
140     writable=0
141     chmod u+w "$tmp" || {
142       res=$?
143       echo >&2 "$0: cannot chmod $tmp"
144       continue
145     }
146   fi
147   if test $decomp -eq 0; then
148     (cat <<'EOF' &&
149 #!/bin/sh
150 skip=44
151
152 tab='   '
153 nl='
154 '
155 IFS=" $tab$nl"
156
157 umask=`umask`
158 umask 77
159
160 gztmpdir=
161 trap 'res=$?
162   test -n "$gztmpdir" && rm -fr "$gztmpdir"
163   (exit $res); exit $res
164 ' 0 1 2 3 5 10 13 15
165
166 if type mktemp >/dev/null 2>&1; then
167   gztmpdir=`mktemp -dt`
168 else
169   gztmpdir=/tmp/gztmp$$; mkdir $gztmpdir
170 fi || { (exit 127); exit 127; }
171
172 gztmp=$gztmpdir/$0
173 case $0 in
174 -* | */*'
175 ') mkdir -p "$gztmp" && rm -r "$gztmp";;
176 */*) gztmp=$gztmpdir/`basename "$0"`;;
177 esac || { (exit 127); exit 127; }
178
179 case `echo X | tail -n +1 2>/dev/null` in
180 X) tail_n=-n;;
181 *) tail_n=;;
182 esac
183 if tail $tail_n +$skip <"$0" | gzip -cd > "$gztmp"; then
184   umask $umask
185   chmod 700 "$gztmp"
186   (sleep 5; rm -fr "$gztmpdir") 2>/dev/null &
187   "$gztmp" ${1+"$@"}; res=$?
188 else
189   echo >&2 "Cannot decompress $0"
190   (exit 127); res=127
191 fi; exit $res
192 EOF
193     gzip -cv9 "$file") > "$tmp" || {
194       res=$?
195       echo >&2 "$0: compression not possible for $i, file unchanged."
196       continue
197     }
198
199   else
200     # decompression
201     skip=44
202     skip_line=`sed -e 1d -e 2q "$file"`
203     case $skip_line in
204     skip=[0-9] | skip=[0-9][0-9] | skip=[0-9][0-9][0-9])
205       eval "$skip_line";;
206     esac
207     case `echo X | tail -n +1 2>/dev/null` in
208     X) tail_n=-n;;
209     *) tail_n=;;
210     esac
211     tail $tail_n +$skip "$file" | gzip -cd > "$tmp" || {
212       res=$?
213       echo >&2 "$0: $i probably not in gzexe format, file unchanged."
214       continue
215     }
216   fi
217   test $writable -eq 1 || chmod u-w "$tmp" || {
218     res=$?
219     echo >&2 "$0: $tmp: cannot chmod"
220     continue
221   }
222   ln -f "$file" "$file~" || {
223     res=$?
224     echo >&2 "$0: cannot backup $i as $i~"
225     continue
226   }
227   mv -f "$tmp" "$file" || {
228     res=$?
229     echo >&2 "$0: cannot rename $tmp to $i"
230     continue
231   }
232   tmp=
233 done
234 (exit $res); exit $res