|new( HOST [, OPTIONS ] )||
Creates a new <B>Net::FTPSSLB> object and opens a connection with the
HOST. HOST is the address of the FTPS server and its a required
argument. OPTIONS are passed in a hash like fashion, using key and value
pairs. If you wish you can also pass OPTIONS as a hash reference.
<B>EncryptionB> - The connection can be implicitly (<B>IMP_CRYPTB>) encrypted, explicitly (<B>EXP_CRYPTB>) encrypted, or regular FTP (<B>CLR_CRYPTB>). In explicit cases the connection begins clear and became encrypted after an AUTH command is sent, while implicit starts off encrypted. For <B>CLR_CRYPTB>, the connection never becomes encrypted. Default value is <B>EXP_CRYPTB>.
<B>PortB> - The port number to connect to on the remote FTPS server. The default port is 21 for <B>EXP_CRYPTB> and <B>CLR_CRYPTB>. But for <B>IMP_CRYPTB> the default port is 990. You only need to provide a port if you need to override the default value.
<B>DataProtLevelB> - The level of security on the data channel. The default is <B>DATA_PROT_PRIVATEB>, where the data is also encrypted. <B>DATA_PROT_CLEARB> is for data sent as clear text. <B>DATA_PROT_SAFEB> and <B>DATA_PROT_CONFIDENTIALB> are not currently supported. If <B>CLR_CRYPTB> was selected, the data channel is always <B>DATA_PROT_CLEARB> and cant be overridden.
<B>ProxyArgsB> - A hash reference to pass to the proxy server. When a proxy server is encountered, this class uses Net::HTTPTunnel to get through to the server you need to talk to. See Net::HTTPTunnel for what values are supported. Options remote-host and remote-port are hard coded to the same values as provided by HOST and PORT above and can not be overriden.
<B>PretB> - Set if you are talking to a distributed FTPS server like DrFtpd that needs a <B>PRETB> command issued before all calls to <B>PASVB>. You only need to use this option if the server barfs at the <B>PRETB> auto-detect logic.
<B>DebugLogFileB> - Redirects the output of <B>DebugB> from STDERR to the requested error log file name. This option is ignored unless <B>DebugB> is also turned on. Enforced this way for backwards compatibility. If <B>DebugB> is set to <B>2B>, the log file will be opened in append mode instead of creating a new log file. This log file is closed when this class instance goes out of scope.
Instead of a file name, you may instead specify an open file handle or GLOB and it will write the logs there insead. (Not really recommended.)
<B>CroakB> - Force most methods to call croak() on failure instead of returning FALSE. The default is to return FALSE or undef on failure. When it croaks, it will attempt to close the FTPS connection as well, preserving the last message before it attempts to close the connection. Allowing the server to know the client is going away. This will cause $Net::FTPSSL::ERRSTR to be set as well.
<B>SSL_Client_CertificateB> - Expects a reference to a hash. Its main purpose is to allow you to use client certificates when talking to your FTP/S server. Options here apply to the creation of the command channel. And when a data channel is needed later, it uses the <B>SSL_reuse_ctxB> option to reuse the command channels context.
See start_SSL() in IO::Socket::SSL for more details on this and other options available besides those for certificates. If an option provided via this hash conflicts with other options we would normally use, the entries in this hash take precedence. If all you want to do is have the data channel use <B>SSL_reuse_ctxB>, just provide an empty hash.
<B>OverridePASVB> - Some FTPS servers sitting behind a firewall incorrectly return their local IP Address instead of their external IP Address used outside the firewall where the client is. To use this option to correct this problem, you must specify the correct host to use for the data channel connection. This should usually match what you provided as the host! But if this server also does load balancing, you are out of luck. This option cant help you if multiple IP Addresses are returned.
<B>OverrideHELPB> - Some FTPS servers on encrypted connections incorrectly send back part of the response to the <B>HELPB> command in clear text instead of it all being encrypted, breaking the command channel connection. This class calls <B>HELPB> internally via supported() for some conditional logic, making a work around necessary to be able to talk to such servers.
This option supports three distinct modes to support your needs. You can pass a reference to an array that lists all the <B>FTPB> commands your sever supports, you can set it to <B>1B> to say all commands are supported, or set it to <B>0B> to say none of the commands are supported. See supported() for more details.
This option can also be usefull when your server doesnt support the HELP command itself and you need to trigger some of the conditional logic.
Most of the methods return true or false, true when the operation was a success and false when failed. Methods like <B>listB> or <B>nlstB> return an empty array when they fail. This behavior can be modified by the <B>CroakB> option.
login( USER, PASSWORD ) Use the given information to log into the FTPS server. quit() This method breaks the connection to the FTPS server. force_epsv( [1/2] ) Used to force <B>EPSVB> instead of <B>PASVB> when establishing a data channel. Once this method is called, it is imposible to swap back to <B>PASVB>. This method should be called as soon as possible after you log in if <B>EPSVB> is required.
After "<B>EPSV ALLB>" is sent, it will attempt to verify your choice of IP Protocol to use: <B>1B> or <B>2B> (v4 or v6). The default is <B>1B>. It will use the selected protocol for all future <B>EPSVB> calls. If you need to change which protocol to use, you may call this function a second time to swap to the other <B>EPSVB> Protocol.
set_croak( [1/0] ) Used to turn the Croak option on/off after the Net::FTPSSL object has been created. It returns the previous Croak settings before the change is made. If you dont provide an argument, all it does is return the current setting. Provided in case the Croak option proves to be too restrictive in some cases. list( [DIRECTORY [, PATTERN]] ) This method returns a list of files in a format similar to this: (Server Specific)
drwxrwx--- 1 owner group 512 May 31 11:16 . drwxrwx--- 1 owner group 512 May 31 11:16 .. drwxrwx--- 1 owner group 512 Oct 27 2004 foo drwxrwx--- 1 owner group 512 Oct 27 2004 pub drwxrwx--- 1 owner group 512 Mar 29 12:09 bar
If DIRECTORY is omitted, the method will return the list of the current directory.
If PATTERN is provided, it would limit the result similar to the unix ls command or the Windows dir command. The only wild cards supported are <B>*B> and <B>?B>. (Match 0 or more chars. Or any one char.) So a pattern of f*, ?Oo or FOO would find just foo from the list above. Files with spaces in their name can cause strange results when searching for a pattern.
nlst( [DIRECTORY [, PATTERN]] ) Same as list but returns the list in this format:
foo pub bar
Spaces in the filename do not cause problems with the PATTERN with nlst. Personally, I suggest using nlst instead of list.
ascii() Sets the file transfer mode to ASCII. CR LF transformations will be done. ASCII is the default transfer mode. binary() Sets the file transfer mode to binary. No CR LF transformation will be done. mixedModeAI() Mixture of ASCII & binary mode. The server does CR LF transfernations while the client side does not. (For a really weird server) mixedModeIA() Mixture of binary & ASCII mode. The client does CR LF transfernations while the server side does not. (For a really weird server) put( LOCAL_FILE [, REMOTE_FILE [, OFFSET]] ) Stores the LOCAL_FILE onto the remote ftps server. LOCAL_FILE may be a file handle, but in this case REMOTE_FILE is required. It returns <B>undefB> if put() fails.
If you provide an OFFSET, this method assumes you are attempting to continue with an upload that was aborted earlier. And its your responsibility to verify that its the same file on the server you tried to upload earlier. By providing the OFFSET, this function will send a <B>RESTB> command to the FTPS Server to skip over that many bytes before it starts writing to the file. This method will also skip over the requested OFFSET after opening the LOCAL_FILE for reading, but if passed a file handle it will assume youve already positioned it correctly. If you provide an OFFSET of <B>-1B>, this method will calculate the offset for you by issuing a SIZE command against the file on the FTPS server. So REMOTE_FILE must already exist to use <B>-1B>, or its an error. It is also an error to make OFFSET larger than the REMOTE_FILE.
If the OFFSET you provide turns out to be smaller than the current size of REMOVE_FILE, the server will truncate the REMOTE_FILE to that size before appending to the end of REMOTE_FILE. (This may not be consistent across all FTPS Servers, so dont depend on this feature without testing it first.)
If the option PreserveTimestamp was used, and the FTPS server supports it, it will attempt to reset the timestamp on REMOTE_FILE to the timestamp on LOCAL_FILE.
append( LOCAL_FILE [, REMOTE_FILE [, OFFSET]] ) Appends the LOCAL_FILE onto the REMOTE_FILE on the ftps server. If REMOTE_FILE doesnt exist, the file will be created. LOCAL_FILE may be a file handle, but in this case REMOTE_FILE is required and OFFSET is ignored. It returns <B>undefB> if append() fails.
If you provide an OFFSET, it will skip over that number of bytes in the LOCAL_FILE except when it was a file handle, but <B>will notB> send a <B>RESTB> command to the server. It will just append to the end of REMOTE_FILE on the server. You can also provide an OFFSET of <B>-1B> with the same limitations as with put(). If you need the <B>RESTB> command sent to the FTPS server, use put() instead.
If the option PreserveTimestamp was used, and the FTPS server supports it, it will attempt to reset the timestamp on REMOTE_FILE to the timestamp on LOCAL_FILE.
uput( LOCAL_FILE, [REMOTE_FILE] ) Stores the LOCAL_FILE onto the remote ftps server. LOCAL_FILE may be a file handle, but in this case REMOTE_FILE is required. If REMOTE_FILE already exists on the ftps server, a unique name is calculated by the server for use instead.
If the file transfer succeeds, this function will return the actual name used on the remote ftps server. If it cant figure that out, it will return what was used for REMOTE_FILE. On failure this method will return <B>undefB>.
If the option PreserveTimestamp was used, and the FTPS server supports it, it will attempt to reset the timestamp on the remote file using the file name being returned by this function to the timestamp on LOCAL_FILE. So if the wrong name is being returned, the wrong file will get its timestamp updated.
xput( LOCAL_FILE, [REMOTE_FILE, [PREFIX, [POSTFIX, [BODY]]]] ) Use when the directory you are dropping REMOTE_FILE into is monitored by a file recognizer that might pick the file up before the file transfer has completed. So the file is transferred using a temporary name using a naming convention that the file recognizer will ignore and is guaranteed to be unique. Once the file transfer successfully completes, it will be renamed to REMOTE_FILE for immediate pickup by the file recognizer. If you requested to preserve the files timestamp, this step is done after the file is renamed and so cant be 100% guaranteed if the file recognizer picks it up first. Since if it was done before the rename, other more serious problems could crop up if the resulting timestamp was old enough.
On failure this function will attempt to delete the scratch file for you if its at all possible. You will have to talk to your FTPS server administrator on good values for PREFIX and POSTFIX if the defaults are no good for you.
<B>PREFIXB> defaults to _tmp. unless you override it. Set to "" if you need to suppress the PREFIX. This PREFIX can be a path to another directory if needed, but that directory must already exist! Set to undef to keep this default and you need to change the default for POSTFIX or BODY.
So the temp scratch file would be called something like this by default: _tmp.testclient.51243.tmp.
As a final note, if REMOTE_FILE has path information in its name, the temp scratch file will have the same directory added to it unless you override the PREFIX with a different directory to drop the scratch file into. This avoids forcing you to change into the requested directory first when you have multiple files to send out into multiple directories.
get( REMOTE_FILE [, LOCAL_FILE [, OFFSET]] ) Retrieves the REMOTE_FILE from the ftps server. LOCAL_FILE may be a filename or a file handle. It returns <B>undefB> if get() fails. You dont usually need to use OFFSET.
If you provide an OFFSET, this method assumes your are attempting to continue with a download that was aborted earlier. And its your responsibility to verify that its the same file you tried to download earlier. By providing the OFFSET, it will send a <B>RESTB> command to the FTPS Server to skip over that many bytes before it starts downloading the file again. If you provide an OFFSET of <B>-1B>, this method will calculate the offset for you based on the size of LOCAL_FILE using the current transfer mode. (ASCII or BINARY). It is an error to set it to <B>-1B> if the LOCAL_FILE is a file handle.
On the client side of the download, the OFFSET will do the following: Open the file and truncate everything after the given OFFSET. So if you give an OFFSET that is too big, its an error. If its too small, the file will be truncated to that OFFSET before appending whats being downloaded. If the LOCAL_FILE is a file handle, it will assume the file handle has already been positioned to the proper OFFEST and it will not perform a truncate. Instead it will just append to that file handles current location. Just beware that using huge OFFSETs in <B>ASCIIB> mode can be a bit slow if the LOCAL_FILE needs to be truncated.
If the option PreserveTimestamp was used, and the FTPS Server supports it, it will attempt to reset the timestamp on LOCAL_FILE to the timestamp on REMOTE_FILE after the download completes.
xget( REMOTE_FILE, [LOCAL_FILE, [PREFIX, [POSTFIX, [BODY]]]] ) The inverse of xput, where the file recognizer is on the client side. The only other difference being what <B>BODYB> defaults to. It defaults to reverse(testclient).PID. So your default scratch file would be something like: _tmp.tneilctset.51243.tmp. transfer( dest_server, REMOTE_FILE [, DEST_FILE [, OFFSET]] ) Retrieves the REMOTE_FILE from the current ftps server and uploads it to the dest_server as DEST_FILE without making any copy of the file on your local file system. If DEST_FILE isnt provided, it uses REMOTE_FILE on the dest_server.
It assumes that you have already successfully logged onto dest_server and set both ends to either binary or ascii mode! So this function skips over the CR/LF logic and lets the other servers handle it. You must also set the Croak option to the same value on both ends.
Finally, if logging is turned on, the logs to this function will be split between the logs on each system. So the logs may be a bit of a pain to follow since youd need to look in two places for each half.
xtransfer( dest_server, REMOTE_FILE, [DEST_FILE, [PREFIX, [POSTFIX, [BODY]]]] )
Same as transfer, but it uses a temporary filename on the dest_server during the transfer. And then renames it to DEST_FILE afterwards.
See xput for the meaning of the remaining parameters.
delete( REMOTE_FILE ) Deletes the indicated REMOTE_FILE. cwd( DIR ) Attempts to change directory to the directory given in DIR on the remote server. pwd( ) Returns the full pathname of the current directory on the remote server. cdup( ) Changes directory to the parent of the current directory on the remote server. mkdir( DIR ) Creates the indicated directory DIR on the remote server. No recursion at the moment. rmdir( DIR ) Removes the empty indicated directory DIR on the remote server. No recursion at the moment. noop( ) It requires no action other than the server send an OK reply. rename( OLD, NEW ) Allows you to rename the file on the remote server. site( ARGS ) Send a SITE command to the remote server and wait for a response. mfmt( time_str, remote_file ) or _mfmt( timestamp, remote_file ) Both are boolean functions that attempt to reset the remote files timestamp on the FTPS server and returns true on success. The 1st version can call croak on failure if Croak is turned on, while the 2nd version will not do this. The other difference between these two functions is the format of the files timestamp to use.
time_str expects the timestamp to be GMT time in format YYYYMMDDHHMMSS. While timestamp expects to be in the same format as returned by localtime().
mdtm( remote_file ) or _mdtm( remote_file ) The 1st version returns the files timestamp as a string in YYYYMMDDHHMMSS format using GMT time, it will return undef or call croak on failure.
The 2nd version returns the files timestamp in the same format as returned by localtime() and will never call croak.
size( remote_file ) This function will return undef or croak on failure. Otherwise it will return the files size in bytes, which may also be zero bytes! Just be aware for text files that the size returned may not match the files actual size after the file has been downloaded to your system in ASCII mode. This is an OS specific issue. It will always match if you are using BINARY mode.
Also SIZE may return a different size for ASCII & BINARY modes. This issue depends on what OS the FTPS server is running under. Should they be different, the ASCII size will be the BINARY size plus the number of lines in the file.
last_message() or message() Use either one to collect the last response from the FTPS server. This is the same response printed to STDERR when Debug is turned on. It may also contain any fatal error message encountered.
If you couldnt create a Net::FTPSSL object, you should get your error message from $Net::FTPSSL::ERRSTR instead. Be careful since $Net::FTPSSL::ERRSTR is shared between instances of Net::FTPSSL, while message & last_message <B>are notB> shared between instances!
last_status_code( ) Returns the one digit status code associated with the last response from the FTPS server. The status is the first digit from the full 3 digit response code. quot( CMD [,ARGS] ) Send a command, that Net::FTPSSL does not directly support, to the remote server and wait for a response. You are responsible for parsing anything you need from message() yourself.
<B>WARNINGB> This call should only be used on commands that do not require data connections. Misuse of this method can hang the connection if the internal list of FTP commands using a data channel is incomplete.
ccc( [ DataProtLevel ] ) Sends the clear command channel request to the FTPS server. If you provide the DataProtLevel, it will change it from the current data protection level to this one before it sends the <B>CCCB> command. After the <B>CCCB> command, the data channel protection level can not be changed again and will always remain at this setting. Once you execute the <B>CCCB> request, you will have to create a new Net::FTPSSL object to secure the command channel again. Due to security concerns it is recommended that you do not use this method. supported( CMD [,SITE_OPT] ) Returns <B>TRUEB> if the remote server supports the given command. CMD must match exactly. This function will ignore the <B>CroakB> request.
If the CMD is SITE or FEAT and SITE_OPT is supplied, it will also check if the specified SITE_OPT sub-command is supported by that command. Not all servers will support the use of SITE_OPT.
It determines if a command is supported by calling <B>HELPB> and parses the results for a match. And if <B>FEATB> is supported it calls <B>FEATB> and adds these commands to the <B>HELPB> list. The results are cached so <B>HELPB> and <B>FEATB> are only called once.
Some rare servers send the <B>HELPB> results partially encrypted and partially in clear text, causing the encrypted channel to break. In that case you will need to override this method for things to work correctly with these non-conforming servers. See the OverrideHELP option in the constructor for how to do this.
This method is used internally for conditional logic usually when checking if the following 5 FTP commands are allowed: <B>ALLOB>, <B>NOOPB>, <B>HELPB>, <B>MFMTB> and <B>MDTMB>. The <B>ALLOB> command is checked during all put/get command sequences. The other four commands are not checked as often. The functions xput and xtransfer also tests for four more commands: <B>STORB>, <B>DELEB>, <B>RNFRB> and <B>RNTOB>.
all_supported( CMD1 [, CMD2 [, CMD3 [, CMD4 [, ...]]]] ) Similar to supported, except that it tests everything in this list of one or more FTP commands passed to it to see if they are supported. If the list is empty, or if even one command in the list isnt supported, it returns <B>FALSEB>. Otherwise it returns <B>TRUEB>. It will also ignore the <B>CroakB> request. restart( OFFSET ) Set the byte offset at which to begin the next data transfer. Net::FTPSSL simply records this value and uses it during the next data transfer. For this reason this method will never return an error, but setting it may cause subsequent data transfers to fail.
I recommend using the OFFSET directly in get(), put(), and append() instead of using this method. It was only added to make Net::FTPSSL compatible with Net::FTP. A non-zero offset in those methods will override what you provide here. If you call any of the other get()/put() variants after calling this function, you will get an error.
It is OK to use an OFFSET of <B>-1B> here to have Net::FTPSSL calculate the correct OFFSET for you before it gets used. Just like if you had provided it directly to the get(), put(), and append() calls.
This OFFSET will be automatically zeroed out after the 1st time it is used.
set_dc_from_hash( HASH ) This function provides you a way to micro manage the SSL characteristics of the FTPS Data Channel without having to hack the Net::FTPSSL code base. It should be called as soon as possible after the call to <B>B>new()<B>B>.
It takes a HASH as its argument. Either by value or by address. This hash of key/value pairs will be used to control the Data Channel SSL options.
If the keys value is set to undef, it is an instruction to delete an existing Data Channel option. If the key has a value it is an instruction to add this key/value pair to the Data Channel options. If the option already exists, it will override that value.
It returns the number of entries updated for the Data Channel.
copy_cc_to_dc( FORCE, ARRAY ) This function provides you a way to copy some of the SSL options used to manage the Command Channel over to the Data Channel as well without having to hack the Net::FTPSSL code base. It should be called as soon as possible after the call to <B>B>new()<B>B>.
It takes an ARRAY as its arguments. Either by value or by address. It looks up each array value in the Command Channels SSL characteristics and copies them over to use as a Data Channel option.
If the option doent exist for the Command Channel, that array entry is ignored.
If the option is already set in the Data Channel, the array entry overrides the current value in the Data Channel.
It returns the number of entries updated for the Data Channel.
set_callback( [cb_func_ref, end_cb_func_ref [, cb_data_ref]] ) This function allows the user to define a callback function to use whenever a data channel to the server is open. If either <B>cb_func_refB> or <B>end_cb_func_refB> is undefined, it disables the callback functionality, since both are required for call backs to function properly.
The <B>cb_func_refB> is a reference to a function to handle processing the data channel data. This is a void function that can be called multiple times. It is called each time a chunk of data is read from or written to the data channel.
The <B>end_cb_func_refB> is a reference to a function to handle closing the callback for this data channel connection. This function is allowed to return a string of additional data to process before the data channel is closed. It is called only once per command after processing all the data channel data.
The <B>cb_data_refB> is an optional reference to an array or hash that the caller can use to store values between calls to the callback function and the end callback function. If you dont need such a work area, its safe to not provide one. The Net::FTPSSL class doesnt look at this reference.
B<callback> (ftps_func_name, data_ref, data_len_ref, total_len, cb_data_ref);
The ftps_func_name will tell what Net::FTPSSL function requested the callback so that your callback function can determine what the data is for and do conditional logic accordingly. We dont provide a reference to the Net::FTPSSL object itself since the class is not recursive. Each Net::FTPSSL object should have its own cb_dat_ref to work with. But methods within the class can share one.
Since we pass the data going through the data channel as a reference, you are allowed to modify the data. But if you do, be sure to update data_len_ref to the new data length as well if it changes. Otherwise you will get buggy responses. Just be aware that if you change the length, more than likely youll be unable to reliably restart an upload or download via restart() or using OFFSET in the put & get commands.
Finally, the total_len is how many bytes have already been processed. It does not include the data passed for the current callback call. So it will always be zero the first time its called.
Once we finish processing data for the data channel, a different callback function will be called to tell you that the data channel is closing. That will be your last chance to affect what is going over the data channel and to do any needed post processing. The end callback function must take the following arguments:
$end = B<end_callback> (ftps_func_name, total_len, cb_data_ref);
These arguments have the same meaning as for the callback function, except that this function allows you to optionally provide additional data to/from the data channel. If reading from the data channel, it will treat the return value as the last data returned before it was closed. Otherwise it will be written to the data channel before it is closed. Please return undef if there is nothing extra for the Net::FTPSSL command to process.
You should also take care to clean up the contents of cb_data_ref in the end_callback function. Otherwise the next callback sequence that uses this work area may behave strangely.
As a final note, should the data channel be empty, it is very likely that just the end_callback function will be called without any calls to the callback function.
get_log_filehandle() Returns the open file handle for the file specified by the <B>DebugLogFileB> option specified by new(). If you did not use this option, it will return undef.
Just be aware that once this object goes out of scope, the returned file handle becomes invalid.
trapWarn() This method is only active if Debug is turned on with DebugLogFile provided as well. Otherwise calling it does nothing. This trap for warnings is automatically turned off when the the instance of this class goes out of scope. It returns <B>1B> if the trap was turned on, else <B>0B> if it wasnt.
Calling this method causes all <B>PerlB> warnings to be written to the log file you specified when you called new(). The warnings will appear in the log file when they occur to assist in debugging this module. It automatically puts the word WARNING: in front of the message being logged.
So this method is only really useful if you wish to open a <B>CPANB> ticket to report a problem with Net::FTPSSL and you think having the generated warning showing up in the logs will help in getting your issue resolved.
You may call this method for multiple Net::FTPSSL instances and it will cause the warning to be written to multiple log files.
If your program already traps warnings before you call this method, this code will forward the warning to your trap logic as well.
The logs generated by Net::FTPSSL are very easy to interpret. After you get past the initial configuration information needed to support opening a CPAN ticket, its basically the <B>FTPSB> traffic going back and forth between your perl Client and the FTPS Server you are talking to.
Each line begins with a prefix that tells what is happening.
>>> - Represents outbound traffic sent to the FTPS Server.
<<< - Represents inbound traffic received from the FTPS Server.
<<+ - Represents messages from Net::FTPSSL itself in response to a request that doesnt hit the FTPS Server.
WARNING: - Represents a trapped perl warning written to the logs.
SKT >>> & SKT <<< represent socket traffic before the Net::FTPSSL object gets created.
There are a couple of other rare variants to the above theme. But they are purely information only. So this is basically it.
Marco Dalla Stella - <kral at paranoici dot org>
Curtis Leach - <cleach at cpan dot org> - As of v0.05
RFC 959 - <http://www.rfc-editor.org/info/rfc959>
RFC 2228 - <http://www.rfc-editor.org/info/rfc2228>
RFC 2246 - <http://www.rfc-editor.org/info/rfc2246>
RFC 4217 - <http://www.rfc-editor.org/info/rfc4217>
Graham Barr <gbarr at pobox dot com> - for have written such a great collection of modules (libnet).
Please report any bugs with a FTPS log file created via options <B>Debug=>1B> and <B>DebugLogFile=>file.txtB> along with your sample code at <http://search.cpan.org/~cleach/Net-FTPSSL-0.30/FTPSSL.pm> or <https://metacpan.org/pod/Net::FTPSSL>.
Patches are appreciated when a log file and sample code are also provided.
Copyright (c) 2009 - 2015 Curtis Leach. All rights reserved.
Copyright (c) 2005 Marco Dalla Stella. All rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
|perl v5.20.3||FTPSSL (3)||2015-08-14|