> ## 5. FTP Client

> The library `FTP_CLIENT.LIB` implements the File Transfer Protocol (FTP) for the client side of the connection.

> ### 5.1 Configuration Macros

> The following macros may be defined in a `#define` statement before the inclusion of `FTP_CLIENT.LIB` in an application program. Note that strings must contain the `NULL` byte, so if a maximum string length is 16, the maximum number of characters is 15.

> #### FTP_MAX_DIRLEN

> The default is 64, which is the maximum string length of a directory name.

> #### FTP_MAX_FNLEN

> The default is 16, which is the maximum string length of a file name.

> #### FTP_MAX_NAMELEN

> The default is 16 which is the maximum string length of usernames and passwords.

> #### FTP_MAXLINE

> The default is 256, which is both the maximum command line length and data chunk size that can be passed between server and client.

> #### FTP_TIMEOUT

> The default is 16, which is the number of seconds that pass before a time out occurs.

> ### 5.2 Functions

> ## ftp_client_setup

>     int ftp_client_setup( long host, int port, char *username, char *password, int mode,  char *filename, char *dir, char *buffer, int length );

> ### Description

> Sets up a FTP transfer. It is called first, then `ftp_client_tick()` is called until it returns non-zero. Failure can occur if the host address is zero, if `length` is negative, or if the internal control socket to the FTP server cannot be opened (e.g. because of lack of socket buffers).

> ### Parameters

> #### host

> Host IP address of FTP server.

> #### port

> Port of FTP server, 0 for default.

> #### username

> Username of account on FTP server.

> #### password

> Password of account on FTP server.

> #### mode

> Mode of transfer: `FTP_MODE_UPLOAD` or`FTP_MODE_DOWNLOAD`. You may also OR in the value `FTP_MODE_PASSIVE` to use passive mode transfer (important if you are behind a firewall).

> #### filename

> Filename to get/put.

> #### dir

> Directory file is in, `NULL` for default directory.

> #### buffer

> Buffer to get/put the file from/to. Must be `NULL` if a data handler function will be used. See `ftp_data_handler()` for more details.

> #### length

> On upload, length of file; on download size of buffer. This parameter limits the transfer size to a maximum of 32767 bytes. For larger transfers, it will be necessary to use a data handler function.

> ### Return value

> `0`: Success.
> `1`: Failure.

> ### Library

> FTP_CLIENT.LIB

> ### See Also

> ftp_client_tick, ftp_data_handler

> ## ftp_client_tick

>     int ftp_client_tick(void);

> ### Description

> Tick function to run the FTP daemon. Must be called periodically. The return codes are not very specific. You can call `ftp_last_code()` to get the integer value of the last FTP message received from the server. See RFC959 for details. For example, code 530 means that the client was not logged in to the server.

> ### Return value

> `FTPC_AGAIN (0)`: still pending, call again.
> `FTPC_OK (1)`: success (file transfer complete).
> `FTPC_ERROR (2)`: failure (call `ftp_last_code()` for more details).
> `FTPC_NOHOST (3)`: failure (Couldn't connect to remote host).
> `FTPC_NOBUF (4)`: failure (no buffer or data handler).
> `FTPC_TIMEOUT` (5): warning (Timed out on close: data may or may not be OK).
> `FTPC_DHERROR` (6): error (Data handler error in `FTPDH_END` operation).

> ### Library

> FTP_CLIENT.LIB

> ### See Also

> ftp_client_setup, ftp_client_filesize, ftp_client_xfer, ftp_last_code

> ## ftp_client_filesize

>     int ftp_client_filesize(void);

> ### Description

> Returns the byte count of data transferred. This function is deprecated in favor of `ftp_client_xfer()`, which returns a long value.

> If the number of bytes transferred was over 32767, then this function returns 32767 which may be misleading.

> ### Return value

> Size, in bytes.

> ### Library

> FTP_CLIENT.LIB

> ### See Also

> ftp_client_setup, ftp_data_handler, ftp_client_xfer

> ## ftp_client_xfer

>     longword ftp_client_xfer(void);

> ### Description

> Returns the byte count of data transferred. Transfers of over 232 bytes (about 4GB) are not reported correctly.

> ### Return Value

> Size, in bytes.

> ### Library

> FTP_CLIENT.LIB

> ### See Also

> ftp_client_setup, ftp_data_handler, ftp_client_filesize

> ## ftp_data_handler

>     void ftp_data_handler(int (*dhnd)(), void * dhnd_data, word opts);

> ### Description

> Sets a data handler for further FTP data transfer(s). This handler is only used if the "buffer" parameter to `ftp_client_setup()` is passed as `NULL`.

> The handler is a function which must be coded according to the following prototype:

> int my_handler(char * data, int len, longword offset, int flags, void * dhnd_data);

> This function is called with `data` pointing to a data buffer, and `len` containing the length of that buffer. `offset` is the byte number relative to the first byte of the entire FTP stream. This is useful for data handler functions that do not wish to keep track of the current state of the data source. `dhnd_data` is the pointer that was passed to `ftp_data_handler()`.

> `flags` contains an indicator of the current operation:

> · `FTPDH_IN`: data is to be stored on this host (obtained from an FTP download).
> · `FTPDH_OUT`: data is to be filled with the next data to upload to the FTP server.
> · `FTPDH_END`: data and len are irrelevant: this marks the end of data, and gives the function an opportunity to e.g. close the file. Called after either in or out processing.
> · `FTPDH_ABORT`: end of data; error encountered during FTP operation. Similar to END except the transfer did not complete. Can use this to e.g. delete a partially written file.

> The return value from this function depends on the in/out flag. For `FTPDH_IN`, the function should return `len` if the data was processed successfully and download should continue; -1 if an error has occurred and the transfer should be aborted. For `FTPDH_OUT`, the function should return the actual number of bytes placed in the data buffer, or -1 to abort. If zero is returned, then the upload is terminated normally. For `FTPDH_END`, the return code should be zero for success or -1 for error. If an error is flagged, then this is used as the return code for `ftp_client_tick()`. For `FTPDH_ABORT`, the return code is ignored.

> ftp_data_handler (continued)

> ### Parameters

> #### dhnd

> Pointer to data handler function, or `NULL` to remove the current data handler.

> #### dhnd_data

> A pointer which is passed to the data handler function. This may be used to point to any further data required by the data handler such as an open file descriptor.

> #### opts

> Options word (currently reserved, set to zero).

> ### Library

> FTP_CLIENT.LIB

> ### See Also

> ftp_client_setup

> ## ftp_last_code

>     int ftp_last_code(void);

> ### Description

> Returns the most recent message code sent by the FTP server. RFC959 describes the codes in detail. This function is most useful for error diagnosis in the case that an FTP transfer failed.

> Return Value

> Error code; a number between 0 and 999. Codes less than 100 indicate that an internal error occurred e.g. the server was never contacted.

> ### Library

> FTP_CLIENT.LIB

> ### See Also

> ftp_client_setup, ftp_client_tick

> ### 5.3 Sample FTP Transfer

> #### Program Name: samples/tcpip/ftp/ftp_client.c

>     #define MY_IP_ADDRESS "10.10.6.105"
>     #define MY_NETMASK "255.255.255.0"

>     #memmap xmem
>     #use "dcrtcp.lib"
>     #use "ftp_client.lib"

>     #define REMOTE_HOST "10.10.6.19"
>     #define REMOTE_PORT 0

>     main() {
>         char buf[2048];
>         int ret, i, j;

>         printf("Calling sock_init()...\n");
>         sock_init();

>     /* Set up the ftp transfer. This is to the host defined above,
>      with a normal anonymous/e-mail password login info. A get
>      of the file "bar" is requested, which will be stored in 'buf.'*/

>        printf("Calling ftp_client_setup()...\n");

>        if(ftp_client_setup(resolve(REMOTE_HOST),REMOTE_PORT, anonymous", "anon@anon.com",FTP_MODE_DOWNLOAD,"bar", NULL,buf,sizeof(buf)))

>        {
>           printf("FTP setup failed.\n");
>           exit(0);
>        }
>        printf("Looping on ftp_client_tick()...\n");
>        while( 0 == (ret = ftp_client_tick()) )
>           continue;

>        if( 1 == ret ) {
>           printf("FTP completed successfully.\n");

>         /* ftp_client_filesize() returns the size of the transfer,
>              since we requested a download.*/

>           buf[ftp_client_filesize()] = '\0';
>           printf("Data => '%s'\n", buf);
>        } else {
>           printf("FTP failed: status == %d\n",ret);
>        }
>     }

> ####

Z-World http://www.zworld.com Voice: 530.757.3737 Fax: 530.757.3792 or 530.753.5141 sales@zworld.com