#!/bin/sh # untar --- extract contents of archive files into a single directory # Author: Noah Friedman # Created: 1996-01-15 # Public domain # $Id: untar,v 1.41 2019/08/01 19:26:33 friedman Exp $ # Commentary: # This started out just unpacking tar files, but now supports more formats. # Code: tmpdir=untar$$ pre() { pkgdir=`echo "$file" | sed -e 's=.*/==' -e 's=\.[^.]*$=='` case $pkgdir in *.tar | *.xtar ) pkgdir=`echo "$pkgdir" | sed -e 's=\.[^.]*$=='` ;; esac if [ -d "$pkgdir" ]; then echo "$pkgdir": directory already exists 1>&2 return 1 fi if [ -d "$tmpdir" ]; then echo "$tmpdir": temp directory already exists, and it shouldn\'t 1>&2 return 1 fi mkdir -p "$tmpdir" || return 1 cd "$tmpdir" || return 1 case $file in /* ) : ;; * ) file=../$file ;; esac return 0 } post() { nfiles=`ls -1A | wc -l` ndir= if [ $nfiles -eq 1 ]; then ndir=`ls -1A` fi if [ $nfiles -gt 1 ] || { [ $nfiles -eq 1 ] && [ ".$ndir" != ".$pkgdir" ]; } then cd .. && mv "$tmpdir" "$pkgdir" elif [ $nfiles -eq 1 ]; then mv "$ndir" .. && cd .. && rmdir "$tmpdir" else echo "$tmpdir": empty directory\? 1>&2 cd .. && rmdir "$tmpdir" return 1 fi } extract() { case $file in *.t[ag]z | *.tar.gz | *.tar.[Zz] | *.xtar.gz | *.xtar.[Zz] | *.nif ) ${GZIP-gzip} -dc "$file" | ${TAR-tar} -xpvf - ;; *.tbz | *.tbz2 | *.tar.bz2 | *.xtar.bz2 | *.tar.bz | *.cbt ) ${BZIP2-bzip2} -dc "$file" | ${TAR-tar} -xpvf - ;; *.tar.xz | *.txz ) # xz uses LZMA, but isn't compatible with `lzma' ${XZ-xz} -dc "$file" | ${TAR-tar} -xpvf - ;; *.tar.lz | *.tlz ) # lzip uses LZMA, but isn't compatible with `lzma' ${LZIP-lzip} -dc "$file" | ${TAR-tar} -xpvf - ;; *.tar.lzma ) ${LZMA-lzma} -dc "$file" | ${TAR-tar} -xpvf - ;; *.tar | *.xtar | *.ova | *.tar.md5 ) ${TAR-tar} -xpvf "$file" ;; *.zip | *.cbz | *.fbu | *.jar | *.apk | *.xpi | *.epub ) ${UNZIP-unzip} -o -d . "$file" ;; *.rpm ) ${RPM2CPIO-rpm2cpio} "$file" | ${CPIO-cpio} -dimv --no-absolute-filenames ;; *.deb | *.udeb ) ${AR-ar} xv "$file" for file in control.tar.* data.tar.* ; do (pre; extract; post) rm -f "$file" done ;; *.lzh ) ${LHA-lha} x "$file" ;; *.rar | *.cbr ) if type unar >/dev/null 2>&1; then : ${UNRAR:=unar} else : ${UNRAR:=unrar} fi case $UNRAR in *unar ) $UNRAR -t "$file" ;; *unrar ) $UNRAR x "$file" ;; esac ;; *.a | *.lib ) ${AR-ar} t "$file" | sed -ne 's=/[^/]*$==p' | xargs --no-run-if-empty mkdir -p ${AR-ar} xv "$file" ;; *.7z ) 7z x "$file" ;; *.cab ) #${CABEXTRACT-cabextract} "$file" ;; 7z x "$file" ;; *.msi ) # ${MSIEXEC-msiexec} /a "$file" /qb TARGETDIR=./$pkgdir ;; 7z x "$file" ;; *.dmg ) 7z x "$file" ;; *.pkg ) # mac pkg files # pkgutil --expand "$file" . basename=${file##*/} pkgdir=${basename%.pkg}.app 7z x -o"$pkgdir" "$file" ;; *initramfs*.img | *initrd*.img | *ramdisk.img ) extract_initrd "$file" ;; *.squashfs ) dest=${file##*/} unsquashfs -i -d "${dest%.squashfs}" "$file" ;; *.iso ) xorriso -for_backup \ -indev "$file" \ -osirrox on:auto_chmod_on \ -chmod_r u+rw / -- \ -extract / . \ -rollback_end ;; esac } extract_initrd() { if ${GREP-grep} -q 'early_cpio' "$file"; then # Skip uncompressed cpu microcode blobs at head of actual archive. blocks=`${CPIO-cpio} -t < "$file" 2>&1 \ | sed -ne '/^\([0-9]*\) blocks$/s//\1/p'` exp() { ${DD-dd} bs=1b skip=$blocks status=none if="$1"; } else exp() { ${CAT-cat} -- "$1"; } fi kind=`exp "$file" | file -` case $kind in *gzip* ) exp2() { ${GZIP-gzip} -dc; } ;; *bzip2* ) exp2() { ${BZIP2-bzip2} -dc; } ;; *XZ* ) exp2() { ${XZ-xz} -dc; } ;; *cpio* ) exp2() { ${CAT-cat}; } ;; * ) echo "$file: unknown file format" 1>&2 exit 1 ;; esac exp "$file" | exp2 | ${CPIO-cpio} -dimv --no-absolute-filenames } main() { for file in ${1+"$@"}; do (pre; extract; post) done } main ${1+"$@"} # eof