This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Upgrade libnet from version 3.07 to 3.08
[perl5.git] / cpan / libnet / lib / Net / Netrc.pm
1 # Net::Netrc.pm
2 #
3 # Versions up to 2.13 Copyright (c) 1995-1998 Graham Barr <gbarr@pobox.com>.
4 # All rights reserved.
5 # Changes in Version 2.13_01 onwards Copyright (C) 2013-2014 Steve Hay.  All
6 # rights reserved.
7 # This module is free software; you can redistribute it and/or modify it under
8 # the same terms as Perl itself, i.e. under the terms of either the GNU General
9 # Public License or the Artistic License, as specified in the F<LICENCE> file.
10
11 package Net::Netrc;
12
13 use 5.008001;
14
15 use strict;
16 use warnings;
17
18 use Carp;
19 use FileHandle;
20
21 our $VERSION = "3.08";
22
23 our $TESTING;
24
25 my %netrc = ();
26
27 sub _readrc {
28   my($class, $host) = @_;
29   my ($home, $file);
30
31   if ($^O eq "MacOS") {
32     $home = $ENV{HOME} || `pwd`;
33     chomp($home);
34     $file = ($home =~ /:$/ ? $home . "netrc" : $home . ":netrc");
35   }
36   else {
37
38     # Some OS's don't have "getpwuid", so we default to $ENV{HOME}
39     $home = eval { (getpwuid($>))[7] } || $ENV{HOME};
40     $home ||= $ENV{HOMEDRIVE} . ($ENV{HOMEPATH} || '') if defined $ENV{HOMEDRIVE};
41     if (-e $home . "/.netrc") {
42       $file = $home . "/.netrc";
43     }
44     elsif (-e $home . "/_netrc") {
45       $file = $home . "/_netrc";
46     }
47     else {
48       return unless $TESTING;
49     }
50   }
51
52   my ($login, $pass, $acct) = (undef, undef, undef);
53   my $fh;
54   local $_;
55
56   $netrc{default} = undef;
57
58   # OS/2 and Win32 do not handle stat in a way compatible with this check :-(
59   unless ($^O eq 'os2'
60     || $^O eq 'MSWin32'
61     || $^O eq 'MacOS'
62     || $^O =~ /^cygwin/)
63   {
64     my @stat = stat($file);
65
66     if (@stat) {
67       if ($stat[2] & 077) { ## no critic (ValuesAndExpressions::ProhibitLeadingZeros)
68         carp "Bad permissions: $file";
69         return;
70       }
71       if ($stat[4] != $<) {
72         carp "Not owner: $file";
73         return;
74       }
75     }
76   }
77
78   if ($fh = FileHandle->new($file, "r")) {
79     my ($mach, $macdef, $tok, @tok) = (0, 0);
80
81     while (<$fh>) {
82       undef $macdef if /\A\n\Z/;
83
84       if ($macdef) {
85         push(@$macdef, $_);
86         next;
87       }
88
89       s/^\s*//;
90       chomp;
91
92       while (length && s/^("((?:[^"]+|\\.)*)"|((?:[^\\\s]+|\\.)*))\s*//) {
93         (my $tok = $+) =~ s/\\(.)/$1/g;
94         push(@tok, $tok);
95       }
96
97     TOKEN:
98       while (@tok) {
99         if ($tok[0] eq "default") {
100           shift(@tok);
101           $mach = bless {}, $class;
102           $netrc{default} = [$mach];
103
104           next TOKEN;
105         }
106
107         last TOKEN
108           unless @tok > 1;
109
110         $tok = shift(@tok);
111
112         if ($tok eq "machine") {
113           my $host = shift @tok;
114           $mach = bless {machine => $host}, $class;
115
116           $netrc{$host} = []
117             unless exists($netrc{$host});
118           push(@{$netrc{$host}}, $mach);
119         }
120         elsif ($tok =~ /^(login|password|account)$/) {
121           next TOKEN unless $mach;
122           my $value = shift @tok;
123
124           # Following line added by rmerrell to remove '/' escape char in .netrc
125           $value =~ s/\/\\/\\/g;
126           $mach->{$1} = $value;
127         }
128         elsif ($tok eq "macdef") {
129           next TOKEN unless $mach;
130           my $value = shift @tok;
131           $mach->{macdef} = {}
132             unless exists $mach->{macdef};
133           $macdef = $mach->{machdef}{$value} = [];
134         }
135       }
136     }
137     $fh->close();
138   }
139 }
140
141
142 sub lookup {
143   my ($class, $mach, $login) = @_;
144
145   $class->_readrc()
146     unless exists $netrc{default};
147
148   $mach ||= 'default';
149   undef $login
150     if $mach eq 'default';
151
152   if (exists $netrc{$mach}) {
153     if (defined $login) {
154       foreach my $m (@{$netrc{$mach}}) {
155         return $m
156           if (exists $m->{login} && $m->{login} eq $login);
157       }
158       return;
159     }
160     return $netrc{$mach}->[0];
161   }
162
163   return $netrc{default}->[0]
164     if defined $netrc{default};
165
166   return;
167 }
168
169
170 sub login {
171   my $me = shift;
172
173   exists $me->{login}
174     ? $me->{login}
175     : undef;
176 }
177
178
179 sub account {
180   my $me = shift;
181
182   exists $me->{account}
183     ? $me->{account}
184     : undef;
185 }
186
187
188 sub password {
189   my $me = shift;
190
191   exists $me->{password}
192     ? $me->{password}
193     : undef;
194 }
195
196
197 sub lpa {
198   my $me = shift;
199   ($me->login, $me->password, $me->account);
200 }
201
202 1;
203
204 __END__
205
206 =head1 NAME
207
208 Net::Netrc - OO interface to users netrc file
209
210 =head1 SYNOPSIS
211
212     use Net::Netrc;
213
214     $mach = Net::Netrc->lookup('some.machine');
215     $login = $mach->login;
216     ($login, $password, $account) = $mach->lpa;
217
218 =head1 DESCRIPTION
219
220 C<Net::Netrc> is a class implementing a simple interface to the .netrc file
221 used as by the ftp program.
222
223 C<Net::Netrc> also implements security checks just like the ftp program,
224 these checks are, first that the .netrc file must be owned by the user and 
225 second the ownership permissions should be such that only the owner has
226 read and write access. If these conditions are not met then a warning is
227 output and the .netrc file is not read.
228
229 =head1 THE .netrc FILE
230
231 The .netrc file contains login and initialization information used by the
232 auto-login process.  It resides in the user's home directory.  The following
233 tokens are recognized; they may be separated by spaces, tabs, or new-lines:
234
235 =over 4
236
237 =item machine name
238
239 Identify a remote machine name. The auto-login process searches
240 the .netrc file for a machine token that matches the remote machine
241 specified.  Once a match is made, the subsequent .netrc tokens
242 are processed, stopping when the end of file is reached or an-
243 other machine or a default token is encountered.
244
245 =item default
246
247 This is the same as machine name except that default matches
248 any name.  There can be only one default token, and it must be
249 after all machine tokens.  This is normally used as:
250
251     default login anonymous password user@site
252
253 thereby giving the user automatic anonymous login to machines
254 not specified in .netrc.
255
256 =item login name
257
258 Identify a user on the remote machine.  If this token is present,
259 the auto-login process will initiate a login using the
260 specified name.
261
262 =item password string
263
264 Supply a password.  If this token is present, the auto-login
265 process will supply the specified string if the remote server
266 requires a password as part of the login process.
267
268 =item account string
269
270 Supply an additional account password.  If this token is present,
271 the auto-login process will supply the specified string
272 if the remote server requires an additional account password.
273
274 =item macdef name
275
276 Define a macro. C<Net::Netrc> only parses this field to be compatible
277 with I<ftp>.
278
279 =back
280
281 =head1 CONSTRUCTOR
282
283 The constructor for a C<Net::Netrc> object is not called new as it does not
284 really create a new object. But instead is called C<lookup> as this is
285 essentially what it does.
286
287 =over 4
288
289 =item lookup ( MACHINE [, LOGIN ])
290
291 Lookup and return a reference to the entry for C<MACHINE>. If C<LOGIN> is given
292 then the entry returned will have the given login. If C<LOGIN> is not given then
293 the first entry in the .netrc file for C<MACHINE> will be returned.
294
295 If a matching entry cannot be found, and a default entry exists, then a
296 reference to the default entry is returned.
297
298 If there is no matching entry found and there is no default defined, or
299 no .netrc file is found, then C<undef> is returned.
300
301 =back
302
303 =head1 METHODS
304
305 =over 4
306
307 =item login ()
308
309 Return the login id for the netrc entry
310
311 =item password ()
312
313 Return the password for the netrc entry
314
315 =item account ()
316
317 Return the account information for the netrc entry
318
319 =item lpa ()
320
321 Return a list of login, password and account information for the netrc entry
322
323 =back
324
325 =head1 AUTHOR
326
327 Graham Barr E<lt>F<gbarr@pobox.com>E<gt>
328
329 Steve Hay E<lt>F<shay@cpan.org>E<gt> is now maintaining libnet as of version
330 1.22_02
331
332 =head1 SEE ALSO
333
334 L<Net::Netrc>,
335 L<Net::Cmd>
336
337 =head1 COPYRIGHT
338
339 Versions up to 2.13 Copyright (c) 1995-1998 Graham Barr. All rights reserved.
340 Changes in Version 2.13_01 onwards Copyright (C) 2013-2014 Steve Hay.  All
341 rights reserved.
342
343 This module is free software; you can redistribute it and/or modify it under the
344 same terms as Perl itself, i.e. under the terms of either the GNU General Public
345 License or the Artistic License, as specified in the F<LICENCE> file.
346
347 =cut