#ifndef _BBS_SUBR_INCLUDED
#define _BBS_SUBR_INCLUDED

#ifndef NO_CRYPT
# define CRYPTFUNC(a,b) crypt(a,b)
#else
# define CRYPTFUNC(a,b) a
#endif

#ifndef NO_RANDOM
# define SRANDOM(a) srandom(a)
# define RANDOM  random
#else
# ifndef NO_LRAND48
#  define SRANDOM(a) srand48(a)
#  define RANDOM  lrand48
# else
#  define SRANDOM(a) srand(a)
#  define RANDOM  rand
# endif
#endif

#ifndef NO_MEMSET
# define BZERO(a,b) memset(a,0,b)
#else
# define BZERO(a,b) bzero(a,b)
#endif

/* bbs */
/* main */
extern PID_T bbsinit(char *, confrecordtyp *, const char *);
extern PID_T testdaemon(const char *, confrecordtyp *);
extern void bbsexit(const int, confrecordtyp *);

/* bbsdstuff */
extern int iniconnecttouserd(const PID_T, const PID_T, char *,
 			     confrecordtyp *);
extern int remconnecttouserd(sessionrecordtyp *, char *, const PID_T,
			     confrecordtyp *);
extern int bbslog(const int, confrecordtyp *, const char *, ...);
extern int sendstatustodaemon(const int, confrecordtyp *);
extern int getsessions(sessionrecordtyp [], const int, confrecordtyp *);
extern int addsession(const sessionrecordtyp *, confrecordtyp *);
extern int removesession(const PID_T, confrecordtyp *);
extern boolean getuserrecord(userrecordtyp *, char *, confrecordtyp *);
extern boolean saveuserrecord(userrecordtyp *, confrecordtyp *);
extern int connect2bbsd(confrecordtyp *);
extern int unconnect2bbsd(const int, confrecordtyp *);

/* do */
extern void do_talk(const char [], confrecordtyp *);
extern void do_sprache(const char [], const char *[], confrecordtyp *);
extern void do_autozmodem(const char [], confrecordtyp *);
extern void do_fullist(const char [], confrecordtyp *);
extern void do_showfile2(const char *, const char *, const int,
                         confrecordtyp *);
extern void do_showfile(const char *, const char *, confrecordtyp *);
extern void do_ls(const char [], const char *, confrecordtyp *);
extern void do_cd(const char [], char [], confrecordtyp *);
extern void do_pwd(const char *, confrecordtyp *);
extern void do_showenv(userrecordtyp *, confrecordtyp *);
extern void do_protokoll(const char [], const char *[], int *,
                         confrecordtyp *);
extern void do_get(const char [], const char *, const char *[], const int,
                   confrecordtyp *);
extern void do_put(const char [], const char *, const int, confrecordtyp *);
extern void do_home(const char [], const char *, userrecordtyp *,
                    confrecordtyp *);
extern int do_term(const char [], userrecordtyp *, confrecordtyp *confrecord);
extern int do_newpasswd(const char [], userrecordtyp *, confrecordtyp *);

/* errorstuff */
extern void errormsg(const int, confrecordtyp *, const char *, const char *,
                     const char *, ...);
extern void bgerror(const char *, const char *, ...);

/* execute */
extern int execute(const char *, char *const [], const int, confrecordtyp *);
extern void executesighandler(int);

/* filesys */
extern int checkfileperms(char *, const UID_T, const GID_T);
extern int getperms(const struct stat *, const UID_T, const GID_T);
extern char *chrootpath(char [], const char *, const char *);
extern char *getchrootcwd(char [], const char *);
extern char *getchrootpath(char [], const char *);
extern char *getrealdir(char [], confrecordtyp *);
extern int readconffile(confrecordtyp *, const char *);
#if 0
extern int expandfilenames(const char *, char [], const int, confrecordtyp *);
#endif

/* menue */
extern int getcmdline_c(char [], menuetyp [], menuetyp [], menuetyp [],
                        const char *, confrecordtyp *);
extern char selectmenue_c(char [], menuetyp [], const char *, const char,
                          confrecordtyp *);
extern int put_c(char [], confrecordtyp *);
extern int talk_c(char [], confrecordtyp *);
extern int sprache_c(char [], confrecordtyp *);
extern int autozmodem_c(char [], confrecordtyp *);
extern int fullist_c(char [], confrecordtyp *);
extern int protokoll_c(char [], confrecordtyp *);
extern int term_c(char [], confrecordtyp *);
extern int newpasswd_c(char [], confrecordtyp *);
extern int selectfiles_c(char [], const int, confrecordtyp *);
extern int selectdir_c(char [], const char *, confrecordtyp *);
extern char selectpager_c(tlistetyp *, const int, const char *, const char *,
                          const boolean, confrecordtyp *);
extern char menueselect_c(char *[], const int, const int, const int,
                          const boolean, confrecordtyp *);
extern int wildcardselect_c(const char, tlistetyp *, const int,
                          confrecordtyp *);
extern int selectpagerquit_c(const char);
extern int wildcardchar_c(const char);
extern int bbsquit_c(char [], confrecordtyp *);

/* msg */
extern char *msg(const char *, const int, const int);

/* signal */
extern void sighandler(int);
extern void sigtalkaccepthandler(int);

/* stringstuff */
extern void lowercases(char *);
extern void strprepend(char *, const char *);
extern char *strmaxcpy(char *, const char *, SIZE_T);
extern char *strmaxcat(char *, const char *, SIZE_T);
extern char *basename(char *);
extern void pathnamedir(const char *, char []);
extern char *buildhelppath(char *, const char *, const char *, confrecordtyp *);
extern int splitparams(char *[], char *);
extern void str2cmdparams(const char [], char [], char []);
extern void split2key_arg(char *, char **, char **);
extern void stringsort(char *[], const int);

/* sysstuff */
extern char *gettime(void);
#ifndef NO_TV_USEC
extern double microtime(void);
#endif
extern int mklockfile(const char []);
extern int fgetnln(char [], const int, FILE *);
extern SSIZE_T recvn(int, void *, SIZE_T, int);
extern SSIZE_T sendn(int, const void *, SIZE_T, int);
extern SSIZE_T readn(int, void *, SIZE_T);
extern SSIZE_T writen(int, const void *, SIZE_T);
extern void (*setsighandler(int, void (*)(int)))(int);
extern void (*setsighandler2(int, SIGSET_T, void (*)(int)))(int);
#ifdef NO_VSYSLOG
extern void vsyslog(int, const char *, va_list);
#endif
extern int mdefenv(const char *, const char *, ...);
extern int mputenv(const char *);
#ifdef NO_PUTENV
extern int putenv(const char *);
#endif

/* talk */
extern int talkscreen(const int, confrecordtyp *);
extern char inserttalktext(char *, const int, WINDOW *);
extern int iniconnecttouser(const PID_T, confrecordtyp *);
extern void praeleaveiniconnecttouser(void);
extern int abortconnecttouser(const PID_T, const PID_T, const int,
			      const char *, confrecordtyp *);
extern int remconnecttouser(confrecordtyp *);
extern void praeleaveremconnecttouser(const int);

/* tliste */
extern int addstrtoliste(tlistetyp **, const boolean, const int, const int,
                         char *, confrecordtyp *);
extern int readliste(tlistetyp **, const boolean, const int, const int,
                     char **, confrecordtyp *);
extern int removeliste(tlistetyp *, const boolean, const int);
extern void sortliste(tlistetyp *, const int, const int, confrecordtyp *);
extern char tlpager(tlistetyp *, const int, const char *, confrecordtyp *);

/* userrw */
extern boolean userlogin(confrecordtyp *, const char *);
extern int usergreeting(confrecordtyp *);
extern int writetouser(confrecordtyp *, const char *, ...);
extern int readfromuser(char [], const int, const boolean);
extern char waitonkeypress(const boolean);
extern char getkeyonprompt(const char *, char *, const boolean, const boolean,
                           confrecordtyp *);
#ifndef NO_TV_USEC
extern char autoz_getch_c(boolean *, const boolean);
#endif
extern int pagerstep(const char);
extern int pagerquit(const char);

/* windowstuff */
extern int windowtext(const char *, const char *, const int, confrecordtyp *);
extern char *savebackground(WINDOW *);
extern int restorebackground(WINDOW *, char *);
extern int window_on(confrecordtyp *);
extern int window_off(confrecordtyp *);
extern boolean termexists(const char *);

/* bbsd */
/* main */
extern PID_T disconnect(confrecordtyp *);
extern int rmdeadsessions(sessionrecordtyp []);
extern void cpysr(sessionrecordtyp *, const sessionrecordtyp *);
extern int dumpbbsdstatus(const char *,sessionrecordtyp [], confrecordtyp *,
			 const char *);
extern int changeuid(const char *);
extern PID_T daemonenkiller(const boolean, char *, const PID_T,
			   confrecordtyp *);
extern void dsighandler(int);
extern void kdsighandler(int);
extern int doaction(const int, const int, sessionrecordtyp [], confrecordtyp *);
extern int writepidsfile(confrecordtyp *, const PID_T, const PID_T);
extern int removepidsfile(confrecordtyp *);

/* daction */
extern int dputinlog(const int, const int);
extern int dsendstatustodaemon(sessionrecordtyp [], confrecordtyp *,
			       const int);
extern int diniconnecttouser(sessionrecordtyp [], confrecordtyp *, const int);
extern int dabortconnecttouser(sessionrecordtyp [], confrecordtyp *,
			       const int);
extern int dremconnecttouser(sessionrecordtyp [], confrecordtyp *, const int);
extern int dgetsessions(sessionrecordtyp [], const int);
extern int daddsession(sessionrecordtyp [], const int);
extern int dremovesession(sessionrecordtyp [], const int);
extern int dgetuserrecord(const int, confrecordtyp *);
extern int dsaveuserrecord(const int, confrecordtyp *);

#endif
