# (C) 2003-2007 Willem Jan Hengeveld <itsme@xs4all.nl>
# Web: http://www.xs4all.nl/~itsme/
#      http://wiki.xda-developers.com/
#
# $Id$
#

use strict;

# copy files from reiserfs using rfstools.

use Dumpvalue;
use POSIX;
use Time::Local;

my $d= Dumpvalue->new();

my $path= shift || "";
my $target= shift || ".";

my $dir= RecurseDir($path);

CopyDir($dir, $path, $target);
exit(0);

sub CopyDir {
    my ($dir, $path, $target)= @_;

    if (!-e $target) {
        mkdir $target or die "mkdir $target\n";
    }
    print "Directory of $path:\n";
    for my $name (sort keys %$dir) {
        if ($dir->{$name}{type} eq "-") {
            if (! -e "$target/$name") {
                CopyFile("$path/$name", "$target/$name");
            }
        }
    }
    for my $name (sort keys %$dir) {
        if ($dir->{$name}{type} eq "d") {
            CopyDir($dir->{$name}{contents}, "$path/$name", "$target/$name");
        }
    }
}
sub CopyFile {
    my ($src, $target) = @_;

    print "copying $src\n";

    open RFS, "rfstool cp $src $target|" or die "error running rfstool: $@\n";
    while (<RFS>) {
        die "$_" if (/ERROR/i);
    }
    close RFS;
}

sub RecurseDir {
    my ($path)= @_;
    print "reading $path\n";
    my $dir= rfsdir($path);
    for my $name (keys %$dir) {
        if ($dir->{$name}{type} eq "d") {
            $dir->{$name}{contents}= RecurseDir("$path/$name");
        }
    }
    return $dir;
}
sub rfsdir {
    my ($path)= @_;

    open RFS, "rfstool ls $path|" or die "error running rfstool: $@\n";

    my $dir={};
    while (<RFS>) {
        if (my ($type, $perms, $size, $month, $day, $time, $year, $name)=
            (m{^(.)(.{9})\s(.{12})\s\w{3}\s(\w{3})\s(\d{2})\s([\d:]{8})\s(\d{4})\s(.*?)\s*$})) {
            next if ($name eq "." || $name eq "..");

            $dir->{$name}= {
                type=>$type,
                perms=>$perms,
                size=>$size =~ /\d/? int($size):0,
                timestamp=>toDateTime($year, $month, $day, $time),
                name=>$name,
            };

        }
    }
    close RFS;

    return $dir;
}

sub toDateTime {
    my ($year, $month, $day, $time)= @_;
    my @months= qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
    my %months= map { $months[$_] => $_ } (0..$#months);

    my ($hour, $minute, $second)= ($time =~ /(\d+):(\d+):(\d+)/);
    return timelocal($second, $minute, $hour, $day, $months{$month}, $year-1900);
}

