File: shar.sh

package info (click to toggle)
sharutils 1:4.2-6
  • links: PTS
  • area: main
  • in suites: hamm
  • size: 1,436 kB
  • ctags: 587
  • sloc: ansic: 6,313; perl: 1,742; makefile: 563; sh: 495; pascal: 293; sed: 93
file content (176 lines) | stat: -rw-r--r-- 4,557 bytes parent folder | download | duplicates (7)
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#!/bin/sh
# UNISRC_ID: @(#)shar.sh	27.1	84/12/17  
: Make a shell archive package

# Usage: $0 [-b] [-c] [-t] [-v] files... > package
# See the manual entry for details.


# Initialize:

diagnostic='eval echo >&2'	# diagnostics to stderr by default.
trap '$diagnostic "$0: quitting early"; exit 1' 1 2 3 15
base_option=FALSE		# use pathnames, not basenames.
check_option=FALSE		# don't generate integrity check.
USAGE='Usage: $0 \[-b] \[-c] \[-t] \[-v] files... \> package'


# Extract and digest options, if any:
#
# Un-comment the "-)" line below to treat single dashes as a no-op.
# Commented means single dashes elicit a usage diagnostic.

while [ -n "$1" ]	# while there are more arguments,
do			# digest them; stop when you find a non-option.
	case "$1" in
	-b)	base_option=TRUE;	shift;;
	-c)	check_option=TRUE;	shift;;
	-v)	verbose=TRUE;		shift;;
	-t)	verbose=TRUE; diagnostic='eval echo >/dev/tty'; shift;;
###	-)	shift;;		# if uncommented, eat single dashes.
	-*)	$diagnostic $USAGE; exit 1;;	 # die at illegal options.
	*)	break;;		# non-option found.
	esac
done


# Check remaining arguments, which should be just a list of files:

if [ $# = 0 ]
then	# no arguments left!
	$diagnostic $USAGE
	exit 1
fi


# Check the cupboard to see if the ingredients are all there:

contents=''	# no files so far.
contdirs=''	# no directories so far.

for arg		# for all files specified,
do		# establish the archive name.
	if [ -f "$arg" ]
	then	# file exists and is not a directory.
		case $base_option in
		TRUE)	unpack_name=`basename "$arg"` ;;
		FALSE)	unpack_name="$arg" ;;
		esac

		contents="$contents $unpack_name"

	elif [ -d "$arg" ]
	then	# file exists and is a directory.
		case $base_option in
		TRUE)   $diagnostic '$0: cannot archive directory "$arg" with -b option.'
			exit 1 ;;
		FALSE)  contdirs="$contdirs $arg/ " ;;
		esac

	else	# not a plain file and not a directory.
		$diagnostic '$0: cannot archive "$arg"'
		exit 1
	fi
done


# Emit the prologue:
# (The leading newline is for those who type csh instead of sh.)

cat <<!!!

# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by `who am i | sed 's/[ 	].*//'` on `date`
!!!


# Emit the list of ingredients:

# Simple version (breaks if you shar lots of files at once):
#	echo "# Contents: $contdirs$contents"
#
# Complex and cosmetic version to pack contents list onto lines that fit on
# one terminal line ("expr string : .*" prints the length of the string):

MAX=80
line='# Contents: '
for item in $contdirs $contents
do
	if [ `expr "$line" : '.*' + 1 + "$item" : '.*'` -lt $MAX ]
	then	# length of old line + new item is short enough,
		line="$line $item"	# so just append it.

	else	# new element makes line too long,
		echo "$line"		# so put it on a new line.
		line="#	$item"		# start a new line.
		MAX=74			# compensate for tab width.
	fi
done

echo "$line"
echo " "


# Emit the files and their separators:

for arg
do
	# Decide which name to archive under.
	case $base_option in
	TRUE)   unpack_name=`basename "$arg"`
		test $verbose && $diagnostic "a - $unpack_name [from $arg]" ;;
	FALSE)  unpack_name="$arg"
		test $verbose && $diagnostic "a - $arg" ;;
	esac

	# Emit either a mkdir or a cat/sed to extract the file.
	if [ -d "$arg" ]
	then
		echo "echo mkdir - $arg"
		echo "mkdir $arg"
	else
		echo "echo x - $unpack_name"
		separator="@//E*O*F $unpack_name//"
		echo "sed 's/^@//' > \"$unpack_name\" <<'$separator'"
		sed  -e 's/^[.~@]/@&/'  -e 's/^From/@&/'  "$arg"
		echo $separator
	fi

	# Emit chmod to set permissions on the extracted file;
	# this keels over if the filename contains "?".
	ls -ld $arg | sed \
		-e 's/^.\(...\)\(...\)\(...\).*/u=\1,g=\2,o=\3/' \
		-e 's/-//g' \
		-e 's?.*?chmod & '"$unpack_name?"
	echo " "
done


# If the -c option was given, emit the checking epilogue:
# (The sed script converts files to basenames so it works regardless of -b.)

if [ $check_option = TRUE ]
then
	echo 'echo Inspecting for damage in transit...'
	echo 'temp=/tmp/shar$$; dtemp=/tmp/.shar$$'
	echo 'trap "rm -f $temp $dtemp; exit" 0 1 2 3 15'
	echo 'cat > $temp <<\!!!'
	case $base_option in
	TRUE)   wc $@ | sed 's=[^ ]*/=='	;;
	FALSE)  wc $contents | sed 's=[^ ]*/=='	;;
	esac
	echo '!!!'
	echo "wc $contents | sed 's=[^ ]*/==' | "'diff -b $temp - >$dtemp'
	echo 'if [ -s $dtemp ]'
	echo 'then echo "Ouch [diff of wc output]:" ; cat $dtemp'
	echo 'else echo "No problems found."'
	echo 'fi'
fi


# Finish up:

echo 'exit 0'	# sharchives unpack even if junk follows.
exit 0