File: syncfiles.pl

package info (click to toggle)
postfix 3.10.6-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 27,968 kB
  • sloc: ansic: 134,721; makefile: 17,984; sh: 6,966; perl: 2,796; python: 1,448; awk: 158
file content (67 lines) | stat: -rwxr-xr-x 1,644 bytes parent folder | download | duplicates (2)
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;