]> jfr.im git - irc/quakenet/newserv.git/blob - noperserv/noperserv_db.c
JUPE: Remove RB support
[irc/quakenet/newserv.git] / noperserv / noperserv_db.c
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"
14 #include "../dbapi2/dbapi2.h"
15
16 #include "noperserv.h"
17 #include "noperserv_db.h"
18
19 #include <stdlib.h>
20
21 int db_loaded = 0;
22 unsigned long loadedusers = 0;
23
24 unsigned long lastuserid;
25
26 no_autheduser *authedusers = NULL;
27
28 void noperserv_create_tables(void);
29
30 void noperserv_free_user(no_autheduser *au);
31 void noperserv_load_users(const DBAPIResult *res, void *arg);
32
33 void noperserv_check_nick(nick *np);
34 void noperserv_nick_account(int hooknum, void *arg);
35 void noperserv_quit_account(int hooknum, void *arg);
36
37 void nopserserv_delete_from_autheduser(nick *np, no_autheduser *au);
38
39 static DBAPIConn *nodb;
40
41 int noperserv_load_db(void) {
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 }
48 }
49
50 db_loaded = 1;
51
52 authedusers = NULL;
53
54 noperserv_create_tables();
55
56 nodb->query(nodb, noperserv_load_users, NULL,
57 "SELECT ID, authname, flags, noticelevel FROM ?", "T", "users");
58
59 return 1;
60 }
61
62 void noperserv_load_users(const DBAPIResult *res, void *arg) {
63 no_autheduser *nu;
64 nick *np;
65 int i;
66
67 if(!res)
68 return;
69
70 if(!res->success) {
71 Error("noperserv", ERR_ERROR, "Error loading user list.");
72 res->clear(res);
73 return;
74 }
75
76 lastuserid = 0;
77
78 while(res->next(res)) {
79 nu = noperserv_new_autheduser(res->get(res, 1));
80 if(!nu)
81 continue;
82
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);
86 nu->newuser = 0;
87 if(nu->id > lastuserid)
88 lastuserid = nu->id;
89 }
90
91 Error("noperserv", ERR_INFO, "Loaded %lu users", loadedusers);
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);
101
102 res->clear(res);
103 }
104
105 void noperserv_create_tables(void) {
106 nodb->createtable(nodb, NULL, NULL,
107 "CREATE TABLE ? ("
108 "ID INT NOT NULL,"
109 "authname VARCHAR(?) NOT NULL,"
110 "flags INT NOT NULL,"
111 "noticelevel INT NOT NULL,"
112 "PRIMARY KEY (ID))", "Td", "users", ACCOUNTLEN);
113 }
114
115 void 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 }
128
129 nodb->close(nodb);
130 nodb = NULL;
131 }
132
133 no_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
154 void noperserv_delete_autheduser(no_autheduser *au) {
155 no_autheduser *ap = authedusers, *lp = NULL;
156
157 if(!au->newuser)
158 nodb->squery(nodb, "DELETE FROM ? WHERE id = ?", "Tu", "users", au->id);
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
173 void noperserv_update_autheduser(no_autheduser *au) {
174 if(au->newuser) {
175 nodb->squery(nodb, "INSERT INTO ? (id, authname, flags, noticelevel) VALUES (?,?,?,?)", "Tusuu", "users", au->id, au->authname->content, NOGetAuthLevel(au), NOGetNoticeLevel(au));
176 au->newuser = 0;
177 } else {
178 nodb->squery(nodb, "UPDATE ? SET flags = ?, noticelevel = ? WHERE id = ?", "Tuuu", "users", NOGetAuthLevel(au), NOGetNoticeLevel(au), au->id);
179 }
180 }
181
182 void 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
198 void 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
204 void noperserv_nick_account(int hooknum, void *arg) {
205 noperserv_check_nick((nick *)arg);
206 }
207
208 void 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
227 no_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
237 unsigned long noperserv_get_autheduser_count(void) {
238 return loadedusers;
239 }
240
241 unsigned long noperserv_next_autheduser_id(void) {
242 return ++lastuserid;
243 }
244
245 void 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
258 void 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 }