#! /bin/sh
#                                                                     
# Written by Guus Jansman
# BSD type of licence (or Public Domain, GPL or closed source, basically
# whatever you want). The license type may be changed according to your
# wishes.
#
# This is a parser for Dar archives in Midnight Commander. You need
# the GPL dar program (version >= 2.3.0) written by Denis Corbin.

# Limitations:
# - The archive files 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

# Changes
# 2010-09-27  Ralf Hoffmann <ralf@boomerangsworld.de>
#  - hard links (h) and special dar file type (e) are handled
#    as regular files

DAR=dar_static

# 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 -ay 2>/dev/null | gawk -v uuid=$(id -ru) '
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
  }
  # change h and e types into regulat types
  if (match(substr(perm, 1, 1), "[he]") != 0)
  {
    perm = "-" substr( perm, 2 );
  }
  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]
  time=substr(record[8], 1, 5)
  year=record[9]
  name=substr(line, index(line, sprintf("%s:", time))+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, time, 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
  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
