]> jfr.im git - irc/quakenet/newserv.git/blob - chanserv/chanserv.c
Merge
[irc/quakenet/newserv.git] / chanserv / chanserv.c
1 /*
2 * chanserv.c:
3 * The main chanserv core file.
4 */
5
6 #include "chanserv.h"
7 #include "../core/hooks.h"
8 #include "../core/schedule.h"
9
10 int chanservext;
11 int chanservnext;
12 int chanservaext;
13
14 int chanserv_init_status;
15
16 sstring **chantypes;
17
18 const flag rcflags[] = {
19 { 'a', QCFLAG_AUTOOP },
20 { 'b', QCFLAG_BITCH },
21 { 'c', QCFLAG_AUTOLIMIT },
22 { 'e', QCFLAG_ENFORCE },
23 { 'f', QCFLAG_FORCETOPIC },
24 { 'g', QCFLAG_AUTOVOICE },
25 { 'i', QCFLAG_INFO },
26 { 'j', QCFLAG_JOINED },
27 { 'k', QCFLAG_KNOWNONLY },
28 { 'p', QCFLAG_PROTECT },
29 { 's', QCFLAG_SPAMPROT },
30 { 't', QCFLAG_TOPICSAVE },
31 { 'v', QCFLAG_VOICEALL },
32 { 'w', QCFLAG_WELCOME },
33 { 'z', QCFLAG_SUSPENDED },
34 { '\0', 0 } };
35
36 const flag rcuflags[] = {
37 { 'a', QCUFLAG_AUTOOP },
38 { 'b', QCUFLAG_BANNED },
39 { 'd', QCUFLAG_DENY },
40 { 'g', QCUFLAG_AUTOVOICE },
41 { 'i', QCUFLAG_HIDEINFO },
42 { 'j', QCUFLAG_AUTOINVITE },
43 { 'k', QCUFLAG_KNOWN },
44 { 'm', QCUFLAG_MASTER },
45 { 'n', QCUFLAG_OWNER },
46 { 'o', QCUFLAG_OP },
47 { 'p', QCUFLAG_PROTECT },
48 { 'q', QCUFLAG_QUIET },
49 { 's', QCUFLAG_SPAMCON },
50 { 't', QCUFLAG_TOPIC },
51 { 'v', QCUFLAG_VOICE },
52 { 'w', QCUFLAG_HIDEWELCOME },
53 { '\0', 0 } };
54
55 const flag ruflags[] = {
56 { 'a', QUFLAG_ADMIN },
57 { 'd', QUFLAG_DEV },
58 { 'g', QUFLAG_GLINE },
59 { 'G', QUFLAG_DELAYEDGLINE },
60 { 'h', QUFLAG_HELPER },
61 { 'i', QUFLAG_INFO },
62 { 'l', QUFLAG_NEEDAUTH },
63 { 'L', QUFLAG_NOAUTHLIMIT },
64 { 'n', QUFLAG_NOTICE },
65 { 'o', QUFLAG_OPER },
66 { 'p', QUFLAG_PROTECT },
67 { 'r', QUFLAG_RESTRICTED },
68 { 'z', QUFLAG_SUSPENDED },
69 { '\0', 0 } };
70
71 void chanservfreestuff();
72 void chanservfinishinit(int hooknum, void *arg);
73
74 void chanservdumpstuff(void *arg) {
75 dumplastjoindata("lastjoin.dump");
76 }
77
78 void _init() {
79 /* Register the extension */
80 chanservext=registerchanext("chanserv");
81 chanservnext=registernickext("nickserv");
82 chanservaext=registerauthnameext("chanserv");
83
84 if (chanservext!=-1 && chanservnext!=-1 && chanservaext!=-1) {
85 /* Set up the chantypes */
86 chantypes=(sstring **)malloc(CHANTYPES*sizeof(sstring *));
87 chantypes[0]=getsstring("(unspecified)",20);
88 chantypes[1]=getsstring("clan",20);
89 chantypes[2]=getsstring("league",20);
90 chantypes[3]=getsstring("private",20);
91 chantypes[4]=getsstring("special",20);
92 chantypes[5]=getsstring("gamesite",20);
93 chantypes[6]=getsstring("game",20);
94
95 /* Set up the allocators and the hashes */
96 chanservallocinit();
97 chanservhashinit();
98
99 /* And the messages */
100 initmessages();
101
102 /* And the log system */
103 cs_initlog();
104
105 /* Now load the database */
106 chanserv_init_status = CS_INIT_DB;
107 chanservdbinit();
108
109 /* Set up the command handler, and built in commands */
110 chanservcommandinit();
111 chanservaddcommand("showcommands", 0, 1, cs_doshowcommands, "Lists available commands.");
112 chanservaddcommand("quit", QCMD_DEV, 1, cs_doquit, "Makes the bot QUIT and \"reconnect\".");
113 chanservaddcommand("rename", QCMD_DEV, 1, cs_dorename, "Changes the bot's name.");
114 chanservaddcommand("rehash", QCMD_DEV, 0, cs_dorehash, "Reloads all text from database.");
115 chanservaddcommand("help", 0, 1, cs_dohelp, "Displays help on a specific command.");
116
117 chanservaddctcpcommand("ping",cs_doctcpping);
118 chanservaddctcpcommand("version",cs_doctcpversion);
119 chanservaddctcpcommand("gender",cs_doctcpgender);
120
121 registerhook(HOOK_CHANSERV_DBLOADED, chanservfinishinit);
122 }
123 }
124
125 void chanservfinishinit(int hooknum, void *arg) {
126 Error("chanserv",ERR_INFO,"Database loaded, finishing initialisation.");
127
128 deregisterhook(HOOK_CHANSERV_DBLOADED, chanservfinishinit);
129
130 readlastjoindata("lastjoin.dump");
131
132 /* Schedule the dumps */
133 schedulerecurring(time(NULL)+DUMPINTERVAL,0,DUMPINTERVAL,chanservdumpstuff,NULL);
134
135 chanserv_init_status = CS_INIT_NOUSER;
136
137 /* Register the user */
138 scheduleoneshot(time(NULL)+1,&chanservreguser,NULL);
139 }
140
141 void chanserv_finalinit() {
142 int i;
143 nick *np;
144
145 /* Scan for users */
146 for (i=0;i<NICKHASHSIZE;i++)
147 for (np=nicktable[i];np;np=np->next)
148 cs_checknick(np);
149
150 /* Register core hooks */
151 registerhook(HOOK_NICK_NEWNICK, cs_handlenick);
152 registerhook(HOOK_NICK_ACCOUNT, cs_handlenick);
153 registerhook(HOOK_NICK_LOSTNICK, cs_handlelostnick);
154 registerhook(HOOK_NICK_SETHOST, cs_handlesethost);
155 registerhook(HOOK_CHANNEL_NEWCHANNEL, cs_handlenewchannel);
156 registerhook(HOOK_CHANNEL_LOSTCHANNEL, cs_handlelostchannel);
157 registerhook(HOOK_CHANNEL_JOIN, cs_handlejoin);
158 registerhook(HOOK_CHANNEL_CREATE, cs_handlejoin);
159 registerhook(HOOK_CHANNEL_MODECHANGE, cs_handlemodechange);
160 registerhook(HOOK_CHANNEL_BURST, cs_handleburst);
161 registerhook(HOOK_CHANNEL_TOPIC, cs_handletopicchange);
162 registerhook(HOOK_CHANNEL_LOSTNICK, cs_handlechanlostuser);
163
164 Error("chanserv",ERR_INFO,"Ready to roll.");
165 }
166
167 void _fini() {
168 deleteallschedules(cs_timerfunc);
169 deleteallschedules(chanservreguser);
170 deleteallschedules(chanservdumpstuff);
171 deleteallschedules(chanservdgline);
172
173 if (chanservext>-1 && chanservnext>-1) {
174 int i;
175 for (i=0;i<CHANTYPES;i++)
176 freesstring(chantypes[i]);
177
178 free(chantypes);
179 }
180
181 chanservfreestuff();
182
183 /* Free everything */
184 if (chanservext!=-1) {
185 releasechanext(chanservext);
186 }
187
188 if (chanservnext!=-1) {
189 releasenickext(chanservnext);
190 }
191
192 if (chanservaext!=-1) {
193 releaseauthnameext(chanservaext);
194 }
195
196 if (chanservnick)
197 deregisterlocaluser(chanservnick, "Leaving");
198
199 deregisterhook(HOOK_NICK_NEWNICK, cs_handlenick);
200 deregisterhook(HOOK_NICK_ACCOUNT, cs_handlenick);
201 deregisterhook(HOOK_NICK_LOSTNICK, cs_handlelostnick);
202 deregisterhook(HOOK_NICK_SETHOST, cs_handlesethost);
203 deregisterhook(HOOK_CHANNEL_NEWCHANNEL, cs_handlenewchannel);
204 deregisterhook(HOOK_CHANNEL_LOSTCHANNEL, cs_handlelostchannel);
205 deregisterhook(HOOK_CHANNEL_JOIN, cs_handlejoin);
206 deregisterhook(HOOK_CHANNEL_CREATE, cs_handlejoin);
207 deregisterhook(HOOK_CHANNEL_MODECHANGE, cs_handlemodechange);
208 deregisterhook(HOOK_CHANNEL_BURST, cs_handleburst);
209 deregisterhook(HOOK_CHANNEL_TOPIC, cs_handletopicchange);
210 deregisterhook(HOOK_CHANNEL_LOSTNICK, cs_handlechanlostuser);
211 /* deregisterhook(HOOK_CHANNEL_OPPED, cs_handleopchange);
212 deregisterhook(HOOK_CHANNEL_DEOPPED, cs_handleopchange);
213 deregisterhook(HOOK_CHANNEL_DEVOICED, cs_handleopchange);
214 deregisterhook(HOOK_CHANNEL_BANSET, cs_handlenewban); */
215 deregisterhook(HOOK_CHANSERV_DBLOADED, chanservfinishinit); /* for safety */
216
217 chanservremovecommand("showcommands", cs_doshowcommands);
218 chanservremovecommand("quit", cs_doquit);
219 chanservremovecommand("rename", cs_dorename);
220 chanservremovecommand("rehash", cs_dorehash);
221 chanservremovecommand("help", cs_dohelp);
222 chanservremovectcpcommand("ping",cs_doctcpping);
223 chanservremovectcpcommand("version",cs_doctcpversion);
224 chanservremovectcpcommand("gender",cs_doctcpgender);
225 chanservcommandclose();
226
227 cs_closelog();
228
229 chanservdbclose();
230 csfreeall();
231 }
232
233 void chanservfreestuff() {
234 int i;
235 chanindex *cip, *ncip;
236 regchan *rcp;
237 reguser *rup;
238 regchanuser *rcup;
239 regban *rbp;
240
241 for (i=0;i<REGUSERHASHSIZE;i++) {
242 for (rup=regusernicktable[i];rup;rup=rup->nextbyname) {
243 freesstring(rup->email);
244 freesstring(rup->lastuserhost);
245 freesstring(rup->suspendreason);
246 freesstring(rup->comment);
247 freesstring(rup->info);
248
249 for (rcup=rup->knownon;rcup;rcup=rcup->nextbyuser)
250 freesstring(rcup->info);
251 }
252 }
253
254 for (i=0;i<CHANNELHASHSIZE;i++) {
255 for (cip=chantable[i];cip;cip=ncip) {
256 ncip=cip->next;
257 if ((rcp=cip->exts[chanservext])) {
258 freesstring(rcp->welcome);
259 freesstring(rcp->topic);
260 freesstring(rcp->key);
261 freesstring(rcp->suspendreason);
262 freesstring(rcp->comment);
263 for (rbp=rcp->bans;rbp;rbp=rbp->next) {
264 freesstring(rbp->reason);
265 freechanban(rbp->cbp);
266 }
267 cip->exts[chanservext]=NULL;
268 releasechanindex(cip);
269 }
270 }
271 }
272
273 }