File Coverage

blib/lib/Unix/PasswdFile.pm
Criterion Covered Total %
statement 75 82 91.4
branch 31 50 62.0
condition 2 3 66.6
subroutine 15 16 93.7
pod 11 13 84.6
total 134 164 81.7


line stmt bran cond sub pod time code
1             package Unix::PasswdFile;
2              
3             # $Id: PasswdFile.pm,v 1.5 2000/05/02 15:58:36 ssnodgra Exp $
4              
5 1     1   639 use strict;
  1         2  
  1         34  
6 1     1   4 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
  1         2  
  1         58  
7 1     1   5 use Unix::ConfigFile;
  1         2  
  1         1052  
8              
9             require Exporter;
10              
11             @ISA = qw(Unix::ConfigFile Exporter);
12             # Items to export into callers namespace by default. Note: do not export
13             # names by default without a very good reason. Use EXPORT_OK instead.
14             # Do not simply export all your public functions/methods/constants.
15             @EXPORT = qw(
16            
17             );
18             $VERSION = '0.06';
19              
20             # Implementation notes
21             #
22             # This module only adds a single field to the basic ConfigFile object.
23             # The field is called 'pwent' (password entry) and is a hash of arrays
24             # (or, more properly, a reference to a hash of references to arrays!).
25             # The key is the username and the array contents are the next six fields
26             # found in the password file.
27              
28             # Preloaded methods go here.
29              
30             # Read the file and build the data structures
31             sub read {
32 1     1 0 2 my ($this, $fh) = @_;
33              
34 1         38 while (<$fh>) {
35 8         11 chop;
36 8         43 $this->user(split /:/);
37             }
38 1         5 return 1;
39             }
40              
41              
42             # Add or change a user
43             sub user {
44 19     19 1 59 my $this = shift;
45              
46 19         27 my $username = shift;
47 19 100       42 unless (@_) {
48 10 100       29 return undef unless defined $this->{pwent}{$username};
49 9         11 return @{$this->{pwent}{$username}};
  9         92  
50             }
51 9 50       17 return undef if @_ > 6;
52             # Need to pad the list to 6 elements or we might lose colons during commit
53 9         23 push @_, "" while @_ < 6;
54             # Note: I first tried setting this to \@_. Bad idea!
55 9         103 $this->{pwent}{$username} = [ @_ ];
56             }
57              
58              
59             # Rename a user
60             sub rename {
61 0     0 1 0 my ($this, $olduser, $newuser) = @_;
62              
63 0 0       0 return 0 unless defined $this->user($olduser);
64 0         0 $this->user($newuser, $this->user($olduser));
65 0         0 $this->delete($olduser);
66 0         0 return 1;
67             }
68              
69              
70             # Delete a user
71             sub delete {
72 1     1 1 35 my ($this, $username) = @_;
73 1         6 delete $this->{pwent}{$username};
74             }
75              
76              
77             # Return the list of usernames
78             # Accepts a sorting order parameter: uid or name (default uid)
79             sub users {
80 2     2 1 43 my $this = shift;
81 2 50       7 my $order = @_ ? shift : "uid";
82              
83             # Is there a way to make this work right in scalar context without
84             # this check? I couldn't find one.
85 2 100       6 return keys %{$this->{pwent}} unless wantarray;
  1         5  
86 1 50       4 if ($order eq "name") {
87 0         0 sort keys %{$this->{pwent}};
  0         0  
88             }
89             else {
90 1         1 sort { $this->uid($a) <=> $this->uid($b) } keys %{$this->{pwent}};
  16         36  
  1         8  
91             }
92             }
93              
94              
95             # Returns the maximum UID in use in the file
96             sub maxuid {
97 2     2 1 160 my ($this, $ignore) = @_;
98 2         4 my @uids = sort { $a <=> $b } map { $this->{pwent}{$_}[1] } keys %{$this->{pwent}};
  32         47  
  16         46  
  2         12  
99 2 50       39 return undef unless @uids;
100 2         4 my $retval = pop @uids;
101 2 100       6 if (defined $ignore) {
102 1   66     14 while ($retval >= $ignore && @uids) {
103 1         4 $retval = pop @uids;
104             }
105             }
106 2         8 return $retval;
107             }
108              
109              
110             # Output the file to disk
111             sub write {
112 1     1 0 3 my ($this, $fh) = @_;
113              
114             # Make sure to output root first if it exists
115 1 50       3 if (defined $this->user("root")) {
116 1 50       5 print $fh join(":", "root", $this->user("root")), "\n" or return 0;
117             }
118 1         5 foreach my $user ($this->users) {
119 8 100       91 next if ($user eq "root");
120 7 50       17 print $fh join(":", $user, $this->user($user)), "\n" or return 0;
121             }
122 1         6 return 1;
123             }
124              
125              
126             # Accessors (these all accept a username and an optional value)
127             # These must check for undefined data, or the act of accessing an array
128             # element will create the data!! (This horrible bug nearly escaped into
129             # the first alpha release. :-)
130             sub passwd {
131 1     1 1 190 my $this = shift;
132 1         3 my $username = shift;
133 1 50       7 return undef unless defined $this->{pwent}{$username};
134 1 50       9 @_ ? $this->{pwent}{$username}[0] = shift : $this->{pwent}{$username}[0];
135             }
136              
137             sub uid {
138 37     37 1 379 my $this = shift;
139 37         45 my $username = shift;
140 37 100       82 return undef unless defined $this->{pwent}{$username};
141 36 100       206 @_ ? $this->{pwent}{$username}[1] = shift : $this->{pwent}{$username}[1];
142             }
143              
144             sub gid {
145 1     1 1 38 my $this = shift;
146 1         6 my $username = shift;
147 1 50       6 return undef unless defined $this->{pwent}{$username};
148 1 50       6 @_ ? $this->{pwent}{$username}[2] = shift : $this->{pwent}{$username}[2];
149             }
150              
151             sub gecos {
152 1     1 1 34 my $this = shift;
153 1         2 my $username = shift;
154 1 50       5 return undef unless defined $this->{pwent}{$username};
155 1 50       8 @_ ? $this->{pwent}{$username}[3] = shift : $this->{pwent}{$username}[3];
156             }
157              
158             sub home {
159 1     1 1 37 my $this = shift;
160 1         3 my $username = shift;
161 1 50       15 return undef unless defined $this->{pwent}{$username};
162 1 50       7 @_ ? $this->{pwent}{$username}[4] = shift : $this->{pwent}{$username}[4];
163             }
164              
165             sub shell {
166 1     1 1 33 my $this = shift;
167 1         12 my $username = shift;
168 1 50       5 return undef unless defined $this->{pwent}{$username};
169 1 50       11 @_ ? $this->{pwent}{$username}[5] = shift : $this->{pwent}{$username}[5];
170             }
171              
172              
173             # Autoload methods go after =cut, and are processed by the autosplit program.
174              
175             1;
176             __END__