#ifdef NO_LONG_LONG
# define LLF "%ld"
# define LLFP(x) "%" x "ld"
# define LLT long
# define ULLF "%lu"
# define ULLFP(x) "%" x "lu"
# define ULLT unsigned long
# define STRTOLL(x,y,z) strtol(x,y,z)
# define LLTMIN LONG_MIN
# define LLTMAX LONG_MAX
#else
# define LLF "%lld"
# define LLFP(x) "%" x "lld"
# define LLT long long
# define ULLF "%llu"
# define ULLFP(x) "%" x "llu"
# define ULLT unsigned long long
# define STRTOLL(x,y,z) strtoll(x,y,z)
# define LLTMIN LLONG_MIN
# define LLTMAX LLONG_MAX
#endif
#define FTP_BUFLEN 512
void abor(void);
void closedataconn(FILE *);
char *conffilename(const char *);
void count_users(void);
void cprintf(FILE *, const char *, ...)
__printflike(2, 3);
void cwd(const char *);
FILE *dataconn(const char *, off_t, const char *);
void delete(const char *);
int display_file(const char *, int);
const char **do_conversion(const char *);
__dead void dologout(int);
__dead void fatal(const char *);
void feat(void);
void format_path(char *, const char *);
int ftpd_pclose(FILE *);
FILE *ftpd_popen(const char *[], const char *, int);
int get_line(char *, int, FILE *);
void init_curclass(void);
void logxfer(const char *, off_t, const char *, const char *,
const struct timeval *, const char *);
struct tab *lookup(struct tab *, const char *);
void makedir(const char *);
void mlsd(const char *);
void mlst(const char *);
void opts(const char *);
void parse_conf(const char *);
void pass(const char *);
void passive(void);
int lpsvproto2af(int);
int af2lpsvproto(int);
int epsvproto2af(int);
int af2epsvproto(int);
void long_passive(const char *, int);
int extended_port(const char *);
void epsv_protounsupp(const char *);
void perror_reply(int, const char *);
void pwd(void);
void removedir(const char *);
void renamecmd(const char *, const char *);
char *renamefrom(const char *);
void reply(int, const char *, ...)
__printflike(2, 3);
void retrieve(const char *[], const char *);
void send_file_list(const char *);
void show_chdir_messages(int);
void sizecmd(const char *);
void statcmd(void);
void statfilecmd(const char *);
void statxfer(void);
void store(const char *, const char *, int);
void user(const char *);
char *ftpd_strdup(const char *);
void yyerror(const char *);
#ifdef SUPPORT_UTMP
struct utmp;
void ftpd_initwtmp(void);
void ftpd_logwtmp(const char *, const char *, const char *);
void ftpd_login(const struct utmp *);
int ftpd_logout(const char *);
#endif
#ifdef SUPPORT_UTMPX
struct utmpx;
struct sockinet;
void ftpd_initwtmpx(void);
void ftpd_logwtmpx(const char *, const char *, const char *,
struct sockinet *, int, int);
void ftpd_loginx(const struct utmpx *);
int ftpd_logoutx(const char *, int, int);
#endif
#include <netinet/in.h>
#if defined(__NetBSD__)
# define HAVE_SETPROCTITLE 1
# define HAVE_STRUCT_SOCKADDR_SA_LEN 1
# define HAVE_SOCKADDR_SNPRINTF 1
#endif
struct sockinet {
union sockunion {
struct sockaddr_in su_sin;
#ifdef INET6
struct sockaddr_in6 su_sin6;
#endif
} si_su;
#if !defined(HAVE_STRUCT_SOCKADDR_SA_LEN)
int si_len;
#endif
};
#if !defined(HAVE_STRUCT_SOCKADDR_SA_LEN)
# define su_len si_len
#else
# define su_len si_su.su_sin.sin_len
#endif
#define su_addr si_su.su_sin.sin_addr
#define su_family si_su.su_sin.sin_family
#define su_port si_su.su_sin.sin_port
#ifdef INET6
# define su_6addr si_su.su_sin6.sin6_addr
# define su_scope_id si_su.su_sin6.sin6_scope_id
#endif
struct tab {
const char *name;
short token;
short state;
short flags;
const char *help;
char *options;
};
struct ftpconv {
struct ftpconv *next;
char *suffix;
char *types;
char *disable;
char *command;
};
typedef enum {
CLASS_GUEST,
CLASS_CHROOT,
CLASS_REAL
} class_ft;
typedef enum {
FLAG_checkportcmd = 1<<0,
FLAG_denyquick = 1<<1,
FLAG_hidesymlinks = 1<<2,
FLAG_modify = 1<<3,
FLAG_passive = 1<<4,
FLAG_private = 1<<5,
FLAG_sanenames = 1<<6,
FLAG_upload = 1<<7,
} classflag_t;
#define CURCLASS_FLAGS_SET(x) (curclass.flags |= (FLAG_ ## x))
#define CURCLASS_FLAGS_CLR(x) (curclass.flags &= ~(FLAG_ ## x))
#define CURCLASS_FLAGS_ISSET(x) (curclass.flags & (FLAG_ ## x))
struct ftpclass {
struct sockinet advertise;
char *chroot;
char *classname;
struct ftpconv *conversions;
char *display;
char *homedir;
classflag_t flags;
LLT limit;
char *limitfile;
LLT maxfilesize;
LLT maxrateget;
LLT maxrateput;
LLT maxtimeout;
char *motd;
char *notify;
LLT portmin;
LLT portmax;
LLT rateget;
LLT rateput;
LLT timeout;
class_ft type;
mode_t umask;
LLT mmapsize;
LLT readsize;
LLT writesize;
LLT recvbufsize;
LLT sendbufsize;
LLT sendlowat;
};
__dead extern void ftp_loop(void);
extern void ftp_handle_line(char *);
#ifndef GLOBAL
#define GLOBAL extern
#endif
GLOBAL struct sockinet ctrl_addr;
GLOBAL struct sockinet data_dest;
GLOBAL struct sockinet data_source;
GLOBAL struct sockinet his_addr;
GLOBAL struct sockinet pasv_addr;
GLOBAL int connections;
GLOBAL struct ftpclass curclass;
GLOBAL int ftpd_debug;
GLOBAL char *emailaddr;
GLOBAL int form;
GLOBAL int gidcount;
GLOBAL gid_t *gidlist;
GLOBAL int hasyyerrored;
GLOBAL char hostname[MAXHOSTNAMELEN+1];
GLOBAL char homedir[MAXPATHLEN];
#ifdef KERBEROS5
GLOBAL krb5_context kcontext;
#endif
GLOBAL int logged_in;
GLOBAL int logging;
GLOBAL int pdata;
#if defined(HAVE_SETPROCTITLE)
GLOBAL char proctitle[BUFSIZ];
#endif
GLOBAL struct passwd *pw;
GLOBAL int quietmessages;
GLOBAL char remotehost[MAXHOSTNAMELEN+1];
GLOBAL char remoteloghost[2 * MAXHOSTNAMELEN + 4];
GLOBAL off_t restart_point;
GLOBAL char tmpline[FTP_BUFLEN];
GLOBAL int type;
GLOBAL int usedefault;
GLOBAL const char *version;
GLOBAL int is_oob;
GLOBAL off_t total_data_in, total_data_out, total_data;
GLOBAL off_t total_files_in, total_files_out, total_files;
GLOBAL off_t total_bytes_in, total_bytes_out, total_bytes;
GLOBAL off_t total_xfers_in, total_xfers_out, total_xfers;
extern struct tab cmdtab[];
#define INTERNAL_LS "/bin/ls"
#define CMD_IMPLEMENTED(x) ((x)->flags != 0)
#define CMD_HAS_OPTIONS(x) ((x)->flags & 0x2)
#define CMD_OOB(x) ((x)->flags & 0x4)
#define CPUTC(c, f) do { \
putc(c, f); total_bytes++; total_bytes_out++; \
} while (0)
#define CURCLASSTYPE curclass.type == CLASS_GUEST ? "GUEST" : \
curclass.type == CLASS_CHROOT ? "CHROOT" : \
curclass.type == CLASS_REAL ? "REAL" : \
"<unknown>"
#define ISDOTDIR(x) (x[0] == '.' && x[1] == '\0')
#define ISDOTDOTDIR(x) (x[0] == '.' && x[1] == '.' && x[2] == '\0')
#define EMPTYSTR(p) ((p) == NULL || *(p) == '\0')
#define NEXTWORD(P, W) do { \
(W) = strsep(&(P), " \t"); \
} while ((W) != NULL && *(W) == '\0')
#define PLURAL(s) ((s) == 1 ? "" : "s")
#define REASSIGN(X,Y) do { if (X) free(X); (X)=(Y); } while (0)
#ifndef IPPORT_ANONMAX
# define IPPORT_ANONMAX 65535
#endif