natPlainSocketImplPosix.cc (bind): Clear SockAddr before using - needed for OS X...
[gcc.git] / libjava / scripts / jar.in
1 #! @SHELL@
2 # Copyright (C) 2006 Free Software Foundation
3 # Written by Paolo Bonzini.
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published
7 # by the Free Software Foundation; either version 2 of the License,
8 # or (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 # for more details.
14 #
15 # You should have received a copy of the GNU General Public License along
16 # with this program; if not, write to the Free Software Foundation, Inc.,
17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
19
20 # POSIX and NLS nuisances, taken from autoconf.
21 if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
22 emulate sh
23 NULLCMD=:
24 # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
25 # is contrary to our usage. Disable this feature.
26 alias -g '${1+"$@"}'='"$@"'
27 setopt NO_GLOB_SUBST
28 else
29 case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
30 fi
31 BIN_SH=xpg4; export BIN_SH # for Tru64
32 DUALCASE=1; export DUALCASE # for MKS sh
33
34 if test "${LANG+set}" = set; then LANG=C; export LANG; fi
35 if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
36 if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
37 if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
38
39 # Also make sure CDPATH is empty, and IFS is space, tab, \n in that order.
40 # Be careful to avoid that editors munge IFS
41 (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
42 IFS=" "" ""
43 "
44
45 : ${TMPDIR=/tmp}
46 : ${ZIP="@ZIP@"}
47 : ${UNZIP="@UNZIP@"}
48 progname="$0"
49
50 # Emit a usage message and exit with error status 1
51 usage () {
52 cat >&2 <<EOF
53 Usage: $0 {ctxu}[vfm0Mi@] [jar-file] [manifest-file] {[-C dir] files} ...
54 Options:
55 -c create new archive
56 -t list table of contents for archive
57 -x extract named (or all) files from archive
58 -u update existing archive
59 -v generate verbose output on standard output
60 -f specify archive file name
61 -m include manifest information from specified manifest file
62 -0 store only; use no ZIP compression
63 -M do not create a manifest file for the entries
64 -i generate index information for the specified jar files
65 -@ instead of {[-C dir] files} ... accept one or more response files,
66 each containing one command-line argument
67 -C change to the specified directory and include the following file
68 If any file is a directory then it is processed recursively.
69 The manifest file name and the archive file name needs to be specified
70 in the same order the 'm' and 'f' flags are specified.
71
72 Example 1: to archive two class files into an archive called classes.jar:
73 jar cvf classes.jar Foo.class Bar.class
74 Example 2: use an existing manifest file 'mymanifest' and archive all the
75 files in the foo/ directory into 'classes.jar':
76 jar cvfm classes.jar mymanifest -C foo/ .
77
78 EOF
79 (exit 1); exit 1
80 }
81
82 # Emit an error message and exit with error status 1
83 error () {
84 echo "$progname: $*" >&2
85 (exit 1); exit 1
86 }
87
88 # Usage: copy SRC DEST
89 # Copy file SRC to directory DEST, which is the staging area of the jar file.
90 # Fail if it is already present or if it is not a regular file.
91 copy () {
92 if test -f "$1"; then
93 # A simple optimization. Optimistically assuming that ln will work
94 # cuts 60% of the run-time!
95 if ln "$1" "$2"/"$1" > /dev/null 2>&1; then
96 return 0
97 fi
98
99 if test -e "$2"/"$1"; then
100 error "$1": Duplicate entry.
101 fi
102 dir=`dirname "$1"`
103 $mkdir_p "$2"/"$dir"
104 ln "$1" "$2"/"$1" > /dev/null 2>&1 || cp "$1" "$2"/"$1"
105 elif test -e "$1"; then
106 error "$1": Invalid file type.
107 else
108 error "$1": File not found.
109 fi
110 }
111
112 # Make a temporary directory and store its name in the JARTMP variable.
113 make_tmp () {
114 test -n "$JARTMP" && return
115
116 {
117 JARTMP=`(umask 077 && mktemp -d "$TMPDIR/jarXXXXXX") 2>/dev/null` &&
118 test -n "$JARTMP" && test -d "$JARTMP"
119 } || {
120 JARTMP=$TMPDIR/jar$$-$RANDOM
121 (umask 077 && mkdir "$JARTMP")
122 } || exit $?
123
124 trap 'exit_status=$?
125 if test -n "$JARTMP"; then rm -rf "$JARTMP"; fi
126 exit $exit_status' 0
127 }
128
129 # Usage: make_manifest destfile kind [source-manifest]
130 # Create a manifest file and store it in destfile. KIND can be "default",
131 # or "user", in which case SOURCE-MANIFEST must be specified as well.
132 make_manifest () {
133 dir=`dirname "$1"`
134 $mkdir_p "$dir"
135 case $2 in
136 default)
137 cat > "$1" <<\EOF
138 Manifest-Version: 1.0
139 Created-By: @VERSION@
140
141 EOF
142 ;;
143 user)
144 cp "$3" "$1"
145 ;;
146 esac
147 }
148
149 # Usage: set_var var [value]
150 # Exit with an error if set_var was already called for the same VAR. Else
151 # set the variable VAR to the value VALUE (or the empty value if no parameter
152 # is given).
153 set_var () {
154 if eval test x\$set_$1 = xset; then
155 error Incompatible or repeated options.
156 else
157 eval $1=\$2
158 eval set_$1=set
159 fi
160 }
161
162 # Process the arguments, including -C options, and copy the whole tree
163 # to $JARTMP/files so that zip can be invoked later from there.
164 make_files () {
165 change=false
166 if $process_response_files; then
167 if test $# = 0; then
168 while read arg; do
169 make_files_1 "$arg"
170 done
171 else
172 for infile
173 do
174 exec 5<&0
175 exec 0< $infile
176 while read arg; do
177 make_files_1 "$arg"
178 done
179 exec 0<&5
180 exec 5<&-
181 done
182 fi
183 else
184 for arg
185 do
186 make_files_1 "$arg"
187 done
188 fi
189 cd "$old_dir"
190 }
191
192 # Usage: make_files_1 ARG
193 # Process one argument, ARG.
194 make_files_1 () {
195 if $change; then
196 change=false
197 if cd "$1"; then
198 return
199 else
200 (exit 1); exit 1
201 fi
202 fi
203 case "$1" in
204 -C)
205 change=:
206 ;;
207 -C*)
208 cd `expr "$1" : '-C\(.*\)' `
209 return
210 ;;
211 *)
212 if test -d "$1"; then
213 $mkdir_p "$JARTMP"/files/"$1"
214 find "$1" | while read file; do
215 if test -d "$file"; then
216 $mkdir_p "$JARTMP"/files/"$file"
217 else
218 copy "$file" "$JARTMP"/files
219 fi
220 done
221 else
222 copy "$1" "$JARTMP"/files
223 fi
224 ;;
225 esac
226 cd "$old_dir"
227 }
228
229 # Same as "jar tf $1".
230 jar_list () {
231 $UNZIP -l "$1" | \
232 sed '1,/^ ----/d;/^ ----/,$d;s/^ *[0-9]* ..-..-.. ..:.. //'
233 }
234
235 # Same as "jar tvf $1".
236 jar_list_verbose () {
237 $UNZIP -l "$1" | \
238 @AWK@ 'BEGIN { yes = 0 }
239 /^ ----/ { yes = !yes; next }
240 yes {
241 size=$1
242 split ($2, d, "-")
243 split ($3, t, ":")
244 d[3] += (d[3] < 80) ? 2000 : 1900
245 timestamp=d[3] " " d[1] " " d[2] " " t[1] " " t[2] " 00"
246 gsub (/^ *[0-9]* ..-..-.. ..:.. /, "")
247 printf "%6d %s %s\n", size, strftime ("%a %b %d %H:%M:%S %Z %Y", mktime (timestamp)), $0
248 }'
249 }
250
251 # mkdir -p emulation based on the mkinstalldirs script.
252 mkdir_p ()
253 {
254 for file
255 do
256 case $file in
257 /*) pathcomp=/ ;;
258 *) pathcomp= ;;
259 esac
260 oIFS=$IFS
261 IFS=/
262 set fnord $file
263 shift
264 IFS=$oIFS
265
266 errstatus=0
267 for d
268 do
269 test "x$d" = x && continue
270 pathcomp=$pathcomp$d
271 case $pathcomp in
272 -*) pathcomp=./$pathcomp ;;
273 esac
274
275 if test ! -d "$pathcomp"; then
276 mkdir "$pathcomp" || lasterr=$?
277 test -d "$pathcomp" || errstatus=$lasterr
278 fi
279 pathcomp=$pathcomp/
280 done
281 done
282 return "$errstatus"
283 }
284
285 # Detect mkdir -p
286 # On NextStep and OpenStep, the `mkdir' command does not
287 # recognize any option. It will interpret all options as
288 # directories to create, and then abort because `.' already
289 # exists.
290 if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
291 mkdir_p='mkdir -p'
292 else
293 mkdir_p='mkdir_p'
294 test -d ./-p && rmdir ./-p
295 test -d ./--version && rmdir ./--version
296 fi
297
298 # Process the first command line option.
299 case "$1" in
300 -*) commands=`echo X"$1" | sed 's/^X-//' ` ;;
301 *) commands="$1"
302 esac
303 shift
304
305 # Operation to perform on the JAR file
306 mode=unknown
307
308 # First -C option on the command line
309 cur_dir=.
310
311 # Base directory for -C options
312 old_dir=`pwd`
313 # JAR file to operate on
314 jarfile=
315
316 # default for no {m,M} option, user for "m" option, none for "M" option
317 manifest_kind=default
318
319 # "-0" if the "0" option was given
320 store=
321
322 # true if the "v" option was given
323 verbose=false
324
325 # true if the non-standard "@" option was given
326 process_response_files=false
327
328 # An exec command if we need to redirect the zip/unzip commands' output
329 out_redirect=:
330
331 while test -n "$commands"; do
332 # Process a letter at a time
333 command=`expr "$commands" : '\(.\)'`
334 commands=`expr "$commands" : '.\(.*\)'`
335 case "$command" in
336 c)
337 set_var mode create
338 ;;
339 t)
340 set_var mode list
341 ;;
342 x)
343 set_var mode extract
344 ;;
345 u)
346 set_var mode update
347 ;;
348
349 f)
350 test $# = 0 && usage
351 # Multiple "f" options are accepted by Sun's JAR tool.
352 jarfile="$1"
353 test -z "$jarfile" && usage
354 shift
355 ;;
356 m)
357 test $# = 0 && usage
358 # Multiple "m" options are accepted by Sun's JAR tool, but
359 # M always overrides m.
360 test "$manifest_kind" = default && manifest_kind=user
361 manifest_file="$1"
362 test -z "$manifest_file" && usage
363 shift
364 ;;
365 0)
366 store=-0
367 ;;
368 v)
369 verbose=:
370 ;;
371 i)
372 # Not yet implemented, and probably never will.
373 ;;
374 M)
375 manifest_kind=none
376 ;;
377 C)
378 test $# = 0 && usage
379 cur_dir="$1"
380 shift
381 ;;
382 @)
383 process_response_files=: ;;
384 *)
385 usage ;;
386 esac
387 done
388
389 set -e
390
391 case "X$jarfile" in
392 X)
393 # Work on stdin/stdout. Messages go to stderr, and if we need an input
394 # JAR file we save it temporarily in the temporary directory.
395 make_tmp
396 $mkdir_p "$JARTMP"/out
397 jarfile="$JARTMP"/out/tmp-stdin.jar
398 out_redirect='exec >&2'
399 case $mode in
400 update|extract|list)
401 if $process_response_files && test $# = 0; then
402 error Cannot use stdin for response file.
403 fi
404 cat > "$JARTMP"/out/tmp-stdin.jar
405 ;;
406 esac
407 ;;
408
409 X*/*)
410 # Make an absolute path.
411 dir=`dirname "$jarfile"`
412 jarfile=`cd $dir && pwd`/`basename "$jarfile"`
413 ;;
414
415 X*)
416 # Make an absolute path from a filename in the current directory.
417 jarfile=`pwd`/`basename "$jarfile"`
418 ;;
419 esac
420
421 # Perform a -C option if given right away.
422 cd "$cur_dir"
423
424 case $mode in
425 unknown)
426 usage
427 ;;
428
429 extract)
430 make_tmp
431
432 # Extract the list of files in the JAR file
433 jar_list "$jarfile" > "$JARTMP"/list
434
435 # If there are files on the command line, expand directories and skip -C
436 # command line arguments
437 for arg
438 do
439 if $skip; then
440 skip=false
441 continue
442 fi
443 case "$arg" in
444 -C) skip=: ;;
445 -C*) ;;
446 *)
447 escaped=`echo "X$arg" | sed 's/^X//; s/[].[^$\\*]/\\\\&/g' `
448 grep "^$escaped/" "$JARTMP"/list >> "$JARTMP"/chosen || :
449 grep "^$escaped\$" "$JARTMP"/list >> "$JARTMP"/chosen || :
450 esac
451 done
452 test -f "$JARTMP"/chosen || cp "$JARTMP"/list "$JARTMP"/chosen
453
454 # Really execute unzip
455 if $verbose; then
456 sort < "$JARTMP"/chosen | uniq | xargs $UNZIP -o "$jarfile" | \
457 sed -ne 's/^ creating/ created/p' -e 's/^ inflating/extracted/p'
458 else
459 sort < "$JARTMP"/chosen | uniq | xargs $UNZIP -o "$jarfile" > /dev/null
460 fi
461 ;;
462
463 create)
464 make_tmp
465 $mkdir_p "$JARTMP"/out
466 $mkdir_p "$JARTMP"/files
467
468 # Do not overwrite the JAR file if something goes wrong
469 tmp_jarfile="$JARTMP"/out/`basename "$jarfile"`
470
471 # Prepare the files in the temporary directory. This is necessary to
472 # support -C and still save relative paths in the JAR file.
473 make_files ${1+"$@"}
474 if test $manifest_kind != none; then
475 make_manifest "$JARTMP"/files/META-INF/MANIFEST.MF $manifest_kind "$manifest_file"
476 fi
477
478 # Really execute zip
479 if $verbose; then
480 (eval $out_redirect; cd "$JARTMP"/files && $ZIP -rv "$tmp_jarfile" $store .)
481 else
482 (cd "$JARTMP/files" && $ZIP -r "$tmp_jarfile" $store . > /dev/null)
483 fi
484 test "$jarfile" = "$tmp_jarfile" || mv "$tmp_jarfile" "$jarfile"
485 ;;
486
487 update)
488 make_tmp
489 $mkdir_p "$JARTMP"/files
490 make_files ${1+"$@"}
491
492 # Same as above, but zip takes care of not overwriting the file
493 case $manifest_kind in
494 none)
495 $verbose && (eval $out_redirect; echo removing manifest)
496 $ZIP -d "$jarfile" META-INF/MANIFEST.MF > /dev/null 2>&1 || :
497 ;;
498 *)
499 make_manifest "$JARTMP"/files/META-INF/MANIFEST.MF $manifest_kind "$manifest_file"
500 ;;
501 esac
502 if $verbose; then
503 (eval $out_redirect; cd "$JARTMP"/files && $ZIP -ruv "$jarfile" $store .)
504 else
505 (cd "$JARTMP"/files && $ZIP -ru "$jarfile" $store . > /dev/null)
506 fi
507 ;;
508
509 list)
510 # Everything's done in the functions
511 if $verbose; then
512 jar_list_verbose "$jarfile"
513 else
514 jar_list "$jarfile"
515 fi ;;
516 esac
517
518 if test "$out_redirect" != :; then
519 # Cat back to stdout if necessary
520 case $mode in
521 create|update) cat "$JARTMP"/out/tmp-stdin.jar ;;
522 esac
523 fi
524 exit 0