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-2022 Free Software
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.
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.
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>."
62 --h*) printf '%s\n' "$usage" ||
exit 1; exit;;
63 --v*) printf '%s\n' "$version" ||
exit 1; exit;;
69 if test $# -eq 0; then
70 printf >&2 '%s\n' "$0: missing operand
71 Try \`$0 --help' for more information."
77 test -n "$tmp" && rm -f "$tmp"
78 (exit $res); exit $res
88 if test ! -f "$file" ||
test ! -r "$file"; then
90 printf >&2 '%s\n' "$0: $i is not a readable regular file"
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"
99 if test -u "$file"; then
100 printf >&2 '%s\n' "$0: $i has setuid permission, unchanged"
103 if test -g "$file"; then
104 printf >&2 '%s\n' "$0: $i has setgid permission, unchanged"
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;;
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
126 if test $mktemp_status -eq 0; then
127 tmp
=`mktemp "${dir}gzexeXXXXXXXXX"`
130 fi && { cp -p "$file" "$tmp" 2>/dev
/null ||
cp "$file" "$tmp"; } ||
{
132 printf >&2 '%s\n' "$0: cannot copy $file"
135 if test -w "$tmp"; then
139 chmod u
+w
"$tmp" ||
{
141 printf >&2 '%s\n' "$0: cannot chmod $tmp"
145 if test $decomp -eq 0; then
160 test -n "$gztmpdir" && rm -fr "$gztmpdir"
161 (exit $res); exit $res
166 /*) TMPDIR=$TMPDIR/;;
169 if type mktemp >/dev/null 2>&1; then
170 gztmpdir=`mktemp -d "${TMPDIR}gztmpXXXXXXXXX"`
172 gztmpdir=${TMPDIR}gztmp$$; mkdir $gztmpdir
173 fi || { (exit 127); exit 127; }
178 ') mkdir -p "$gztmp" && rm -r "$gztmp";;
179 */*) gztmp=$gztmpdir/`basename "$0"`;;
180 esac || { (exit 127); exit 127; }
182 case `printf 'X\n' | tail -n +1 2>/dev/null` in
186 if tail $tail_n +$skip <"$0" | gzip -cd > "$gztmp"; then
189 (sleep 5; rm -fr "$gztmpdir") 2>/dev/null &
190 "$gztmp" ${1+"$@"}; res=$?
192 printf >&2 '%s\n' "Cannot decompress $0"
196 gzip -cv9 "$file") > "$tmp" ||
{
198 printf >&2 '%s\n' "$0: compression not possible for $i, file unchanged."
205 skip_line
=`sed -e 1d -e 2q "$file"`
207 skip
=[0-9] | skip
=[0-9][0-9] | skip
=[0-9][0-9][0-9])
210 case `printf 'X\n' | tail -n +1 2>/dev/null` in
214 tail $tail_n +$skip "$file" |
gzip -cd > "$tmp" ||
{
216 printf >&2 '%s\n' "$0: $i probably not in gzexe format, file unchanged."
220 test $writable -eq 1 ||
chmod u-w
"$tmp" ||
{
222 printf >&2 '%s\n' "$0: $tmp: cannot chmod"
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~"
230 printf >&2 '%s\n' "$0: cannot backup $i as $i~"
233 mv -f "$tmp" "$file" ||
{
235 printf >&2 '%s\n' "$0: cannot rename $tmp to $i"
240 (exit $res); exit $res