/*
 * ftp.h : Definitions for the asynchronous FTP client
 *
 * George Ferguson, ferguson@cs.rochester.edu, 23 Apr 1993.
 * 28 Apr 1993: Changed constant from _FTP_H to _XA_FTP_H.
 */

#ifndef _XA_FTP_H
#define _XA_FTP_H_

#include <sys/types.h>
#include <netinet/in.h>

#if NeedFunctionPrototypes
struct _FtpContext;
#endif

typedef void (*FtpCallbackProc)(
#if NeedFunctionPrototypes
    struct _FtpContext* ftpc
#endif
);

typedef void (*FtpTraceProc)(
#if NeedFunctionPrototypes
    struct _FtpContext* ftpc,
    int who,		/* 0 => recvd, non-0 => sent */
    char *text
#endif
);

typedef struct _FtpContext {
    /* Connection parameters */
    char *hostname;		/* hostname to contact */
    unsigned short servport;	/* port of ftp service */
    char **h_addr_list;		/* list of host addresses to try */
    char **this_addr;		/* which address are we trying */
    struct sockaddr_in saddr;	/* address of the control connection */
    /* Connection state */
    int state;			/* state of FTP process */
    int iostate;		/* connecting, reading, writing, or ready */
    int reply_state;		/* sub-state during reply parsing */
    int saved_state;		/* saved sub-state during IAC parsing */
    char *cmd;			/* pending part of cmd to send */
    /* Control connection */
    int	ctrl;			/* file descriptor of control connection */
    int	retcode;		/* code of last reply */
    int	tmpcode;		/* scratchpad for continuation lines */
    char reply[BUFSIZ<<4]; 	/* text of last reply */
    int reply_len;		/* length of reply (so far) */
    /* User transfer params */
    char *user;			/* usually anonymous */
    char *pass;			/* usually user@host.dom */
    char *cwd;			/* remote directory */
    char *wd;			/* the part of cwd remaining to do */
    char *local_dir;		/* directory for local files */
    int	type;			/* current transfer mode */
    int	stripcr;		/* 1 if want to remove CR from ASCII files */
    int prompt;			/* 1 to prompt during transfers */
    int filecmd;		/* FTP_GET or FTP_PUT */
    char **files;		/* array of files to GET or PUT */
    int num_files;		/* how many files */
    int this_file;		/* which file are we working on */
    int this_size;		/* how big is it (if we know) */
    FtpTraceProc trace;		/* called to trace transactions */
    FtpCallbackProc done;	/* called when connection finished */
    FtpCallbackProc done1;	/* called when each file transfer finished */
    /* Data connection */
    int	port;			/* the socket on which we will acccept(2) */
    int	data;			/* a data connection established */
    int local_fd;		/* fd for local copy of file (read or write) */
    int num_bytes;		/* bytes transferred this file */
} FtpContext;

extern FtpContext *ftpNewContext(
#if NeedFunctionPrototypes
    char *hostname, char *user, char *pass, char *cwd, char *local_dir,
    int type, int stripcr, int prompt,
    int filecmd, char **files, int num_files,
    FtpTraceProc trace, FtpCallbackProc done1, FtpCallbackProc done
#endif
);

extern void ftpStart(
#if NeedFunctionPrototypes
    FtpContext *ftpc
#endif
);

extern void ftpAbort(
#if NeedFunctionPrototypes
    FtpContext *ftpc
#endif
);

extern void ftpFreeContext(
#if NeedFunctionPrototypes
    FtpContext *ftpc
#endif
);

/*
 * Filecmd codes
 */
#define FTP_GET 1
#define FTP_PUT 2

/* Values for state field of FtpContext */
#define FTPS_OPEN		10
#define FTPS_CONNECT		11
#define FTPS_CONNECTED		12
#define FTPS_USER		13
#define FTPS_PASS		14
#define FTPS_CWD		15
#define FTPS_TYPE		16
#define FTPS_READY		17
#define FTPS_PORT		18
#define FTPS_GETPUT		19
#define FTPS_TRANSFER		20
#define FTPS_EOF		21
#define FTPS_QUIT		22
#define FTPS_ABORT		23
#define FTPS_ABORT2		24

/* Values for reply_state field of FtpContext */
#define FTPS_REPLY_CODE		101
#define FTPS_REPLY_CONT		102
#define FTPS_REPLY_LAST		103
#define FTPS_REPLY_MORE		104
#define FTPS_REPLY_CHCK		105
#define FTPS_REPLY_IAC1		106
#define FTPS_REPLY_IAC2		107
#define FTPS_REPLY_IAC3		108

/*
 * Telnet codes
 */
#ifndef NO_ARPA_H
# include <arpa/ftp.h>
# include <arpa/telnet.h>
#else
  /* <arpa/ftp.h> */
# define TYPE_A          1       /* ASCII */
# define TYPE_E          2       /* EBCDIC */
# define TYPE_I          3       /* image */
# define TYPE_L          4       /* local byte size */
  /* <arpa/telnet.h> */
# define IAC     255             /* interpret as command: */
# define DONT    254             /* you are not to use option */
# define DO      253             /* please, you use option */
# define WONT    252             /* I won't use option */
# define WILL    251             /* I will use option */
# define IP      244             /* interrupt process--permanently */
# define DM      242             /* data mark--for connect. cleaning */
#endif /* !NO_ARPA_H */

/*
 * FTP reply codes, per RFC 959
 */

/* First digit */
#define FTP_REPLY_TYPE(X)	(X/100)
#define FTP_REPLY_PRELIM(X)	(FTP_REPLY_TYPE(X) == 1) /* +ve preliminary  */
#define FTP_REPLY_COMPLETE(X)	(FTP_REPLY_TYPE(X) == 2) /* +ve complete     */
#define FTP_REPLY_CONTINUE(X)	(FTP_REPLY_TYPE(X) == 3) /* +ve intermediate */
#define FTP_REPLY_TRANSIENT(X)	(FTP_REPLY_TYPE(X) == 4) /* -ve transient    */
#define FTP_REPLY_ERROR(X)	(FTP_REPLY_TYPE(X) == 5) /* -ve permanent    */
#define FTP_REPLY_OK(X)		(X < 400)
#define FTP_REPLY_ERR(X)	(X >= 400)

/* Second digit */
#define FTP_REPLY_FUNCTION(X)	((X%100)/10)
#define FTP_REPLY_SYNTAX(X)	(FTP_REPLY_FUNCTION(X) == 0) /* syntax       */
#define FTP_REPLY_INFO(X)	(FTP_REPLY_FUNCTION(X) == 1) /* information  */
#define FTP_REPLY_CONN(X)	(FTP_REPLY_FUNCTION(X) == 2) /* connections  */
#define FTP_REPLY_AUTH(X)	(FTP_REPLY_FUNCTION(X) == 3) /*authentication*/
#define FTP_REPLY_UNSPEC(X)	(FTP_REPLY_FUNCTION(X) == 4) /* unspecified  */
#define FTP_REPLY_FILE(X)	(FTP_REPLY_FUNCTION(X) == 5) /* file system  */

/* Third digit */
#define FTP_REPLY_SPECIFIC(X)	(X%10)

/* Reply Codes by Function Groups (comment text from RFC959) */
#define FTP_COMMAND_OK		200 /* Command okay. */
#define FTP_SYNTAX_ERROR	500 /* Syntax error, command unrecognized.
				       This may include errors such as
				       command line too long. */
#define FTP_PARM_SYNTAX_ERROR	501 /* Syntax error in parameters or
				       arguments. */
#define FTP_CMD_NOT_NEEDED	202 /* Command not implemented, superfluous
				       at this site. */
#define FTP_CMD_NOT_IMPL	502 /* Command not implemented. */
#define FTP_BAD_CMD_SEQ		503 /* Bad sequence of commands. */
#define FTP_CMD_PARM_NOT_IMPL	504 /* Command not implemented for that
				       parameter. */

#define FTP_RESTART_MARKER	110 /* Restart marker reply.
				       In this case, the text is exact and not
				       left to the particular implementation;
				       it must read:
				           MARK yyyy = mmmm
				       Where yyyy is User-process data stream
				       marker, and mmmm server's equivalent
				       marker (note the spaces between markers
				       and "="). */
#define FTP_SYS_STATUS		211 /* System status, or system help reply. */
#define FTP_DIR_STATUS		212 /* Directory status. */
#define FTP_FILE_STATUS		213 /* File status. */
#define FTP_HELP_MSG		214 /* Help message.
				       On how to use the server or the meaning
				       of a particular non-standard command.
				       This reply is useful only to the human
				       user. */
#define FTP_SYS_NAME		215 /* NAME system type.
				       Where NAME is an official system name
				       from the list in the Assigned Numbers
				       document. */
#define FTP_SERVICE_RDY_TIME	120 /* Service ready in nnn minutes. */
#define FTP_SERVICE_RDY_USER	220 /* Service ready for new user. */
#define FTP_SERVICE_CLOSING     221 /* Service closing control connection.
				       Logged out if appropriate. */
#define FTP_SERVICE_UNAVAILABLE	421 /* Service not available, closing control
				       connection. This may be a reply to any
				       command if the service knows it must
				       shut down. */
#define FTP_TRANSFER_STARTING	125 /* Data connection already open; transfer
				       starting. */
#define FTP_DATA_OPEN		225 /* Data connection open; no transfer in
				       progress. */
#define FTP_DATA_FAILED		425 /* Can't open data connection. */
#define FTP_DATA_CLOSE_OK	226 /* Closing data connection.
				       Requested file action successful (for
				       example, file transfer or file abort).*/
#define FTP_DATA_CLOSE_ABORT	426 /* Connection closed; transfer aborted. */
#define FTP_ENTERING_PASSIVE	227 /* Entering Passive Mode
				       (h1,h2,h3,h4,p1,p2). */

#define FTP_LOGIN_OK		230 /* User logged in, proceed. */
#define FTP_LOGIN_ERR		530 /* Not logged in. */
#define FTP_LOGIN_NEED_PASSWD	331 /* User name okay, need password. */
#define FTP_LOGIN_NEED_ACCT	332 /* Need account for login. */
#define FTP_FILE_NEED_ACCT	532 /* Need account for storing files. */

#define FTP_DATACONN_OPEN	150 /* File status okay; about to open data
				       connection. */
#define FTP_FILE_ACTION_OK	250 /* Requested file action okay, completed.*/
#define FTP_PATHNAME_CREATED	257 /* "PATHNAME" created. */
#define FTP_FILE_ACTION_PENDING	350 /* Requested file action pending further
				       information. */
#define FTP_FILE_UNAVAILABLE	450 /* Requested file action not taken.
				       File unavailable (e.g., file busy). */
#define FTP_ACTION_NOT_TAKEN	550 /* Requested action not taken.
				       File unavailable (e.g., file not found,
				       no access). */
#define FTP_ABORTED_LOCAL_ERR	451 /* Requested action aborted. Local error
				       in processing. */
#define FTP_ABORTED_PAGE_TYPE	551 /* Requested action aborted. Page type
				       unknown. */
#define FTP_INSUFFICIENT_SPACE	452 /* Requested action not taken.
				       Insufficient storage space in system.*/
#define FTP_EXCEEDED_ALLOCATION	552 /* Requested file action aborted.
				       Exceeded storage allocation (for
				       current directory or dataset). */
#define FTP_BAD_FILENAME	553 /* Requested action not taken.
				       File name not allowed. */

#endif /* !_XA_FTP_H */
