File Coverage

blib/lib/AutoSession/Driver/File.pm
Criterion Covered Total %
statement 132 177 74.5
branch 31 66 46.9
condition 11 36 30.5
subroutine 17 18 94.4
pod 0 14 0.0
total 191 311 61.4


line stmt bran cond sub pod time code
1             #############################################################################
2             ## Name: File.pm
3             ## Purpose: AutoSession::Driver::File
4             ## Author: Graciliano M. P.
5             ## Modified by:
6             ## Created: 20/5/2003
7             ## RCS-ID:
8             ## Copyright: (c) 2003 Graciliano M. P.
9             ## Licence: This program is free software; you can redistribute it and/or
10             ## modify it under the same terms as Perl itself
11             #############################################################################
12            
13             package AutoSession::Driver::File ;
14             our $VERSION = '1.0' ;
15            
16 1     1   5 use strict qw(vars) ;
  1         2  
  1         35  
17            
18 1     1   5 no warnings ;
  1         3  
  1         41  
19            
20 1     1   5 use vars qw(@ISA) ;
  1         2  
  1         2101  
21             @ISA = qw(AutoSession::Driver) ;
22            
23             #################
24             # LOAD_STORABLE #
25             #################
26            
27             sub load_storable {
28 1     1 0 3 $INC{'Log/Agent.pm'} = '#ignore#' ;
29 1     1   1069551 eval(q`use Storable qw(thaw freeze) ;`) ;
  1         4732  
  1         93  
  1         66  
30             }
31            
32             #######
33             # NEW #
34             #######
35            
36             sub new {
37 1     1 0 4 &load_storable() ;
38            
39 1         3 my $class = shift ;
40 1         8 my ( %args ) = @_ ;
41            
42 1         3 my $this = {} ;
43            
44 1         6 bless($this,$class) ;
45            
46 1         10 $this->{id} = $args{id} ;
47 1   33     10 $this->{idsize} = $args{idsize} || $AutoSession::DEF_IDSIZE ;
48            
49 1 50 33     12 if (defined $args{directory} && !defined $args{dir}) { $args{dir} = $args{directory} ;}
  1         5  
50 1 50 33     81 if (defined $args{dir} && $args{dir} eq '') { $args{dir} = '.' ;}
  0         0  
51            
52 1         4 $this->{dir} = $args{dir} ;
53 1 50 33     36 if ($this->{dir} eq '' || !-d $this->{dir}) { $this->{dir} = '/tmp' ;}
  0         0  
54            
55 1         8 $this->{dir} =~ s/[\\\/]+$//gs ;
56            
57 1 50       8 if ($this->{id} eq '') {
58 0         0 $this->{id} = $this->new_id ;
59 0         0 $this->{file} = $this->filename( $this->{id} ) ;
60             }
61             else {
62 1   33     8 $this->{file} = $this->exist_id( $this->{id} ) || $this->filename( $this->{id} ) ;
63             }
64            
65 1   33     4 $this->{expire} = $args{expire} || $AutoSession::DEF_EXPIRE ;
66            
67 1 50       5 if (!defined $args{expire}) { $this->{defexpire} = 1 ;}
  0         0  
68            
69 1         12 $this->{expire} = $this->parse_expire($this->{expire}) ;
70            
71 1         4 $this->{base64} = $args{base64} ;
72            
73 1         4 $this->{nocreate} = $args{nocreate} ;
74            
75             ## Create file if needed:
76 1 50       8 $this->create if !$this->{nocreate} ;
77            
78 1 50       17 if (!-e $this->{file}) { return( undef ) ;}
  0         0  
79            
80 1         7 return( $this ) ;
81             }
82            
83             ##########
84             # CREATE #
85             ##########
86            
87             sub create {
88 1     1 0 3 my $this = shift ;
89            
90 1 50       5 if ($this->{nocreate}) { return ;}
  0         0  
91            
92 1 50       13 if (!-e $this->{file}) {
93 1         3 my $fh ;
94 1         142 open ($fh,">$this->{file}") ; binmode($fh) ;
  1         5  
95 1         16 close($fh) ;
96 1         13 return( 1 ) ;
97             }
98            
99 0         0 return( undef ) ;
100             }
101            
102             ##########
103             # DELETE #
104             ##########
105            
106             sub delete {
107 1     1 0 2 my $this = shift ;
108            
109 1 50       18 if (-e $this->{file}) {
110 1         151 my $v = unlink($this->{file}) ;
111 1         3 $this->{closed} = 1 ;
112 1 50       29 return( 1 ) if (!-e $this->{file}) ;
113             }
114 0         0 return( undef ) ;
115             }
116            
117             ########
118             # TIME #
119             ########
120            
121             sub time {
122 7     7 0 8 my $this = shift ;
123 7         2609 my @stats = stat($this->{file}) ;
124 7 50       24 if (! $stats[7] ) { return( 0 ) ;}
  0         0  
125 7         57 return( $stats[9] ) ;
126             }
127            
128             ########
129             # LOAD #
130             ########
131            
132             sub load {
133 2     2 0 5 my $this = shift ;
134            
135 2 50       10 if ($this->{closed}) { return( undef ) ;}
  0         0  
136            
137 2 50       119 if (!-s $this->{file}) {
138 0         0 $this->{tree} = {} ;
139 0         0 $this->{time} = 0 ;
140             }
141             else {
142 2         8 my ($data,$header,$hsz,$fh) ;
143            
144 2         110 open ($fh,$this->{file}) ; binmode($fh) ;
  2         7  
145            
146 2 50       9 while($hsz !~ />/s) { my $n = read($fh , $hsz , 1 , length($hsz) ) ; last if !$n ;}
  6         41  
  6         24  
147 2         15 $hsz =~ s/\D//gs ;
148            
149 2         8 read($fh , $header , $hsz) ;
150            
151 2         28 1 while( read($fh , $data , 1024*8 , length($data) ) ) ;
152            
153 2         22 close($fh) ;
154            
155 2         10 my %headers = $this->parse_header($header) ;
156            
157 2 50       10 if ( $this->{defexpire} ) {
158 0 0       0 $this->{expire} = $headers{expire} if $headers{expire} ;
159             }
160            
161 2 50       7 if ( $headers{base64} ) {
162 0         0 require AutoSession::Base64 ;
163 0         0 $data = &AutoSession::Base64::decode_base64($data) ;
164             }
165            
166 2         11 $this->{tree} = Storable::thaw($data) ;
167            
168 2         80 $this->{time} = $this->time ;
169             }
170            
171 2         60 return( $this->{tree} ) ;
172             }
173            
174             ########
175             # SAVE #
176             ########
177            
178             sub save {
179 6     6 0 13 my $this = shift ;
180            
181 6 100 66     41 if (!$this->{tree} || $this->{closed}) { return( undef ) ;}
  1         127  
182            
183 5 50 33     15 if ($this->{nocreate} && !-e $this->{file}) { return ;}
  0         0  
184            
185 5 50       15 if ( !ref($this->{tree}) ) { $this->{tree} = {} ;}
  0         0  
186            
187 5         20 my $data = Storable::freeze($this->{tree}) ;
188            
189 5 50       507 if ( $this->{base64} ) {
190 0         0 require AutoSession::Base64 ;
191 0         0 $data = &AutoSession::Base64::encode_base64($data) ;
192             }
193            
194 5         7 my $fh ;
195 5         521 open ($fh,">$this->{file}") ; binmode($fh) ;
  5         16  
196            
197 5         19 print $fh $this->header ;
198 5         12 print $fh $data ;
199            
200 5         672 close($fh) ;
201            
202 5         27 return( 1 ) ;
203             }
204            
205             #########
206             # LOCAL #
207             #########
208            
209             sub local {
210 1     1 0 2 my $this = shift ;
211 1         5 return( $this->{file} ) ;
212             }
213            
214             ############
215             # EXIST_ID #
216             ############
217            
218             sub exist_id {
219 1     1 0 2 my $this = shift ;
220 1         3 my ( $id ) = @_ ;
221            
222 1 50       79 if ($id eq '') { $id = $this->{id} ;}
  0         0  
223            
224 1         5 my @file = $this->filename($id) ;
225            
226 1         4 foreach my $file ( @file ) {
227 2 50       25 if (-e $file) { return( $file ) ;}
  0         0  
228             }
229            
230 1         14 return( undef ) ;
231             }
232            
233             #################
234             # CHECK_EXPIRED #
235             #################
236            
237             sub check_expired {
238 2     2 0 5 my $this = shift ;
239            
240 2         2 my $dh ; opendir($dh, $this->{dir}) ;
  2         82  
241            
242 2         442 while (my $filename = readdir $dh) {
243 29 100       142 if ($filename =~ /^SESSION-(\w+)\.(?:tmp|hpl)$/s) {
244 1         4 my $id = $1 ;
245 1         4 my $file = "$this->{dir}/$filename" ;
246            
247 1         23 my @stats = stat($file) ;
248 1         4 my $size = @stats[7] ;
249 1         2 my $mdtime = @stats[9] ;
250            
251 1 0 0     10 if ($id ne $this->{id} && ($size || ($size == 0 && (time-$mdtime) > 60*60*24) ) ) {
      33        
252 0         0 my %headers = $this->get_file_header($file) ;
253 0         0 my $idle = time - $headers{time} ;
254 0 0       0 if ($idle >= $headers{expire}) { unlink($file) ;}
  0         0  
255             }
256             }
257             }
258            
259 2         50 closedir($dh) ;
260             }
261            
262             ###################
263             # GET_FILE_HEADER #
264             ###################
265            
266             sub get_file_header {
267 0     0 0 0 my $this = shift ;
268 0   0     0 my $file = $_[0] || $this->{file} ;
269            
270 0 0       0 if (-s $file) {
271 0         0 my $fh ; open ($fh,$file) ; binmode($fh) ;
  0         0  
  0         0  
272            
273 0         0 my $sz ;
274 0         0 while($sz !~ />/s) {
275 0         0 my $n = read($fh , $sz , 1 , length($sz) ) ;
276 0 0       0 last if !$n ;
277             }
278 0         0 $sz =~ s/\D//gs ;
279            
280 0         0 my $data ;
281 0         0 read($fh , $data , $sz) ;
282            
283 0         0 close($fh);
284            
285 0         0 return $this->parse_header($data) ;
286             }
287            
288 0         0 return() ;
289             }
290            
291             ############
292             # FILENAME #
293             ############
294            
295             sub filename {
296 2     2 0 5 my $this = shift ;
297 2         79 my ( $id ) = @_ ;
298            
299 2         8 my $file = $this->{dir} . "/SESSION-$id" ;
300            
301 2 100       6 if ( wantarray ) {
302 1         7 return( "$file.tmp" , "$file.hpl" ) ;
303             }
304            
305 1 50       5 if ( $AutoSession::WITH_HPL ) { $file .= '.hpl' ;}
  0         0  
306 1         4 else { $file .= '.tmp' ;}
307            
308 1         6 return( $file ) ;
309             }
310            
311             ##########
312             # HEADER #
313             ##########
314            
315             sub header {
316 5     5 0 7 my $this = shift ;
317            
318 5         11 my $time = time() ;
319 5         10 my $id = $this->{id} ;
320 5         11 my $expire = $this->{expire} ;
321 5         8 my $version = $AutoSession::VERSION ;
322 5         9 my $base64 = $this->{base64} ;
323            
324 5         65 my $header = "AutoSession:$version:$time:$expire:$base64:$id" ;
325 5         14 $header = length($header) . ">$header" ;
326            
327 5 50       12 if ( $AutoSession::WITH_HPL ) { $header = "#!hidden\n" . $header ;}
  0         0  
328            
329 5         29 return($header) ;
330             }
331            
332             ################
333             # PARSE_HEADER #
334             ################
335            
336             sub parse_header {
337 2     2 0 4 my $this = shift ;
338 2         4 my ( $header ) = @_ ;
339            
340 2         15 my ($module , $ver , $time , $expire , $base64 , $id) = split(":" , $header , 6) ;
341            
342 2 50 33     340 if ($module eq 'AutoSession' && $ver == $AutoSession::VERSION) {
343 2         15 my %header = (
344             time => $time ,
345             expire => $expire ,
346             id => $id ,
347             base64 => $base64 ,
348             ) ;
349            
350 2         21 return( %header ) ;
351             }
352            
353 0           return() ;
354             }
355            
356             #######
357             # END #
358             #######
359            
360             1;
361            
362