1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
|
#! /usr/bin/perl -W
#
# Update a set of files in the given chroot dir.
# Decision to update is based on file size and date, -
# if any of these don't match, whole file is copied
# to a temp file and renamed into place.
# In the destination, files are copied with full path.
# Only regular files (or symlinks to regular files)
# are copied.
use strict;
use Fcntl qw(O_RDONLY O_WRONLY O_EXCL O_CREAT S_IMODE S_ISREG);
use Errno qw(EEXIST ENOENT);
my $dest = shift @ARGV;
-d "$dest" or die "not a directory: $dest\n";
foreach my $snm (@ARGV) {
sysopen SRC, $snm, O_RDONLY
and my @sst = stat SRC
or die "unable to open $snm: $!\n";
my $dnm = "$dest/$snm";
if (my @dst = stat $dnm) {
next if $sst[7] == $dst[7] && $sst[9] == $dst[9];
}
die "$snm: not a regular file\n"
unless S_ISREG($sst[2]);
print "updating $snm => $dnm\n";
my $dtnm = "$dnm.tmp";
unlink "$dtnm";
while (!sysopen DST, $dtnm, O_WRONLY|O_EXCL|O_CREAT, 0600) {
$! == ENOENT or die "unable to create $dtnm: $!\n";
my @c = split /\/+/, $snm;
pop @c; # all but last component
my $dd = $dest;
foreach my $c (@c) {
$dd .= '/' . $c;
unless (mkdir $dd, 0755) {
die "unable to mkdir $dd: $!" unless $! == EEXIST;
}
}
}
my $r;
while($r = sysread(SRC,$_,64*1024)) {
syswrite(DST,$_) or die "error writing to $dtnm: $!\n";
}
$r == 0 or die "error reading from $snm: $!\n";
close SRC;
utime $sst[9], $sst[9], \*DST;
chmod S_IMODE($sst[2]), \*DST;
chown $sst[4], $sst[5], \*DST;
close DST and rename $dtnm, $dnm
or die "error renaming $dtnm to $dnm: $!\n";
}
exit 0;
|