/*
**  Copyright 2000-2002 University of Illinois Board of Trustees
**  Copyright 2000-2002 Mark D. Roth
**  All rights reserved.
**
**  libfget.h - header file for libfget
**
**  Mark D. Roth <roth@uiuc.edu>
**  Campus Information Technologies and Educational Services
**  University of Illinois at Urbana-Champaign
*/

#ifndef LIBFGET_H
#define LIBFGET_H

#include <netdb.h>
#include <sys/types.h>
#include <sys/param.h>
#include <fcntl.h>


#ifndef MAXUSERNAMELEN
# define MAXUSERNAMELEN		16	/* max length of user name */
#endif

#ifndef MAXGROUPNAMELEN
# define MAXGROUPNAMELEN	8	/* max length of group name */
#endif

/* macros for bitfield manipulation */
#define BIT_ISSET(bitfield, opt) ((bitfield) & (opt))
#define BIT_SET(bitfield, opt) ((bitfield) |= (opt))
#define BIT_CLEAR(bitfield, opt) ((bitfield) &= ~(opt))
#define BIT_TOGGLE(bitfield, opt) { \
  if (BIT_ISSET(bitfield, opt)) \
    BIT_CLEAR(bitfield, opt); \
  else \
    BIT_SET(bitfield, opt); \
}


extern const char libfget_version[];

typedef struct ftp FTP;


/***** ftpstat.c *************************************************************/

struct ftpstat
{
	char fs_filename[MAXPATHLEN];		/* file name */
	char fs_linkname[MAXPATHLEN];		/* link name */
	mode_t fs_mode;				/* file mode */
	nlink_t fs_nlink;			/* number of links */
#ifdef FGET_COMPAT
# define fs_refcount fs_nlink
#endif
	char fs_username[MAXUSERNAMELEN];	/* user name */
	char fs_groupname[MAXGROUPNAMELEN];	/* group name */
	off_t fs_size;				/* size */
	time_t fs_mtime;			/* date */
#ifdef FGET_COMPAT
# define fs_date fs_mtime
#endif
	dev_t fs_rdev;				/* device ID */
};

/* stat a symlink */
int ftp_lstat(FTP *, char *, struct ftpstat *);

/* stat a file */
int ftp_stat(FTP *, char *, struct ftpstat *);

/* read the contents of a symbolic link */
int ftp_readlink(FTP *, char *, char *, size_t);

/* resolve symlinks */
int ftp_realpath(FTP *, char *, char *, size_t);


/***** handle.c **************************************************************/

typedef void (*ftp_hookfunc_t)(char *);

/*
** ftp_connect() - open a control connection to the FTP server
** returns:
**	0				success
**	-1 (and sets errno)		failure
*/
int ftp_connect(FTP **, char *, char *, size_t,
		unsigned short, time_t, long, time_t,
		ftp_hookfunc_t, ftp_hookfunc_t);

/* values for ftp_connect() flags bitmask */
#define FTP_PASSIVE		1	/* use PASV mode for data connection */
#define FTP_ROUNDROBIN		2	/* grok round-robin DNS entries */

/*
** ftp_login() - login to the FTP server
** returns:
**	0				success
**	-1 (and sets errno)		failure
*/
int ftp_login(FTP *, char *, char *);

/*
** ftp_quit() - disconnect from FTP server
** returns:
**	0				success
**	-1 (and sets errno)		failure
*/
int ftp_quit(FTP *, unsigned short);

/* flags for ftp_quit() */
#define FTP_FASTCLOSE		1	/* close without sending "QUIT" */

/*
** ftp_fd() - return file descriptor associated with FTP control connection
** returns:
**	file descriptor of ftp control connection
*/
int ftp_fd(FTP *);

/*
** ftp_data_fd() - return file descriptor associated with FTP data connection
** returns:
**	file descriptor of ftp data connection
*/
int ftp_data_fd(FTP *);

/*
 * get and set various FTP parameters
 */
long ftp_get_cache_max_size(FTP *);
void ftp_set_cache_max_size(FTP *, long);

time_t ftp_get_cache_expire_time(FTP *);
void ftp_set_cache_expire_time(FTP *, time_t);

unsigned short ftp_get_flags(FTP *);
void ftp_set_flags(FTP *, unsigned short);

time_t ftp_get_io_timeout(FTP *);
void ftp_set_io_timeout(FTP *, time_t);

char *ftp_get_host(FTP *);
char *ftp_whoami(FTP *);


/***** protocol.c ************************************************************/

/*
** ftp_set_sendhook() - set the send hook function.
*/
void ftp_set_sendhook(FTP *, ftp_hookfunc_t);

/*
** ftp_set_recvhook() - set the receive hook function.
*/
void ftp_set_recvhook(FTP *, ftp_hookfunc_t);


/***** ftpdir.c **************************************************************/

typedef struct ftpdir FTPDIR;

struct ftpdirent
{
	char *fd_name;		/* file name */
};


/* open directory */
int ftp_opendir(FTPDIR **, FTP *, char *);

/* read directory */
int ftp_readdir(FTPDIR *, struct ftpdirent *);

/* rewind directory */
void ftp_rewinddir(FTPDIR *);

/* tell where we are in the directory */
off_t ftp_telldir(FTPDIR *);

/* seek to a given point in the directory */
void ftp_seekdir(FTPDIR *, off_t);

/* close directory */
void ftp_closedir(FTPDIR *);


/***** ftpfile.c *************************************************************/

typedef struct ftpfile FTPFILE;


/* open a file via FTP */
int ftp_open(FTPFILE **, FTP *, char *, int);

/* values for mode */
#ifdef FGET_COMPAT
# define FTP_READ		O_RDONLY
# define FTP_WRITE		O_WRONLY
#endif

/* read a file via FTP */
int ftp_read(FTPFILE *, char *, size_t);

/* write a file via FTP */
int ftp_write(FTPFILE *, char *, size_t);

/* seek to a given offset in an FTP file */
int ftp_lseek(FTPFILE *, off_t, int);

/* close an FTP file */
int ftp_close(FTPFILE *);


/***** ftpglob.c *************************************************************/

typedef struct
{
	int gl_pathc;		/* Count of total paths so far. */
	int gl_matchc;		/* Count of paths matching pattern. */
	int gl_offs;		/* Reserved at beginning of gl_pathv. */
	int gl_flags;		/* Copy of flags parameter to glob. */
	char **gl_pathv;	/* List of paths matching pattern. */
	int (*gl_errfunc)(const char *, int);
				/* Copy of errfunc parameter to glob. */
}
ftp_glob_t;

/* Flags */
# define FTPGLOB_APPEND	0x0001	/* Append to output from previous call. */
# define FTPGLOB_DOOFFS	0x0002	/* Use gl_offs. */
# define FTPGLOB_ERR	0x0004	/* Return on error. */
# define FTPGLOB_MARK	0x0008	/* Append / to matching directories. */
# define FTPGLOB_NOCHECK 0x0010	/* Return pattern itself if nothing matches. */
# define FTPGLOB_NOSORT	0x0020	/* Don't sort. */
# define FTPGLOB_BRACE	0x0080	/* Expand braces ala csh. */
# define FTPGLOB_MAGCHAR 0x0100	/* Pattern had globbing characters. */
# define FTPGLOB_NOMAGIC 0x0200	/* FTPGLOB_NOCHECK without magic chars (csh). */
# define FTPGLOB_NOESCAPE 0x1000	/* Disable backslash escaping. */

/* Error values returned by glob(3) */
# define FTPGLOB_NOSPACE (-1)	/* Malloc call failed. */
# define FTPGLOB_ABORTED (-2)	/* Unignored error. */
# define FTPGLOB_NOMATCH (-3)	/* No match and FTPGLOB_NOCHECK not set. */


/*
** ftp_glob() - generate pathnames of remote files matching a pattern
** returns:
**	0			success
**	FTPGLOB_NOSPACE		malloc() error
**	FTPGLOB_ABORTED		error (and sets errno)
**	FTPGLOB_NOMATCH		no match and FTPGLOB_NOCHECK not set
*/
int ftp_glob(FTP *, const char *, int,
	     int (*)(const char *, int), ftp_glob_t *);

/*
** ftp_globfree() - free memory allocated by ftp_glob()
*/
void ftp_globfree(ftp_glob_t *);


/***** ftpops.c **************************************************************/

/* rename a file */
int ftp_rename(FTP *, char *, char *);

/* remove a file */
int ftp_remove(FTP *, char *);

/* execute a site command */
int ftp_site(FTP *, char *, unsigned short);

#define FTP_DATACONN		1	/* ftp_site() needs data connection */

/* determine the remote system type */
char *ftp_systype(FTP *);

/* get server status */
int ftp_status(FTP *, char *, size_t);

/* change directory */
int ftp_chdir(FTP *, char *);

/* make a directory */
int ftp_mkdir(FTP *, char *);

/* remove a directory */
int ftp_rmdir(FTP *, char *);

/* get current directory */
char *ftp_getcwd(FTP *);


/***** url.c *****************************************************************/

#define MAXPASSLEN              64
#define MAXURLLEN               (MAXHOSTNAMELEN + MAXUSERNAMELEN + \
                                 MAXPASSLEN + MAXPATHLEN + 9)

struct ftp_url
{
#ifdef FTP_URL_COMPAT
	char host[MAXHOSTNAMELEN];
	char user[MAXUSERNAMELEN];
	char pass[MAXPASSLEN];
	char path[MAXPATHLEN];
#else
	char fu_hostname[MAXHOSTNAMELEN];
	char fu_login[MAXUSERNAMELEN];
	char fu_passwd[MAXPASSLEN];
	char fu_path[MAXPATHLEN];
#endif
};

#ifdef FTP_URL_COMPAT
typedef struct ftp_url FTPURL;
# define ftp_parse_url ftp_url_parse
#endif


/* parse RFC-1738 style URL and fill in caller-supplied fields */
int ftp_url_parse(char *, struct ftp_url *);


#endif /* ! LIBFGET_H */
