#!/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