* extfs/patchfs.in: rm and proper copyin support, more
functions to make code more clear.
Этот коммит содержится в:
родитель
4dc31f3e06
Коммит
9ec797a024
@ -1,3 +1,8 @@
|
|||||||
|
2003-02-24 Adam Byrtek <alpha@debian.org>
|
||||||
|
|
||||||
|
* extfs/patchfs.in: rm and proper copyin support, more
|
||||||
|
functions to make code more clear.
|
||||||
|
|
||||||
2003-02-19 Andrew V. Samoilov <sav@bcs.zp.ua>
|
2003-02-19 Andrew V. Samoilov <sav@bcs.zp.ua>
|
||||||
|
|
||||||
* smbfs.c (smbfs_lseek): Backport from Samba 2.2.7 Suite.
|
* smbfs.c (smbfs_lseek): Backport from Samba 2.2.7 Suite.
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
use bytes;
|
use bytes;
|
||||||
use strict;
|
use strict;
|
||||||
use POSIX;
|
use POSIX;
|
||||||
|
use File::Temp 'tempfile';
|
||||||
|
|
||||||
# standard binaries
|
# standard binaries
|
||||||
my $bzip = 'bzip2';
|
my $bzip = 'bzip2';
|
||||||
@ -14,7 +15,7 @@ my $gzip = 'gzip';
|
|||||||
my $file = 'file';
|
my $file = 'file';
|
||||||
|
|
||||||
# date parsing requires Date::Parse from TimeDate module
|
# date parsing requires Date::Parse from TimeDate module
|
||||||
my $parsedates = eval "require Date::Parse";
|
my $parsedates = eval 'require Date::Parse';
|
||||||
|
|
||||||
# regular expressions
|
# regular expressions
|
||||||
my $unified_header=qr/^--- .*\n\+\+\+ .*\n@@ .* @@.*\n$/;
|
my $unified_header=qr/^--- .*\n\+\+\+ .*\n@@ .* @@.*\n$/;
|
||||||
@ -33,7 +34,7 @@ my $basename=qr|^(.*/)*([^/]+)$|;
|
|||||||
sub timef
|
sub timef
|
||||||
{
|
{
|
||||||
my @time=localtime($_[0]);
|
my @time=localtime($_[0]);
|
||||||
return sprintf "%02d-%02d-%02d %02d:%02d", $time[4]+1, $time[3],
|
return sprintf '%02d-%02d-%02d %02d:%02d', $time[4]+1, $time[3],
|
||||||
$time[5]+1900, $time[2], $time[1];
|
$time[5]+1900, $time[2], $time[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,6 +56,90 @@ sub error
|
|||||||
exit 1;
|
exit 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# (compressed) input
|
||||||
|
sub myin
|
||||||
|
{
|
||||||
|
my ($qfname)=(quotemeta $_[0]);
|
||||||
|
|
||||||
|
$_=`$file $qfname`;
|
||||||
|
if (/bzip/) {
|
||||||
|
return "$bzip -dc $qfname";
|
||||||
|
} elsif (/gzip/) {
|
||||||
|
return "$gzip -dc $qfname";
|
||||||
|
} else {
|
||||||
|
return "cat $qfname";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# (compressed) output
|
||||||
|
sub myout
|
||||||
|
{
|
||||||
|
my ($qfname,$append)=(quotemeta $_[0],$_[1]);
|
||||||
|
my ($sep) = $append ? '>>' : '>';
|
||||||
|
|
||||||
|
$_=`$file $qfname`;
|
||||||
|
if (/bzip/) {
|
||||||
|
return "$bzip -c $sep $qfname";
|
||||||
|
} elsif (/gzip/) {
|
||||||
|
return "$gzip -c $sep $qfname";
|
||||||
|
} else {
|
||||||
|
return "cat $sep $qfname";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# select diff filename conforming with rules found in diff.info
|
||||||
|
sub diff_filename
|
||||||
|
{
|
||||||
|
my ($fsrc,$fdst)=@_;
|
||||||
|
|
||||||
|
if (!$fdst && !$fsrc) {
|
||||||
|
error 'Index: not yet implemented';
|
||||||
|
} elsif (!$fsrc || $fsrc eq '/dev/null') {
|
||||||
|
return ($fdst,'PATCH-CREATE/');
|
||||||
|
} elsif (!$fdst || $fdst eq '/dev/null') {
|
||||||
|
return ($fsrc,'PATCH-REMOVE/');
|
||||||
|
} elsif (($fdst eq '/dev/null') && ($fsrc eq '/dev/null')) {
|
||||||
|
error 'Malformed diff';
|
||||||
|
} else {
|
||||||
|
# fewest path name components
|
||||||
|
if ($fdst=~s|/|/|g < $fsrc=~s|/|/|g) {
|
||||||
|
return ($fdst,'');
|
||||||
|
} elsif ($fdst=~s|/|/|g > $fsrc=~s|/|/|g) {
|
||||||
|
return ($fsrc,'');
|
||||||
|
} else {
|
||||||
|
# shorter base name
|
||||||
|
if (($fdst=~/$basename/,length $2) < ($fsrc=~/$basename/,length $2)) {
|
||||||
|
return ($fdst,'');
|
||||||
|
} elsif (($fdst=~/$basename/,length $2) > ($fsrc=~/$basename/,length $2)) {
|
||||||
|
return ($fsrc,'');
|
||||||
|
} else {
|
||||||
|
# shortest names
|
||||||
|
if (length $fdst < length $fsrc) {
|
||||||
|
return ($fdst,'');
|
||||||
|
} else {
|
||||||
|
return ($fsrc,'');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# parse unified or context header
|
||||||
|
sub parse_header
|
||||||
|
{
|
||||||
|
my ($unified,$context,$buf)=@_;
|
||||||
|
|
||||||
|
if ($unified) {
|
||||||
|
error "Can't parse unified diff header"
|
||||||
|
unless ((($$buf.=<I>).=<I>)=~/$unified_header/);
|
||||||
|
return $$buf=~/$unified_extract/;
|
||||||
|
} elsif ($context) {
|
||||||
|
error "Can't parse context diff header"
|
||||||
|
unless ((($$buf.=<I>).=<I>)=~/$context_header/);
|
||||||
|
return $$buf=~/$context_extract/;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# list files affected by patch
|
# list files affected by patch
|
||||||
sub list
|
sub list
|
||||||
{
|
{
|
||||||
@ -91,49 +176,8 @@ sub list
|
|||||||
}
|
}
|
||||||
$state=1;
|
$state=1;
|
||||||
|
|
||||||
# parse diff header
|
($fsrc,$fdst,$time)=parse_header($unified,$context,\$_);
|
||||||
if ($unified) {
|
($f,$prefix)=diff_filename($fsrc,$fdst);
|
||||||
error "Can't parse unified diff header"
|
|
||||||
unless ((($_.=<I>).=<I>)=~/$unified_header/);
|
|
||||||
($fsrc,$fdst,$time)=/$unified_extract/;
|
|
||||||
} elsif ($context) {
|
|
||||||
error "Can't parse context diff header"
|
|
||||||
unless ((($_.=<I>).=<I>)=~/$context_header/);
|
|
||||||
($fsrc,$fdst,$time)=/$context_extract/;
|
|
||||||
}
|
|
||||||
|
|
||||||
# select filename, conform with (diff.info)Multiple patches
|
|
||||||
$prefix="";
|
|
||||||
if (!$fdst && !$fsrc) {
|
|
||||||
error 'Index: not yet implemented';
|
|
||||||
} elsif (!$fsrc || $fsrc eq '/dev/null') {
|
|
||||||
$f=$fdst; $prefix="PATCH-CREATE/";
|
|
||||||
} elsif (!$fdst || $fdst eq '/dev/null') {
|
|
||||||
$f=$fsrc; $prefix="PATCH-REMOVE/";
|
|
||||||
} elsif (($fdst eq "/dev/null") && ($fsrc eq "/dev/null")) {
|
|
||||||
error "Malformed diff";
|
|
||||||
} else {
|
|
||||||
# fewest path name components
|
|
||||||
if ($fdst=~s|/|/|g < $fsrc=~s|/|/|g) {
|
|
||||||
$f=$fdst;
|
|
||||||
} elsif ($fdst=~s|/|/|g > $fsrc=~s|/|/|g) {
|
|
||||||
$f=$fsrc;
|
|
||||||
} else {
|
|
||||||
# shorter base name
|
|
||||||
if (($fdst=~/$basename/,length $2) < ($fsrc=~/$basename/,length $2)) {
|
|
||||||
$f=$fdst;
|
|
||||||
} elsif (($fdst=~/$basename/,length $2) > ($fsrc=~/$basename/,length $2)) {
|
|
||||||
$f=$fsrc;
|
|
||||||
} else {
|
|
||||||
# shortest names
|
|
||||||
if (length $fdst < length $fsrc) {
|
|
||||||
$f=$fdst;
|
|
||||||
} else {
|
|
||||||
$f=$fsrc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$f=$f.".diff";
|
$f=$f.".diff";
|
||||||
|
|
||||||
} elsif ($state==1 && (($unified && !/$unified_contents/) || ($context && !/$context_contents/))) {
|
} elsif ($state==1 && (($unified && !/$unified_contents/) || ($context && !/$context_contents/))) {
|
||||||
@ -146,7 +190,7 @@ sub list
|
|||||||
$len+=length;
|
$len+=length;
|
||||||
}
|
}
|
||||||
printf "-rw-r--r-- 1 %s %s %d %s %s%s\n", $uid, $gid, $len, datetime($time), $prefix, $f
|
printf "-rw-r--r-- 1 %s %s %d %s %s%s\n", $uid, $gid, $len, datetime($time), $prefix, $f
|
||||||
if $f;
|
if ($f && $state==1);
|
||||||
}
|
}
|
||||||
|
|
||||||
# extract diff from patch
|
# extract diff from patch
|
||||||
@ -176,23 +220,14 @@ sub copyout
|
|||||||
last if ($state==1 && $found);
|
last if ($state==1 && $found);
|
||||||
$state=1;
|
$state=1;
|
||||||
|
|
||||||
# parse diff header
|
($fsrc,$fdst,)=parse_header($unified,$context,\$_);
|
||||||
if ($unified) {
|
|
||||||
error "Can't parse unified diff header"
|
|
||||||
unless ((($_.=<I>).=<I>)=~/$unified_header/);
|
|
||||||
($fsrc,$fdst)=/$unified_extract/;
|
|
||||||
} elsif ($context) {
|
|
||||||
error "Can't parse context diff header"
|
|
||||||
unless ((($_.=<I>).=<I>)=~/$context_header/);
|
|
||||||
($fsrc,$fdst)=/$context_extract/;
|
|
||||||
}
|
|
||||||
$found=1 if (($fsrc eq $file) || ($fdst eq $file));
|
$found=1 if (($fsrc eq $file) || ($fdst eq $file));
|
||||||
|
|
||||||
} elsif ($state==1 && (($unified && !/$unified_contents/) || ($context && !/$context_contents/))) {
|
} elsif ($state==1 && (($unified && !/$unified_contents/) || ($context && !/$context_contents/))) {
|
||||||
# start of comments, end of diff contents
|
# start of comments, end of diff contents
|
||||||
last if ($found);
|
last if ($found);
|
||||||
$state=0;
|
$state=0;
|
||||||
$buf="";
|
$buf='';
|
||||||
}
|
}
|
||||||
|
|
||||||
$buf.=$_ if ($found || $state==0)
|
$buf.=$_ if ($found || $state==0)
|
||||||
@ -204,58 +239,128 @@ sub copyout
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# remove diff(s) from patch
|
||||||
|
sub rm
|
||||||
|
{
|
||||||
|
my ($archive)=(shift);
|
||||||
|
my ($fsrc,$fdst,$found,$state,$buf);
|
||||||
|
my ($tmp,$tmpname)=tempfile();
|
||||||
|
my ($unified,$context)=(0,0);
|
||||||
|
|
||||||
|
@_=map {scalar(s/^(PATCH-(CREATE|REMOVE)\/)?(.*)\.diff$/$3/,$_)} @_;
|
||||||
|
|
||||||
|
# state==1 means diff contents, state==0 mens comments
|
||||||
|
$state=0; $found=0; $buf='';
|
||||||
|
while (<I>) {
|
||||||
|
|
||||||
|
# recognize diff type
|
||||||
|
if (!$unified && !$context) {
|
||||||
|
$unified=1 if (/^--- /);
|
||||||
|
$context=1 if (/^\*\*\* /);
|
||||||
|
if (!$unified && !$context) {
|
||||||
|
$buf.=$_;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($unified && /^--- /) || ($context && /^\*\*\* [^\*]*$/)) {
|
||||||
|
$state=1;
|
||||||
|
|
||||||
|
($fsrc,$fdst,)=parse_header($unified,$context,\$_);
|
||||||
|
|
||||||
|
# remove listed files
|
||||||
|
foreach (@_) {
|
||||||
|
if (($fsrc eq $_) || ($fdst eq $_)) {
|
||||||
|
$found=1;
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$found) {
|
||||||
|
print $tmp $buf;
|
||||||
|
$buf='';
|
||||||
|
}
|
||||||
|
|
||||||
|
} elsif ($state==1 && (($unified && !/$unified_contents/) || ($context && !/$context_contents/))) {
|
||||||
|
# start of comments, end of diff contents
|
||||||
|
$found=0;
|
||||||
|
$state=0;
|
||||||
|
$buf='';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($state==0) {
|
||||||
|
$buf.=$_;
|
||||||
|
} elsif (!$found) {
|
||||||
|
print $tmp $_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print $tmp $buf if (!$found);
|
||||||
|
close $tmp;
|
||||||
|
close I;
|
||||||
|
|
||||||
|
# replace archive with temporary file
|
||||||
|
system('cat '.quotemeta($tmpname).'|'.myout($archive,0))==0
|
||||||
|
or error "Can't write to archive";
|
||||||
|
system 'rm -f '.quotemeta($tmpname);
|
||||||
|
}
|
||||||
|
|
||||||
# append diff to archive
|
# append diff to archive
|
||||||
sub copyin
|
sub copyin
|
||||||
{
|
{
|
||||||
my ($archive,$name,$f)=(quotemeta $_[0],$_[1],quotemeta $_[2]);
|
my ($archive,$name,$src)=(@_);
|
||||||
my ($cmd);
|
my ($fsrc,$fdst,$f,@files);
|
||||||
|
my ($unified,$context)=(0,0);
|
||||||
|
my ($cmd1,$cmd2);
|
||||||
|
|
||||||
error "File must have .diff or .patch extension"
|
error 'File must have .diff or .patch extension'
|
||||||
unless $name=~/\.(diff|patch)(\.(bz|bz2|gz|z|Z))?$/;
|
unless $name=~/\.(diff|patch)(\.(bz|bz2|gz|z|Z))?$/;
|
||||||
|
|
||||||
$_=`$file $f`;
|
$file=~s/^(PATCH-(CREATE|REMOVE)\/)?(.*)\.diff$/$3/;
|
||||||
if (/bzip/) {
|
|
||||||
$cmd="$bzip -dc $f";
|
|
||||||
} elsif (/gzip/) {
|
|
||||||
$cmd="$gzip -dc $f";
|
|
||||||
} else {
|
|
||||||
$cmd="cat $f";
|
|
||||||
}
|
|
||||||
|
|
||||||
$_=`$file $archive`;
|
# build filelist
|
||||||
if (/bzip/) {
|
open I, myin($src).'|';
|
||||||
system "$cmd | $bzip -c >> $archive";
|
while (<I>) {
|
||||||
} elsif (/gzip/) {
|
# recognize diff type
|
||||||
system "$cmd | $gzip -c >> $archive";
|
if (!$unified && !$context) {
|
||||||
} else {
|
$unified=1 if (/^--- /);
|
||||||
system "$cmd >> $archive";
|
$context=1 if (/^\*\*\* /);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
# open (compressed) archive for reading
|
if (($unified && /^--- /) || ($context && /^\*\*\* [^\*]*$/)) {
|
||||||
sub openread
|
($fsrc,$fdst,)=parse_header($unified,$context,\$_);
|
||||||
{
|
($f,)=diff_filename($fsrc,$fdst);
|
||||||
my ($archive) = (quotemeta $_[0]);
|
push(@files,$f);
|
||||||
|
}
|
||||||
$_=`$file $archive`;
|
|
||||||
if (/bzip/) {
|
|
||||||
open I, "$bzip -dc $archive |";
|
|
||||||
} elsif (/gzip/) {
|
|
||||||
open I, "$gzip -dc $archive |";
|
|
||||||
} else {
|
|
||||||
open I, "< $ARGV[1]";
|
|
||||||
}
|
}
|
||||||
|
close I;
|
||||||
|
|
||||||
|
# remove overwrited files
|
||||||
|
open I, myin($archive).'|';
|
||||||
|
rm ($archive, map($_.'.diff',@files));
|
||||||
|
close I;
|
||||||
|
|
||||||
|
$cmd1=myin($src);
|
||||||
|
$cmd2=myout($archive,1);
|
||||||
|
system("$cmd1 | $cmd2")==0
|
||||||
|
or error "Can't write to archive";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ($ARGV[0] eq 'list') {
|
if ($ARGV[0] eq 'list') {
|
||||||
openread $ARGV[1];
|
open I, myin($ARGV[1]).'|';
|
||||||
list $ARGV[1];
|
list $ARGV[1];
|
||||||
exit 0;
|
exit 0;
|
||||||
} if ($ARGV[0] eq 'copyout') {
|
} if ($ARGV[0] eq 'copyout') {
|
||||||
openread $ARGV[1];
|
open I, myin($ARGV[1])."|";
|
||||||
copyout ($ARGV[2], $ARGV[3]);
|
copyout ($ARGV[2], $ARGV[3]);
|
||||||
exit 0;
|
exit 0;
|
||||||
|
} if ($ARGV[0] eq 'rm') {
|
||||||
|
open I, myin($ARGV[1])."|";
|
||||||
|
rm ($ARGV[1], $ARGV[2]);
|
||||||
|
exit 0;
|
||||||
|
} if ($ARGV[0] eq 'rmdir') {
|
||||||
|
exit 0;
|
||||||
|
} if ($ARGV[0] eq 'mkdir') {
|
||||||
|
exit 0;
|
||||||
} if ($ARGV[0] eq 'copyin') {
|
} if ($ARGV[0] eq 'copyin') {
|
||||||
copyin ($ARGV[1], $ARGV[2], $ARGV[3]);
|
copyin ($ARGV[1], $ARGV[2], $ARGV[3]);
|
||||||
exit 0;
|
exit 0;
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user