Package: moreutils
Version: 0.20
Severity: normal
Tags: patch

vidir should do some more sanity checks:

1) it should give an error if control characters (especially newlines) are
   in the filenames

2) if the source of a rename does not exist (and thus the rename will fail
   anyway), vidir should not move an existing target file to a tmpfile.


other bug fixes:

3) if a directory is renamed, vidir should take that into account when
   renaming files in this directory

4) vidir should be able to unlink directories and recursive unlinks

5) if a directory name is passed as name/ to vidir, vidir should not
   add second slash after the name


2)+3) bite if you do "find ... | vidir -" and then do a global search and
replace on a directory name

1), 2), 3) and 5) are fixed in vidir-sanity-checks.patch

A proposed fix for 4) is in vidir-recursive-unlink.patch, though this needs
some more testing. Maybe it would be a good idea to ask before unlinking many
files unless an -f option is given?

The patches assume that the patch from #404753 is applied first, but should
be easy to adapt.


-- System Information:
Debian Release: 4.0
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.17-k1
Locale: [EMAIL PROTECTED], [EMAIL PROTECTED] (charmap=ISO-8859-15)

Versions of packages moreutils depends on:
ii  libc6                       2.3.6.ds1-13 GNU C Library: Shared libraries
ii  perl                        5.8.8-7      Larry Wall's Practical Extraction 

moreutils recommends no packages.

-- no debconf information
--- /usr/local/bin/vidir        2006-12-22 13:18:24.335896000 +0100
+++ vidir       2007-02-23 09:52:35.763423000 +0100
@@ -88,13 +88,17 @@ foreach my $item (@ARGV) {
                open(STDIN, "/dev/tty") || die "reopen: $!\n";
        }
        elsif (-d $item) {
+               $item =~ s{/?$}{/};
                opendir(DIR, $item) || die "$0: cannot read $item: $!\n";
-               push @dir, map { "$item/$_" } sort readdir(DIR);
+               push @dir, map { "$item$_" } sort readdir(DIR);
                closedir DIR;
        }
        else {
                push @dir, $item;
        }
+       if ( grep(/[[:cntrl:]]/, @dir) ) {
+               die "control characters in filenames are not supported\n";
+       }
 }
        
 my $tmp=File::Temp->new(template => "dirXXXXX");
@@ -146,6 +150,12 @@ while (<IN>) {
                        next unless length $name;
                        my $src=$item{$num};
                        
+                       if (! (-e $src || -l $src) ) {
+                               print STDERR "$src does not exist\n";
+                               delete $item{$num};
+                               next;
+                       }
+                       
                        # deal with swaps
                        if (-e $name || -l $name) {
                                my $tmp=$name."~";
@@ -173,8 +183,15 @@ while (<IN>) {
                                $error=1;
                                $name=$src;
                        }
-                       elsif ($verbose) {
-                               print "'$src' => '$name'\n";
+                       else {
+                               if (-d $name) {
+                                       foreach (values %item) {
+                                               s/^\Q$src\E/$name/;
+                                       }
+                               }
+                               if ($verbose) {
+                                       print "'$src' => '$name'\n";
+                               }
                        }
                }
                $done{$num}=$name;
--- vidir.n1    2007-02-23 10:11:14.718341000 +0100
+++ vidir       2007-02-23 10:09:21.595236000 +0100
@@ -246,12 +246,22 @@
 close IN;
 unlink($tmp.'~') if -e $tmp.'~';
 
-foreach my $item (sort values %item) {
-       if (! unlink($item)) {
+sub rm {
+       my $file = shift;
+       if (-d $file) {
+               return rmdir $file;
+       }
+       else {
+               return unlink $file;
+       }
+}
+
+foreach my $item (reverse sort values %item) {
+       if (! rm($item)) {
                print STDERR "$0: failed to remove $item: $!\n";
                $error=1;
        }
-       if ($verbose) {
+       elsif ($verbose) {
                print "removed '$item'\n";
        }
 }

Reply via email to