about summary refs log tree commit
diff options
context:
space:
mode:
-rw-r--r--Artistic131
-rw-r--r--Changes565
-rwxr-xr-xConfigure2
-rw-r--r--Copying251
-rw-r--r--INSTALL42
-rw-r--r--LICENCE23
-rw-r--r--MANIFEST15
-rw-r--r--Makefile.PL35
-rw-r--r--README55
-rwxr-xr-xdemos/smtp.self6
-rw-r--r--lib/Net/Cmd.pm203
-rw-r--r--lib/Net/Config.pm26
-rw-r--r--lib/Net/Domain.pm20
-rw-r--r--lib/Net/FTP.pm114
-rw-r--r--lib/Net/FTP/A.pm2
-rw-r--r--lib/Net/FTP/E.pm2
-rw-r--r--lib/Net/FTP/I.pm2
-rw-r--r--lib/Net/FTP/L.pm2
-rw-r--r--lib/Net/FTP/dataconn.pm2
-rw-r--r--lib/Net/NNTP.pm116
-rw-r--r--lib/Net/Netrc.pm12
-rw-r--r--lib/Net/POP3.pm65
-rw-r--r--lib/Net/SMTP.pm105
-rw-r--r--lib/Net/Time.pm12
-rw-r--r--lib/Net/libnetFAQ.pod6
-rw-r--r--t/changes.t48
-rw-r--r--t/config.t4
-rw-r--r--t/critic.t10
-rw-r--r--t/datasend.t13
-rw-r--r--t/external/ftp-ssl.t2
-rw-r--r--t/ftp.t4
-rw-r--r--t/hostname.t4
-rw-r--r--t/netrc.t4
-rw-r--r--t/nntp.t4
-rw-r--r--t/nntp_ipv6.t12
-rw-r--r--t/nntp_ssl.t18
-rw-r--r--t/pod.t8
-rw-r--r--t/pod_coverage.t12
-rw-r--r--t/pop3_ipv6.t14
-rw-r--r--t/pop3_ssl.t26
-rw-r--r--t/require.t4
-rw-r--r--t/smtp.t4
-rw-r--r--t/smtp_ipv6.t14
-rw-r--r--t/smtp_ssl.t26
-rw-r--r--t/time.t4
45 files changed, 1501 insertions, 548 deletions
diff --git a/Artistic b/Artistic
new file mode 100644
index 0000000..d1b6e5a
--- /dev/null
+++ b/Artistic
@@ -0,0 +1,131 @@
+
+
+
+
+                         The "Artistic License"
+
+                                Preamble
+
+The intent of this document is to state the conditions under which a
+Package may be copied, such that the Copyright Holder maintains some
+semblance of artistic control over the development of the package,
+while giving the users of the package the right to use and distribute
+the Package in a more-or-less customary fashion, plus the right to make
+reasonable modifications.
+
+Definitions:
+
+        "Package" refers to the collection of files distributed by the
+        Copyright Holder, and derivatives of that collection of files
+        created through textual modification.
+
+        "Standard Version" refers to such a Package if it has not been
+        modified, or has been modified in accordance with the wishes
+        of the Copyright Holder as specified below.
+
+        "Copyright Holder" is whoever is named in the copyright or
+        copyrights for the package.
+
+        "You" is you, if you're thinking about copying or distributing
+        this Package.
+
+        "Reasonable copying fee" is whatever you can justify on the
+        basis of media cost, duplication charges, time of people involved,
+        and so on.  (You will not be required to justify it to the
+        Copyright Holder, but only to the computing community at large
+        as a market that must bear the fee.)
+
+        "Freely Available" means that no fee is charged for the item
+        itself, though there may be fees involved in handling the item.
+        It also means that recipients of the item may redistribute it
+        under the same conditions they received it.
+
+1. You may make and give away verbatim copies of the source form of the
+Standard Version of this Package without restriction, provided that you
+duplicate all of the original copyright notices and associated disclaimers.
+
+2. You may apply bug fixes, portability fixes and other modifications
+derived from the Public Domain or from the Copyright Holder.  A Package
+modified in such a way shall still be considered the Standard Version.
+
+3. You may otherwise modify your copy of this Package in any way, provided
+that you insert a prominent notice in each changed file stating how and
+when you changed that file, and provided that you do at least ONE of the
+following:
+
+    a) place your modifications in the Public Domain or otherwise make them
+    Freely Available, such as by posting said modifications to Usenet or
+    an equivalent medium, or placing the modifications on a major archive
+    site such as uunet.uu.net, or by allowing the Copyright Holder to include
+    your modifications in the Standard Version of the Package.
+
+    b) use the modified Package only within your corporation or organization.
+
+    c) rename any non-standard executables so the names do not conflict
+    with standard executables, which must also be provided, and provide
+    a separate manual page for each non-standard executable that clearly
+    documents how it differs from the Standard Version.
+
+    d) make other distribution arrangements with the Copyright Holder.
+
+4. You may distribute the programs of this Package in object code or
+executable form, provided that you do at least ONE of the following:
+
+    a) distribute a Standard Version of the executables and library files,
+    together with instructions (in the manual page or equivalent) on where
+    to get the Standard Version.
+
+    b) accompany the distribution with the machine-readable source of
+    the Package with your modifications.
+
+    c) give non-standard executables non-standard names, and clearly
+    document the differences in manual pages (or equivalent), together
+    with instructions on where to get the Standard Version.
+
+    d) make other distribution arrangements with the Copyright Holder.
+
+5. You may charge a reasonable copying fee for any distribution of this
+Package.  You may charge any fee you choose for support of this
+Package.  You may not charge a fee for this Package itself.  However,
+you may distribute this Package in aggregate with other (possibly
+commercial) programs as part of a larger (possibly commercial) software
+distribution provided that you do not advertise this Package as a
+product of your own.  You may embed this Package's interpreter within
+an executable of yours (by linking); this shall be construed as a mere
+form of aggregation, provided that the complete Standard Version of the
+interpreter is so embedded.
+
+6. The scripts and library files supplied as input to or produced as
+output from the programs of this Package do not automatically fall
+under the copyright of this Package, but belong to whoever generated
+them, and may be sold commercially, and may be aggregated with this
+Package.  If such scripts or library files are aggregated with this
+Package via the so-called "undump" or "unexec" methods of producing a
+binary executable image, then distribution of such an image shall
+neither be construed as a distribution of this Package nor shall it
+fall under the restrictions of Paragraphs 3 and 4, provided that you do
+not represent such an executable image as a Standard Version of this
+Package.
+
+7. C subroutines (or comparably compiled subroutines in other
+languages) supplied by you and linked into this Package in order to
+emulate subroutines and variables of the language defined by this
+Package shall not be considered part of this Package, but are the
+equivalent of input as in Paragraph 6, provided these subroutines do
+not change the language in any way that would cause it to fail the
+regression tests for the language.
+
+8. Aggregation of this Package with a commercial distribution is always
+permitted provided that the use of this Package is embedded; that is,
+when no overt attempt is made to make this Package's interfaces visible
+to the end user of the commercial distribution.  Such use shall not be
+construed as a distribution of this Package.
+
+9. The name of the Copyright Holder may not be used to endorse or promote
+products derived from this software without specific prior written permission.
+
+10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+                                The End
diff --git a/Changes b/Changes
index 1d5a19d..3983d06 100644
--- a/Changes
+++ b/Changes
@@ -1,170 +1,395 @@
-libnet 1.28  -- TODO
-
-  * Stop Makefile.PL from requiring interactive configuration when running via
-    cpan, cpanp or cpanm: just accept all defaults in these cases, as when
-    running non-interactively.  [Resolves CPAN RT#48966]
-  * Add optional POD coverage testing.
-  * Add optional POD testing.
-  * Add optional Perl::Critic testing.
-  * Make code Perl::Critic clean.
-  * Move Net/*.pm into lib/Net/ sub-directory within distribution. This is the
-    usual layout style these days.
-  * Change Net::SMTP::auth() so that it now falls back to another supported AUTH
-    method if a given AUTH method fails.  [Ivan Baktsheev; closes PR#3]
-  * Change Net::SMTP::auth() so that it uses the SMTP AUTH mechanism(s)
-    specified in the Authen::SASL object if one is provided instead of a
-    username.   If a plain text username is specified then use the first
-    reported SMTP AUTH method supported, as usual.  [Ewen McNeill; resolves CPAN
-    RT#58002]
-  * Add support for IPv6 and SSL to Net::FTP, Net::NNTP, Net::POP3 and
-    Net::SMTP.  These features are only available if the user has
-
-      a recent IO::Socket::SSL for SSL support
-      a recent IO::Socket::IP or an older IO::Socket::INET6 for IPv6 support
-
-    If no SSL module is available it will work as before, but attempts to use
-    the SSL functionality will result in an error message.  If no IPv6 modules
-    are available it will just use IPv4 as before.  With IPv6 modules installed
-    one can of course still access IPv4 hosts.
-    [Steffen Ullrich; resolves CPAN RT#93823]
-
-libnet 1.27  -- Fri May 30 2014
-
-  * Simplified Makefile.PL requirements.
-
-libnet 1.26  -- Fri May 30 2014
-
-  * Set minimum required ExtUtils::MakeMaker version to 6.64 to ensure that all
-    parameters used are supported, to save jumping through hoops to support
-    earlier versions.  (This should not be a problem since ExtUtils::MakeMaker
-    6.64 is easily installed into Perl 5.8.1 and above, that being the whole
-    point of the new choice of minimum supported Perl version.)
-  * Set minimum required Perl version to 5.8.1.  This is in line with the
-    minimum requirement of the "Perl Toolchain".
-
-libnet 1.25  -- Tue Feb 04 2014
-
-  * Fix Net::FTP::pasv_wait() not handling errors from Net::Cmd::reponse()
-    [bergner@cs.umu.se; resolves CPAN RT#50420]
-  * Make inheritance from Net::Cmd clearer in the documentation [Resolves CPAN
-    RT#72889]
-  * Set timeout for data connection creation in Net::FTP [Oleg G; resolves CPAN
-    RT#78926]
-  * Stop Net::Domain::domainname() from giving out warnings in android [Brian
-    Fraser]
-
-libnet 1.24  -- Mon Jan 06 2014
-
-  * Fix incorrect handling of CRLF in Net::FTP [Willem Monsuwé; resolves CPAN
-    RT#41642/62029]
-  * POD fixes [Dominic Hargreaves; resolves CPAN RT#91761]
-
-libnet 1.23  -- Mon Aug 12 2013
-
-  * Typo fixes [David Steinbrunner; resolves CPAN RT#87681]
-
-libnet 1.22_02 -- Thu Aug 08 2013
-
-  * Make Net::FTP::dataconn::close() more robust [Together with changes to
-    Net::FTP already made in 1.22_01, this resolves CPAN RT#37700]
-  * Document scalar/list context return values from Net::Cmd::message()
-  * Fix broken URL [Resolves CPAN RT#68749]
-  * Fix documentation typo in Net::Netrc
-  * Fix broken POD in Net::POP3
-  * Improve Net::SMTP documentation of new(), auth() and message() [Resolves
-    CPAN RT#36038]
-  * Add proper skips to skipped tests in ftp.t
-  * Import hostname.t fix from perl core commit #adeb94125a
-  * Add time.t, imported from perl core commit #c85707204c
-  * Add new maintainer information, with updated CPAN and GitHub links
-
-libnet 1.22_01 -- Mon May 31 09:40:25 CDT 2010
-
-  * Do not create/pass a remote name if one is not given to put_unique
-  * Add ->passive method to switch between PORT/PASV connections
-  * Accept - in command parsed from SMTP HELO response
-  * Allow group to set to a group named "0"
-  * Set $@ when ->new returns undef
-  * Add support for LocalAddr to be passed to ->new
-  * Document that timeout is in seconds
-  * Fix leading . encoding in datasend
-  * Make ->supported check ->feature
-  * Allow words other than FILE to prefix the unique name returned in info message from stou
-  * Send ALLO command just before the store command
-  * Avoid warnings when server do not prefix messages with codes
-  * Use uppercase characters for xtext encoding
-  * Catch timeout condition while doing an abort
-  * Ensure REST is sent directly before command being restarted
-  * [rt.cpan.org #49920] Fix URL [Leon Brocard]
-  * Avoid long hang on Mac OS X when hostname is *.local by not calling gethostbyname [Father Chrysostomos]
-  * Avoid infinite recursion in rmdir
-  * Allow finding _netrc on machines that do not support .netrc [Ben Bimber]
-
-libnet 1.22  -- Sun Aug 26 07:13:18 CDT 2007
-
-Bug Fixes
-  * Fix a bug in Net::Cmd that is_utf8 does not exist prior to perl 5.8.1
-
-libnet 1.21  -- Sat May 19 08:53:09 CDT 2007
-
-Bug Fixes
-  * Fix bug causing utf8 encoding of 8bit strings in Net::Cmd
-  * Fix precedence issue in Net::NNTP. Patch from Brendan O'Dea
-  * Fixed bug causing removal of last character on the line when
-    doing ASCII FTP transfers
-
-Enhancements
-  * Add support for ENVID and AUTH to Net::SMTP. Patch by Mark Martinec
-  * Changed default for FTP transfers to be passive
-  * Added support for FTP FEAT command
-
-libnet 1.20  -- Fri Feb  2 19:42:51 CST 2007
-
-Bug Fixes
-  * Fixed incorrect handling of CRLF that straddled two blocks
-  * Fix bug in response() which was too liberal in what it thought was a response line
-  * Silence uninitialized value warnings in Net::Cmd during testing on Win32
-  * Documentations typos and updates
-
-Enhancements
-  * Added support for ORCPT into Net::SMTP
-  * Support for servers that expect the USER command in upper or lower case. Try USER
-    first then try user if that fails
-
-libnet 1.19  -- Wed Jun 30 14:53:48 BST 2004
-
-Bug Fixes
-  * Fixed datasend test to work on Win32 platform
-  * Fixed Authen::SASL checking in SMTP.pm and POP3.pm
-  * Fixed bug that a restarted get with Net::FTP did not append to local file
-
-libnet 1.18  -- Mon Mar 22 16:19:01 GMT 2004
-
-Bug Fixes
-  * Fixed bug in CRLF translation in Net::Cmd datasend/dataend methods
-  * Fixed bug in converting numbers returned by PASV command into a
-    packed IP address
-  * Fixed bug that caused Net::FTP->get to truncate the local file after
-    the restart method had been called
-  * Fixed bug in Net::FTP-.rmdir when the server returned . and .. in
-    the contents of a directory
-  * Fixed bug in POP3 that was sending unnecessary RSETs
-
-Enhancements
-  * Added support for POP3 CAPA command
-  * Added support for XVERP to Net::SMTP
-  * Added Net::POP3->banner method to return the banner received from
-    the server during connect
-  * Added Net::POP3->auth method for performing authentication using
-    SASL, requires Authen::SASL
-  * Added Host option to ->new constructor of FTP, NNTP, SMTP and POP3
-    which can be used instead of passing the host as the first argument
-  * Added ->host method to FTP, NNTP, SMTP and POP3 to return the host
-    string used for the connect. This is useful to determine which host
-    was connected to when multiple hosts are specified
-  * Added support for more non-standard responses to Net::FTP->size
-  * Updated POD for Net::SMTP wrt. not passing a Hello parameter to the
-    constructor. (Jeff Macdonald)
-
-ChangeLogs for releases prior to 1.18 may be found at
-http://svn.mutatus.co.uk/browse/libnet/tags/libnet-1.17/ChangeLog
+Revision history for Perl distribution libnet
+
+3.08 Development
+
+    - Documented the fact that Net::SMTP::auth() can accept an Authen::SASL
+      object instead of a username and password.  [Jan Viktorin, CPAN RT#106183]
+
+    - Simplified specification of INSTALLDIRS: We do not need to check the lower
+      bound since we only support Perl 5.8.1 and higher anyway.
+
+3.07 2015-07-17
+
+    - Net::FTP::rmdir() has been made more robust by making use of the MLSD
+      command in addition to the NLST command since the latter is known not to
+      be processed correctly by some FTP servers.  [Chris Lindee, CPAN
+      RT#100694]
+
+    - Net::FTP, Net::NNTP, Net::POP3 and Net::SMTP can now restrict domain to
+      IPv4 even if IPv6 is available by using the new Domain or Family argument.
+
+      Net::NNTP now supports the LocalPort argument in addition to LocalAddr.
+
+      Net::POP3 now supports the LocalAddr and LocalPort arguments in addition
+      to ResvPort (which is retained for backwards compatibility).
+
+      [Steffen Ullrich, PR#18]
+
+    - Fixed a bug in Net::Cmd::datasend() which caused octets in [\x80-\xFF]
+      stored in a "binary string" to be replaced with their UTF-8 encodings if
+      the string happened to be stored internally in an "upgraded" state (i.e.
+      with the UTF-8 flag on).  (As noted below, strings passed to datasend()
+      should always be encoded first, and therefore not stored in such a state
+      anyway, but it is all too easy for perl to change this internal state
+      unless the encodeing is done at the very last minute before calling
+      datasend(), so it helps if datasend() plays more nicely in this case.  In
+      particular, it was wrong of datasend() to treat upgraded and downgraded
+      strings differently when their contents were identical at the Perl level.)
+
+      This bugfix results in a breaking change to the case of a "text string"
+      with characters in U+0080..U+00FF stored internally in an upgraded state
+      since those characters are likewise no longer encoded to UTF-8 by
+      datasend(), but callers of datasend() should not have been relying on this
+      behaviour anyway: In general, datasend() has no idea what encoding is
+      required for output so callers should always encode the data to be output
+      to whatever encoding is required first.  This has now been clarified in
+      the documentation.
+
+      Finally, a text string with characters >= U+0100 will now cause a "Wide
+      character in print" warning from datasend() since such characters cannot
+      be output as bytes and datasend() no longer encodes to UTF-8.  In this
+      case, UTF-8 bytes will still be output as before since that happens to be
+      the internal representation of such characters, but the warning is new.
+      Callers should heed this warning and encode such strings to whatever
+      encoding is required before calling datasend(), as noted above.
+
+      [Ricardo Signes, CPAN RT#104433]
+
+3.06 2015-04-01
+
+    - Fixed INSTALLDIRS to account for the @INC reordering change in Perl 5.12.
+      See Perl RT#116479 for details.  (libnet entered the perl core in Perl
+      5.7.2 so that's what the lower bound of the check should strictly be, but
+      since we only support Perl 5.8.1 and higher anyway it suffices to check
+      for Perl 5.8.  The upper bound is correctly Perl 5.11.0 since the @INC
+      reordering change in question (Perl core commit #b9ba2fadb1) first
+      appeared in Perl 5.11.0.)  [CPAN RT#103238]
+
+    - Fixed Net::FTP authorize() method, which incorrectly interpreted the
+      return value of the _RESP() method and falsely reported a failure.  [Troy
+      Loveday, CPAN RT#48532]
+
+    - Added optional SendHello argument to Net::SMTP->new() to allow preventing
+      the EHLO/HELO command from being automatically sent by the constructor.
+      [Danil Onishchenko, PR#13]
+
+3.05 2015-01-12
+
+    - Fixed infinite loop in Net::SMTP::auth().  [CPAN RT#100235]
+
+3.04 2014-11-29
+
+    - SNI is now only used for SSL connections if it is supported by
+      IO::Socket::SSL (i.e. OpenSSL version >= 1).  (The previous release
+      switched to using SNI by default, which caused some CPAN Testers
+      failures.)  [Steffen Ullrich, PR#10]
+
+3.03 2014-11-28
+
+    - Remodelled SSL support in Net::NNTP in the manner of Net::POP3 and
+      Net::SMTP.  [Steffen Ullrich, PR#9]
+
+    - Increased minimum requred IO::Socket::SSL version from 1.999 to 2.007 to
+      fix data connection problems in Net::FTP.  [Steffen Ullrich, CPAN
+      RT#100529]
+
+    - Fixed a broken port() call in pasv_xfer()/pasv_xfer_unique() in Net::FTP.
+      [Mario Preksavec, PR#8]
+
+    - Increased minimum required Socket version from 1.3 to 2.016.  This may be
+      required when those modules that can support IPv6 load IO::Socket::IP (on
+      some OSes, at least).  It does not appear to be necessary if they load
+      IO::Socket::INET6 or IO::Socket::INET instead, but this is not easy for
+      the end-user to control so it is simpler to always insist on Socket 2.016
+      or higher.  [CPAN RT#100020]
+
+    - Fixed "Argument ... isn't numeric in subroutine entry" warnings when using
+      older versions of Perl.  [CPAN RT#100020]
+
+    - Added optional Changes testing (skipped unless AUTHOR_TESTING).
+
+    - Reformatted Changes file as per CPAN::Changes::Spec.
+
+3.02 2014-10-10
+
+    - Don't run interactive prompt() in Makefile.PL when in PERL_CORE.
+
+    - Fix $smtp->auth($sasl) to try the AUTH mechanism (if present) in the
+      Authen::SASL object before falling back on other mechanisms.  [CPAN
+      RT#99415]
+
+3.01 2014-10-09
+
+    - Require IO::Socket::SSL >= 1.999 to protect against a bad version (0.30)
+      of IO::Socket::IP and hopefully fix another bunch of CPAN Testers
+      failures.
+
+3.00 2014-10-09
+
+    - Skip Perl Critic, Pod and Pod Coverage tests unless AUTHOR_TESTING.  [CPAN
+      RT#99399]
+
+    - Synchronize all $VERSIONs to the distribution's version number, bumping
+      that to 3.00 so that no $VERSIONs end up going backwards.
+
+1.30 2014-10-08
+
+    - Sigh. Fix PAUSE indexing problem again. Net::SMTP::SSL is already used by
+      Net-SMTP-SSL.
+
+1.29 2014-10-08
+
+    - Fix PAUSE indexing problem. Net::POP3::_SSLified and Net::SMTP::_SSLified
+      are already used by Net-SSLGlue.
+
+1.28 2014-10-08
+
+    - Improve code()/message() initialization and error handling in Net::Cmd.
+      [Tom Metro, CPAN RT#14875]
+
+    - Don't use the ALLO command on FTP servers that don't support it.  [CPAN
+      RT#95717]
+
+    - Stop Makefile.PL from requiring interactive configuration when running via
+      cpan, cpanp or cpanm: just accept all defaults in these cases, as when
+      running non-interactively.  [CPAN RT#48966]
+
+    - Add optional POD coverage testing.
+
+    - Add optional POD testing.
+
+    - Add optional Perl::Critic testing.
+
+    - Make code Perl::Critic clean.
+
+    - Move Net/*.pm into lib/Net/ sub-directory within distribution.  This is
+      the usual layout style these days.
+
+    - Change Net::SMTP::auth() so that it now falls back to another supported
+      AUTH method if a given AUTH method fails.  [Ivan Baktsheev, PR#3]
+
+    - Change Net::SMTP::auth() so that it uses the SMTP AUTH mechanism(s)
+      specified in the Authen::SASL object if one is provided instead of a
+      username.   If a plain text username is specified then use the first
+      reported SMTP AUTH method supported, as usual.  [Ewen McNeill, CPAN
+      RT#58002]
+
+    - Add support for IPv6 and SSL to Net::FTP, Net::NNTP, Net::POP3 and
+      Net::SMTP.  These features are only available if the user has:
+
+      * a recent IO::Socket::SSL for SSL support;
+
+      * a recent IO::Socket::IP or an older IO::Socket::INET6 for IPv6 support.
+
+      If no SSL module is available it will work as before, but attempts to use
+      the SSL functionality will result in an error message.  If no IPv6 modules
+      are available it will just use IPv4 as before.  With IPv6 modules
+      installed one can of course still access IPv4 hosts.
+
+      [Steffen Ullrich, CPAN RT#93823]
+
+1.27 2014-05-30
+
+    - Simplified Makefile.PL requirements.
+
+1.26 2014-05-30
+
+    - Set minimum required ExtUtils::MakeMaker version to 6.64 to ensure that
+      all parameters used are supported, to save jumping through hoops to
+      support earlier versions.  (This should not be a problem since
+      ExtUtils::MakeMaker 6.64 is easily installed into Perl 5.8.1 and above,
+      that being the whole point of the new choice of minimum supported Perl
+      version.)
+
+    - Set minimum required Perl version to 5.8.1.  This is in line with the
+      minimum requirement of the "Perl Toolchain".
+
+1.25 2014-02-04
+
+    - Fix Net::FTP::pasv_wait() not handling errors from Net::Cmd::reponse().
+      [bergner@cs.umu.se, CPAN RT#50420]
+
+    - Make inheritance from Net::Cmd clearer in the documentation.  [CPAN
+      RT#72889]
+
+    - Set timeout for data connection creation in Net::FTP.  [Oleg G, CPAN
+      RT#78926]
+
+    - Stop Net::Domain::domainname() from giving out warnings in Android.
+      [Brian Fraser]
+
+1.24 2014-01-06
+
+    - Fix incorrect handling of CRLF in Net::FTP.  [Willem Monsuwé, CPAN
+      RT#41642/62029]
+
+    - POD fixes.  [Dominic Hargreaves, CPAN RT#91761]
+
+1.23 2013-08-12
+
+    - Typo fixes.  [David Steinbrunner, CPAN RT#87681]
+
+1.22_02 2013-08-08
+
+    - Make Net::FTP::dataconn::close() more robust.  [Together with changes to
+      Net::FTP already made in 1.22_01, this resolves CPAN RT#37700.]
+
+    - Document scalar/list context return values from Net::Cmd::message().
+
+    - Fix broken URL.  [CPAN RT#68749]
+
+    - Fix documentation typo in Net::Netrc.
+
+    - Fix broken POD in Net::POP3.
+
+    - Improve Net::SMTP documentation of new(), auth() and message().  [CPAN
+      RT#36038]
+
+    - Add proper skips to skipped tests in ftp.t.
+
+    - Import hostname.t fix from Perl core commit #adeb94125a.
+
+    - Add time.t, imported from Perl core commit #c85707204c.
+
+    - Add new maintainer information, with updated CPAN and GitHub links.
+
+1.22_01 2010-05-31 09:40:25-05:00
+
+    - Do not create/pass a remote name if one is not given to put_unique.
+
+    - Add ->passive() method to switch between PORT/PASV connections.
+
+    - Accept - in command parsed from SMTP HELO response.
+
+    - Allow group to set to a group named "0".
+
+    - Set $@ when ->new() returns undef.
+
+    - Add support for LocalAddr to be passed to ->new().
+
+    - Document that timeout is in seconds.
+
+    - Fix leading . encoding in datasend().
+
+    - Make ->supported() check ->feature().
+
+    - Allow words other than FILE to prefix the unique name returned in info
+      message from stou.
+
+    - Send ALLO command just before the store command.
+
+    - Avoid warnings when server do not prefix messages with codes.
+
+    - Use uppercase characters for xtext encoding.
+
+    - Catch timeout condition while doing an abort.
+
+    - Ensure REST is sent directly before command being restarted.
+
+    - Fix URL.  [Leon Brocard, CPAN RT#49920]
+
+    - Avoid long hang on Mac OS X when hostname is *.local by not calling
+      gethostbyname().  [Father Chrysostomos]
+
+    - Avoid infinite recursion in rmdir().
+
+    - Allow finding _netrc on machines that do not support .netrc.  [Ben Bimber]
+
+1.22 2007-08-26 07:13:18-05:00
+
+[Bug Fixes]
+
+    - Fix a bug in Net::Cmd that is_utf8() does not exist prior to Perl 5.8.1.
+
+1.21 2007-05-19 08:53:09-05:00
+
+[Bug Fixes]
+
+    - Fix bug causing utf8 encoding of 8-bit strings in Net::Cmd.
+
+    - Fix precedence issue in Net::NNTP.  [Brendan O'Dea]
+
+    - Fixed bug causing removal of last character on the line when doing ASCII
+      FTP transfers.
+
+[Enhancements]
+
+    - Add support for ENVID and AUTH to Net::SMTP.  [Mark Martinec]
+
+    - Changed default for FTP transfers to be passive.
+
+    - Added support for FTP FEAT command.
+
+1.20 2007-02-02 19:42:51-06:00
+
+[Bug Fixes]
+
+    - Fixed incorrect handling of CRLF that straddled two blocks.
+
+    - Fix bug in response() which was too liberal in what it thought was a
+      response line.
+
+    - Silence uninitialized value warnings in Net::Cmd during testing on Win32.
+
+    - Documentation typos and updates.
+
+[Enhancements]
+
+    - Added support for ORCPT into Net::SMTP.
+
+    - Support for servers that expect the USER command in upper or lower case.
+      Try USER first then try user if that fails.
+
+1.19 2004-06-30 14:53:48+01:00
+
+[Bug Fixes]
+
+    - Fixed datasend() test to work on Win32 platform.
+
+    - Fixed Authen::SASL checking in Net::SMTP and Net::POP3.
+
+    - Fixed bug that a restarted get with Net::FTP did not append to local file.
+
+1.18 2004-03-22 16:19:01Z
+
+[Bug Fixes]
+
+    - Fixed bug in CRLF translation in Net::Cmd datasend()/dataend() methods.
+
+    - Fixed bug in converting numbers returned by PASV command into a packed IP
+      address.
+
+    - Fixed bug that caused Net::FTP->get() to truncate the local file after the
+      restart method had been called.
+
+    - Fixed bug in Net::FTP->rmdir() when the server returned . and .. in the
+      contents of a directory.
+
+    - Fixed bug in Net::POP3 that was sending unnecessary RSETs.
+
+[Enhancements]
+
+    - Added support for POP3 CAPA command.
+
+    - Added support for XVERP to Net::SMTP.
+
+    - Added Net::POP3->banner() method to return the banner received from the
+      server during connect.
+
+    - Added Net::POP3->auth() method for performing authentication using SASL;
+      requires Authen::SASL.
+
+    - Added Host option to ->new() constructor of FTP, NNTP, SMTP and POP3,
+      which can be used instead of passing the host as the first argument.
+
+    - Added ->host() method to FTP, NNTP, SMTP and POP3 to return the host
+      string used for the connect.  This is useful to determine which host was
+      connected to when multiple hosts are specified.
+
+    - Added support for more non-standard responses to Net::FTP->size().
+
+    - Updated POD for Net::SMTP with respect to not passing a Hello parameter to
+      the constructor.  [Jeff Macdonald]
+
+ChangeLogs for releases prior to 1.18 may be found at:
+https://github.com/steve-m-hay/perl-libnet/blob/v1.17/ChangeLog
diff --git a/Configure b/Configure
index c207277..105e151 100755
--- a/Configure
+++ b/Configure
@@ -255,10 +255,8 @@ if( -f $libnet_cfg )
 elsif (eval { require Net::Config })
  {
   $have_old = 1;
-  {
   no warnings 'once';
   %oldcfg = %Net::Config::NetConfig;
-  }
  }
 
 map { $cfg{lc $_} = $cfg{$_}; delete $cfg{$_} if /[A-Z]/ } keys %cfg;
diff --git a/Copying b/Copying
new file mode 100644
index 0000000..8de98af
--- /dev/null
+++ b/Copying
@@ -0,0 +1,251 @@
+
+                    GNU GENERAL PUBLIC LICENSE
+                     Version 1, February 1989
+
+ Copyright (C) 1989 Free Software Foundation, Inc.
+                    51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The license agreements of most software companies try to keep users
+at the mercy of those companies.  By contrast, our General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  The
+General Public License applies to the Free Software Foundation's
+software and to any other program whose authors commit to using it.
+You can use it for your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Specifically, the General Public License is designed to make
+sure that you have the freedom to give away or sell copies of free
+software, that you receive source code or can get it if you want it,
+that you can change the software or use pieces of it in new free
+programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of a such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must tell them their rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any program or other work which
+contains a notice placed by the copyright holder saying it may be
+distributed under the terms of this General Public License.  The
+"Program", below, refers to any such program or work, and a "work based
+on the Program" means either the Program or any work containing the
+Program or a portion of it, either verbatim or with modifications.  Each
+licensee is addressed as "you".
+
+  1. You may copy and distribute verbatim copies of the Program's source
+code as you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and
+disclaimer of warranty; keep intact all the notices that refer to this
+General Public License and to the absence of any warranty; and give any
+other recipients of the Program a copy of this General Public License
+along with the Program.  You may charge a fee for the physical act of
+transferring a copy.
+
+  2. You may modify your copy or copies of the Program or any portion of
+it, and copy and distribute such modifications under the terms of Paragraph
+1 above, provided that you also do the following:
+
+    a) cause the modified files to carry prominent notices stating that
+    you changed the files and the date of any change; and
+
+    b) cause the whole of any work that you distribute or publish, that
+    in whole or in part contains the Program or any part thereof, either
+    with or without modifications, to be licensed at no charge to all
+    third parties under the terms of this General Public License (except
+    that you may choose to grant warranty protection to some or all
+    third parties, at your option).
+
+    c) If the modified program normally reads commands interactively when
+    run, you must cause it, when started running for such interactive use
+    in the simplest and most usual way, to print or display an
+    announcement including an appropriate copyright notice and a notice
+    that there is no warranty (or else, saying that you provide a
+    warranty) and that users may redistribute the program under these
+    conditions, and telling the user how to view a copy of this General
+    Public License.
+
+    d) You may charge a fee for the physical act of transferring a
+    copy, and you may at your option offer warranty protection in
+    exchange for a fee.
+
+Mere aggregation of another independent work with the Program (or its
+derivative) on a volume of a storage or distribution medium does not bring
+the other work under the scope of these terms.
+
+  3. You may copy and distribute the Program (or a portion or derivative of
+it, under Paragraph 2) in object code or executable form under the terms of
+Paragraphs 1 and 2 above provided that you also do one of the following:
+
+    a) accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of
+    Paragraphs 1 and 2 above; or,
+
+    b) accompany it with a written offer, valid for at least three
+    years, to give any third party free (except for a nominal charge
+    for the cost of distribution) a complete machine-readable copy of the
+    corresponding source code, to be distributed under the terms of
+    Paragraphs 1 and 2 above; or,
+
+    c) accompany it with the information you received as to where the
+    corresponding source code may be obtained.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form alone.)
+
+Source code for a work means the preferred form of the work for making
+modifications to it.  For an executable file, complete source code means
+all the source code for all modules it contains; but, as a special
+exception, it need not include source code for modules which are standard
+libraries that accompany the operating system on which the executable
+file runs, or for standard header files or definitions files that
+accompany that operating system.
+
+  4. You may not copy, modify, sublicense, distribute or transfer the
+Program except as expressly provided under this General Public License.
+Any attempt otherwise to copy, modify, sublicense, distribute or transfer
+the Program is void, and will automatically terminate your rights to use
+the Program under this License.  However, parties who have received
+copies, or rights to use copies, from you under this General Public
+License will not have their licenses terminated so long as such parties
+remain in full compliance.
+
+  5. By copying, distributing or modifying the Program (or any work based
+on the Program) you indicate your acceptance of this license to do so,
+and all its terms and conditions.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the original
+licensor to copy, distribute or modify the Program subject to these
+terms and conditions.  You may not impose any further restrictions on the
+recipients' exercise of the rights granted herein.
+
+  7. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of the license which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+the license, you may choose any version ever published by the Free Software
+Foundation.
+
+  8. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+        Appendix: How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to humanity, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these
+terms.
+
+  To do so, attach the following notices to the program.  It is safest to
+attach them to the start of each source file to most effectively convey
+the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 1, or (at your option)
+    any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19xx name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the
+appropriate parts of the General Public License.  Of course, the
+commands you use may be called something other than `show w' and `show
+c'; they could even be mouse-clicks or menu items--whatever suits your
+program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  program `Gnomovision' (a program to direct compilers to make passes
+  at assemblers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..8608d8c
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,42 @@
+PREREQUISITES
+
+    Perl
+
+        Perl version 5.8.1 or later.
+        The latest version of Perl is available from http://www.perl.com/.
+
+    Perl Modules
+
+        There are no non-standard Perl modules required by this module.
+
+INSTALLATION
+
+    To install this module, cd to the directory that contains this INSTALL file
+    and type the following:
+
+        perl Makefile.PL
+        make
+        make test
+        make install
+
+    Normally when Makefile.PL is run it will run Configure which will ask some
+    questions about your system.  The results of these questions will be stored
+    in a file called libnet.cfg which will be installed alongside the other perl
+    modules in this distribution.  Makefile.PL will run Configure in an
+    interactive mode unless these exists a file called libnet.cfg in the build
+    directory or Makefile.PL itself is being run non-interactively or via cpan,
+    cpanp or cpanm.
+
+    If you are on a system which cannot run this script you can create an empty
+    file to make Makefile.PL skip running Configure.  If you want to keep your
+    existing settings and not run interactivly then simply run:
+
+        perl Configure -d
+
+    before running Makefile.PL.
+
+    On Windows, you will need to use "nmake" or "dmake" rather than "make" in
+    the commands above, depending on what your perl was built with.  To
+    determine which make program was used to build your perl type the following:
+
+        perl -V:make
diff --git a/LICENCE b/LICENCE
new file mode 100644
index 0000000..cafb5b6
--- /dev/null
+++ b/LICENCE
@@ -0,0 +1,23 @@
+This distribution is free software; you can redistribute it and/or modify it
+under the terms of either:
+
+a) the GNU General Public License as published by the Free Software Foundation;
+   either version 1, or (at your option) any later version; or
+
+b) the "Artistic License" which comes with this distribution.
+
+This distribution is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE.  See either the GNU General Public License or the
+Artistic License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this distribution in the file named "Copying".  If not, write to the Free
+Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA or visit their web page on the internet at
+http://www.gnu.org/copyleft/gpl.html or the Perl web page at
+http://dev.perl.org/licenses/gpl1.html.
+
+You should also have received a copy of the Artistic License with this
+distribution, in the file named "Artistic".  If not, visit the Perl web page on
+the internet at http://dev.perl.org/licenses/artistic.html.
diff --git a/MANIFEST b/MANIFEST
index d5a9bcd..c40c1c1 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,5 +1,9 @@
+Artistic
 Changes
 Configure
+Copying
+INSTALL
+LICENCE
 MANIFEST
 MANIFEST.SKIP
 Makefile.PL
@@ -25,25 +29,26 @@ lib/Net/POP3.pm                          Post Office Protocol
 lib/Net/SMTP.pm                          Simple Mail Transfer Protocol Client
 lib/Net/Time.pm                          time & nettime protocols
 lib/Net/libnetFAQ.pod
+t/changes.t
 t/config.t
 t/critic.t
 t/datasend.t
-t/external/smtp-ssl.t
-t/external/pop3-ssl.t
 t/external/ftp-ssl.t
+t/external/pop3-ssl.t
+t/external/smtp-ssl.t
 t/ftp.t
 t/hostname.t
 t/libnet_t.pl
 t/netrc.t
 t/nntp.t
-t/nntp_ssl.t
 t/nntp_ipv6.t
+t/nntp_ssl.t
 t/pod.t
 t/pod_coverage.t
 t/require.t
 t/smtp.t
-t/smtp_ssl.t
 t/smtp_ipv6.t
-t/pop3_ssl.t
+t/smtp_ssl.t
 t/pop3_ipv6.t
+t/pop3_ssl.t
 t/time.t
diff --git a/Makefile.PL b/Makefile.PL
index fdfbc04..64d6959 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -7,11 +7,13 @@
 #   Makefile creation script.
 #
 # COPYRIGHT
-#   Copyright (C) 2014 Steve Hay.  All rights reserved.
+#   Copyright (C) 2014, 2015 Steve Hay.  All rights reserved.
 #
 # LICENCE
-#   You may distribute under the terms of either the GNU General Public License
-#   or the Artistic License, as specified in the LICENCE file.
+#   This script is free software; you can redistribute it and/or modify it under
+#   the same terms as Perl itself, i.e. under the terms of either the GNU
+#   General Public License or the Artistic License, as specified in the LICENCE
+#   file.
 #
 #===============================================================================
 
@@ -47,7 +49,7 @@ MAIN: {
     $prereq_pms{'Convert::EBCDIC'} = '0.06' if $^O eq 'os390';
 
     my $xt = 'n';
-    if (not running_under_cpan()) {
+    if (not running_under_cpan() and not $ENV{PERL_CORE}) {
         $xt = prompt("Should I do external tests?\n" .
                      "These tests will fail if there is no internet" .
                      " connection or if a firewall\n" .
@@ -64,7 +66,7 @@ MAIN: {
         ABSTRACT => 'Collection of network protocol modules',
         AUTHOR   => 'Graham Barr <gbarr@pobox.com>, Steve Hay <shay@cpan.org>',
         LICENSE  => 'perl_5',
-        VERSION  => '1.28',
+        VERSION  => '3.08',
 
         META_MERGE => {
             'meta-spec' => {
@@ -107,7 +109,7 @@ MAIN: {
                     prereqs => {
                         runtime => {
                             requires => {
-                                'IO::Socket::SSL' => '1.994'
+                                'IO::Socket::SSL' => '2.007'
                             }
                         }
                     }
@@ -125,6 +127,17 @@ MAIN: {
                     }
                 },
 
+                changestest => {
+                    description => 'Changes testing',
+                    prereqs => {
+                        test => {
+                            requires => {
+                                'Test::CPAN::Changes' => '0'
+                            }
+                        }
+                    }
+                },
+
                 critictest => {
                     description => 'Perl::Critic testing',
                     prereqs => {
@@ -165,7 +178,7 @@ MAIN: {
         CONFIGURE_REQUIRES => {
             'ExtUtils::MakeMaker' => '6.64',
             'Getopt::Std'         => '0',
-            'IO:File'             => '0',
+            'IO::File'            => '0',
             'perl'                => '5.008001',
             'strict'              => '0',
             'vars'                => '0',
@@ -173,7 +186,8 @@ MAIN: {
         },
 
         TEST_REQUIRES => {
-            'Cwd' => '0'
+            'Config' => '0',
+            'Cwd'    => '0'
         },
 
         PREREQ_PM => {
@@ -187,15 +201,16 @@ MAIN: {
             'IO::Select'     => '0',
             'IO::Socket'     => '1.05',
             'POSIX'          => '0',
-            'Socket'         => '1.3',
+            'Socket'         => '2.016',
             'Symbol'         => '0',
             'Time::Local'    => '0',
             'constant'       => '0',
             'strict'         => '0',
+            'utf8'           => '0',
             'vars'           => '0'
         },
 
-        INSTALLDIRS => 'perl',
+        INSTALLDIRS => ($] < 5.011 ? 'perl' : 'site'),
 
         realclean => {
             FILES => $CfgFile
diff --git a/README b/README
index e3183e7..d1bcf74 100644
--- a/README
+++ b/README
@@ -32,52 +32,11 @@ If you have a Git client, then you can checkout the latest code with
 
     git clone http://github.com/steve-m-hay/perl-libnet.git
 
-INSTALLATION
-
-In order to use this package you will need Perl version 5.8.1 or
-better.  You install libnet, as you would install any perl module
-library, by running these commands:
-
-   perl Makefile.PL
-   make
-   make test
-   make install
-
-If you want to install a private copy of libnet in your home
-directory, then you should try to produce the initial Makefile with
-something like this command:
-
-  perl Makefile.PL PREFIX=~/perl
-
-
-The Makefile.PL program will start out by checking your perl
-installation for a few packages that are recommended to be installed
-together with libnet.  These packages should be available on CPAN
-(described above).
-
-CONFIGURE
-
-Normally when Makefile.PL is run it will run Configure which will
-ask some questions about your system. The results of these questions
-will be stored in a file called libnet.cfg which will be installed
-alongside the other perl modules in this distribution. Makefile.PL
-will run Configure in an interactive mode unless these exists a file
-called libnet.cfg in the build directory or Makefile.PL itself is being
-run non-interactively or via cpan, cpanp or cpanm.
-
-If you are on a system which cannot run this script you can create an
-empty file to make Makefile.PL skip running Configure. If you want to
-keep your existing settings and not run interactivly then simply run
-
-  perl Configure -d
-
-before running Makefile.PL.
-
 DOCUMENTATION
 
-See ChangeLog for recent changes.  POD style documentation is included
+See Changes for recent changes.  POD style documentation is included
 in all modules and scripts.  These are normally converted to manual
-pages and installed as part of the "make install" process.  You should
+pages and installed as part of the installation process.  You should
 also be able to use the 'perldoc' utility to extract documentation from
 the module files directly.
 
@@ -94,9 +53,9 @@ SUPPORT
 
 Questions about how to use this library should be directed to the
 comp.lang.perl.modules USENET Newsgroup.  Bug reports and suggestions
-for improvements can be reported on the CPAN request tracker at
+for improvements can be reported on the CPAN Request Tracker at
 
-    http://rt.cpan.org/Dist/Display.html?Name=libnet
+    http://rt.cpan.org/Public/Bug//Report.html?Queue=libnet
 
 Most of the modules in this library have an option to output a debug
 transcript to STDERR. When reporting bugs/problems please, if possible,
@@ -108,7 +67,9 @@ COPYRIGHT
   Changes in Version 1.22_02 onwards Copyright (C) 2013-2014 Steve Hay.
   All rights reserved.
 
-This library is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
+This distribution is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself, i.e. under the terms of either the GNU
+General Public License or the Artistic License, as specified in the LICENCE
+file.
 
 Share and Enjoy!
diff --git a/demos/smtp.self b/demos/smtp.self
index 2929183..e34d585 100755
--- a/demos/smtp.self
+++ b/demos/smtp.self
@@ -43,9 +43,9 @@ Send the message to C<USERNAME>
 
 =cut
 
-my $opt_debug = undef;
-my $opt_user = undef;
-my $opt_help = undef;
+our $opt_debug = undef;
+our $opt_user = undef;
+our $opt_help = undef;
 GetOptions(qw(debug user=s help));
 exec("pod2text $0")
     if defined $opt_help;
diff --git a/lib/Net/Cmd.pm b/lib/Net/Cmd.pm
index 9bf9f4f..e9d0d25 100644
--- a/lib/Net/Cmd.pm
+++ b/lib/Net/Cmd.pm
@@ -2,10 +2,11 @@
 #
 # Versions up to 2.29_1 Copyright (c) 1995-2006 Graham Barr <gbarr@pobox.com>.
 # All rights reserved.
-# Changes in Version 2.29_2 onwards Copyright (C) 2013-2014 Steve Hay.  All
+# Changes in Version 2.29_2 onwards Copyright (C) 2013-2015 Steve Hay.  All
 # rights reserved.
-# This program is free software; you can redistribute it and/or
-# modify it under the same terms as Perl itself.
+# This module is free software; you can redistribute it and/or modify it under
+# the same terms as Perl itself, i.e. under the terms of either the GNU General
+# Public License or the Artistic License, as specified in the F<LICENCE> file.
 
 package Net::Cmd;
 
@@ -26,22 +27,7 @@ BEGIN {
   }
 }
 
-BEGIN {
-  if (!eval { require utf8 }) {
-    *is_utf8 = sub { 0 };
-  }
-  elsif (eval { utf8::is_utf8(undef); 1 }) {
-    *is_utf8 = \&utf8::is_utf8;
-  }
-  elsif (eval { require Encode; Encode::is_utf8(undef); 1 }) {
-    *is_utf8 = \&Encode::is_utf8;
-  }
-  else {
-    *is_utf8 = sub { $_[0] =~ /[^\x00-\xff]/ };
-  }
-}
-
-our $VERSION = "2.31";
+our $VERSION = "3.08";
 our @ISA     = qw(Exporter);
 our @EXPORT  = qw(CMD_INFO CMD_OK CMD_MORE CMD_REJECT CMD_ERROR CMD_PENDING);
 
@@ -52,6 +38,8 @@ use constant CMD_REJECT  => 4;
 use constant CMD_ERROR   => 5;
 use constant CMD_PENDING => 0;
 
+use constant DEF_REPLY_CODE => 421;
+
 my %debug = ();
 
 my $tr = $^O eq 'os390' ? Convert::EBCDIC->new() : undef;
@@ -171,7 +159,7 @@ sub code {
 
   my $cmd = shift;
 
-  ${*$cmd}{'net_cmd_code'} = "000"
+  ${*$cmd}{'net_cmd_code'} = $cmd->DEF_REPLY_CODE
     unless exists ${*$cmd}{'net_cmd_code'};
 
   ${*$cmd}{'net_cmd_code'};
@@ -193,7 +181,7 @@ sub set_status {
   my $cmd = shift;
   my ($code, $resp) = @_;
 
-  $resp = [$resp]
+  $resp = defined $resp ? [$resp] : []
     unless ref($resp);
 
   (${*$cmd}{'net_cmd_code'}, ${*$cmd}{'net_cmd_resp'}) = ($code, $resp);
@@ -202,14 +190,38 @@ sub set_status {
 }
 
 
-sub command {
+
+sub _set_status_timeout {
   my $cmd = shift;
+  my $pkg = ref($cmd) || $cmd;
 
-  unless (defined fileno($cmd)) {
-    $cmd->set_status("599", "Connection closed");
-    return $cmd;
+  $cmd->set_status($cmd->DEF_REPLY_CODE, "[$pkg] Timeout");
+  carp(ref($cmd) . ": " . (caller(1))[3] . "(): timeout") if $cmd->debug;
+}
+
+sub _set_status_closed {
+  my $cmd = shift;
+  my $pkg = ref($cmd) || $cmd;
+
+  $cmd->set_status($cmd->DEF_REPLY_CODE, "[$pkg] Connection closed");
+  carp(ref($cmd) . ": " . (caller(1))[3]
+    . "(): unexpected EOF on command channel: $!") if $cmd->debug;
+}
+
+sub _is_closed {
+  my $cmd = shift;
+  if (!defined fileno($cmd)) {
+     $cmd->_set_status_closed;
+     return 1;
   }
+  return 0;
+}
 
+sub command {
+  my $cmd = shift;
+
+  return $cmd
+    if $cmd->_is_closed;
 
   $cmd->dataend()
     if (exists ${*$cmd}{'net_cmd_last_ch'});
@@ -231,14 +243,14 @@ sub command {
     my $len = length $str;
     my $swlen;
 
-    $cmd->close
-      unless (defined($swlen = syswrite($cmd, $str, $len)) && $swlen == $len);
-
     $cmd->debug_print(1, $str)
       if ($cmd->debug);
 
-    ${*$cmd}{'net_cmd_resp'} = [];       # the response
-    ${*$cmd}{'net_cmd_code'} = "000";    # Made this one up :-)
+    unless (defined($swlen = syswrite($cmd,$str,$len)) && $swlen == $len) {
+      $cmd->close;
+      $cmd->_set_status_closed;
+      return $cmd;
+    }
   }
 
   $cmd;
@@ -256,8 +268,8 @@ sub ok {
 sub unsupported {
   my $cmd = shift;
 
-  ${*$cmd}{'net_cmd_resp'} = ['Unsupported command'];
-  ${*$cmd}{'net_cmd_code'} = 580;
+  $cmd->set_status(580, 'Unsupported command');
+
   0;
 }
 
@@ -271,11 +283,11 @@ sub getline {
     if scalar(@{${*$cmd}{'net_cmd_lines'}});
 
   my $partial = defined(${*$cmd}{'net_cmd_partial'}) ? ${*$cmd}{'net_cmd_partial'} : "";
-  my $fd      = fileno($cmd);
 
   return
-    unless defined $fd;
+    if $cmd->_is_closed;
 
+  my $fd = fileno($cmd);
   my $rin = "";
   vec($rin, $fd, 1) = 1;
 
@@ -288,9 +300,8 @@ sub getline {
     my $select_ret = select($rout = $rin, undef, undef, $timeout);
     if ($select_ret > 0) {
       unless (sysread($cmd, $buf = "", 1024)) {
-        carp(ref($cmd) . ": Unexpected EOF on command channel")
-          if $cmd->debug;
         $cmd->close;
+        $cmd->_set_status_closed;
         return;
       }
 
@@ -304,8 +315,7 @@ sub getline {
 
     }
     else {
-      my $msg = $select_ret ? "Error or Interrupted: $!" : "Timeout";
-      carp("$cmd: $msg") if ($cmd->debug);
+      $cmd->_set_status_timeout;
       return;
     }
   }
@@ -341,7 +351,7 @@ sub response {
   my $cmd = shift;
   my ($code, $more) = (undef) x 2;
 
-  ${*$cmd}{'net_cmd_resp'} ||= [];
+  $cmd->set_status($cmd->DEF_REPLY_CODE, undef); # initialize the response
 
   while (1) {
     my $str = $cmd->getline();
@@ -354,9 +364,10 @@ sub response {
 
     ($code, $more) = $cmd->parse_response($str);
     unless (defined $code) {
+      carp("$cmd: response(): parse error in '$str'") if ($cmd->debug);
       $cmd->ungetline($str);
       $@ = $str;   # $@ used as tunneling hack
-      last;
+      return CMD_ERROR;
     }
 
     ${*$cmd}{'net_cmd_code'} = $code;
@@ -403,11 +414,20 @@ sub datasend {
   my $arr  = @_ == 1 && ref($_[0]) ? $_[0] : \@_;
   my $line = join("", @$arr);
 
-  # encode to individual utf8 bytes if
-  # $line is a string (in internal UTF-8)
-  utf8::encode($line) if is_utf8($line);
-
-  return 0 unless defined(fileno($cmd));
+  # Perls < 5.10.1 (with the exception of 5.8.9) have a performance problem with
+  # the substitutions below when dealing with strings stored internally in
+  # UTF-8, so downgrade them (if possible).
+  # Data passed to datasend() should be encoded to octets upstream already so
+  # shouldn't even have the UTF-8 flag on to start with, but if it so happens
+  # that the octets are stored in an upgraded string (as can sometimes occur)
+  # then they would still downgrade without fail anyway.
+  # Only Unicode codepoints > 0xFF stored in an upgraded string will fail to
+  # downgrade. We fail silently in that case, and a "Wide character in print"
+  # warning will be emitted later by syswrite().
+  utf8::downgrade($line, 1) if $] < 5.010001 && $] != 5.008009;
+
+  return 0
+    if $cmd->_is_closed;
 
   my $last_ch = ${*$cmd}{'net_cmd_last_ch'};
 
@@ -457,15 +477,16 @@ sub datasend {
     if ((defined $s and $s > 0) or -f $cmd)    # -f for testing on win32
     {
       my $w = syswrite($cmd, $line, $len, $offset);
-      unless (defined($w)) {
-        carp("$cmd: $!") if $cmd->debug;
+      unless (defined($w) && $w == $len) {
+        $cmd->close;
+        $cmd->_set_status_closed;
         return;
       }
       $len -= $w;
       $offset += $w;
     }
     else {
-      carp("$cmd: Timeout") if ($cmd->debug);
+      $cmd->_set_status_timeout;
       return;
     }
   }
@@ -479,7 +500,8 @@ sub rawdatasend {
   my $arr  = @_ == 1 && ref($_[0]) ? $_[0] : \@_;
   my $line = join("", @$arr);
 
-  return 0 unless defined(fileno($cmd));
+  return 0
+    if $cmd->_is_closed;
 
   return 1
     unless length($line);
@@ -500,15 +522,16 @@ sub rawdatasend {
     my $wout;
     if (select(undef, $wout = $win, undef, $timeout) > 0) {
       my $w = syswrite($cmd, $line, $len, $offset);
-      unless (defined($w)) {
-        carp("$cmd: $!") if $cmd->debug;
+      unless (defined($w) && $w == $len) {
+        $cmd->close;
+        $cmd->_set_status_closed;
         return;
       }
       $len -= $w;
       $offset += $w;
     }
     else {
-      carp("$cmd: Timeout") if ($cmd->debug);
+      $cmd->_set_status_timeout;
       return;
     }
   }
@@ -520,7 +543,8 @@ sub rawdatasend {
 sub dataend {
   my $cmd = shift;
 
-  return 0 unless defined(fileno($cmd));
+  return 0
+    if $cmd->_is_closed;
 
   my $ch = ${*$cmd}{'net_cmd_last_ch'};
   my $tosend;
@@ -539,7 +563,14 @@ sub dataend {
   $cmd->debug_print(1, ".\n")
     if ($cmd->debug);
 
-  syswrite($cmd, $tosend, length $tosend);
+  my $len = length $tosend;
+  my $w = syswrite($cmd, $tosend, $len);
+  unless (defined($w) && $w == $len)
+  {
+    $cmd->close;
+    $cmd->_set_status_closed;
+    return 0;
+  }
 
   delete ${*$cmd}{'net_cmd_last_ch'};
 
@@ -661,12 +692,12 @@ debug level for a given class.
 
 Returns the text message returned from the last command. In a scalar
 context it returns a single string, in a list context it will return
-each line as a separate element
+each line as a separate element. (See L<PSEUDO RESPONSES> below.)
 
 =item code ()
 
 Returns the 3-digit code from the last command. If a command is pending
-then the value 0 is returned
+then the value 0 is returned. (See L<PSEUDO RESPONSES> below.)
 
 =item ok ()
 
@@ -684,6 +715,8 @@ is pending then C<CMD_PENDING> is returned.
 Send data to the remote server, converting LF to CRLF. Any line starting
 with a '.' will be prefixed with another '.'.
 C<DATA> may be an array or a reference to an array.
+The C<DATA> passed in must be encoded by the caller to octets of whatever
+encoding is required, e.g. by using the Encode module's C<encode()> function.
 
 =item dataend ()
 
@@ -707,21 +740,21 @@ Print debugging information. C<DIR> denotes the direction I<true> being
 data being sent to the server. Calls C<debug_text> before printing to
 STDERR.
 
-=item debug_text ( TEXT )
+=item debug_text ( DIR, TEXT )
 
 This method is called to print debugging information. TEXT is
-the text being sent. The method should return the text to be printed
+the text being sent. The method should return the text to be printed.
 
 This is primarily meant for the use of modules such as FTP where passwords
 are sent, but we do not want to display them in the debugging information.
 
 =item command ( CMD [, ARGS, ... ])
 
-Send a command to the command server. All arguments a first joined with
+Send a command to the command server. All arguments are first joined with
 a space character and CRLF is appended, this string is then sent to the
 command server.
 
-Returns undef upon failure
+Returns undef upon failure.
 
 =item unsupported ()
 
@@ -731,14 +764,14 @@ Returns zero.
 =item response ()
 
 Obtain a response from the server. Upon success the most significant digit
-of the status code is returned. Upon failure, timeout etc., I<undef> is
+of the status code is returned. Upon failure, timeout etc., I<CMD_ERROR> is
 returned.
 
 =item parse_response ( TEXT )
 
 This method is called by C<response> as a method with one argument. It should
 return an array of 2 values, the 3-digit status code and a flag which is true
-when this is part of a multi-line response and this line is not the list.
+when this is part of a multi-line response and this line is not the last.
 
 =item getline ()
 
@@ -756,6 +789,9 @@ Unget a line of text from the server.
 
 Send data to the remote server without performing any conversions. C<DATA>
 is a scalar.
+As with C<datasend()>, the C<DATA> passed in must be encoded by the caller
+to octets of whatever encoding is required, e.g. by using the Encode module's
+C<encode()> function.
 
 =item read_until_dot ()
 
@@ -776,6 +812,44 @@ See the Net::POP3 and Net::SMTP modules for examples of this.
 
 =back
 
+=head1 PSEUDO RESPONSES
+
+Normally the values returned by C<message()> and C<code()> are
+obtained from the remote server, but in a few circumstances, as
+detailed below, C<Net::Cmd> will return values that it sets. You
+can alter this behavior by overriding DEF_REPLY_CODE() to specify
+a different default reply code, or overriding one of the specific
+error handling methods below.
+
+=over 4
+
+=item Initial value
+
+Before any command has executed or if an unexpected error occurs
+C<code()> will return "421" (temporary connection failure) and
+C<message()> will return undef.
+
+=item Connection closed
+
+If the underlying C<IO::Handle> is closed, or if there are
+any read or write failures, the file handle will be forced closed,
+and C<code()> will return "421" (temporary connection failure)
+and C<message()> will return "[$pkg] Connection closed"
+(where $pkg is the name of the class that subclassed C<Net::Cmd>).
+The _set_status_closed() method can be overridden to set a different
+message (by calling set_status()) or otherwise trap this error.
+
+=item Timeout
+
+If there is a read or write timeout C<code()> will return "421"
+(temporary connection failure) and C<message()> will return
+"[$pkg] Timeout" (where $pkg is the name of the class
+that subclassed C<Net::Cmd>). The _set_status_timeout() method
+can be overridden to set a different message (by calling set_status())
+or otherwise trap this error.
+
+=back
+
 =head1 EXPORTS
 
 C<Net::Cmd> exports six subroutines, five of these, C<CMD_INFO>, C<CMD_OK>,
@@ -795,7 +869,8 @@ Versions up to 2.29_1 Copyright (c) 1995-2006 Graham Barr. All rights reserved.
 Changes in Version 2.29_2 onwards Copyright (C) 2013-2014 Steve Hay.  All rights
 reserved.
 
-This program is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
+This module is free software; you can redistribute it and/or modify it under the
+same terms as Perl itself, i.e. under the terms of either the GNU General Public
+License or the Artistic License, as specified in the F<LICENCE> file.
 
 =cut
diff --git a/lib/Net/Config.pm b/lib/Net/Config.pm
index 18da9d1..3aa547e 100644
--- a/lib/Net/Config.pm
+++ b/lib/Net/Config.pm
@@ -4,8 +4,9 @@
 # All rights reserved.
 # Changes in Version 1.11_01 onwards Copyright (C) 2013-2014 Steve Hay.  All
 # rights reserved.
-# This program is free software; you can redistribute it and/or
-# modify it under the same terms as Perl itself.
+# This module is free software; you can redistribute it and/or modify it under
+# the same terms as Perl itself, i.e. under the terms of either the GNU General
+# Public License or the Artistic License, as specified in the F<LICENCE> file.
 
 package Net::Config;
 
@@ -19,7 +20,7 @@ use Socket qw(inet_aton inet_ntoa);
 
 our @EXPORT  = qw(%NetConfig);
 our @ISA     = qw(Net::LocalCfg Exporter);
-our $VERSION = "1.15";
+our $VERSION = "3.08";
 
 our($CONFIGURE, $LIBNET_CFG);
 
@@ -133,7 +134,7 @@ __END__
 
 Net::Config - Local configuration data for libnet
 
-=head1 SYNOPSYS
+=head1 SYNOPSIS
 
     use Net::Config qw(%NetConfig);
 
@@ -319,4 +320,21 @@ If true then C<Configure> will check each hostname given that it exists
 
 =back
 
+=head1 AUTHOR
+
+Graham Barr E<lt>F<gbarr@pobox.com>E<gt>
+
+Steve Hay E<lt>F<shay@cpan.org>E<gt> is now maintaining libnet as of version
+1.22_02
+
+=head1 COPYRIGHT
+
+Versions up to 1.11 Copyright (c) 1998-2011 Graham Barr. All rights reserved.
+Changes in Version 1.11_01 onwards Copyright (C) 2013-2014 Steve Hay.  All
+rights reserved.
+
+This module is free software; you can redistribute it and/or modify it under the
+same terms as Perl itself, i.e. under the terms of either the GNU General Public
+License or the Artistic License, as specified in the F<LICENCE> file.
+
 =cut
diff --git a/lib/Net/Domain.pm b/lib/Net/Domain.pm
index b7a887d..e2be3b1 100644
--- a/lib/Net/Domain.pm
+++ b/lib/Net/Domain.pm
@@ -4,8 +4,9 @@
 # All rights reserved.
 # Changes in Version 2.22 onwards Copyright (C) 2013-2014 Steve Hay.  All rights
 # reserved.
-# This program is free software; you can redistribute it and/or
-# modify it under the same terms as Perl itself.
+# This module is free software; you can redistribute it and/or modify it under
+# the same terms as Perl itself, i.e. under the terms of either the GNU General
+# Public License or the Artistic License, as specified in the F<LICENCE> file.
 
 package Net::Domain;
 
@@ -20,7 +21,7 @@ use Net::Config;
 
 our @ISA       = qw(Exporter);
 our @EXPORT_OK = qw(hostname hostdomain hostfqdn domainname);
-our $VERSION = "2.24";
+our $VERSION = "3.08";
 
 my ($host, $domain, $fqdn) = (undef, undef, undef);
 
@@ -43,7 +44,7 @@ sub _hostname {
     }
     if (defined($host) && index($host, '.') > 0) {
       $fqdn = $host;
-      ($host, $domain) = $fqdn =~ /^([^\.]+)\.(.*)$/;
+      ($host, $domain) = $fqdn =~ /^([^.]+)\.(.*)$/;
     }
     return $host;
   }
@@ -55,7 +56,7 @@ sub _hostname {
     $host = $ENV{'MULTINET_HOST_NAME'} if defined($ENV{'MULTINET_HOST_NAME'});
     if (index($host, '.') > 0) {
       $fqdn = $host;
-      ($host, $domain) = $fqdn =~ /^([^\.]+)\.(.*)$/;
+      ($host, $domain) = $fqdn =~ /^([^.]+)\.(.*)$/;
     }
     return $host;
   }
@@ -98,7 +99,7 @@ sub _hostname {
       }
 
       # Apollo pre-SR10
-      || eval { $host = (split(/[:\. ]/, `/com/host`, 6))[0]; }
+      || eval { $host = (split(/[:. ]/, `/com/host`, 6))[0]; }
 
       || eval { $host = ""; };
   }
@@ -198,7 +199,7 @@ sub _hostdomain {
 
         # Extract domain from FQDN
 
-        ($domain = $site) =~ s/\A[^\.]+\.//;
+        ($domain = $site) =~ s/\A[^.]+\.//;
         return $domain;
       }
     }
@@ -356,7 +357,8 @@ Versions up to 2.21 Copyright (c) 1995-1998 Graham Barr. All rights reserved.
 Changes in Version 2.22 onwards Copyright (C) 2013-2014 Steve Hay.  All rights
 reserved.
 
-This program is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
+This module is free software; you can redistribute it and/or modify it under the
+same terms as Perl itself, i.e. under the terms of either the GNU General Public
+License or the Artistic License, as specified in the F<LICENCE> file.
 
 =cut
diff --git a/lib/Net/FTP.pm b/lib/Net/FTP.pm
index 2ad11ed..eb56e1a 100644
--- a/lib/Net/FTP.pm
+++ b/lib/Net/FTP.pm
@@ -2,10 +2,11 @@
 #
 # Versions up to 2.77_2 Copyright (c) 1995-2004 Graham Barr <gbarr@pobox.com>.
 # All rights reserved.
-# Changes in Version 2.77_3 onwards Copyright (C) 2013-2014 Steve Hay.  All
+# Changes in Version 2.77_3 onwards Copyright (C) 2013-2015 Steve Hay.  All
 # rights reserved.
-# This program is free software; you can redistribute it and/or
-# modify it under the same terms as Perl itself.
+# This module is free software; you can redistribute it and/or modify it under
+# the same terms as Perl itself, i.e. under the terms of either the GNU General
+# Public License or the Artistic License, as specified in the F<LICENCE> file.
 #
 # Documentation (at end) improved 1996 by Nathan Torkington <gnat@frii.com>.
 
@@ -21,29 +22,33 @@ use Fcntl qw(O_WRONLY O_RDONLY O_APPEND O_CREAT O_TRUNC);
 use IO::Socket;
 use Net::Cmd;
 use Net::Config;
-use Socket 1.3;
+use Socket;
 use Time::Local;
 
-our $VERSION = '2.80';
+our $VERSION = '3.08';
 
 our $IOCLASS;
+my $family_key;
 BEGIN {
   # Code for detecting if we can use SSL
   my $ssl_class = eval {
     require IO::Socket::SSL;
     # first version with default CA on most platforms
-    IO::Socket::SSL->VERSION(1.994);
+    no warnings 'numeric';
+    IO::Socket::SSL->VERSION(2.007);
   } && 'IO::Socket::SSL';
 
   my $nossl_warn = !$ssl_class &&
-    'To use SSL please install IO::Socket::SSL with version>=1.994';
+    'To use SSL please install IO::Socket::SSL with version>=2.007';
 
   # Code for detecting if we can use IPv6
   my $inet6_class = eval {
     require IO::Socket::IP;
+    no warnings 'numeric';
     IO::Socket::IP->VERSION(0.20);
   } && 'IO::Socket::IP' || eval {
     require IO::Socket::INET6;
+    no warnings 'numeric';
     IO::Socket::INET6->VERSION(2.62);
   } && 'IO::Socket::INET6';
 
@@ -51,6 +56,10 @@ BEGIN {
   sub can_inet6 { $inet6_class };
 
   $IOCLASS = $ssl_class || $inet6_class || 'IO::Socket::INET';
+  $family_key =
+    ( $ssl_class ? $ssl_class->can_ipv6 : $inet6_class || '' )
+      eq 'IO::Socket::IP'
+      ? 'Family' : 'Domain';
 }
 
 our @ISA = ('Exporter','Net::Cmd',$IOCLASS);
@@ -100,20 +109,23 @@ sub new {
     %tlsargs = (
       SSL_verifycn_scheme => 'ftp',
       SSL_verifycn_name => $hostname,
+      # use SNI if supported by IO::Socket::SSL
+      $pkg->can_client_sni ? (SSL_hostname => $hostname):(),
       # reuse SSL session of control connection in data connections
-      SSL_session_cache => Net::FTP::SSL_SingleSessionCache->new,
+      SSL_session_cache => Net::FTP::_SSL_SingleSessionCache->new,
     );
     # user defined SSL arg
     $tlsargs{$_} = $arg{$_} for(grep { m{^SSL_} } keys %arg);
 
   } elsif ($arg{SSL}) {
-    croak("IO::Socket::SSL >= 1.944 needed for SSL support");
+    croak("IO::Socket::SSL >= 2.007 needed for SSL support");
   }
 
   my $ftp = $pkg->SUPER::new(
     PeerAddr  => $peer,
     PeerPort  => $arg{Port} || ($arg{SSL} ? 'ftps(990)' : 'ftp(21)'),
     LocalAddr => $arg{'LocalAddr'},
+    $family_key => $arg{Domain} || $arg{Family},
     Proto     => 'tcp',
     Timeout   => defined $arg{Timeout} ? $arg{Timeout} : 120,
     %tlsargs,
@@ -125,6 +137,7 @@ sub new {
   ${*$ftp}{'net_ftp_blksize'} = abs($arg{'BlockSize'} || 10240);
 
   ${*$ftp}{'net_ftp_localaddr'} = $arg{'LocalAddr'};
+  ${*$ftp}{'net_ftp_domain'} = $arg{Domain} || $arg{Family};
 
   ${*$ftp}{'net_ftp_firewall'} = $fire
     if (defined $fire);
@@ -287,7 +300,7 @@ sub size {
 
 sub starttls {
   my $ftp = shift;
-  can_ssl() or croak("IO::Socket::SSL >= 1.944 needed for SSL support");
+  can_ssl() or croak("IO::Socket::SSL >= 2.007 needed for SSL support");
   $ftp->is_SSL and croak("called starttls within SSL session");
   $ftp->_AUTH('TLS') == CMD_OK or return;
 
@@ -447,7 +460,7 @@ sub authorize {
 
   my $ok = $ftp->_AUTH($auth || "");
 
-  $ok = $ftp->_RESP($resp || "")
+  return $ftp->_RESP($resp || "")
     if ($ok == CMD_MORE);
 
   $ok == CMD_OK;
@@ -490,7 +503,7 @@ sub alloc {
     unless (defined $size);
 
   return
-    unless ($ftp->_ALLO($size, @_));
+    unless ($ftp->supported("ALLO") and $ftp->_ALLO($size, @_));
 
   ${*$ftp}{'net_ftp_allo'} = join(" ", $size, @_);
 
@@ -656,8 +669,12 @@ sub rmdir {
     or !$recurse;
 
   # Try to delete the contents
-  # Get a list of all the files in the directory
-  my @filelist = grep { !/^\.{1,2}$/ } $ftp->ls($dir);
+  # Get a list of all the files in the directory, excluding the current and parent directories
+  my @filelist = map { /^(?:\S+;)+ (.+)$/ ? ($1) : () } grep { !/^(?:\S+;)*type=[cp]dir;/ } $ftp->_list_cmd("MLSD", $dir);
+
+  # Fallback to using the less well-defined NLST command if MLSD fails
+  @filelist = grep { !/^\.{1,2}$/ } $ftp->ls($dir)
+    unless @filelist;
 
   return
     unless @filelist;    # failed, it is probably not a directory
@@ -883,9 +900,10 @@ sub _eprt {
       Listen    => 1,
       Timeout   => $ftp->timeout,
       LocalAddr => $ftp->sockhost,
+      $family_key  => $ftp->sockdomain,
       can_ssl() ? (
-        %{ ${*$ftp}{net_ftp_tlsargs} },
-        SSL_startHandshake => 0,
+        %{ ${*$ftp}{net_ftp_tlsargs} },
+        SSL_startHandshake => 0,
       ):(),
     );
     ${*$ftp}{net_ftp_intern_port} = 1;
@@ -897,6 +915,8 @@ sub _eprt {
       my $p = $listen->sockport;
       $port = join(',',split(m{\.},$listen->sockhost),$p >> 8,$p & 0xff);
     }
+  } elsif (ref($port) eq 'ARRAY') {
+    $port = join(',',split(m{\.},@$port[0]),@$port[1] >> 8,@$port[1] & 0xff);
   }
   my $ok = $cmd eq 'EPRT' ? $ftp->_EPRT($port) : $ftp->_PORT($port);
   ${*$ftp}{net_ftp_port} = $port if $ok;
@@ -956,7 +976,7 @@ sub supported {
     unless $ftp->_HELP($cmd);
 
   my $text = $ftp->message;
-  if ($text =~ /following\s+commands/i) {
+  if ($text =~ /following.+commands/i) {
     $text =~ s/^.*\n//;
     while ($text =~ /(\*?)(\w+)(\*?)/sg) {
       $hash->{"\U$2"} = !length("$1$3");
@@ -1027,13 +1047,18 @@ sub _dataconn {
       PeerAddr  => $pasv->[0],
       PeerPort  => $pasv->[1],
       LocalAddr => ${*$ftp}{net_ftp_localaddr},
+      $family_key => ${*$ftp}{net_ftp_domain},
       Timeout   => $ftp->timeout,
       can_ssl() ? (
-        SSL_startHandshake => 0,
-        $ftp->is_SSL ? (
-          SSL_reuse_ctx => $ftp,
-          SSL_verifycn_name => ${*$ftp}{net_ftp_tlsargs}{SSL_verifycn_name},
-        ) :( %{${*$ftp}{net_ftp_tlsargs}} ),
+        SSL_startHandshake => 0,
+        $ftp->is_SSL ? (
+          SSL_reuse_ctx => $ftp,
+          SSL_verifycn_name => ${*$ftp}{net_ftp_tlsargs}{SSL_verifycn_name},
+          # This will cause the use of SNI if supported by IO::Socket::SSL.
+          $ftp->can_client_sni ? (
+            SSL_hostname  => ${*$ftp}{net_ftp_tlsargs}{SSL_hostname}
+          ):(),
+        ) :( %{${*$ftp}{net_ftp_tlsargs}} ),
       ):(),
     ) or return;
   } elsif (my $listen =  delete ${*$ftp}{net_ftp_listen}) {
@@ -1130,7 +1155,7 @@ sub _data_cmd {
     my $data = $ftp->_dataconn();
     if (CMD_INFO == $ftp->response()) {
       $data->reading
-        if $data && $cmd =~ /RETR|LIST|NLST/;
+        if $data && $cmd =~ /RETR|LIST|NLST|MLSD/;
       return $data;
     }
     $data->_close if $data;
@@ -1148,7 +1173,9 @@ sub _data_cmd {
   return
     unless $ok;
 
-  if ($cmd =~ /(STOR|APPE|STOU)/ and exists ${*$ftp}{net_ftp_allo}) {
+  if ($cmd =~ /(STOR|APPE|STOU)/ and exists ${*$ftp}{net_ftp_allo} and
+      $ftp->supported("ALLO"))
+  {
     $ftp->_ALLO(delete ${*$ftp}{net_ftp_allo})
       or return;
   }
@@ -1167,7 +1194,7 @@ sub _data_cmd {
     my $data = $ftp->_dataconn();
 
     $data->reading
-      if $data && $cmd =~ /RETR|LIST|NLST/;
+      if $data && $cmd =~ /RETR|LIST|NLST|MLSD/;
 
     return $data;
   }
@@ -1375,7 +1402,7 @@ sub _REIN { shift->unsupported(@_) }
 {
   # Session Cache with single entry
   # used to make sure that we reuse same session for control and data channels
-  package Net::FTP::SSL_SingleSessionCache;
+  package Net::FTP::_SSL_SingleSessionCache;
   sub new { my $x; return bless \$x,shift }
   sub add_session {
     my ($cache,$key,$session) = @_;
@@ -1421,10 +1448,15 @@ Net::FTP - FTP Client class
 =head1 DESCRIPTION
 
 C<Net::FTP> is a class implementing a simple FTP client in Perl as
-described in RFC959.  It provides wrappers for a subset of the RFC959
-commands.
+described in RFC959.  It provides wrappers for the commonly used subset of the
+RFC959 commands.
+If L<IO::Socket::IP> or L<IO::Socket::INET6> is installed it also provides
+support for IPv6 as defined in RFC2428.
+And with L<IO::Socket::SSL> installed it provides support for implicit FTPS
+and explicit FTPS as defined in RFC4217.
 
-The Net::FTP class is a subclass of Net::Cmd and IO::Socket::INET.
+The Net::FTP class is a subclass of Net::Cmd and (depending on avaibility) of
+IO::Socket::IP, IO::Socket::INET6 or IO::Socket::INET.
 
 =head1 OVERVIEW
 
@@ -1525,8 +1557,15 @@ simply invokes the C<hash()> method for you, so that hash marks
 are displayed for all transfers.  You can, of course, call C<hash()>
 explicitly whenever you'd like.
 
-B<LocalAddr> - Local address to use for all socket connections, this
-argument will be passed to L<IO::Socket::INET>
+B<LocalAddr> - Local address to use for all socket connections. This
+argument will be passed to the super class, i.e. L<IO::Socket::INET>
+or L<IO::Socket::IP>.
+
+B<Domain> - Domain to use, i.e. AF_INET or AF_INET6. This
+argument will be passed to the IO::Socket super class.
+This can be used to enforce IPv4 even with L<IO::Socket::IP>
+which would default to IPv6.
+B<Family> is accepted as alternative name for B<Domain>.
 
 If the constructor fails undef will be returned and an error message will
 be in $@
@@ -1578,8 +1617,8 @@ Only C<LEVEL>s "C" (clear) and "P" (private) are supported.
 
 =item host ()
 
-Returns the value used by the constructor, and passed to IO::Socket::INET,
-to connect to the host.
+Returns the value used by the constructor, and passed to the IO::Socket super
+class to connect to the host.
 
 =item account( ACCT )
 
@@ -1826,6 +1865,7 @@ C<put_unique> and those that do not require data connections.
 =over 4
 
 =item port ( [ PORT ] )
+
 =item eprt ( [ PORT ] )
 
 Send a C<PORT> (IPv4) or C<EPRT> (IPv6) command to the server. If C<PORT> is
@@ -1833,6 +1873,7 @@ specified then it is sent to the server. If not, then a listen socket is created
 and the correct information sent to the server.
 
 =item pasv ()
+
 =item epsv ()
 
 Tell the server to go into passive mode (C<pasv> for IPv4, C<epsv> for IPv6).
@@ -1998,10 +2039,11 @@ Roderick Schertler <roderick@gate.net> - for various inputs
 =head1 COPYRIGHT
 
 Versions up to 2.77_2 Copyright (c) 1995-2004 Graham Barr. All rights reserved.
-Changes in Version 2.77_3 onwards Copyright (C) 2013-2014 Steve Hay.  All rights
+Changes in Version 2.77_3 onwards Copyright (C) 2013-2015 Steve Hay.  All rights
 reserved.
 
-This program is free software; you can redistribute it and/or modify it
-under the same terms as Perl itself.
+This module is free software; you can redistribute it and/or modify it under the
+same terms as Perl itself, i.e. under the terms of either the GNU General Public
+License or the Artistic License, as specified in the F<LICENCE> file.
 
 =cut
diff --git a/lib/Net/FTP/A.pm b/lib/Net/FTP/A.pm
index 4c99019..a1ae30b 100644
--- a/lib/Net/FTP/A.pm
+++ b/lib/Net/FTP/A.pm
@@ -13,7 +13,7 @@ use Carp;
 use Net::FTP::dataconn;
 
 our @ISA     = qw(Net::FTP::dataconn);
-our $VERSION = "1.20";
+our $VERSION = "3.08";
 
 our $buf;
 
diff --git a/lib/Net/FTP/E.pm b/lib/Net/FTP/E.pm
index dd96e3b..cf09d90 100644
--- a/lib/Net/FTP/E.pm
+++ b/lib/Net/FTP/E.pm
@@ -8,6 +8,6 @@ use warnings;
 use Net::FTP::I;
 
 our @ISA = qw(Net::FTP::I);
-our $VERSION = "0.02";
+our $VERSION = "3.08";
 
 1;
diff --git a/lib/Net/FTP/I.pm b/lib/Net/FTP/I.pm
index 0145ed2..b014f08 100644
--- a/lib/Net/FTP/I.pm
+++ b/lib/Net/FTP/I.pm
@@ -13,7 +13,7 @@ use Carp;
 use Net::FTP::dataconn;
 
 our @ISA     = qw(Net::FTP::dataconn);
-our $VERSION = "1.13";
+our $VERSION = "3.08";
 
 our $buf;
 
diff --git a/lib/Net/FTP/L.pm b/lib/Net/FTP/L.pm
index b0858e0..d13efe7 100644
--- a/lib/Net/FTP/L.pm
+++ b/lib/Net/FTP/L.pm
@@ -8,6 +8,6 @@ use warnings;
 use Net::FTP::I;
 
 our @ISA = qw(Net::FTP::I);
-our $VERSION = "0.02";
+our $VERSION = "3.08";
 
 1;
diff --git a/lib/Net/FTP/dataconn.pm b/lib/Net/FTP/dataconn.pm
index c9c3c14..8d82030 100644
--- a/lib/Net/FTP/dataconn.pm
+++ b/lib/Net/FTP/dataconn.pm
@@ -13,7 +13,7 @@ use Carp;
 use Errno;
 use Net::Cmd;
 
-our $VERSION = '0.13';
+our $VERSION = '3.08';
 
 $Net::FTP::IOCLASS or die "please load Net::FTP before Net::FTP::dataconn";
 our @ISA = $Net::FTP::IOCLASS;
diff --git a/lib/Net/NNTP.pm b/lib/Net/NNTP.pm
index a8fac38..0d690de 100644
--- a/lib/Net/NNTP.pm
+++ b/lib/Net/NNTP.pm
@@ -2,10 +2,11 @@
 #
 # Versions up to 2.24_1 Copyright (c) 1995-1997 Graham Barr <gbarr@pobox.com>.
 # All rights reserved.
-# Changes in Version 2.25 onwards Copyright (C) 2013-2014 Steve Hay.  All rights
+# Changes in Version 2.25 onwards Copyright (C) 2013-2015 Steve Hay.  All rights
 # reserved.
-# This program is free software; you can redistribute it and/or
-# modify it under the same terms as Perl itself.
+# This module is free software; you can redistribute it and/or modify it under
+# the same terms as Perl itself, i.e. under the terms of either the GNU General
+# Public License or the Artistic License, as specified in the F<LICENCE> file.
 
 package Net::NNTP;
 
@@ -20,31 +21,37 @@ use Net::Cmd;
 use Net::Config;
 use Time::Local;
 
-our $VERSION = "2.27";
+our $VERSION = "3.08";
 
 # Code for detecting if we can use SSL
 my $ssl_class = eval {
   require IO::Socket::SSL;
   # first version with default CA on most platforms
-  IO::Socket::SSL->VERSION(1.994);
+  no warnings 'numeric';
+  IO::Socket::SSL->VERSION(2.007);
 } && 'IO::Socket::SSL';
 
 my $nossl_warn = !$ssl_class &&
-  'To use SSL please install IO::Socket::SSL with version>=1.994';
+  'To use SSL please install IO::Socket::SSL with version>=2.007';
 
 # Code for detecting if we can use IPv6
+my $family_key = 'Domain';
 my $inet6_class = eval {
   require IO::Socket::IP;
-  IO::Socket::IP->VERSION(0.20);
+  no warnings 'numeric';
+  IO::Socket::IP->VERSION(0.20) || die;
+  $family_key = 'Family';
 } && 'IO::Socket::IP' || eval {
   require IO::Socket::INET6;
+  no warnings 'numeric';
   IO::Socket::INET6->VERSION(2.62);
 } && 'IO::Socket::INET6';
 
+
 sub can_ssl   { $ssl_class };
 sub can_inet6 { $inet6_class };
 
-our @ISA = ('Net::Cmd', $ssl_class || $inet6_class || 'IO::Socket::INET');
+our @ISA = ('Net::Cmd', $inet6_class || 'IO::Socket::INET');
 
 
 sub new {
@@ -70,37 +77,33 @@ sub new {
 
   my %connect = ( Proto => 'tcp');
 
-  if ($ssl_class) {
-    $connect{SSL_verifycn_scheme} = 'nntp';
+  if ($arg{SSL}) {
+    # SSL from start
+    die $nossl_warn if ! $ssl_class;
+    $arg{Port} ||= 563;
     $connect{$_} = $arg{$_} for(grep { m{^SSL_} } keys %arg);
-    if ($arg{SSL}) {
-      # SSL from start
-      $arg{Port} ||= 563;
-    } else {
-      # upgrade later with STARTTLS
-      $connect{SSL_startHandshake} = 0;
-    }
-  } elsif ($arg{SSL}) {
-    die $nossl_warn;
   }
 
-  foreach my $o (qw(LocalAddr Timeout)) {
+  foreach my $o (qw(LocalAddr LocalPort Timeout)) {
     $connect{$o} = $arg{$o} if exists $arg{$o};
   }
+  $connect{$family_key} = $arg{Domain} || $arg{Family};
   $connect{Timeout} = 120 unless defined $connect{Timeout};
   $connect{PeerPort} = $arg{Port} || 'nntp(119)';
   foreach my $h (@{$hosts}) {
     $connect{PeerAddr} = $h;
-    $connect{SSL_verifycn_name} = $arg{SSL_verifycn_name} || $h if $ssl_class;
-    $obj = $type->SUPER::new(%connect)
-      and last;
+    $obj = $type->SUPER::new(%connect) or next;
+    ${*$obj}{'net_nntp_host'} = $h;
+    ${*$obj}{'net_nntp_arg'} = \%arg;
+    if ($arg{SSL}) {
+      Net::NNTP::_SSL->start_SSL($obj,%arg) or next;
+    }
+    last:
   }
 
   return
     unless defined $obj;
 
-  ${*$obj}{'net_nntp_host'} = $connect{PeerAddr};
-
   $obj->autoflush(1);
   $obj->debug(exists $arg{Debug} ? $arg{Debug} : undef);
 
@@ -165,9 +168,12 @@ sub postok {
 sub starttls {
   my $self = shift;
   $ssl_class or die $nossl_warn;
-  $self->is_SSL and croak("NNTP connection is already in SSL mode");
   $self->_STARTTLS or return;
-  $self->connect_SSL;
+  Net::NNTP::_SSL->start_SSL($self,
+    %{ ${*$self}{'net_nntp_arg'} }, # (ssl) args given in new
+    @_   # more (ssl) args
+  ) or return;
+  return 1;
 }
 
 
@@ -747,6 +753,28 @@ sub DESTROY {
   defined(fileno($nntp)) && $nntp->quit;
 }
 
+{
+  package Net::NNTP::_SSL;
+  our @ISA = ( $ssl_class ? ($ssl_class):(), 'Net::NNTP' );
+  sub starttls { die "NNTP connection is already in SSL mode" }
+  sub start_SSL {
+    my ($class,$nntp,%arg) = @_;
+    delete @arg{ grep { !m{^SSL_} } keys %arg };
+    ( $arg{SSL_verifycn_name} ||= $nntp->host )
+        =~s{(?<!:):[\w()]+$}{}; # strip port
+    $arg{SSL_hostname} = $arg{SSL_verifycn_name}
+        if ! defined $arg{SSL_hostname} && $class->can_client_sni;
+    my $ok = $class->SUPER::start_SSL($nntp,
+      SSL_verifycn_scheme => 'nntp',
+      %arg
+    );
+    $@ = $ssl_class->errstr if !$ok;
+    return $ok;
+  }
+}
+
+
+
 
 1;
 
@@ -775,8 +803,11 @@ Net::NNTP - NNTP Client class
 
 C<Net::NNTP> is a class implementing a simple NNTP client in Perl as described
 in RFC977 and RFC4642.
+With L<IO::Socket::SSL> installed it also provides support for implicit and
+explicit TLS encryption, i.e. NNTPS or NNTP+STARTTLS.
 
-The Net::NNTP class is a subclass of Net::Cmd and IO::Socket::INET.
+The Net::NNTP class is a subclass of Net::Cmd and (depending on avaibility) of
+IO::Socket::IP, IO::Socket::INET6 or IO::Socket::INET.
 
 =head1 CONSTRUCTOR
 
@@ -819,10 +850,12 @@ so that the remote server becomes innd. If the C<Reader> option is given
 with a value of zero, then this command will not be sent and the
 connection will be left talking to nnrpd.
 
-B<LocalAddr> - If multiple IP addresses are present on the client host
-with a valid route to the destination, you can specify the address your
-C<Net::NNTP> connects from and this way override the operating system's
-pick.
+B<LocalAddr> and B<LocalPort> - These parameters are passed directly
+to IO::Socket to allow binding the socket to a specific local address and port.
+
+B<Domain> - This parameter is passed directly to IO::Socket and makes it
+possible to enforce IPv4 connections even if L<IO::Socket::IP> is used as super
+class. Alternatively B<Family> can be used.
 
 =back
 
@@ -923,15 +956,17 @@ implementation) from the server. Returns the text or undef upon failure.
 
 The C<ihave> command informs the server that the client has an article
 whose id is C<MSGID>.  If the server desires a copy of that
-article, and C<MESSAGE> has been given the it will be sent.
+article and C<MESSAGE> has been given then it will be sent.
 
 Returns I<true> if the server desires the article and C<MESSAGE> was
-successfully sent,if specified.
+successfully sent, if specified.
 
 If C<MESSAGE> is not specified then the message must be sent using the
 C<datasend> and C<dataend> methods from L<Net::Cmd>
 
-C<MESSAGE> can be either an array of lines or a reference to an array.
+C<MESSAGE> can be either an array of lines or a reference to an array
+and must be encoded by the caller to octets of whatever encoding is required,
+e.g. by using the Encode module's C<encode()> function.
 
 =item last ()
 
@@ -1004,7 +1039,9 @@ is allowed then the message will be sent.
 If C<MESSAGE> is not specified then the message must be sent using the
 C<datasend> and C<dataend> methods from L<Net::Cmd>
 
-C<MESSAGE> can be either an array of lines or a reference to an array.
+C<MESSAGE> can be either an array of lines or a reference to an array
+and must be encoded by the caller to octets of whatever encoding is required,
+e.g. by using the Encode module's C<encode()> function.
 
 The message, either sent via C<datasend> or as the C<MESSAGE>
 parameter, must be in the format as described by RFC822 and must
@@ -1255,10 +1292,11 @@ Steve Hay E<lt>F<shay@cpan.org>E<gt> is now maintaining libnet as of version
 =head1 COPYRIGHT
 
 Versions up to 2.24_1 Copyright (c) 1995-1997 Graham Barr. All rights reserved.
-Changes in Version 2.25 onwards Copyright (C) 2013-2014 Steve Hay.  All rights
+Changes in Version 2.25 onwards Copyright (C) 2013-2015 Steve Hay.  All rights
 reserved.
 
-This program is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
+This module is free software; you can redistribute it and/or modify it under the
+same terms as Perl itself, i.e. under the terms of either the GNU General Public
+License or the Artistic License, as specified in the F<LICENCE> file.
 
 =cut
diff --git a/lib/Net/Netrc.pm b/lib/Net/Netrc.pm
index 33772d0..4945604 100644
--- a/lib/Net/Netrc.pm
+++ b/lib/Net/Netrc.pm
@@ -4,8 +4,9 @@
 # All rights reserved.
 # Changes in Version 2.13_01 onwards Copyright (C) 2013-2014 Steve Hay.  All
 # rights reserved.
-# This program is free software; you can redistribute it and/or
-# modify it under the same terms as Perl itself.
+# This module is free software; you can redistribute it and/or modify it under
+# the same terms as Perl itself, i.e. under the terms of either the GNU General
+# Public License or the Artistic License, as specified in the F<LICENCE> file.
 
 package Net::Netrc;
 
@@ -17,7 +18,7 @@ use warnings;
 use Carp;
 use FileHandle;
 
-our $VERSION = "2.15";
+our $VERSION = "3.08";
 
 our $TESTING;
 
@@ -339,7 +340,8 @@ Versions up to 2.13 Copyright (c) 1995-1998 Graham Barr. All rights reserved.
 Changes in Version 2.13_01 onwards Copyright (C) 2013-2014 Steve Hay.  All
 rights reserved.
 
-This program is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
+This module is free software; you can redistribute it and/or modify it under the
+same terms as Perl itself, i.e. under the terms of either the GNU General Public
+License or the Artistic License, as specified in the F<LICENCE> file.
 
 =cut
diff --git a/lib/Net/POP3.pm b/lib/Net/POP3.pm
index 772bf76..bccdfb0 100644
--- a/lib/Net/POP3.pm
+++ b/lib/Net/POP3.pm
@@ -2,10 +2,11 @@
 #
 # Versions up to 2.29 Copyright (c) 1995-2004 Graham Barr <gbarr@pobox.com>.
 # All rights reserved.
-# Changes in Version 2.29_01 onwards Copyright (C) 2013-2014 Steve Hay.  All
+# Changes in Version 2.29_01 onwards Copyright (C) 2013-2015 Steve Hay.  All
 # rights reserved.
-# This program is free software; you can redistribute it and/or
-# modify it under the same terms as Perl itself.
+# This module is free software; you can redistribute it and/or modify it under
+# the same terms as Perl itself, i.e. under the terms of either the GNU General
+# Public License or the Artistic License, as specified in the F<LICENCE> file.
 
 package Net::POP3;
 
@@ -19,27 +20,33 @@ use IO::Socket;
 use Net::Cmd;
 use Net::Config;
 
-our $VERSION = "2.32";
+our $VERSION = "3.08";
 
 # Code for detecting if we can use SSL
 my $ssl_class = eval {
   require IO::Socket::SSL;
   # first version with default CA on most platforms
-  IO::Socket::SSL->VERSION(1.968);
+  no warnings 'numeric';
+  IO::Socket::SSL->VERSION(2.007);
 } && 'IO::Socket::SSL';
 
 my $nossl_warn = !$ssl_class &&
-  'To use SSL please install IO::Socket::SSL with version>=1.968';
+  'To use SSL please install IO::Socket::SSL with version>=2.007';
 
 # Code for detecting if we can use IPv6
+my $family_key = 'Domain';
 my $inet6_class = eval {
   require IO::Socket::IP;
-  IO::Socket::IP->VERSION(0.20);
+  no warnings 'numeric';
+  IO::Socket::IP->VERSION(0.20) || die;
+  $family_key = 'Family';
 } && 'IO::Socket::IP' || eval {
   require IO::Socket::INET6;
+  no warnings 'numeric';
   IO::Socket::INET6->VERSION(2.62);
 } && 'IO::Socket::INET6';
 
+
 sub can_ssl   { $ssl_class };
 sub can_inet6 { $inet6_class };
 
@@ -59,7 +66,6 @@ sub new {
   }
   my $hosts = defined $host ? [$host] : $NetConfig{pop3_hosts};
   my $obj;
-  my @localport = exists $arg{ResvPort} ? (LocalPort => $arg{ResvPort}) : ();
 
   if ($arg{SSL}) {
     # SSL from start
@@ -74,7 +80,9 @@ sub new {
       PeerAddr => ($host = $h),
       PeerPort => $arg{Port} || 'pop3(110)',
       Proto => 'tcp',
-      @localport,
+      $family_key => $arg{Domain} || $arg{Family},
+      LocalAddr => $arg{LocalAddr},
+      LocalPort => exists($arg{ResvPort}) ? $arg{ResvPort} : $arg{LocalPort},
       Timeout => $arg{Timeout},
       )
       and last;
@@ -84,14 +92,11 @@ sub new {
     unless defined $obj;
 
   ${*$obj}{'net_pop3_arg'} = \%arg;
+  ${*$obj}{'net_pop3_host'} = $host;
   if ($arg{SSL}) {
-    Net::POP3::_SSLified->start_SSL($obj,
-      SSL_verifycn_name => $host,%arg
-    ) or return;
+    Net::POP3::_SSL->start_SSL($obj,%arg) or return;
   }
 
-  ${*$obj}{'net_pop3_host'} = $host;
-
   $obj->autoflush(1);
   $obj->debug(exists $arg{Debug} ? $arg{Debug} : undef);
 
@@ -136,7 +141,7 @@ sub starttls {
   my $self = shift;
   $ssl_class or die $nossl_warn;
   $self->_STLS or return;
-  Net::POP3::_SSLified->start_SSL($self,
+  Net::POP3::_SSL->start_SSL($self,
     %{ ${*$self}{'net_pop3_arg'} }, # (ssl) args given in new
     @_   # more (ssl) args
   ) or return;
@@ -570,14 +575,16 @@ sub banner {
 }
 
 {
-  package Net::POP3::_SSLified;
+  package Net::POP3::_SSL;
   our @ISA = ( $ssl_class ? ($ssl_class):(), 'Net::POP3' );
   sub starttls { die "POP3 connection is already in SSL mode" }
   sub start_SSL {
     my ($class,$pop3,%arg) = @_;
     delete @arg{ grep { !m{^SSL_} } keys %arg };
     ( $arg{SSL_verifycn_name} ||= $pop3->host )
-        =~s{(?<!:):[\w()]+$}{}; # strip port
+        =~s{(?<!:):[\w()]+$}{}; # strip port
+    $arg{SSL_hostname} = $arg{SSL_verifycn_name}
+        if ! defined $arg{SSL_hostname} && $class->can_client_sni;
     $arg{SSL_verifycn_scheme} ||= 'pop3';
     my $ok = $class->SUPER::start_SSL($pop3,%arg);
     $@ = $ssl_class->errstr if !$ok;
@@ -620,12 +627,16 @@ Net::POP3 - Post Office Protocol 3 Client class (RFC1939)
 This module implements a client interface to the POP3 protocol, enabling
 a perl5 application to talk to POP3 servers. This documentation assumes
 that you are familiar with the POP3 protocol described in RFC1939.
+With L<IO::Socket::SSL> installed it also provides support for implicit and
+explicit TLS encryption, i.e. POP3S or POP3+STARTTLS.
 
 A new Net::POP3 object must be created with the I<new> method. Once
 this has been done, all POP3 commands are accessed via method calls
 on the object.
 
-The Net::POP3 class is a subclass of Net::Cmd and IO::Socket::INET.
+The Net::POP3 class is a subclass of Net::Cmd and (depending on avaibility) of
+IO::Socket::IP, IO::Socket::INET6 or IO::Socket::INET.
+
 
 =head1 CONSTRUCTOR
 
@@ -656,9 +667,14 @@ upgrade with C<starttls>.
 You can use SSL arguments as documented in L<IO::Socket::SSL>, but it will
 usually use the right arguments already.
 
-B<ResvPort> - If given then the socket for the C<Net::POP3> object
-will be bound to the local port given using C<bind> when the socket is
-created.
+B<LocalAddr> and B<LocalPort> - These parameters are passed directly
+to IO::Socket to allow binding the socket to a specific local address and port.
+For compatibility with older versions B<ResvPort> can be used instead of
+B<LocalPort>.
+
+B<Domain> - This parameter is passed directly to IO::Socket and makes it
+possible to enforce IPv4 connections even if L<IO::Socket::IP> is used as super
+class. Alternatively B<Family> can be used.
 
 B<Timeout> - Maximum time, in seconds, to wait for a response from the
 POP3 server (default: 120)
@@ -837,10 +853,11 @@ Steve Hay E<lt>F<shay@cpan.org>E<gt> is now maintaining libnet as of version
 =head1 COPYRIGHT
 
 Versions up to 2.29 Copyright (c) 1995-2004 Graham Barr. All rights reserved.
-Changes in Version 2.29_01 onwards Copyright (C) 2013-2014 Steve Hay.  All
+Changes in Version 2.29_01 onwards Copyright (C) 2013-2015 Steve Hay.  All
 rights reserved.
 
-This program is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
+This module is free software; you can redistribute it and/or modify it under the
+same terms as Perl itself, i.e. under the terms of either the GNU General Public
+License or the Artistic License, as specified in the F<LICENCE> file.
 
 =cut
diff --git a/lib/Net/SMTP.pm b/lib/Net/SMTP.pm
index 4e0c387..6d3e4c2 100644
--- a/lib/Net/SMTP.pm
+++ b/lib/Net/SMTP.pm
@@ -2,10 +2,11 @@
 #
 # Versions up to 2.31_1 Copyright (c) 1995-2004 Graham Barr <gbarr@pobox.com>.
 # All rights reserved.
-# Changes in Version 2.31_2 onwards Copyright (C) 2013-2014 Steve Hay.  All
+# Changes in Version 2.31_2 onwards Copyright (C) 2013-2015 Steve Hay.  All
 # rights reserved.
-# This program is free software; you can redistribute it and/or
-# modify it under the same terms as Perl itself.
+# This module is free software; you can redistribute it and/or modify it under
+# the same terms as Perl itself, i.e. under the terms of either the GNU General
+# Public License or the Artistic License, as specified in the F<LICENCE> file.
 
 package Net::SMTP;
 
@@ -18,26 +19,31 @@ use Carp;
 use IO::Socket;
 use Net::Cmd;
 use Net::Config;
-use Socket 1.3;
+use Socket;
 
-our $VERSION = "2.35";
+our $VERSION = "3.08";
 
 # Code for detecting if we can use SSL
 my $ssl_class = eval {
   require IO::Socket::SSL;
   # first version with default CA on most platforms
-  IO::Socket::SSL->VERSION(1.968);
+  no warnings 'numeric';
+  IO::Socket::SSL->VERSION(2.007);
 } && 'IO::Socket::SSL';
 
 my $nossl_warn = !$ssl_class &&
-  'To use SSL please install IO::Socket::SSL with version>=1.968';
+  'To use SSL please install IO::Socket::SSL with version>=2.007';
 
 # Code for detecting if we can use IPv6
+my $family_key = 'Domain';
 my $inet6_class = eval {
   require IO::Socket::IP;
-  IO::Socket::IP->VERSION(0.20);
+  no warnings 'numeric';
+  IO::Socket::IP->VERSION(0.20) || die;
+  $family_key = 'Family';
 } && 'IO::Socket::IP' || eval {
   require IO::Socket::INET6;
+  no warnings 'numeric';
   IO::Socket::INET6->VERSION(2.62);
 } && 'IO::Socket::INET6';
 
@@ -76,6 +82,7 @@ sub new {
       PeerPort => $arg{Port} || 'smtp(25)',
       LocalAddr => $arg{LocalAddr},
       LocalPort => $arg{LocalPort},
+      $family_key => $arg{Domain} || $arg{Family},
       Proto     => 'tcp',
       Timeout   => $arg{Timeout}
       )
@@ -86,8 +93,10 @@ sub new {
     unless defined $obj;
 
   ${*$obj}{'net_smtp_arg'} = \%arg;
+  ${*$obj}{'net_smtp_host'} = $host;
+
   if ($arg{SSL}) {
-    Net::SMTP::_SSLified->start_SSL($obj,SSL_verifycn_name => $host,%arg)
+    Net::SMTP::_SSL->start_SSL($obj,%arg)
       or return;
   }
 
@@ -103,16 +112,17 @@ sub new {
   }
 
   ${*$obj}{'net_smtp_exact_addr'} = $arg{ExactAddresses};
-  ${*$obj}{'net_smtp_host'}       = $host;
 
   (${*$obj}{'net_smtp_banner'}) = $obj->message;
   (${*$obj}{'net_smtp_domain'}) = $obj->message =~ /\A\s*(\S+)/;
 
-  unless ($obj->hello($arg{Hello} || "")) {
-    my $err = ref($obj) . ": " . $obj->code . " " . $obj->message;
-    $obj->close();
-    $@ = $err;
-    return;
+  if (!exists $arg{SendHello} || $arg{SendHello}) {
+    unless ($obj->hello($arg{Hello} || "")) {
+      my $err = ref($obj) . ": " . $obj->code . " " . $obj->message;
+      $obj->close();
+      $@ = $err;
+      return;
+    }
   }
 
   $obj;
@@ -189,12 +199,13 @@ sub auth {
     if ($client) {
       # $client mechanism failed, so we need to exclude this mechanism from list
       my $failed_mechanism = $client->mechanism;
+      return unless defined $failed_mechanism;
       $self->debug_text("Auth mechanism failed: $failed_mechanism")
         if $self->debug;
       $mechanisms =~ s/\b\Q$failed_mechanism\E\b//;
-      last unless $mechanisms =~ /\S/;
+      return unless $mechanisms =~ /\S/;
+      $sasl->mechanism($mechanisms);
     }
-    $sasl->mechanism($mechanisms);
     
     # We should probably allow the user to pass the host, but I don't
     # currently know and SASL mechanisms that are used by smtp that need it
@@ -254,7 +265,7 @@ sub starttls {
   my $self = shift;
   $ssl_class or die $nossl_warn;
   $self->_STARTTLS or return;
-  Net::SMTP::_SSLified->start_SSL($self,
+  Net::SMTP::_SSL->start_SSL($self,
     %{ ${*$self}{'net_smtp_arg'} }, # (ssl) args given in new
     @_   # more (ssl) args
   ) or return;
@@ -603,14 +614,16 @@ sub _STARTTLS { shift->command("STARTTLS")->response() == CMD_OK }
 
 
 {
-  package Net::SMTP::_SSLified;
+  package Net::SMTP::_SSL;
   our @ISA = ( $ssl_class ? ($ssl_class):(), 'Net::SMTP' );
   sub starttls { die "SMTP connection is already in SSL mode" }
   sub start_SSL {
     my ($class,$smtp,%arg) = @_;
     delete @arg{ grep { !m{^SSL_} } keys %arg };
     ( $arg{SSL_verifycn_name} ||= $smtp->host )
-        =~s{(?<!:):[\w()]+$}{}; # strip port
+        =~s{(?<!:):[\w()]+$}{}; # strip port
+    $arg{SSL_hostname} = $arg{SSL_verifycn_name}
+        if ! defined $arg{SSL_hostname} && $class->can_client_sni;
     $arg{SSL_verifycn_scheme} ||= 'smtp';
     my $ok = $class->SUPER::start_SSL($smtp,%arg);
     $@ = $ssl_class->errstr if !$ok;
@@ -641,12 +654,12 @@ Net::SMTP - Simple Mail Transfer Protocol Client
 This module implements a client interface to the SMTP and ESMTP
 protocol, enabling a perl5 application to talk to SMTP servers. This
 documentation assumes that you are familiar with the concepts of the
-SMTP protocol described in RFC821.
-
-A new Net::SMTP object must be created with the I<new> method. Once
-this has been done, all SMTP commands are accessed through this object.
+SMTP protocol described in RFC2821.
+With L<IO::Socket::SSL> installed it also provides support for implicit and
+explicit TLS encryption, i.e. SMTPS or SMTP+STARTTLS.
 
-The Net::SMTP class is a subclass of Net::Cmd and IO::Socket::INET.
+The Net::SMTP class is a subclass of Net::Cmd and (depending on avaibility) of
+IO::Socket::IP, IO::Socket::INET6 or IO::Socket::INET.
 
 =head1 EXAMPLES
 
@@ -705,6 +718,10 @@ B<Hello> - SMTP requires that you identify yourself. This option
 specifies a string to pass as your mail domain. If not given localhost.localdomain
 will be used.
 
+B<SendHello> - If false then the EHLO (or HELO) command that is normally sent
+when constructing the object will not be sent. In that case the command will
+have to be sent manually by calling C<hello()> instead.
+
 B<Host> - SMTP host to connect to. It may be a single scalar (hostname[:port]),
 as defined for the C<PeerAddr> option in L<IO::Socket::INET>, or a reference to
 an array with hosts to try in turn. The L</host> method will return the value
@@ -720,7 +737,11 @@ You can use SSL arguments as documented in L<IO::Socket::SSL>, but it will
 usually use the right arguments already.
 
 B<LocalAddr> and B<LocalPort> - These parameters are passed directly
-to IO::Socket to allow binding the socket to a local port.
+to IO::Socket to allow binding the socket to a specific local address and port.
+
+B<Domain> - This parameter is passed directly to IO::Socket and makes it
+possible to enforce IPv4 connections even if L<IO::Socket::IP> is used as super
+class. Alternatively B<Family> can be used.
 
 B<Timeout> - Maximum time, in seconds, to wait for a response from the
 SMTP server (default: 120)
@@ -751,11 +772,11 @@ Example:
 
     # the same with direct SSL
     $smtp = Net::SMTP->new('mailhost',
-                           Hello => 'my.mail.domain',
-                           Timeout => 30,
-                           Debug   => 1,
-                           SSL     => 1,
-                          );
+                           Hello => 'my.mail.domain',
+                           Timeout => 30,
+                           Debug   => 1,
+                           SSL     => 1,
+                          );
 
     # Connect to the default server from Net::config
     $smtp = Net::SMTP->new(
@@ -812,7 +833,11 @@ usually use the right arguments already.
 
 =item auth ( USERNAME, PASSWORD )
 
-Attempt SASL authentication. Requires Authen::SASL module.
+=item auth ( SASL )
+
+Attempt SASL authentication. Requires Authen::SASL module. The first form
+constructs a new Authen::SASL object using the given username and password;
+the second form uses the given Authen::SASL object.
 
 =item mail ( ADDRESS [, OPTIONS] )
 
@@ -928,9 +953,12 @@ Synonyms for C<recipient>.
 
 Initiate the sending of the data from the current message.
 
-C<DATA> may be a reference to a list or a list. If specified the contents
-of C<DATA> and a termination string C<".\r\n"> is sent to the server. And the
-result will be true if the data was accepted.
+C<DATA> may be a reference to a list or a list and must be encoded by the
+caller to octets of whatever encoding is required, e.g. by using the Encode
+module's C<encode()> function.
+
+If specified the contents of C<DATA> and a termination string C<".\r\n"> is
+sent to the server. The result will be true if the data was accepted.
 
 If C<DATA> is not specified then the result will indicate that the server
 wishes the data to be sent. The data must then be sent using the C<datasend>
@@ -1004,10 +1032,11 @@ Steve Hay E<lt>F<shay@cpan.org>E<gt> is now maintaining libnet as of version
 =head1 COPYRIGHT
 
 Versions up to 2.31_1 Copyright (c) 1995-2004 Graham Barr. All rights reserved.
-Changes in Version 2.31_2 onwards Copyright (C) 2013-2014 Steve Hay.  All rights
+Changes in Version 2.31_2 onwards Copyright (C) 2013-2015 Steve Hay.  All rights
 reserved.
 
-This program is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
+This module is free software; you can redistribute it and/or modify it under the
+same terms as Perl itself, i.e. under the terms of either the GNU General Public
+License or the Artistic License, as specified in the F<LICENCE> file.
 
 =cut
diff --git a/lib/Net/Time.pm b/lib/Net/Time.pm
index 26f43a1..fae93f8 100644
--- a/lib/Net/Time.pm
+++ b/lib/Net/Time.pm
@@ -4,8 +4,9 @@
 # All rights reserved.
 # Changes in Version 2.11 onwards Copyright (C) 2014 Steve Hay.  All rights
 # reserved.
-# This program is free software; you can redistribute it and/or
-# modify it under the same terms as Perl itself.
+# This module is free software; you can redistribute it and/or modify it under
+# the same terms as Perl itself, i.e. under the terms of either the GNU General
+# Public License or the Artistic License, as specified in the F<LICENCE> file.
 
 package Net::Time;
 
@@ -23,7 +24,7 @@ use Net::Config;
 our @ISA       = qw(Exporter);
 our @EXPORT_OK = qw(inet_time inet_daytime);
 
-our $VERSION = "2.12";
+our $VERSION = "3.08";
 
 our $TIMEOUT = 120;
 
@@ -156,7 +157,8 @@ Versions up to 2.11 Copyright (c) 1995-2004 Graham Barr. All rights reserved.
 Changes in Version 2.11 onwards Copyright (C) 2014 Steve Hay.  All rights
 reserved.
 
-This program is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
+This module is free software; you can redistribute it and/or modify it under the
+same terms as Perl itself, i.e. under the terms of either the GNU General Public
+License or the Artistic License, as specified in the F<LICENCE> file.
 
 =cut
diff --git a/lib/Net/libnetFAQ.pod b/lib/Net/libnetFAQ.pod
index c609018..f8ad797 100644
--- a/lib/Net/libnetFAQ.pod
+++ b/lib/Net/libnetFAQ.pod
@@ -14,9 +14,9 @@ available on the libnet web page at
 =head2 How to contribute to this document
 
 You may report corrections, additions, and suggestions on the
-CPAN request tracker at
+CPAN Request Tracker at
 
-    http://rt.cpan.org/Dist/Display.html?Name=libnet
+    http://rt.cpan.org/Public/Bug/Report.html?Queue=libnet
 
 =head1 Author and Copyright Information
 
@@ -54,7 +54,7 @@ which requires Convert::EBCDIC.
 
 Authen::SASL is required for AUTH support.
 
-IO::Socket::SSL version 1.994 or higher is required for SSL support.
+IO::Socket::SSL version 2.007 or higher is required for SSL support.
 
 IO::Socket::IP version 0.20 or IO::Socket::INET6 version 2.62 is
 required for IPv6 support.
diff --git a/t/changes.t b/t/changes.t
new file mode 100644
index 0000000..0ddff50
--- /dev/null
+++ b/t/changes.t
@@ -0,0 +1,48 @@
+#!perl
+#===============================================================================
+#
+# t/changes.t
+#
+# DESCRIPTION
+#   Test script to check CPAN::Changes conformance.
+#
+# COPYRIGHT
+#   Copyright (C) 2014 Steve Hay.  All rights reserved.
+#
+# LICENCE
+#   This script is free software; you can redistribute it and/or modify it under
+#   the same terms as Perl itself, i.e. under the terms of either the GNU
+#   General Public License or the Artistic License, as specified in the LICENCE
+#   file.
+#
+#===============================================================================
+
+use 5.008001;
+
+use strict;
+use warnings;
+
+use Test::More;
+
+#===============================================================================
+# MAIN PROGRAM
+#===============================================================================
+
+MAIN: {
+    plan skip_all => 'Author testing only' unless $ENV{AUTHOR_TESTING};
+
+    my $ok = eval {
+        require Test::CPAN::Changes;
+        Test::CPAN::Changes->import();
+        1;
+    };
+
+    if (not $ok) {
+        plan skip_all => 'Test::CPAN::Changes required to test Changes';
+    }
+    else {
+        changes_ok();
+    }
+}
+
+#===============================================================================
diff --git a/t/config.t b/t/config.t
index d686ab1..3c29a03 100644
--- a/t/config.t
+++ b/t/config.t
@@ -6,12 +6,12 @@ use strict;
 use warnings;
 
 BEGIN {
-    if (!eval { require Socket; 1 }) {
+    if (!eval { require Socket }) {
         print "1..0 # no Socket\n"; exit 0;
     }
     undef *{Socket::inet_aton};
     undef *{Socket::inet_ntoa};
-    if (ord('A') == 193 && !eval { require Convert::EBCDIC; 1 }) {
+    if (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
         print "1..0 # EBCDIC but no Convert::EBCDIC\n"; exit 0;
     }
     $INC{'Socket.pm'} = 1;
diff --git a/t/critic.t b/t/critic.t
index 5fe75e1..914f722 100644
--- a/t/critic.t
+++ b/t/critic.t
@@ -10,8 +10,10 @@
 #   Copyright (C) 2014 Steve Hay.  All rights reserved.
 #
 # LICENCE
-#   You may distribute under the terms of either the GNU General Public License
-#   or the Artistic License, as specified in the LICENCE file.
+#   This script is free software; you can redistribute it and/or modify it under
+#   the same terms as Perl itself, i.e. under the terms of either the GNU
+#   General Public License or the Artistic License, as specified in the LICENCE
+#   file.
 #
 #===============================================================================
 
@@ -27,9 +29,11 @@ use Test::More;
 #===============================================================================
 
 MAIN: {
+    plan skip_all => 'Author testing only' unless $ENV{AUTHOR_TESTING};
+
     my $ok = eval {
         require Test::Perl::Critic;
-        Test::Perl::Critic->import();
+        Test::Perl::Critic->import(-profile => '');
         1;
     };
 
diff --git a/t/datasend.t b/t/datasend.t
index cdbdc29..0aea9d4 100644
--- a/t/datasend.t
+++ b/t/datasend.t
@@ -6,10 +6,10 @@ use strict;
 use warnings;
 
 BEGIN {
-    if (!eval { require Socket; 1 }) {
+    if (!eval { require Socket }) {
         print "1..0 # no Socket\n"; exit 0;
     }
-    if (ord('A') == 193 && !eval { require Convert::EBCDIC; 1 }) {
+    if (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
         print "1..0 # EBCDIC but no Convert::EBCDIC\n"; exit 0;
     }
 }
@@ -44,7 +44,7 @@ BEGIN {
 (my $libnet_t = __FILE__) =~ s/datasend.t/libnet_t.pl/;
 require $libnet_t or die;
 
-print "1..51\n";
+print "1..54\n";
 
 sub check {
   my $expect = pop;
@@ -158,3 +158,10 @@ check(
   "a\015\012..\015\012.\015\012",
 );
 
+# Test that datasend() plays nicely with bytes in an upgraded string,
+# even though the input should really be encode()d already.
+check(
+  substr("\x{100}", 0, 0) . "\x{e9}",
+
+  "\x{e9}\015\012.\015\012"
+);
diff --git a/t/external/ftp-ssl.t b/t/external/ftp-ssl.t
index 3036630..28c038a 100644
--- a/t/external/ftp-ssl.t
+++ b/t/external/ftp-ssl.t
@@ -44,7 +44,7 @@ IO::Socket::SSL->start_SSL($sock,
     %sslargs,
 ) or do {
     plan skip_all => "$server:990 not upgradable to SSL: ".
-        $IO::Socket::SSL::SSL_ERROR;
+        $IO::Socket::SSL::SSL_ERROR;
 };
 
 plan tests => 9;
diff --git a/t/ftp.t b/t/ftp.t
index 288cdbc..16cb868 100644
--- a/t/ftp.t
+++ b/t/ftp.t
@@ -6,10 +6,10 @@ use strict;
 use warnings;
 
 BEGIN {
-    if (!eval { require Socket; 1 }) {
+    if (!eval { require Socket }) {
         print "1..0 # Skip: no Socket module\n"; exit 0;
     }
-    if (ord('A') == 193 && !eval { require Convert::EBCDIC; 1 }) {
+    if (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
         print "1..0 # Skip: EBCDIC but no Convert::EBCDIC\n"; exit 0;
     }
 }
diff --git a/t/hostname.t b/t/hostname.t
index 25f1cda..55031bf 100644
--- a/t/hostname.t
+++ b/t/hostname.t
@@ -6,10 +6,10 @@ use strict;
 use warnings;
 
 BEGIN {
-    if (!eval { require Socket; 1 }) {
+    if (!eval { require Socket }) {
         print "1..0 # no Socket\n"; exit 0;
     }
-    if (ord('A') == 193 && !eval { require Convert::EBCDIC; 1 }) {
+    if (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
         print "1..0 # EBCDIC but no Convert::EBCDIC\n"; exit 0;
     }
 }
diff --git a/t/netrc.t b/t/netrc.t
index 1149bb8..e270b36 100644
--- a/t/netrc.t
+++ b/t/netrc.t
@@ -6,10 +6,10 @@ use strict;
 use warnings;
 
 BEGIN {
-    if (!eval { require Socket; 1 }) {
+    if (!eval { require Socket }) {
         print "1..0 # no Socket\n"; exit 0;
     }
-    if (ord('A') == 193 && !eval { require Convert::EBCDIC; 1 }) {
+    if (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
         print "1..0 # EBCDIC but no Convert::EBCDIC\n"; exit 0;
     }
 }
diff --git a/t/nntp.t b/t/nntp.t
index 303aac4..559f398 100644
--- a/t/nntp.t
+++ b/t/nntp.t
@@ -6,10 +6,10 @@ use strict;
 use warnings;
 
 BEGIN {
-    if (!eval { require Socket; 1 }) {
+    if (!eval { require Socket }) {
         print "1..0 # no Socket\n"; exit 0;
     }
-    if (ord('A') == 193 && !eval { require Convert::EBCDIC; 1 }) {
+    if (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
         print "1..0 # EBCDIC but no Convert::EBCDIC\n"; exit 0;
     }
 }
diff --git a/t/nntp_ipv6.t b/t/nntp_ipv6.t
index 62167b9..1992618 100644
--- a/t/nntp_ipv6.t
+++ b/t/nntp_ipv6.t
@@ -5,6 +5,7 @@ use 5.008001;
 use strict;
 use warnings;
 
+use Config;
 use File::Temp 'tempfile';
 use Net::NNTP;
 use Test::More;
@@ -15,7 +16,10 @@ my $inet6class = Net::NNTP->can_inet6;
 plan skip_all => "no IPv6 support found in Net::NNTP" if ! $inet6class;
 
 plan skip_all => "fork not supported on this platform"
-  if grep { $^O =~m{$_} } qw(MacOS VOS vmesa riscos amigaos);
+  unless $Config::Config{d_fork} || $Config::Config{d_pseudofork} ||
+    (($^O eq 'MSWin32' || $^O eq 'NetWare') and
+     $Config::Config{useithreads} and
+     $Config::Config{ccflags} =~ /-DPERL_IMPLICIT_SYS/);
 
 my $srv = $inet6class->new(
   LocalAddr => '::1',
@@ -24,7 +28,7 @@ my $srv = $inet6class->new(
 plan skip_all => "cannot create listener on ::1: $!" if ! $srv;
 my $host = $srv->sockhost;
 my $port = $srv->sockport;
-diag("server on $host port $port");
+note("server on $host port $port");
 
 plan tests => 1;
 
@@ -32,7 +36,7 @@ defined( my $pid = fork()) or die "fork failed: $!";
 exit(nntp_server()) if ! $pid;
 
 my $cl = Net::NNTP->new(Host => $host, Port => $port,, Debug => $debug);
-diag("created Net::NNTP object");
+note("created Net::NNTP object");
 if (!$cl) {
   fail("IPv6 NNTP connect failed");
 } else {
@@ -58,5 +62,5 @@ sub nntp_server {
       print "500 unknown cmd\r\n";
     }
   }
-  diag("NNTP dialog done");
+  note("NNTP dialog done");
 }
diff --git a/t/nntp_ssl.t b/t/nntp_ssl.t
index e4b4bcb..e6a4fe5 100644
--- a/t/nntp_ssl.t
+++ b/t/nntp_ssl.t
@@ -5,6 +5,7 @@ use 5.008001;
 use strict;
 use warnings;
 
+use Config;
 use File::Temp 'tempfile';
 use Net::NNTP;
 use Test::More;
@@ -16,10 +17,10 @@ my $parent = 0;
 plan skip_all => "no SSL support found in Net::NNTP" if ! Net::NNTP->can_ssl;
 
 plan skip_all => "fork not supported on this platform"
-  if grep { $^O =~m{$_} } qw(MacOS VOS vmesa riscos amigaos);
-
-plan skip_all => "incomplete or version of IO::Socket::SSL"
-  if ! eval { require IO::Socket::SSL::Utils };
+  unless $Config::Config{d_fork} || $Config::Config{d_pseudofork} ||
+    (($^O eq 'MSWin32' || $^O eq 'NetWare') and
+     $Config::Config{useithreads} and
+     $Config::Config{ccflags} =~ /-DPERL_IMPLICIT_SYS/);
 
 my $srv = IO::Socket::INET->new(
   LocalAddr => '127.0.0.1',
@@ -31,6 +32,7 @@ my $port = $srv->sockport;
 
 plan tests => 2;
 
+require IO::Socket::SSL::Utils;
 my ($ca,$key) = IO::Socket::SSL::Utils::CERT_create( CA => 1 );
 my ($fh,$cafile) = tempfile();
 print $fh IO::Socket::SSL::Utils::PEM_cert2string($ca);
@@ -71,7 +73,7 @@ sub nntp_client {
     Debug => $debug,
     %sslopt,
   );
-  diag("created Net::NNTP object");
+  note("created Net::NNTP object");
   if (!$cl) {
     fail( ($ssl ? "SSL ":"" )."NNTP connect failed");
   } elsif ($ssl) {
@@ -113,8 +115,8 @@ sub nntp_server {
     } elsif ( ! $ssl and $cmd eq 'STARTTLS' ) {
       print $cl "382 Continue with TLS negotiation\r\n";
       if ( ! IO::Socket::SSL->start_SSL($cl, %sslargs)) {
-        diag("initial ssl handshake with client failed");
-        return;
+        diag("initial ssl handshake with client failed");
+        return;
       }
       $ssl = 1;
     } else {
@@ -123,5 +125,5 @@ sub nntp_server {
     }
   }
 
-  diag("NNTP dialog done");
+  note("NNTP dialog done");
 }
diff --git a/t/pod.t b/t/pod.t
index 5af23ae..1fdd220 100644
--- a/t/pod.t
+++ b/t/pod.t
@@ -10,8 +10,10 @@
 #   Copyright (C) 2014 Steve Hay.  All rights reserved.
 #
 # LICENCE
-#   You may distribute under the terms of either the GNU General Public License
-#   or the Artistic License, as specified in the LICENCE file.
+#   This script is free software; you can redistribute it and/or modify it under
+#   the same terms as Perl itself, i.e. under the terms of either the GNU
+#   General Public License or the Artistic License, as specified in the LICENCE
+#   file.
 #
 #===============================================================================
 
@@ -27,6 +29,8 @@ use Test::More;
 #===============================================================================
 
 MAIN: {
+    plan skip_all => 'Author testing only' unless $ENV{AUTHOR_TESTING};
+
     my $ok = eval {
         require Test::Pod;
         Test::Pod->import();
diff --git a/t/pod_coverage.t b/t/pod_coverage.t
index d72778c..3d674d4 100644
--- a/t/pod_coverage.t
+++ b/t/pod_coverage.t
@@ -7,11 +7,13 @@
 #   Test script to check POD coverage.
 #
 # COPYRIGHT
-#   Copyright (C) 2014 Steve Hay.  All rights reserved.
+#   Copyright (C) 2014, 2015 Steve Hay.  All rights reserved.
 #
 # LICENCE
-#   You may distribute under the terms of either the GNU General Public License
-#   or the Artistic License, as specified in the LICENCE file.
+#   This script is free software; you can redistribute it and/or modify it under
+#   the same terms as Perl itself, i.e. under the terms of either the GNU
+#   General Public License or the Artistic License, as specified in the LICENCE
+#   file.
 #
 #===============================================================================
 
@@ -27,6 +29,8 @@ use Test::More;
 #===============================================================================
 
 MAIN: {
+    plan skip_all => 'Author testing only' unless $ENV{AUTHOR_TESTING};
+
     my $ok = eval {
         require Test::Pod::Coverage;
         Test::Pod::Coverage->import();
@@ -44,7 +48,7 @@ MAIN: {
         my $params = { coverage_class => qw(Pod::Coverage::CountParents) };
         pod_coverage_ok('Net::Cmd', {
             %$params,
-            also_private => [qw(is_utf8 toascii toebcdic set_status)]
+            also_private => [qw(toascii toebcdic set_status)]
         });
         pod_coverage_ok('Net::Config', {
             %$params,
diff --git a/t/pop3_ipv6.t b/t/pop3_ipv6.t
index 9b3c8cb..1c88c1a 100644
--- a/t/pop3_ipv6.t
+++ b/t/pop3_ipv6.t
@@ -5,6 +5,7 @@ use 5.008001;
 use strict;
 use warnings;
 
+use Config;
 use File::Temp 'tempfile';
 use Net::POP3;
 use Test::More;
@@ -15,7 +16,10 @@ my $inet6class = Net::POP3->can_inet6;
 plan skip_all => "no IPv6 support found in Net::POP3" if ! $inet6class;
 
 plan skip_all => "fork not supported on this platform"
-  if grep { $^O =~m{$_} } qw(MacOS VOS vmesa riscos amigaos);
+  unless $Config::Config{d_fork} || $Config::Config{d_pseudofork} ||
+    (($^O eq 'MSWin32' || $^O eq 'NetWare') and
+     $Config::Config{useithreads} and
+     $Config::Config{ccflags} =~ /-DPERL_IMPLICIT_SYS/);
 
 my $srv = $inet6class->new(
   LocalAddr => '::1',
@@ -23,7 +27,7 @@ my $srv = $inet6class->new(
 );
 plan skip_all => "cannot create listener on ::1: $!" if ! $srv;
 my $saddr = "[".$srv->sockhost."]".':'.$srv->sockport;
-diag("server on $saddr");
+note("server on $saddr");
 
 plan tests => 1;
 
@@ -31,7 +35,7 @@ defined( my $pid = fork()) or die "fork failed: $!";
 exit(pop3_server()) if ! $pid;
 
 my $cl = Net::POP3->new($saddr, Debug => $debug);
-diag("created Net::POP3 object");
+note("created Net::POP3 object");
 if (!$cl) {
   fail("IPv6 POP3 connect failed");
 } else {
@@ -51,12 +55,12 @@ sub pop3_server {
       last;
     } elsif ( $cmd eq 'CAPA' ) {
       print $cl "+OK\r\n".
-        ".\r\n";
+        ".\r\n";
     } else {
       diag("received unknown command: $cmd");
       print "-ERR unknown cmd\r\n";
     }
   }
 
-  diag("POP3 dialog done");
+  note("POP3 dialog done");
 }
diff --git a/t/pop3_ssl.t b/t/pop3_ssl.t
index 3ba74af..356de40 100644
--- a/t/pop3_ssl.t
+++ b/t/pop3_ssl.t
@@ -5,6 +5,7 @@ use 5.008001;
 use strict;
 use warnings;
 
+use Config;
 use File::Temp 'tempfile';
 use Net::POP3;
 use Test::More;
@@ -16,14 +17,10 @@ my $parent = 0;
 plan skip_all => "no SSL support found in Net::POP3" if ! Net::POP3->can_ssl;
 
 plan skip_all => "fork not supported on this platform"
-  if grep { $^O =~m{$_} } qw(MacOS VOS vmesa riscos amigaos);
-
-plan skip_all => "incomplete or to old version of IO::Socket::SSL" if ! eval {
-  require IO::Socket::SSL
-    && IO::Socket::SSL->VERSION(1.968)
-    && require IO::Socket::SSL::Utils
-    && defined &IO::Socket::SSL::Utils::CERT_create;
-};
+  unless $Config::Config{d_fork} || $Config::Config{d_pseudofork} ||
+    (($^O eq 'MSWin32' || $^O eq 'NetWare') and
+     $Config::Config{useithreads} and
+     $Config::Config{ccflags} =~ /-DPERL_IMPLICIT_SYS/);
 
 my $srv = IO::Socket::INET->new(
   LocalAddr => '127.0.0.1',
@@ -34,6 +31,7 @@ my $saddr = $srv->sockhost.':'.$srv->sockport;
 
 plan tests => 2;
 
+require IO::Socket::SSL::Utils;
 my ($ca,$key) = IO::Socket::SSL::Utils::CERT_create( CA => 1 );
 my ($fh,$cafile) = tempfile();
 print $fh IO::Socket::SSL::Utils::PEM_cert2string($ca);
@@ -69,7 +67,7 @@ sub pop3_client {
   );
   $sslopt{SSL} = 1 if $ssl;
   my $cl = Net::POP3->new($saddr, %sslopt, Debug => $debug);
-  diag("created Net::POP3 object");
+  note("created Net::POP3 object");
   if (!$cl) {
     fail( ($ssl ? "SSL ":"" )."POP3 connect failed");
   } elsif ($ssl) {
@@ -108,13 +106,13 @@ sub pop3_server {
       last;
     } elsif ( $cmd eq 'CAPA' ) {
       print $cl "+OK\r\n".
-        ( $ssl ? "" : "STLS\r\n" ).
-        ".\r\n";
+        ( $ssl ? "" : "STLS\r\n" ).
+        ".\r\n";
     } elsif ( ! $ssl and $cmd eq 'STLS' ) {
       print $cl "+OK starting ssl\r\n";
       if ( ! IO::Socket::SSL->start_SSL($cl, %sslargs)) {
-        diag("initial ssl handshake with client failed");
-        return;
+        diag("initial ssl handshake with client failed");
+        return;
       }
       $ssl = 1;
     } else {
@@ -123,5 +121,5 @@ sub pop3_server {
     }
   }
 
-  diag("POP3 dialog done");
+  note("POP3 dialog done");
 }
diff --git a/t/require.t b/t/require.t
index a48951a..70ec1f6 100644
--- a/t/require.t
+++ b/t/require.t
@@ -6,10 +6,10 @@ use strict;
 use warnings;
 
 BEGIN {
-    if (!eval { require Socket; 1 }) {
+    if (!eval { require Socket }) {
         print "1..0 # no Socket\n"; exit 0;
     }
-    if (ord('A') == 193 && !eval { require Convert::EBCDIC; 1 }) {
+    if (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
         print "1..0 # EBCDIC but no Convert::EBCDIC\n"; exit 0;
     }
 }
diff --git a/t/smtp.t b/t/smtp.t
index 634390f..9d6f65a 100644
--- a/t/smtp.t
+++ b/t/smtp.t
@@ -6,10 +6,10 @@ use strict;
 use warnings;
 
 BEGIN {
-    if (!eval { require Socket; 1 }) {
+    if (!eval { require Socket }) {
         print "1..0 # no Socket\n"; exit 0;
     }
-    if (ord('A') == 193 && eval { require Convert::EBCDIC; 1 }) {
+    if (ord('A') == 193 && eval { require Convert::EBCDIC }) {
         print "1..0 # EBCDIC but no Convert::EBCDIC\n"; exit 0;
     }
 }
diff --git a/t/smtp_ipv6.t b/t/smtp_ipv6.t
index 6e4a990..a31b6ff 100644
--- a/t/smtp_ipv6.t
+++ b/t/smtp_ipv6.t
@@ -5,6 +5,7 @@ use 5.008001;
 use strict;
 use warnings;
 
+use Config;
 use File::Temp 'tempfile';
 use Net::SMTP;
 use Test::More;
@@ -15,7 +16,10 @@ my $inet6class = Net::SMTP->can_inet6;
 plan skip_all => "no IPv6 support found in Net::SMTP" if ! $inet6class;
 
 plan skip_all => "fork not supported on this platform"
-  if grep { $^O =~m{$_} } qw(MacOS VOS vmesa riscos amigaos);
+  unless $Config::Config{d_fork} || $Config::Config{d_pseudofork} ||
+    (($^O eq 'MSWin32' || $^O eq 'NetWare') and
+     $Config::Config{useithreads} and
+     $Config::Config{ccflags} =~ /-DPERL_IMPLICIT_SYS/);
 
 my $srv = $inet6class->new(
   LocalAddr => '::1',
@@ -23,7 +27,7 @@ my $srv = $inet6class->new(
 );
 plan skip_all => "cannot create listener on ::1: $!" if ! $srv;
 my $saddr = "[".$srv->sockhost."]".':'.$srv->sockport;
-diag("server on $saddr");
+note("server on $saddr");
 
 plan tests => 1;
 
@@ -31,7 +35,7 @@ defined( my $pid = fork()) or die "fork failed: $!";
 exit(smtp_server()) if ! $pid;
 
 my $cl = Net::SMTP->new($saddr, Debug => $debug);
-diag("created Net::SMTP object");
+note("created Net::SMTP object");
 if (!$cl) {
   fail("IPv6 SMTP connect failed");
 } else {
@@ -53,12 +57,12 @@ sub smtp_server {
       print $cl "250 localhost\r\n";
     } elsif ( $cmd eq 'EHLO' ) {
       print $cl "250-localhost\r\n".
-        "250 HELP\r\n";
+        "250 HELP\r\n";
     } else {
       diag("received unknown command: $cmd");
       print "500 unknown cmd\r\n";
     }
   }
 
-  diag("SMTP dialog done");
+  note("SMTP dialog done");
 }
diff --git a/t/smtp_ssl.t b/t/smtp_ssl.t
index b7a533f..7290176 100644
--- a/t/smtp_ssl.t
+++ b/t/smtp_ssl.t
@@ -5,6 +5,7 @@ use 5.008001;
 use strict;
 use warnings;
 
+use Config;
 use File::Temp 'tempfile';
 use Net::SMTP;
 use Test::More;
@@ -16,14 +17,10 @@ my $parent = 0;
 plan skip_all => "no SSL support found in Net::SMTP" if ! Net::SMTP->can_ssl;
 
 plan skip_all => "fork not supported on this platform"
-  if grep { $^O =~m{$_} } qw(MacOS VOS vmesa riscos amigaos);
-
-plan skip_all => "incomplete or to old version of IO::Socket::SSL" if ! eval {
-  require IO::Socket::SSL
-    && IO::Socket::SSL->VERSION(1.968)
-    && require IO::Socket::SSL::Utils
-    && defined &IO::Socket::SSL::Utils::CERT_create;
-};
+  unless $Config::Config{d_fork} || $Config::Config{d_pseudofork} ||
+    (($^O eq 'MSWin32' || $^O eq 'NetWare') and
+     $Config::Config{useithreads} and
+     $Config::Config{ccflags} =~ /-DPERL_IMPLICIT_SYS/);
 
 my $srv = IO::Socket::INET->new(
   LocalAddr => '127.0.0.1',
@@ -34,6 +31,7 @@ my $saddr = $srv->sockhost.':'.$srv->sockport;
 
 plan tests => 2;
 
+require IO::Socket::SSL::Utils;
 my ($ca,$key) = IO::Socket::SSL::Utils::CERT_create( CA => 1 );
 my ($fh,$cafile) = tempfile();
 print $fh IO::Socket::SSL::Utils::PEM_cert2string($ca);
@@ -69,7 +67,7 @@ sub smtp_client {
   );
   $sslopt{SSL} = 1 if $ssl;
   my $cl = Net::SMTP->new($saddr, %sslopt, Debug => $debug);
-  diag("created Net::SMTP object");
+  note("created Net::SMTP object");
   if (!$cl) {
     fail( ($ssl ? "SSL ":"" )."SMTP connect failed");
   } elsif ($ssl) {
@@ -110,13 +108,13 @@ sub smtp_server {
       print $cl "250 localhost\r\n";
     } elsif ( $cmd eq 'EHLO' ) {
       print $cl "250-localhost\r\n".
-        ( $ssl ? "" : "250-STARTTLS\r\n" ).
-        "250 HELP\r\n";
+        ( $ssl ? "" : "250-STARTTLS\r\n" ).
+        "250 HELP\r\n";
     } elsif ( ! $ssl and $cmd eq 'STARTTLS' ) {
       print $cl "250 starting ssl\r\n";
       if ( ! IO::Socket::SSL->start_SSL($cl, %sslargs)) {
-        diag("initial ssl handshake with client failed");
-        return;
+        diag("initial ssl handshake with client failed");
+        return;
       }
       $ssl = 1;
     } else {
@@ -125,5 +123,5 @@ sub smtp_server {
     }
   }
 
-  diag("SMTP dialog done");
+  note("SMTP dialog done");
 }
diff --git a/t/time.t b/t/time.t
index 43b0e0e..6dcba3a 100644
--- a/t/time.t
+++ b/t/time.t
@@ -6,10 +6,10 @@ use strict;
 use warnings;
 
 BEGIN {
-    if (!eval { require Socket; 1 }) {
+    if (!eval { require Socket }) {
         print "1..0 # no Socket\n"; exit 0;
     }
-    if (ord('A') == 193 && !eval { require Convert::EBCDIC; 1 }) {
+    if (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
         print "1..0 # EBCDIC but no Convert::EBCDIC\n"; exit 0;
     }
     $INC{'IO/Socket.pm'} = 1;