]> jfr.im git - irc/quakenet/newserv.git/blob - noperserv/noperserv_db.c
Fix more warnings.
[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 "../dbapi/dbapi.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(DBConn *dbconn, 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 int noperserv_load_db(void) {
40 if(!dbconnected()) {
41 Error("noperserv", ERR_STOP, "Could not connect to database.");
42 return 0;
43 }
44
45 if(db_loaded)
46 noperserv_cleanup_db();
47
48 db_loaded = 1;
49
50 authedusers = NULL;
51
52 noperserv_create_tables();
53
54 dbasyncquery(noperserv_load_users, NULL,
55 "SELECT ID, authname, flags, noticelevel FROM noperserv.users");
56
57 return 1;
58 }
59
60 void noperserv_load_users(DBConn *dbconn, void *arg) {
61 DBResult *pgres = dbgetresult(dbconn);
62 no_autheduser *nu;
63 nick *np;
64 int i;
65
66 if(!dbquerysuccessful(pgres)) {
67 Error("noperserv", ERR_ERROR, "Error loading user list.");
68 dbclear(pgres);
69 return;
70 }
71
72 lastuserid = 0;
73
74 while(dbfetchrow(pgres)) {
75 nu = noperserv_new_autheduser(dbgetvalue(pgres, 1));
76 if(!nu)
77 continue;
78
79 nu->id = strtoul(dbgetvalue(pgres, 0), NULL, 10);
80 nu->authlevel = strtoul(dbgetvalue(pgres, 2), NULL, 10);
81 nu->noticelevel = strtoul(dbgetvalue(pgres, 3), NULL, 10);
82 nu->newuser = 0;
83 if(nu->id > lastuserid)
84 lastuserid = nu->id;
85 }
86
87 Error("noperserv", ERR_INFO, "Loaded %d users", loadedusers);
88
89 for(i=0;i<NICKHASHSIZE;i++)
90 for(np=nicktable[i];np;np=np->next)
91 if(IsAccount(np))
92 noperserv_check_nick(np);
93
94 registerhook(HOOK_NICK_ACCOUNT, &noperserv_nick_account);
95 registerhook(HOOK_NICK_NEWNICK, &noperserv_nick_account);
96 registerhook(HOOK_NICK_LOSTNICK, &noperserv_quit_account);
97
98 dbclear(pgres);
99 }
100
101 void noperserv_create_tables(void) {
102 dbattach("noperserv");
103 dbcreatequery(
104 "CREATE TABLE noperserv.users ("
105 "ID INT NOT NULL,"
106 "authname VARCHAR(%d) NOT NULL,"
107 "flags INT NOT NULL,"
108 "noticelevel INT NOT NULL,"
109 "PRIMARY KEY (ID))", ACCOUNTLEN);
110 }
111
112 void noperserv_cleanup_db(void) {
113 no_autheduser *ap, *np;
114
115 deregisterhook(HOOK_NICK_LOSTNICK, &noperserv_quit_account);
116 deregisterhook(HOOK_NICK_NEWNICK, &noperserv_nick_account);
117 deregisterhook(HOOK_NICK_ACCOUNT, &noperserv_nick_account);
118
119 ap = authedusers;
120 while(ap) {
121 np = ap->next;
122 noperserv_free_user(ap);
123 ap = np;
124 }
125
126 dbdetach("noperserv");
127 }
128
129 no_autheduser *noperserv_new_autheduser(char *authname) {
130 no_autheduser *au = (no_autheduser *)malloc(sizeof(no_autheduser));
131 if(!au)
132 return NULL;
133
134 au->authname = getsstring(authname, ACCOUNTLEN);
135 if(!au->authname) {
136 free(au);
137 return NULL;
138 }
139
140 loadedusers++;
141 au->newuser = 1;
142 au->nick = NULL;
143
144 au->next = authedusers;
145 authedusers = au;
146
147 return au;
148 }
149
150 void noperserv_delete_autheduser(no_autheduser *au) {
151 no_autheduser *ap = authedusers, *lp = NULL;
152
153 if(!au->newuser)
154 dbquery("DELETE FROM noperserv.users WHERE id = %d", au->id);
155
156 for(;ap;lp=ap,ap=ap->next) {
157 if(ap == au) {
158 if(lp) {
159 lp->next = ap->next;
160 } else {
161 authedusers = ap->next;
162 }
163 noperserv_free_user(ap);
164 return;
165 }
166 }
167 }
168
169 void noperserv_update_autheduser(no_autheduser *au) {
170 if(au->newuser) {
171 char escapedauthname[ACCOUNTLEN * 2 + 1];
172 dbescapestring(escapedauthname, au->authname->content, au->authname->length);
173 dbquery("INSERT INTO noperserv.users (id, authname, flags, noticelevel) VALUES (%lu,'%s',%u,%u)", au->id, au->authname->content, NOGetAuthLevel(au), NOGetNoticeLevel(au));
174 au->newuser = 0;
175 } else {
176 dbquery("UPDATE noperserv.users SET flags = %u, noticelevel = %u WHERE id = %lu", NOGetAuthLevel(au), NOGetNoticeLevel(au), au->id);
177 }
178 }
179
180 void noperserv_free_user(no_autheduser *au) {
181 no_nicklist *cp = au->nick, *np;
182
183 while(cp) {
184 cp->nick->exts[noperserv_ext] = NULL;
185 np = cp->next;
186 free(cp);
187 cp = np;
188 }
189
190 freesstring(au->authname);
191 free(au);
192
193 loadedusers--;
194 }
195
196 void noperserv_check_nick(nick *np) {
197 no_autheduser *au = noperserv_get_autheduser(np->authname);
198 if(au)
199 noperserv_add_to_autheduser(np, au);
200 }
201
202 void noperserv_nick_account(int hooknum, void *arg) {
203 noperserv_check_nick((nick *)arg);
204 }
205
206 void noperserv_quit_account(int hooknum, void *arg) {
207 nick *np = (void *)arg;
208 no_autheduser *au = NOGetAuthedUser(np);
209 no_nicklist *nl, *ln = NULL;
210 if(!au)
211 return;
212
213 for(nl=au->nick;nl;ln=nl,nl=nl->next)
214 if(nl->nick == np) {
215 if(ln) {
216 ln->next = nl->next;
217 } else {
218 au->nick = nl->next;
219 }
220 free(nl);
221 break;
222 }
223 }
224
225 no_autheduser *noperserv_get_autheduser(char *authname) {
226 no_autheduser *au = authedusers;
227
228 for(;au;au=au->next)
229 if(!ircd_strcmp(authname, au->authname->content))
230 return au;
231
232 return NULL;
233 }
234
235 unsigned long noperserv_get_autheduser_count(void) {
236 return loadedusers;
237 }
238
239 unsigned long noperserv_next_autheduser_id(void) {
240 return ++lastuserid;
241 }
242
243 void noperserv_add_to_autheduser(nick *np, no_autheduser *au) {
244 no_nicklist *nl = (no_nicklist *)malloc(sizeof(no_nicklist));
245 if(!nl)
246 return;
247
248 np->exts[noperserv_ext] = au;
249
250 nl->nick = np;
251
252 nl->next = au->nick;
253 au->nick = nl;
254 }
255
256 void nopserserv_delete_from_autheduser(nick *np, no_autheduser *au) {
257 no_nicklist *cp = au->nick, *lp = NULL;
258
259 for(;cp;lp=cp,cp=cp->next)
260 if(cp->nick == np) {
261 if(lp) {
262 lp->next = cp->next;
263 } else {
264 au->nick = cp->next;
265 }
266 free(cp);
267 break;
268 }
269 }