]> jfr.im git - irc/quakenet/newserv.git/blame - noperserv/noperserv_db.c
Add raw string type 'R', and table name 'T' to dbsafequery.
[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);
114b4eea 31void noperserv_load_users(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
114b4eea 56 nodb->query(nodb, noperserv_load_users, NULL,
4277aef7 57 "SELECT ID, authname, flags, noticelevel FROM %s", nodb->tablename(nodb, "users"));
7a32ca6e
CP
58
59 return 1;
3e3692bf
CP
60}
61
114b4eea 62void noperserv_load_users(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) {
114b4eea 106 nodb->createtable(nodb, NULL, NULL,
4277aef7 107 "CREATE TABLE %s ("
3e3692bf
CP
108 "ID INT NOT NULL,"
109 "authname VARCHAR(%d) NOT NULL,"
110 "flags INT NOT NULL,"
111 "noticelevel INT NOT NULL,"
4277aef7 112 "PRIMARY KEY (ID))", nodb->tablename(nodb, "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)
4277aef7 158 nodb->squery(nodb, "DELETE FROM %s WHERE id = %lu", nodb->tablename(nodb, "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) {
175 char escapedauthname[ACCOUNTLEN * 2 + 1];
114b4eea 176 nodb->escapestring(nodb, escapedauthname, au->authname->content, au->authname->length);
4277aef7 177 nodb->squery(nodb, "INSERT INTO %s (id, authname, flags, noticelevel) VALUES (%lu,'%s',%u,%u)", nodb->tablename(nodb, "users"), au->id, au->authname->content, NOGetAuthLevel(au), NOGetNoticeLevel(au));
3e3692bf
CP
178 au->newuser = 0;
179 } else {
4277aef7 180 nodb->squery(nodb, "UPDATE %s SET flags = %u, noticelevel = %u WHERE id = %lu", nodb->tablename(nodb, "users"), NOGetAuthLevel(au), NOGetNoticeLevel(au), au->id);
3e3692bf
CP
181 }
182}
183
184void noperserv_free_user(no_autheduser *au) {
185 no_nicklist *cp = au->nick, *np;
186
187 while(cp) {
188 cp->nick->exts[noperserv_ext] = NULL;
189 np = cp->next;
190 free(cp);
191 cp = np;
192 }
193
194 freesstring(au->authname);
195 free(au);
196
197 loadedusers--;
198}
199
200void noperserv_check_nick(nick *np) {
201 no_autheduser *au = noperserv_get_autheduser(np->authname);
202 if(au)
203 noperserv_add_to_autheduser(np, au);
204}
205
206void noperserv_nick_account(int hooknum, void *arg) {
207 noperserv_check_nick((nick *)arg);
208}
209
210void noperserv_quit_account(int hooknum, void *arg) {
211 nick *np = (void *)arg;
212 no_autheduser *au = NOGetAuthedUser(np);
213 no_nicklist *nl, *ln = NULL;
214 if(!au)
215 return;
216
217 for(nl=au->nick;nl;ln=nl,nl=nl->next)
218 if(nl->nick == np) {
219 if(ln) {
220 ln->next = nl->next;
221 } else {
222 au->nick = nl->next;
223 }
224 free(nl);
225 break;
226 }
227}
228
229no_autheduser *noperserv_get_autheduser(char *authname) {
230 no_autheduser *au = authedusers;
231
232 for(;au;au=au->next)
233 if(!ircd_strcmp(authname, au->authname->content))
234 return au;
235
236 return NULL;
237}
238
239unsigned long noperserv_get_autheduser_count(void) {
240 return loadedusers;
241}
242
243unsigned long noperserv_next_autheduser_id(void) {
244 return ++lastuserid;
245}
246
247void noperserv_add_to_autheduser(nick *np, no_autheduser *au) {
248 no_nicklist *nl = (no_nicklist *)malloc(sizeof(no_nicklist));
249 if(!nl)
250 return;
251
252 np->exts[noperserv_ext] = au;
253
254 nl->nick = np;
255
256 nl->next = au->nick;
257 au->nick = nl;
258}
259
260void nopserserv_delete_from_autheduser(nick *np, no_autheduser *au) {
261 no_nicklist *cp = au->nick, *lp = NULL;
262
263 for(;cp;lp=cp,cp=cp->next)
264 if(cp->nick == np) {
265 if(lp) {
266 lp->next = cp->next;
267 } else {
268 au->nick = cp->next;
269 }
270 free(cp);
271 break;
272 }
273}