This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Upgrade libnet from version 3.07 to 3.08
[perl5.git] / cpan / libnet / lib / Net / Cmd.pm
1 # Net::Cmd.pm
2 #
3 # Versions up to 2.29_1 Copyright (c) 1995-2006 Graham Barr <gbarr@pobox.com>.
4 # All rights reserved.
5 # Changes in Version 2.29_2 onwards Copyright (C) 2013-2015 Steve Hay.  All
6 # rights reserved.
7 # This module is free software; you can redistribute it and/or modify it under
8 # the same terms as Perl itself, i.e. under the terms of either the GNU General
9 # Public License or the Artistic License, as specified in the F<LICENCE> file.
10
11 package Net::Cmd;
12
13 use 5.008001;
14
15 use strict;
16 use warnings;
17
18 use Carp;
19 use Exporter;
20 use Symbol 'gensym';
21 use Errno 'EINTR';
22
23 BEGIN {
24   if ($^O eq 'os390') {
25     require Convert::EBCDIC;
26
27     #    Convert::EBCDIC->import;
28   }
29 }
30
31 our $VERSION = "3.08";
32 our @ISA     = qw(Exporter);
33 our @EXPORT  = qw(CMD_INFO CMD_OK CMD_MORE CMD_REJECT CMD_ERROR CMD_PENDING);
34
35 use constant CMD_INFO    => 1;
36 use constant CMD_OK      => 2;
37 use constant CMD_MORE    => 3;
38 use constant CMD_REJECT  => 4;
39 use constant CMD_ERROR   => 5;
40 use constant CMD_PENDING => 0;
41
42 use constant DEF_REPLY_CODE => 421;
43
44 my %debug = ();
45
46 my $tr = $^O eq 'os390' ? Convert::EBCDIC->new() : undef;
47
48 sub toebcdic {
49   my $cmd = shift;
50
51   unless (exists ${*$cmd}{'net_cmd_asciipeer'}) {
52     my $string    = $_[0];
53     my $ebcdicstr = $tr->toebcdic($string);
54     ${*$cmd}{'net_cmd_asciipeer'} = $string !~ /^\d+/ && $ebcdicstr =~ /^\d+/;
55   }
56
57   ${*$cmd}{'net_cmd_asciipeer'}
58     ? $tr->toebcdic($_[0])
59     : $_[0];
60 }
61
62
63 sub toascii {
64   my $cmd = shift;
65   ${*$cmd}{'net_cmd_asciipeer'}
66     ? $tr->toascii($_[0])
67     : $_[0];
68 }
69
70
71 sub _print_isa {
72   no strict 'refs'; ## no critic (TestingAndDebugging::ProhibitNoStrict)
73
74   my $pkg = shift;
75   my $cmd = $pkg;
76
77   $debug{$pkg} ||= 0;
78
79   my %done = ();
80   my @do   = ($pkg);
81   my %spc  = ($pkg, "");
82
83   while ($pkg = shift @do) {
84     next if defined $done{$pkg};
85
86     $done{$pkg} = 1;
87
88     my $v =
89       defined ${"${pkg}::VERSION"}
90       ? "(" . ${"${pkg}::VERSION"} . ")"
91       : "";
92
93     my $spc = $spc{$pkg};
94     $cmd->debug_print(1, "${spc}${pkg}${v}\n");
95
96     if (@{"${pkg}::ISA"}) {
97       @spc{@{"${pkg}::ISA"}} = ("  " . $spc{$pkg}) x @{"${pkg}::ISA"};
98       unshift(@do, @{"${pkg}::ISA"});
99     }
100   }
101 }
102
103
104 sub debug {
105   @_ == 1 or @_ == 2 or croak 'usage: $obj->debug([LEVEL])';
106
107   my ($cmd, $level) = @_;
108   my $pkg    = ref($cmd) || $cmd;
109   my $oldval = 0;
110
111   if (ref($cmd)) {
112     $oldval = ${*$cmd}{'net_cmd_debug'} || 0;
113   }
114   else {
115     $oldval = $debug{$pkg} || 0;
116   }
117
118   return $oldval
119     unless @_ == 2;
120
121   $level = $debug{$pkg} || 0
122     unless defined $level;
123
124   _print_isa($pkg)
125     if ($level && !exists $debug{$pkg});
126
127   if (ref($cmd)) {
128     ${*$cmd}{'net_cmd_debug'} = $level;
129   }
130   else {
131     $debug{$pkg} = $level;
132   }
133
134   $oldval;
135 }
136
137
138 sub message {
139   @_ == 1 or croak 'usage: $obj->message()';
140
141   my $cmd = shift;
142
143   wantarray
144     ? @{${*$cmd}{'net_cmd_resp'}}
145     : join("", @{${*$cmd}{'net_cmd_resp'}});
146 }
147
148
149 sub debug_text { $_[2] }
150
151
152 sub debug_print {
153   my ($cmd, $out, $text) = @_;
154   print STDERR $cmd, ($out ? '>>> ' : '<<< '), $cmd->debug_text($out, $text);
155 }
156
157
158 sub code {
159   @_ == 1 or croak 'usage: $obj->code()';
160
161   my $cmd = shift;
162
163   ${*$cmd}{'net_cmd_code'} = $cmd->DEF_REPLY_CODE
164     unless exists ${*$cmd}{'net_cmd_code'};
165
166   ${*$cmd}{'net_cmd_code'};
167 }
168
169
170 sub status {
171   @_ == 1 or croak 'usage: $obj->status()';
172
173   my $cmd = shift;
174
175   substr(${*$cmd}{'net_cmd_code'}, 0, 1);
176 }
177
178
179 sub set_status {
180   @_ == 3 or croak 'usage: $obj->set_status(CODE, MESSAGE)';
181
182   my $cmd = shift;
183   my ($code, $resp) = @_;
184
185   $resp = defined $resp ? [$resp] : []
186     unless ref($resp);
187
188   (${*$cmd}{'net_cmd_code'}, ${*$cmd}{'net_cmd_resp'}) = ($code, $resp);
189
190   1;
191 }
192
193 sub _syswrite_with_timeout {
194   my $cmd = shift;
195   my $line = shift;
196
197   my $len    = length($line);
198   my $offset = 0;
199   my $win    = "";
200   vec($win, fileno($cmd), 1) = 1;
201   my $timeout = $cmd->timeout || undef;
202   my $initial = time;
203   my $pending = $timeout;
204
205   local $SIG{PIPE} = 'IGNORE' unless $^O eq 'MacOS';
206
207   while ($len) {
208     my $wout;
209     my $nfound = select(undef, $wout = $win, undef, $pending);
210     if ((defined $nfound and $nfound > 0) or -f $cmd)    # -f for testing on win32
211     {
212       my $w = syswrite($cmd, $line, $len, $offset);
213       if (! defined($w) ) {
214         my $err = $!;
215         $cmd->close;
216         $cmd->_set_status_closed($err);
217         return;
218       }
219       $len -= $w;
220       $offset += $w;
221     }
222     elsif ($nfound == -1) {
223       if ( $! == EINTR ) {
224         if ( defined($timeout) ) {
225           redo if ($pending = $timeout - ( time - $initial ) ) > 0;
226           $cmd->_set_status_timeout;
227           return;
228         }
229         redo;
230       }
231       my $err = $!;
232       $cmd->close;
233       $cmd->_set_status_closed($err);
234       return;
235     }
236     else {
237       $cmd->_set_status_timeout;
238       return;
239     }
240   }
241
242   return 1;
243 }
244
245 sub _set_status_timeout {
246   my $cmd = shift;
247   my $pkg = ref($cmd) || $cmd;
248
249   $cmd->set_status($cmd->DEF_REPLY_CODE, "[$pkg] Timeout");
250   carp(ref($cmd) . ": " . (caller(1))[3] . "(): timeout") if $cmd->debug;
251 }
252
253 sub _set_status_closed {
254   my $cmd = shift;
255   my $err = shift;
256   my $pkg = ref($cmd) || $cmd;
257
258   $cmd->set_status($cmd->DEF_REPLY_CODE, "[$pkg] Connection closed");
259   carp(ref($cmd) . ": " . (caller(1))[3]
260     . "(): unexpected EOF on command channel: $err") if $cmd->debug;
261 }
262
263 sub _is_closed {
264   my $cmd = shift;
265   if (!defined fileno($cmd)) {
266      $cmd->_set_status_closed($!);
267      return 1;
268   }
269   return 0;
270 }
271
272 sub command {
273   my $cmd = shift;
274
275   return $cmd
276     if $cmd->_is_closed;
277
278   $cmd->dataend()
279     if (exists ${*$cmd}{'net_cmd_last_ch'});
280
281   if (scalar(@_)) {
282     my $str = join(
283       " ",
284       map {
285         /\n/
286           ? do { my $n = $_; $n =~ tr/\n/ /; $n }
287           : $_;
288         } @_
289     );
290     $str = $cmd->toascii($str) if $tr;
291     $str .= "\015\012";
292
293     $cmd->debug_print(1, $str)
294       if ($cmd->debug);
295
296     # though documented to return undef on failure, the legacy behavior
297     # was to return $cmd even on failure, so this odd construct does that
298     $cmd->_syswrite_with_timeout($str)
299       or return $cmd;
300   }
301
302   $cmd;
303 }
304
305
306 sub ok {
307   @_ == 1 or croak 'usage: $obj->ok()';
308
309   my $code = $_[0]->code;
310   0 < $code && $code < 400;
311 }
312
313
314 sub unsupported {
315   my $cmd = shift;
316
317   $cmd->set_status(580, 'Unsupported command');
318
319   0;
320 }
321
322
323 sub getline {
324   my $cmd = shift;
325
326   ${*$cmd}{'net_cmd_lines'} ||= [];
327
328   return shift @{${*$cmd}{'net_cmd_lines'}}
329     if scalar(@{${*$cmd}{'net_cmd_lines'}});
330
331   my $partial = defined(${*$cmd}{'net_cmd_partial'}) ? ${*$cmd}{'net_cmd_partial'} : "";
332
333   return
334     if $cmd->_is_closed;
335
336   my $fd = fileno($cmd);
337   my $rin = "";
338   vec($rin, $fd, 1) = 1;
339
340   my $buf;
341
342   until (scalar(@{${*$cmd}{'net_cmd_lines'}})) {
343     my $timeout = $cmd->timeout || undef;
344     my $rout;
345
346     my $select_ret = select($rout = $rin, undef, undef, $timeout);
347     if ($select_ret > 0) {
348       unless (sysread($cmd, $buf = "", 1024)) {
349         my $err = $!;
350         $cmd->close;
351         $cmd->_set_status_closed($err);
352         return;
353       }
354
355       substr($buf, 0, 0) = $partial;    ## prepend from last sysread
356
357       my @buf = split(/\015?\012/, $buf, -1);    ## break into lines
358
359       $partial = pop @buf;
360
361       push(@{${*$cmd}{'net_cmd_lines'}}, map {"$_\n"} @buf);
362
363     }
364     else {
365       $cmd->_set_status_timeout;
366       return;
367     }
368   }
369
370   ${*$cmd}{'net_cmd_partial'} = $partial;
371
372   if ($tr) {
373     foreach my $ln (@{${*$cmd}{'net_cmd_lines'}}) {
374       $ln = $cmd->toebcdic($ln);
375     }
376   }
377
378   shift @{${*$cmd}{'net_cmd_lines'}};
379 }
380
381
382 sub ungetline {
383   my ($cmd, $str) = @_;
384
385   ${*$cmd}{'net_cmd_lines'} ||= [];
386   unshift(@{${*$cmd}{'net_cmd_lines'}}, $str);
387 }
388
389
390 sub parse_response {
391   return ()
392     unless $_[1] =~ s/^(\d\d\d)(.?)//o;
393   ($1, $2 eq "-");
394 }
395
396
397 sub response {
398   my $cmd = shift;
399   my ($code, $more) = (undef) x 2;
400
401   $cmd->set_status($cmd->DEF_REPLY_CODE, undef); # initialize the response
402
403   while (1) {
404     my $str = $cmd->getline();
405
406     return CMD_ERROR
407       unless defined($str);
408
409     $cmd->debug_print(0, $str)
410       if ($cmd->debug);
411
412     ($code, $more) = $cmd->parse_response($str);
413     unless (defined $code) {
414       carp("$cmd: response(): parse error in '$str'") if ($cmd->debug);
415       $cmd->ungetline($str);
416       $@ = $str;   # $@ used as tunneling hack
417       return CMD_ERROR;
418     }
419
420     ${*$cmd}{'net_cmd_code'} = $code;
421
422     push(@{${*$cmd}{'net_cmd_resp'}}, $str);
423
424     last unless ($more);
425   }
426
427   return unless defined $code;
428   substr($code, 0, 1);
429 }
430
431
432 sub read_until_dot {
433   my $cmd = shift;
434   my $fh  = shift;
435   my $arr = [];
436
437   while (1) {
438     my $str = $cmd->getline() or return;
439
440     $cmd->debug_print(0, $str)
441       if ($cmd->debug & 4);
442
443     last if ($str =~ /^\.\r?\n/o);
444
445     $str =~ s/^\.\././o;
446
447     if (defined $fh) {
448       print $fh $str;
449     }
450     else {
451       push(@$arr, $str);
452     }
453   }
454
455   $arr;
456 }
457
458
459 sub datasend {
460   my $cmd  = shift;
461   my $arr  = @_ == 1 && ref($_[0]) ? $_[0] : \@_;
462   my $line = join("", @$arr);
463
464   # Perls < 5.10.1 (with the exception of 5.8.9) have a performance problem with
465   # the substitutions below when dealing with strings stored internally in
466   # UTF-8, so downgrade them (if possible).
467   # Data passed to datasend() should be encoded to octets upstream already so
468   # shouldn't even have the UTF-8 flag on to start with, but if it so happens
469   # that the octets are stored in an upgraded string (as can sometimes occur)
470   # then they would still downgrade without fail anyway.
471   # Only Unicode codepoints > 0xFF stored in an upgraded string will fail to
472   # downgrade. We fail silently in that case, and a "Wide character in print"
473   # warning will be emitted later by syswrite().
474   utf8::downgrade($line, 1) if $] < 5.010001 && $] != 5.008009;
475
476   return 0
477     if $cmd->_is_closed;
478
479   my $last_ch = ${*$cmd}{'net_cmd_last_ch'};
480
481   # We have not send anything yet, so last_ch = "\012" means we are at the start of a line
482   $last_ch = ${*$cmd}{'net_cmd_last_ch'} = "\012" unless defined $last_ch;
483
484   return 1 unless length $line;
485
486   if ($cmd->debug) {
487     foreach my $b (split(/\n/, $line)) {
488       $cmd->debug_print(1, "$b\n");
489     }
490   }
491
492   $line =~ tr/\r\n/\015\012/ unless "\r" eq "\015";
493
494   my $first_ch = '';
495
496   if ($last_ch eq "\015") {
497     # Remove \012 so it does not get prefixed with another \015 below
498     # and escape the . if there is one following it because the fixup
499     # below will not find it
500     $first_ch = "\012" if $line =~ s/^\012(\.?)/$1$1/;
501   }
502   elsif ($last_ch eq "\012") {
503     # Fixup below will not find the . as the first character of the buffer
504     $first_ch = "." if $line =~ /^\./;
505   }
506
507   $line =~ s/\015?\012(\.?)/\015\012$1$1/sg;
508
509   substr($line, 0, 0) = $first_ch;
510
511   ${*$cmd}{'net_cmd_last_ch'} = substr($line, -1, 1);
512
513   $cmd->_syswrite_with_timeout($line)
514     or return;
515
516   1;
517 }
518
519
520 sub rawdatasend {
521   my $cmd  = shift;
522   my $arr  = @_ == 1 && ref($_[0]) ? $_[0] : \@_;
523   my $line = join("", @$arr);
524
525   return 0
526     if $cmd->_is_closed;
527
528   return 1
529     unless length($line);
530
531   if ($cmd->debug) {
532     my $b = "$cmd>>> ";
533     print STDERR $b, join("\n$b", split(/\n/, $line)), "\n";
534   }
535
536   $cmd->_syswrite_with_timeout($line)
537     or return;
538
539   1;
540 }
541
542
543 sub dataend {
544   my $cmd = shift;
545
546   return 0
547     if $cmd->_is_closed;
548
549   my $ch = ${*$cmd}{'net_cmd_last_ch'};
550   my $tosend;
551
552   if (!defined $ch) {
553     return 1;
554   }
555   elsif ($ch ne "\012") {
556     $tosend = "\015\012";
557   }
558
559   $tosend .= ".\015\012";
560
561   $cmd->debug_print(1, ".\n")
562     if ($cmd->debug);
563
564   $cmd->_syswrite_with_timeout($tosend)
565     or return 0;
566
567   delete ${*$cmd}{'net_cmd_last_ch'};
568
569   $cmd->response() == CMD_OK;
570 }
571
572 # read and write to tied filehandle
573 sub tied_fh {
574   my $cmd = shift;
575   ${*$cmd}{'net_cmd_readbuf'} = '';
576   my $fh = gensym();
577   tie *$fh, ref($cmd), $cmd;
578   return $fh;
579 }
580
581 # tie to myself
582 sub TIEHANDLE {
583   my $class = shift;
584   my $cmd   = shift;
585   return $cmd;
586 }
587
588 # Tied filehandle read.  Reads requested data length, returning
589 # end-of-file when the dot is encountered.
590 sub READ {
591   my $cmd = shift;
592   my ($len, $offset) = @_[1, 2];
593   return unless exists ${*$cmd}{'net_cmd_readbuf'};
594   my $done = 0;
595   while (!$done and length(${*$cmd}{'net_cmd_readbuf'}) < $len) {
596     ${*$cmd}{'net_cmd_readbuf'} .= $cmd->getline() or return;
597     $done++ if ${*$cmd}{'net_cmd_readbuf'} =~ s/^\.\r?\n\Z//m;
598   }
599
600   $_[0] = '';
601   substr($_[0], $offset + 0) = substr(${*$cmd}{'net_cmd_readbuf'}, 0, $len);
602   substr(${*$cmd}{'net_cmd_readbuf'}, 0, $len) = '';
603   delete ${*$cmd}{'net_cmd_readbuf'} if $done;
604
605   return length $_[0];
606 }
607
608
609 sub READLINE {
610   my $cmd = shift;
611
612   # in this context, we use the presence of readbuf to
613   # indicate that we have not yet reached the eof
614   return unless exists ${*$cmd}{'net_cmd_readbuf'};
615   my $line = $cmd->getline;
616   return if $line =~ /^\.\r?\n/;
617   $line;
618 }
619
620
621 sub PRINT {
622   my $cmd = shift;
623   my ($buf, $len, $offset) = @_;
624   $len ||= length($buf);
625   $offset += 0;
626   return unless $cmd->datasend(substr($buf, $offset, $len));
627   ${*$cmd}{'net_cmd_sending'}++;    # flag that we should call dataend()
628   return $len;
629 }
630
631
632 sub CLOSE {
633   my $cmd = shift;
634   my $r = exists(${*$cmd}{'net_cmd_sending'}) ? $cmd->dataend : 1;
635   delete ${*$cmd}{'net_cmd_readbuf'};
636   delete ${*$cmd}{'net_cmd_sending'};
637   $r;
638 }
639
640 1;
641
642 __END__
643
644
645 =head1 NAME
646
647 Net::Cmd - Network Command class (as used by FTP, SMTP etc)
648
649 =head1 SYNOPSIS
650
651     use Net::Cmd;
652
653     @ISA = qw(Net::Cmd);
654
655 =head1 DESCRIPTION
656
657 C<Net::Cmd> is a collection of methods that can be inherited by a sub class
658 of C<IO::Handle>. These methods implement the functionality required for a
659 command based protocol, for example FTP and SMTP.
660
661 =head1 USER METHODS
662
663 These methods provide a user interface to the C<Net::Cmd> object.
664
665 =over 4
666
667 =item debug ( VALUE )
668
669 Set the level of debug information for this object. If C<VALUE> is not given
670 then the current state is returned. Otherwise the state is changed to 
671 C<VALUE> and the previous state returned. 
672
673 Different packages
674 may implement different levels of debug but a non-zero value results in 
675 copies of all commands and responses also being sent to STDERR.
676
677 If C<VALUE> is C<undef> then the debug level will be set to the default
678 debug level for the class.
679
680 This method can also be called as a I<static> method to set/get the default
681 debug level for a given class.
682
683 =item message ()
684
685 Returns the text message returned from the last command. In a scalar
686 context it returns a single string, in a list context it will return
687 each line as a separate element. (See L<PSEUDO RESPONSES> below.)
688
689 =item code ()
690
691 Returns the 3-digit code from the last command. If a command is pending
692 then the value 0 is returned. (See L<PSEUDO RESPONSES> below.)
693
694 =item ok ()
695
696 Returns non-zero if the last code value was greater than zero and
697 less than 400. This holds true for most command servers. Servers
698 where this does not hold may override this method.
699
700 =item status ()
701
702 Returns the most significant digit of the current status code. If a command
703 is pending then C<CMD_PENDING> is returned.
704
705 =item datasend ( DATA )
706
707 Send data to the remote server, converting LF to CRLF. Any line starting
708 with a '.' will be prefixed with another '.'.
709 C<DATA> may be an array or a reference to an array.
710 The C<DATA> passed in must be encoded by the caller to octets of whatever
711 encoding is required, e.g. by using the Encode module's C<encode()> function.
712
713 =item dataend ()
714
715 End the sending of data to the remote server. This is done by ensuring that
716 the data already sent ends with CRLF then sending '.CRLF' to end the
717 transmission. Once this data has been sent C<dataend> calls C<response> and
718 returns true if C<response> returns CMD_OK.
719
720 =back
721
722 =head1 CLASS METHODS
723
724 These methods are not intended to be called by the user, but used or 
725 over-ridden by a sub-class of C<Net::Cmd>
726
727 =over 4
728
729 =item debug_print ( DIR, TEXT )
730
731 Print debugging information. C<DIR> denotes the direction I<true> being
732 data being sent to the server. Calls C<debug_text> before printing to
733 STDERR.
734
735 =item debug_text ( DIR, TEXT )
736
737 This method is called to print debugging information. TEXT is
738 the text being sent. The method should return the text to be printed.
739
740 This is primarily meant for the use of modules such as FTP where passwords
741 are sent, but we do not want to display them in the debugging information.
742
743 =item command ( CMD [, ARGS, ... ])
744
745 Send a command to the command server. All arguments are first joined with
746 a space character and CRLF is appended, this string is then sent to the
747 command server.
748
749 Returns undef upon failure.
750
751 =item unsupported ()
752
753 Sets the status code to 580 and the response text to 'Unsupported command'.
754 Returns zero.
755
756 =item response ()
757
758 Obtain a response from the server. Upon success the most significant digit
759 of the status code is returned. Upon failure, timeout etc., I<CMD_ERROR> is
760 returned.
761
762 =item parse_response ( TEXT )
763
764 This method is called by C<response> as a method with one argument. It should
765 return an array of 2 values, the 3-digit status code and a flag which is true
766 when this is part of a multi-line response and this line is not the last.
767
768 =item getline ()
769
770 Retrieve one line, delimited by CRLF, from the remote server. Returns I<undef>
771 upon failure.
772
773 B<NOTE>: If you do use this method for any reason, please remember to add
774 some C<debug_print> calls into your method.
775
776 =item ungetline ( TEXT )
777
778 Unget a line of text from the server.
779
780 =item rawdatasend ( DATA )
781
782 Send data to the remote server without performing any conversions. C<DATA>
783 is a scalar.
784 As with C<datasend()>, the C<DATA> passed in must be encoded by the caller
785 to octets of whatever encoding is required, e.g. by using the Encode module's
786 C<encode()> function.
787
788 =item read_until_dot ()
789
790 Read data from the remote server until a line consisting of a single '.'.
791 Any lines starting with '..' will have one of the '.'s removed.
792
793 Returns a reference to a list containing the lines, or I<undef> upon failure.
794
795 =item tied_fh ()
796
797 Returns a filehandle tied to the Net::Cmd object.  After issuing a
798 command, you may read from this filehandle using read() or <>.  The
799 filehandle will return EOF when the final dot is encountered.
800 Similarly, you may write to the filehandle in order to send data to
801 the server after issuing a command that expects data to be written.
802
803 See the Net::POP3 and Net::SMTP modules for examples of this.
804
805 =back
806
807 =head1 PSEUDO RESPONSES
808
809 Normally the values returned by C<message()> and C<code()> are
810 obtained from the remote server, but in a few circumstances, as
811 detailed below, C<Net::Cmd> will return values that it sets. You
812 can alter this behavior by overriding DEF_REPLY_CODE() to specify
813 a different default reply code, or overriding one of the specific
814 error handling methods below.
815
816 =over 4
817
818 =item Initial value
819
820 Before any command has executed or if an unexpected error occurs
821 C<code()> will return "421" (temporary connection failure) and
822 C<message()> will return undef.
823
824 =item Connection closed
825
826 If the underlying C<IO::Handle> is closed, or if there are
827 any read or write failures, the file handle will be forced closed,
828 and C<code()> will return "421" (temporary connection failure)
829 and C<message()> will return "[$pkg] Connection closed"
830 (where $pkg is the name of the class that subclassed C<Net::Cmd>).
831 The _set_status_closed() method can be overridden to set a different
832 message (by calling set_status()) or otherwise trap this error.
833
834 =item Timeout
835
836 If there is a read or write timeout C<code()> will return "421"
837 (temporary connection failure) and C<message()> will return
838 "[$pkg] Timeout" (where $pkg is the name of the class
839 that subclassed C<Net::Cmd>). The _set_status_timeout() method
840 can be overridden to set a different message (by calling set_status())
841 or otherwise trap this error.
842
843 =back
844
845 =head1 EXPORTS
846
847 C<Net::Cmd> exports six subroutines, five of these, C<CMD_INFO>, C<CMD_OK>,
848 C<CMD_MORE>, C<CMD_REJECT> and C<CMD_ERROR>, correspond to possible results
849 of C<response> and C<status>. The sixth is C<CMD_PENDING>.
850
851 =head1 AUTHOR
852
853 Graham Barr E<lt>F<gbarr@pobox.com>E<gt>
854
855 Steve Hay E<lt>F<shay@cpan.org>E<gt> is now maintaining libnet as of version
856 1.22_02
857
858 =head1 COPYRIGHT
859
860 Versions up to 2.29_1 Copyright (c) 1995-2006 Graham Barr. All rights reserved.
861 Changes in Version 2.29_2 onwards Copyright (C) 2013-2014 Steve Hay.  All rights
862 reserved.
863
864 This module is free software; you can redistribute it and/or modify it under the
865 same terms as Perl itself, i.e. under the terms of either the GNU General Public
866 License or the Artistic License, as specified in the F<LICENCE> file.
867
868 =cut