Changeset 2263


Ignore:
Timestamp:
2001-04-03T11:45:46+12:00 (23 years ago)
Author:
sjboddie
Message:

Altered the way filecopy.pl works to avoid infinite recursion when the
destination directory is a subdirectory of one of the source directories.
Also doesn't now follow symbolic links by default and makes certain that
it bails out when the collectors "stop building" button is pressed.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/gsdl/bin/script/filecopy.pl

    r2137 r2263  
    4646
    4747    print STDERR "  options:\n";
     48    print STDERR "   -follow_links           Follow symbolic links when recursing directory\n";
     49    print STDERR "                           structure\n";
    4850    print STDERR "   -collectdir directory   Collection directory (defaults to " .
    4951    &util::filename_cat ($ENV{'GSDLHOME'}, "collect") . ")\n";
     
    5254}
    5355
    54 sub download_files
    55 {
    56     my $dirname = pop(@_);
     56sub get_file_list {
     57    my $dirhash = shift @_;
     58    my $filehash = shift @_;
     59    my $dirname = shift @_;
     60
    5761    my $full_importname
    5862    = &util::filename_cat($collectdir, $dirname, "import");
    5963
    60     # split argv into 2 lists: files and directories
    61     my (@files,@dirs) = ((),());
    62     my $a;
    63     foreach $a (@_)
    64     {
    65     $a =~ s/^\"//;
    66     $a =~ s/\"$//;
     64    # check for .kill file
     65    if (-e &util::filename_cat($collectdir, $dirname, ".kill")) {
     66    print $out "filecopy.pl killed by .kill file\n";
     67    die "\n";
     68    }
    6769
    68     if (-e $a)
    69     {
    70         if (-d $a)
    71         {
    72         push(@dirs,$a);
    73         }
    74         else
    75         {
    76         push(@files,$a);
    77         }
    78     }
    79     else
    80     {
    81         print $out "Error: filename '$a' does not exist\n";
    82     }
    83     }
    84    
    85     if (scalar(@files)>0)
    86     {
    87     my $f; 
    88     foreach $f (@files)
    89     {
    90         my $src_file = $f;
    91         my $dst_file = &get_dst_dir ($full_importname,$f);
     70    foreach my $file (@_) {
    9271
    93         my $do_copy = "no";
    94         if (-e $dst_file)
    95         {
    96         # compare file dates
    97         my $src_stat = stat($src_file);
    98         my $dst_stat = stat($dst_file);
     72    $file =~ s/^\"//;
     73    $file =~ s/\"$//;
    9974
    100         if ($src_stat->mtime > $dst_stat->mtime)
    101         {
    102             $do_copy = "yes";
    103         }
    104         }
    105         else
    106         {
    107         $do_copy = "yes";
     75    if (!$follow_links && -l $file) {
     76        # do nothing as we don't want to follow symbolic links
     77
     78    } elsif (-d $file) {
     79        my $dst_dir = &get_dst_dir ($full_importname, $file);
     80        # add this directory to the list to be created
     81        $dirhash->{$dst_dir} = 1;
     82
     83        # read in dir
     84            if (!opendir (DIR, $file)) {
     85                print $out "Error: Could not open directory $file\n";
     86            } else {
     87                my @sub_files = grep (!/^\.\.?$/, readdir (DIR));
     88                closedir DIR;
     89        map { $_ = &util::filename_cat($file, $_); } @sub_files;
     90        &get_file_list($dirhash, $filehash, $dirname, @sub_files);
    10891        }
    10992
    110         if ($do_copy eq "yes")
    111         {
    112         my $dst_dir = &File::Basename::dirname($dst_file);
    113         &util::mk_all_dir($dst_dir) unless -d $dst_dir;
    114         print $out "Copying $src_file-->$dst_file\n";
    115         &util::cp($src_file,$dst_file);
    116         }
    117     }
    118     }
     93    } else {
     94        my $dst_file = &get_dst_dir ($full_importname, $file);
    11995
    120 
    121     if (scalar(@dirs)>0)
    122     {
    123     my $d; 
    124     foreach $d (@dirs)
    125     {
    126         my $src_dir = $d;
    127         my $dst_dir = &get_dst_dir ($full_importname, $d);
    128         if (!-e $dst_dir)
    129         {
    130         # create it if it doesn't exist
    131         &util::mk_all_dir($dst_dir);
    132         }
    133 
    134         # read in dir
    135             if (!opendir (INDIR, $d))
    136         {
    137                 print $out "Error: Could not open directory $d\n";
    138             }
    139         else
    140         {
    141                 my @sub_files = grep (!/^\.\.?$/, readdir (INDIR));
    142                 closedir (INDIR);
    143 
    144         map { $_ = &util::filename_cat($d,$_); } @sub_files;
    145         download_files(@sub_files,$dirname);
     96        if (-e $dst_file) {
     97        # if destination file exists already we'll only copy it if
     98        # the source file is newer
     99        my $src_stat = stat($file);
     100        my $dst_stat = stat($dst_file);
     101        $filehash->{$file} = $dst_file if ($src_stat->mtime > $dst_stat->mtime);
     102        } else {
     103        $filehash->{$file} = $dst_file;
    146104        }
    147105    }
     
    149107}
    150108
    151 sub main
    152 {
     109
     110sub main {
     111
    153112    if (!parsargv::parse(\@ARGV,
     113             'follow_links', \$follow_links,
    154114             'collectdir/.*/', \$collectdir,
    155115             'out/.*/STDERR', \$out)) {
     
    162122    }
    163123
     124    my $collection = pop @ARGV;
     125
    164126    my $close_out = 0;
    165127    if ($out !~ /^(STDERR|STDOUT)$/i) {
     
    170132    $out->autoflush(1);
    171133
    172     download_files(@ARGV);
     134    # first compile a list of all the files we want to copy (we do it this
     135    # way rather than simply copying the files as we recurse the directory
     136    # structure to avoid nasty infinite recursion if the directory we're
     137    # copying to happens to be a subdirectory of one of the directories
     138    # we're copying from)
     139    my $dirhash = {};
     140    my $filehash = {};
     141    &get_file_list($dirhash, $filehash, $collection, @ARGV);
     142
     143    # create all the required destination directories
     144    my $count = 0;
     145    foreach my $dir (keys %$dirhash) {
     146    # check for .kill file
     147    if (($count ++ % 20 == 0) &&
     148        (-e &util::filename_cat($collectdir, $collection, ".kill"))) {
     149        print $out "filecopy.pl killed by .kill file\n";
     150        die "\n";
     151    }
     152    &util::mk_all_dir($dir);
     153    }
     154
     155    # copy all the files
     156    foreach my $file (keys %$filehash) {
     157    # check for .kill file
     158    if (($count ++ % 20 == 0) &&
     159        (-e &util::filename_cat($collectdir, $collection, ".kill"))) {
     160        print $out "filecopy.pl killed by .kill file\n";
     161        die "\n";
     162    }
     163    print $out "copying $file --> $filehash->{$file}\n";
     164    &util::cp($file, $filehash->{$file});
     165    }
    173166
    174167    close OUT if $close_out;
     
    183176    $dir =~ s/^[a-z]:[\\\/]//i;
    184177    }
    185     return &util::filename_cat($full_importname,$dir);
     178    return &util::filename_cat($full_importname, $dir);
    186179}
    187180
Note: See TracChangeset for help on using the changeset viewer.