summaryrefslogtreecommitdiff
path: root/gnu/usr.bin/gzip/gzexe
blob: 65bbf25290247e35579c4c00fb793fda612e04d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/bin/sh
# gzexe: compressor for Unix executables.
# Use this only for binaries that you do not use frequently.
#
# The compressed version is a shell script which decompresses itself after
# skipping $skip lines of shell commands.  We try invoking the compressed
# executable with the original name (for programs looking at their name).
# We also try to retain the original file permissions on the compressed file.
# For safety reasons, gzexe will not create setuid or setgid shell scripts.

# WARNING: the first line of this file must be either : or #!/bin/sh
# The : is required for some old versions of csh.
# On Ultrix, /bin/sh is too buggy, change the first line to: #!/bin/sh5
#
# $OpenBSD: gzexe,v 1.7 2003/02/08 10:19:30 pvalchev Exp $

x=`basename "$0"`
if test $# = 0; then
  echo compress executables. original file foo is renamed to foo~
  echo usage: ${x} [-d] files...
  echo   "   -d  decompress the executables"
  exit 1
fi

decomp=0
res=0
test "$x" = "ungzexe" && decomp=1
if test "x$1" = "x-d"; then
  decomp=1
  shift
fi

tail=""
IFS="${IFS= 	}"; saveifs="$IFS"; IFS="${IFS}:"
for dir in $PATH; do
  test -z "$dir" && dir=.
  if test -f $dir/tail; then
    tail="$dir/tail"
    break
  fi
done
IFS="$saveifs"
if test -z "$tail"; then
  echo cannot find tail
  exit 1
fi

for i do
  if test ! -f "$i" ; then
    echo ${x}: $i not a file
    res=1
    continue
  fi
  if test $decomp -eq 0; then
    if sed -e 1d -e 2q "$i" | grep "^skip=[0-9]*$" >/dev/null; then
      echo "${x}: $i is already gzexe'd"
      continue
    fi
  fi
  if ls -l "$i" | grep '^...[sS]' > /dev/null; then
    echo "${x}: $i has setuid permission, unchanged"
    continue
  fi
  if ls -l "$i" | grep '^......[sS]' > /dev/null; then
    echo "${x}: $i has setgid permission, unchanged"
    continue
  fi
  case "`basename $i`" in
  sh | gzip | tail | chmod | ln | sleep | rm | sed | mktemp)
	echo "${x}: $i would depend on itself"; continue ;;
  esac

  tmp=`/usr/bin/mktemp gzXXXXXXXXXX` || exit 1
  trap "rm -f $tmp; exit 1" 1 2 3 5 10 13 15

  cp -p "$i" $tmp 2>/dev/null || cp "$i" $tmp
  if test -w $tmp 2>/dev/null; then
    writable=1
  else
    writable=0
    chmod u+w $tmp 2>/dev/null
  fi
  if test $decomp -eq 0; then
    sed 1q "$0" > $tmp
    sed "s|^if tail|if $tail|" >> $tmp <<'EOF'
skip=14
tmpdir=`/usr/bin/mktemp -d /tmp/gzexeXXXXXXXXXX` || {
	rm -f ${tmp}
	exit 1
}
prog="${tmpdir}/`echo \"$0\" | sed 's|^.*/||'`"
if tail +$skip "$0" | gzip -cd > "$prog"; then
  chmod 700 "$prog"
  trap '/bin/rm -rf $tmpdir exit $res' 0
  "$prog" ${1+"$@"}; res=$?
else
  echo Cannot decompress $0
  rm -rf $tmpdir
  exit 1
fi; exit $res
EOF
    gzip -cv9 "$i" >> $tmp || {
      /bin/rm -f $tmp
      echo ${x}: compression not possible for $i, file unchanged.
      res=1
      continue
    }

  else
    # decompression
    skip=18
    if sed -e 1d -e 2q "$i" | grep "^skip=[0-9]*$" >/dev/null; then
      eval `sed -e 1d -e 2q "$i"`
    fi
    if tail +$skip "$i" | gzip -cd > $tmp; then
      :
    else
      echo ${x}: $i probably not in gzexe format, file unchanged.
      /bin/rm -f $tmp
      res=1
      continue
    fi
  fi
  rm -f "$i~"
  mv "$i" "$i~" || {
    echo ${x}: cannot backup $i as $i~
    /bin/rm -f $tmp
    res=1
    continue
  }
  mv $tmp "$i" || cp -p $tmp "$i" 2>/dev/null || cp $tmp "$i" || {
    echo ${x}: cannot create $i
    /bin/rm -f $tmp
    res=1
    continue
  }
  /bin/rm -f $tmp
  if test $writable -eq 0; then
    chmod u-w $i 2>/dev/null
  fi
done
exit $res