2 |
2 |
3 use v5.10; |
3 use v5.10; |
4 use strict; |
4 use strict; |
5 use warnings; |
5 use warnings; |
6 |
6 |
7 my $to = 600; |
7 use File::Basename; |
8 my $i = "$ENV{HOME}/incoming"; |
8 use Linux::Inotify2; |
9 |
9 |
10 # XXX |
10 #my $to = 600; |
11 #$| = 1; |
11 my $to = 60; |
12 |
12 |
13 my $s = time; |
13 my $inotify = new Linux::Inotify2 |
|
14 or die "unable to create new inotify object: $!"; |
|
15 $inotify->blocking(0); |
14 |
16 |
15 if ($ARGV[0] =~ m,^(\Q$i\E/)?repair_.*\.changes$,) { |
17 my %size; |
16 my $d = "$i/$&"; |
18 my $exit_after; |
17 $d =~ s/\.changes$/.deb/; |
|
18 my $p = qr/^\Q$d\E:( [0-9]+[cefFrm]*)+$/; |
|
19 |
19 |
20 { # 'last' needs this in a 'do ... while' loop? see 'man perlsyn' |
20 my $ME = basename $0; |
21 do { |
|
22 |
21 |
23 if (-e $d) { |
22 sub delay_exit { my $fn = shift; $exit_after = time + $to if $size{basename $fn}; } |
|
23 sub verify_size { |
|
24 my $fn = shift; |
|
25 delay_exit $fn; |
|
26 my $bn = basename $fn; |
|
27 my $s = -s $fn; |
|
28 delete $size{$bn} if defined $s and $s >= $size{$bn}; |
|
29 } |
24 |
30 |
25 $_ = qx(fuser $d); |
31 my $incoming = "$ENV{HOME}/incoming"; |
|
32 my $nfiles = 0; |
|
33 my $c = "$incoming/$ARGV[0]"; |
26 |
34 |
27 die "output from 'fuser' expected but got none - is it in \$PATH?" unless defined; |
35 # first setup a file creation watch on the incoming directory (we cannot set |
28 last if $_ eq ''; |
36 # watches on objects that dont exist yet); then *if* a file which is listed in |
29 die "unexpected output - please check" unless /$p/; |
37 # the changes file is created inside that directory then setup file |
|
38 # {modification,close} watches on it; we need the modification watch to reset |
|
39 # the 'timeout counter' and verify the file size in the close watch. ofcourse |
|
40 # we need the list of files from the changes file first; we build it here |
|
41 open C, '<', $c or die "Can't open '<$c': $!\n"; |
|
42 my $skip = 1; |
|
43 while (<C>) { |
|
44 no warnings qw(syntax); |
|
45 if (/^files:\s*$/i) { $skip = 0; next; } |
|
46 next if $skip; |
|
47 unless (/^ ([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +([^ \n]+) *$/) { $skip = 1; next; } |
|
48 use warnings; |
|
49 $size{$5} = $2; |
|
50 $nfiles++; |
|
51 } |
|
52 close C; |
|
53 warn "$ME: no files found in changes file.\n" unless $nfiles; |
30 |
54 |
31 } |
55 $inotify->watch($incoming, IN_MODIFY, sub { my $e = shift; delay_exit $e->fullname; } ) or warn "Can't watch: $!"; |
|
56 $inotify->watch($incoming, IN_CLOSE, sub { my $e = shift; verify_size $e->fullname; } ) or warn "Can't watch: $!"; |
32 |
57 |
33 die "timeout exceeded while waiting for package file '$d'" if time - $s > $to; |
58 # do initial check on file in case its upload is already finished |
|
59 verify_size "$incoming/$_" for keys %size; |
34 |
60 |
35 } while (sleep 10); |
61 my $done = 0; |
|
62 do { |
36 |
63 |
|
64 warn scalar localtime; |
|
65 |
|
66 $inotify->poll; |
|
67 if (time > $exit_after) { |
|
68 warn "$ME: file upload timed out.\n"; |
|
69 $done = 1; |
37 } |
70 } |
38 |
71 |
39 } |
72 $done = 1 unless %size; |
|
73 exec "$ENV{HOME}/bin/rpi" if $done; |
40 |
74 |
41 exec "$ENV{HOME}/bin/rpi"; |
75 } while (sleep 1); |