#!/bin/sh

# This is a parser for 7-Zip archive files in Midnight Commander. You need
# the LGPL p7zip program (version >= 4.37) written by Igor Pavlov.

# Author: Guus Jansman

# Limitations:
# The archive file can not be changed.
# Short filenames can not have trailing spaces.

# Settings:
SEVENZIP="7za"

mc7zfs_list ()
{
    $SEVENZIP l "$1" 2>/dev/null | gawk -v uid=${UID-0} '
    BEGIN { hyphens=0; date="JanFebMarAprMayJunJulAugSepOctNovDec" }
    /^----/ { hyphens++; next }
    /^$/ { next }
    // { if (hyphens != 1) next }
    {
        year=substr($0, 1, 4)
        month=substr(date, (substr($0, 6, 2)-1)*3 + 1, 3)
        day=substr($0, 9, 2)
        tm=substr($0, 12, 5)
        attr=substr($0, 21, 5)
        perm="-rwxr-xr-x"
        if (index(attr, "D") != 0)
        {
            perm=("d" substr(perm, 2))
        }
        else
        {
            gsub(/x/, "-", perm)
        }
        if (index(attr, "R") != 0)
        {
            gsub(/w/, "-", perm)
        }
        size=substr($0, 26, 13)
        name=substr($0, 54)
        # Short name has trailing spaces
        if (length(name) == 12)
        {
            while (length(name) > 0 && substr(name, length(name), 1) == " ")
            {
                name = substr(name, 1, length(name) - 1)
            }
        }
        if (length(name) == 0) next
        printf "%s    1 %-8d %-8d %8d %3s %2d %4d %s %s\n", perm, uid, 0, size, month, day, year, tm, name
    }'
}

mc7zfs_copyout ()
{
    filename=$2
    # 7za can not handle files with included path name "./"
    if echo "$filename" | grep -e '^\.' >/dev/null; then
        filename="`echo $filename | sed 's/^\.[\\/]*//'`"
    fi
    $SEVENZIP x "$1" -so "$filename" >"$3" 2>/dev/null
}

mc7zfs_test ()
{
    if $SEVENZIP t "$1" >/dev/null 2>&1; then
        echo "OK"
    else
        echo "UNKNOWN"
    fi
}

umask 077

cmd="$1"
shift
case "$cmd" in
    list)    mc7zfs_list    "$@" ;;
    copyout) mc7zfs_copyout "$@" ;;
#    test)    mc7zfs_test    "$@" ;;        # Not supported by MC extfs
    *)       exit 1 ;;
esac
exit 0

