]> jfr.im git - irc/quakenet/newserv.git/blob - trusts/db.c
Fix bug in db flushing.
[irc/quakenet/newserv.git] / trusts / db.c
1 #include "../dbapi2/dbapi2.h"
2 #include "../core/error.h"
3 #include "../core/hooks.h"
4 #include "../core/schedule.h"
5 #include "trusts.h"
6
7 DBAPIConn *trustsdb;
8 static int tgmaxid, thmaxid;
9 static int loaderror;
10 static void *flushschedule;
11
12 int trustsdbloaded;
13
14 void createtrusttables(int migration);
15 void trusts_flush(void);
16
17 void createtrusttables(int migration) {
18 char *groups, *hosts;
19
20 if(migration) {
21 groups = "migration_groups";
22 hosts = "migration_hosts";
23 } else {
24 groups = "groups";
25 hosts = "hosts";
26 }
27
28 trustsdb->createtable(trustsdb, NULL, NULL,
29 "CREATE TABLE ? (id INT PRIMARY KEY, name VARCHAR(?), trustedfor INT, mode INT, maxperident INT, maxusage INT, expires INT, lastseen INT, lastmaxuserreset INT, createdby VARCHAR(?), contact VARCHAR(?), comment VARCHAR(?))",
30 "Tdddd", groups, TRUSTNAMELEN, NICKLEN, CONTACTLEN, COMMENTLEN
31 );
32
33 /* I'd like multiple keys here but that's not gonna happen on a cross-database platform :( */
34 trustsdb->createtable(trustsdb, NULL, NULL, "CREATE TABLE ? (id INT PRIMARY KEY, groupid INT, host VARCHAR(?), maxusage INT, lastseen INT)", "Td", hosts, TRUSTHOSTLEN);
35 }
36
37 static void flushdatabase(void *arg) {
38 trusts_flush();
39 }
40
41 static void loadcomplete(void) {
42 /* error has already been shown */
43 if(loaderror)
44 return;
45
46 trustsdbloaded = 1;
47 flushschedule = schedulerecurring(time(NULL) + 300, 0, 300, flushdatabase, NULL);
48
49 triggerhook(HOOK_TRUSTS_DB_LOADED, NULL);
50 }
51
52 static void loadhosts_data(const DBAPIResult *result, void *tag) {
53 if(!result) {
54 loaderror = 1;
55 return;
56 }
57
58 if(!result->success) {
59 Error("trusts", ERR_ERROR, "Error loading hosts table.");
60 loaderror = 1;
61
62 result->clear(result);
63 return;
64 }
65
66 if(result->fields != 5) {
67 Error("trusts", ERR_ERROR, "Wrong number of fields in hosts table.");
68 loaderror = 1;
69
70 result->clear(result);
71 return;
72 }
73
74 while(result->next(result)) {
75 unsigned int groupid, id;
76 char *host;
77 unsigned int maxusage, lastseen;
78 trustgroup *tg;
79
80 id = strtoul(result->get(result, 0), NULL, 10);
81 if(id > thmaxid)
82 thmaxid = id;
83
84 groupid = strtoul(result->get(result, 1), NULL, 10);
85
86 tg = tg_getbyid(groupid);
87 if(!tg) {
88 Error("trusts", ERR_WARNING, "Orphaned trust group host: %d", groupid);
89 continue;
90 }
91
92 /* NOTE: 2 is at the bottom */
93 maxusage = strtoul(result->get(result, 3), NULL, 10);
94 lastseen = (time_t)strtoul(result->get(result, 4), NULL, 10);
95 host = result->get(result, 2);
96
97 if(!th_add(tg, id, host, maxusage, lastseen))
98 Error("trusts", ERR_WARNING, "Error adding host to trust %d: %s", groupid, host);
99 }
100
101 result->clear(result);
102
103 loadcomplete();
104 }
105
106 static void loadhosts_fini(const DBAPIResult *result, void *tag) {
107 Error("trusts", ERR_INFO, "Finished loading hosts, maximum id: %d", thmaxid);
108 }
109
110 static void loadgroups_data(const DBAPIResult *result, void *tag) {
111 if(!result) {
112 loaderror = 1;
113 return;
114 }
115
116 if(!result->success) {
117 Error("trusts", ERR_ERROR, "Error loading group table.");
118 loaderror = 1;
119
120 result->clear(result);
121 return;
122 }
123
124 if(result->fields != 12) {
125 Error("trusts", ERR_ERROR, "Wrong number of fields in groups table.");
126 loaderror = 1;
127
128 result->clear(result);
129 return;
130 }
131
132 while(result->next(result)) {
133 unsigned int id;
134 sstring *name, *createdby, *contact, *comment;
135 unsigned int trustedfor, mode, maxperident, maxusage;
136 time_t expires, lastseen, lastmaxuserreset;
137
138 id = strtoul(result->get(result, 0), NULL, 10);
139 if(id > tgmaxid)
140 tgmaxid = id;
141
142 name = getsstring(result->get(result, 1), TRUSTNAMELEN);
143 trustedfor = strtoul(result->get(result, 2), NULL, 10);
144 mode = atoi(result->get(result, 3));
145 maxperident = strtoul(result->get(result, 4), NULL, 10);
146 maxusage = strtoul(result->get(result, 5), NULL, 10);
147 expires = (time_t)strtoul(result->get(result, 6), NULL, 10);
148 lastseen = (time_t)strtoul(result->get(result, 7), NULL, 10);
149 lastmaxuserreset = (time_t)strtoul(result->get(result, 8), NULL, 10);
150 createdby = getsstring(result->get(result, 9), NICKLEN);
151 contact = getsstring(result->get(result, 10), CONTACTLEN);
152 comment = getsstring(result->get(result, 11), COMMENTLEN);
153
154 if(name && createdby && contact && comment) {
155 if(!tg_add(id, name->content, trustedfor, mode, maxperident, maxusage, expires, lastseen, lastmaxuserreset, createdby->content, contact->content, comment->content))
156 Error("trusts", ERR_WARNING, "Error adding trustgroup %d: %s", id, name->content);
157 } else {
158 Error("trusts", ERR_ERROR, "Error allocating sstring in group loader, id: %d", id);
159 }
160
161 freesstring(name);
162 freesstring(createdby);
163 freesstring(contact);
164 freesstring(comment);
165 }
166
167 result->clear(result);
168 }
169
170 static void loadgroups_fini(const DBAPIResult *result, void *tag) {
171 Error("trusts", ERR_INFO, "Finished loading groups, maximum id: %d.", tgmaxid);
172 }
173
174 int trusts_loaddb(void) {
175 trustsdb = dbapi2open(NULL, "trusts");
176 if(!trustsdb) {
177 Error("trusts", ERR_WARNING, "Unable to connect to db -- not loaded.");
178 return 0;
179 }
180
181 createtrusttables(0);
182
183 loaderror = 0;
184
185 trustsdb->loadtable(trustsdb, NULL, loadgroups_data, loadgroups_fini, NULL, "groups");
186 trustsdb->loadtable(trustsdb, NULL, loadhosts_data, loadhosts_fini, NULL, "hosts");
187
188 return 1;
189 }
190
191 void trusts_closedb(void) {
192 if(!trustsdb)
193 return;
194
195 deleteschedule(flushschedule, flushdatabase, NULL);
196 flushdatabase(NULL);
197
198 trusts_freeall();
199 trustsdbloaded = 0;
200 thmaxid = tgmaxid = 0;
201
202 trustsdb->close(trustsdb);
203 trustsdb = NULL;
204 }
205
206 void th_dbupdatecounts(trusthost *th) {
207 trustsdb->squery(trustsdb, "UPDATE ? SET lastseen = ?, maxusage = ? WHERE id = ?", "Ttuu", "hosts", th->lastseen, th->maxusage, th->id);
208 }
209
210 void tg_dbupdatecounts(trustgroup *tg) {
211 trustsdb->squery(trustsdb, "UPDATE ? SET lastseen = ?, maxusage = ? WHERE id = ?", "Ttuu", "groups", tg->lastseen, tg->maxusage, tg->id);
212 }