/* 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 <assert.h> /* enable assertions */
#include "myglob.h" /* use our simple glob */
#include "util/strerror.h"
#include <sys/types.h>
#ifdef HAVE_SYS_CAPABILITY_H
#include <sys/capability.h>
#undef WNOHANG
#undef WUNTRACED
#endif
#include <sys/ipc.h>
#include <sys/shm.h>
#include <pwd.h>
#include <grp.h>
#include <stdarg.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
#include <string.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/resource.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <ctype.h>
#include <dirent.h>
#include <syslog.h>
#include <setjmp.h>
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#endif
#ifdef HAVE_CRYPT_H
#include <crypt.h>
#endif
#ifdef HAVE_GETSPNAM
#include <shadow.h>
#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);
syntax highlighted by Code2HTML, v. 0.9.1