|
1 #!/bin/sh |
|
2 # |
|
3 # Makeself version 2.1.x |
|
4 # by Stephane Peter <megastep@megastep.org> |
|
5 # |
|
6 # $Id: makeself.sh,v 1.64 2008/01/04 23:52:14 megastep Exp $ |
|
7 # |
|
8 # Utility to create self-extracting tar.gz archives. |
|
9 # The resulting archive is a file holding the tar.gz archive with |
|
10 # a small Shell script stub that uncompresses the archive to a temporary |
|
11 # directory and then executes a given script from withing that directory. |
|
12 # |
|
13 # Makeself home page: http://www.megastep.org/makeself/ |
|
14 # |
|
15 # Version 2.0 is a rewrite of version 1.0 to make the code easier to read and maintain. |
|
16 # |
|
17 # Version history : |
|
18 # - 1.0 : Initial public release |
|
19 # - 1.1 : The archive can be passed parameters that will be passed on to |
|
20 # the embedded script, thanks to John C. Quillan |
|
21 # - 1.2 : Package distribution, bzip2 compression, more command line options, |
|
22 # support for non-temporary archives. Ideas thanks to Francois Petitjean |
|
23 # - 1.3 : More patches from Bjarni R. Einarsson and Francois Petitjean: |
|
24 # Support for no compression (--nocomp), script is no longer mandatory, |
|
25 # automatic launch in an xterm, optional verbose output, and -target |
|
26 # archive option to indicate where to extract the files. |
|
27 # - 1.4 : Improved UNIX compatibility (Francois Petitjean) |
|
28 # Automatic integrity checking, support of LSM files (Francois Petitjean) |
|
29 # - 1.5 : Many bugfixes. Optionally disable xterm spawning. |
|
30 # - 1.5.1 : More bugfixes, added archive options -list and -check. |
|
31 # - 1.5.2 : Cosmetic changes to inform the user of what's going on with big |
|
32 # archives (Quake III demo) |
|
33 # - 1.5.3 : Check for validity of the DISPLAY variable before launching an xterm. |
|
34 # More verbosity in xterms and check for embedded command's return value. |
|
35 # Bugfix for Debian 2.0 systems that have a different "print" command. |
|
36 # - 1.5.4 : Many bugfixes. Print out a message if the extraction failed. |
|
37 # - 1.5.5 : More bugfixes. Added support for SETUP_NOCHECK environment variable to |
|
38 # bypass checksum verification of archives. |
|
39 # - 1.6.0 : Compute MD5 checksums with the md5sum command (patch from Ryan Gordon) |
|
40 # - 2.0 : Brand new rewrite, cleaner architecture, separated header and UNIX ports. |
|
41 # - 2.0.1 : Added --copy |
|
42 # - 2.1.0 : Allow multiple tarballs to be stored in one archive, and incremental updates. |
|
43 # Added --nochown for archives |
|
44 # Stopped doing redundant checksums when not necesary |
|
45 # - 2.1.1 : Work around insane behavior from certain Linux distros with no 'uncompress' command |
|
46 # Cleaned up the code to handle error codes from compress. Simplified the extraction code. |
|
47 # - 2.1.2 : Some bug fixes. Use head -n to avoid problems. |
|
48 # - 2.1.3 : Bug fixes with command line when spawning terminals. |
|
49 # Added --tar for archives, allowing to give arbitrary arguments to tar on the contents of the archive. |
|
50 # Added --noexec to prevent execution of embedded scripts. |
|
51 # Added --nomd5 and --nocrc to avoid creating checksums in archives. |
|
52 # Added command used to create the archive in --info output. |
|
53 # Run the embedded script through eval. |
|
54 # - 2.1.4 : Fixed --info output. |
|
55 # Generate random directory name when extracting files to . to avoid problems. (Jason Trent) |
|
56 # Better handling of errors with wrong permissions for the directory containing the files. (Jason Trent) |
|
57 # Avoid some race conditions (Ludwig Nussel) |
|
58 # Unset the $CDPATH variable to avoid problems if it is set. (Debian) |
|
59 # Better handling of dot files in the archive directory. |
|
60 # - 2.1.5 : Made the md5sum detection consistent with the header code. |
|
61 # Check for the presence of the archive directory |
|
62 # Added --encrypt for symmetric encryption through gpg (Eric Windisch) |
|
63 # Added support for the digest command on Solaris 10 for MD5 checksums |
|
64 # Check for available disk space before extracting to the target directory (Andreas Schweitzer) |
|
65 # Allow extraction to run asynchronously (patch by Peter Hatch) |
|
66 # Use file descriptors internally to avoid error messages (patch by Kay Tiong Khoo) |
|
67 # |
|
68 # (C) 1998-2008 by Stéphane Peter <megastep@megastep.org> |
|
69 # |
|
70 # This software is released under the terms of the GNU GPL version 2 and above |
|
71 # Please read the license at http://www.gnu.org/copyleft/gpl.html |
|
72 # |
|
73 |
|
74 MS_VERSION=2.1.5 |
|
75 MS_COMMAND="$0" |
|
76 unset CDPATH |
|
77 |
|
78 for f in "${1+"$@"}"; do |
|
79 MS_COMMAND="$MS_COMMAND \\\\ |
|
80 \\\"$f\\\"" |
|
81 done |
|
82 |
|
83 # Procedures |
|
84 |
|
85 MS_Usage() |
|
86 { |
|
87 echo "Usage: $0 [params] archive_dir file_name label [startup_script] [args]" |
|
88 echo "params can be one or more of the following :" |
|
89 echo " --version | -v : Print out Makeself version number and exit" |
|
90 echo " --help | -h : Print out this help message" |
|
91 echo " --gzip : Compress using gzip (default if detected)" |
|
92 echo " --bzip2 : Compress using bzip2 instead of gzip" |
|
93 echo " --compress : Compress using the UNIX 'compress' command" |
|
94 echo " --nocomp : Do not compress the data" |
|
95 echo " --notemp : The archive will create archive_dir in the" |
|
96 echo " current directory and uncompress in ./archive_dir" |
|
97 echo " --copy : Upon extraction, the archive will first copy itself to" |
|
98 echo " a temporary directory" |
|
99 echo " --append : Append more files to an existing Makeself archive" |
|
100 echo " The label and startup scripts will then be ignored" |
|
101 echo " --current : Files will be extracted to the current directory." |
|
102 echo " Implies --notemp." |
|
103 echo " --nomd5 : Don't calculate an MD5 for archive" |
|
104 echo " --nocrc : Don't calculate a CRC for archive" |
|
105 echo " --header file : Specify location of the header script" |
|
106 echo " --follow : Follow the symlinks in the archive" |
|
107 echo " --nox11 : Disable automatic spawn of a xterm" |
|
108 echo " --nowait : Do not wait for user input after executing embedded" |
|
109 echo " program from an xterm" |
|
110 echo " --lsm file : LSM file describing the package" |
|
111 echo |
|
112 echo "Do not forget to give a fully qualified startup script name" |
|
113 echo "(i.e. with a ./ prefix if inside the archive)." |
|
114 exit 1 |
|
115 } |
|
116 |
|
117 # Default settings |
|
118 if type gzip 2>&1 > /dev/null; then |
|
119 COMPRESS=gzip |
|
120 else |
|
121 COMPRESS=Unix |
|
122 fi |
|
123 KEEP=n |
|
124 CURRENT=n |
|
125 NOX11=n |
|
126 APPEND=n |
|
127 COPY=none |
|
128 TAR_ARGS=cvf |
|
129 HEADER=`dirname $0`/makeself-header.sh |
|
130 |
|
131 # LSM file stuff |
|
132 LSM_CMD="echo No LSM. >> \"\$archname\"" |
|
133 |
|
134 while true |
|
135 do |
|
136 case "$1" in |
|
137 --version | -v) |
|
138 echo Makeself version $MS_VERSION |
|
139 exit 0 |
|
140 ;; |
|
141 --bzip2) |
|
142 COMPRESS=bzip2 |
|
143 shift |
|
144 ;; |
|
145 --gzip) |
|
146 COMPRESS=gzip |
|
147 shift |
|
148 ;; |
|
149 --compress) |
|
150 COMPRESS=Unix |
|
151 shift |
|
152 ;; |
|
153 --encrypt) |
|
154 COMPRESS=gpg |
|
155 shift |
|
156 ;; |
|
157 --nocomp) |
|
158 COMPRESS=none |
|
159 shift |
|
160 ;; |
|
161 --notemp) |
|
162 KEEP=y |
|
163 shift |
|
164 ;; |
|
165 --copy) |
|
166 COPY=copy |
|
167 shift |
|
168 ;; |
|
169 --current) |
|
170 CURRENT=y |
|
171 KEEP=y |
|
172 shift |
|
173 ;; |
|
174 --header) |
|
175 HEADER="$2" |
|
176 shift 2 |
|
177 ;; |
|
178 --follow) |
|
179 TAR_ARGS=cvfh |
|
180 shift |
|
181 ;; |
|
182 --nox11) |
|
183 NOX11=y |
|
184 shift |
|
185 ;; |
|
186 --nowait) |
|
187 shift |
|
188 ;; |
|
189 --nomd5) |
|
190 NOMD5=y |
|
191 shift |
|
192 ;; |
|
193 --nocrc) |
|
194 NOCRC=y |
|
195 shift |
|
196 ;; |
|
197 --append) |
|
198 APPEND=y |
|
199 shift |
|
200 ;; |
|
201 --lsm) |
|
202 LSM_CMD="cat \"$2\" >> \"\$archname\"" |
|
203 shift 2 |
|
204 ;; |
|
205 -h | --help) |
|
206 MS_Usage |
|
207 ;; |
|
208 -*) |
|
209 echo Unrecognized flag : "$1" |
|
210 MS_Usage |
|
211 ;; |
|
212 *) |
|
213 break |
|
214 ;; |
|
215 esac |
|
216 done |
|
217 |
|
218 if test $# -lt 1; then |
|
219 MS_Usage |
|
220 else |
|
221 if test -d "$1"; then |
|
222 archdir="$1" |
|
223 else |
|
224 echo "Directory $1 does not exist." |
|
225 exit 1 |
|
226 fi |
|
227 fi |
|
228 archname="$2" |
|
229 |
|
230 if test "$APPEND" = y; then |
|
231 if test $# -lt 2; then |
|
232 MS_Usage |
|
233 fi |
|
234 |
|
235 # Gather the info from the original archive |
|
236 OLDENV=`sh "$archname" --dumpconf` |
|
237 if test $? -ne 0; then |
|
238 echo "Unable to update archive: $archname" >&2 |
|
239 exit 1 |
|
240 else |
|
241 eval "$OLDENV" |
|
242 fi |
|
243 else |
|
244 if test "$KEEP" = n -a $# = 3; then |
|
245 echo "ERROR: Making a temporary archive with no embedded command does not make sense!" >&2 |
|
246 echo |
|
247 MS_Usage |
|
248 fi |
|
249 # We don't really want to create an absolute directory... |
|
250 if test "$CURRENT" = y; then |
|
251 archdirname="." |
|
252 else |
|
253 archdirname=`basename "$1"` |
|
254 fi |
|
255 |
|
256 if test $# -lt 3; then |
|
257 MS_Usage |
|
258 fi |
|
259 |
|
260 LABEL="$3" |
|
261 SCRIPT="$4" |
|
262 test x$SCRIPT = x || shift 1 |
|
263 shift 3 |
|
264 SCRIPTARGS="$*" |
|
265 fi |
|
266 |
|
267 if test "$KEEP" = n -a "$CURRENT" = y; then |
|
268 echo "ERROR: It is A VERY DANGEROUS IDEA to try to combine --notemp and --current." >&2 |
|
269 exit 1 |
|
270 fi |
|
271 |
|
272 case $COMPRESS in |
|
273 gzip) |
|
274 GZIP_CMD="gzip -c9" |
|
275 GUNZIP_CMD="gzip -cd" |
|
276 ;; |
|
277 bzip2) |
|
278 GZIP_CMD="bzip2 -9" |
|
279 GUNZIP_CMD="bzip2 -d" |
|
280 ;; |
|
281 gpg) |
|
282 GZIP_CMD="gpg -ac -z9" |
|
283 GUNZIP_CMD="gpg -d" |
|
284 ;; |
|
285 Unix) |
|
286 GZIP_CMD="compress -cf" |
|
287 GUNZIP_CMD="exec 2>&-; uncompress -c || test \\\$? -eq 2 || gzip -cd" |
|
288 ;; |
|
289 none) |
|
290 GZIP_CMD="cat" |
|
291 GUNZIP_CMD="cat" |
|
292 ;; |
|
293 esac |
|
294 |
|
295 tmpfile="${TMPDIR:=/tmp}/mkself$$" |
|
296 |
|
297 if test -f $HEADER; then |
|
298 oldarchname="$archname" |
|
299 archname="$tmpfile" |
|
300 # Generate a fake header to count its lines |
|
301 SKIP=0 |
|
302 . $HEADER |
|
303 SKIP=`cat "$tmpfile" |wc -l` |
|
304 # Get rid of any spaces |
|
305 SKIP=`expr $SKIP` |
|
306 rm -f "$tmpfile" |
|
307 echo Header is $SKIP lines long >&2 |
|
308 |
|
309 archname="$oldarchname" |
|
310 else |
|
311 echo "Unable to open header file: $HEADER" >&2 |
|
312 exit 1 |
|
313 fi |
|
314 |
|
315 echo |
|
316 |
|
317 if test "$APPEND" = n; then |
|
318 if test -f "$archname"; then |
|
319 echo "WARNING: Overwriting existing file: $archname" >&2 |
|
320 fi |
|
321 fi |
|
322 |
|
323 USIZE=`du -ks $archdir | cut -f1` |
|
324 DATE=`LC_ALL=C date` |
|
325 |
|
326 if test "." = "$archdirname"; then |
|
327 if test "$KEEP" = n; then |
|
328 archdirname="makeself-$$-`date +%Y%m%d%H%M%S`" |
|
329 fi |
|
330 fi |
|
331 |
|
332 test -d "$archdir" || { echo "Error: $archdir does not exist."; rm -f "$tmpfile"; exit 1; } |
|
333 echo About to compress $USIZE KB of data... |
|
334 echo Adding files to archive named \"$archname\"... |
|
335 exec 3<> "$tmpfile" |
|
336 (cd "$archdir" && ( tar $TAR_ARGS - . | eval "$GZIP_CMD" >&3 ) ) || { echo Aborting: Archive directory not found or temporary file: "$tmpfile" could not be created.; exec 3>&-; rm -f "$tmpfile"; exit 1; } |
|
337 exec 3>&- # try to close the archive |
|
338 |
|
339 fsize=`cat "$tmpfile" | wc -c | tr -d " "` |
|
340 |
|
341 # Compute the checksums |
|
342 |
|
343 md5sum=00000000000000000000000000000000 |
|
344 crcsum=0000000000 |
|
345 |
|
346 if test "$NOCRC" = y; then |
|
347 echo "skipping crc at user request" |
|
348 else |
|
349 crcsum=`cat "$tmpfile" | CMD_ENV=xpg4 cksum | sed -e 's/ /Z/' -e 's/ /Z/' | cut -dZ -f1` |
|
350 echo "CRC: $crcsum" |
|
351 fi |
|
352 |
|
353 if test "$NOMD5" = y; then |
|
354 echo "skipping md5sum at user request" |
|
355 else |
|
356 # Try to locate a MD5 binary |
|
357 OLD_PATH=$PATH |
|
358 PATH=${GUESS_MD5_PATH:-"$OLD_PATH:/bin:/usr/bin:/sbin:/usr/local/ssl/bin:/usr/local/bin:/opt/openssl/bin"} |
|
359 MD5_ARG="" |
|
360 MD5_PATH=`exec <&- 2>&-; which md5sum || type md5sum` |
|
361 test -x $MD5_PATH || MD5_PATH=`exec <&- 2>&-; which md5 || type md5` |
|
362 test -x $MD5_PATH || MD5_PATH=`exec <&- 2>&-; which digest || type digest` |
|
363 PATH=$OLD_PATH |
|
364 if test `basename $MD5_PATH` = digest; then |
|
365 MD5_ARG="-a md5" |
|
366 fi |
|
367 if test -x "$MD5_PATH"; then |
|
368 md5sum=`cat "$tmpfile" | eval "$MD5_PATH $MD5_ARG" | cut -b-32`; |
|
369 echo "MD5: $md5sum" |
|
370 else |
|
371 echo "MD5: none, MD5 command not found" |
|
372 fi |
|
373 fi |
|
374 |
|
375 if test "$APPEND" = y; then |
|
376 mv "$archname" "$archname".bak || exit |
|
377 |
|
378 # Prepare entry for new archive |
|
379 filesizes="$filesizes $fsize" |
|
380 CRCsum="$CRCsum $crcsum" |
|
381 MD5sum="$MD5sum $md5sum" |
|
382 USIZE=`expr $USIZE + $OLDUSIZE` |
|
383 # Generate the header |
|
384 . $HEADER |
|
385 # Append the original data |
|
386 tail -n +$OLDSKIP "$archname".bak >> "$archname" |
|
387 # Append the new data |
|
388 cat "$tmpfile" >> "$archname" |
|
389 |
|
390 chmod +x "$archname" |
|
391 rm -f "$archname".bak |
|
392 echo Self-extractible archive \"$archname\" successfully updated. |
|
393 else |
|
394 filesizes="$fsize" |
|
395 CRCsum="$crcsum" |
|
396 MD5sum="$md5sum" |
|
397 |
|
398 # Generate the header |
|
399 . $HEADER |
|
400 |
|
401 # Append the compressed tar data after the stub |
|
402 echo |
|
403 cat "$tmpfile" >> "$archname" |
|
404 chmod +x "$archname" |
|
405 echo Self-extractible archive \"$archname\" successfully created. |
|
406 fi |
|
407 rm -f "$tmpfile" |