pkgsrc/mk/scripts/extract

293 lines
8 KiB
Text
Raw Normal View History

#!/bin/sh
#
# $NetBSD: extract,v 1.14 2006/01/21 19:26:09 jlam Exp $
#
# Copyright (c) 2006 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Johnny C. Lam.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the NetBSD
# Foundation, Inc. and its contributors.
# 4. Neither the name of The NetBSD Foundation nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
######################################################################
#
# NAME
# extract -- extract distfile, regardless of format
#
# SYNOPSIS
# extract [options] distfile [file ...]
#
# DESCRIPTION
# extract will unpack the contents of the named distfile into the
# current working directory. If any optional files are specified then
# only they will be extracted from the distfile, provided that the
# underlying tool supports this ability. If the distfile's file
# extension doesn't match any known archive format's, then the
# distfile is simply copied into the current working directory. If
# "-" is given as the distfile, then standard input is used as the
# contents of the archive, provided that the underlying tool supports
# this ability.
#
# OPTIONS
# -d dir Extract the files into the specified dir instead
# of the current working directory. If the directory
# doesn't exist, then it is created along with any
# intermediate directories using the current umask.
#
# -f format Force interpretation of the distfile's archive
# format to be the specified format.
#
# -t tarprog This specifies the tool to use to extract tar/ustar
# archives, and may be either "tar" or "pax", or the
# full path to the program.
#
# -X excludefile excludefile is a list of file patterns to exclude
# from extraction. If the -X option is specified
# then any optional files listed on the command line
# are ignored.
#
# -x This causes the optional files listed on the
# command line to be excluded from extraction,
# provided the underlying tool supports this
# ability.
#
# ENVIRONMENT
# EXTRACT_OPTS_BIN
# EXTRACT_OPTS_LHA
# EXTRACT_OPTS_PAX
# EXTRACT_OPTS_RAR
# EXTRACT_OPTS_TAR
# EXTRACT_OPTS_ZIP
# EXTRACT_OPTS_ZOO
# These variables set additional arguments passed to the
# underlying extraction tool to unpack their respective
# archive formats.
#
######################################################################
: ${BZCAT:=bzcat}
: ${CAT:=cat}
: ${CP:=cp}
: ${ECHO:=echo}
: ${GZCAT:=gzcat}
: ${LHA:=lha}
: ${MKDIR:=mkdir}
: ${PAX:=pax}
: ${RM:=rm}
: ${SH:=sh}
: ${TAR:=tar}
: ${TEST:=test}
: ${TMPDIR:=/tmp}
: ${UNRAR:=unrar}
: ${UNZIP:=unzip}
: ${UNZOO:=unzoo}
self="${0##*/}"
usage() {
${ECHO} 1>&2 "usage: $self [-d dir] [-f format] [-t tarprog] [-X excludefile | -x] distfile [file ...]"
}
exitcode=0
decompress_cat="${CAT}"
exclude=no
exclude_file=
exclude_flag=
extract_dir=.
extract_using=tar
format=
# Process optional arguments
while ${TEST} $# -gt 0; do
case "$1" in
-d) extract_dir="$2"; shift 2 ;;
-f) format="$2"; shift 2 ;;
2006-01-20 21:00:15 +01:00
-t) extract_using="$2"; shift 2 ;;
-X) exclude_file="$2"; shift 2 ;;
-x) exclude=yes; shift ;;
--) shift; break ;;
-?*) ${ECHO} 1>&2 "$self: unknown option -- ${1#-}"
usage
exit 1
;;
*) break ;;
esac
done
case "$extract_using" in
/*tar|/*pax) tarprog="$extract_using" ;;
*tar) tarprog="${TAR}" ;;
*pax) tarprog="${PAX}" ;;
esac
if ${TEST} -n "$exclude_file" -a ! -f "$exclude_file"; then
${ECHO} 1>&2 "$self: exclude file missing: $exclude_file"
exit 1
fi
# Process required arguments
${TEST} $# -gt 0 || { usage; exit 1; }
distfile="$1"; shift
# Set the command to decompress the file and write the contents to stdout.
case "$distfile" in
*.gz|*.tgz|*.z) decompress_cat="${GZCAT}" ;;
*.bz2|*.tbz|*.tbz2) decompress_cat="${BZCAT}" ;;
*.Z) decompress_cat="${GZCAT}" ;;
-) decompress_cat="${CAT}" ;;
esac
# Derive the format of the archive based on the file extension.
case "$distfile" in
*.tar.gz|*.tgz|*_tar.gz|*.tar.bz2|*.tbz|*.tbz2|*.tar.Z|*.tar)
_format=tar ;;
*.shar.gz|*.shar.bz2|*.shar.Z|*.shar|*.shr.gz|*.shr.bz2|*.shr.Z|*.shr)
_format=shar ;;
*.zip) _format=zip ;;
*.lha|*.lzh) _format=lha ;;
*.Z|*.bz2|*.gz|*.z)
_format=compressed ;;
*.zoo) _format=zoo ;;
*.rar) _format=rar ;;
*.bin) _format=jre-bin ;;
*) _format=none ;;
esac
${TEST} -n "$format" || format="$_format"
case "$format" in
tar|shar) ;;
*) if ${TEST} "$distfile" = "-"; then
${ECHO} 1>&2 "$self: archive format cannot be given on standard input -- $format"
exit 1
fi
;;
esac
${TEST} -d "$extract_dir" || ${MKDIR} -p "$extract_dir"
cd "$extract_dir"
# Use the correct tool and extraction procedure to perform the extraction
# based on the archive format.
#
case "$format" in
tar)
case "$extract_using" in
*pax)
case "$extract_using" in
/*) paxprog="$extract_using" ;;
*) paxprog="${PAX}" ;;
esac
if ${TEST} -n "$exclude_file"; then
exclude=yes
set -- dummy `${CAT} "$exclude_file"`; shift
fi
${TEST} "$exclude" = no || exclude_flag="-c"
$decompress_cat "$distfile" |
$paxprog ${EXTRACT_OPTS_PAX} $exclude_flag -O -r "$@"
;;
*tar)
case "$extract_using" in
/*) tarprog="$extract_using" ;;
*) tarprog="${TAR}" ;;
esac
tmpfile=
if ${TEST} "$exclude" = "yes"; then
tmpfile="${TMPDIR}/$self.$$"
${RM} -f "$tmpfile"
for i in "$@"; do
${ECHO} "$i" >> "$tmpfile"
done
exclude_file="$tmpfile"
fi
if ${TEST} -n "$exclude_file"; then
exclude_flag="-X $exclude_file"
set -- dummy; shift
fi
$decompress_cat "$distfile" |
$tarprog ${EXTRACT_OPTS_TAR} $exclude_flag -xf - "$@"
exitcode=$?
${TEST} "$exclude" = "no" || ${RM} -f "$tmpfile"
;;
*)
${ECHO} 1>&2 "$self: unknown tar program: $extract_using"
exit 1
esac
;;
2006-01-20 21:00:44 +01:00
shar)
$decompress_cat "$distfile" | ${SH}
;;
2006-01-20 21:00:44 +01:00
zip)
: ${EXTRACT_OPTS_ZIP=-Laqo}
${TEST} "$exclude" = "no" || exclude_flag="-x"
if ${TEST} -n "$exclude_file"; then
set -- dummy `${CAT} "$exclude_file"`; shift
fi
${UNZIP} ${EXTRACT_OPTS_ZIP} "$distfile" $exclude_flag "$@"
;;
2006-01-20 21:00:44 +01:00
lha)
: ${EXTRACT_OPTS_LHA=q}
${LHA} x$extract_options "$distfile" "$@"
;;
2006-01-20 21:00:44 +01:00
compressed)
target="${distfile##*/}"; target="${target%.*}"
$decompress_cat "$distfile" > "$target"
;;
2006-01-20 21:00:44 +01:00
zoo)
${UNZOO} -x ${EXTRACT_OPTS_ZOO} "$distfile" "$@"
;;
2006-01-20 21:00:44 +01:00
rar)
: ${EXTRACT_OPTS_RAR=-inul}
${UNRAR} -x ${EXTRACT_OPTS_RAR} "$distfile" "$@"
;;
2006-01-20 21:00:44 +01:00
jre-bin)
${ECHO} yes | "$distfile" ${EXTRACT_OPTS_BIN} >/dev/null
;;
none)
# By default, copy the distfile over to the current working directory.
${CP} "$distfile" .
;;
*)
${ECHO} 1>&2 "$self: archive format not recognized -- $format"
exit 1
;;
esac
exit $exitcode