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