]> jfr.im git - irc/quakenet/newserv.git/blame - noperserv/noperserv_db.c
CHANNEL/LUA: Add ability to see old modes to HOOK_CHANNEL_MODECHANGE.
[irc/quakenet/newserv.git] / noperserv / noperserv_db.c
CommitLineData
3e3692bf
CP
1/*
2 * NOperserv v0.01
3 *
4 * A replacement for Germania's ageing Operservice2
5 * DB functions
6 *
7 * Copyright (C) 2005 Chris Porter.
8 */
9
10#include "../nick/nick.h"
11#include "../core/error.h"
12#include "../lib/irc_string.h"
13#include "../core/schedule.h"
114b4eea 14#include "../dbapi2/dbapi2.h"
3e3692bf
CP
15
16#include "noperserv.h"
3e3692bf
CP
17#include "noperserv_db.h"
18
3e3692bf
CP
19#include <stdlib.h>
20
e43481af 21int db_loaded = 0;
3e3692bf
CP
22unsigned long loadedusers = 0;
23
24unsigned long lastuserid;
25
26no_autheduser *authedusers = NULL;
27
e43481af
CP
28void noperserv_create_tables(void);
29
3e3692bf 30void noperserv_free_user(no_autheduser *au);
e54cd6b5 31void noperserv_load_users(const DBAPIResult *res, void *arg);
3e3692bf
CP
32
33void noperserv_check_nick(nick *np);
34void noperserv_nick_account(int hooknum, void *arg);
35void noperserv_quit_account(int hooknum, void *arg);
36
37void nopserserv_delete_from_autheduser(nick *np, no_autheduser *au);
3e3692bf 38
114b4eea
CP
39static DBAPIConn *nodb;
40
7a32ca6e 41int noperserv_load_db(void) {
114b4eea
CP
42 if(!nodb) {
43 nodb = dbapi2open(DBAPI2_DEFAULT, "noperserv");
44 if(!nodb) {
45 Error("noperserv", ERR_STOP, "Could not connect to database.");
46 return 0;
47 }
ad50c27c 48 }
7a32ca6e 49
e43481af 50 db_loaded = 1;
3e3692bf
CP
51
52 authedusers = NULL;
53
e43481af
CP
54 noperserv_create_tables();
55
e4b54524 56 nodb->query(nodb, noperserv_load_users, NULL,
e54cd6b5 57 "SELECT ID, authname, flags, noticelevel FROM ?", "T", "users");
7a32ca6e
CP
58
59 return 1;
3e3692bf
CP
60}
61
e54cd6b5 62void noperserv_load_users(const DBAPIResult *res, void *arg) {
3e3692bf
CP
63 no_autheduser *nu;
64 nick *np;
ee8cd7d0 65 int i;
3e3692bf 66
114b4eea
CP
67 if(!res)
68 return;
69
70 if(!res->success) {
3e3692bf 71 Error("noperserv", ERR_ERROR, "Error loading user list.");
114b4eea
CP
72 res->clear(res);
73 return;
3e3692bf
CP
74 }
75
3e3692bf
CP
76 lastuserid = 0;
77
114b4eea
CP
78 while(res->next(res)) {
79 nu = noperserv_new_autheduser(res->get(res, 1));
3e3692bf
CP
80 if(!nu)
81 continue;
82
114b4eea
CP
83 nu->id = strtoul(res->get(res, 0), NULL, 10);
84 nu->authlevel = strtoul(res->get(res, 2), NULL, 10);
85 nu->noticelevel = strtoul(res->get(res, 3), NULL, 10);
3e3692bf
CP
86 nu->newuser = 0;
87 if(nu->id > lastuserid)
88 lastuserid = nu->id;
89 }
90
16739dbe 91 Error("noperserv", ERR_INFO, "Loaded %lu users", loadedusers);
3e3692bf
CP
92
93 for(i=0;i<NICKHASHSIZE;i++)
94 for(np=nicktable[i];np;np=np->next)
95 if(IsAccount(np))
96 noperserv_check_nick(np);
97
98 registerhook(HOOK_NICK_ACCOUNT, &noperserv_nick_account);
99 registerhook(HOOK_NICK_NEWNICK, &noperserv_nick_account);
100 registerhook(HOOK_NICK_LOSTNICK, &noperserv_quit_account);
ee8cd7d0 101
114b4eea 102 res->clear(res);
3e3692bf
CP
103}
104
105void noperserv_create_tables(void) {
e4b54524 106 nodb->createtable(nodb, NULL, NULL,
e54cd6b5 107 "CREATE TABLE ? ("
3e3692bf 108 "ID INT NOT NULL,"
e54cd6b5 109 "authname VARCHAR(?) NOT NULL,"
3e3692bf
CP
110 "flags INT NOT NULL,"
111 "noticelevel INT NOT NULL,"
e54cd6b5 112 "PRIMARY KEY (ID))", "Td", "users", ACCOUNTLEN);
3e3692bf
CP
113}
114
115void noperserv_cleanup_db(void) {
116 no_autheduser *ap, *np;
117
118 deregisterhook(HOOK_NICK_LOSTNICK, &noperserv_quit_account);
119 deregisterhook(HOOK_NICK_NEWNICK, &noperserv_nick_account);
120 deregisterhook(HOOK_NICK_ACCOUNT, &noperserv_nick_account);
121
122 ap = authedusers;
123 while(ap) {
124 np = ap->next;
125 noperserv_free_user(ap);
126 ap = np;
127 }
aa944539 128
114b4eea
CP
129 nodb->close(nodb);
130 nodb = NULL;
3e3692bf
CP
131}
132
133no_autheduser *noperserv_new_autheduser(char *authname) {
134 no_autheduser *au = (no_autheduser *)malloc(sizeof(no_autheduser));
135 if(!au)
136 return NULL;
137
138 au->authname = getsstring(authname, ACCOUNTLEN);
139 if(!au->authname) {
140 free(au);
141 return NULL;
142 }
143
144 loadedusers++;
145 au->newuser = 1;
146 au->nick = NULL;
147
148 au->next = authedusers;
149 authedusers = au;
150
151 return au;
152}
153
154void noperserv_delete_autheduser(no_autheduser *au) {
155 no_autheduser *ap = authedusers, *lp = NULL;
156
157 if(!au->newuser)
e4b54524 158 nodb->squery(nodb, "DELETE FROM ? WHERE id = ?", "Tu", "users", au->id);
3e3692bf
CP
159
160 for(;ap;lp=ap,ap=ap->next) {
161 if(ap == au) {
162 if(lp) {
163 lp->next = ap->next;
164 } else {
165 authedusers = ap->next;
166 }
167 noperserv_free_user(ap);
168 return;
169 }
170 }
171}
172
173void noperserv_update_autheduser(no_autheduser *au) {
174 if(au->newuser) {
e4b54524 175 nodb->squery(nodb, "INSERT INTO ? (id, authname, flags, noticelevel) VALUES (?,?,?,?)", "Tusuu", "users", au->id, au->authname->content, NOGetAuthLevel(au), NOGetNoticeLevel(au));
3e3692bf
CP
176 au->newuser = 0;
177 } else {
e4b54524 178 nodb->squery(nodb, "UPDATE ? SET flags = ?, noticelevel = ? WHERE id = ?", "Tuuu", "users", NOGetAuthLevel(au), NOGetNoticeLevel(au), au->id);
3e3692bf
CP
179 }
180}
181
182void noperserv_free_user(no_autheduser *au) {
183 no_nicklist *cp = au->nick, *np;
184
185 while(cp) {
186 cp->nick->exts[noperserv_ext] = NULL;
187 np = cp->next;
188 free(cp);
189 cp = np;
190 }
191
192 freesstring(au->authname);
193 free(au);
194
195 loadedusers--;
196}
197
198void noperserv_check_nick(nick *np) {
199 no_autheduser *au = noperserv_get_autheduser(np->authname);
200 if(au)
201 noperserv_add_to_autheduser(np, au);
202}
203
204void noperserv_nick_account(int hooknum, void *arg) {
205 noperserv_check_nick((nick *)arg);
206}
207
208void noperserv_quit_account(int hooknum, void *arg) {
209 nick *np = (void *)arg;
210 no_autheduser *au = NOGetAuthedUser(np);
211 no_nicklist *nl, *ln = NULL;
212 if(!au)
213 return;
214
215 for(nl=au->nick;nl;ln=nl,nl=nl->next)
216 if(nl->nick == np) {
217 if(ln) {
218 ln->next = nl->next;
219 } else {
220 au->nick = nl->next;
221 }
222 free(nl);
223 break;
224 }
225}
226
227no_autheduser *noperserv_get_autheduser(char *authname) {
228 no_autheduser *au = authedusers;
229
230 for(;au;au=au->next)
231 if(!ircd_strcmp(authname, au->authname->content))
232 return au;
233
234 return NULL;
235}
236
237unsigned long noperserv_get_autheduser_count(void) {
238 return loadedusers;
239}
240
241unsigned long noperserv_next_autheduser_id(void) {
242 return ++lastuserid;
243}
244
245void noperserv_add_to_autheduser(nick *np, no_autheduser *au) {
246 no_nicklist *nl = (no_nicklist *)malloc(sizeof(no_nicklist));
247 if(!nl)
248 return;
249
250 np->exts[noperserv_ext] = au;
251
252 nl->nick = np;
253
254 nl->next = au->nick;
255 au->nick = nl;
256}
257
258void nopserserv_delete_from_autheduser(nick *np, no_autheduser *au) {
259 no_nicklist *cp = au->nick, *lp = NULL;
260
261 for(;cp;lp=cp,cp=cp->next)
262 if(cp->nick == np) {
263 if(lp) {
264 lp->next = cp->next;
265 } else {
266 au->nick = cp->next;
267 }
268 free(cp);
269 break;
270 }
271}