#define _GNU_SOURCE
#include <string.h>
#include <time.h>
+#include <stdarg.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 "../dbapi/dbapi.h"
#define CS_PARANOID
#endif
/* Q9 Version */
-#define QVERSION "0.80"
+#define QVERSION "1.00"
/* Mini-hash of known users on channels to make lookups faster;
* how big do we make it? */
#define LINGERTIME 300
#define DUMPINTERVAL 300
#define EMAILLEN 60
-#define CHANTYPES 7
+#define CHANTYPES 8
+#define CHANOPHISTORY 10
/* Suspension and g-line hit count limits */
#define MAXGLINEUSERS 50
#define MAXSUSPENDHIT 500
/* Maximum number of times a user may attempt to auth */
-#define MAXAUTHATTEMPT 3
+#define MAXAUTHATTEMPT 5
/* Maximum number of hellos in a session */
#define MAXHELLOS 3
/* Maximum number of times a user may actually be authed */
#define MAXAUTHCOUNT 2
+/* Maximum number of accounts that may share an email address */
+#define MD_DEFAULTACTLIMIT 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 40
+
/* Sizes of the main hashes */
#define REGUSERHASHSIZE 60000
#define MAILDOMAINHASHSIZE 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_DURATIONTOOLONG 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
+#include "chanserv_messages.h"
/* 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_CHANGECHANFLAGS 200
#define QPRIV_CHANGECHANLEV 201
/* User flags */
-#define QUFLAG_NEEDAUTH 0x0001 /* +l */
+#define QUFLAG_NOINFO 0x0001 /* +s */
#define QUFLAG_GLINE 0x0002 /* +g */
#define QUFLAG_NOTICE 0x0004 /* +n */
-#define QUFLAG_RESTRICTED 0x0008 /* +r */
+#define QUFLAG_STAFF 0x0008 /* +q */
#define QUFLAG_SUSPENDED 0x0010 /* +z */
#define QUFLAG_OPER 0x0020 /* +o */
#define QUFLAG_DEV 0x0040 /* +d */
#define QUFLAG_DELAYEDGLINE 0x0800 /* +G */
#define QUFLAG_NOAUTHLIMIT 0x1000 /* +L */
#define QUFLAG_CLEANUPEXEMPT 0x4000 /* +D */
-#define QUFLAG_ALL 0x1fff
+#define QUFLAG_TRUST 0x8000 /* +T */
+#define QUFLAG_ALL 0xdfff
-#define UIsNeedAuth(x) ((x)->flags & QUFLAG_NEEDAUTH)
+#define UIsNoInfo(x) ((x)->flags & QUFLAG_NOINFO)
#define UIsGline(x) ((x)->flags & QUFLAG_GLINE)
#define UIsNotice(x) ((x)->flags & QUFLAG_NOTICE)
-#define UIsRestricted(x) ((x)->flags & QUFLAG_RESTRICTED)
#define UIsSuspended(x) ((x)->flags & QUFLAG_SUSPENDED)
#define UIsOper(x) ((x)->flags & QUFLAG_OPER)
#define UIsDev(x) ((x)->flags & QUFLAG_DEV)
#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 UHasSuspension(x) ((x)->flags & (QUFLAG_GLINE|QUFLAG_DELAYEDGLINE|QUFLAG_SUSPENDED|QUFLAG_NEEDAUTH))
+#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 USetNeedAuth(x) ((x)->flags |= QUFLAG_NEEDAUTH)
#define USetGline(x) ((x)->flags |= QUFLAG_GLINE)
#define USetNotice(x) ((x)->flags |= QUFLAG_NOTICE)
-#define USetRestricted(x) ((x)->flags |= QUFLAG_RESTRICTED)
#define USetSuspended(x) ((x)->flags |= QUFLAG_SUSPENDED)
#define USetOper(x) ((x)->flags |= QUFLAG_OPER)
#define USetDev(x) ((x)->flags |= QUFLAG_DEV)
#define USetCleanupExempt(x) ((x)->flags |= QUFLAG_CLEANUPEXEMPT)
#define USetTrust(x) ((x)->flags |= QUFLAG_TRUST)
-#define UClearNeedAuth(x) ((x)->flags &= ~QUFLAG_NEEDAUTH)
#define UClearGline(x) ((x)->flags &= ~QUFLAG_GLINE)
#define UClearNotice(x) ((x)->flags &= ~QUFLAG_NOTICE)
-#define UClearRestricted(x) ((x)->flags &= ~QUFLAG_RESTRICTED)
#define UClearSuspended(x) ((x)->flags &= ~QUFLAG_SUSPENDED)
#define UClearOper(x) ((x)->flags &= ~QUFLAG_OPER)
#define UClearDev(x) ((x)->flags &= ~QUFLAG_DEV)
#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 QCFLAG_JOINED 0x0080 /* +j */
#define QCFLAG_KNOWNONLY 0x0100 /* +k */
#define QCFLAG_PROTECT 0x0200 /* +p */
+#define QCFLAG_NOINFO 0x0400 /* +s */
#define QCFLAG_TOPICSAVE 0x0800 /* +t */
#define QCFLAG_VOICEALL 0x1000 /* +v */
#define QCFLAG_WELCOME 0x2000 /* +w */
#define CIsWelcome(x) ((x)->flags & QCFLAG_WELCOME)
#define CIsSuspended(x) ((x)->flags & QCFLAG_SUSPENDED)
#define CIsInfo(x) ((x)->flags & QCFLAG_INFO)
+#define CIsNoInfo(x) ((x)->flags & QCFLAG_NOINFO)
#define CSetAutoOp(x) ((x)->flags |= QCFLAG_AUTOOP)
#define CSetBitch(x) ((x)->flags |= QCFLAG_BITCH)
#define QCUFLAG_DENY 0x0004 /* +d */
#define QCUFLAG_AUTOVOICE 0x0008 /* +g */
#define QCUFLAG_QUIET 0x0010 /* +q */
+#define QCUFLAG_NOINFO 0x0020 /* +s */
#define QCUFLAG_TOPIC 0x0040 /* +t */
#define QCUFLAG_HIDEWELCOME 0x0080 /* +w */
#define QCUFLAG_PROTECT 0x0100 /* +p */
-#define QCUFLAG_HIDEINFO 0x0200 /* +i */
+#define QCUFLAG_INFO 0x0200 /* +i */
#define QCUFLAG_KNOWN 0x0400 /* +k */
#define QCUFLAG_AUTOINVITE 0x0800 /* +j */
QCUFLAG_VOICE|QCUFLAG_PROTECT)
#define QCUFLAG_SELFCON (QCUFLAG_OP | QCUFLAG_VOICE | QCUFLAG_AUTOOP | QCUFLAG_AUTOVOICE | \
- QCUFLAG_TOPIC | QCUFLAG_HIDEINFO)
+ QCUFLAG_TOPIC | QCUFLAG_INFO)
-#define QCUFLAGS_PERSONAL (QCUFLAG_HIDEINFO | QCUFLAG_HIDEWELCOME | QCUFLAG_AUTOINVITE)
+#define QCUFLAGS_PUBLIC (QCUFLAG_OWNER | QCUFLAG_MASTER | QCUFLAG_OP | QCUFLAG_VOICE | \
+ QCUFLAG_KNOWN | QCUFLAG_AUTOOP | QCUFLAG_AUTOVOICE | QCUFLAG_TOPIC | \
+ QCUFLAG_PROTECT)
+
+#define QCUFLAGS_PUNISH (QCUFLAG_BANNED | QCUFLAG_QUIET | QCUFLAG_DENY)
+#define QCUFLAGS_PERSONAL (QCUFLAG_HIDEWELCOME | QCUFLAG_AUTOINVITE)
#define QCUFLAG_ALL 0xffff
#define CUIsDeny(x) ((x)->flags & QCUFLAG_DENY)
#define CUIsAutoVoice(x) ((x)->flags & QCUFLAG_AUTOVOICE)
#define CUIsQuiet(x) ((x)->flags & QCUFLAG_QUIET)
+#define CUIsNoInfo(x) ((x)->flags & QCUFLAG_NOINFO)
#define CUIsTopic(x) ((x)->flags & QCUFLAG_TOPIC)
#define CUIsHideWelcome(x) ((x)->flags & QCUFLAG_HIDEWELCOME)
#define CUIsProtect(x) ((x)->flags & QCUFLAG_PROTECT)
-#define CUIsHideInfo(x) ((x)->flags & QCUFLAG_HIDEINFO)
+#define CUIsInfo(x) ((x)->flags & QCUFLAG_INFO)
#define CUIsKnown(x) ((x)->flags & QCUFLAG_KNOWN)
#define CUIsAutoInvite(x) ((x)->flags & QCUFLAG_AUTOINVITE)
#define MDFLAG_ACTLIMIT 0x0004 /* +u */
#define MDFLAG_ALL 0x0007
+#define MDFLAG_DEFAULT MDFLAG_ACTLIMIT
+
#define MDHasLimit(x) ((x)->flags & MDFLAG_LIMIT)
#define MDSetLimit(x) ((x)->flags |= MDFLAG_LIMIT)
#define MDClearLimit(x) ((x)->flags &= ~MDFLAG_LIMIT)
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 */
time_t lastbancheck; /* Timestamp of last ban check */
time_t lastcountersync; /* When the counters were last synced.. */
time_t lastpart; /* When the last user left the channel */
+ time_t suspendtime; /* When the channel was suspended */
unsigned int founder; /* founder */
unsigned int addedby; /* oper adding chan */
struct regchanuser *regusers[REGCHANUSERHASHSIZE];
struct regban *bans; /* List of bans on the channel */
+
+ char chanopnicks[CHANOPHISTORY][NICKLEN+1]; /* Last CHANOPHISTORY ppl to get ops */
+ unsigned int chanopaccts[CHANOPHISTORY]; /* Which account was responsible for each one */
+ short chanoppos; /* Position in the array */
} regchan;
/* Registered user */
unsigned int suspendby; /* Userid of oper who suspended this user */
time_t suspendexp; /* Expiry date of suspension */
+ time_t suspendtime; /* When user was suspended */
+ time_t lockuntil; /* Time until users account is unlocked (pass change, email, etc) */
char password[PASSLEN+1];
sstring *localpart;
maildomain *domain;
- sstring *email; /* Registered e-mail */
+ sstring *email; /* Registered e-mail */
+ sstring *lastemail; /* Last registered e-mail */
sstring *lastuserhost; /* Last user@host */
sstring *suspendreason; /* Why the account is suspended */
sstring *comment; /* Oper-settable user comment */
struct activeuser *next; /* purely for keeping track of free, but not free'd structures */
} activeuser;
+typedef struct maillock {
+#ifdef CS_PARANOID
+ unsigned int maillock_magic;
+#endif
+ unsigned int id;
+ sstring *pattern;
+ sstring *reason;
+ unsigned int createdby;
+ time_t created;
+ struct maillock *next;
+} maillock;
+
#ifdef CS_PARANOID
#define REGUSERMAGIC 0x4d42de03
#define REGCHANBANMAGIC 0x5a6f555a
#define ACTIVEUSERMAGIC 0x897f98a0
#define MAILDOMAINMAGIC 0x27cde46f
+#define MAILLOCKMAGIC 0x3c81d762
#define verifyreguser(x) assert((x)->reguser_magic == REGUSERMAGIC)
#define verifyregchan(x) assert((x)->regchan_magic == REGCHANMAGIC)
#define verifyregchanban(x) assert((x)->regchanban_magic == REGCHANBANMAGIC)
#define verifyactiveuser(x) assert((x)->activeuser_magic == ACTIVEUSERMAGIC)
#define verifymaildomain(x) assert((x)->maildomain_magic == MAILDOMAINMAGIC)
+#define verifymaillock(x) assert((x)->maillock_magic == MAILLOCKMAGIC)
#define tagreguser(x) ((x)->reguser_magic = REGUSERMAGIC)
#define tagregchan(x) ((x)->regchan_magic = REGCHANMAGIC)
#define tagregchanban(x) ((x)->regchanban_magic = REGCHANBANMAGIC)
#define tagactiveuser(x) ((x)->activeuser_magic = ACTIVEUSERMAGIC)
#define tagmaildomain(x) ((x)->maildomain_magic = MAILDOMAINMAGIC)
-
+#define tagmaillock(x) ((x)->maillock_magic = MAILLOCKMAGIC)
#else
#define verifyreguser(x)
#define verifyregchanban(x)
#define verifyactiveuser(x)
#define verifymaildomain(x)
+#define verifymaillock(x)
#define tagreguser(x)
#define tagregchan(x)
#define tagregchanban(x)
#define tagactiveuser(x)
#define tagmaildomain(x)
+#define tagmaillock(x)
#endif
extern unsigned int lastchannelID;
extern unsigned int lastbanID;
extern unsigned int lastdomainID;
+extern unsigned int lastmaillockID;
extern int chanserv_init_status;
extern int chanservdb_ready;
+extern DBModuleIdentifier q9dbid, q9adbid, q9cdbid, q9udbid;
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 sstring **chantypes;
+extern maillock *maillocks;
+
+extern sstring *cs_quitreason;
+
/* Function prototypes */
/* chanserv.c */
void freeactiveuser(activeuser *aup);
maildomain *getmaildomain();
void freemaildomain(maildomain *mdp);
+maillock *getmaillock();
+void freemaillock(maillock *mlp);
/* chanservhash.c */
void chanservhashinit();
maildomain *findmaildomainbydomain(char *domain);
maildomain *findmaildomainbyemail(char *email);
maildomain *findorcreatemaildomain(char *email);
+maildomain *findnearestmaildomain(char *domain);
void removemaildomainfromhash(maildomain *mdp);
void addregusertomaildomain(reguser *rup, maildomain *mdp);
void delreguserfrommaildomain(reguser *rup, maildomain *mdp);
+reguser *findreguserbyemail(const char *email);
/* chanservdb.c */
int chanservdbinit();
void csdb_createmail(reguser *rup, int type);
void csdb_dohelp(nick *np, Command *cmd);
+#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__)
+
/* chanservcrypto.c */
typedef int (*CRAlgorithm)(char *, const char *, const char *, const char *);
void chanservcryptoinit(void);
+void chanservcryptofree(void);
void cs_getrandbytes(unsigned char *buf, size_t bytes);
char *cs_calcchallenge(const unsigned char *entropy);
CRAlgorithm cs_cralgorithm(const char *algorithm);
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);
/* chanservuser.c */
void chanservreguser(void *arg);
void chanservjoinchan(channel *cp);
-void chanservsendmessage(nick *np, char *message, ... );
+#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 chanservcommandinit();
void chanservcommandclose();
void cs_schedupdate(chanindex *cip, int mintime, int maxtime);
void cs_timerfunc(void *arg);
void cs_removechannel(regchan *rcp);
+int cs_removechannelifempty(nick *sender, regchan *rcp);
void cs_doallautomodes(nick *np);
void cs_checknickbans(nick *np);
void cs_setregban(chanindex *cip, regban *rbp);
int checkresponse(reguser *rup, const unsigned char *entropy, const char *response, CRAlgorithm algorithm);
int checkhashpass(reguser *rup, const char *junk, const char *hash);
flag_t cs_sanitisechanlev(flag_t flags);
-
typedef int (*UnbanFN)(void *arg, struct chanban *ban);
-void cs_unbanfn(nick *sender, chanindex *cip, UnbanFN fn, void *arg, int removepermbans);
+int cs_unbanfn(nick *sender, chanindex *cip, UnbanFN fn, void *arg, int removepermbans, int abortonfailure);
+void cs_logchanop(regchan *rcp, char *nick, reguser *rup);
/* 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);
int cs_doctcpping(void *source, int cargc, char **cargv);
int cs_doctcpversion(void *source, int cargc, char **cargv);
int cs_doctcpgender(void *source, int cargc, char **cargv);
+int cs_sendhelp(nick *sender, char *cmd, int oneline);
/* chanservnetevents.c */
void cs_handlenick(int hooknum, void *arg);
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_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);
+
+/* chanserv_flags.c */
+flag_t cs_accountflagmap(reguser *rup);
+flag_t cs_accountflagmap_str(char *flags);
#endif