File Coverage

blib/lib/LibZip.pm
Criterion Covered Total %
statement 141 197 71.5
branch 48 98 48.9
condition 12 39 30.7
subroutine 21 23 91.3
pod 0 11 0.0
total 222 368 60.3


line stmt bran cond sub pod time code
1             #############################################################################
2             ## Name: LibZip.pm
3             ## Purpose: Use lib.zip files as Perl librarys directorys.
4             ## Author: Graciliano M. P.
5             ## Modified by:
6             ## Created: 21/10/2002
7             ## RCS-ID:
8             ## Copyright: (c) 2002 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 LibZip ;
14            
15             $VERSION = '0.06' ;
16            
17 2     2   16633 no warnings ;
  2         4  
  2         245  
18            
19 2 50   2   246 BEGIN { $INC{'LibZip.pm'} = 1 if !$INC{'LibZip.pm'} ;}
20            
21 2     2   1032 use LibZip::CORE ;
  2         6  
  2         14  
22 2     2   1298 use LibZip::InitLib ;
  2         5  
  2         80  
23 2     2   1231 use LibZip::DynaLoader ;
  2         5  
  2         67  
24 2     2   1209 use LibZip::MyArchZip ;
  2         8  
  2         492  
25            
26             ########
27             # VARS #
28             ########
29            
30             my (@LIBBASES,%LIBTREE,$ZIP,%DEP,@DATAPACK,@FIND_LIB) ;
31            
32             BEGIN {
33 2     2   7 *LIBZIP = \$LibZip::InitLib::LIBZIP ;
34 2         5 *LIBTMP = \$LibZip::InitLib::LIBTMP ;
35 2         6 *LIBTMPFIX = \$LibZip::InitLib::LIBTMPFIX ;
36 2         8 *FILETMP = \*LibZip::InitLib::FILETMP ;
37            
38 2         5 $DEBUG = 0 ;
39            
40 2 50       13 $LIBTMP = './lib/' if !defined $LIBTMP ;
41 2 50       7 $CALL_BEGIN = 0 if !defined $CALL_BEGIN ;
42 2 50       475 $HOOK_ADDED = 0 if !defined $HOOK_ADDED ;
43             }
44            
45             begin() ;
46            
47             ##########
48             # IMPORT #
49             ##########
50            
51             sub import {
52 2     2   95 my ($class , @args) = @_ ;
53            
54 2 50       16 if (-s $args[0]) { $LIBZIP = $args[0] ;}
  0         0  
55            
56 2 50       14 &LoadLibZip($LIBZIP) if $LIBZIP ;
57             }
58            
59             #######
60             # INC #
61             #######
62            
63             sub INC {
64 15     15   291757 my ( $ref , $pack ) = @_ ;
65            
66 15 100       219 print "HOOK>> $pack\n" if $DEBUG ;
67            
68 15         49 my $pack_fl = find_file_zip($pack) ;
69            
70 15 100       126 if ($pack_fl eq '') { return( undef ) ;}
  14         14621  
71            
72 1         5 check_pack_dep($pack_fl) ;
73            
74 1         4 $INC{$pack} = "$LIBTMP/$pack_fl" ;
75            
76 1         5 return( get_file_zip_handle( $pack_fl , $pack ) ) ;
77             }
78            
79             sub BEGIN {
80 2 50   2   16 if ( !$HOOK_ADDED ) {
81 2         4 $HOOK_ADDED = 1 ;
82 2         5973 unshift(@INC , \&INC ) ;
83             }
84             }
85            
86             ##############
87             # LOADLIBZIP #
88             ##############
89            
90             sub LoadLibZip {
91 2     2 0 4 my ( $libzip ) = @_ ;
92            
93 2 50       9 print "LOAD>> $libzip\n" if $DEBUG ;
94            
95 2 50       34 if (!-s $libzip) { warn("Can't find or load LibZip: $libzip") ; return ;}
  0         0  
  0         0  
96            
97 2         12 begin() ;
98            
99 2         18 $ZIP = LibZip::MyArchZip->new();
100 2         11 $ZIP->read($libzip);
101            
102 2         12 %LIBTREE = map { $_ => 1 } ($ZIP->memberNames()) ;
  4         17  
103            
104 2         13 foreach my $Key ( keys %LIBTREE ) {
105 4         26 my ($dir) = ( $Key =~ /^(.*?)[\\\/][^\\\/]+$/ );
106 4         20 $LIBTREE{"$dir/"} = $LIBTREE{"$dir"} = 1 ;
107             }
108            
109 2         13 my %libbases ;
110 2         7 foreach my $libtree_i ( keys %LIBTREE ) {
111 10 100       41 if ($libtree_i =~ /^(\/*(?:lib|site\/lib))\/[^\\\/]/i) {
112 2 50       16 push(@LIBBASES , $1) if !$libbases{$1}++ ;
113             #my $memb = $ZIP->memberNamed($libtree_i) ;
114             #if ( $memb->isDirectory ) { push(@LIBBASES , $libtree_i) ;}
115             }
116             }
117            
118 2         6 push(@LIBBASES , "") ;
119            
120 2         11 foreach my $LIBBASES_i ( @LIBBASES ) { unshift(@INC , "$LIBTMP/$LIBBASES_i") ;}
  4         17  
121            
122 2         4 my $libzipdir ;
123            
124 2         6 foreach my $LIBBASES_i ( @LIBBASES ) {
125 4         13 my $dir = zip_path($LIBBASES_i,'LibZip') ;
126 4 50       24 if ($LIBTREE{$dir}) { $libzipdir = $dir ;}
  0         0  
127             }
128            
129 2         4 my $LibZipInfo_pm ;
130            
131 2 50       7 if ($libzipdir eq '') { $LibZipInfo_pm = 'LibZipInfo.pm' ;}
  2         7  
132 0         0 else { $LibZipInfo_pm = zip_path($libzipdir,'Info.pm') ;}
133            
134 2 50       9 if ($LIBTREE{$LibZipInfo_pm}) {
135 0         0 my $pack = pm2pack($LibZipInfo_pm) ;
136 0         0 eval("require $pack ;") ;
137             }
138 2         149 else { eval("require LibZip::Info ;") ;}
139            
140             }
141            
142             #################
143             # FIND_FILE_ZIP #
144             #################
145            
146             sub find_file_zip {
147 15     15 0 97 my ( $pack ) = @_ ;
148            
149 15         35 foreach my $LIB_i ( @LIBBASES ) {
150 29         75 my $fl = zip_path($LIB_i,$pack) ;
151 29 100       115 if ( $LIBTREE{$fl} ) { return( $fl ) ;}
  1         4  
152             }
153            
154 14         30 return( undef ) ;
155             }
156            
157             #######################
158             # GET_FILE_ZIP_HANDLE #
159             #######################
160            
161             sub get_file_zip_handle {
162 1     1 0 2 my ( $file , $pack ) = @_ ;
163            
164 1         4 my $filename = "$LIBTMP/$file" ;
165            
166 1         8 my $memb = $ZIP->memberNamed($file) ;
167 1         3 my $size = $memb->{'uncompressedSize'} ;
168            
169 1 50 33     31 if ($size > 0 && -s $filename != $size) {
170 1         7 $ZIP->extractMember($file,$filename) ;
171 1 50       154 print "ZIP>> $file >> $filename\n" if $DEBUG ;
172             }
173            
174 1         3 $PMFILE = $filename ;
175            
176 1         3 my $fh ;
177 1         37 open ($fh,$filename) ; binmode($fh) ;
  1         3  
178            
179 1         316 return( $fh ) ;
180             }
181            
182             ###########
183             # PM2PACK #
184             ###########
185            
186             sub pm2pack {
187 0     0 0 0 my ( $pack ) = @_ ;
188 0         0 $pack =~ s/^.*?\/lib\///i ;
189 0         0 $pack =~ s/[\\\/]/::/gs ;
190 0         0 $pack =~ s/\.pm$//i ;
191 0         0 return( $pack ) ;
192             }
193            
194             ############
195             # ZIP_PATH #
196             ############
197            
198             sub zip_path {
199 35     35 0 65 my ( $dir ) = @_ ;
200 35 100 66     214 $dir .= '/' if ($dir ne '' && $dir !~ /\/$/) ;
201 35         59 $dir .= $_[1] ;
202 35         81 return( $dir ) ;
203             }
204            
205             ##################
206             # CHECK_PACK_DEP #
207             ##################
208            
209             sub check_pack_dep {
210 1     1 0 3 my ( $pack ) = @_ ;
211            
212 1         8 $pack =~ s/\/*\.pm$/\//i ;
213            
214 1 50       115 print "LIBZIP DEP>> @_\n" if $DEBUG ;
215            
216 1 50       7 if ( $DEP{$pack} ) { return ;}
  0         0  
217            
218 1 50 33     9 if ( !$LIBTREE{$pack} && !$LIBTREE{$_[0]} ) {
219 0         0 my $exists ;
220 0         0 foreach my $LIBBASES_i ( @LIBBASES ) {
221 0         0 my $path0 = zip_path($LIBBASES_i,$pack) ;
222 0         0 my $path1 = zip_path($LIBBASES_i,$_[0]) ;
223 0 0 0     0 if ( $LIBTREE{$path0} || $LIBTREE{$path1} ) {
224 0         0 $pack = $path0 ;
225 0         0 $exists = 1 ;
226 0         0 last ;
227             }
228             }
229 0 0       0 return if !$exists ;
230             }
231            
232 1         4 $DEP{$pack} = 1 ;
233            
234 1         4 foreach my $path ( keys %LIBTREE ) {
235 5 100       18 if ( $path !~ /\/$/ ) {
236 3 50 33     44 if ( $path =~ /^\Q$pack\E[^\/]+$/ && $path !~ /\.pm$/i) {
237 0         0 my $extract = "$LIBTMP/$path" ;
238 0         0 my $memb = $ZIP->memberNamed($path) ;
239 0         0 my $size = $memb->{'uncompressedSize'} ;
240            
241 0 0 0     0 if ($size > 0 && -s $extract != $size) {
242 0         0 $ZIP->extractMember($path,$extract) ;
243 0 0       0 print "DEP>> $path\n" if $DEBUG ;
244             }
245             }
246             }
247             }
248            
249 1 50 33     15 if ($pack =~ /^(?:lib|site\/lib)\/([^\/]+.*)$/ && !$_[1] ) {
250 1         4 my $pack_path = $1 ;
251 1         3 foreach my $LIBBASES_i ( @LIBBASES ) {
252 2         10 my $auto = zip_path($LIBBASES_i,"auto/$pack_path") ;
253 2 50       8 if ( $LIBTREE{$auto} ) { check_pack_dep("$auto.pm",1) ;}
  0         0  
254             }
255             }
256            
257 1 50       4 if ( %LibZip::Info::DEPENDENCIES ) {
258 0         0 my $package = pm2pack($_[0]) ;
259 0         0 $package =~ s/^(?:lib|site::lib)::// ;
260            
261 0         0 foreach my $Key ( keys %LibZip::Info::DEPENDENCIES ) {
262 0 0       0 if ( $Key =~ /^$package$/i ) {
263 0         0 my @dep ;
264 0 0       0 if (ref($LibZip::Info::DEPENDENCIES{$Key}) eq 'ARRAY' ) { @dep = @{$LibZip::Info::DEPENDENCIES{$Key}} ;}
  0         0  
  0         0  
265 0         0 else { @dep = $LibZip::Info::DEPENDENCIES{$Key} ;}
266 0         0 foreach my $dep_i ( @dep ) {
267 0         0 my $path = find_file_zip($dep_i) ;
268 0         0 my $extract = "$LIBTMP/$path" ;
269 0 0       0 if ($path =~ /\/$/) {
270 0         0 $ZIP->extractTree($path,$extract) ;
271 0 0       0 print "%DEP>> $path >> $extract\n" if $DEBUG ;
272             }
273             else {
274 0         0 my $memb = $ZIP->memberNamed($path) ;
275 0         0 my $size = $memb->{'uncompressedSize'} ;
276 0 0 0     0 if ($size > 0 && -s $extract != $size) {
277 0         0 $ZIP->extractMember($path,$extract) ;
278 0 0       0 print "%DEP>> $path >> $extract\n" if $DEBUG ;
279             }
280             }
281 0         0 check_pack_dep($path) ;
282             }
283             }
284             }
285             }
286            
287 1         3 return( undef ) ;
288             }
289            
290             ######################
291             # LIB_HAS_DYNALOADER #
292             ######################
293            
294             sub lib_has_dynaLoader {
295 0 0 0 0 0 0 return 1 if $LIBTREE{"DynaLoader.pm"} || $LIBTREE{"lib/DynaLoader.pm"} ;
296             }
297            
298             ################
299             # CHK_DEAD_TMP # Check LIBTMP for dead files and rmtree(LIBTMP) if possible.
300             ################
301            
302             sub chk_dead_tmp {
303 4     4 0 129 opendir (LIBTMPDIR, $LIBTMP) ;
304            
305 4         6 my ($has_files,@dirs) ;
306            
307 4         122 while (my $filename = readdir LIBTMPDIR) {
308 11 100 100     88 if ($filename ne "\." && $filename ne "\.\.") {
309 3         9 my $file = "$LIBTMP/$filename" ;
310 3 100       43 if (-d $file) {
311 1 50 33     10 push(@dirs , $file) if !$LIBTMPFIX || $filename ne 'auto' ;
312             }
313             else {
314 2         28 my ($pid) = ( $filename =~ /^pm-(-?[\d]+)-/i );
315 2 50       8 if ($_[0] ne '') {
    0          
316 2 50 33     20 if ($pid != $_[0] && !kill(0,$pid)) { unlink ($file) ;}
  0         0  
317 2         10 else { $has_files = 1 ;}
318             }
319 0         0 elsif (! kill(0,$pid)) { unlink ($file) ;}
320 0         0 else { $has_files = 1 ;}
321             }
322             }
323             }
324            
325 4 100       18 if (! $has_files) {
326 2         14 foreach my $dirs_i ( @dirs ) { LibZip::File::Path::rmtree($dirs_i,0) ;}
  1         7  
327             }
328            
329 4         56 closedir(LIBTMPDIR) ;
330             }
331            
332             ###################
333             # CHK_DEAD_TMPDIR # Check for libtmp dirs of ended PIDs.
334             ###################
335            
336             sub chk_dead_tmpdir {
337 4     4 0 10 my $dir = '.' ;
338 4         78 opendir (LIBTMPDIR, $dir) ;
339            
340 4         68 while (my $filename = readdir LIBTMPDIR) {
341 24 100       269 if ($filename =~ /^libzip-(-?\d+)-\w+-tmp$/ ) {
342 4         19 my $pid = $1 ;
343 4         12 my $file = "$dir/$filename" ;
344 4 50 33     129 if ( -d $file && !kill(0,$pid) ) {
345 0         0 LibZip::File::Path::rmtree($file,0) ;
346             }
347             }
348             }
349            
350 4         41 closedir(LIBTMPDIR) ;
351             }
352            
353             #########
354             # BEGIN #
355             #########
356            
357             sub begin {
358 6 100   6 0 18 return if $CALL_BEGIN ;
359 2         5 $CALL_BEGIN = 1 ;
360 2         20 LibZip::InitLib::begin() ;
361 2         9 chk_dead_tmp($$) ;
362 2         8 chk_dead_tmpdir() ;
363 2         574 return ;
364             }
365            
366 2     2   9 sub BEGIN { &begin ;}
367            
368             #######
369             # END #
370             #######
371            
372             sub end {
373 2     2 0 6 $END = 1 ;
374            
375 2         8 foreach my $DATAPACK_i ( @DATAPACK ) {
376 0         0 eval(qq`close($DATAPACK_i\::DATA);`);
377             }
378            
379 2         32 close(FILETMP) ;
380 2         194 unlink($FILETMP) ;
381            
382 2         9 &chk_dead_tmp ;
383 2         10 &chk_dead_tmpdir ;
384            
385 2         22 LibZip::InitLib::end() ;
386             }
387            
388 2     2   1007 sub END { &end }
389            
390             #######
391             # END #
392             #######
393            
394             1;
395            
396