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