1*5a645f22SBen Gras#!/bin/sh - 2*5a645f22SBen Gras# 3*5a645f22SBen Gras# $NetBSD: gzexe,v 1.3 2004/05/01 08:22:41 wiz Exp $ 4*5a645f22SBen Gras# 5*5a645f22SBen Gras# $OpenBSD: gzexe,v 1.3 2003/08/05 18:22:17 deraadt Exp $ 6*5a645f22SBen Gras# 7*5a645f22SBen Gras# Copyright (c) 2003 Otto Moerbeek <otto@drijf.net> 8*5a645f22SBen Gras# 9*5a645f22SBen Gras# Permission to use, copy, modify, and distribute this software for any 10*5a645f22SBen Gras# purpose with or without fee is hereby granted, provided that the above 11*5a645f22SBen Gras# copyright notice and this permission notice appear in all copies. 12*5a645f22SBen Gras# 13*5a645f22SBen Gras# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14*5a645f22SBen Gras# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15*5a645f22SBen Gras# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16*5a645f22SBen Gras# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17*5a645f22SBen Gras# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18*5a645f22SBen Gras# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19*5a645f22SBen Gras# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20*5a645f22SBen Gras# 21*5a645f22SBen Gras 22*5a645f22SBen Gras# The number of lines plus one in the on-the-fly decompression script 23*5a645f22SBen Graslines=19 24*5a645f22SBen Gras 25*5a645f22SBen Gras# A simple string to recognize already compressed files 26*5a645f22SBen Grasmagic="# compressed by gzexe" 27*5a645f22SBen Gras 28*5a645f22SBen Gras# Write the decompression script to stdout 29*5a645f22SBen Grasheader () { 30*5a645f22SBen Gras # first section needs variable expansion, second not 31*5a645f22SBen Gras cat <<- EOF 32*5a645f22SBen Gras #!/bin/sh - 33*5a645f22SBen Gras $magic 34*5a645f22SBen Gras lines=$lines 35*5a645f22SBen Gras EOF 36*5a645f22SBen Gras cat <<- 'EOF' 37*5a645f22SBen Gras prog=`/usr/bin/basename "$0"` 38*5a645f22SBen Gras tmp=`/usr/bin/mktemp -d /tmp/gzexeXXXXXXXXXX` || { 39*5a645f22SBen Gras /bin/echo "$prog: cannot create tmp dir"; exit 1 40*5a645f22SBen Gras } 41*5a645f22SBen Gras trap '/bin/rm -rf "$tmp"' 0 42*5a645f22SBen Gras if /usr/bin/tail +$lines "$0" | 43*5a645f22SBen Gras /usr/bin/gzip -dc > "$tmp/$prog" 2> /dev/null; then 44*5a645f22SBen Gras /bin/chmod u+x "$tmp/$prog" 45*5a645f22SBen Gras "$tmp/$prog" ${1+"$@"} 46*5a645f22SBen Gras ret=$? 47*5a645f22SBen Gras else 48*5a645f22SBen Gras /bin/echo "$prog: cannot decompress $0" 49*5a645f22SBen Gras ret=1 50*5a645f22SBen Gras fi 51*5a645f22SBen Gras exit $ret 52*5a645f22SBen Gras EOF 53*5a645f22SBen Gras} 54*5a645f22SBen Gras 55*5a645f22SBen Gras# Test if a file is compressed by checking the magic line 56*5a645f22SBen Grascompressed () { 57*5a645f22SBen Gras test "X`sed -n 2p "$1" 2> /dev/null`" = "X$magic" 58*5a645f22SBen Gras} 59*5a645f22SBen Gras 60*5a645f22SBen Gras# Decompress a file 61*5a645f22SBen Grasdecompress () { 62*5a645f22SBen Gras tmp=`mktemp /tmp/gzexeXXXXXXXXXX` || { 63*5a645f22SBen Gras echo "$prog: cannot create tmp file" 64*5a645f22SBen Gras return 1 65*5a645f22SBen Gras } 66*5a645f22SBen Gras if ! cp "$1" "$tmp"; then 67*5a645f22SBen Gras echo "$prog: cannot copy $1 to $tmp" 68*5a645f22SBen Gras rm -f "$tmp" 69*5a645f22SBen Gras return 1 70*5a645f22SBen Gras fi 71*5a645f22SBen Gras if ! tail +$lines "$tmp" | gzip -vdc > "$1"; then 72*5a645f22SBen Gras echo "$prog: cannot decompress $1" 73*5a645f22SBen Gras cp "$tmp" "$1" 74*5a645f22SBen Gras rm -f "$tmp" 75*5a645f22SBen Gras return 1 76*5a645f22SBen Gras fi 77*5a645f22SBen Gras} 78*5a645f22SBen Gras 79*5a645f22SBen Gras# Perform some sanity checks on the file 80*5a645f22SBen Grascheck () { 81*5a645f22SBen Gras if test ! -e "$1"; then 82*5a645f22SBen Gras echo "$prog: cannot compress non-existing file $1" 83*5a645f22SBen Gras return 1 84*5a645f22SBen Gras fi 85*5a645f22SBen Gras 86*5a645f22SBen Gras if test ! -f "$1"; then 87*5a645f22SBen Gras echo "$prog: cannot compress non-regular file $1" 88*5a645f22SBen Gras return 1 89*5a645f22SBen Gras fi 90*5a645f22SBen Gras 91*5a645f22SBen Gras case `basename "$1"` in 92*5a645f22SBen Gras sh | mktemp | rm | echo | tail | gzip | chmod) 93*5a645f22SBen Gras echo "$prog: cannot compress $1, I depend on it" 94*5a645f22SBen Gras return 1 95*5a645f22SBen Gras esac 96*5a645f22SBen Gras 97*5a645f22SBen Gras if test ! -x "$1"; then 98*5a645f22SBen Gras echo "$prog: cannot compress $1, it is not executable" 99*5a645f22SBen Gras return 1 100*5a645f22SBen Gras fi 101*5a645f22SBen Gras 102*5a645f22SBen Gras if test -u "$1" -o -g "$1"; then 103*5a645f22SBen Gras echo "$prog: cannot compress $1, it has an s bit set" 104*5a645f22SBen Gras return 1 105*5a645f22SBen Gras fi 106*5a645f22SBen Gras} 107*5a645f22SBen Gras 108*5a645f22SBen Gras# Compress a file 109*5a645f22SBen Grascompress () { 110*5a645f22SBen Gras tmp=`mktemp /tmp/gzexeXXXXXXXXXX` || { 111*5a645f22SBen Gras echo "$prog: cannot create tmp file" 112*5a645f22SBen Gras return 1 113*5a645f22SBen Gras } 114*5a645f22SBen Gras if ! cp "$1" "$tmp"; then 115*5a645f22SBen Gras echo "$prog: cannot copy $1 to $tmp" 116*5a645f22SBen Gras rm -f "$tmp" 117*5a645f22SBen Gras return 1 118*5a645f22SBen Gras fi 119*5a645f22SBen Gras if ! cp "$1" "$1"~; then 120*5a645f22SBen Gras echo "$prog: cannot create backup copy $1~" 121*5a645f22SBen Gras rm -f "$1"~ "$tmp" 122*5a645f22SBen Gras return 1 123*5a645f22SBen Gras fi 124*5a645f22SBen Gras 125*5a645f22SBen Gras # Use cp to overwrite the existing file preserving mode and owner 126*5a645f22SBen Gras # if possible. If the file is not writable, this will produce an 127*5a645f22SBen Gras # error. 128*5a645f22SBen Gras 129*5a645f22SBen Gras if header "$1" > "$tmp" && gzip -vc "$1" >> "$tmp"; then 130*5a645f22SBen Gras if ! cp "$tmp" "$1"; then 131*5a645f22SBen Gras echo "$prog: cannot copy $tmp to $1" 132*5a645f22SBen Gras rm -f "$tmp" 133*5a645f22SBen Gras return 1 134*5a645f22SBen Gras fi 135*5a645f22SBen Gras else 136*5a645f22SBen Gras echo "$prog: cannot compress $1" 137*5a645f22SBen Gras rm -f "$1"~ "$tmp" 138*5a645f22SBen Gras return 1 139*5a645f22SBen Gras fi 140*5a645f22SBen Gras} 141*5a645f22SBen Gras 142*5a645f22SBen Gras# Is the -d flag specified? 143*5a645f22SBen Grasdflag= 144*5a645f22SBen Gras 145*5a645f22SBen Gras# Return value 146*5a645f22SBen Grasrc=0 147*5a645f22SBen Gras 148*5a645f22SBen Grasif test "X$1" = X-d; then 149*5a645f22SBen Gras dflag=1 150*5a645f22SBen Gras shift 151*5a645f22SBen Grasfi 152*5a645f22SBen Gras 153*5a645f22SBen Grasprog=`basename "$0"` 154*5a645f22SBen GrasUSAGE="usage: $prog [-d] file ..." 155*5a645f22SBen Grasif test $# -eq 0; then 156*5a645f22SBen Gras echo $USAGE 157*5a645f22SBen Gras exit 1 158*5a645f22SBen Grasfi 159*5a645f22SBen Gras 160*5a645f22SBen Graswhile test $# -ne 0; do 161*5a645f22SBen Gras if test $dflag; then 162*5a645f22SBen Gras if ! compressed "$1"; then 163*5a645f22SBen Gras echo "$prog: $1 is not compressed" 164*5a645f22SBen Gras rc=1; 165*5a645f22SBen Gras elif ! decompress "$1"; then 166*5a645f22SBen Gras rc=$? 167*5a645f22SBen Gras fi 168*5a645f22SBen Gras else 169*5a645f22SBen Gras if compressed "$1"; then 170*5a645f22SBen Gras echo "$prog: $1 is already compressed" 171*5a645f22SBen Gras rc=1; 172*5a645f22SBen Gras elif ! check "$1" || ! compress "$1"; then 173*5a645f22SBen Gras rc=$? 174*5a645f22SBen Gras fi 175*5a645f22SBen Gras fi 176*5a645f22SBen Gras shift 177*5a645f22SBen Grasdone 178*5a645f22SBen Grasexit $rc 179