#! /bin/sh # # Written by andrey joukov # (C) 1996 2:5020/337.13@fidonet.org # Updated by christian.gennerat@alcatel.fr 1999 # Andrew V. Samoilov 2000 # # Andrew Borodin # David Haller # 2013: support unrar5 # # beta version 2.0 # # rar and unrar can be found on http://www.rarlabs.com/ RAR=rar # Prefer unrar (freeware). UNRAR=`which unrar 2>/dev/null` [ -z $UNRAR ] && UNRAR=$RAR [ ! -x $UNRAR -a -x $RAR ] && UNRAR=$RAR # Let the test framework hook in: UNRAR=${MC_TEST_EXTFS_LIST_CMD:-$UNRAR} # Determine the $UNRAR version if [ -n "$MC_TEST_EXTFS_UNRAR_VERSION" ]; then # Let the test framework fool us: UNRAR_VERSION=$MC_TEST_EXTFS_UNRAR_VERSION else # Figure it out from rar itself: UNRAR_VERSION=`$UNRAR -cfg- -? | grep "Copyright" | sed -e 's/.*\([0-9]\)\..*/\1/'` fi mcrar4fs_list () { $UNRAR v -c- -cfg- "$1" | @AWK@ -v uid=`id -u` -v gid=`id -g` ' BEGIN { flag=0 } /^-------/ { flag++; if (flag > 1) exit 0; next } flag==1 { str = substr($0, 2) getline split($4, a, "-") if (index($6, "D") != 0) $6="drwxr-xr-x" else if (index($6, ".") != 0) $6="-rw-r--r--" printf "%s 1 %s %s %d %02d/%02d/%02d %s ./%s\n", $6, uid, gid, $1, a[2], a[1], a[3], $5, str }' } mcrar5fs_list () { $UNRAR vt -c- -cfg- "$1" | @AWK@ -F ':' -v uid=`id -u` -v gid=`id -g` ' { ### remove space after the ":" of the field name sub ("^ ", "", $2); } $1 ~ /^ *Name$/ { ### next file name = mtime = size = attrs = ""; delete date; name = $2; ### if the name contains ":", append the rest of the fields if (NF > 2) { for (i = 3; i <= NF; i++) { name = name ":" $i; } } } $1 ~ /^ *mtime$/ { mtime = $2 ":" $3; } $1 ~ /^ *Size$/ { size = $2; } $1 ~ /^ *Attributes$/ { attrs = $2; } $1 ~ /^ *Compression$/ { ### file done, using /^$/ is not so good you ### would have to skip the version stuff first ### get date and time split (mtime, date, " "); time = date[2]; ### cut off seconds from the time sub (",[0-9]*$", "", time); ### split for reordering of the date in the printf below split (date[1], date, "-"); ### mc seems to be able to parse 4 digit years too, so remove if tested # sub ("^..", "", date[1]); ### cut year to 2 digits only ### check/adjust rights if (index (attrs, "D") != 0) { attrs = "drwxr-xr-x"; } else { if (index (attrs, ".") != 0) { attrs = "-rw-r--r--"; } } ### and finally printf ("%s 1 %s %s %d %02d/%02d/%02d %s ./%s\n", attrs, uid, gid, size, date[2], date[3], date[1], time, name); } ' } mcrarfs_list () { [ x$UNRAR_VERSION = x6 -o x$UNRAR_VERSION = x5 ] && mcrar5fs_list "$@" || mcrar4fs_list "$@" } mcrarfs_copyin () { # copyin by christian.gennerat@alcatel.fr # preserve pwd. It is clean, but is it necessary? pwd=`pwd` # Create a directory and copy in it the tmp file with the good name mkdir "$3.dir" cd "$3.dir" di="${2%/*}" # if file is to be written upper in the archive tree, make fake dir if test x"$di" != x"${2##*/}" ; then mkdir -p "$di" fi cp -fp "$3" "$3.dir/$2" $RAR a "$1" "$2" >/dev/null cd "$pwd" rm -rf "$3.dir" } mcrarfs_copyout () { $UNRAR p -p- -c- -cfg- -inul "$1" "$2" > "$3" } mcrarfs_mkdir () { # preserve pwd. It is clean, but is it necessary? pwd=`pwd` # Create a directory and create in it a tmp directory with the good name dir=`mktemp -d "${MC_TMPDIR:-/tmp}/mctmpdir-urar.XXXXXX"` || exit 1 cd "$dir" mkdir -p "$2" # rar cannot create an empty directory touch "$2"/.rarfs $RAR a -r "$1" "$2" >/dev/null $RAR d "$1" "$2/.rarfs" >/dev/null cd "$pwd" rm -rf "$dir" } mcrarfs_rm () { $RAR d "$1" "$2" >/dev/null } umask 077 cmd="$1" shift case "$cmd" in # Workaround for a bug in mc - directories must precede files to # avoid duplicate entries, so we sort output by filenames list) mcrarfs_list "$@" | sort -k 8 ;; rm) mcrarfs_rm "$@" ;; rmdir) mcrarfs_rm "$@" ;; mkdir) mcrarfs_mkdir "$@" ;; copyin) mcrarfs_copyin "$@" ;; copyout) mcrarfs_copyout "$@" ;; *) exit 1 ;; esac exit 0