123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524 |
- #! @SHELL@
- # Copyright (C) 2006 Free Software Foundation
- # Written by Paolo Bonzini.
- #
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published
- # by the Free Software Foundation; either version 2 of the License,
- # or (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful, but
- # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- # for more details.
- #
- # You should have received a copy of the GNU General Public License along
- # with this program; if not, write to the Free Software Foundation, Inc.,
- # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- # POSIX and NLS nuisances, taken from autoconf.
- if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
- emulate sh
- NULLCMD=:
- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
- else
- case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
- fi
- BIN_SH=xpg4; export BIN_SH # for Tru64
- DUALCASE=1; export DUALCASE # for MKS sh
- if test "${LANG+set}" = set; then LANG=C; export LANG; fi
- if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
- if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
- if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
- # Also make sure CDPATH is empty, and IFS is space, tab, \n in that order.
- # Be careful to avoid that editors munge IFS
- (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
- IFS=" "" ""
- "
- : ${TMPDIR=/tmp}
- : ${ZIP="@ZIP@"}
- : ${UNZIP="@UNZIP@"}
- progname="$0"
- # Emit a usage message and exit with error status 1
- usage () {
- cat >&2 <<EOF
- Usage: $0 {ctxu}[vfm0Mi@] [jar-file] [manifest-file] {[-C dir] files} ...
- Options:
- -c create new archive
- -t list table of contents for archive
- -x extract named (or all) files from archive
- -u update existing archive
- -v generate verbose output on standard output
- -f specify archive file name
- -m include manifest information from specified manifest file
- -0 store only; use no ZIP compression
- -M do not create a manifest file for the entries
- -i generate index information for the specified jar files
- -@ instead of {[-C dir] files} ... accept one or more response files,
- each containing one command-line argument
- -C change to the specified directory and include the following file
- If any file is a directory then it is processed recursively.
- The manifest file name and the archive file name needs to be specified
- in the same order the 'm' and 'f' flags are specified.
- Example 1: to archive two class files into an archive called classes.jar:
- jar cvf classes.jar Foo.class Bar.class
- Example 2: use an existing manifest file 'mymanifest' and archive all the
- files in the foo/ directory into 'classes.jar':
- jar cvfm classes.jar mymanifest -C foo/ .
- EOF
- (exit 1); exit 1
- }
- # Emit an error message and exit with error status 1
- error () {
- echo "$progname: $*" >&2
- (exit 1); exit 1
- }
- # Usage: copy SRC DEST
- # Copy file SRC to directory DEST, which is the staging area of the jar file.
- # Fail if it is already present or if it is not a regular file.
- copy () {
- if test -f "$1"; then
- # A simple optimization. Optimistically assuming that ln will work
- # cuts 60% of the run-time!
- if ln "$1" "$2"/"$1" > /dev/null 2>&1; then
- return 0
- fi
- if test -f "$2"/"$1"; then
- error "$1": Duplicate entry.
- fi
- dir=`dirname "$1"`
- $mkdir_p "$2"/"$dir"
- ln "$1" "$2"/"$1" > /dev/null 2>&1 || cp "$1" "$2"/"$1"
- elif test -e "$1"; then
- error "$1": Invalid file type.
- else
- error "$1": File not found.
- fi
- }
- # Make a temporary directory and store its name in the JARTMP variable.
- make_tmp () {
- test -n "$JARTMP" && return
- {
- JARTMP=`(umask 077 && mktemp -d "$TMPDIR/jarXXXXXX") 2>/dev/null` &&
- test -n "$JARTMP" && test -d "$JARTMP"
- } || {
- JARTMP=$TMPDIR/jar$$-$RANDOM
- (umask 077 && mkdir "$JARTMP")
- } || exit $?
- trap 'exit_status=$?
- if test -n "$JARTMP"; then rm -rf "$JARTMP"; fi
- exit $exit_status' 0
- }
- # Usage: make_manifest destfile kind [source-manifest]
- # Create a manifest file and store it in destfile. KIND can be "default",
- # or "user", in which case SOURCE-MANIFEST must be specified as well.
- make_manifest () {
- dir=`dirname "$1"`
- $mkdir_p "$dir"
- case $2 in
- default)
- cat > "$1" <<\EOF
- Manifest-Version: 1.0
- Created-By: @VERSION@
- EOF
- ;;
- user)
- cp "$3" "$1"
- ;;
- esac
- }
- # Usage: set_var var [value]
- # Exit with an error if set_var was already called for the same VAR. Else
- # set the variable VAR to the value VALUE (or the empty value if no parameter
- # is given).
- set_var () {
- if eval test x\$set_$1 = xset; then
- error Incompatible or repeated options.
- else
- eval $1=\$2
- eval set_$1=set
- fi
- }
- # Process the arguments, including -C options, and copy the whole tree
- # to $JARTMP/files so that zip can be invoked later from there.
- make_files () {
- change=false
- if $process_response_files; then
- if test $# = 0; then
- while read arg; do
- make_files_1 "$arg"
- done
- else
- for infile
- do
- exec 5<&0
- exec 0< $infile
- while read arg; do
- make_files_1 "$arg"
- done
- exec 0<&5
- exec 5<&-
- done
- fi
- else
- for arg
- do
- make_files_1 "$arg"
- done
- fi
- cd "$old_dir"
- }
- # Usage: make_files_1 ARG
- # Process one argument, ARG.
- make_files_1 () {
- if $change; then
- change=false
- if cd "$1"; then
- return
- else
- (exit 1); exit 1
- fi
- fi
- case "$1" in
- -C)
- change=:
- ;;
- -C*)
- cd `expr "$1" : '-C\(.*\)' `
- return
- ;;
- *)
- if test -d "$1"; then
- $mkdir_p "$JARTMP"/files/"$1"
- find "$1" | while read file; do
- if test -d "$file"; then
- $mkdir_p "$JARTMP"/files/"$file"
- else
- copy "$file" "$JARTMP"/files
- fi
- done
- else
- copy "$1" "$JARTMP"/files
- fi
- ;;
- esac
- cd "$old_dir"
- }
- # Same as "jar tf $1".
- jar_list () {
- $UNZIP -l "$1" | \
- sed '1,/^ ----/d;/^ ----/,$d;s/^ *[0-9]* ..-..-.. ..:.. //'
- }
- # Same as "jar tvf $1".
- jar_list_verbose () {
- $UNZIP -l "$1" | \
- @AWK@ 'BEGIN { yes = 0 }
- /^ ----/ { yes = !yes; next }
- yes {
- size=$1
- split ($2, d, "-")
- split ($3, t, ":")
- d[3] += (d[3] < 80) ? 2000 : 1900
- timestamp=d[3] " " d[1] " " d[2] " " t[1] " " t[2] " 00"
- gsub (/^ *[0-9]* ..-..-.. ..:.. /, "")
- printf "%6d %s %s\n", size, strftime ("%a %b %d %H:%M:%S %Z %Y", mktime (timestamp)), $0
- }'
- }
- # mkdir -p emulation based on the mkinstalldirs script.
- func_mkdir_p () {
- for file
- do
- case $file in
- /*) pathcomp=/ ;;
- *) pathcomp= ;;
- esac
- oIFS=$IFS
- IFS=/
- set fnord $file
- shift
- IFS=$oIFS
- errstatus=0
- for d
- do
- test "x$d" = x && continue
- pathcomp=$pathcomp$d
- case $pathcomp in
- -*) pathcomp=./$pathcomp ;;
- esac
- if test ! -d "$pathcomp"; then
- mkdir "$pathcomp" || lasterr=$?
- test -d "$pathcomp" || errstatus=$lasterr
- fi
- pathcomp=$pathcomp/
- done
- done
- return "$errstatus"
- }
- # Detect mkdir -p
- # On NextStep and OpenStep, the `mkdir' command does not
- # recognize any option. It will interpret all options as
- # directories to create, and then abort because `.' already
- # exists.
- if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
- mkdir_p='mkdir -p'
- else
- mkdir_p='func_mkdir_p'
- test -d ./-p && rmdir ./-p
- test -d ./--version && rmdir ./--version
- fi
- # Process the first command line option.
- case "$1" in
- -*) commands=`echo X"$1" | sed 's/^X-//' ` ;;
- *) commands="$1"
- esac
- shift
- # Operation to perform on the JAR file
- mode=unknown
- # First -C option on the command line
- cur_dir=.
- # Base directory for -C options
- old_dir=`pwd`
- # JAR file to operate on
- jarfile=
- # default for no {m,M} option, user for "m" option, none for "M" option
- manifest_kind=default
- # "-0" if the "0" option was given
- store=
- # true if the "v" option was given
- verbose=false
- # true if the non-standard "@" option was given
- process_response_files=false
- # An exec command if we need to redirect the zip/unzip commands' output
- out_redirect=:
- while test -n "$commands"; do
- # Process a letter at a time
- command=`expr "$commands" : '\(.\)'`
- commands=`expr "$commands" : '.\(.*\)'`
- case "$command" in
- c)
- set_var mode create
- ;;
- t)
- set_var mode list
- ;;
- x)
- set_var mode extract
- ;;
- u)
- set_var mode update
- ;;
- f)
- test $# = 0 && usage
- # Multiple "f" options are accepted by Sun's JAR tool.
- jarfile="$1"
- test -z "$jarfile" && usage
- shift
- ;;
- m)
- test $# = 0 && usage
- # Multiple "m" options are accepted by Sun's JAR tool, but
- # M always overrides m.
- test "$manifest_kind" = default && manifest_kind=user
- manifest_file="$1"
- test -z "$manifest_file" && usage
- shift
- ;;
- 0)
- store=-0
- ;;
- v)
- verbose=:
- ;;
- i)
- # Not yet implemented, and probably never will.
- ;;
- M)
- manifest_kind=none
- ;;
- C)
- test $# = 0 && usage
- cur_dir="$1"
- shift
- ;;
- @)
- process_response_files=: ;;
- *)
- usage ;;
- esac
- done
- set -e
- case "X$jarfile" in
- X)
- # Work on stdin/stdout. Messages go to stderr, and if we need an input
- # JAR file we save it temporarily in the temporary directory.
- make_tmp
- $mkdir_p "$JARTMP"/out
- jarfile="$JARTMP"/out/tmp-stdin.jar
- out_redirect='exec >&2'
- case $mode in
- update|extract|list)
- if $process_response_files && test $# = 0; then
- error Cannot use stdin for response file.
- fi
- cat > "$JARTMP"/out/tmp-stdin.jar
- ;;
- esac
- ;;
- X*/*)
- # Make an absolute path.
- dir=`dirname "$jarfile"`
- jarfile=`cd $dir && pwd`/`basename "$jarfile"`
- ;;
- X*)
- # Make an absolute path from a filename in the current directory.
- jarfile=`pwd`/`basename "$jarfile"`
- ;;
- esac
- # Perform a -C option if given right away.
- cd "$cur_dir"
- case $mode in
- unknown)
- usage
- ;;
- extract)
- make_tmp
- # Extract the list of files in the JAR file
- jar_list "$jarfile" > "$JARTMP"/list
- # If there are files on the command line, expand directories and skip -C
- # command line arguments
- for arg
- do
- if $skip; then
- skip=false
- continue
- fi
- case "$arg" in
- -C) skip=: ;;
- -C*) ;;
- *)
- escaped=`echo "X$arg" | sed 's/^X//; s/[].[^$\\*]/\\\\&/g' `
- grep "^$escaped/" "$JARTMP"/list >> "$JARTMP"/chosen || :
- grep "^$escaped\$" "$JARTMP"/list >> "$JARTMP"/chosen || :
- esac
- done
- test -f "$JARTMP"/chosen || cp "$JARTMP"/list "$JARTMP"/chosen
- # Really execute unzip
- if $verbose; then
- sort < "$JARTMP"/chosen | uniq | xargs $UNZIP -o "$jarfile" | \
- sed -ne 's/^ creating/ created/p' -e 's/^ inflating/extracted/p'
- else
- sort < "$JARTMP"/chosen | uniq | xargs $UNZIP -o "$jarfile" > /dev/null
- fi
- ;;
- create)
- make_tmp
- $mkdir_p "$JARTMP"/out
- $mkdir_p "$JARTMP"/files
- # Do not overwrite the JAR file if something goes wrong
- tmp_jarfile="$JARTMP"/out/`basename "$jarfile"`
- # Prepare the files in the temporary directory. This is necessary to
- # support -C and still save relative paths in the JAR file.
- make_files ${1+"$@"}
- if test $manifest_kind != none; then
- make_manifest "$JARTMP"/files/META-INF/MANIFEST.MF $manifest_kind "$manifest_file"
- fi
- # Really execute zip
- if $verbose; then
- (eval $out_redirect; cd "$JARTMP"/files && $ZIP -rv "$tmp_jarfile" $store .)
- else
- (cd "$JARTMP/files" && $ZIP -r "$tmp_jarfile" $store . > /dev/null)
- fi
- test "$jarfile" = "$tmp_jarfile" || mv "$tmp_jarfile" "$jarfile"
- ;;
- update)
- make_tmp
- $mkdir_p "$JARTMP"/files
- make_files ${1+"$@"}
- # Same as above, but zip takes care of not overwriting the file
- case $manifest_kind in
- none)
- $verbose && (eval $out_redirect; echo removing manifest)
- $ZIP -d "$jarfile" META-INF/MANIFEST.MF > /dev/null 2>&1 || :
- ;;
- *)
- make_manifest "$JARTMP"/files/META-INF/MANIFEST.MF $manifest_kind "$manifest_file"
- ;;
- esac
- if $verbose; then
- (eval $out_redirect; cd "$JARTMP"/files && $ZIP -ruv "$jarfile" $store .)
- else
- (cd "$JARTMP"/files && $ZIP -ru "$jarfile" $store . > /dev/null)
- fi
- ;;
- list)
- # Everything's done in the functions
- if $verbose; then
- jar_list_verbose "$jarfile"
- else
- jar_list "$jarfile"
- fi ;;
- esac
- if test "$out_redirect" != :; then
- # Cat back to stdout if necessary
- case $mode in
- create|update) cat "$JARTMP"/out/tmp-stdin.jar ;;
- esac
- fi
- exit 0
|