File Coverage

blib/lib/Text/Authinfo.pm
Criterion Covered Total %
statement 50 81 61.7
branch 4 24 16.6
condition 7 32 21.8
subroutine 11 13 84.6
pod 5 5 100.0
total 77 155 49.6


line stmt bran cond sub pod time code
1             package Text::Authinfo;
2              
3 2     2   56093 use strict;
  2         5  
  2         74  
4 2     2   10 use warnings;
  2         5  
  2         63  
5 2     2   2071 use File::Copy qw(move);
  2         12093  
  2         161  
6 2     2   4021 use Text::CSV;
  2         31949  
  2         18  
7 2     2   100 use Carp qw(croak carp);
  2         6  
  2         183  
8 2     2   11 use vars qw($VERSION @EXPORT);
  2         5  
  2         119  
9 2     2   10 use Exporter;
  2         5  
  2         78  
10 2     2   13 use base qw(Exporter);
  2         4  
  2         2843  
11              
12              
13             @EXPORT = qw(readauthinfo writeauthinfo as_string);
14              
15             our $VERSION = '0.03';
16             our $wildcard = 'ANY';
17             our $authinfofile = $ENV{'HOME'} . '/.authinfo';
18              
19              
20             sub new {
21 1     1 1 17 my $self = {};
22 1         3 my $class = shift;
23              
24 1   33     6 $self->{FILE} = shift || $authinfofile;
25 1         4 $self->{AUTHINFO} = {};
26              
27 1         3 bless $self,$class ;
28 1         3 return $self;
29             }
30              
31              
32             sub readauthinfo {
33 1     1 1 7 my $self = shift;
34              
35 1         3 my $ai = {};
36 1   33     12 my $csv = Text::CSV->new({sep_char=> ' '}) || croak 'new Text::CSV';
37              
38 1 50       188 open(my $fh,'<',$self->{FILE}) || croak "open $self->{FILE}:$!";
39              
40 1         39 LINE:while (my $line = <$fh>) {
41 1         4 chomp $line;
42 1         7 $csv->parse($line);
43 1         639 my %l = $csv->fields();
44             # this package requires at least these fields to be on a valid
45             # line:
46 1 50 33     28 if (defined($l{'machine'}) &&
      33        
47             defined($l{'login'}) &&
48             defined($l{'password'})) {
49             # allow port to be defined or ANY
50 1         2 my $port = $wildcard;
51 1 50       7 $port = $l{'port'} if (defined($l{'port'}));
52 1         27 $ai->{$l{'machine'}}->{$port}->{$l{'login'}} = $l{'password'};
53             } else {
54 0         0 carp "$line missing some fields? skipping";
55 0         0 next LINE;
56             }
57             }
58              
59 1         4 $self->{AUTHINFO} = $ai;
60              
61 1 50       16 close($fh) || croak "close $authinfofile:$!";
62              
63 1         24 return 1; # caller can now query authinfo data as a perl assoc array
64             }
65              
66              
67             sub getauth() {
68              
69 2     2 1 1008 my $self = shift;
70 2   33     7 my $machine = shift || croak 'use: getauth(machine,login,[port])';
71 2   33     5 my $login = shift || croak 'use: getauth(machine,login,[port])';
72 2   33     6 my $port = shift || $wildcard;
73              
74             # retval may be undef
75 2         10 return $self->{AUTHINFO}->{$machine}->{$port}->{$login};
76             }
77              
78              
79             sub as_string {
80 0     0 1   my $self = shift;
81              
82 0           my $c = '';
83 0           for my $machine (keys %{$self->{AUTHINFO}}) {
  0            
84 0           for my $port (keys %{$self->{AUTHINFO}->{$machine}}) {
  0            
85 0           for my $login (keys %{$self->{AUTHINFO}->{$machine}->{$port}}) {
  0            
86 0           my $pass = $self->{AUTHINFO}->{$machine}->{$port}->{$login};
87 0           $c .= 'machine ' . $machine . ' login ' . $login .
88             ' password ' . $pass;
89 0 0         $c .= ' port ' . $port if ($port ne $wildcard);
90 0           $c .= "\n";
91             }
92             }
93             }
94 0           return $c;
95             }
96              
97              
98             sub writeauthinfo {
99 0     0 1   my $self = shift;
100              
101 0   0       my $ops = shift || undef;
102 0 0 0       if (defined($ops) && (ref($ops) ne 'HASH')) {
103 0           carp "args are passed to writeauthinfo via a hash ref";
104             }
105              
106 0 0         if (-w $self->{FILE}) {
107             # there is already a .authinfo file, mv it to .authinfo.bak
108 0 0         if (defined($ops->{nobackup})) {
109 0   0       unlink $self->{FILE} || croak "rm old $self->{FILE}:$!"
110             } else { # by default, make a backup old old authinfo file
111 0           my $bak = $self->{FILE} . '.bak';
112 0 0         move($self->{FILE},$bak) || croak "mv $self->{FILE} $bak:$!";
113             }
114             }
115              
116 0           my $c = $self->as_string();
117 0 0         if ($c) {
118 0 0         open(my $fh,'>',$self->{FILE}) || croak "open $self->{FILE}:$!";
119 0           print $fh $c;
120 0 0         close($fh) || croak "close $self->{FILE}:$!";
121 0   0       chmod 0600, $self->{FILE} || croak "chmod fail on $self->{FILE}:$!";
122             }
123              
124 0           return 1;
125             }
126              
127             __END__;