Midnight Commander plugin for DAR

From SME Server
Jump to: navigation, search

Midnight Commander, or mc, is a text-based visual file manager which makes it easy to browse your filesystem, move and copy files and directories, and perform many other common file operations. DAR is backup software used by the "Backup to Workstation" function in SME server, as well as some contribs. This plugin, developed by Guus Jansman (see https://mail.gnome.org/archives/mc-devel/2006-April/msg00001.html), allows you to view the contents of DAR archives within Midnight Commander. Installation involves adding the plugin script itself, and editing two Midnight Commander configuration files.

First, create the script with this command:

# nano -w /usr/share/mc/extfs/udar

Copy and paste the following text into the script:

#!/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

Then press Ctrl+X to exit, and Y to save. You'll need to set the appropriate permissions on this script:

# chmod 755 /usr/share/mc/extfs/udar

You'll next need to edit two of the Midnight Commander configuration files. First, extfs.ini:

# nano -w /etc/mc/extfs/extfs.ini

Add these lines to the bottom of that file:

# Disk archivers
udar

Then, mc.ext:

# nano -w /etc/mc/mc.ext

Add these lines in the "Archivers" section of that file. The exact location is unimportant, but placing them in this section will make them easier to find later if necessary:

# dar
regex/\.[0-9]*\.[Dd][Aa][Rr]$
	Open=%cd %p#udar
	View=%view{ascii} dar -l `echo %f | sed 's/\.[0-9]*\.[Dd][Aa][Rr]$//'` -N