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