#define _GNU_SOURCE
#include <string.h>
#include <time.h>
+#include <stdarg.h>
+#include <stdint.h>
+
#include "../lib/sstring.h"
#include "../core/schedule.h"
#include "../lib/flags.h"
#include "../channel/channel.h"
#include "../parser/parser.h"
#include "../localuser/localuserchannel.h"
-#include "../pqsql/pqsql.h"
+
+#ifndef CS_NODB
+#include "../dbapi/dbapi.h"
+#endif
#define CS_PARANOID
#endif
/* Q9 Version */
-#define QVERSION "1.00-RC2"
+#define QVERSION "1.00"
+
+/* Achievements: Nothing before ACHIEVEMENTS_START
+ * opt-in only after ACHIEVEMENTS_END
+ * Titles are valid only between ACHIEVEMENTS_START and ACHIEVEMENTS_END */
+
+//#define ACH_TEST_APRIL1
+
+#ifdef ACH_TEST_APRIL1
+
+#define ACHIEVEMENTS_START 1269702917
+#define ACHIEVEMENTS_END 1270162800
+
+#elif defined(ACH_TEST_POSTAPRIL1)
+
+#define ACHIEVEMENTS_START 0
+#define ACHIEVEMENTS_END 1269702917
+
+#else
+
+#define ACHIEVEMENTS_START 1270076400
+#define ACHIEVEMENTS_END 1270162800
+
+#endif
/* Mini-hash of known users on channels to make lookups faster;
* how big do we make it? */
#define MAXSUSPENDHIT 500
/* Maximum number of times a user may attempt to auth */
-#define MAXAUTHATTEMPT 5
+#define MAXAUTHATTEMPT 10
/* Maximum number of hellos in a session */
-#define MAXHELLOS 3
+#define MAXHELLOS 2
/* Maximum number of times a user may actually be authed */
#define MAXAUTHCOUNT 2
/* If set will issue warnings when authgate cached stuff changes */
#define AUTHGATE_WARNINGS
+/* Challenge auth faq site */
+#define CHALLENGEAUTHSITE "http://www.quakenet.org/development/challengeauth/"
+
/* Cleanup options */
-#define CLEANUP_ACCOUNT_INACTIVE 80
-#define CLEANUP_ACCOUNT_UNUSED 10
-#define CLEANUP_CHANNEL_INACTIVE 30
+#define CLEANUP_ACCOUNT_INACTIVE 180
+#define CLEANUP_ACCOUNT_UNUSED 3
+#define CLEANUP_CHANNEL_INACTIVE 40
+
+#define CLEANUP_AUTHHISTORY 60
+
+#define CLEANUP_MIN_CHAN_SIZE 2
/* Sizes of the main hashes */
#define REGUSERHASHSIZE 60000
/* Number of languages and messages */
#define MAXLANG 50
-#define MAXMESSAGES 200
/* Maximum number of user chanlevs and bans */
-#define MAXCHANLEVS 250
+#define MAXCHANLEVS 500
#define MAXBANS 50
/* Sources of entropy and standard length defines */
#define ENTROPYSOURCE "/dev/urandom"
#define ENTROPYLEN 8
-/* The list of messages */
-#define QM_PROTECTED 0
-#define QM_UNKNOWNCMD 1
-#define QM_SECUREONLY 2
-#define QM_AUTHEDONLY 3
-#define QM_UNAUTHEDONLY 4
-#define QM_COMMANDLIST 5
-#define QM_ENDOFLIST 6
-#define QM_DONE 7
-#define QM_NOTENOUGHPARAMS 8
-#define QM_UNKNOWNCHAN 9
-#define QM_NOACCESSONCHAN 10
-#define QM_CURCHANFLAGS 11
-#define QM_CURFORCEMODES 12
-#define QM_NOACCESS 13
-#define QM_UNKNOWNUSER 14
-#define QM_USERNOTAUTHED 15
-#define QM_CHANLEVHEADER 16
-#define QM_CHANLEVCOLSHORT 17
-#define QM_CHANLEVCOLFULL 18
-#define QM_NOUSERSONCHANLEV 19
-#define QM_CHANUSERFLAGS 20
-#define QM_CHANUSERUNKNOWN 21
-#define QM_INVALIDCHANLEVCHANGE 22
-#define QM_USERISAUTHEDAS 23
-#define QM_USERISHELPER 24
-#define QM_USERISOPER 25
-#define QM_USERISADMIN 26
-#define QM_USERISDEV 27
-#define QM_WHOISHEADER 28
-#define QM_WHOISCOLS 29
-#define QM_USERONNOCHANS 30
-#define QM_CHANAUTOLIMIT 31
-#define QM_CHANBANAUTOREMOVE 32
-#define QM_NOCHANBANAUTOREMOVE 33
-#define QM_INVALIDCHANNAME 34
-#define QM_ALREADYREGISTERED 35
-#define QM_CURUSERFLAGS 36
-#define QM_WELCOMEMESSAGEIS 37
-#define QM_GLOBALINFO 38
-#define QM_CHANNELINFO 39
-#define QM_PROTECTEDNICK 40
-#define QM_NICKWASFAKED 41
-#define QM_NOTPROTECTED 42
-#define QM_SAMEAUTH 43
-#define QM_AUTHFAIL 44
-#define QM_AUTHOK 45
-#define QM_NEWACCOUNT 46
-#define QM_AUTHNAMEINUSE 47
-#define QM_ALREADYONCHAN 48
-#define QM_NOTONCHAN 49
-#define QM_ALREADYOPPED 50
-#define QM_USERNOTONCHAN 51
-#define QM_USEROPPEDONCHAN 52
-#define QM_CANTOP 53
-#define QM_NOTOPPED 54
-#define QM_ALREADYVOICED 55
-#define QM_NOTVOICED 56
-#define QM_USERVOICEDONCHAN 57
-#define QM_REGBANHEADER 58
-#define QM_NOBANS 59
-#define QM_REMOVEDCHANBAN 60
-#define QM_NOTREMOVEDPERMBAN 61
-#define QM_REMOVEDPERMBAN 62
-#define QM_CANTVOICE 63
-#define QM_NOHELP 64
-#define QM_WHOISHEADER_NICK 65
-#define QM_WHOISHEADER_AUTH 66
-#define QM_WHOIS_USERS 67
-#define QM_WHOIS_LASTAUTH 68
-#define QM_WHOIS_LASTUSERHOST 69
-#define QM_WHOIS_USERID 70
-#define QM_WHOIS_INFO 71
-#define QM_WHOIS_COMMENT 72
-#define QM_WHOIS_FLAGS 73
-#define QM_WHOIS_CREATED 74
-#define QM_WHOIS_CHANHEADER 75
-#define QM_WHOIS_EMAIL 76
-#define QM_WHOIS_EMAILSET 77
-#define QM_COMMENT 78
-#define QM_NOCOMMENT 79
-#define QM_BADAUTH 80
-#define QM_USERHASBADAUTH 81
-#define QM_BADEMAIL 82
-#define QM_MAILTHROTTLED 83
-#define QM_MAILQUEUED 84
-#define QM_PWDONTMATCH 85
-#define QM_PWTOSHORT 86
-#define QM_PWCHANGED 87
-#define QM_INVALIDDURATION2 88
-#define QM_EMAILCHANGED 89
-#define QM_EMAILDONTMATCH 90
-#define QM_INVALIDEMAIL 91
-#define QM_EMAILTOOSHORT 92
-#define QM_NOTYOUREMAIL 93
-#define QM_EMAILNOAT 94
-#define QM_EMAILATEND 95
-#define QM_EMAILINVCHR 96
-#define QM_CHANNELNOTSUSPENDED 97
-#define QM_CHANNELALREADYSUSPENDED 98
-#define QM_CHANTYPE 99
-#define QM_UNKNOWNCHANTYPE 100
-#define QM_FOUNDER 101
-#define QM_ADDEDBY 102
-#define QM_ALREADYKNOWNONCHAN 103
-#define QM_CANNOTREMOVEOWNER 104
-#define QM_CANNOTREMOVEMASTER 105
-#define QM_UNKNOWNBAN 106
-#define QM_YOURLANGUAGE 107
-#define QM_LANGUAGELIST 108
-#define QM_UNKNOWNLANGUAGE 109
-#define QM_WHOIS_USERLANG 110
-#define QM_CHANTYPEIS 111
-#define QM_STATSHEADER 112
-#define QM_STATSADDED 113
-#define QM_STATSJOINS 114
-#define QM_STATSLASTACTIVE 115
-#define QM_AUTHSUSPENDED 116
-#define QM_REASON 117
-#define QM_EXPIRES 118
-#define QM_TOOMANYAUTHS 119
-#define QM_INVALIDDURATION 120
-#define QM_DISCONNECTINGUSER 121
-#define QM_USERALREADYSUSPENDED 122
-#define QM_USERNOTSUSPENDED 123
-#define QM_SPEWHEADER 124
-#define QM_TOOMANYRESULTS 125
-#define QM_RESULTCOUNT 126
-#define QM_SUSPENDKILL 127
-#define QM_LISTFLAGSHEADER 128
-#define QM_SUSPENDUSERLISTHEADER 129
-#define QM_SUSPENDCHANLISTHEADER 130
-#define QM_NOREQUESTOWNER 131
-#define QM_GRANTEDOWNER 132
-#define QM_AUTHHISTORYHEADER 133
-#define QM_CURDOMAINMODES 134
-#define QM_SPEWDOMAINHEADER 135
-#define QM_DOMAINLIMIT 136
-#define QM_PWTOWEAK 137
-#define QM_GIVEOWNERNOTMASTER 138
-#define QM_GIVEOWNERALREADYOWNER 139
-#define QM_GIVEOWNERNEEDHASH 140
-#define QM_GIVEOWNERWRONGHASH 141
-#define QM_SHOWINGDURATION 142
-#define QM_INVALIDACCOUNTNAME 143
-#define QM_CHALLENGEBADALGORITHM 144
-#define QM_NOCHALLENGE 145
-#define QM_USEGIVEOWNER 146
-#define QM_NOFLAGSPECIFIED 147
-#define QM_NEWBANALREADYBANNED 148
-#define QM_NEWBANOVERLAPS 149
-#define QM_REPLACINGTEMPBAN 150
-#define QM_PERMBANALREADYSET 151
-#define QM_NOTREPLACINGBANLDURATION 152
-#define QM_REPLACINGBANSDURATION 153
-#define QM_TOOMANYCHANLEVS 154
-#define QM_TOOMANYBANS 155
-#define QM_WARNNOTREMOVEDPERMBAN 156
-#define QM_MAXHELLOLIMIT 157
-#define QM_ADDRESSLIMIT 158
-#define QM_DOMAINBANNED 159
-#define QM_TYPEHELPFORHELP 160
-#define QM_REQUESTPASSPRIVUSER 161
-#define QM_EMAILMATCHESOLD 162
-#define QM_INVALIDLIMIT 163
-#define QM_ACCOUNTLOCKED 164
-#define QM_ACCOUNTNOTLOCKED 165
-#define QM_RESETOK 166
-#define QM_BADRESETCODE 167
-#define QM_CHALLENGEDDEPRECATED 168
-#define QM_CHANLEVSUMMARY 169
-#define QM_MAILLOCKHEADER 170
-#define QM_MAILLOCKLINE 171
-#define QM_MAILLOCKDOESNTEXIST 172
-#define QM_MAILLOCKALREADYEXISTS 173
-#define QM_MAILLOCKED 174
-#define QM_NOACCESSONUSER 175
-#define QM_NOCHANOPHISTORY 176
-#define QM_CHANOPHISTORYHEADER 177
-#define QM_OTHERUSERAUTHEDLIMIT 178
-#define QM_OTHERUSERAUTHED 179
-#define QM_STATSRESET 180
-#define QM_CHANLEVEMPTIEDCHANNEL 181
-#define QM_CHANLEVCHANGED 182
-#define QM_CHANLEVREMOVED 183
-#define QM_CHANLEVNOCHANGE 184
-#define QM_USERSHEADER 185
-#define QM_EMPTYCHAN 186
-#define QM_USERSSUMMARY 187
+/* Minimum acceptable reason length for stuff like deluser */
+#define MIN_REASONLEN 20
+
+#include "chanserv_messages.h"
+
+#define CSMIN(a, b) ((a)<(b)?(a):(b))
+#define CSMAX(a, b) ((a)>(b)?(a):(b))
/* List of privileged operations */
#define QPRIV_VIEWWELCOME 107
#define QPRIV_VIEWCOMMENTS 108
#define QPRIV_VIEWEMAIL 109
+#define QPRIV_VIEWCHANSUSPENSION 110
+#define QPRIV_VIEWSUSPENDEDBY 111
+#define QPRIV_VIEWWALLMESSAGE 112
#define QPRIV_CHANGECHANFLAGS 200
#define QPRIV_CHANGECHANLEV 201
/* User flags */
-#define QUFLAG_NOINFO 0x0001 /* +s */
+/* to reenable this also grep for NOINFO... as some code has been commented out */
+//#define QUFLAG_NOINFO 0x0001 /* +s */
+#define QUFLAG_INACTIVE 0x0001 /* +I */
#define QUFLAG_GLINE 0x0002 /* +g */
#define QUFLAG_NOTICE 0x0004 /* +n */
-/* SPARE FLAG 0x0008 */
+#define QUFLAG_STAFF 0x0008 /* +q */
#define QUFLAG_SUSPENDED 0x0010 /* +z */
#define QUFLAG_OPER 0x0020 /* +o */
#define QUFLAG_DEV 0x0040 /* +d */
#define QUFLAG_INFO 0x0400 /* +i */
#define QUFLAG_DELAYEDGLINE 0x0800 /* +G */
#define QUFLAG_NOAUTHLIMIT 0x1000 /* +L */
+#define QUFLAG_ACHIEVEMENTS 0x2000 /* +c */
#define QUFLAG_CLEANUPEXEMPT 0x4000 /* +D */
#define QUFLAG_TRUST 0x8000 /* +T */
-#define QUFLAG_ALL 0xdff7
+#define QUFLAG_ALL 0xffff
-#define UIsNoInfo(x) ((x)->flags & QUFLAG_NOINFO)
+//#define UIsNoInfo(x) ((x)->flags & QUFLAG_NOINFO)
+#define UIsNoInfo(x) 0
+#define UIsInactive(x) ((x)->flags & QUFLAG_INACTIVE)
#define UIsGline(x) ((x)->flags & QUFLAG_GLINE)
#define UIsNotice(x) ((x)->flags & QUFLAG_NOTICE)
#define UIsSuspended(x) ((x)->flags & QUFLAG_SUSPENDED)
#define UIsDelayedGline(x) ((x)->flags & QUFLAG_DELAYEDGLINE)
#define UIsNoAuthLimit(x) ((x)->flags & QUFLAG_NOAUTHLIMIT)
#define UIsCleanupExempt(x) ((x)->flags & QUFLAG_CLEANUPEXEMPT)
+#define UIsStaff(x) ((x)->flags & QUFLAG_STAFF)
+#define UIsAchievements(x) ((x)->flags & QUFLAG_ACHIEVEMENTS)
#define UHasSuspension(x) ((x)->flags & (QUFLAG_GLINE|QUFLAG_DELAYEDGLINE|QUFLAG_SUSPENDED))
+#define UHasStaffPriv(x) ((x)->flags & (QUFLAG_STAFF | QUFLAG_HELPER | QUFLAG_OPER | QUFLAG_ADMIN | QUFLAG_DEV))
#define UHasHelperPriv(x) ((x)->flags & (QUFLAG_HELPER | QUFLAG_OPER | QUFLAG_ADMIN | QUFLAG_DEV))
#define UHasOperPriv(x) ((x)->flags & (QUFLAG_OPER | QUFLAG_ADMIN | QUFLAG_DEV))
#define UHasAdminPriv(x) ((x)->flags & (QUFLAG_ADMIN | QUFLAG_DEV))
+#define USetInactive(x) ((x)->flags |= QUFLAG_INACTIVE)
#define USetGline(x) ((x)->flags |= QUFLAG_GLINE)
#define USetNotice(x) ((x)->flags |= QUFLAG_NOTICE)
#define USetSuspended(x) ((x)->flags |= QUFLAG_SUSPENDED)
#define USetCleanupExempt(x) ((x)->flags |= QUFLAG_CLEANUPEXEMPT)
#define USetTrust(x) ((x)->flags |= QUFLAG_TRUST)
+#define UClearInactive(x) ((x)->flags &= ~QUFLAG_INACTIVE)
#define UClearGline(x) ((x)->flags &= ~QUFLAG_GLINE)
#define UClearNotice(x) ((x)->flags &= ~QUFLAG_NOTICE)
#define UClearSuspended(x) ((x)->flags &= ~QUFLAG_SUSPENDED)
/* email */
#define MAX_RESEND_TIME 2*3600L /* cooling off period */
-#define VALID_EMAIL "^[-_.+[:alpha:][:digit:]]+(\\.[-_[:digit:][:alpha:]]+)*@([[:digit:][:alpha:]](-?[[:digit:][:alpha:]])*\\.)+[[:alpha:]]{2}([zmuvtgo]|fo|me|seum|op|ro)?$"
+#define VALID_EMAIL "^[-_.+[:alpha:][:digit:]]+(\\.[-_[:digit:][:alpha:]]+)*@([[:digit:][:alpha:]](-?[[:digit:][:alpha:]])*\\.)+[[:alpha:]]{2}([zmuvtgol]|fo|me|seum|op|ro)?$"
-#define VALID_ACCOUNT_NAME "^[-a-z0-9]*$"
+#define VALID_ACCOUNT_NAME "^[a-z][-a-z0-9]+$"
#define QMAIL_NEWACCOUNT 1 /* new account */
#define QMAIL_REQPW 2 /* requestpassword */
#define QMAIL_NEWPW 3 /* new password */
#define QMAIL_RESET 4 /* reset account */
#define QMAIL_NEWEMAIL 5 /* new email address */
+#define QMAIL_ACTIVATEEMAIL 6 /* new style new account */
/* Channel flags */
#define QCFLAG_VOICEALL 0x1000 /* +v */
#define QCFLAG_WELCOME 0x2000 /* +w */
#define QCFLAG_SUSPENDED 0x4000 /* +z */
+#define QCFLAG_ACHIEVEMENTS 0x8000 /* +h */
#define CIsAutoOp(x) ((x)->flags & QCFLAG_AUTOOP)
#define CIsBitch(x) ((x)->flags & QCFLAG_BITCH)
#define CIsSuspended(x) ((x)->flags & QCFLAG_SUSPENDED)
#define CIsInfo(x) ((x)->flags & QCFLAG_INFO)
#define CIsNoInfo(x) ((x)->flags & QCFLAG_NOINFO)
+#define CIsAchievements(x) ((x)->flags & QCFLAG_ACHIEVEMENTS)
#define CSetAutoOp(x) ((x)->flags |= QCFLAG_AUTOOP)
#define CSetBitch(x) ((x)->flags |= QCFLAG_BITCH)
#define QCFLAG_USERCONTROL (QCFLAG_AUTOOP|QCFLAG_BITCH|QCFLAG_AUTOLIMIT| \
QCFLAG_ENFORCE|QCFLAG_FORCETOPIC|QCFLAG_AUTOVOICE| \
QCFLAG_PROTECT|QCFLAG_TOPICSAVE|QCFLAG_VOICEALL| \
- QCFLAG_WELCOME|QCFLAG_KNOWNONLY)
+ QCFLAG_WELCOME|QCFLAG_KNOWNONLY|QCFLAG_ACHIEVEMENTS )
-#define QCFLAG_ALL 0x7fff
+#define QCFLAG_ALL 0xffff
/* Channel user ("chanlev") flags */
#define QCMD_OPER 0x0020 /* Only available to opers */
#define QCMD_ADMIN 0x0040 /* Only available to admins */
#define QCMD_DEV 0x0080 /* Only available to developers */
+#define QCMD_STAFF 0x0200 /* Only available to staff */
#define QCMD_ALIAS 0x0100 /* Don't list on SHOWCOMMANDS */
+#define QCMD_HIDDEN QCMD_ALIAS
+
+#define QCMD_ACHIEVEMENTS 0x0400 /* Achievement-related commands */
+#define QCMD_TITLES 0x0800 /* Title-related commands */
#define CS_INIT_DB 0x1 /* Loading database.. */
#define CS_INIT_NOUSER 0x2 /* Loaded DB, waiting for user to be created */
flag_t forcemodes; /* Forced modes */
flag_t denymodes; /* Denied modes */
- short limit; /* Limit to enforce if +l is set */
+ unsigned short limit; /* Limit to enforce if +l is set */
short autolimit; /* How many slots to leave when autolimiting */
short banstyle; /* Ban style for +b type bans */
short chanoppos; /* Position in the array */
} regchan;
+struct achievement_record;
+
/* Registered user */
typedef struct reguser {
#ifdef CS_PARANOID
int stealcount; /* How many times we've had to free the nick up */
nick *fakeuser; /* If we had to "take" the nick, here's the pointer */
+ time_t lastpasschange;
+
struct reguser *nextbydomain;
struct reguser *nextbyname;
struct reguser *nextbyID;
extern int chanserv_init_status;
extern int chanservdb_ready;
-extern PQModuleIdentifier q9pqid, q9apqid, q9cpqid, q9upqid;
+
+#ifndef CS_NODB
+extern DBModuleIdentifier q9dbid, q9adbid, q9cdbid, q9udbid;
+#endif
extern maildomain *maildomainnametable[MAILDOMAINHASHSIZE];
extern maildomain *maildomainIDtable[MAILDOMAINHASHSIZE];
extern unsigned int cslangcount;
extern sstring *csmessages[MAXLANG][MAXMESSAGES];
-extern char *defaultmessages[MAXMESSAGES];
extern const flag rcflags[];
extern const flag rcuflags[];
extern maillock *maillocks;
+extern sstring *cs_quitreason;
+
/* Function prototypes */
/* chanserv.c */
void csdb_createmail(reguser *rup, int type);
void csdb_dohelp(nick *np, Command *cmd);
-#define q9asyncquery(handler, tag, format, ...) pqasyncqueryi(q9pqid, handler, tag, format , ##__VA_ARGS__)
-#define q9a_asyncquery(handler, tag, format, ...) pqasyncqueryi(q9apqid, handler, tag, format , ##__VA_ARGS__)
-#define q9u_asyncquery(handler, tag, format, ...) pqasyncqueryi(q9upqid, handler, tag, format , ##__VA_ARGS__)
-#define q9c_asyncquery(handler, tag, format, ...) pqasyncqueryi(q9cpqid, handler, tag, format , ##__VA_ARGS__)
+#define q9asyncquery(handler, tag, format, ...) dbasyncqueryi(q9dbid, handler, tag, format , ##__VA_ARGS__)
+#define q9a_asyncquery(handler, tag, format, ...) dbasyncqueryi(q9adbid, handler, tag, format , ##__VA_ARGS__)
+#define q9u_asyncquery(handler, tag, format, ...) dbasyncqueryi(q9udbid, handler, tag, format , ##__VA_ARGS__)
+#define q9c_asyncquery(handler, tag, format, ...) dbasyncqueryi(q9cdbid, handler, tag, format , ##__VA_ARGS__)
+#define q9cleanup_asyncquery(handler, tag, format, ...) dbasyncqueryi(q9cleanupdbid, handler, tag, format , ##__VA_ARGS__)
/* chanservcrypto.c */
typedef int (*CRAlgorithm)(char *, const char *, const char *, const char *);
const char *cs_cralgorithmlist(void);
int cs_checkhashpass(const char *username, const char *password, const char *junk, const char *hash);
char *csc_generateresetcode(time_t lockuntil, char *username);
+int csc_verifyqticket(char *data, char *digest);
/* chanservuser.c */
void chanservreguser(void *arg);
void chanservjoinchan(channel *cp);
-#define chanservsendmessage(np, fmt, args...) chanservsendmessage_real(np, 0, fmt , ## args)
-#define chanservsendmessageoneline(np, fmt, args...) chanservsendmessage_real(np, 1, fmt , ## args)
-void chanservsendmessage_real(nick *np, int oneline, char *message, ... );
-void chanservwallmessage(char *message, ... );
+void chanservpartchan(channel *cp, char *reason);
+#define chanservsendmessage(np, fmt, ...) chanservsendmessage_real(np, 0, fmt , ##__VA_ARGS__)
+#define chanservsendmessageoneline(np, fmt, ...) chanservsendmessage_real(np, 1, fmt , ##__VA_ARGS__)
+void chanservsendmessage_real(nick *np, int oneline, char *message, ... ) __attribute__ ((format (printf, 3, 4)));
+void chanservwallmessage(char *message, ... ) __attribute__ ((format (printf, 1, 2)));
void chanservcommandinit();
void chanservcommandclose();
void chanservstdmessage(nick *np, int messageid, ... );
void cs_checkbans(channel *cp);
void cs_schedupdate(chanindex *cip, int mintime, int maxtime);
void cs_timerfunc(void *arg);
-void cs_removechannel(regchan *rcp);
+void cs_removechannel(regchan *rcp, char *reason);
int cs_removechannelifempty(nick *sender, regchan *rcp);
void cs_doallautomodes(nick *np);
void cs_checknickbans(nick *np);
typedef int (*UnbanFN)(void *arg, struct chanban *ban);
int cs_unbanfn(nick *sender, chanindex *cip, UnbanFN fn, void *arg, int removepermbans, int abortonfailure);
void cs_logchanop(regchan *rcp, char *nick, reguser *rup);
+int checkreason(nick *np, char *reason);
/* chanservstdcmds.c */
int cs_doshowcommands(void *source, int cargc, char **cargv);
int cs_dohelp(void *source, int cargc, char **cargv);
int cs_doquit(void *source, int cargc, char **cargv);
+int cs_dosetquitreason(void *source, int cargc, char **cargv);
int cs_dorename(void *source, int cargc, char **cargv);
int cs_dorehash(void *source, int cargc, char **cargv);
int cs_doversion(void *source, int cargc, char **cargv);
void cs_handleopchange(int hooknum, void *arg);
void cs_handlenewban(int hooknum, void *arg);
void cs_handlechanlostuser(int hooknum, void *arg);
+int cs_ischannelactive(channel *cp, regchan *rcp);
/* chanservmessages.c */
void initmessages();
/* chanservlog.c */
void cs_initlog();
void cs_closelog();
-void cs_log(nick *np, char *event, ...);
+void cs_log(nick *np, char *event, ...) __attribute__ ((format (printf, 2, 3)));
/* chanservdump.c */
int dumplastjoindata(const char *filename);
void csdb_createmaildomain(maildomain *mdp);
void csdb_updatemaildomain(maildomain *mdp);
void csdb_chanlevhistory_insert(regchan *rcp, nick *np, reguser *trup, flag_t oldflags, flag_t newflags);
-void csdb_accounthistory_insert(nick *np, char *oldpass, char *newpass, sstring *oldemail, sstring *newemail);
-void csdb_cleanuphistories();
+void csdb_accounthistory_insert(nick *np, char *oldpass, char *newpass, char *oldemail, char *newemail);
+void csdb_cleanuphistories(time_t);
void csdb_deletemaillock(maillock *mlp);
void csdb_createmaillock(maillock *mlp);
void csdb_updatemaillock(maillock *mlp);
+/* q9snprintf.c */
+void q9snprintf(char *buf, size_t size, const char *format, const char *args, ...);
+void q9vsnprintf(char *buf, size_t size, const char *format, const char *args, va_list ap);
+void q9strftime(char *buf, size_t size, time_t t);
+
+/* chanserv_flags.c */
+u_int64_t cs_accountflagmap(reguser *rup);
+u_int64_t cs_accountflagmap_str(char *flags);
+
+/* chanserv_cleanupdb.c */
+void cs_cleanupdb(nick *np);
+
#endif