]> jfr.im git - irc/quakenet/newserv.git/blame - chanserv/chanserv.c
Add module version info for trusts_migration and whowas_channels.
[irc/quakenet/newserv.git] / chanserv / chanserv.c
CommitLineData
c86edd1d
Q
1/*
2 * chanserv.c:
3 * The main chanserv core file.
4 */
5
6#include "chanserv.h"
dc9548f4 7#include "authlib.h"
c86edd1d
Q
8#include "../core/hooks.h"
9#include "../core/schedule.h"
b567a875
CP
10#include "../lib/version.h"
11
12MODULE_VERSION(QVERSION);
c86edd1d 13
c86edd1d
Q
14int chanservnext;
15
16int chanserv_init_status;
17
18sstring **chantypes;
9ecce0e8 19sstring *cs_quitreason;
c86edd1d 20
c86edd1d
Q
21void chanservfreestuff();
22void chanservfinishinit(int hooknum, void *arg);
2bb65abd 23static void cs_hourlyfunc(void *arg);
c86edd1d 24
ee8cd7d0 25DBModuleIdentifier q9dbid;
b3565978 26
c86edd1d
Q
27void chanservdumpstuff(void *arg) {
28 dumplastjoindata("lastjoin.dump");
29}
30
31void _init() {
b263aa79 32 /* Register the nick extension - the others are registered in the db module */
c86edd1d
Q
33 chanservnext=registernickext("nickserv");
34
45770ae6 35 chanservcryptoinit();
dc9548f4 36 csa_initregex();
45770ae6 37
ee8cd7d0 38 q9dbid = dbgetid();
b3565978 39
316959c1 40 if (chanservext!=-1 && chanservnext!=-1 && chanservaext!=-1) {
c86edd1d
Q
41 /* Set up the chantypes */
42 chantypes=(sstring **)malloc(CHANTYPES*sizeof(sstring *));
43 chantypes[0]=getsstring("(unspecified)",20);
44 chantypes[1]=getsstring("clan",20);
45 chantypes[2]=getsstring("league",20);
46 chantypes[3]=getsstring("private",20);
47 chantypes[4]=getsstring("special",20);
48 chantypes[5]=getsstring("gamesite",20);
49 chantypes[6]=getsstring("game",20);
af862bd5 50 chantypes[7]=getsstring("upgrade",20);
c86edd1d 51
c86edd1d
Q
52 /* And the log system */
53 cs_initlog();
54
c86edd1d
Q
55 /* Set up the command handler, and built in commands */
56 chanservcommandinit();
dd258305 57 chanservaddcommand("showcommands", 0, 1, cs_doshowcommands, "Lists available commands.","Usage: SHOWCOMMANDS [<mask>]\nPrints a list of commands currently available to you, where:\nmask - Mask of commands to list (* or ? are wildcards). If no mask is specified,\n all available commands are displayed.");
1f0d7c8b 58 chanservaddcommand("quit", QCMD_DEV, 1, cs_doquit, "Makes the bot QUIT and \"reconnect\".","");
f22ae726 59 chanservaddcommand("setquitreason", QCMD_DEV, 1, cs_dosetquitreason, "Sets the reason to be sent when quitting due to an unload.","");
1f0d7c8b 60 chanservaddcommand("rename", QCMD_DEV, 1, cs_dorename, "Changes the bot's name.","");
61 chanservaddcommand("rehash", QCMD_DEV, 0, cs_dorehash, "Reloads all text from database.","");
96249709 62 /* Make "HELP" take 2 arguments so things like "HELP chanflags #channel" work. Any junk after the command will go into arg 2 and be ignored. */
63 chanservaddcommand("help", 0, 2, cs_dohelp, "Displays help on a specific command.","Usage: HELP <command>\nShows help for a command, where:\ncommand - the command to show help for.\nFor a list of available commands, see SHOWCOMMANDS.\n");
634a5bfa 64 chanservaddcommand("version", 0, 1, cs_doversion, "Show Version.","Usage: VERSION\nShows the version number of the running bot.");
64f17f02 65
c86edd1d
Q
66 chanservaddctcpcommand("ping",cs_doctcpping);
67 chanservaddctcpcommand("version",cs_doctcpversion);
68 chanservaddctcpcommand("gender",cs_doctcpgender);
69
70 registerhook(HOOK_CHANSERV_DBLOADED, chanservfinishinit);
b263aa79 71
72 /* Now that the database is in a separate module it might be loaded already. */
73 if (chanservdb_ready)
74 chanservfinishinit(HOOK_CHANSERV_DBLOADED, NULL);
c86edd1d
Q
75 }
76}
77
78void chanservfinishinit(int hooknum, void *arg) {
79 Error("chanserv",ERR_INFO,"Database loaded, finishing initialisation.");
80
81 deregisterhook(HOOK_CHANSERV_DBLOADED, chanservfinishinit);
82
83 readlastjoindata("lastjoin.dump");
84
85 /* Schedule the dumps */
86 schedulerecurring(time(NULL)+DUMPINTERVAL,0,DUMPINTERVAL,chanservdumpstuff,NULL);
87
88 chanserv_init_status = CS_INIT_NOUSER;
89
90 /* Register the user */
91 scheduleoneshot(time(NULL)+1,&chanservreguser,NULL);
92}
93
94void chanserv_finalinit() {
95 int i;
fdba86cb 96 nick *np, *nnp;
c86edd1d
Q
97
98 /* Scan for users */
99 for (i=0;i<NICKHASHSIZE;i++)
fdba86cb 100 for (np=nicktable[i];np;np=nnp) {
101 nnp=np->next;
c86edd1d 102 cs_checknick(np);
fdba86cb 103 }
c86edd1d
Q
104
105 /* Register core hooks */
106 registerhook(HOOK_NICK_NEWNICK, cs_handlenick);
107 registerhook(HOOK_NICK_ACCOUNT, cs_handlenick);
108 registerhook(HOOK_NICK_LOSTNICK, cs_handlelostnick);
109 registerhook(HOOK_NICK_SETHOST, cs_handlesethost);
110 registerhook(HOOK_CHANNEL_NEWCHANNEL, cs_handlenewchannel);
111 registerhook(HOOK_CHANNEL_LOSTCHANNEL, cs_handlelostchannel);
112 registerhook(HOOK_CHANNEL_JOIN, cs_handlejoin);
113 registerhook(HOOK_CHANNEL_CREATE, cs_handlejoin);
114 registerhook(HOOK_CHANNEL_MODECHANGE, cs_handlemodechange);
115 registerhook(HOOK_CHANNEL_BURST, cs_handleburst);
116 registerhook(HOOK_CHANNEL_TOPIC, cs_handletopicchange);
117 registerhook(HOOK_CHANNEL_LOSTNICK, cs_handlechanlostuser);
32562540 118
119 chanserv_init_status = CS_INIT_READY;
120 triggerhook(HOOK_CHANSERV_RUNNING, NULL);
2bb65abd
CP
121
122 /* run every 60 minutes, first one 5 minutes after start */
123 schedulerecurring(time(NULL)+60*5,0,3600,cs_hourlyfunc,NULL);
124
316959c1 125 Error("chanserv",ERR_INFO,"Ready to roll.");
c86edd1d
Q
126}
127
128void _fini() {
ee8cd7d0 129 dbfreeid(q9dbid);
b3565978 130
2bb65abd 131 deleteallschedules(cs_hourlyfunc);
c86edd1d
Q
132 deleteallschedules(cs_timerfunc);
133 deleteallschedules(chanservreguser);
134 deleteallschedules(chanservdumpstuff);
135 deleteallschedules(chanservdgline);
136
b263aa79 137 if (chanservext>-1 && chanservnext>-1 && chanservaext>-1) {
c86edd1d
Q
138 int i;
139 for (i=0;i<CHANTYPES;i++)
140 freesstring(chantypes[i]);
141
142 free(chantypes);
143 }
144
c86edd1d 145 /* Free everything */
c86edd1d
Q
146 if (chanservnext!=-1) {
147 releasenickext(chanservnext);
148 }
149
150 if (chanservnick)
9ecce0e8 151 deregisterlocaluser(chanservnick, cs_quitreason?cs_quitreason->content:"Leaving");
152
153 freesstring(cs_quitreason);
c86edd1d
Q
154
155 deregisterhook(HOOK_NICK_NEWNICK, cs_handlenick);
156 deregisterhook(HOOK_NICK_ACCOUNT, cs_handlenick);
157 deregisterhook(HOOK_NICK_LOSTNICK, cs_handlelostnick);
158 deregisterhook(HOOK_NICK_SETHOST, cs_handlesethost);
159 deregisterhook(HOOK_CHANNEL_NEWCHANNEL, cs_handlenewchannel);
160 deregisterhook(HOOK_CHANNEL_LOSTCHANNEL, cs_handlelostchannel);
161 deregisterhook(HOOK_CHANNEL_JOIN, cs_handlejoin);
162 deregisterhook(HOOK_CHANNEL_CREATE, cs_handlejoin);
163 deregisterhook(HOOK_CHANNEL_MODECHANGE, cs_handlemodechange);
164 deregisterhook(HOOK_CHANNEL_BURST, cs_handleburst);
165 deregisterhook(HOOK_CHANNEL_TOPIC, cs_handletopicchange);
166 deregisterhook(HOOK_CHANNEL_LOSTNICK, cs_handlechanlostuser);
167 /* deregisterhook(HOOK_CHANNEL_OPPED, cs_handleopchange);
168 deregisterhook(HOOK_CHANNEL_DEOPPED, cs_handleopchange);
169 deregisterhook(HOOK_CHANNEL_DEVOICED, cs_handleopchange);
170 deregisterhook(HOOK_CHANNEL_BANSET, cs_handlenewban); */
65f2c6a3 171 deregisterhook(HOOK_CHANSERV_DBLOADED, chanservfinishinit); /* for safety */
c86edd1d
Q
172
173 chanservremovecommand("showcommands", cs_doshowcommands);
174 chanservremovecommand("quit", cs_doquit);
f22ae726 175 chanservremovecommand("setquitreason", cs_dosetquitreason);
c86edd1d
Q
176 chanservremovecommand("rename", cs_dorename);
177 chanservremovecommand("rehash", cs_dorehash);
178 chanservremovecommand("help", cs_dohelp);
64f17f02 179 chanservremovecommand("version", cs_doversion);
c86edd1d
Q
180 chanservremovectcpcommand("ping",cs_doctcpping);
181 chanservremovectcpcommand("version",cs_doctcpversion);
182 chanservremovectcpcommand("gender",cs_doctcpgender);
183 chanservcommandclose();
184
dc9548f4 185 csa_freeregex();
30a66d6c 186 chanservcryptofree();
dc9548f4 187
c86edd1d 188 cs_closelog();
c86edd1d 189}
2bb65abd
CP
190
191static void cs_hourlyfunc(void *arg) {
192 int i, total = 0, touched = 0, toorecent = 0;
193 chanindex *cip, *ncip;
194 regchan *rcp;
195 time_t t = time(NULL);
196
197 for (i=0;i<CHANNELHASHSIZE;i++) {
198 for (cip=chantable[i];cip;cip=ncip) {
199 ncip=cip->next;
200 if (!(rcp=cip->exts[chanservext]))
201 continue;
202
203 total++;
204
205 if(cip->channel && cs_ischannelactive(cip->channel, rcp)) {
206 rcp->lastactive = t;
207 if (rcp->lastcountersync < (t - COUNTERSYNCINTERVAL)) {
208 csdb_updatechannelcounters(rcp);
209 rcp->lastcountersync=t;
210 touched++;
211 } else {
212 toorecent++;
213 }
214 }
215
216 }
217 }
218 cs_log(NULL,"hourly update active completed, %d seen, %d touched, %d too recent to update.",total,touched,toorecent);
219}