<< Previous | Index | Next >>

6. FTP Client

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

This library supports a single FTP session at any one time since the session state is maintained in a single global structure in root memory.

You can upload and download files to either a static buffer in root data memory (for simple applications) or, starting with Dynamic C version 7.20, you can have the data passed to, or generated by, a data handler callback function that you specify. The data handler function can implement large file transfers in extended memory buffers, or it can be used to generate or process data on-the-fly with minimal buffering.

Starting with Dynamic C 7.20, you can specify "passive" mode transfers. This is most important for clients which are inside a firewall. Passive mode is specified by passing the FTP_MODE_PASSIVE option to ftp_client_setup(). When passive mode is specified, the client will actively open the data transfer port to the server, rather than the other way around. This avoids the need for the server to penetrate the firewall with an active connection from the outside, which is most often blocked by the firewall. For this reason, it is recommended that your FTP client application uses passive mode by default, unless overridden by an end-user.

6.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 the FTP data transfer socket and the data handler (if any defined).

FTP_TIMEOUT

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

6.2 API 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).
FTPC_CANCELLED (7): FTP control socket was aborted (reset) by the server.

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.

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

6.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"

#define TCPCONFIG 1

#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 transfer size, since we asked for download.
buf[ftp_client_filesize()] = '\0';

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


TCP/IP Manual
Vol. 2
<< Previous | Index | Next>> rabbit.com