106 lines
2.7 KiB
Plaintext
106 lines
2.7 KiB
Plaintext
|
#!/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)
|
||
|
# 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
|