]> git.pld-linux.org Git - projects/distfiles.git/blob - file-fetcher.pl
- added flags support
[projects/distfiles.git] / file-fetcher.pl
1 #!/usr/bin/perl -w
2 #
3
4 $spool_dir = "./spool";
5 $ftp_dir = "./ftp";
6 $email_cc = "";
7
8
9 @md5 = ();
10 %url = ();
11 $problems = "";
12 $normal_out = "";
13 $requester = "";
14 $file = "";
15 $fetched_count = 0;
16 $force_reply = 0;
17
18 # try lookup some file in spool, exit if it cannot be done
19 sub find_file_in_spool()
20 {
21   opendir(DIR, $spool_dir) || die "can't opendir $spool_dir: $!";
22   while (1) {
23     my $f = readdir(DIR);
24     defined $f or last;
25     -f "$spool_dir/$f" or next;
26     $file = "$spool_dir/$f";
27     last;
28   }
29   closedir(DIR);
30
31   exit 0 if ($file eq "");
32 }
33
34 # read file from spool, and try unlink it. if cannot unlink -- exit
35 # sets $requester (email), $problems, @md5 (arrays of md5's) 
36 # and %url (map from md5 to urls)
37 sub read_spool_file()
38 {
39   open(F, "< $file") || exit 0;
40   $requester = <F>;
41   chomp $requester;
42   $requester =~ /^[a-zA-Z_\-0-9\@\.]+$/ 
43         or die "$file: evil requester: $requester";
44   my $flags = <F>;
45   $force_reply++ if ($flags =~ /force-reply/);
46         
47   while (<F>) {
48     if (/^ERROR/) {
49       s/^ERROR: //;
50       $problems .= $_;
51     }
52     /^([a-f0-9]{32})\s+((ftp|http):\/\/([a-z0-9A-Z:\+\~\.\-\/_]|\%[0-9])+)\s*$/ 
53         or die "$file: corrupted";
54     push @md5, $1;
55     $url{$1} = $2;
56     /\/$/ and die "$file: cannot fetch dir";
57   }
58   close(F);
59
60   unlink($file) || exit 0;
61 }
62
63 sub file_path($$)
64 {
65   my ($md5, $url) = @_;
66   
67   $md5 =~ /^(.)(.)/;
68   my $md5_dir = "$ftp_dir/by-md5/$1/$2/$md5";
69   $url =~ /\/([^\/]+)$/ or die;
70   my $basename = $1;
71   return "$md5_dir/$basename";
72 }
73
74 sub install_dir
75 {
76   my $dir = shift;
77   return if (-e $dir);
78   $dir =~ /(.*)\/[^\/]+$/ and install_dir($1);
79   mkdir($dir);
80 }
81
82 sub move_file($$)
83 {
84   my ($md5, $url) = @_;
85
86   my $path = file_path($md5, $url);
87   
88   $path =~ /(.*)\/[^\/]+$/ and install_dir($1);
89   
90   if (system("mv -f \"tmp/$md5\" \"$path\"")) {
91     $problems .= "FATAL: cannot mv file ($url)\n";
92   } else {
93     $normal_out .= "STORED: $url ($md5, " .  (-s $path) . " bytes)\n";
94     $fetched_count++;
95   }
96 }
97
98 sub fetch_file($$)
99 {
100   my ($md5, $url) = @_;
101   my $out = "";
102   my $cmd = "wget -nv -O tmp/$md5 \"$url\"";
103   
104   my $path = file_path($md5, $url);
105   if (-f $path) {
106     $normal_out .= "ALREADY GOT: $url ($md5, " .  (-s $path) . " bytes)\n";
107     return;
108   }
109     
110   open(W, "$cmd 2>&1 |");
111   while (<W>) {
112     /URL:.*\s+\-\>\s+.*/ and next;
113     $out .= $_;
114   }
115   close(W);
116   if ($out ne "") {
117     $problems .= "$cmd:\n$out\n\n";
118   }
119   if (-f "tmp/$md5" && -s "tmp/$md5" > 0) {
120     my $computed_md5 = `md5sum tmp/$md5`;
121     $computed_md5 =~ /^([a-f0-9]{32})/ and $computed_md5 = $1;
122     if ($computed_md5 ne $md5) {
123       $problems .= "FATAL: $url md5 mismatch, needed $md5, got $computed_md5\n";
124     } else {
125       move_file($md5, $url);
126     }
127   } else {
128     $problems .= "FATAL: $url ($md5) was not fetched\n";
129   }
130 }
131
132 sub fetch_files()
133 {
134   $problems .= "\n\n" if ($problems ne "");
135   foreach $md5 (@md5) {
136     fetch_file($md5, $url{$md5});
137   }
138 }
139
140 sub send_email()
141 {
142   #open(EMAIL, "| /usr/sbin/sendmail -t");
143   open(EMAIL, "| cat");
144   my $marker = "OK";
145   if ($problems ne "") {
146     $marker = "ERRORS";
147   }
148   print EMAIL 
149 "From: distfiles <feedback\@pld-linux.org>
150 To: $requester
151 Cc: $email_cc
152 Subject: [distfiles] sources fetched $marker
153 Message-ID: <$$." . time . "\@distfiles.pld-linux.org>
154 X-distfiles-program: file-fetcher.pl
155 X-distfiles-version: " . '$Id$' . "
156
157 $problems
158 Files fetched: $fetched_count
159
160 $normal_out
161
162 -- 
163 Virtually yours: distfiles.
164 ";
165   close(EMAIL) or die;
166 }
167
168 find_file_in_spool();
169 read_spool_file();
170 fetch_files();
171 send_email() unless (!$force_reply and $problems eq "" and $fetched_count == 0);
This page took 0.034872 seconds and 3 git commands to generate.