New patchfs script

Adam Byrtek 'alpha' alpha at student.uci.agh.edu.pl
Mon Dec 9 15:53:56 UTC 2002


Hi. I've rewiten patchfs in Perl - now it can properly handle all
patches in unified diff format (the most common format for patches).

Methods supported: list, copyout

The algorithm isn't too fast (yet), but I think it's quite usable,
especialy for smaller patches. When I've tested it on 27MB kernel
patch 'list' took 4s and 'copyout' (in the worst case) 6s (duron
900mhz).

I have some issues on my todo list (info about size, date), but I
think this extfs is already ready for inclusion.

Entry to add to mc.ext:

regex/\.(diff|patch)(\.(bz|bz2|gz|z|Z))?$
        Open=%cd %p#patchfs


Regards
alpha

PS. The latest mc snapshot segfaults after pressing f4 to edit file.
Don't have time to check if it's fixed in cvs.

-- 

  _.|._ |_  _.    : Adam Byrtek, alpha@(irc.pl|debian.org)
 (_|||_)| |(_|    : gg 1802819, pgp 0xB25952C0
     |            : jid alpha.jabberpl.org
-------------- next part --------------
#! /usr/bin/perl
#
# Written by Adam Byrtek <alpha at debian.org>, 2002
# 
# extfs to handle patches in unified diff format

my $bzcat = "bzip2 -dc";
my $gzcat = "zcat";
my $file = "file";

sub now
{
    my @time = localtime;
    return sprintf "%02d-%02d-%02d %02d:%02d", $time[4]+1, $time[3], $time[5]%100, $time[2], $time[1];
}

sub list
{
    my ($archive)=@_;
    my ($uid,$gid)=(`id -nu` || "0",`id -ng` || "0");
    my ($len,$f);
    chomp ($uid, $gid);

    while (<I>) {
	if (/^--- /) {
	    printf "-rw-r--r-- 1 %s %s %d %s %s\n", $uid, $gid, $len-1, now, $f
	      if $f;
	    s/^--- ([^\s]+).*$/$1/;
	    chomp;
	    $f=$_;
	    $len=0;
	} elsif (/^[+\-]/) {
	    $len=0;
	    $len++;
	}
    }
    printf "-rw-r--r-- 1 %s %s %d %s %s\n", $uid, $gid, $len-1, now, $f
      if $f;
    close I;
}

sub copyout
{
    my ($archive,$file,$out)=@_;
    my ($f,$state,$notebuf,$diffbuf,$note);

    open O, "> $out";
    while (<I>) {
	if (/^--- /) {
	    last if ($f eq $file);
	    # switch to diff mode
	    $state=1;
	    $note=$notebuf;
	    $notebuf=$diffbuf="";
	    $f=$_;
	    $f=~s/^--- ([^\s]+).*$/$1/;
	    chomp $f;
	} elsif (!/^([+\- ]|@@)/) {
	    # switch to normal mode
	    $state=0;
	}
	
	if ($state==0) {
	    $notebuf.=$_;
	} elsif ($state==1) {
	    $diffbuf.=$_;
	}
    }
    print O ($note, $diffbuf) if ($f eq $file);
    close O;
}

$_=`$file $ARGV[1]`;
if (/bzip/) {
    open I, "$bzcat $ARGV[1] |";
} elsif (/gzip/) {
    open I, "$gzcat $ARGV[1] |";
} else {
    open I, "< $ARGV[1]";
}

if ($ARGV[0] eq "list") {
    list $ARGV[1];
    exit(0);
} if ($ARGV[0] eq "copyout") {
    copyout ($ARGV[1], $ARGV[2], $ARGV[3]);
    exit(0);
}
exit(1);


More information about the mc-devel mailing list