/* Copyright (C) 1999 Beau Kuiper This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Includes */ #ifndef DEBUG /* If we are not debuging, disable assertions! */ #define NDEBUG #endif #include "../config.h" /* Insert the config header */ #include "../defaults.h" /* insert default info */ #include /* enable assertions */ #include "myglob.h" /* use our simple glob */ #include "util/strerror.h" #include #ifdef HAVE_SYS_CAPABILITY_H #include #undef WNOHANG #undef WUNTRACED #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_DLFCN_H #include #endif #ifdef HAVE_CRYPT_H #include #endif #ifdef HAVE_GETSPNAM #include #endif #ifndef INT_MAX #define INT_MAX 0x7FFFFFFF #endif #include "pnums.h" #include "configfile.h" #include "acl.h" #include "tokset.h" #include "ratio.h" #include "string.h" /* Inportant Constants */ #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE !FALSE #endif #define SYSLOG 1 #define TERMINAL 2 #define MUDLOG 3 #define MYLOG_DACCESS 1 #define MYLOG_FTRANS 2 #define MYLOG_COMMAND 4 #define MYLOG_RESPONSE 8 #define MYLOG_INFO 16 #define MYLOG_LOGIN 32 #define MYLOG_DEBUG 64 #define TRANS_LIST 1 #define TRANS_UPLOAD 2 #define TRANS_DOWNLOAD 3 #define TRANS_SUPLOAD 4 #define TRANS_RUNNING 5 /* used in authentication modules */ #define AUTH_OK 0 #define AUTH_USERNKNOW 1 #define AUTH_ERROR 2 /* used for config errors */ #define CONFIG_OK 0 #define CONFIG_HANDLER_ERROR 1 #define CONFIG_FILE_UNSAFE 2 #define CONFIG_FILE_ERROR 3 #define CFC_INCLUDE_ERROR 10 #define CFC_SECTION_NONE 11 #define CFC_SECTION_EXISTS 12 #define CFC_NO_SECTION 13 #define CFC_INCLUDE_LOOP 14 /* used to define maximum IP address size (for ipv6 support) */ #define MAX_IPSIZE 16 #define FTP_IPV4 1 #define FTP_IPV6 2 /* DO NOT CHANGE THESE DEFINES. THEY ARE REQUIRED CONSTANTS */ #define CR 13 #define LF 10 /* Macros */ #define MAXIMUM(x, y) ((x) > (y) ? (x) : (y)) #define MINIMUM(x, y) ((x) > (y) ? (y) : (x)) #define ERRORMSG(x) errormsg(x, __FILE__, __LINE__) #define ERRORMSGFATAL(x) errormsgfatal(x, __FILE__, __LINE__) #ifndef FNM_PATHNAME #define FNM_PATHNAME 1 #endif /* this specifies that the operation cannot be stopped by a signal */ #define NOSIGNALINTR(x) while(((x) == -1) && (errno == EINTR)) /* Typedefs */ typedef unsigned int ipaddr_mt[MAX_IPSIZE]; typedef struct { int fd; STRING *buffer; int eof; } NEWFILE; typedef struct strcache { int size; struct { int num; char *str; } data[STRCACHESIZE]; } STRCACHE; struct selector; struct selectorobj { int (* readsockopt)(struct selector *, int, void *); int (* writesockopt)(struct selector *, int,void *); void *readdata; void *writedata; int next; /* linked list of file descriptors */ int last; }; typedef struct selector { fd_set readset; fd_set writeset; struct selectorobj **fdtable; int firstfd; int maxfds; int smax; } SELECTER; typedef struct limiter { int maxspeed; struct timeval current_time; int bytes_transfered; } LIMITER; typedef struct { int pos; MYGLOBDATA *dirdata; int nlist; int recursive; int all; STRCACHE *uidcache; STRCACHE *gidcache; char *dir; char *rdir; int odirlen; int numsubdirs; char **subdirs; unsigned int year; /* this is stored as 4 chars */ } LISTHANDLE; typedef struct dataport { int filefd; int socketfd; off_t pos; off_t startpos; off_t tsize; STRING *buffer; LISTHANDLE *lhandle; int trans_type; int binary; int passive; off_t transbytes; LIMITER *download_limiter; LIMITER *upload_limiter; } DATAPORT; typedef struct { unsigned int ipaddr; unsigned int netmask; char *fnstr; int type; int accept; } IPACL; typedef struct { int count; IPACL *list; } IPACLLIST; typedef struct vserver { IPACLLIST *ipaccess; int maxusers; int loglevel; int timeout; char *logfile; char *email; int logincount; int authwait; int umask; int maxperip; char *sectionname; char **grouplist; char *vhostname; char *prelogindump; char *prelogindumpdata; char *greetline; char *toobusy; struct vserver *next; } VSERVER; typedef struct vserverconn { int port; int ip; int fd; VSERVER *vptr; struct vserverconn *next; } VSERVERCONN; typedef struct configdata { CONFIGFILECACHE *configfile; pid_t parentpid; /* the pid to signal when an fatal error occurs */ int rootmode; /* are we in root mode or not */ int logout; /* log context */ uid_t uidt_asuid; /* change to this user after listening to port */ gid_t gidt_asgid; int toobusycount; /* number of connections being given too busy messages by main thread */ char *username; /* the username muddleftpd will run as */ uid_t uidt_nobodyuid; /* uid for user nobody */ gid_t gidt_nobodygid; /* gid for user nobody */ int inetd; /* are we running as inetd */ int hostvservers; /* are we running with hostname only virtual servers */ int dnstimeout; /* maximum time to wait for reversedns */ int altlongreplies; /* use alternate long replies, more compatible with crappy clients */ int smartbind; /* specifies whether to search for effecient fd usage, or correct binding */ int zerobind; /* bind all ports using address 0.0.0.0, use with smartbind on Freebsd to use virtual servers */ char *hostname; /* Computer host name */ VSERVER *defaults; /* Default values for VSERVER */ VSERVER *defaulthost; /* The default host for hostvservers */ char **vserverlist; /* list of virtual servers names */ VSERVER *vservers; /* virtual server list */ VSERVERCONN *inports; /* input ports */ } CONFIGDATA; typedef struct ftpstate { int remotefd; /* fd of the port to the remote system */ unsigned int remoteip; /* the systems IP number */ int connport; /* port connected to */ char *username; /* the username of the ftp user */ char *pwd; /* the current dir the ftp user is in */ char *homedir; /* the home directory of the ftp user */ char *basedir; /* the / directory for that user */ int passiveport; /* the fd of the listening passive port */ char *renameoldname; /* the source file to rename */ int loggedin; /* true if the user is logged in */ off_t restartpos; /* the position to start a download or upload */ int remoteport; /* the port number to connect to for data conns */ int binary; /* true if binary mode is set */ int threadnum; /* the number of the thread in ftpd terms (not pid) */ int *cmddisableset; /* a set of integers used to disable commands */ int *sitedisableset; /* a set of integers used to disable site commands */ STRING *inbuffer; /* the input buffer */ char *logindump; /* file to print after login */ char *cwddump; /* dump this file when you move to this dir */ char *busydump; /* dump this file if too many users are logged in */ char *quitdump; /* dump this file when the user quits */ char *logindumpdata; /* this is for login dump */ char *cwddumpdata; /* this is when we change dir */ char *busydumpdata; /* this is when we are too busy */ char *quitdumpdata; /* this is when we quit */ ACLLIST *acldata; /* The access lists for this user */ int umask; /* the umask of newly created files */ gid_t gidt_asgid; /* all file work is done as this gid (if possible) */ uid_t uidt_asuid; /* all file work is done as this uid (if possible) */ int maxusers; /* maximum instances of this user allowed to be logged in */ int maxtimeout; /* maximum time out for this user */ int timeout; /* timeout for this user */ int chmodable; /* can do chmod and change umask */ SELECTER *sel; /* select data stored here */ DATAPORT *dport; /* Data port information */ int loginsleft; /* number of login attempts left */ int jailenabled; /* is this user a jail */ int chroot; /* does a chroot occur */ int droproot; /* do we drop root when logging in */ int nicevalue; /* what niceness to run as */ int realdir; /* use real directory instead of built up name */ int fxpallow; /* allow fxp(server-server) transfers */ int usercount; /* the number of users in the current group when the user logged on */ char *hostname; /* the hostname of the remote host */ int accessdevices; /* can the user access device files */ char *groupname; int fakemode; char *fakename; char *fakegroup; VSERVER *vserver; /* vserver the user is connected to */ RATIOHANDLE *ratioinfo; /* ratio info */ gid_t *supgids; /* user supplementary gids */ unsigned int dataip; /* ip to connect data port to */ STRING *outbuffer; /* output coalessing buffer */ int maxtranspd; /* Maximum transfer speed */ int maxtranspd_down; /* Maximum download speed, overrides maxtranspd */ int maxtranspd_up; /* Maximum upload speed, overrides maxtranspd */ int epsv_forced; /* EPSV ALL was called, deny everything else */ /* Counters for stats */ int downloadedfiles; int uploadedfiles; off_t downloadedfilebytes; off_t uploadedfilebytes; off_t listdownloadedbytes; int listconns; } FTPSTATE; typedef struct ftpcmd { char *command; int (* ftpfunc)(FTPSTATE *peer, char *params); int paramnum; int needslogin; int dataportok; char *helpdesc; } FTPCMD; typedef struct inputline { FTPCMD *command; char *parameters; } INPUTLINE; /* GLOBAL VARIABLES */ CONFIGDATA *config; /* configuration data stored here for easy access */ int inetd; /* is process running as inetd */ int logerrors; /* do we log config errors to screen, syslog, or screen */ /* these prototypes are mostly auto generated by scribe */ /* procnum.h */ void writescratch(int pos, int size, char *buff); void writeshmem(int num, int pos, int len, void *buff); void shinfo_addtogrouplist(VSERVER *vs); void shinfo_setuparea(void); void shinfo_init(char *scfilename); void inetd_init(char *scfile); void shinfo_reinit(void); int shinfo_addstandalone(int newthid, char *vservername, unsigned int ip, int viplimit, int iplimit); int shinfo_adduser_inetd(unsigned int ip, int slimit, int iplimit, int *error); int shinfo_adduser(char *vserver, unsigned int ip, int vlimit, int slimit, int viplimit, int iplimit); int shinfo_setvserver(int thid, char *vservername, unsigned int ip, int vlimit, int viplimit, int *error); int shinfo_newuser_standalone(unsigned int ip, int iplimit, int *error); void shinfo_changeop(char *operation); void shinfo_changeuser(char *username); void shinfo_sethost(char *hostname); int shinfo_addusergroup(char *groupname, int limit); void shinfo_setpid(int thrid, int pid); void shinfo_delbypid(int pid); void shinfo_delusergroup(char *groupname); void shinfo_freebynum(int threadnum); void shinfo_freethreads(int freecount, pid_t *freelist); void pnums_signalchildren(int signalnum); void shinfo_shutdown(void); /* socket.h */ char *getipstr(unsigned int server); void takentoolong(int sig); char *getnetworkstr(unsigned int server); int getnetworkint(char *server, unsigned int *out); int conn_server(unsigned int ip, int port); int conn_server_nonblocking(unsigned int ip, int port, int localport, int fd); int listenport(int port, unsigned int ip, int maxconnect); int get_conn(int socketin, unsigned int *addr); int listenparrelelport(int fd, int *port, unsigned int *ip, int maxconnect); void getsockinfo(int fd, unsigned int *ip, int *port); unsigned int getremoteip(int fd); void socket_flush_wait(int fd, int timeout); /* select.h */ SELECTER *select_new(void); void select_addfd(SELECTER *sel, int newport); void select_delfd(SELECTER *sel, int deadport); void select_addread(SELECTER *sel, int port, int (* proc)(SELECTER *, int, void *), void *dat); void select_addwrite(SELECTER *sel, int port, int (* proc)(SELECTER *, int, void *), void *dat); void select_takeread(SELECTER *sel, int port); void select_takewrite(SELECTER *sel, int port); int select_do(SELECTER *sel, int *signum, int timeout); void select_shutdown(SELECTER *sel); /* ftpsite.h */ int ftp_site(FTPSTATE *peer, char *cmd); int ftpsite_dump(FTPSTATE *peer, char *cmd); int ftpsite_umask(FTPSTATE *peer, char *cmd); int ftpsite_help(FTPSTATE *peer, char *cmd); int ftpsite_idle(FTPSTATE *peer, char *cmd); int ftpsite_chmod(FTPSTATE *peer, char *cmd); int ftpsite_access(FTPSTATE *peer, char *cmd); /* proxy.h */ int controlportgotdata(SELECTER *sel, int fd, void *peerdata); char *remove_rootcomponent(FTPSTATE *peer, char *filename, char *descript); void dochroot(FTPSTATE *peer); void rotatelogs(FTPSTATE *peer); void ftpserverside_main(int remotefd, int remoteip, int threadnum, int portnum, VSERVER *vserver); int inport_bind(int portid, unsigned int bindip, int dodie); int inport_getconn(SELECTER *mainsel, int fd, void *vs); int vserver_select(FTPSTATE *peer, VSERVER *vserver); /* version.h */ void showversion(char *desc); /* acl.h */ ACLLIST *acllist_create(void); char *acllist_makepermstr(ACLLIST *acl, int cnt, char *ret); void acllist_add(ACLLIST *acl, char *dir, char *attribs, int is_regexp); void acllist_tokendo(ACLLIST *acl, TOKENSET *tset); int acllist_check(ACLLIST *acl, char *dir, int attr); int check_acl(FTPSTATE *peer, char *path, int perm); void acllist_dest(ACLLIST *acl); /* ftpout.h */ void control_timeout(int num); int ftp_write(FTPSTATE *peer, int bare, int messnum, char *fmt, ...); /* utils.h */ void *mallocwrapper(int size); void reallocwrapper(int size, void **inarea); char *strdupwrapper(char *s); void freewrapper(void *tofree); void freeifnotnull(void *); char *offt_tostr(off_t size); int strto_offt(char *str, off_t *ret); #ifndef HAVE_MEMMOVE void *memmove(void *, const void *, int); #endif void strtrimspace(char *string); int strchrcount(char *string, char tok); char *safe_vsnprintf(int size, char *format, va_list ap); char *safe_snprintf(char *format, ...); char *getcwd2(void); void pathname_simplify(char *pathname); void test_libc(int verbose); #ifndef HAVE_USLEEP int usleep(int usecs); #endif STRCACHE *strcache_new(void); char *strcache_check(STRCACHE *cache, int num); void strcache_add(STRCACHE *cache, int num, char *str); void strcache_free(STRCACHE *cache); TOKENSET *tokenset_new(void); void tokenset_settoken(TOKENSET *tset, unsigned char tok, char *data); void tokenset_deltoken(TOKENSET *tset, unsigned char tok); char *tokenset_apply(TOKENSET *tok, char *inputstr, int); void tokenset_finish(TOKENSET *tset); void init_pwgrfiles(void); char *get_passwdname(uid_t inuid, int usefile); char *get_groupname(gid_t ingid, int usefile); gid_t *getusergrouplist(char *username); gid_t *newgidlist(void); gid_t *addgidlist(gid_t *list, gid_t new); void delgidlist(gid_t *list, gid_t old); gid_t *parsegidlist(char *str); char *makegidliststr(gid_t *list); void kill_uidgidfiles(void); int isfilesafe(int fd); LIMITER *limiter_new(int maxspeed); void limiter_add(LIMITER *l, int byte_count, int force); int giveuproot(uid_t uid, gid_t gid); void errormsg( char *errmessage, char *file, int line ); void errormsgfatal( char *errmessage, char *file, int line ); void blockallsignals( void ); void unblockallsignals( void ); /* init.h */ void ftpd_setnogroups(void); void ftpd_preinit(void); void ftpd_init(char *filename, int verbose); /* ftp.h */ void reporterror(FTPSTATE *peer, char *filename, int errorno); int readipstr(char *data, int *port, unsigned int *ip); int ftp_dele(FTPSTATE *peer, char *filename); int ftp_chmod(FTPSTATE *peer, char *filename, int mode); int ftp_size(FTPSTATE *peer, char *filename); int ftp_mdtm(FTPSTATE *peer, char *filename); void setdumptokens(FTPSTATE *peer, TOKENSET *ts); int ftp_dumper(FTPSTATE *peer, NEWFILE *infile, int number, char *fmessage, int dotokens, int endtokens); int ftp_dumpstr(FTPSTATE *peer, char *dumpstr, int number, char *fmessage, int endtokens); int ftp_rnto(FTPSTATE *peer, char *filename); int ftp_mkd(FTPSTATE *peer, char *filename); int ftp_rmd(FTPSTATE *peer, char *filename); int ftp_cwddo(FTPSTATE *peer, char *newdir, int dump); int ftp_cwd(FTPSTATE *peer, char *newdir); int ftp_run(FTPSTATE *peer, INPUTLINE *cmd, char *token); int ftp_quit(FTPSTATE *peer, char *param); int ftp_user(FTPSTATE *peer, char *param); int ftp_pass(FTPSTATE *peer, char *param); int ftp_rest(FTPSTATE *peer, char *param); int ftp_syst(FTPSTATE *peer, char *param); int ftp_port(FTPSTATE *peer, char *param); int ftp_pwd(FTPSTATE *peer, char *param); int ftp_type(FTPSTATE *peer, char *param); int ftp_abor(FTPSTATE *peer, char *param); int ftp_pasv(FTPSTATE *peer, char *param); int ftp_list(FTPSTATE *peer, char *param); int ftp_nlst(FTPSTATE *peer, char *param); int ftp_cdup(FTPSTATE *peer, char *param); int ftp_rnfr(FTPSTATE *peer, char *param); int ftp_noop(FTPSTATE *peer, char *param); int ftp_rein(FTPSTATE *peer, char *param); int ftp_none(FTPSTATE *peer, char *param); int ftp_help(FTPSTATE *peer, char *param); int ftp_dohelp(FTPSTATE *peer, FTPCMD *ftpcmds, char *command, int *disableset); int ftp_allo(FTPSTATE *peer, char *param); int ftp_acct(FTPSTATE *peer, char *param); int ftp_stru(FTPSTATE *peer, char *param); /* ftpstat.h */ int ftp_stat(FTPSTATE *peer, char *param); /* cmd.h */ int *disableset_create(void); void disableset_disablecmd(int *set, FTPCMD *ctable, char *cmd); char *getkeyword(char **iline); void cmd_split(FTPSTATE *peer, INPUTLINE *cmd, char* inpline, FTPCMD *ctable, int log, int *disableset); /* logger.h */ int log_initcontext(char *logname); void log_setcontext(int logfd, int logmask); void log_addentry(int type, FTPSTATE *peer, char *desc); void log_giveentry(int type, FTPSTATE *peer, char *desc); void debuglog(char *format, ...); void log_shutdown(void); /* dir.h */ char *dir_getreal(FTPSTATE *peer); char *dir_getvirtual(FTPSTATE *peer, char *); void dir_combine(FTPSTATE *peer, char **pwd, char *newdir); /* shmem.h */ void shmem_finish(int shmemnum); void *shmem_get(char *ipcfile, int size, int *shmemnum, int *isnew, int *lockfd); /* ftplist.h */ int ftplist_parseflags(char *params); char *listmakeline(FTPSTATE *peer, char *longname, char *filename, struct stat *fileinfo, STRCACHE *uidcache, STRCACHE *gidcache, int year); LISTHANDLE *getlisthandle(FTPSTATE *peer, char *dirpattern, int nlist, char *reldir, int params); char *getlisthandleline(FTPSTATE *peer, LISTHANDLE *lh); void freelisthandle(LISTHANDLE *lh); int list_write(SELECTER *sel, int fd, void *peerv); char *listmakepattern(FTPSTATE *peer, char *parm, char **rdir, int flags); int ftp_lister(FTPSTATE *peer, char *parm, int nlist, int params); /* checkip.h */ int checknamelist(CONFIGFILECACHE *cf, int section, char *username); IPACLLIST *ipacllist_new(CONFIGFILECACHE *cf, int section, char *name); void ipacllist_destroy(IPACLLIST *list); int user_allowed(IPACLLIST *list, int ip, char *hostname); /* ftpstate.h */ void ftpstate_init(FTPSTATE *ftp, int fd, int ip, int threadnum, int portnum, VSERVER *vs); void ftpstate_dest(FTPSTATE *ftp); /* bufread.h */ int popcmd(FTPSTATE *peer, char **outstr); int readcmd(FTPSTATE *peer); /* config.h */ int loadconfigfile(char *filename, int (* confighandler)(char *, char *, int, void *), void *configdata, int bescure, int *handlererror, int *linenum); int cachemaker(char *cmd, char *data, int linenum, void *c); CONFIGFILECACHE *loadconfigcache(char *filename, int *linenum, int *error); char *config_errorstr(int result); int getsectionid(CONFIGFILECACHE *cache, char *section); char *getconfigdata_r(CONFIGFILECACHE *cache, int section, char *cmd, int *occur, int depth, int *error); char *getconfigdata(CONFIGFILECACHE *cache, int section, char *cmd, int occur); char **makeconfiglist(CONFIGFILECACHE *cache, char *section, char *label); void loadintfromconfig(CONFIGFILECACHE *cache, int section, char *setting, int *to, int def); void loadstrfromconfig(CONFIGFILECACHE *cache, int section, char *setting, char **to, char *def); void freeconfigcache(CONFIGFILECACHE *cache); /* ftptrans.h */ int sigio_handler(int signum); int filter_toascii(char *data, int *len); int filter_fromascii(char *data, int *len); int download_write(SELECTER *sel, int fd, void *peerv); int upload_read(SELECTER *sel, int fd, void *peerv); int ftp_retr(FTPSTATE *peer, char *filename); int ftp_stor(FTPSTATE *peer, char *filename); int ftp_stou(FTPSTATE *peer, char *filename); int ftp_appe(FTPSTATE *peer, char *filename); /* newfile.h */ int readbuffer(NEWFILE *file); NEWFILE *nfopen(char *filename); NEWFILE *nfdopen(int fd); char *nfgetcs(NEWFILE *file, char testchar); void nfclose(NEWFILE *file); /* main.h */ void logfullmessage(int error, unsigned int ip); VSERVER *findvserver(unsigned int ip, int port); void smartbind(SELECTER *selset, VSERVERCONN *list, int dodie); void dumbbind(SELECTER *selset, VSERVERCONN *list, int dodie); void sighandler(int signum); int mainprog(char *fconfig, int runforeground, int verbose); void mainprog_inetd(char *fconfig, unsigned int ip); void diehandler(int signum); int main(int argc, char **argv); /* datasock.h */ int datasock_connect(SELECTER *sel, int fd, void *peerv); int startdatasocket(FTPSTATE *peer, int filefd, int trans_type, off_t tsize); void closedatasocket(FTPSTATE *peer); void abortdatasocket(FTPSTATE *peer); /* auth.h */ void converttorealstr(char *strbuf); int chkpassword(char *encrypass, char *password); int checkexploits(FTPSTATE *peer); int authlogmsg(char *directive, char *groupname); int checkabsdir(char *dir); void clearauth(FTPSTATE *peer); char *mkconfrealstr(int sectionid, char *item, char *defaul); char *mktokconfstr(TOKENSET *tset, int sectionid, char *item, char *defaul); int mktokconfint(TOKENSET *tset, int sectionid, char *item, char *format, char *defaultstr, int defaultint); void setupacls(FTPSTATE *peer, TOKENSET *tset, int section, char *funcname, int aclfunc); int transferconfig(FTPSTATE *peer, TOKENSET *tset, int section); int auth_getcursectionid(FTPSTATE *peer); void *auth_getconfigcache(void); char *setuseropts(FTPSTATE *peer, char *password); /* file.h */ void file_becomeuser(FTPSTATE *peer); void file_becomeroot(FTPSTATE *peer); int checkdir(char *dir); int checkfile(char *file); int checkchdir(FTPSTATE *peer, char *dir); void convertperms(char *permstr, int mode); char *file_expand(FTPSTATE *peer, char *filename); int file_isfdregularfile(int fd); int file_isfdadir(int fd); int file_ustoreopen(FTPSTATE *peer, char *, int *, char **rname); int file_storeopen(FTPSTATE *peer, char *infile, char **rname); int file_readopen(FTPSTATE *peer, char *infile, char **rname); NEWFILE *file_nfopen(FTPSTATE *peer, char *filename); MYGLOBDATA *file_glob(FTPSTATE *peer, char *dir, char *pattern, int allfiles); int file_unlink(FTPSTATE *peer, char *infile); char *file_rename(FTPSTATE *peer, char *infile, char *infile2); int file_stat(FTPSTATE *peer, char *infile, struct stat *output); int file_mkdir(FTPSTATE *peer, char *infile); int file_rmdir(FTPSTATE *peer, char *infile); int file_chmod(FTPSTATE *peer, char *infile, int mode); /* cfloader.h */ char *gethostname2(void); void configerror(char *str); void vserver_kill(VSERVER *c); VSERVER *vserver_load(CONFIGDATA *cf, char *sectionname, VSERVER *def, VSERVERCONN ***vp); void ftpd_killconfig(CONFIGDATA *dc); CONFIGDATA *ftpd_loadconfig(char *inidata, int as_inetd, int use_umask); int ftpd_checkvserver(CONFIGDATA *cdat, VSERVER *vs); int ftpd_checkconfig(CONFIGDATA *cdat); /* ratio.h */ int lockarea(int fd, int pos, int len, int locktype, int do_wait); void lock_n_read(RATIOHANDLE *rh); void write_n_unlock(RATIOHANDLE *rh); int openratiofile(char *filename); int decoderatiostr(char *ratstr, int *pa, int *pb); RATIOHANDLE *ratio_loaduser(char *username, int section); void ratio_uploadbytes(RATIOHANDLE *rh, int bytes); int ratio_downloadbytes(RATIOHANDLE *rh, int bytes); void ratio_uploadfile(RATIOHANDLE *rh); int ratio_downloadfile(RATIOHANDLE *rh); void ratio_reread(RATIOHANDLE *rh); void ratio_stat(FTPSTATE *peer, RATIOHANDLE *rh, char *replystr); void ratio_settokens(RATIOHANDLE *rh, TOKENSET *ts); void ratio_finish(RATIOHANDLE *rh);