• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

lib/H04-Sep-2009-1,074713

net-ftp-scripts/H04-Sep-2009-6251

samples/H04-Sep-2009-8246

scripts/H04-Sep-2009-310193

t/H04-Sep-2009-257183

.gitignoreH A D04-Sep-200968 97

ChangeLogH A D03-Sep-2009720 2815

MANIFESTH A D04-Sep-2009756 3433

META.ymlH A D04-Sep-2009414 1514

Makefile.PLH A D03-Sep-20092 KiB7252

READMEH A D20-Feb-200616.6 KiB423333

TODOH A D20-Feb-2006297 87

releaseH A D25-Sep-2003117 107

README

1NAME
2    Net::FTP::Common - simplify common usages of Net::FTP
3
4SYNOPSIS
5     our %netftp_cfg =
6        (Debug => 1, Timeout => 120);
7
8     our %common_cfg =
9        (
10         #
11         # The first 2 options, if not present,
12         # lead to relying on .netrc for login
13         #
14         User => 'anonymous',
15         Pass => 'tbone@cpan.org',
16
17         #
18         # Other options
19         #
20
21         LocalFile => 'delete.zip'       # setup something for $ez->get
22         Host => 'ftp.fcc.gov',          # overwrite ftp.microsoft.com default
23         RemoteDir  => '/',                    # automatic CD on remote machine to RemoteDir
24         Type => 'A'                     # overwrite I (binary) TYPE default
25         );
26
27      # NOTE WELL!!! one constructor arg is  passed by reference, the
28      # other by value. This is inconsistent, but still it is A Good Thing.
29      # Believe me! I thought about this. And I have a good reason for it:
30      # This is to allow the least modification of legacy Net::FTP source code.
31
32      $ez = Net::FTP::Common->new(\%common_cfg, %netftp_config);
33
34      # can we login to the machine?
35      # Note: it is NEVER necessary to first login before calling
36      # Net::FTP::Common API functions.
37      # This function is just for checking to see if a machine is up.
38      # It is published as part of the API because I have found it
39      # useful when writing FTP scripts which scan for the
40      # first available FTP site to use for upload. The exact
41      # call-and-return semantics for this function are described
42      # and justified below.
43
44      $ez->login or die "cant login: $@";
45
46      # Get a listing of a remote directory
47
48      @listing =    $ez->ls;
49
50      # Let's list a different directory, over-riding and changing the
51      # default directory
52
53      @listing =    $ez->ls(RemoteDir => '/pub/rfcs');
54
55      # Let's list the default dir on several hosts
56
57      @host_listings = map { $ez->ls(Host => $_) } @host_list
58
59      # Let's get the listings of several directories
60
61      @dir_listings  = map { $ez->ls(RemoteDir  => $_) } @dir_list;
62
63      # Let's get a detailed directory listing... (thanks Kevin!)
64
65      %listing =    $ez->dir; # Note this is a hash, not an array return value.
66
67      ### representative output
68
69                'test' => {
70                          'owner' => 'root',
71                          'month' => 'Jan',
72                          'linkTarget' => undef,
73                          'inode' => '1',
74                          'size' => '6',
75                          'group' => 'root',
76                          'yearOrTime' => '1999',
77                          'day' => '27',
78                          'perm' => '-rw-r--r--'
79                        },
80              'ranc' => {
81                          'owner' => 'root',
82                          'month' => 'Oct',
83                          'linkTarget' => undef,
84                          'inode' => '2',
85                          'size' => '4096',
86                          'group' => 'root',
87                          'yearOrTime' => '00:42',
88                          'day' => '31',
89                          'perm' => 'drwxr-xr-x'
90                        }
91
92      # Get a file from the remote machine
93
94      $ez->get(RemoteFile => 'codex.txt', LocalFile => '/tmp/crypto.txt');
95
96      # Get a file from the remote machine, specifying dir:
97      $ez->get(RemoteFile => 'codex.txt', LocalDir => '/tmp');
98
99      # NOTE WELL:  because the prior call set LocalFile, it is still a
100      # part of the object store. In other words this example will try
101      # to store the downloaded file in /tmp/tmp/crypto.txt.
102      # Better to say:
103
104      $ez->get(RemoteFile => 'codex.txt', LocalDir => '/tmp', LocalFile => '');
105
106      # Send a file to the remote machine (*dont* use put!)
107
108      $ez->send(RemoteFile => 'codex.txt');
109
110      # test for a file's existence on the remote machine (using =~)
111
112      @file = $ez->grep(Grep => qr/[A-M]*[.]txt/);
113
114      # test for a file on the remote machine (using eq)
115
116      $ez->exists(RemoteFile => 'needed-file.txt');
117
118      # note this is no more than you manually calling:
119      # (scalar grep { $_ eq 'needed-file.txt' } $ez->ls) > 0;
120
121      # Let's get all output written to STDERR to goto a logfile
122
123      my $ez = Net::FTP::Common->new( { %CFG, STDERR => $logfile }, %netftp_cfg);
124
125    The test suite contains plenty of common examples.
126
127DESCRIPTION
128    This module is intended to make the common uses of Net::FTP a one-line,
129    no-argument affair. In other words, you have 100% programming with
130    Net::FTP. With Net::FTP::Common you will have 95% configuration and 5%
131    programming.
132
133    The way that it makes it a one-line affair is that the common pre-phase
134    of login, cd, file type (binary/ascii) is handled for you. The way that
135    it makes usage a no-argument affair is by pulling things from the hash
136    that configured it at construction time. Should arguments be supplied to
137    any API function, then these changes are applied to the hash of the
138    object's state and used by any future-called API function which might
139    need them.
140
141    Usage of this module is intended to be straightforward and stereotyped.
142    The general steps to be used are:
143
144    * use Net::FTP::Common
145    * Define FTP configuration information
146        This can be inlined within the script but oftentimes this will be
147        stored in a module for usage in many other scripts.
148
149    * Use a Net::FTP::Common API function
150        Note well that you NEVER have to login first. All API functions
151        automatically log you in and change to the configured or specified
152        directory. However, sometimes it is useful to see if you can
153        actually login before attempting to do something else on an FTP
154        site. This is the only time you will need the login() API method.
155
156METHODS
157  "$ez = Net::FTP::Common-"new($net_ftp_common_hashref, %net_ftp_hash)>
158        This method takes initialization information for Net::FTP::Common as
159        well as Net::FTP and returns a new Net::FTP::Common object. Though
160        the calling convention may seem a bit inconsistent, it is actually
161        the best API to support re-use of legacy Net::FTP constructor calls.
162        For example if you had a Net::FTP script which looked like this:
163
164                   use Net::FTP;
165
166                   $ftp = Net::FTP->new("some.host.name", Debug => 0);
167                   $ftp->login("anonymous",'me@here.there');
168                   $ftp->cwd("/pub");
169                   $ftp->get("that.file");
170                   $ftp->quit;
171
172        Here is all you would have to do to convert it to the
173        Net::FTP::Common API:
174
175                   use Net::FTP::Common;
176
177                   $common_cfg = { Host => 'some.host.name',
178                                   User => 'anonymous',
179                                   Pass => 'me@here.there',
180                                   RemoteDir  => '/pub'
181                                   }
182
183                   $ftp = Net::FTP::Common->new($common_cfg, Debug => 0);
184                   $ftp->get("that.file");
185                   $ftp->quit;
186
187  $ez->Common(%config)
188        This is hardly ever necessary to use in isolation as all public API
189        methods will call this as their first step in processing your
190        request. However, it is available should you wish to extend this
191        module.
192
193  $ez->GetCommon($config_key)
194        Again, this is hardly ever necessary to use in isolation. However,
195        it is available should you wish to extend this module.
196
197  $ez->NetFTP(%netftp_config_overrides)
198        This creates and returns a Net::FTP object. In this case, any
199        overrides are shuttled onward to the Net::FTP object as opposed to
200        the configuration of the Net::FTP::Common object.
201
202        Also note that any overrides are preserved and used for all future
203        calls.
204
205  $ez->login(%override)
206        This logs into an FTP server. %override is optional. It relies on 2
207        Common configuration options, "User" and "Pass", which, if not
208        present load to logging in via a .netrc file.
209
210        Normal login with "User" and "Pass" are tested. .netrc logins are
211        not.
212
213  $ez->ls (%override)
214        When given no arguments, "ls()" uses Common configuration
215        information to login to the ftp site, change directory and transfer
216        type and then return an array of directory contents. You may only
217        call this routine in array context and unlike Net::FTP, it returns a
218        list representing the contents of the remote directory and in the
219        case of no files, returns an empty array instead of (like Net::FTP)
220        returning a 1-element array containing the element undef.
221
222        You may give this function any number of configuration arguments to
223        over-ride the predefined configuration options. For example:
224
225         my %dir;
226         my @dir =qw (/tmp /pub /gnu);
227         map { @{$dir{$_}} = $ftp->ls(RemoteDir => $_ ) } @dir;
228
229  %retval = $ez->dir (%override)
230        this function returns a hash NOT an array
231
232        When given no arguments, "dir()" uses Common configuration
233        information to login to the ftp site, change directory and transfer
234        type and then return a hash of with detailed description of
235        directory contents. You may only call this routine and expect a hash
236        back.
237
238        You may give this function any number of configuration arguments to
239        over-ride the predefined configuration options.
240
241        Here is the results of the example from the the test suite
242        (t/dir.t):
243
244         my %retval = $ez->dir;
245
246        # warn "NEW_DIR ...", Dumper(\%retval);
247
248                  'incoming' => {
249                                  'owner' => 'root',
250                                  'month' => 'Jul',
251                                  'linkTarget' => undef,
252                                  'inode' => '2',
253                                  'size' => '4096',
254                                  'group' => 'root',
255                                  'yearOrTime' => '2001',
256                                  'day' => '10',
257                                  'perm' => 'drwxrwxrwx'
258                                },
259
260                  'test' => {
261                              'owner' => 'root',
262                              'month' => 'Jan',
263                              'linkTarget' => undef,
264                              'inode' => '1',
265                              'size' => '6',
266                              'group' => 'root',
267                              'yearOrTime' => '1999',
268                              'day' => '27',
269                              'perm' => '-rw-r--r--'
270                            },
271                  'SEEMORE-database' => {
272                                          'owner' => 'mel',
273                                          'month' => 'Aug',
274                                          'linkTarget' => 'image',
275                                          'inode' => '1',
276                                          'size' => '14',
277                                          'group' => 'lnc',
278                                          'yearOrTime' => '20:35',
279                                          'day' => '15',
280                                          'perm' => 'lrwxrwxrwx'
281                                        },
282                  'holt' => {
283                              'owner' => 'holt',
284                              'month' => 'Jun',
285                              'linkTarget' => undef,
286                              'inode' => '2',
287                              'size' => '4096',
288                              'group' => 'daemon',
289                              'yearOrTime' => '2000',
290                              'day' => '12',
291                              'perm' => 'drwxr-xr-x'
292                            },
293                  'SEEMORE-images' => {
294                                        'owner' => 'mel',
295                                        'month' => 'Aug',
296                                        'linkTarget' => 'images',
297                                        'inode' => '1',
298                                        'size' => '6',
299                                        'group' => 'lnc',
300                                        'yearOrTime' => '20:35',
301                                        'day' => '15',
302                                        'perm' => 'lrwxrwxrwx'
303                                      },
304                  'dlr' => {
305                             'owner' => 'root',
306                             'month' => 'Sep',
307                             'linkTarget' => undef,
308                             'inode' => '2',
309                             'size' => '4096',
310                             'group' => 'root',
311                             'yearOrTime' => '1998',
312                             'day' => '11',
313                             'perm' => 'drwxr-xr-x'
314                           },
315                  'fiser' => {
316                               'owner' => '506',
317                               'month' => 'May',
318                               'linkTarget' => undef,
319                               'inode' => '2',
320                               'size' => '4096',
321                               'group' => 'daemon',
322                               'yearOrTime' => '1996',
323                               'day' => '25',
324                               'perm' => 'drwxr-xr-x'
325                             },
326
327  $ez->mkdir (%override)
328        Makes directories on remote FTP server. Will recurse if Recurse => 1
329        is in object's internal state of overridden at method call time.
330
331        This function has no test case but a working example of its use is
332        in "scripts/rsync.pl". I use it to back up my stuff.
333
334  $ez->exists (%override)
335        uses the "RemoteFile" option of object internal state (or override)
336        to check for a file in a directory listing. This means a "eq", not
337        regex match.
338
339  $ez->grep(%override)
340        uses the "Grep" option of object internal state (or override) to
341        check for a file in a directory listing. This means a regex, not
342        "eq" match.
343
344  $ez->get(%override)
345        uses the "RemoteFile", "LocalFile", and "LocalDir" options of object
346        internal state (or override) to download a file. No slashes need be
347        appended to the end of "LocalDir". If "LocalFile" and "LocalDir"
348        arent defined, then the file is written to the current directory.
349        "LocalDir" must exist: "Net::FTP::Common" will not create it for
350        you.
351
352        All of the following have test cases and work:
353
354          LocalDir    LocalFile  Action
355          --------    ---------  ------
356          null        null       download to local dir using current dir
357          null        file       download to local dir using current dir but spec'ed file
358          dir         null       download to spec'ed dir using remote file name
359          dir         file       download to spec'ed dir using spec'ed file name
360
361        null is any Perl non-true value... 0, '', undef.
362
363  $ez->send(%override)
364TRAPS FOR THE UNWARY
365    *
366          @file = $ez->grep(Grep => '[A-M]*[.]txt');
367
368        is correct
369
370          @file = $ez->grep('[A-M]*[.]txt');
371
372        looks correct but is not because you did not name the argument as
373        you are supposed to.
374
375NOTES
376        * A good example of Net::FTP::Common usage comes with your download:
377            "scripts/rsync.pl"
378
379            Although this script requires AppConfig, Net::FTP::Common in
380            general does not... but go get AppConfig anyway, it rocks the
381            house.
382
383        * A slide talk on Net::FTP::Common in HTML format is available at
384              http://www.metaperl.com
385
386        * subscribe to the mailing list via
387            net-ftp-common-subscribe@yahoogroups.com
388
389TODO
390  Definite
391        * support resumeable downloads
392
393  Musings
394        * Cache directory listings?
395        * parsing FTP list output
396            This output is not standard. We did a fair job for most common
397            Unixen, but if we aspire to the heights of an ange-ftp or other
398            high-quality FTP client, we need something like they have in
399            python:
400
401                 http://freshmeat.net/redir/ftpparsemodule/20709/url_homepage/
402
403Net::FTP FAQ
404        Because I end up fielding so many Net::FTP questions, I feel it best
405        to start a small FAQ.
406
407  Trapping fatal exceptions
408        http://perlmonks.org/index.pl?node_id=317408
409
410SEE ALSO
411        *
412        * http://lftp.yar.ru
413        * Net::FTP::Recursive
414        * Net::FTP::blat
415        * Tie::FTP
416
417AUTHOR
418        T. M. Brannon <tbone@cpan.org>
419
420        dir() method contributed by Kevin Evans (kevin _! a t (* i n s i g
421        ht dot-com
422
423