#!/bin/sh # This is a parser for Dar archives in Midnight Commander. You need # the GPL dar program (version >= 2.3.0) written by Denis Corbin. # Author: Guus Jansman # Limitations: # - The archive file can not be changed # - Symbolic and hard links are not handled properly # - Block and character special files are not handled # - Files not stored in (differential) backups are not handled # - Dar files in archives are not handled (due filename restriction) DAR=dar # dar expects the basename (without number and extension) BASENAME="`echo "$2" | sed -e 's/\.[0-9]*\.[Dd][Aa][Rr]$//'`" mcdarfs_list () { $DAR -l "$BASENAME" -N -Q -as 2>/dev/null | gawk -v uuid=${UID-0} ' BEGIN { flag=0 } /^-------/ { flag++; if (flag > 1) exit 0; next } /^$/ { next } { if (flag == 0) next line=$0 split(line, record, " ") # Do not display removed files if (record[1] == "[" && record[2] == "REMOVED") { next } # We want "line" to start with permutation # TODO: better algorithm while (length(record[1]) != 10 || match(substr(record[1], 2, 1), "[r-]") == 0) { # line without real contents if (length(line) == 0) { next } line=substr(line, length(record[1])+1) while (length(line) != 0 && substr(line, 1, 1) != " ") { line=substr(line, 2) } split(line, record, " ") } perm=record[1] # Block and character special files not supported # Change [bc] to [bcl] if symbolic links should not show up either if (match(substr(perm, 1, 1), "[bc]") != 0) { next } uid=record[2] if (match(uid, "^[0-9]*$") != 0) { uid=sprintf("%-8d", uid) } gid=record[3] if (match(gid, "^[0-9]*$") != 0) { gid=sprintf("%-8d", gid) } size=record[4] month=record[6] day=record[7] tm=substr(record[8], 1, 5) year=record[9] name=substr(line, index(line, sprintf("%s:", tm))+14) tm="" # TODO: find symbolic link target (probably the link has to be extracted) printf "%s 1 %s %s %8d %3s %02d %04d %s %s\n", perm, uid, gid, size, month, day, year, tm, name }' } mcdarfs_copyout () { # Dummy directory necessary since dar cannot output to stdout or named file mkdir "$3.dir.tmp" chmod 700 "$3.dir.tmp" if [ ! -d "$3.dir.tmp" ]; then exit 1; fi $DAR -x "$BASENAME" -N -O -Q -wa -g "$2" -R "$3.dir.tmp" >/dev/null 2>&1 if [ -e "$3.dir.tmp/$2" ]; then mv "$3.dir.tmp/$2" "$3" rm -rf "$3.dir.tmp" else rm -rf "$3.dir.tmp" exit 1 fi } umask 077 cmd="$1" shift case "$cmd" in list) mcdarfs_list "$@" ;; copyout) mcdarfs_copyout "$@" ;; *) exit 1 ;; esac exit 0