File Coverage

blib/lib/CGI/SSI_Parser.pm
Criterion Covered Total %
statement 12 208 5.7
branch 0 98 0.0
condition 0 9 0.0
subroutine 4 21 19.0
pod 0 17 0.0
total 16 353 4.5


line stmt bran cond sub pod time code
1             package CGI::SSI_Parser;
2              
3 1     1   726 use strict;
  1         2  
  1         40  
4 1     1   997 use POSIX;
  1         9071  
  1         11  
5 1     1   4059 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
  1         9  
  1         218  
6              
7             require Exporter;
8              
9             @ISA = qw(Exporter AutoLoader);
10             @EXPORT = qw(fssi sssi);
11             $VERSION = '0.01';
12              
13 1     1   6 use vars qw($recursive $debug);
  1         2  
  1         3292  
14              
15             $recursive = 0;
16             $debug = 0;
17              
18             my $error_msg = '[an error occurred while processing this directive]';
19             my $SIZEFMT_BYTES = 0; # sizefmt = bytes
20             my $SIZEFMT_KMG = 1; # sizefmt = abbrev
21             my $sizefmt = $SIZEFMT_KMG;
22             my $timefmt = "%c"; # current locale's default
23             my($starting_sequence, $ending_sequence) = ('');
24             my($real_path, $virtual_path);
25              
26              
27             # Usage: ssi_init();
28             #
29             sub ssi_init {
30 0     0 0   my(@real_path, @virtual_path);
31 0           my $i;
32              
33 0 0 0       unless (defined($ENV{'DOCUMENT_ROOT'}) ||
      0        
34             defined($ENV{'SCRIPT_FILENAME'}) ||
35             defined($ENV{'SCRIPT_NAME'})) {
36 0           print FOUT $error_msg;
37 0           return 0;
38             }
39              
40 0           @real_path = reverse split(/\//, $ENV{'SCRIPT_FILENAME'});
41 0           pop(@real_path);
42 0           @virtual_path = reverse split(/\//, $ENV{'SCRIPT_NAME'});
43 0           pop(@virtual_path);
44              
45 0   0       for ($i=0; (($i <= $#virtual_path) && ($virtual_path[$i] eq $real_path[$i])); $i++) {
46             }
47              
48 0           $real_path = "/" . join("/", reverse @real_path[$i..$#real_path]);
49 0           $virtual_path = "/" . join("/", reverse @virtual_path[$i..$#virtual_path]);
50              
51             # $file =~ s/^$virtual_path/$real_path\//o;
52             # warn($file) if ($debug);
53             }
54              
55             # Usage: ssi_config_errmsg($line);
56             #
57             sub ssi_config_errmsg {
58 0     0 0   my $line = shift;
59              
60 0           $error_msg = $line;
61             }
62              
63             # Usage: ssi_config_sizefmt($line);
64             #
65             sub ssi_config_sizefmt {
66 0     0 0   my $line = shift;
67              
68 0 0         if ($line eq "bytes") {
    0          
69 0           $sizefmt = $SIZEFMT_BYTES;
70             } elsif ($line eq "abbrev") {
71 0           $sizefmt = $SIZEFMT_KMG;
72             }
73             }
74              
75             # Usage: ssi_config_timefmt($line);
76             #
77             sub ssi_config_timefmt {
78 0     0 0   my $line = shift;
79              
80 0           $timefmt = $line;
81             }
82              
83             # Usage: ssi_echo_var($line);
84             #
85             sub ssi_echo_var {
86 0     0 0   my $line = shift;
87              
88 0 0         if ($line eq "DATE_GMT") {
    0          
    0          
    0          
    0          
89 0           print FOUT strftime($timefmt, gmtime(time));
90             } elsif ($line eq "DATE_LOCAL") {
91 0           print FOUT strftime($timefmt, localtime(time));
92             } elsif ($line eq "DOCUMENT_NAME") {
93 0           print FOUT "(none)";
94             } elsif ($line eq "DOCUMENT_URI") {
95 0           print FOUT "(none)";
96             } elsif ($line eq "LAST_MODIFIED") {
97 0           print FOUT "(none)";
98             } else {
99 0           print FOUT "(none)";
100             }
101             }
102              
103             # Usage: ssi_exec_cgi($file);
104             #
105             sub ssi_exec_cgi {
106 0     0 0   my $file = shift;
107 0           my $line;
108 0           local(*FIN);
109              
110 0           $file =~ s/^$virtual_path/$real_path\//o;
111              
112 0           open(FIN, "$file|");
113 0 0         unless($line = join("", )) {
114 0 0         warn("Can't run $file\n") if ($debug);
115 0           print FOUT $error_msg;
116 0           return;
117             }
118 0           $line =~ /\r?\n\r?\n/o;
119 0           $line = $';
120 0 0         if ($recursive) {
121 0           sssi($line);
122             } else {
123 0           print FOUT $line;
124             }
125 0           close(FIN);
126             }
127              
128             # Usage: ssi_exec_cmd($file);
129             #
130             sub ssi_exec_cmd {
131 0     0 0   my $file = shift;
132 0           my $line;
133 0           local(*FIN);
134              
135 0           open(FIN, "$file|");
136 0 0         unless($line = join("", )) {
137 0           print FOUT $error_msg;
138 0           return;
139             }
140 0 0         if ($recursive) {
141 0           sssi($line);
142             } else {
143 0           print FOUT $line;
144             }
145 0           close(FIN);
146             }
147              
148             # Usage: ssi_fsize_file($file);
149             #
150             sub ssi_fsize_file {
151 0     0 0   my $file = shift;
152 0           my $size;
153              
154 0           $size = (stat("$file"))[7];
155 0 0         if ($sizefmt == $SIZEFMT_KMG) {
156 0 0         if ($size/1048576 >= 1) { # 1024*1024
157 0           $size = sprintf("%.1fM", $size/1048576);
158             } else {
159 0           $size = ceil($size/1024) . "k";
160             }
161             }
162 0           print FOUT $size;
163             }
164              
165             # Usage: ssi_fsize_virtual($file);
166             #
167             sub ssi_fsize_virtual {
168 0     0 0   my $file = shift;
169              
170 0           $file = "$ENV{'DOCUMENT_ROOT'}/$file";
171 0           ssi_fsize_file($file);
172             }
173              
174             # Usage: ssi_flastmod_file($file);
175             #
176             sub ssi_flastmod_file {
177 0     0 0   my $file = shift;
178 0           my $lastmod;
179              
180 0           $lastmod = (stat("$file"))[9];
181 0           $lastmod = strftime($timefmt, localtime($lastmod));
182 0           print FOUT $lastmod;
183             }
184              
185             # Usage: ssi_flastmod_virtual($file);
186             #
187             sub ssi_flastmod_virtual {
188 0     0 0   my $file = shift;
189              
190 0           $file = "$ENV{'DOCUMENT_ROOT'}/$file";
191 0           ssi_flastmod_file($file);
192             }
193              
194             # Usage: ssi_include_file($file);
195             #
196             sub ssi_include_file {
197 0     0 0   my $file = shift;
198 0           my $line;
199 0           local(*FIN);
200              
201 0 0         unless(open(FIN, $file)) {
202 0           print FOUT $error_msg;
203 0           warn("Can't open file $file: $!");
204 0           return;
205             }
206 0           $line = join("", );
207 0 0         if ($recursive) {
208 0           sssi($line);
209             } else {
210 0           print FOUT $line;
211             }
212 0           close(FIN);
213             }
214              
215             # Usage: ssi_include_virtual($file);
216             #
217             sub ssi_include_virtual {
218 0     0 0   my $file = shift;
219              
220 0           $file = "$ENV{'DOCUMENT_ROOT'}/$file";
221 0           ssi_include_file($file);
222             }
223              
224             # Usage: ssi_printenv();
225             #
226             sub ssi_printenv {
227 0     0 0   foreach (sort keys(%ENV)) {
228 0           print "$_=$ENV{$_}\n";
229             }
230             }
231              
232             # Usage: parse_ssi($ssi);
233             #
234             sub parse_ssi {
235 0     0 0   my $ssi = shift;
236 0           my($element, @attr);
237              
238 0           $ssi =~ /^(\w+)/;
239 0           $element = $1;
240 0           $ssi = $';
241 0           $ssi =~ s/^\s+//;
242 0 0         if ($element eq "config") {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
243 0           while ($ssi =~ /(\w+)="(.*[^\\])"/) {
244 0 0         if ($1 eq "errmsg") {
    0          
    0          
245 0           ssi_config_errmsg($2);
246             } elsif ($1 eq "sizefmt") {
247 0           ssi_config_sizefmt($2);
248             } elsif ($1 eq "timefmt") {
249 0           ssi_config_timefmt($2);
250             } else {
251 0           print FOUT $error_msg;
252             }
253 0           $ssi = $';
254             }
255             } elsif ($element eq "echo") {
256 0           while ($ssi =~ /(\w+)="(.*[^\\])"/) {
257 0 0         if ($1 eq "var") {
258 0           ssi_echo_var($2);
259             } else {
260 0           print FOUT $error_msg;
261             }
262 0           $ssi = $';
263             }
264             } elsif ($element eq "exec") {
265 0           while ($ssi =~ /(\w+)="(.*[^\\])"/) {
266 0 0         if ($1 eq "cgi") {
    0          
267 0           ssi_exec_cgi($2);
268             } elsif ($1 eq "cmd") {
269 0           ssi_exec_cmd($2);
270             } else {
271 0           print FOUT $error_msg;
272             }
273 0           $ssi = $';
274             }
275             } elsif ($element eq "fsize") {
276 0           while ($ssi =~ /(\w+)="(.*[^\\])"/) {
277 0 0         if ($1 eq "file") {
    0          
278 0           ssi_fsize_file($2);
279             } elsif ($1 eq "virtual") {
280 0           ssi_fsize_virtual($2);
281             } else {
282 0           print FOUT $error_msg;
283             }
284 0           $ssi = $';
285             }
286             } elsif ($element eq "flastmod") {
287 0           while ($ssi =~ /(\w+)="(.*[^\\])"/) {
288 0 0         if ($1 eq "file") {
    0          
289 0           ssi_flastmod_file($2);
290             } elsif ($1 eq "virtual") {
291 0           ssi_flastmod_virtual($2);
292             } else {
293 0           print FOUT $error_msg;
294             }
295 0           $ssi = $';
296             }
297             } elsif ($element eq "include") {
298 0           while ($ssi =~ /(\w+)="(.*[^\\])"/) {
299 0 0         if ($1 eq "file") {
    0          
300 0           ssi_include_file($2);
301             } elsif ($1 eq "virtual") {
302 0           ssi_include_virtual($2);
303             } else {
304 0           print FOUT $error_msg;
305             }
306 0           $ssi = $';
307             }
308             } elsif ($element eq "printenv") {
309 0 0         if ($ssi eq "") {
310 0           ssi_printenv();
311             } else {
312 0           print FOUT $error_msg;
313             }
314             } elsif ($element eq "set") {
315 0           print FOUT $error_msg;
316             } else {
317 0           print FOUT $error_msg;
318             }
319             }
320              
321             # Usage: fssi($file);
322             #
323             sub fssi {
324 0     0 0   my $file = shift;
325 0           my($line, $ssi);
326 0           local(*FIN, *FOUT);
327 0           my $inside = 0;
328              
329 0           *FOUT = *STDOUT;
330              
331 0 0         ssi_init() || return 0;
332              
333 0 0         unless(open(FIN, $file)) {
334 0           print FOUT $error_msg;
335 0           warn("Can't open file $file: $!");
336 0           return;
337             }
338              
339 0           while ($line = ) {
340 0 0         if ($inside) {
341 0 0         if ($line =~ /$ending_sequence/) {
342 0           $inside = 0;
343 0           $ssi .= $`;
344 0           $line = $';
345 0           $ssi =~ s/^\s+//s;
346 0           $ssi =~ s/\s+$//s;
347 0           $ssi =~ s/\s+/ /s;
348             # execute SSI
349 0 0         warn("SSI: $ssi.\n") if ($debug);
350 0           parse_ssi($ssi);
351 0           $ssi = '';
352 0           redo;
353             } else {
354 0           $ssi .= $line;
355             }
356             } else {
357 0 0         if ($line =~ /$starting_sequence/) {
358 0           $inside = 1;
359 0           print FOUT $`;
360 0           $line = $';
361 0           redo;
362             } else {
363 0           print FOUT $line;
364             }
365             }
366             }
367              
368 0           close(FIN);
369             }
370              
371             # Usage: sssi($line);
372             #
373             sub sssi {
374 0     0 0   my $line = shift;
375 0           my $ssi;
376 0           local(*FIN, *FOUT);
377 0           my $inside = 0;
378              
379 0           *FOUT = *STDOUT;
380              
381 0 0         ssi_init() || return 0;
382              
383 0           while (1) {
384 0 0         if ($inside) {
385 0 0         if ($line =~ /$ending_sequence/) {
386 0           $inside = 0;
387 0           $ssi .= $`;
388 0           $line = $';
389 0           $ssi =~ s/^\s+//s;
390 0           $ssi =~ s/\s+$//s;
391 0           $ssi =~ s/\s+/ /s;
392             # execute SSI
393 0 0         warn("SSI: $ssi.\n") if ($debug);
394 0           parse_ssi($ssi);
395 0           $ssi = '';
396 0           redo;
397             } else {
398 0           $ssi .= $line;
399             }
400             } else {
401 0 0         if ($line =~ /$starting_sequence/) {
402 0           $inside = 1;
403 0           print FOUT $`;
404 0           $line = $';
405 0           redo;
406             } else {
407 0           print FOUT $line;
408 0           last;
409             }
410             }
411             }
412             }
413              
414             1;
415             __END__