maint: update bootstrap and m4/.gitignore to latest Gnulib
[gzip.git] / gzexe.in
blob55bcdb97d8e29d2bbd1321fb06c9b24af8feed9c
1 #!/bin/sh
2 # gzexe: compressor for Unix executables.
3 # Use this only for binaries that you do not use frequently.
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.
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
16 # Copyright (C) 1998, 2002, 2004, 2006-2007, 2010-2024 Free Software
17 # Foundation, Inc.
18 # Copyright (C) 1993 Jean-loup Gailly
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.
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.
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.
34 tab=' '
35 nl='
37 IFS=" $tab$nl"
39 version='gzexe (gzip) @VERSION@
40 Copyright (C) 2024 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.
45 Written by Jean-loup Gailly.'
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.
51 -d Decompress each FILE instead of compressing it.
52 --help display this help and exit
53 --version output version information and exit
55 Report bugs to <bug-gzip@gnu.org>."
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
69 if test $# -eq 0; then
70 printf >&2 '%s\n' "$0: missing operand
71 Try \`$0 --help' for more information."
72 exit 1
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
81 mktemp_status=
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
93 if test $decomp -eq 0; then
94 case `LC_ALL=C sed -n -e 1d -e '/^skip=[0-9][0-9]*$/p' -e 2q "$file"` in
95 skip=[0-9] | skip=[0-9][0-9] | skip=[0-9][0-9][0-9])
96 printf >&2 '%s\n' "$0: $i is already gzexe'd"
97 continue;;
98 esac
100 if test -u "$file"; then
101 printf >&2 '%s\n' "$0: $i has setuid permission, unchanged"
102 continue
104 if test -g "$file"; then
105 printf >&2 '%s\n' "$0: $i has setgid permission, unchanged"
106 continue
108 case /$file in
109 */basename | */bash | */cat | */chmod | */cp | \
110 */dirname | */expr | */'gzip' | \
111 */ln | */mkdir | */mktemp | */mv | */printf | */rm | \
112 */sed | */sh | */sleep | */test | */tail)
113 printf >&2 '%s\n' "$0: $i might depend on itself"; continue;;
114 esac
116 dir=`dirname "$file"` || dir=$TMPDIR
117 test -d "$dir" && test -w "$dir" && test -x "$dir" || dir=/tmp
118 test -n "$tmp" && rm -f "$tmp"
119 if test -z "$mktemp_status"; then
120 type mktemp >/dev/null 2>&1
121 mktemp_status=$?
123 case $dir in
124 */) ;;
125 *) dir=$dir/;;
126 esac
127 if test $mktemp_status -eq 0; then
128 tmp=`mktemp "${dir}gzexeXXXXXXXXX"`
129 else
130 tmp=${dir}gzexe$$
131 fi && { cp -p "$file" "$tmp" 2>/dev/null || cp "$file" "$tmp"; } || {
132 res=$?
133 printf >&2 '%s\n' "$0: cannot copy $file"
134 continue
136 if test -w "$tmp"; then
137 writable=1
138 else
139 writable=0
140 chmod u+w "$tmp" || {
141 res=$?
142 printf >&2 '%s\n' "$0: cannot chmod $tmp"
143 continue
146 if test $decomp -eq 0; then
147 (cat <<'EOF' &&
148 #!/bin/sh
149 skip=49
151 tab=' '
152 nl='
154 IFS=" $tab$nl"
156 umask=`umask`
157 umask 77
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
165 case $TMPDIR in
166 / | /*/) ;;
167 /*) TMPDIR=$TMPDIR/;;
168 *) TMPDIR=/tmp/;;
169 esac
170 if type mktemp >/dev/null 2>&1; then
171 gztmpdir=`mktemp -d "${TMPDIR}gztmpXXXXXXXXX"`
172 else
173 gztmpdir=${TMPDIR}gztmp$$; mkdir $gztmpdir
174 fi || { (exit 127); exit 127; }
176 gztmp=$gztmpdir/$0
177 case $0 in
178 -* | */*'
179 ') mkdir -p "$gztmp" && rm -r "$gztmp";;
180 */*) gztmp=$gztmpdir/`basename "$0"`;;
181 esac || { (exit 127); exit 127; }
183 case `printf 'X\n' | tail -n +1 2>/dev/null` in
184 X) tail_n=-n;;
185 *) tail_n=;;
186 esac
187 if tail $tail_n +$skip <"$0" | 'gzip' -cd > "$gztmp"; then
188 umask $umask
189 chmod 700 "$gztmp"
190 (sleep 5; rm -fr "$gztmpdir") 2>/dev/null &
191 "$gztmp" ${1+"$@"}; res=$?
192 else
193 printf >&2 '%s\n' "Cannot decompress $0"
194 (exit 127); res=127
195 fi; exit $res
197 'gzip' -cv9 "$file") > "$tmp" || {
198 res=$?
199 printf >&2 '%s\n' "$0: compression not possible for $i, file unchanged."
200 continue
203 else
204 # decompression
205 skip=44
206 skip_line=`LC_ALL=C sed -e 1d -e 2q "$file"`
207 case $skip_line in
208 skip=[0-9] | skip=[0-9][0-9] | skip=[0-9][0-9][0-9])
209 eval "$skip_line";;
210 esac
211 case `printf 'X\n' | tail -n +1 2>/dev/null` in
212 X) tail_n=-n;;
213 *) tail_n=;;
214 esac
215 tail $tail_n +$skip "$file" | 'gzip' -cd > "$tmp" || {
216 res=$?
217 printf >&2 '%s\n' "$0: $i probably not in gzexe format, file unchanged."
218 continue
221 test $writable -eq 1 || chmod u-w "$tmp" || {
222 res=$?
223 printf >&2 '%s\n' "$0: $tmp: cannot chmod"
224 continue
226 ln -f "$file" "$file~" 2>/dev/null || {
227 # Hard links may not work. Fall back on rm+cp so that $file always exists.
228 rm -f "$file~" && cp -p "$file" "$file~"
229 } || {
230 res=$?
231 printf >&2 '%s\n' "$0: cannot backup $i as $i~"
232 continue
234 mv -f "$tmp" "$file" || {
235 res=$?
236 printf >&2 '%s\n' "$0: cannot rename $tmp to $i"
237 continue
239 tmp=
240 done
241 (exit $res); exit $res