File Coverage

blib/lib/Net/Netrc.pm
Criterion Covered Total %
statement 81 95 85.2
branch 44 62 70.9
condition 10 28 35.7
subroutine 11 11 100.0
pod 5 5 100.0
total 151 201 75.1


line stmt bran cond sub pod time code
1             # Net::Netrc.pm
2             #
3             # Copyright (C) 1995-1998 Graham Barr. All rights reserved.
4             # Copyright (C) 2013-2014, 2020 Steve Hay. All rights reserved.
5             # This module is free software; you can redistribute it and/or modify it under
6             # the same terms as Perl itself, i.e. under the terms of either the GNU General
7             # Public License or the Artistic License, as specified in the F file.
8              
9             package Net::Netrc;
10              
11 2     2   5134 use 5.008001;
  2         8  
12              
13 2     2   23 use strict;
  2         4  
  2         79  
14 2     2   10 use warnings;
  2         4  
  2         107  
15              
16 2     2   15 use Carp;
  2         7  
  2         205  
17 2     2   642 use FileHandle;
  2         9255  
  2         1290  
18              
19             our $VERSION = "3.13";
20              
21             our $TESTING;
22              
23             my %netrc = ();
24              
25             sub _readrc {
26 2     2   2458 my($class, $host) = @_;
27 2         3 my ($home, $file);
28              
29 2 50       8 if ($^O eq "MacOS") {
30 0   0     0 $home = $ENV{HOME} || `pwd`;
31 0         0 chomp($home);
32 0 0       0 $file = ($home =~ /:$/ ? $home . "netrc" : $home . ":netrc");
33             }
34             else {
35              
36             # Some OS's don't have "getpwuid", so we default to $ENV{HOME}
37 2   33     4 $home = eval { (getpwuid($>))[7] } || $ENV{HOME};
38 2 50 0     5987 $home ||= $ENV{HOMEDRIVE} . ($ENV{HOMEPATH} || '') if defined $ENV{HOMEDRIVE};
      0        
39 2 50       144 if (-e $home . "/.netrc") {
    50          
40 0         0 $file = $home . "/.netrc";
41             }
42             elsif (-e $home . "/_netrc") {
43 0         0 $file = $home . "/_netrc";
44             }
45             else {
46 2 50       15 return unless $TESTING;
47             }
48             }
49              
50 2         18 my ($login, $pass, $acct) = (undef, undef, undef);
51 2         9 my $fh;
52 2         10 local $_;
53              
54 2         17 $netrc{default} = undef;
55              
56             # OS/2 and Win32 do not handle stat in a way compatible with this check :-(
57 2 50 33     104 unless ($^O eq 'os2'
      33        
      33        
58             || $^O eq 'MSWin32'
59             || $^O eq 'MacOS'
60             || $^O =~ /^cygwin/)
61             {
62 2         25 my @stat = stat($file);
63              
64 2 50       17 if (@stat) {
65 2 100       14 if ($stat[2] & 077) { ## no critic (ValuesAndExpressions::ProhibitLeadingZeros)
66 1         62 carp "Bad permissions: $file";
67 1         454 return;
68             }
69 1 50       31 if ($stat[4] != $<) {
70 0         0 carp "Not owner: $file";
71 0         0 return;
72             }
73             }
74             }
75              
76 1 50       22 if ($fh = FileHandle->new($file, "r")) {
77 1         158 my ($mach, $macdef, $tok, @tok) = (0, 0);
78              
79 1         15 while (<$fh>) {
80 10 50       70 undef $macdef if /\A\n\Z/;
81              
82 10 50       15 if ($macdef) {
83 0         0 push(@$macdef, $_);
84 0         0 next;
85             }
86              
87 10         36 s/^\s*//;
88 10         15 chomp;
89              
90 10   66     59 while (length && s/^("((?:[^"]+|\\.)*)"|((?:[^\\\s]+|\\.)*))\s*//) {
91 29         84 (my $tok = $+) =~ s/\\(.)/$1/g;
92 29         109 push(@tok, $tok);
93             }
94              
95             TOKEN:
96 10         19 while (@tok) {
97 20 100       41 if ($tok[0] eq "default") {
98 2         7 shift(@tok);
99 2         7 $mach = bless {}, $class;
100 2         43 $netrc{default} = [$mach];
101              
102 2         5 next TOKEN;
103             }
104              
105             last TOKEN
106 18 100       35 unless @tok > 1;
107              
108 15         19 $tok = shift(@tok);
109              
110 15 100       60 if ($tok eq "machine") {
    100          
    100          
111 2         4 my $host = shift @tok;
112 2         8 $mach = bless {machine => $host}, $class;
113              
114             $netrc{$host} = []
115 2 100       20 unless exists($netrc{$host});
116 2         4 push(@{$netrc{$host}}, $mach);
  2         7  
117             }
118             elsif ($tok =~ /^(login|password|account)$/) {
119 10 100       31 next TOKEN unless $mach;
120 9         14 my $value = shift @tok;
121              
122             # Following line added by rmerrell to remove '/' escape char in .netrc
123 9         13 $value =~ s/\/\\/\\/g;
124 9         35 $mach->{$1} = $value;
125             }
126             elsif ($tok eq "macdef") {
127 1 50       9 next TOKEN unless $mach;
128 0         0 my $value = shift @tok;
129             $mach->{macdef} = {}
130 0 0       0 unless exists $mach->{macdef};
131 0         0 $macdef = $mach->{machdef}{$value} = [];
132             }
133             }
134             }
135 1         12 $fh->close();
136             }
137             }
138              
139              
140             sub lookup {
141 5     5 1 1267 my ($class, $mach, $login) = @_;
142              
143             $class->_readrc()
144 5 50       13 unless exists $netrc{default};
145              
146 5   100     20 $mach ||= 'default';
147 5 100       12 undef $login
148             if $mach eq 'default';
149              
150 5 100       10 if (exists $netrc{$mach}) {
151 4 100       7 if (defined $login) {
152 1         3 foreach my $m (@{$netrc{$mach}}) {
  1         11  
153             return $m
154 2 100 66     15 if (exists $m->{login} && $m->{login} eq $login);
155             }
156 0         0 return;
157             }
158 3         14 return $netrc{$mach}->[0];
159             }
160              
161             return $netrc{default}->[0]
162 1 50       5 if defined $netrc{default};
163              
164 0         0 return;
165             }
166              
167              
168             sub login {
169 4     4 1 6 my $me = shift;
170              
171             exists $me->{login}
172             ? $me->{login}
173 4 100       19 : undef;
174             }
175              
176              
177             sub account {
178 4     4 1 460 my $me = shift;
179              
180             exists $me->{account}
181             ? $me->{account}
182 4 100       29 : undef;
183             }
184              
185              
186             sub password {
187 4     4 1 435 my $me = shift;
188              
189             exists $me->{password}
190             ? $me->{password}
191 4 100       52 : undef;
192             }
193              
194              
195             sub lpa {
196 2     2 1 440 my $me = shift;
197 2         4 ($me->login, $me->password, $me->account);
198             }
199              
200             1;
201              
202             __END__