]> git.donarmstrong.com Git - infobot.git/blob - src/Net.pl
53bde522a6168d8f23275375bc9a3974f5b3b86c
[infobot.git] / src / Net.pl
1 #
2 #   Net.pl: FTP//HTTP helper
3 #   Author: xk <xk@leguin.openprojects.net>
4 #  Version: v0.1 (20000309)
5 #  Created: 20000309
6 #
7
8 if (&IsParam("useStrict")) { use strict; }
9
10 use vars qw(%ftp);
11
12 # Usage: &ftpGet($host,$dir,$file,[$lfile]);
13 sub ftpGet {
14     my ($host,$dir,$file,$lfile) = @_;
15     my $verbose_ftp     = 1;
16
17     return unless &loadPerlModule("Net::FTP");
18
19     &status("FTP: opening connection to $host.") if ($verbose_ftp);
20     my $ftp = Net::FTP->new($host,
21         'Timeout'       => 600,
22         'BlockSize'     => 1024,
23     );
24
25     if ($@) {
26         &ERROR("FTP: $@.");
27         return;
28     }
29
30     # login.
31     if ($ftp->login()) {
32         &status("FTP: logged in successfully.") if ($verbose_ftp);
33     } else {
34         &status("FTP: login failed.");
35         $ftp->quit();
36         return 0;
37     }
38
39     # change directories.
40     if ($ftp->cwd($dir)) {
41         &status("FTP: changed dirs to $dir.") if ($verbose_ftp);
42     } else {
43         &status("FTP: cwd dir ($dir) does not exist.");
44         $ftp->quit();
45         return 0;
46     }
47
48     # get the size of the file.
49     my ($size, $lsize);
50     if ($size = $ftp->size($file)) {
51         &status("FTP: file size is $size") if ($verbose_ftp);
52         my $thisfile    = $file || $lfile;
53         &DEBUG("lfile => '$lfile'.");
54         if ( -f $thisfile) {
55             $lsize      = -s $thisfile;
56             if ($_ != $lsize) {
57                 &status("FTP: local size is $lsize; downloading.") if ($verbose_ftp);
58             } else {
59                 &status("FTP: same size; skipping.");
60                 &system("touch $thisfile");     # lame hack.
61                 $ftp->quit();
62                 return 1;
63             }
64         }
65     } else {
66         &status("FTP: file does not exist.");
67         $ftp->quit();
68         return 0;
69     }
70
71     my $start_time = &gettimeofday();
72     if (defined $lfile) {
73         &status("FTP: getting $file as $lfile.") if ($verbose_ftp);
74         $ftp->get($file,$lfile);
75     } else {
76         &status("FTP: getting $file.") if ($verbose_ftp);
77         $ftp->get($file);
78     }
79     &DEBUG("FTP: remsize => '$size'.");
80     if (defined $lsize) {
81         &DEBUG("FTP: locsize => '$lsize'.");
82         if ($size != $lsize) {
83             &WARN("FTP: downloaded file seems truncated. FIXME.");
84         }
85     }
86
87     my $delta_time = &gettimeofday() - $start_time;
88     if ($delta_time > 0 and $verbose_ftp) {
89         &status(sprintf("FTP: %.02f sec to complete.", $delta_time));
90         my ($rateunit,$rate) = ("B", $size / $delta_time);
91         if ($rate > 1024) {
92             $rate /= 1024;
93             $rateunit = "kB";
94         }
95         &status(sprintf("FTP: %.01f ${rateunit}/sec.", $rate));
96     }
97
98     $ftp->quit();
99
100     return 1;
101 }
102
103 # Usage: &ftpList($host,$dir);
104 sub ftpList {
105     my ($host,$dir) = @_;
106     my $verbose_ftp = 1;
107
108     return unless &loadPerlModule("Net::FTP");
109
110     &status("FTP: opening connection to $host.") if ($verbose_ftp);
111     my $ftp = Net::FTP->new($host,'Timeout'=>600);
112
113     if ($@) {
114         &ERROR("FTP: $@.");
115         return;
116     }
117
118     # login.
119     if ($ftp->login()) {
120         &status("FTP: logged in successfully.") if ($verbose_ftp);
121     } else {
122         &status("FTP: login failed.");
123         $ftp->quit();
124         return;
125     }
126
127     # change directories.
128     if ($ftp->cwd($dir)) {
129         &status("FTP: changed dirs to $dir.") if ($verbose_ftp);
130     } else {
131         &status("FTP: cwd dir ($dir) does not exist.");
132         $ftp->quit();
133         return;
134     }
135
136     &status("FTP: doing ls.") if ($verbose_ftp);
137     foreach ($ftp->dir()) {
138         # modes d uid gid size month day time file.
139         if (/^(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+) (\S{3})\s+(\d+) \d+:\d+ (.*)$/) {
140             # name = size.
141             $ftp{$8} = $5;
142         } else {
143             &DEBUG("FTP: UNKNOWN  => '$_'.");
144         }
145     }
146     &status("FTP: ls done. ". scalar(keys %ftp) ." entries.");
147     $ftp->quit();
148
149     return %ftp;
150 }
151
152 ### LWP.
153 # Usage: &getURL($url, [$post]);
154 sub getURL {
155     my ($url,$post) = @_;
156     my ($ua,$res,$req);
157
158     return unless &loadPerlModule("LWP::UserAgent");
159
160     $ua = new LWP::UserAgent;
161     $ua->proxy('http', $param{'httpProxy'}) if &IsParam("httpProxy");
162
163     if (defined $post) {
164         $req = new HTTP::Request('POST',$url);
165         $req->content_type('application/x-www-form-urlencoded');
166         $req->content($post);
167     } else {
168         $req = new HTTP::Request('GET',$url);
169     }
170
171     &status("getURL: getting '$url'");
172     my $time = time();
173     $res = $ua->request($req);
174     my $size = length($res->content);
175     if ($size and time - $time) {
176         my $rate = int( $size/1000/(time - $time) );
177         &status("getURL: Done (took ".&Time2String(time - $time).", $rate k/sec)");
178     }
179
180     # return NULL upon error.
181     return unless ($res->is_success);
182
183     return(split '\n', $res->content);
184 }
185
186 sub getURLAsFile {
187     my ($url,$file) = @_;
188     my ($ua,$res,$req);
189
190     return unless &loadPerlModule("LWP::Simple");
191
192 ### PROXY NOT SUPPORTED WITH SIMPLE?
193 ###    $ua->proxy('http', $param{'httpProxy'}) if &IsParam("httpProxy");
194     my $time    = time();
195     &status("getURLAsFile: getting '$url' as '$file'");
196     my $retval  = getstore($url, $file);
197     my $delta_time      = time() - $time;
198     if ($delta_time) {
199         my $size = -s $file || 0;
200         my $rate = int($size / $delta_time / 1024);
201         &status("getURLAsFile: Done. ($rate kB/sec)");
202     }
203
204     return $retval;
205 }
206
207 1;