document mingw linker fix and close associated bug
[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-2018 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-2018 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 <https://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 Replace each executable FILE with a compressed version of itself.
49 Make a backup FILE~ of the old version of FILE.
50
51   -d             Decompress each FILE instead of compressing it.
52       --help     display this help and exit
53       --version  output version information and exit
54
55 Report bugs to <bug-gzip@gnu.org>."
56
57 decomp=0
58 res=0
59 while :; do
60   case $1 in
61   -d) decomp=1; shift;;
62   --h*) printf '%s\n' "$usage"   || exit 1; exit;;
63   --v*) printf '%s\n' "$version" || exit 1; exit;;
64   --) shift; break;;
65   *) break;;
66   esac
67 done
68
69 if test $# -eq 0; then
70   printf >&2 '%s\n' "$0: missing operand
71 Try \`$0 --help' for more information."
72   exit 1
73 fi
74
75 tmp=
76 trap 'res=$?
77   test -n "$tmp" && rm -f "$tmp"
78   (exit $res); exit $res
79 ' 0 1 2 3 5 10 13 15
80
81 mktemp_status=
82
83 for i do
84   case $i in
85   -*) file=./$i;;
86   *)  file=$i;;
87   esac
88   if test ! -f "$file" || test ! -r "$file"; then
89     res=$?
90     printf >&2 '%s\n' "$0: $i is not a readable regular file"
91     continue
92   fi
93   if test $decomp -eq 0; then
94     if sed -e 1d -e 2q "$file" | grep "^skip=[0-9][0-9]*$" >/dev/null; then
95       printf >&2 '%s\n' "$0: $i is already gzexe'd"
96       continue
97     fi
98   fi
99   if test -u "$file"; then
100     printf >&2 '%s\n' "$0: $i has setuid permission, unchanged"
101     continue
102   fi
103   if test -g "$file"; then
104     printf >&2 '%s\n' "$0: $i has setgid permission, unchanged"
105     continue
106   fi
107   case /$file in
108   */basename | */bash | */cat | */chmod | */cp | \
109   */dirname | */expr | */gzip | \
110   */ln | */mkdir | */mktemp | */mv | */printf | */rm | \
111   */sed | */sh | */sleep | */test | */tail)
112     printf >&2 '%s\n' "$0: $i might depend on itself"; continue;;
113   esac
114
115   dir=`dirname "$file"` || dir=$TMPDIR
116   test -d "$dir" && test -w "$dir" && test -x "$dir" || dir=/tmp
117   test -n "$tmp" && rm -f "$tmp"
118   if test -z "$mktemp_status"; then
119     type mktemp >/dev/null 2>&1
120     mktemp_status=$?
121   fi
122   case $dir in
123     */) ;;
124     *) dir=$dir/;;
125   esac
126   if test $mktemp_status -eq 0; then
127     tmp=`mktemp "${dir}gzexeXXXXXXXXX"`
128   else
129     tmp=${dir}gzexe$$
130   fi && { cp -p "$file" "$tmp" 2>/dev/null || cp "$file" "$tmp"; } || {
131     res=$?
132     printf >&2 '%s\n' "$0: cannot copy $file"
133     continue
134   }
135   if test -w "$tmp"; then
136     writable=1
137   else
138     writable=0
139     chmod u+w "$tmp" || {
140       res=$?
141       printf >&2 '%s\n' "$0: cannot chmod $tmp"
142       continue
143     }
144   fi
145   if test $decomp -eq 0; then
146     (cat <<'EOF' &&
147 #!/bin/sh
148 skip=44
149
150 tab='   '
151 nl='
152 '
153 IFS=" $tab$nl"
154
155 umask=`umask`
156 umask 77
157
158 gztmpdir=
159 trap 'res=$?
160   test -n "$gztmpdir" && rm -fr "$gztmpdir"
161   (exit $res); exit $res
162 ' 0 1 2 3 5 10 13 15
163
164 case $TMPDIR in
165   / | /*/) ;;
166   /*) TMPDIR=$TMPDIR/;;
167   *) TMPDIR=/tmp/;;
168 esac
169 if type mktemp >/dev/null 2>&1; then
170   gztmpdir=`mktemp -d "${TMPDIR}gztmpXXXXXXXXX"`
171 else
172   gztmpdir=${TMPDIR}gztmp$$; mkdir $gztmpdir
173 fi || { (exit 127); exit 127; }
174
175 gztmp=$gztmpdir/$0
176 case $0 in
177 -* | */*'
178 ') mkdir -p "$gztmp" && rm -r "$gztmp";;
179 */*) gztmp=$gztmpdir/`basename "$0"`;;
180 esac || { (exit 127); exit 127; }
181
182 case `printf 'X\n' | tail -n +1 2>/dev/null` in
183 X) tail_n=-n;;
184 *) tail_n=;;
185 esac
186 if tail $tail_n +$skip <"$0" | gzip -cd > "$gztmp"; then
187   umask $umask
188   chmod 700 "$gztmp"
189   (sleep 5; rm -fr "$gztmpdir") 2>/dev/null &
190   "$gztmp" ${1+"$@"}; res=$?
191 else
192   printf >&2 '%s\n' "Cannot decompress $0"
193   (exit 127); res=127
194 fi; exit $res
195 EOF
196     gzip -cv9 "$file") > "$tmp" || {
197       res=$?
198       printf >&2 '%s\n' "$0: compression not possible for $i, file unchanged."
199       continue
200     }
201
202   else
203     # decompression
204     skip=44
205     skip_line=`sed -e 1d -e 2q "$file"`
206     case $skip_line in
207     skip=[0-9] | skip=[0-9][0-9] | skip=[0-9][0-9][0-9])
208       eval "$skip_line";;
209     esac
210     case `printf 'X\n' | tail -n +1 2>/dev/null` in
211     X) tail_n=-n;;
212     *) tail_n=;;
213     esac
214     tail $tail_n +$skip "$file" | gzip -cd > "$tmp" || {
215       res=$?
216       printf >&2 '%s\n' "$0: $i probably not in gzexe format, file unchanged."
217       continue
218     }
219   fi
220   test $writable -eq 1 || chmod u-w "$tmp" || {
221     res=$?
222     printf >&2 '%s\n' "$0: $tmp: cannot chmod"
223     continue
224   }
225   ln -f "$file" "$file~" 2>/dev/null || {
226     # Hard links may not work.  Fall back on rm+cp so that $file always exists.
227     rm -f "$file~" && cp -p "$file" "$file~"
228   } || {
229     res=$?
230     printf >&2 '%s\n' "$0: cannot backup $i as $i~"
231     continue
232   }
233   mv -f "$tmp" "$file" || {
234     res=$?
235     printf >&2 '%s\n' "$0: cannot rename $tmp to $i"
236     continue
237   }
238   tmp=
239 done
240 (exit $res); exit $res