File Coverage

blib/lib/Fax/Hylafax/Client.pm
Criterion Covered Total %
statement 39 304 12.8
branch 2 158 1.2
condition 21 244 8.6
subroutine 6 22 27.2
pod 5 5 100.0
total 73 733 9.9


line stmt bran cond sub pod time code
1             ######################################################################
2             # Description: Hylafax client that connects directly to the server #
3             # via Hylafax's proprietory FTP protocol #
4             # Author: Alex Rak (arak@cpan.org) #
5             # Copyright: See COPYRIGHT section in POD text below for usage and #
6             # distribution rights #
7             ######################################################################
8              
9             package Fax::Hylafax::Client;
10              
11 1     1   18649 use 5.006;
  1         4  
  1         41  
12 1     1   6 use strict;
  1         1  
  1         35  
13 1     1   7 use warnings;
  1         7  
  1         41  
14              
15 1     1   5 use Carp;
  1         1  
  1         103  
16 1     1   1180 use Net::FTP;
  1         127989  
  1         11556  
17             require Exporter;
18              
19             our @ISA = qw(Exporter);
20             our @EXPORT_OK = qw(faxinfo faxrm faxstat sendfax sendpage);
21              
22             our $VERSION = "1.02";
23              
24             our $Host;
25             our $Port;
26             our $User;
27             our $Password;
28             our $Passive;
29             our $Debug;
30             our $NotifyAddr;
31              
32              
33             sub faxinfo
34             {
35 0 0   0 1 0 shift if $_[0] eq __PACKAGE__;
36 0 0       0 my %param = scalar @_ == 1 ? ('jobid', shift) : @_;
37 0         0 my $self = {
38             TRACE => '',
39             SUCCESS => '',
40             CONTENT => '',
41             };
42              
43             ## Set defaults
44 0   0     0 $param{host} ||= $Host || 'localhost';
      0        
45 0   0     0 $param{port} ||= $Port || '4559';
      0        
46 0   0     0 $param{user} ||= $User || 'anonymous';
      0        
47 0   0     0 $param{password} ||= $Password || 'anonymous';
      0        
48 0   0     0 $param{passive} ||= $Passive || '0';
      0        
49              
50             ## Basic error checking
51 0 0       0 croak __PACKAGE__ . ": *jobid* parameter is missing" unless $param{jobid};
52              
53             ## Try to connect
54 0   0     0 my $client = Net::FTP->new($param{host}, Port => $param{port}, Passive => $param{passive}) || croak __PACKAGE__ . ": " . $@;
55 0 0       0 $client->login($param{user}, $param{password}) || _com_error($client);
56 0         0 $self->{TRACE} .= $client->message;
57              
58             ## Process the task
59 0 0       0 $client->quot("job", $param{jobid}) || _com_error($client);
60 0         0 $self->{TRACE} .= $client->message;
61              
62 0 0       0 $client->quot("jparm state") || _com_error($client);
63 0         0 $self->{TRACE} .= $client->message;
64 0         0 $self->{CONTENT} = $client->message;
65              
66             ## Disconnect
67 0         0 $client->quit;
68 0         0 $self->{TRACE} .= $client->message;
69              
70 0         0 return bless $self, __PACKAGE__ . "::Instant";
71             }
72              
73              
74             sub faxrm
75             {
76 0 0   0 1 0 shift if $_[0] eq __PACKAGE__;
77 0 0       0 my %param = scalar @_ == 1 ? ('jobid', shift) : @_;
78 0         0 my $self = {
79             TRACE => '',
80             SUCCESS => '',
81             };
82              
83             ## Set defaults
84 0   0     0 $param{host} ||= $Host || 'localhost';
      0        
85 0   0     0 $param{port} ||= $Port || '4559';
      0        
86 0   0     0 $param{user} ||= $User || 'anonymous';
      0        
87 0   0     0 $param{password} ||= $Password || 'anonymous';
      0        
88 0   0     0 $param{passive} ||= $Passive || '0';
      0        
89              
90             ## Basic error checking
91 0 0       0 croak __PACKAGE__ . ": *jobid* parameter is missing" unless $param{jobid};
92              
93             ## Try to connect
94 0   0     0 my $client = Net::FTP->new($param{host}, Port => $param{port}, Passive => $param{passive}) || croak __PACKAGE__ . ": " . $@;
95 0 0       0 $client->login($param{user}, $param{password}) || _com_error($client);
96 0         0 $self->{TRACE} .= $client->message;
97              
98             ## Process the task
99 0 0       0 $client->quot("jkill", $param{jobid}) || _com_error($client);
100 0         0 $self->{TRACE} .= $client->message;
101 0 0 0     0 $self->{SUCCESS} = $client->message =~ /failed/i || $client->message =~ /cannot/i ? 0 : 1;
102              
103             ## Disconnect
104 0         0 $client->quit;
105 0         0 $self->{TRACE} .= $client->message;
106              
107 0         0 return bless $self, __PACKAGE__ . "::Instant";
108             }
109              
110              
111             sub faxstat
112             {
113 0 0   0 1 0 shift if $_[0] eq __PACKAGE__;
114 0         0 my %param = @_;
115 0         0 my $self = {
116             TRACE => '',
117             SUCCESS => '',
118             CONTENT => '',
119             };
120              
121             ## Set defaults
122 0   0     0 $param{host} ||= $Host || 'localhost';
      0        
123 0   0     0 $param{port} ||= $Port || '4559';
      0        
124 0   0     0 $param{user} ||= $User || 'anonymous';
      0        
125 0   0     0 $param{password} ||= $Password || 'anonymous';
      0        
126 0   0     0 $param{passive} ||= $Passive || '0';
      0        
127 0   0     0 $param{filefmt} ||= '';
128 0   0     0 $param{jobfmt} ||= '%-4j %3i %1a %6.6o %-12.12e %5P %5D %7z %.25s';
129 0   0     0 $param{rcvfmt} ||= '%-7m %4p%1z %-8.8o %14.14s %7t %f';
130 0   0     0 $param{info} ||= '0'; # -i flag
131 0   0     0 $param{files} ||= '0'; # -f flag
132 0   0     0 $param{queue} ||= '0'; # -s flag
133 0   0     0 $param{done} ||= '0'; # -d flag
134 0   0     0 $param{received} ||= '0'; # -r flag
135              
136             ## Try to connect
137 0   0     0 my $client = Net::FTP->new($param{host}, Port => $param{port}, Passive => $param{passive}) || croak __PACKAGE__ . ": " . $@;
138 0 0       0 $client->login($param{user}, $param{password}) || _com_error($client);
139 0         0 $self->{TRACE} .= $client->message;
140              
141             ## Process the task
142 0 0       0 if ($param{info})
143             {
144 0   0     0 my $dataconn = $client->retr("status/any.info") || _com_error($client);
145 0         0 while ($dataconn->read(my $buffer, 1024))
146             {
147 0         0 $self->{CONTENT} .= $buffer;
148             }
149 0         0 $dataconn->close;
150 0         0 $self->{TRACE} .= $client->message;
151             }
152              
153 0   0     0 my $dataconn = $client->list("status") || _com_error($client);
154 0         0 while ($dataconn->read(my $buffer, 1024))
155             {
156 0         0 $self->{CONTENT} .= $buffer;
157             }
158 0         0 $dataconn->close;
159 0         0 $self->{TRACE} .= $client->message;
160              
161 0 0       0 if ($param{files})
162             {
163 0 0       0 $client->quot("filefmt", $param{filefmt}) || _com_error($client);
164 0   0     0 my $dataconn = $client->list("docq") || _com_error($client);
165 0         0 my $content;
166 0         0 while ($dataconn->read(my $buffer, 1024))
167             {
168 0         0 $content .= $buffer;
169             }
170 0         0 $dataconn->close;
171 0 0       0 $self->{CONTENT} .= "\n$content" if $content;
172 0         0 $self->{TRACE} .= $client->message;
173             }
174              
175 0 0       0 if ($param{queue})
176             {
177 0 0       0 $client->quot("jobfmt", $param{jobfmt}) || _com_error($client);
178 0   0     0 my $dataconn = $client->list("sendq") || _com_error($client);
179 0         0 my $content;
180 0         0 while ($dataconn->read(my $buffer, 1024))
181             {
182 0         0 $content .= $buffer;
183             }
184 0         0 $dataconn->close;
185 0 0       0 $self->{CONTENT} .= "\n$content" if $content;
186 0         0 $self->{TRACE} .= $client->message;
187             }
188              
189 0 0       0 if ($param{done})
190             {
191 0 0       0 $client->quot("jobfmt", $param{jobfmt}) || _com_error($client);
192 0   0     0 my $dataconn = $client->list("doneq") || _com_error($client);
193 0         0 my $content;
194 0         0 while ($dataconn->read(my $buffer, 1024))
195             {
196 0         0 $content .= $buffer;
197             }
198 0         0 $dataconn->close;
199 0 0       0 $self->{CONTENT} .= "\n$content" if $content;
200 0         0 $self->{TRACE} .= $client->message;
201             }
202              
203 0 0       0 if ($param{received})
204             {
205 0 0       0 $client->quot("rcvfmt", $param{rcvfmt}) || _com_error($client);
206 0   0     0 my $dataconn = $client->list("recvq") || _com_error($client);
207 0         0 my $content;
208 0         0 while ($dataconn->read(my $buffer, 1024))
209             {
210 0         0 $content .= $buffer;
211             }
212 0         0 $dataconn->close;
213 0 0       0 $self->{CONTENT} .= "\n$content" if $content;
214 0         0 $self->{TRACE} .= $client->message;
215             }
216              
217             ## Disconnect
218 0         0 $client->quit;
219 0         0 $self->{TRACE} .= $client->message;
220              
221 0         0 return bless $self, __PACKAGE__ . "::Instant";
222             }
223              
224              
225             sub sendfax
226             {
227 1 50   1 1 6145 shift if $_[0] eq __PACKAGE__;
228 1         62 my %param = @_;
229 1         5939 my $hostname = `hostname`; chomp $hostname;
  1         21  
230 1         63 my $self = {
231             JOB_ID => '',
232             TRACE => '',
233             SUCCESS => '',
234             };
235              
236             ## Set defaults
237 1   0     217 $param{host} ||= $Host || 'localhost';
      33        
238 1   50     60 $param{port} ||= $Port || '4559';
      33        
239 1   0     12 $param{user} ||= $User || 'anonymous';
      33        
240 1   0     17 $param{password} ||= $Password || 'anonymous';
      33        
241 1   50     104 $param{passive} ||= $Passive || '0';
      33        
242 1   50     49 $param{debug} ||= $Debug || '0';
      33        
243 1   50     20 $param{lasttime} ||= '000259';
244 1   50     22 $param{maxdials} ||= '12';
245 1   50     14 $param{maxtries} ||= '3';
246 1   50     27 $param{pagewidth} ||= '216';
247 1   50     13 $param{pagelength} ||= '279';
248 1   50     25 $param{vres} ||= '196';
249 1   50     21 $param{schedpri} ||= '127';
250 1   50     17 $param{chopthreshold} ||= '3';
251 1   50     9 $param{notify} ||= 'none';
252 1   33     23 $param{notifyaddr} ||= $NotifyAddr || $param{'user'} . '@' . $hostname;
      33        
253 1   50     17 $param{sendtime} ||= 'now';
254              
255 1         9 $self->{PARAM} = \%param;
256              
257             ## Basic error checking
258 1 50       1065 croak __PACKAGE__ . ": *dialstring* parameter is missing" unless $param{dialstring};
259 0 0 0       croak __PACKAGE__ . ": *docfile* parameter is missing" if (! $param{docfile} && ! $param{poll});
260 0 0 0       croak __PACKAGE__ . ": $param{coverfile} does not exist" if ($param{coverfile} && ! -e $param{coverfile});
261              
262 0 0         if (ref(\$param{docfile}) eq 'SCALAR')
    0          
263             {
264 0           $param{docfiles} = [ $param{docfile} ];
265             }
266             elsif (ref($param{docfile}) eq 'ARRAY')
267             {
268 0           $param{docfiles} = $param{docfile};
269             }
270             else
271             {
272 0           croak __PACKAGE__ . ": *docfile* parameter must be a SCALAR or an ARRAY REFERENCE";
273             }
274              
275 0           foreach my $docfile (@{$param{docfiles}})
  0            
276             {
277 0 0         croak __PACKAGE__ . ": $docfile does not exist" if (! -e $docfile);
278             }
279              
280 0           delete $param{docfile};
281              
282             ## Try to connect
283 0   0       my $client = Net::FTP->new($param{'host'}, Port => $param{'port'}, Passive => $param{'passive'}, Debug => $param{'debug'}) || croak __PACKAGE__ . ": " . $@;
284 0 0         $client->login($param{'user'}, $param{'password'}) || _com_error($client);
285 0           $self->{TRACE} .= $client->message;
286 0 0         $client->binary || _com_error($client);
287 0           $self->{TRACE} .= $client->message;
288              
289             ## Process the job
290 0           my @tempfiles = ();
291              
292 0 0         if ($param{coverfile})
293             {
294 0           my $unique = time . sprintf('%05d', $$) . sprintf('%04d', int(rand 10000));
295 0           my $remote = '/tmp/cover.' . $hostname . '.' . $unique;
296              
297 0 0         $client->put($param{coverfile}, $remote) || _com_error($client); # (STOT would be nice, but Net::FTP doesn`t support it and STOU is broken)
298 0           $self->{TRACE} .= $client->message;
299              
300 0           push (@tempfiles, $remote);
301             }
302              
303 0           foreach my $docfile (@{$param{docfiles}})
  0            
304             {
305 0           my $unique = time . sprintf('%05d', $$) . sprintf('%04d', int(rand 10000));
306 0           my $remote = '/tmp/doc.' . $hostname . '.' . $unique;
307              
308 0 0         $client->put($docfile, $remote) || _com_error($client);
309 0           $self->{TRACE} .= $client->message;
310              
311 0           push (@tempfiles, $remote);
312             }
313              
314 0 0         $client->quot("jnew") || _com_error($client);
315 0           $self->{TRACE} .= $client->message;
316 0           $client->message =~ /jobid: (\d+)/i;
317 0 0         $self->{JOB_ID} = $1 if $1;
318 0           $self->{PARAM}->{jobid} = $self->{JOB_ID};
319              
320 0 0         $client->quot("jparm fromuser", $param{'user'}) || _com_error($client);
321 0           $self->{TRACE} .= $client->message;
322              
323 0 0         $client->quot("jparm lasttime", $param{lasttime}) || _com_error($client);
324 0           $self->{TRACE} .= $client->message;
325              
326 0 0         $client->quot("jparm maxdials", $param{maxdials}) || _com_error($client);
327 0           $self->{TRACE} .= $client->message;
328              
329 0 0         $client->quot("jparm maxtries", $param{maxtries}) || _com_error($client);
330 0           $self->{TRACE} .= $client->message;
331              
332 0 0         $client->quot("jparm schedpri", $param{schedpri}) || _com_error($client);
333 0           $self->{TRACE} .= $client->message;
334              
335 0 0         $client->quot("jparm dialstring", $param{dialstring}) || _com_error($client);
336 0           $self->{TRACE} .= $client->message;
337              
338 0 0         $client->quot("jparm sendtime", $param{sendtime}) || _com_error($client);
339 0           $self->{TRACE} .= $client->message;
340              
341 0 0         $client->quot("jparm notifyaddr", $param{notifyaddr}) || _com_error($client);
342 0           $self->{TRACE} .= $client->message;
343              
344 0 0         $client->quot("jparm vres", $param{vres}) || _com_error($client);
345 0           $self->{TRACE} .= $client->message;
346              
347 0 0         $client->quot("jparm pagewidth", $param{pagewidth}) || _com_error($client);
348 0           $self->{TRACE} .= $client->message;
349              
350 0 0         $client->quot("jparm pagelength", $param{pagelength}) || _com_error($client);
351 0           $self->{TRACE} .= $client->message;
352              
353 0 0         $client->quot("jparm notify", $param{notify}) || _com_error($client);
354 0           $self->{TRACE} .= $client->message;
355              
356 0 0         $client->quot("jparm pagechop", "default") || _com_error($client);
357 0           $self->{TRACE} .= $client->message;
358              
359 0 0         $client->quot("jparm chopthreshold", $param{chopthreshold}) || _com_error($client);
360 0           $self->{TRACE} .= $client->message;
361              
362 0           foreach my $docfile (@tempfiles)
363             {
364 0 0 0       if ($param{coverfile} && $docfile eq $tempfiles[0])
365             {
366 0 0         $client->quot("jparm cover", $docfile) or _com_error($client);
367             }
368             else
369             {
370 0 0         $client->quot("jparm document", $docfile) or _com_error($client);
371             }
372              
373 0           $self->{TRACE} .= $client->message;
374             }
375              
376 0 0         if (defined $param{poll})
377             {
378 0           my ($selector, $passwd) = split(" ", $param{poll});
379 0 0 0       $client->quot("jparm poll", $selector || "", $passwd || "") || _com_error($client);
      0        
380 0           $self->{TRACE} .= $client->message;
381             }
382              
383 0 0         $client->quot("jsubm") || _com_error($client);
384 0           $self->{TRACE} .= $client->message;
385 0 0 0       $self->{SUCCESS} = $client->message =~ /failed/i || $client->message =~ /failed/i? 0 : 1;
386              
387             ## Disconnect
388 0           $client->quit;
389 0           $self->{TRACE} .= $client->message;
390              
391 0           return bless $self, __PACKAGE__ . "::Queued";
392             }
393              
394              
395             sub sendpage
396             {
397 0 0   0 1   shift if $_[0] eq __PACKAGE__;
398 0           my %param = @_;
399 0           my $hostname = `hostname`; chomp $hostname;
  0            
400 0           my $unique = time . $$ . int(rand 10000);
401 0           my $self = {
402             JOB_ID => '',
403             TRACE => '',
404             SUCCESS => '',
405             };
406              
407             ## Set defaults
408 0   0       $param{host} ||= $Host || 'localhost';
      0        
409 0   0       $param{port} ||= $Port || '444';
      0        
410 0   0       $param{user} ||= $User || 'anonymous';
      0        
411 0   0       $param{password} ||= $Password || 'anonymous';
      0        
412 0   0       $param{passive} ||= $Passive || '0';
      0        
413 0   0       $param{maxdials} ||= '12';
414 0   0       $param{maxtries} ||= '3';
415 0   0       $param{notify} ||= 'none';
416 0   0       $param{notifyaddr} ||= $NotifyAddr || $param{'user'} . '@' . $hostname;
      0        
417 0   0       $param{level} ||= '1';
418              
419 0           $self->{PARAM} = \%param;
420              
421             ## Basic error checking
422 0 0         croak __PACKAGE__ . ": *pin* parameter is missing" unless $param{pin};
423              
424             ## Try to connect
425 0   0       my $client = Net::FTP->new($param{'host'}, Port => $param{'port'}, Passive => $param{'passive'}) || croak __PACKAGE__ . ": " . $@;
426 0 0         $client->quot("logi", $param{user}, $param{password}) || _com_error($client);
427 0           $self->{TRACE} .= $client->message;
428              
429             ## Process the job
430 0 0         $client->quot("site help", "notify") || _com_error($client);
431 0           $self->{TRACE} .= $client->message;
432              
433 0 0         $client->quot("leve", $param{level}) || _com_error($client);
434 0           $self->{TRACE} .= $client->message;
435              
436 0 0         $client->quot("site fromuser", $param{'user'}) || _com_error($client);
437 0           $self->{TRACE} .= $client->message;
438              
439 0 0         $client->quot("site maxdials", $param{maxdials}) || _com_error($client);
440 0           $self->{TRACE} .= $client->message;
441              
442 0 0         $client->quot("site maxtries", $param{maxtries}) || _com_error($client);
443 0           $self->{TRACE} .= $client->message;
444              
445 0 0         $client->quot("site mailaddr", $param{notifyaddr}) || _com_error($client);
446 0           $self->{TRACE} .= $client->message;
447              
448 0 0         $client->quot("site notify", $param{notify}) || _com_error($client);
449 0           $self->{TRACE} .= $client->message;
450              
451 0 0         $client->quot("site jqueue", "yes") || _com_error($client);
452 0           $self->{TRACE} .= $client->message;
453              
454 0 0         $client->quot("page", $param{pin}) || _com_error($client);
455 0           $self->{TRACE} .= $client->message;
456 0           $client->message =~ /jobid: (\d+)\./i;
457 0 0         $self->{JOB_ID} = $1 if $1;
458 0           $self->{PARAM}->{jobid} = $self->{JOB_ID};
459              
460 0 0         if ($param{message})
461             {
462 0 0         $client->quot("mess", $param{message}) || _com_error($client);
463 0           $self->{TRACE} .= $client->message;
464             }
465              
466 0 0         $client->quot("send") || _com_error($client);
467 0           $self->{TRACE} .= $client->message;
468 0 0         $self->{SUCCESS} = $client->message =~ /success/i ? 1 : 0;
469              
470             ## Disconnect
471 0           $client->quit;
472 0           $self->{TRACE} .= $client->message;
473              
474 0           return bless $self, __PACKAGE__ . "::Queued";
475             }
476              
477             ######################################################################
478              
479             sub _com_error
480             {
481 0     0     my $client = shift;
482 0           croak __PACKAGE__ . ": Communication error: " . $client->message;
483             }
484              
485              
486             sub _content
487             {
488 0     0     my $class = shift;
489 0           my $self = shift;
490 0   0       return $self->{CONTENT} || undef;
491             }
492              
493              
494             sub _success
495             {
496 0     0     my $class = shift;
497 0           my $self = shift;
498 0   0       return $self->{SUCCESS} || undef;
499             }
500              
501              
502             sub _trace
503             {
504 0     0     my $class = shift;
505 0           my $self = shift;
506 0   0       return $self->{TRACE} || undef;
507             }
508              
509             ######################################################################
510              
511             package Fax::Hylafax::Client::Queued;
512              
513              
514             sub faxinfo
515             {
516 0     0     my $self = shift;
517 0           my $conn = Fax::Hylafax::Client->faxinfo(%{$self->{PARAM}});
  0            
518 0           $self->{TRACE} = $conn->trace;
519 0           $self->{SUCCESS} = $conn->success;
520 0           return $conn->content;
521             }
522              
523              
524             sub faxrm
525             {
526 0     0     my $self = shift;
527 0           my $conn = Fax::Hylafax::Client->faxrm(%{$self->{PARAM}});
  0            
528 0           $self->{TRACE} = $conn->trace;
529 0           $self->{SUCCESS} = $conn->success;
530 0           return $conn->success;
531             }
532              
533              
534             sub jobid
535             {
536 0     0     my $self = shift;
537 0           return $self->{JOB_ID};
538             }
539              
540              
541             sub success
542             {
543 0     0     return Fax::Hylafax::Client->_success(shift);
544             }
545              
546              
547             sub trace
548             {
549 0     0     return Fax::Hylafax::Client->_trace(shift);
550             }
551              
552             ######################################################################
553              
554             package Fax::Hylafax::Client::Instant;
555              
556              
557             sub content
558             {
559 0     0     return Fax::Hylafax::Client->_content(shift);
560             }
561              
562              
563             sub success
564             {
565 0     0     return Fax::Hylafax::Client->_success(shift);
566             }
567              
568              
569             sub trace
570             {
571 0     0     return Fax::Hylafax::Client->_trace(shift);
572             }
573              
574             ######################################################################
575              
576             1;
577              
578             __END__