#!/bin/bash
# -*- coding: utf-8 -*-
# rpmdev-extract -- Extract various archives in "tar xvf" style
#
# Copyright (c) 2004-2007 Fedora Project .
# Author: Ville Skyttä
#
# 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 St, Fifth Floor, Boston, MA 02110-1301 USA
# TODO: more archive types
set -e
unset CDPATH
ftype=
decomp=
quiet=
force=
dir=
shopt -s extglob
version()
{
cat <.
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.
Written by Ville Skyttä.
EOF
}
help()
{
cat <."
}
usage()
{
cat </dev/null`
fmime "$t"
[ -n "$ftype" ] && return
case "$t" in
application/x-compress|application/x-gzip) decomp="gzip -dc" ;;
application/x-bzip2) decomp="bzip2 -dc" ;;
esac
if [ -n "$decomp" ] ; then
t=`file -zibL "$1" 2>/dev/null`
fmime "$t"
[ -n "$ftype" ] && return
fi
t=`file -${decomp:+z}bL "$1" 2>/dev/null`
case "$t" in
*Z[iI][pP]\ *archive*) ftype=zip ;;
*tar\ archive*) ftype=tar ;;
*ar\ archive*|*Debian\ *package*) ftype=ar ;;
*ARJ\ *archive*) ftype=arj ;;
*Zoo\ *archive*) ftype=zoo ;;
*cpio\ archive*) ftype=cpio ;;
*C[aA][bB]*archive*) ftype=cab ;;
RPM\ *) ftype=rpm ;;
*ACE\ *archive*) ftype=ace ;;
*LHa\ *archive*) ftype=lha ;;
*RAR\ *archive*) ftype=rar ;;
esac
}
unarch()
{
case "$1" in
/*) f="$1" ;;
*) f="$PWD/$1" ;;
esac
ftype "$1"
cd "$2"
case "$ftype" in
tar)
[ -n "$force" ] && o= || o=k
${decomp:-cat} "$f" | tar xv$o
;;
zip)
[ -n "$force" ] && o=-o || o=-n
unzip $o "$f"
;;
rar)
[ -n "$force" ] && o=+ || o=-
unrar x -o$o -y "$f"
;;
cab)
# force not supported, it's always on (as of cabextract 1.[01])
cabextract -f "$f"
;;
rpm)
name=`rpm -qp --qf="%{NAME}-%{VERSION}-%{RELEASE}" "$f"`
if [ -z "$name" ] ; then # workaround for #250990
bname="`basename "$f"`"
name=${bname/?(\.*([^\.]))\.rpm/}
fi
mkdir -p "$name"
cd "$name"
rpm2cpio "$f" \
| cpio --quiet --no-absolute-filenames -id${force:+u}mv 2>&1 \
| sed "s|^\(\./\)\?|$name/|"
cd ..
;;
cpio)
${decomp:-cat} "$f" | \
cpio --quiet --no-absolute-filenames -id${force:+u}mv
;;
ar)
# force not supported, it's always on
ar xvo "$f"
;;
ace)
[ -n "$force" ] && o=+ || o=-
unace x -o$o -y "$f"
;;
arj)
# force not supported, it's always off (as of unarj 2.6[35])
# it will also return an error if some files already exist :(
unarj x "$f"
;;
zoo)
zoo x${force:+OOS} "$f"
;;
lha)
lha x${force:+f} "$f" < /dev/null
;;
*)
echo "Error: unrecognized archive: '$f'" >&2
exit 1
;;
esac
cd - >/dev/null 2>&1
}
dir="$PWD"
while getopts "qfC:hv" key ; do
case "$key" in
q) quiet=1 ;;
f) force=1 ;;
C) dir="$OPTARG" ;;
h) help ; exit 0 ;;
v) version ; exit 0 ;;
*) usage ; exit 1 ;;
esac
done
shift $(( $OPTIND -1 ))
if [ ! -d "$dir" ] ; then
[ -e "$dir" ] && \
echo "Error: not a directory: '$dir'" >&2 ||
echo "Error: directory does not exist: '$dir'" >&2
exit 1
fi
for file in "$@" ; do
if [ ! -f "$file" ] ; then
[ -e "$file" ] && \
echo "Error: not a regular file: '$file'" >&2 ||
echo "Error: file does not exist: '$file'" >&2
exit 1
fi
# Not that fancy at the moment, but -q is for backwards compatibility
# and in case we need to do more fine-grained stuff for some unarchivers
# later.
if [ -n "$quiet" ] ; then
unarch "$file" "$dir" >/dev/null
else
unarch "$file" "$dir"
fi
done