File Coverage

blib/lib/Csistck/Test/FileBase.pm
Criterion Covered Total %
statement 76 121 62.8
branch 13 42 30.9
condition 2 12 16.6
subroutine 24 31 77.4
pod 0 19 0.0
total 115 225 51.1


line stmt bran cond sub pod time code
1             package Csistck::Test::FileBase;
2              
3 17     17   285 use 5.010;
  17         42  
4 17     17   72 use strict;
  17         23  
  17         334  
5 17     17   60 use warnings;
  17         21  
  17         456  
6              
7 17     17   63 use base 'Csistck::Test';
  17         24  
  17         1444  
8 17     17   98 use Csistck::Oper qw/debug/;
  17         22  
  17         928  
9 17     17   6532 use Csistck::Util qw/backup_file hash_file hash_string/;
  17         49  
  17         1186  
10              
11 17     17   95 use Digest::MD5;
  17         28  
  17         543  
12 17     17   83 use File::Basename;
  17         28  
  17         991  
13 17     17   82 use File::Copy;
  17         31  
  17         726  
14 17     17   110 use FindBin;
  17         25  
  17         513  
15 17     17   8957 use File::stat;
  17         103209  
  17         96  
16 17     17   10066 use Sys::Hostname::Long qw//;
  17         41470  
  17         20435  
17              
18 0     0 0 0 sub desc { sprintf("File check on %s", shift->{target}); }
19 47     47 0 434 sub dest { shift->{target}; }
20 14     14 0 78 sub src { shift->{src}; }
21 42     42 0 80 sub mode { shift->{mode}; }
22 14     14 0 49 sub uid { shift->{uid}; }
23 14     14 0 52 sub gid { shift->{gid}; }
24              
25             sub check {
26 11     11 0 3441 my $self = shift;
27 11         17 my $ret = 1;
28              
29 11 50       55 die("Destination path not found")
30             if (! -e $self->dest);
31            
32             # If we defined a source file
33 11 50 33     43 if (defined($self->src) and $self->can('file_check')) {
34 0         0 $ret &= $self->file_check;
35             }
36 11         53 $ret &= $self->mode_process(\&mode_check);
37 11         52 $ret &= $self->uid_process(\&uid_check);
38 11         55 $ret &= $self->gid_process(\&gid_check);
39              
40 11 100       70 return (($ret == 1) ? $self->pass('File matches') :
41             $self->fail("File doesn't match"));
42             }
43              
44             sub repair {
45 3     3 0 7 my $self = shift;
46 3         5 my $ret = 1;
47              
48             # If we defined a source file
49 3 50 33     9 if (defined($self->src) and $self->can('file_repair')) {
50 0 0       0 if (-e $self->dest) {
51 0 0       0 die("Destination ${\$self->dest} is not a file")
  0         0  
52             if (-d $self->dest);
53 0 0 0     0 die("Destination ${\$self->dest} exists is is not writable")
  0         0  
54             if (-f $self->dest and ! -w $self->dest);
55 0         0 backup_file($self->dest);
56             }
57            
58 0         0 $ret &= $self->file_repair;
59             }
60 3         13 $ret &= $self->mode_process(\&mode_repair);
61 3         15 $ret &= $self->uid_process(\&uid_repair);
62 3         13 $ret &= $self->gid_process(\&gid_repair);
63            
64 3 50       39 return (($ret == 1) ? $self->pass('File repaired') :
65             $self->fail('File not repaired'));
66             }
67              
68             # Diff for files
69             sub diff {
70 0     0 0 0 my $self = shift;
71            
72 0 0       0 die("Destination file does not exist: dest=<${\$self->dest}>")
  0         0  
73             unless (-f -e -r $self->dest);
74            
75             # If we defined a source file
76 0 0 0     0 if (defined($self->src) and $self->can('file_diff')) {
77 0         0 $self->file_diff();
78             }
79              
80             # TODO mode, uid, gid diff functions
81             }
82              
83             # Wrapper functions to perform sanity tests on arguments
84             # Return pass if arguments are missing, die if invalid
85             sub mode_process {
86 14     14 0 24 my ($self, $func) = @_;
87              
88 14 50       42 return 1 unless($self->mode);
89 14         24 my $mode = $self->mode;
90 14 50       83 die("Invalid file mode")
91             if ($mode !~ m/^[0-7]{3,4}$/);
92 14         34 $mode =~ s/^([0-7]{3})$/0$1/;
93 14         25 $self->{mode} = $mode;
94            
95 14         30 &{$func}($self->dest, $self->mode);
  14         32  
96             }
97              
98             sub uid_process {
99 14     14 0 24 my ($self, $func) = @_;
100              
101 14 50       52 return 1 unless ($self->uid);
102 0 0       0 die("Invalid user id")
103             if ($self->uid !~ m/^[0-9]+$/);
104            
105 0         0 &{$func}($self->dest, $self->uid);
  0         0  
106             }
107              
108             sub gid_process {
109 14     14 0 21 my ($self, $func) = @_;
110              
111 14 50       44 return 1 unless ($self->gid);
112 0 0       0 die("Invalid group id")
113             if ($self->gid !~ m/^[0-9]+$/);
114              
115 0         0 &{$func}($self->dest, $self->gid);
  0         0  
116             }
117              
118             # Mode operations
119             sub mode_check {
120 11     11 0 19 my ($file, $mode) = @_;
121 11         47 my $fh = stat($file);
122 11 50       1736 if ($fh) {
123 11         275 my $curmode = sprintf "%04o", $fh->mode & 07777;
124 11         143 debug("File mode: file=<$file> mode=<$curmode>");
125 11 100       130 return 1 if ($curmode eq $mode);
126             }
127             }
128              
129             sub mode_repair {
130 3     3 0 7 my ($file, $mode) = @_;
131 3         22 debug("Chmod file: file=<$file> mode=<$mode>");
132 3         127 chmod(oct($mode), $file);
133             }
134              
135             # UID operations
136             sub uid_check {
137 0     0 0   my ($file, $uid) = @_;
138 0           my $fh = stat($file);
139 0           my $curuid = undef;
140 0 0         if ($fh) {
141 0           my $curuid = $fh->uid;
142 0           debug("File owner: file=<$file> uid=<$uid>");
143             }
144 0           return ($curuid == $uid);
145             }
146              
147             sub uid_repair {
148 0     0 0   my ($file, $uid) = @_;
149 0           debug("Chown file: file=<$file> uid=<$uid>");
150 0           chown($uid, -1, $file);
151             }
152              
153             # GID operations
154             sub gid_check {
155 0     0 0   my ($file, $gid) = @_;
156 0           my $fh = stat($file);
157 0           my $curgid = undef;
158 0 0         if ($fh) {
159 0           $curgid = $fh->gid;
160 0           debug("File group: file=<$file> gid=<$gid>");
161             }
162 0           return ($curgid == $gid);
163             }
164              
165             sub gid_repair {
166 0     0 0   my ($file, $gid) = @_;
167 0           debug("Chown file: file=<$file> gid=<$gid>");
168 0           chown(-1, $gid, $file);
169             }
170              
171             # Compare hashes between two files
172             sub file_compare {
173 0     0 0   my @files = @_;
174 0 0         return 0 unless (scalar @files == 2);
175            
176             # Get hashes and return compare
177 0           my ($hasha, $hashb) = map hash_file($_), @files;
178 0           debug(sprintf "File compare result: ", $hasha, $hashb);
179 0           return ($hasha eq $hashb);
180             }
181              
182             1;
183             __END__