X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FNet%2FNetrc.pm;h=429982186548d8a094b2415e2aecd30ec9ff663d;hb=7e1af8bca57f405a8444b575a870918a6d88fc5c;hp=58f066363d88ead197caaaff1c5fcb0baeef192e;hpb=7f3dfc00eaef7e421633b2b47af9963dbc626e75;p=p5sagit%2Fp5-mst-13.2.git diff --git a/lib/Net/Netrc.pm b/lib/Net/Netrc.pm index 58f0663..4299821 100644 --- a/lib/Net/Netrc.pm +++ b/lib/Net/Netrc.pm @@ -1,40 +1,196 @@ +# Net::Netrc.pm +# +# Copyright (c) 1995 Graham Barr . All rights +# reserved. This program is free software; you can redistribute it and/or +# modify it under the same terms as Perl itself. + package Net::Netrc; +=head1 NAME + +Net::Netrc - OO interface to users netrc file + +=head1 SYNOPSIS + + use Net::Netrc; + + $mach = Net::Netrc->lookup('some.machine'); + $login = $mach->login; + ($login, $password, $account) = $mach->lpa; + +=head1 DESCRIPTION + +C is a class implementing a simple interface to the .netrc file +used as by the ftp program. + +C also implements security checks just like the ftp program, +these checks are, first that the .netrc file must be owned by the user and +second the ownership permissions should be such that only the owner has +read and write access. If these conditions are not met then a warning is +output and the .netrc file is not read. + +=head1 THE .netrc FILE + +The .netrc file contains login and initialization information used by the +auto-login process. It resides in the user's home directory. The following +tokens are recognized; they may be separated by spaces, tabs, or new-lines: + +=over 4 + +=item machine name + +Identify a remote machine name. The auto-login process searches +the .netrc file for a machine token that matches the remote machine +specified. Once a match is made, the subsequent .netrc tokens +are processed, stopping when the end of file is reached or an- +other machine or a default token is encountered. + +=item default + +This is the same as machine name except that default matches +any name. There can be only one default token, and it must be +after all machine tokens. This is normally used as: + + default login anonymous password user@site + +thereby giving the user automatic anonymous login to machines +not specified in .netrc. + +=item login name + +Identify a user on the remote machine. If this token is present, +the auto-login process will initiate a login using the +specified name. + +=item password string + +Supply a password. If this token is present, the auto-login +process will supply the specified string if the remote server +requires a password as part of the login process. + +=item account string + +Supply an additional account password. If this token is present, +the auto-login process will supply the specified string +if the remote server requires an additional account password. + +=item macdef name + +Define a macro. C only parses this field to be compatible +with I. + +=back + +=head1 CONSTRUCTOR + +The constructor for a C object is not called new as it does not +really create a new object. But instead is called C as this is +essentially what it deos. + +=over 4 + +=item lookup ( MACHINE [, LOGIN ]) + +Lookup and return a reference to the entry for C. If C is given +then the entry returned will have the given login. If C is not given then +the first entry in the .netrc file for C will be returned. + +If a matching entry cannot be found, and a default entry exists, then a +reference to the default entry is returned. + +=back + +=head1 METHODS + +=over 4 + +=item login () + +Return the login id for the netrc entry + +=item password () + +Return the password for the netrc entry + +=item account () + +Return the account information for the netrc entry + +=item lpa () + +Return a list of login, password and account information fir the netrc entry + +=back + +=head1 AUTHOR + +Graham Barr + +=head1 REVISION + +$Revision: 2.1 $ + +=head1 SEE ALSO + +L +L + +=head1 COPYRIGHT + +Copyright (c) 1995 Graham Barr. All rights reserved. This program is free +software; you can redistribute it and/or modify it under the same terms +as Perl itself. + +=cut + use Carp; use strict; +use FileHandle; +use vars qw($VERSION); + +$VERSION = sprintf("%d.%02d", q$Revision: 2.1 $ =~ /(\d+)\.(\d+)/); my %netrc = (); -sub _readrc { +sub _readrc +{ my $host = shift; - my $file = (getpwuid($>))[7] . "/.netrc"; + + # Some OS's don't have `getpwuid', so we default to $ENV{HOME} + my $home = eval { (getpwuid($>))[7] } || $ENV{HOME}; + my $file = $home . "/.netrc"; + my($login,$pass,$acct) = (undef,undef,undef); - local *NETRC; + my $fh; local $_; $netrc{default} = undef; - my @stat = stat($file); + # OS/2 does not handle stat in a way compatable with this check :-( + unless($^O eq 'os2') + { + my @stat = stat($file); - if(@stat) - { - if($stat[2] & 077) + if(@stat) { - carp "Bad permissions: $file"; - return (); - } - if($stat[4] != $<) - { - carp "Not owner: $file"; - return (); + if($stat[2] & 077) + { + carp "Bad permissions: $file"; + return; + } + if($stat[4] != $<) + { + carp "Not owner: $file"; + return; + } } } - if(open(NETRC,$file)) + if($fh = FileHandle->new($file,"r")) { my($mach,$macdef,$tok,@tok) = (0,0); - while() + while(<$fh>) { undef $macdef if /\A\n\Z/; @@ -50,72 +206,109 @@ TOKEN: while(@tok) { if($tok[0] eq "default") - { - shift(@tok); - $mach = $netrc{default} = {}; + { + shift(@tok); + $mach = bless {}; + $netrc{default} = [$mach]; + + next TOKEN; + } - next TOKEN; - } + last TOKEN + unless @tok > 1; - last TOKEN unless @tok > 1; $tok = shift(@tok); if($tok eq "machine") - { + { my $host = shift @tok; - $mach = $netrc{$host} = {}; - } + $mach = bless {machine => $mach}; + + $netrc{$host} = [] + unless exists($netrc{$host}); + push(@{$netrc{$host}}, $mach); + } elsif($tok =~ /^(login|password|account)$/) - { + { next TOKEN unless $mach; my $value = shift @tok; $mach->{$1} = $value; - } + } elsif($tok eq "macdef") - { + { next TOKEN unless $mach; my $value = shift @tok; - $mach->{macdef} = {} unless exists $mach->{macdef}; + $mach->{macdef} = {} + unless exists $mach->{macdef}; $macdef = $mach->{machdef}{$value} = []; - } + } } } - close(NETRC); + $fh->close(); } } -sub lookup { - my $pkg = shift; - my $mach = shift; +sub lookup +{ + my($pkg,$mach,$login) = @_; + + _readrc() + unless exists $netrc{default}; - _readrc() unless exists $netrc{default}; + $mach ||= 'default'; + undef $login + if $mach eq 'default'; - return bless \$mach if exists $netrc{$mach}; + if(exists $netrc{$mach}) + { + if(defined $login) + { + my $m; + foreach $m (@{$netrc{$mach}}) + { + return $m + if(exists $m->{login} && $m->{login} eq $login); + } + return undef; + } + return $netrc{$mach}->[0] + } - return bless \("default") if defined $netrc{default}; + return $netrc{default} + if defined $netrc{default}; return undef; } -sub login { +sub login +{ my $me = shift; - $me = $netrc{$$me}; - exists $me->{login} ? $me->{login} : undef; + + exists $me->{login} + ? $me->{login} + : undef; } -sub account { +sub account +{ my $me = shift; - $me = $netrc{$$me}; - exists $me->{account} ? $me->{account} : undef; + + exists $me->{account} + ? $me->{account} + : undef; } -sub password { +sub password +{ my $me = shift; - $me = $netrc{$$me}; - exists $me->{password} ? $me->{password} : undef; + + exists $me->{password} + ? $me->{password} + : undef; } -sub lpa { +sub lpa +{ my $me = shift; ($me->login, $me->password, $me->account); }