File Coverage

blib/lib/HTTP/ProxyAutoConfig.pm
Criterion Covered Total %
statement 165 321 51.4
branch 78 254 30.7
condition 48 237 20.2
subroutine 20 28 71.4
pod 3 20 15.0
total 314 860 36.5


line stmt bran cond sub pod time code
1             package HTTP::ProxyAutoConfig;
2              
3             =head1 NAME
4              
5             HTTP::ProxyAutoConfig - use a .pac or wpad.dat file to get proxy information
6              
7             =head1 SYNOPSIS
8              
9             use HTTP::ProxyAutoConfig;
10              
11             my $pac = HTTP::ProxyAutoConfig->new("http://foo.bar/auto-proxy.pac");
12             my $pac = new HTTP::ProxyAutoConfig('/Documents and Settings/me/proxy.pac');
13             my $pac = HTTP::ProxyAutoConfig->new();
14              
15             my $proxy = $pac->FindProxy('http://www.yahoo.com');
16              
17             =head1 DESCRIPTION
18              
19             I allows perl scripts that need to access the
20             Internet to determine whether to do so via a proxy server. To do this,
21             it uses proxy settings provided by an IT department, either on the Web
22             or in a browser's I<.pac> file on disk.
23              
24             It provides means to find the proxy server (or lack of one) for
25             a given URL. If your application has located either a I
26             file or a I<.pac> file, I processes it
27             to determine how to handle a particular destination URL.
28             If it's not given a I or I<.pac> file, I
29             tests environment variables to determine whether there's a proxy server.
30              
31             A I or I<.pac> file contains a JavaScript function called
32             I. This module allows you to call the function to
33             learn how to access various URLs.
34              
35             Mapping from a URL to the proxy information is provided by a
36             I or I function call.
37             Both functions return a string that tells your application what to do,
38             namely a direct connection to the Internet or a connection via a proxy
39             server.
40              
41             The Proxy Auto Config format and rules were originally developed at
42             Netscape. The Netscape documentation is archived at
43             L
44              
45             More recent references include:
46              
47             =over 4
48              
49             =item L
50              
51             =item L
52              
53             =item L
54              
55             =item L
56              
57             =back
58              
59             =head1 METHODS
60              
61             =head2 new( url_or_file )
62              
63             This call creates the I function and the object through
64             which it can be called. The I argument is optional, and
65             points to the auto-proxy file provided on your network or a file used
66             by your browser. If there is no argument, I
67             will check the I environment variable, followed by the
68             I, I, and I variables.
69              
70             As shown above, you can use either the Inew()>
71             or the I form, but don't use the
72             I form.
73              
74             =head2 FindProxyForURL( url, host )
75              
76             This takes the url, and the host (minus port) from the URL, and
77             determines the action you should take to contact that host.
78             It returns one of three strings:
79              
80             DIRECT - connect directly
81             PROXY host:port - connect via the proxy
82             SOCKS host:port - connect via SOCKS
83              
84             This result can be used to configure a net-access module like LWP.
85              
86             =head2 FindProxy( url )
87              
88             Same as the previous call, except you don't have to extract the host
89             from the URL.
90              
91             =head1 AUTHORS
92              
93             By Ryan Eatmon in May of 2001
94             0.2 by Craig MacKenna, March 2010
95              
96             =head1 COPYRIGHT AND LICENSE
97              
98             Copyright (C) 2001, Ryan Eatmon
99             Copyright (C) 2010, Craig MacKenna
100              
101             This module is free software; you may redistribute it and/or
102             modify it under the same terms as Perl 5.10.1. For more details,
103             see the full text of the licenses at
104             L and
105             L
106              
107             This program is distributed in the hope that it will be useful, but
108             it is provided 'as is' and without any express or implied warranties.
109             For details, see the full text of the licenses at the above URLs.
110              
111             =cut
112              
113 2     2   1726036 use strict;
  2         4  
  2         72  
114 2     2   11 use warnings;
  2         4  
  2         59  
115 2     2   10 use Carp;
  2         7  
  2         149  
116 2     2   1021 use Sys::Hostname;
  2         1158  
  2         104  
117 2     2   1750 use IO::Socket;
  2         75128  
  2         9  
118              
119             our $VERSION = "0.3";
120              
121             sub new {
122 3     3 1 606522 my $proto = shift;
123 3         10 my $self = { };
124              
125 3         9 bless($self,$proto);
126              
127 3 50       36 $self->{URL} = shift if ($#_ > -1);
128 3         17 $self->Reload();
129 3         16 return $self;
130             }
131              
132              
133             ##############################################################################
134             #
135             # FindProxy - wrapper for FindProxyForURL function so that you don't have to
136             # figure out the host.
137             #
138             ##############################################################################
139             sub FindProxy {
140 12     12 1 316742 my $self = shift;
141 12         26 my ($url) = @_;
142 12         25 my $host;
143 12         207 (undef, $host) = ($url =~ m'^([a-z]+://)?([^/]+)');
144              
145 12         977 foreach my $proxy (split(/\s*\;\s*/, $self->FindProxyForURL($url, $host))) {
146              
147 12 100       50 return $proxy if ($proxy eq "DIRECT");
148              
149 8         44 my ($host, $port) = ($proxy =~ /^PROXY\s*(\S+):(\d+)$/);
150              
151 8 50       240 return $proxy if (new IO::Socket::INET(PeerAddr=>$host,
152             PeerPort=>$port,
153             Proto=>"tcp"));
154             }
155 0         0 return undef;
156             }
157              
158              
159             ##############################################################################
160             #
161             # Reload - grok the environment variables and define the FindProxyForURL
162             # function.
163             #
164             ##############################################################################
165             sub Reload {
166 3     3 0 11 my $self = shift;
167              
168 3 50       17 my $url = (exists($self->{URL}) ? $self->{URL} : $ENV{"http_auto_proxy"});
169              
170 3 50 33     29 if (defined($url) && ($url ne "")) {
171              
172             ########## accept file path as well as URL
173             ########## added to version 0.2 cmac march 2010
174 3         8 my $function = ""; # used to be further down
175 3         5 my ($rsize, $f);
176 3 100 66     73 if ($url !~ m'^[a-z]+://'
177             && -e $url) {
178              
179             # looks like $url is a path to a file
180 2 50       88 open($f, "<$url") or die "Can't open $url for read: $!";
181 2 50       32 my $size = -s $url or die "$url seems to be empty";
182 2 50 33     71 ($rsize = read($f, $function, $size)) && $rsize == $size
183             or die "$url contains $size bytes, but 'read' read $rsize bytes";
184 2 50       25 close($f) or die "Can't close $url: $!";
185             } else {
186             ########## end addition
187              
188 1         12 my ($host, $port, $path) = ($url =~ /^http:\/\/([^\/:]+):?(\d*)\/?(.*)$/);
189              
190 1 50       7 $port = 80 if ($port eq "");
191              
192 1         15 my $sock = new IO::Socket::INET(PeerAddr=>$host,
193             PeerPort=>$port,
194             Proto=>"tcp");
195              
196 1 50       154908 die("Cannot create normal socket: $!") unless defined($sock);
197              
198 1         12 my $send = "GET /$path HTTP/1.1\r\nCache-Control: no-cache\r\nHost: $host:$port\r\n\r\n";
199              
200 1         28 $sock->syswrite($send, length($send), 0);
201             # modified 25 Mar 2010: it took minutes for a timeout on a 0-length buffer
202             # what's a reasonable max for HTTP headers plus a GetProxyFromURL function?
203 1         161 $sock->sysread($function, 1<<20);
204              
205 1         163702 my $chunked = ($function =~ /chunked/);
206              
207 1         78 $function =~ s/^.+?\r?\n\r?\n//s;
208 1 50       301 if ($chunked == 1) {
209 0         0 $function =~ s/\n\r\n\S+\s*\r\n/\n/g;
210 0         0 $function =~ s/^\S+\s*\r\n//;
211             }
212             } # end of get $function from internet
213 3         23 $function = $self->JavaScript2Perl($function);
214             {
215 2     2   2613 no warnings 'redefine';
  2         4  
  2         1239  
  3         8  
216 3 100   8 1 607 eval($function);
  8 100       26  
  8 100       13  
  8         57  
  2         20  
  6         25  
  1         7  
  5         257  
  2         18  
  3         32  
217             }
218             ########## added to version 0.2 cmac march 2010
219 3 50       34 if ($@) {die "Bad JavaScript->perl translation.\n"
  0         0  
220             . "Please notify the co-maintainer of HTTP::ProxyAutoConfig:\n$@"}
221             } else {
222 0         0 my $http_host;
223             my $http_port;
224 0         0 my $function = "sub FindProxyForURL { my (\$self,\$url,\$host) = \@_; ";
225 0         0 $function .= "if (isResolvable(\$host)) { return \"DIRECT\"; } ";
226 0 0       0 if (exists($ENV{http_proxy})) {
227 0         0 ($http_host,$http_port) = ($ENV{"http_proxy"} =~ /^(\S+)\:(\d+)$/);
228 0         0 $http_host =~ s/^http\:\/\///;
229 0         0 $function .= "if (shExpMatch(\$url,\"http://*\")) { return \"PROXY $http_host\:$http_port\"; } ";
230             }
231 0 0       0 if (exists($ENV{https_proxy})) {
232 0         0 my($host,$port) = ($ENV{"https_proxy"} =~ /^(\S+)\:(\d+)$/);
233 0         0 $host =~ s/^https?\:\/\///;
234 0         0 $function .= "if (shExpMatch(\$url,\"https://*\")) { return \"PROXY $host\:$port\"; } ";
235             }
236 0 0       0 if (exists($ENV{ftp_proxy})) {
237 0         0 my($host,$port) = ($ENV{"ftp_proxy"} =~ /^(\S+)\:(\d+)$/);
238 0         0 $host =~ s/^ftp\:\/\///;
239 0         0 $function .= "if (shExpMatch(\$url,\"ftp://*\")) { return \"PROXY $host\:$port\"; } ";
240             }
241 0 0 0     0 if (defined($http_host) && defined($http_port)) {
242 0         0 $function .= " return \"PROXY $http_host\:$http_port\"; }";
243             } else {
244 0         0 $function .= " return \"DIRECT\"; }";
245             }
246             {
247 2     2   12 no warnings 'redefine';
  2         4  
  2         4782  
  0         0  
248 0         0 eval($function);
249             }
250 0 0       0 if ($@) {die $@}
  0         0  
251             }
252             }
253              
254             ##############################################################################
255             #
256             # JavaScript2Perl - function to convert JavaScript code into Perl code.
257             #
258             ##############################################################################
259             sub JavaScript2Perl {
260 3     3 0 7 my $self = shift;
261 3         8 my ($function) = @_;
262              
263 3         8 my $quoted = 0;
264 3         7 my $blockComment = 0;
265 3         4 my $lineComment = 0;
266 3         6 my $newFunction = "";
267              
268 3         6 my %vars;
269             my $variable;
270              
271             # remove comments, substitute . for +, index variable names
272 3         302 foreach my $piece (split(/(\s)/,$function)) {
273 552         1243 foreach my $subpiece (split(/([\"\'\=])/,$piece)) {
274 581 100       1117 next if ($subpiece eq "");
275 554 100 100     1223 if ($subpiece eq "=" && $variable =~ /^\w/) {
276 2         5 $vars{$variable} = 1;
277             }
278 554 100       1119 $variable = $subpiece unless ($subpiece eq " ");
279              
280 554 50 66     2002 $subpiece = "." if (($quoted == 0) && ($subpiece eq "+"));
281              
282 554 100       1027 $lineComment = 0 if ($subpiece eq "\n");
283 554 100 100     3424 $quoted ^= 1 if (($blockComment == 0) &&
      100        
284             ($lineComment == 0) &&
285             ($subpiece =~ /(\"|\')/));
286 554 100 100     4317 if (($quoted == 0) && ($subpiece =~ /\/\*/)) {
    100 100        
    100 100        
287 2         7 $blockComment = 1;
288             } elsif (($quoted == 0) && ($subpiece =~ /\/\//)) {
289 7         25 $lineComment = 1;
290             } elsif (($blockComment == 1) && ($subpiece =~ /\*\//)) {
291 2         8 $blockComment = 0;
292             } else {
293 543 100 100     2702 $newFunction .= $subpiece
294             unless (($blockComment == 1) || ($lineComment == 1));
295             }
296             }
297             }
298              
299 3         138 $newFunction =~ s/^\s*function\s*(\S+)\s*\(\s*([^\,]+)\s*\,\s*([^\)]+)\s*\)\s*\{/sub $1 \{\n my \(\$self, $2 ,$3\) = \@_\;\n my(\$stub);\n/;
300 3         13 $vars{$2} = 2;
301 3         9 $vars{$3} = 2;
302              
303 3         5 $quoted = 0;
304 3         8 my $finalFunction = "";
305              
306 3         127 foreach my $piece (split(/(\s)/,$newFunction)) {
307 396 100       679 if ($piece eq "my(\$stub);") {
308 3         6 $piece = "my(\$stub";
309 3         11 foreach my $var (keys(%vars)) {
310 6 50       19 next if ($vars{$var} == 2);
311 0         0 $piece .= ",\$".$var;
312             }
313 3         8 $piece .= ");";
314             }
315 396         967 foreach my $subpiece (split(/([\"\'\=\,\+\x29\x28])/,$piece)) {
316 512 100       918 next if ($subpiece eq "");
317 445 100 33     3006 $quoted ^= 1 if (($blockComment == 0) &&
      66        
318             ($lineComment == 0) &&
319             ($subpiece =~ /(\"|\')/));
320 445 100 100     1560 $subpiece = "\$".$subpiece
321             if (($quoted == 0) && exists($vars{$subpiece}));
322 445         897 $finalFunction .= $subpiece;
323             }
324             }
325             ######### added to ProxyAutoConfig 0.2 by cmac, March 2010
326             # the preceding code has taken comments out, which makes life simpler
327              
328             # since most comparisons will be strings, change JS relational operators
329             # to perl's string operators
330 3         62 my %opers = ('===' => 'eq', '==' => 'eq', '!=' => 'ne', '>=' => 'ge',
331             '<=' => 'le', '>' => 'gt', '<' => 'lt');
332              
333 3         32 my $search = '(\'|")|(' . join('|', sort {length($b) <=> length($a)} keys(%opers)) . ')';
  41         58  
334 3         161 while ($finalFunction =~ /$search/mg) {
335 27 100       61 if ($1) {
336 25 50       184 $finalFunction =~ /(\A|[^\\])$1/mg or last;
337             } else {
338 2         13 my $pos = pos($finalFunction) - length($2);
339 2         9 substr ($finalFunction, $pos, length($2), " $opers{$2} ");
340 2         7 pos($finalFunction) = $pos + 4;
341             }
342 27         167 my $zzz=0;
343             }
344             # collapse 'else if' into 'elsif'
345 3         11 $finalFunction =~ s/\belse\s+if\b/elsif/mg;
346              
347             # javascript allows if/for/while/else/do without {} around a subsequent
348             # single statement, but perl doesn't so put {} around such statements
349              
350 3         61 while ($finalFunction =~ /('|"|\b(if|for|while|elsif|(else|do))\b)\s*/mg) {
351 34         96 my $posLP = pos($finalFunction);
352 34 100 66     202 if ($1 eq "'" || $1 eq '"') {
    50 33        
353 25 50       335 $finalFunction =~ /(\A|[^\\])$1/mg or last;
354             } elsif ($3
355             || slide_lp_thru_rp($finalFunction)) {
356 9         12 my $posRP = pos($finalFunction);
357 9 100       39 if ($finalFunction =~ s/\G([^\x7B])/\x7B$1/) {
358 3         9 place_ending_rb($finalFunction, $posRP+1);
359             }
360 9         84 pos($finalFunction) = $posLP;
361             } }
362 3         36 return $finalFunction;
363             }
364             # slide through (expression) after if/for/while/elsif
365             sub slide_lp_thru_rp {
366 9     9 0 15 my $parenCt = 0;
367 9         51 while ($_[0] =~ /(\x28|\x29|'|")/mg) {
368 47 100 100     254 if ($1 eq '(') {
    100 66        
    100          
369 17         69 $parenCt++;
370             } elsif ($1 eq ')' && --$parenCt <= 0) {
371 9         22 $_[0] =~ /\s+/mg; # slide to what's after the )
372 9         47 return 1;
373             } elsif ($1 eq '"' || $1 eq "'") {
374 13 50       161 $_[0] =~ /(\A|[^\\])$1/mg or last;
375             } } }
376             # add } at end of single statement after if/for/while/else/do
377             sub place_ending_rb {
378 3     3 0 7 pos($_[0]) = $_[1];
379             # scan to ; or end of line
380 3         19 while ($_[0] =~ /(;|$|'|")/mg) {
381 6 100       16 if ($1 eq ';') {pos($_[0])--}
  3         7  
382 6 100 66     37 if (!$1 || $1 eq ';') {
    50 33        
383             # put in the }
384 3         12 $_[0] =~ s/\G;?/\x7D/;
385 3         5 return;
386             } elsif ($1 eq '"' || $1 eq "'") {
387 3 50       65 $_[0] =~ /(\A|[^\\])$1/mg or last;
388             } } }
389              
390             sub validIP {
391 24   33 24 0 452 return $_[0] =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/
392             && $1 <= 255 && $2 <= 255 && $3 <= 255 && $4 <= 255;
393             }
394              
395             ##############################################################################
396             #
397             # isPlainHostName - PAC command that tells if this is a plain host name
398             # (no dots)
399             #
400             ##############################################################################
401             sub isPlainHostName {
402 0     0 0 0 my ($host) = @_;
403              
404 0         0 return $host !~ /\./;
405             }
406              
407             ##############################################################################
408             #
409             # dnsDomainIs - PAC command to tell if the host is in the domain.
410             #
411             ##############################################################################
412             sub dnsDomainIs {
413 3     3 0 7 my ($host, $domain) = @_;
414              
415 3         9 my $lh = length($host);
416 3         5 my $ld = length($domain);
417 3   66     316 return $lh >= $ld
418             && substr($host, $lh - $ld) eq $domain;
419             }
420              
421             ##############################################################################
422             #
423             # localHostOrDomainIs - PAC command to tell if the host matches, or if it is
424             # unqualified and in the domain.
425             #
426             ##############################################################################
427             sub localHostOrDomainIs {
428 0     0 0 0 my ($host, $hostdom) = @_;
429              
430 0   0     0 return $host eq $hostdom
431             || rindex($hostdom, "$host.") == 0;
432             }
433              
434             ##############################################################################
435             #
436             # isResolvable - PAC command to see if the host can be resolved via DNS.
437             #
438             ##############################################################################
439             sub isResolvable {
440 0     0 0 0 return defined(gethostbyname($_[0]));
441             }
442              
443             ##############################################################################
444             #
445             # isInNet - PAC command to see if the IP address is in this network based on
446             # the mask and pattern.
447             #
448             ##############################################################################
449             sub isInNet {
450 8     8 0 22 my ($ipaddr, $pattern, $maskstr) = @_;
451              
452 8 100       26 if (!validIP($ipaddr)) {
453 3         13 $ipaddr = dnsResolve($ipaddr);
454 3 50       13 if (!$ipaddr) {return ''}
  0         0  
455             }
456 8 50 33     26 if (!validIP($pattern) || !validIP($maskstr)) {return ''}
  0         0  
457              
458 8         57 my $host = inet_aton($ipaddr);
459 8         27 my $pat = inet_aton($pattern);
460 8         43 my $mask = inet_aton($maskstr);
461 8         319 return ($host & $mask) eq ($pat & $mask);
462             }
463              
464             ##############################################################################
465             #
466             # dnsResolve - PAC command to get the IP from the host name.
467             #
468             ##############################################################################
469             sub dnsResolve {
470 3     3 0 8448 my $ipad = inet_aton($_[0]);
471 3 50       22 if ($ipad) {return inet_ntoa($ipad)}
  3         32  
472 0         0 return;
473             }
474              
475             ##############################################################################
476             #
477             # myIpAddress - PAC command to get your IP.
478             #
479             ##############################################################################
480             my $myIpAddress;
481             BEGIN {
482 2     2   14 my $hostname = hostname();
483 2         1501 my $ipad = inet_aton($hostname);
484 2 50       3759 $myIpAddress = $ipad ? inet_ntoa($ipad) : '127.0.0.1';
485             }
486             sub myIpAddress {
487 0     0 0 0 return $myIpAddress;
488             }
489              
490             ##############################################################################
491             #
492             # dnsDomainLevels - PAC command to tell how many domain levels there are in
493             # the host name (number of dots).
494             #
495             ##############################################################################
496             sub dnsDomainLevels {
497 0     0 0 0 my @parts = split /\./, $_[0];
498 0         0 return @parts-1;
499             }
500              
501             ##############################################################################
502             #
503             # shExpMatch - PAC command to see if a URL/path matches the shell expression.
504             # Shell expressions are like */foo/* or http://*.
505             #
506             ##############################################################################
507             sub shExpMatch {
508 14     14 0 25 my ($str, $shellExp) = @_;
509              
510             # this escapes the perl regexp characters that need it except ? and *
511             # it also escapes /
512 14         121 $shellExp =~ s#([\\|\x28\x29\x5B\x7B^\$+./])#\\$1#g;
513              
514             # there are two wildcards in "shell expressions": * and ?
515 14         32 $shellExp =~ s/\?/./g;
516 14         54 $shellExp =~ s/\*/.*?/g;
517              
518 14         731 return $str =~ /^$shellExp$/;
519             }
520              
521             ##############################################################################
522             #
523             # weekDayRange - PAC command to see if the current weekday falls within a
524             # range.
525             #
526             ##############################################################################
527             sub weekDayRange {
528 0     0 0   my $wd1 = shift;
529 0           my $wd2 = "";
530 0 0         $wd2 = shift if ($_[0] ne "GMT");
531 0           my $gmt = "";
532 0 0         $gmt = shift if ($_[0] eq "GMT");
533              
534 0           my %wd = ( SUN=>0, MON=>1, TUE=>2, WED=>3, THU=>4, FRI=>5, SAT=>6);
535 0 0         my $dow = (($gmt eq "GMT") ? (gmtime)[6] : (localtime)[6]);
536              
537 0 0         if ($wd2 eq "") {
538 0           return $dow eq $wd{$wd1};
539             } else {
540 0           my @range;
541 0 0         if ($wd{$wd1} < $wd{$wd2}) {
542 0           @range = ($wd{$wd1}..$wd{$wd2});
543             } else {
544 0           @range = ($wd{$wd1}..6,0..$wd{$wd2});
545             }
546 0           foreach my $tdow (@range) {
547 0           return $dow eq $tdow;
548             } }
549 0           return '';
550             }
551              
552             ##############################################################################
553             #
554             # dateRange - PAC command to see if the current date falls within a range.
555             #
556             ##############################################################################
557             sub dateRange {
558 0     0 0   my %mon = ( JAN=>0,FEB=>1,MAR=>2,APR=>3,MAY=>4,JUN=>5,JUL=>6,AUG=>7,SEP=>8,OCT=>9,NOV=>10,DEC=>11);
559              
560 0           my %args;
561 0           my $dayCount = 1;
562 0           my $monCount = 1;
563 0           my $yearCount = 1;
564              
565 0           while ($#_ > -1) {
566 0 0         if ($_[0] eq "GMT") {
    0          
    0          
567 0           $args{gmt} = shift;
568             } elsif (exists($mon{$_[0]})) {
569 0           my $month = shift;
570 0           $args{"mon$monCount"} = $mon{$month};
571 0           $monCount++;
572             } elsif ($_[0] > 31) {
573 0           $args{"year$yearCount"} = shift;
574 0           $yearCount++;
575             } else {
576 0           $args{"day$dayCount"} = shift;
577 0           $dayCount++;
578             }
579             }
580              
581 0 0         my $mday = (exists($args{gmt}) ? (gmtime)[3] : (localtime)[3]);
582 0 0         my $mon = (exists($args{gmt}) ? (gmtime)[4] : (localtime)[4]);
583 0 0         my $year = 1900+(exists($args{gmt}) ? (gmtime)[5] : (localtime)[5]);
584              
585 0 0 0       if (exists($args{day1}) && exists($args{mon1}) && exists($args{year1}) &&
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
      0        
      0        
      0        
      0        
      0        
586             exists($args{day2}) && exists($args{mon2}) && exists($args{year2})) {
587              
588 0 0 0       if (($args{year1} < $year) && ($args{year2} > $year)) {
    0 0        
    0 0        
589 0           return 1;
590             } elsif (($args{year1} == $year) && ($args{mon1} <= $mon)) {
591 0           return 1;
592             } elsif (($args{year2} == $year) && ($args{mon2} >= $mon)) {
593 0           return 1;
594             }
595 0           return 0;
596              
597             } elsif (exists($args{mon1}) && exists($args{year1}) &&
598             exists($args{mon2}) && exists($args{year2})) {
599 0 0 0       if (($args{year1} < $year) && ($args{year2} > $year)) {
    0 0        
    0 0        
    0 0        
    0 0        
      0        
      0        
600 0           return 1;
601             } elsif (($args{year1} == $year) && ($args{mon1} < $mon)) {
602 0           return 1;
603             } elsif (($args{year2} == $year) && ($args{mon2} > $mon)) {
604 0           return 1;
605             } elsif (($args{year1} == $year) && ($args{mon1} == $mon) &&
606             ($args{day1} <= $mday)) {
607 0           return 1;
608             } elsif (($args{year2} == $year) && ($args{mon2} == $mon) &&
609             ($args{day2} >= $mday)) {
610 0           return 1;
611             }
612 0           return 0;
613             } elsif (exists($args{day1}) && exists($args{mon1}) &&
614             exists($args{day2}) && exists($args{mon2})) {
615 0 0 0       if (($args{mon1} < $mon) && ($args{mon2} > $mon)) {
    0 0        
    0 0        
616 0           return 1;
617             } elsif (($args{mon1} == $mon) && ($args{day1} <= $mday)) {
618 0           return 1;
619             } elsif (($args{mon2} == $mon) && ($args{day2} >= $mday)) {
620 0           return 1;
621             }
622 0           return 0;
623             } elsif (exists($args{year1}) && exists($args{year2})) {
624 0           foreach my $tyear ($args{year1}..$args{year2}) {
625 0 0         return 1 if ($tyear == $year);
626             }
627 0           return 0;
628             } elsif (exists($args{mon1}) && exists($args{mon2})) {
629 0           foreach my $tmon ($args{mon1}..$args{mon2}) {
630 0 0         return 1 if ($tmon == $mon);
631             }
632 0           return 0;
633             } elsif (exists($args{day1}) && exists($args{day2})) {
634 0           foreach my $tmday ($args{day1}..$args{day2}) {
635 0 0         return 1 if ($tmday == $mday);
636             }
637 0           return 0;
638             } elsif (exists($args{year1})) {
639 0 0         return (($args{year1} == $year) ? 1 : 0);
640             } elsif (exists($args{mon1})) {
641 0 0         return (($args{mon1} == $mon) ? 1 : 0);
642             } elsif (exists($args{day1})) {
643 0 0         return (($args{day1} == $mday) ? 1 : 0);
644             }
645 0           return 0;
646             }
647              
648             ##############################################################################
649             #
650             # timeRange - PAC command to see if the current time falls within a range.
651             #
652             ##############################################################################
653             sub timeRange {
654 0     0 0   my %args;
655 0           my $dayCount = 1;
656 0           my $monCount = 1;
657 0           my $yearCount = 1;
658              
659 0 0         $args{gmt} = pop(@_) if ($_[$#_] eq "GMT");
660              
661 0 0         if ($#_ == 0) {
    0          
    0          
    0          
662 0           $args{hour1} = shift;
663             } elsif ($#_ == 1) {
664 0           $args{hour1} = shift;
665 0           $args{hour2} = shift;
666             } elsif ($#_ == 3) {
667 0           $args{hour1} = shift;
668 0           $args{min1} = shift;
669 0           $args{hour2} = shift;
670 0           $args{min2} = shift;
671             } elsif ($#_ == 5) {
672 0           $args{hour1} = shift;
673 0           $args{min1} = shift;
674 0           $args{sec1} = shift;
675 0           $args{hour2} = shift;
676 0           $args{min2} = shift;
677 0           $args{sec2} = shift;
678             }
679              
680 0 0         my $sec = (exists($args{gmt}) ? (gmtime)[0] : (localtime)[0]);
681 0 0         my $min = (exists($args{gmt}) ? (gmtime)[1] : (localtime)[1]);
682 0 0         my $hour = (exists($args{gmt}) ? (gmtime)[2] : (localtime)[2]);
683              
684 0 0 0       if (exists($args{sec1}) && exists($args{min1}) && exists($args{hour1}) &&
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
      0        
      0        
      0        
      0        
      0        
685             exists($args{sec2}) && exists($args{min2}) && exists($args{hour2})) {
686              
687 0 0 0       if (($args{hour1} < $hour) && ($args{hour2} > $hour)) {
    0 0        
    0 0        
688 0           return 1;
689             } elsif (($args{hour1} == $hour) && ($args{min1} <= $min)) {
690 0           return 1;
691             } elsif (($args{hour2} == $hour) && ($args{min2} >= $min)) {
692 0           return 1;
693             }
694 0           return 0;
695              
696             } elsif (exists($args{min1}) && exists($args{hour1}) &&
697             exists($args{min2}) && exists($args{hour2})) {
698 0 0 0       if (($args{hour1} < $hour) && ($args{hour2} > $hour)) {
    0 0        
    0 0        
    0 0        
    0 0        
      0        
      0        
699 0           return 1;
700             } elsif (($args{hour1} == $hour) && ($args{min1} < $min)) {
701 0           return 1;
702             } elsif (($args{hour2} == $hour) && ($args{min2} > $min)) {
703 0           return 1;
704             } elsif (($args{hour1} == $hour) && ($args{min1} == $min) &&
705             ($args{sec1} <= $sec)) {
706 0           return 1;
707             } elsif (($args{hour2} == $hour) && ($args{min2} == $min) &&
708             ($args{sec2} >= $sec)) {
709 0           return 1;
710             }
711 0           return 0;
712             } elsif (exists($args{sec1}) && exists($args{min1}) &&
713             exists($args{sec2}) && exists($args{min2})) {
714 0 0 0       if (($args{min1} < $min) && ($args{min2} > $min)) {
    0 0        
    0 0        
715 0           return 1;
716             } elsif (($args{min1} == $min) && ($args{sec1} <= $sec)) {
717 0           return 1;
718             } elsif (($args{min2} == $min) && ($args{sec2} >= $sec)) {
719 0           return 1;
720             }
721 0           return 0;
722             } elsif (exists($args{hour1}) && exists($args{hour2})) {
723 0           foreach my $thour ($args{hour1}..$args{hour2}) {
724 0 0         return 1 if ($thour == $hour);
725             }
726 0           return 0;
727             } elsif (exists($args{min1}) && exists($args{min2})) {
728 0           foreach my $tmin ($args{min1}..$args{min2}) {
729 0 0         return 1 if ($tmin == $min);
730             }
731 0           return 0;
732             } elsif (exists($args{sec1}) && exists($args{sec2})) {
733 0           foreach my $tsec ($args{sec1}..$args{sec2}) {
734 0 0         return 1 if ($tsec == $sec);
735             }
736 0           return 0;
737             } elsif (exists($args{hour1})) {
738 0 0         return (($args{hour1} == $hour) ? 1 : 0);
739             } elsif (exists($args{min1})) {
740 0 0         return (($args{min1} == $min) ? 1 : 0);
741             } elsif (exists($args{sec1})) {
742 0 0         return (($args{sec1} == $sec) ? 1 : 0);
743             }
744 0           return 0;
745             }
746             1;