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 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
#!/usr/bin/perl -w
use Getopt::Std;
use File::Basename;
use Cwd qw(abs_path getcwd);
our $prg = $0;
$prg =~ s:(.*)/::;
$0 = "$prg @ARGV";
$| = 1;
$usage = "$prg: fex new created or modified files
usage: $prg [-v] [-n] [-a] [-A] [-t NAME] [-k DAYS] [-w SECONDS] [RECIPIENT]
options:
-v verbose mode
-n do not send notification email
-a also fex files where attributes have been modified
-A fex ALL files, not only new ones
-t use transport NAME, must have suffix .tar .tgz or .zip
-k keep DAYS on server (default: 1)
-w wait SECONDS to collect new files (default: 10)
example:
$prg -v -a framstag\@rus.uni-stuttgart.de
";
$ENV{FUA} = 'autofex';
$opt_h = $opt_v = $opt_n = $opt_a = $opt_A = 0;
$opt_k = 1;
$opt_w = 10;
$opt_t = basename(getcwd()).'.tar';
getopts('hvnaAt:w:k:') or die $usage;
if ($opt_h) {
print $usage;
exit;
}
$wait = 10;
$wait = $1 if $opt_w =~ /^(\d+)$/;
$keep = 1;
$keep = $1 if $opt_k =~ /^(\d+)$/;
$lsof = searchpath('lsof') or die "$prg: lsof not installed\n";
$inotify = searchpath('inotifywait') or die "$prg: inotifywait not installed\n";
$inotify .= ' -qmr -e close_write -e moved_to -e create -e modify';
$inotify .= ' -e attrib' if $opt_a;
@fexsend = ('fexsend');
push @fexsend,'-k',$keep;
push @fexsend,'-n' if $opt_n;
$recipient = join(',',@ARGV) || '.';
if ($opt_t !~ /\.(tar|tgz|zip)$/) {
die "$prg: transport name must have suffix .tar .tgz or .zip\n";
}
print "\$ $inotify .\n" if $opt_v;
open $inotify,"$inotify . |" or die "$prg: cannot run inotifywait - $!\n";
$SIG{ALRM} = \&fexsend;
%files = ();
while (<$inotify>) {
alarm($wait);
print if $opt_v;
chomp;
if (s/ (CREATE|CLOSE|MOVE|ATTRIB)[_,A-Z]* //) {
unless ($files{$_}) {
if ((@s = lstat) and $s[3]>1) {
my $find = "find . -xdev -type f -inum $s[1]";
print "\$ $find\n" if $opt_v;
if (open my $find,"$find 2>/dev/null|") {
while (<$find>) {
chomp;
$files{$_}++;
}
close $find;
}
} else {
$files{$_}++;
}
}
}
if ($opt_v and %files) {
kill 9,$spid if $spid;
local $SIG{CHLD} = 'IGNORE';
$spid = fork();
if (defined $spid and $spid == 0) {
for (my $i = $wait; $i; $i--) {
printf "%3d\r",$i;
sleep 1;
}
exit;
}
}
}
sub fexsend {
local $_;
my @files = keys %files;
if (@files and @files = grep { -r or -l } sort(@files)) {
print "\r";
my @fexsend = @fexsend;
my $archive = $opt_t;
if ($opt_A) {
my @wof = ();
if ($lsof) {
if (open my $lsof,"$lsof +D . 2>/dev/null|") {
while (<$lsof>) {
if (/^\S+\s+\d+\s+\S+\s+\d+w\w*\s+(\S+\s+){4}(.+)/) {
push @wof,$2;
}
}
close $lsof;
}
}
push @fexsend,('-#',join('#',@wof)) if @wof;
@files = ('.');
} else {
my @d = localtime time;
my $t = sprintf('%d%02d%02d_%02d%02d%02d',
$d[5]+1900,$d[4]+1,$d[3],$d[2],$d[1],$d[0]);
$archive =~ s/(\.\w+)$/_$t$1/;
@files = map { s:^\./::;$_ } @files;
}
push @fexsend,('-A',$archive,@files,$recipient);
print "\$ @fexsend\n" if $opt_v;
system(@fexsend);
print "\n";
}
%files = ();
};
sub searchpath {
my ($prg,$path,@PATH);
@PATH = split(':',$ENV{PATH});
foreach $prg (@_) {
foreach $path (@PATH) {
return $prg if -x "$path/$prg";
}
}
return '';
}
|