File Coverage

lib/Sys/Filesystem/ID.pm
Criterion Covered Total %
statement 72 88 81.8
branch 26 46 56.5
condition 1 2 50.0
subroutine 15 17 88.2
pod n/a
total 114 153 74.5


line stmt bran cond sub pod time code
1             package Sys::Filesystem::ID;
2 1     1   25778 use strict;
  1         3  
  1         27  
3 1     1   732 use Sys::Filesystem;
  1         40295  
  1         33  
4 1     1   773 use LEOCHARRE::DEBUG;
  1         1531  
  1         4  
5 1     1   74 use Exporter;
  1         1  
  1         44  
6 1     1   5 use vars qw(%FS @FSALL @FSOK $fs @ISA @EXPORT_OK %EXPORT_TAGS $VERSION);
  1         1  
  1         1213  
7             @ISA = qw/Exporter/;
8             @EXPORT_OK = qw/&abs_id &get_id &create_id %FS @FSOK @FSALL/;
9             %EXPORT_TAGS = ( 'all' => \@EXPORT_OK );
10             $VERSION = sprintf "%d.%02d", q$Revision: 1.6 $ =~ /(\d+)/g;
11              
12             *get_id = \&_id_by_arg;
13             *create_id = \&_write_new_idfile_by_arg;
14             *abs_id = \&_abs_id_by_arg;
15              
16             _init();
17              
18             sub _init {
19            
20 1     1   5 $fs = new Sys::Filesystem;
21              
22 1         1045 for my $mnt ($fs->filesystems) {
23 17         156 my $format = $fs->format($mnt);
24 17         321 my $dev = $fs->device($mnt);
25              
26 17         198 $FS{$mnt} = {
27             mnt => $mnt,
28             dev => $dev,
29             format => $format,
30             };
31 17         51 debug("found $mnt, dev $dev, format $format");
32             }
33              
34              
35             # which do we want to use for storage ?
36              
37 1         11 @FSOK = grep { _format_is_desired($FS{$_}{format}) } keys %FS;
  17         29  
38 1         6 @FSALL = keys %FS;
39              
40             }
41              
42             sub _format_is_desired {
43 17     17   22 my $format = shift;
44 17 100       46 return ( $format=~/^ext\d$/ ? 1 : 0 ); # kind of filesystem
45             # we are selecting ext* (ext3, ext2)
46             }
47              
48              
49              
50             sub _arg_type { # is arg a dev or mnt
51 4     4   11 my $arg = shift;
52 4         84 for my $mnt( keys %FS ){
53 68 50       115 if ( $arg eq $mnt ){
54 0         0 return 'mnt';
55             }
56 68 50       170 if ( $FS{$mnt}{dev} eq $arg ){
57 0         0 return 'dev';
58             }
59             }
60 4         24 return 'path';
61             }
62              
63             sub _arg_to_mount_point { # take mnt or dev, return mnt point
64 4     4   15 my $arg = shift;
65 4         23 my $argtype = _arg_type($arg);
66              
67 4 50       35 if ( $argtype eq 'mnt'){
    50          
    50          
68 0         0 return $arg;
69             }
70             elsif ( $argtype eq 'dev'){
71 0         0 return _find_mount_point_by_dev($arg);
72             }
73             elsif ( $argtype eq 'path' ){
74 4         20 return _find_mount_point_by_path($arg);
75             }
76             else {
77 0         0 die("not fs: $arg");
78             }
79             }
80              
81             sub _find_mount_point_by_dev {
82 0     0   0 my $arg = shift;
83 0 0       0 defined $arg or die('missing dev arg');
84              
85 0         0 for my $mnt ( keys %FS ){
86 0 0       0 if ( $FS{$mnt}->{dev} eq $arg){
87 0         0 return $mnt;
88             }
89             }
90 0         0 return;
91             }
92              
93             sub _find_mount_point_by_path {
94 4     4   6 my $arg = shift;
95              
96              
97 4         56 require Cwd; # deffinitely resolve symlinks!!!
98 4 50       211 my $abs = Cwd::abs_path($arg)
99             or die("cant resolve $arg as path");
100 4         45 debug("resolved to '$abs'");
101              
102 4         53 my $subpath = $abs;
103 4         15 while($subpath){
104 24         75 debug("subpath : $subpath");
105              
106 24 100       172 return $subpath if exists $FS{$subpath};
107              
108 20 50       35 last if $subpath eq '/'; # we hit root but not FS mnt (just in case).
109              
110              
111 20 100       267 $subpath=~s/^\/[^\/]+$/\// # change /this to /
112             or $subpath=~s/\/[^\/]+$// ;# change /this/that to /this
113            
114             }
115              
116 0         0 die("cant get mount point for path $abs");
117             }
118              
119             sub _abs_id_by_arg { # arg is mount pont
120 4     4   4164 my $arg = shift;
121 4 50       27 my $mnt = _arg_to_mount_point($arg) or return;
122 4         36 return "$mnt/.fsid";
123             }
124              
125             sub _id_by_arg {
126 2     2   5721 my $arg = shift;
127 2 50       25 my $abs_id = _abs_id_by_arg($arg) or return;
128 2 100       12 my $id = _read_idfile($abs_id) or return;
129 1         3 return $id;
130             }
131              
132             sub _id_string_is_ok {
133 2 50   2   18 +shift =~/^.+$/ ? 1 : 0;
134             }
135              
136             sub _read_idfile {
137 2     2   7 my $abs_id = shift;
138 2 100 50     149 -f $abs_id or debug("no abs id on disk: $abs_id") and return;
139 1         4 local $\;
140 1 50       34 open(FILE,'<',$abs_id) or die("cant open $abs_id for reading, $!");
141 1         28 my $id = ;
142 1         14 close FILE;
143 1         9 $id=~s/^\s+|\s+$//g;
144 1 50       3 _id_string_is_ok($id) or die("id string in $abs_id is not ok");
145 1         5 return $id;
146             }
147              
148             sub _generate_new_id {
149            
150             # get bogus data and then do md5sum of it ??
151             my $id = _suggest_id_string();
152              
153             debug("length: ". (length $id)." id: $id");
154              
155             _id_string_is_ok($id) or die("id string generated is not ok [$id]");
156             return $id;
157             }
158              
159             # override me if wanted
160             sub _suggest_id_string {
161 0     0   0 my $id;
162 0         0 for( 0 .. 31 ){
163 0         0 $id .= int rand 9;
164             }
165 0         0 return $id;
166             }
167              
168             sub _write_new_idfile_by_arg {
169 1     1   26 my $arg = shift;
170 1 50       7 my $abs_id = _abs_id_by_arg($arg) or die("cant get abs id for $arg");
171 1 50       12 !-f $abs_id or die("cant create '$abs_id', file exists.");
172              
173 1         10 my $id = _generate_new_id();
174 1 50       55 _id_string_is_ok($id) or die("id string generated is not ok [$id]");
175              
176 1 50       100 open(FILE,'>',$abs_id) or die("cannot open $abs_id for writing, $!");
177 1         11 print FILE $id;
178 1         83 close FILE;
179              
180             # set perms, world read, no write
181 1         37 chmod 0444, $abs_id;
182 1         5 return $id;
183             }
184              
185              
186              
187             1;
188              
189              
190              
191             __END__