File Coverage

blib/lib/Apache/Auth/UserDB/File.pm
Criterion Covered Total %
statement 63 70 90.0
branch 5 12 41.6
condition 2 6 33.3
subroutine 15 15 100.0
pod 0 2 0.0
total 85 105 80.9


line stmt bran cond sub pod time code
1             #
2             # Apache::Auth::UserDB::File
3             # An abstract Apache file user database manager class.
4             #
5             # (C) 2003-2007 Julian Mehnle
6             # $Id: File.pm 31 2007-09-18 01:39:14Z julian $
7             #
8             ##############################################################################
9              
10             package Apache::Auth::UserDB::File;
11              
12 2     2   12 use version; our $VERSION = qv('0.120');
  2         4  
  2         11  
13              
14 2     2   149 use warnings;
  2         4  
  2         45  
15 2     2   11 use strict;
  2         2  
  2         60  
16              
17 2     2   10 use base qw(Apache::Auth::UserDB);
  2         2  
  2         1148  
18              
19 2     2   14 use Carp;
  2         3  
  2         115  
20             # TODO: We are not fully multi-user-safe yet!
21             #use IPC::SysV;
22             #use IPC::Semaphore;
23 2     2   1945 use IO::File;
  2         25484  
  2         300  
24 2     2   2010 use File::Copy;
  2         11195  
  2         154  
25              
26             # Constants:
27             ##############################################################################
28              
29 2     2   15 use constant TRUE => (0 == 0);
  2         3  
  2         151  
30 2     2   10 use constant FALSE => not TRUE;
  2         5  
  2         83  
31              
32             # When writing user DB files ...
33 2     2   10 use constant file_write_mode_write_rename => 0; # write new file, then rename over old one.
  2         4  
  2         102  
34 2     2   10 use constant file_write_mode_overwrite => 1; # overwrite old file in-place.
  2         5  
  2         1071  
35              
36             # Implementation:
37             ##############################################################################
38              
39             sub new {
40 4     4 0 46 my ($class, %options) = @_;
41 4         45 my $self = $class->SUPER::new(%options);
42 4   33     58 $self->{file_write_mode} ||= $self->file_write_mode_write_rename;
43 4         12 return $self;
44             }
45              
46             sub open {
47 2     2 0 890 my ($class, %options) = @_;
48            
49 2         11 my $self = $class->new(%options);
50 2 50 33     20 if (defined($self) and $self->_read()) {
51 2         8 return $self;
52             }
53             else {
54 0         0 return undef;
55             }
56             }
57              
58             sub _read {
59 2     2   5 my ($self) = @_;
60            
61 2         12 my $file = IO::File->new($self->{file_name}, '<');
62 2 50       163 return undef if not $file;
63             #croak("Unable to open file for reading: $self->{file_name}")
64             # if not $file;
65            
66 2         20 $self->clear();
67            
68 2         90 while (my $line = <$file>) {
69 2         7 chomp($line);
70 2         11 my $user = $self->_parse_entry($line);
71 2         4 push(@{$self->{users}}, $user);
  2         18  
72             }
73            
74 2         8 $file->close();
75            
76 2         36 return TRUE;
77             }
78              
79             sub _write {
80 4     4   8 my ($self) = @_;
81            
82 4 50       21 if ($self->{file_write_mode} == $self->file_write_mode_write_rename) {
    0          
83             # Write new file, then rename over old one:
84            
85 4         43 my $temp_file_name = $self->{file_name} . sprintf('.%d:%d', $$, time());
86 4         43 my $temp_file = IO::File->new($temp_file_name, '>');
87 4 50       969 return undef if not $temp_file;
88             #croak("Unable to open file for writing: $temp_file_name")
89             # if not $temp_file;
90            
91 4         13 foreach my $user (@{$self->{users}}) {
  4         13  
92 5         38 $temp_file->print($self->_build_entry($user), "\n");
93             }
94            
95 4         90 $temp_file->close();
96 4 50       234 move($temp_file_name, $self->{file_name})
97             or return undef;
98             #or croak("Unable to replace $self->{file_name} with $temp_file_name");
99             }
100             elsif ($self->{file_write_mode} == $self->file_write_mode_overwrite) {
101             # Overwrite old file in-place, preserving file ownership and permissions.
102            
103 0         0 my $file = IO::File->new($self->{file_name}, '>');
104            
105 0         0 foreach my $user (@{$self->{users}}) {
  0         0  
106 0         0 $file->print($self->_build_entry($user), "\n");
107             }
108            
109 0         0 $file->close();
110             }
111             else {
112 0         0 return undef;
113             #or croak("Unexpected file_write_mode: " . $self->{file_write_mode});
114             }
115            
116 4         697 return TRUE;
117             }
118              
119             TRUE;