]> jfr.im git - irc/quakenet/newserv.git/blame - trusts/db.c
We guarantee all sstrings are non NULL.
[irc/quakenet/newserv.git] / trusts / db.c
CommitLineData
2b6e02e2
CP
1#include "../dbapi2/dbapi2.h"
2#include "../core/error.h"
be2823bc 3#include "../core/hooks.h"
4be1aaf2 4#include "../core/schedule.h"
2b6e02e2
CP
5#include "trusts.h"
6
7DBAPIConn *trustsdb;
9bf9e8a1 8static int tgmaxid, thmaxid;
be2823bc 9static int loaderror;
4be1aaf2
CP
10static void *flushschedule;
11
be2823bc 12int trustsdbloaded;
2b6e02e2 13
be2823bc 14void createtrusttables(int migration);
4be1aaf2 15void trusts_flush(void);
2b6e02e2 16
be2823bc
CP
17void 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,
4be1aaf2 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(?))",
be2823bc
CP
30 "Tdddd", groups, TRUSTNAMELEN, NICKLEN, CONTACTLEN, COMMENTLEN
31 );
9bf9e8a1
CP
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);
4be1aaf2
CP
35}
36
37static void flushdatabase(void *arg) {
38 trusts_flush();
be2823bc
CP
39}
40
4be1aaf2 41static void loadcomplete(void) {
bf5b66e5
CP
42 /* error has already been shown */
43 if(loaderror)
44 return;
2b6e02e2 45
bf5b66e5 46 trustsdbloaded = 1;
4be1aaf2
CP
47 flushschedule = schedulerecurring(time(NULL) + 300, 0, 300, flushdatabase, NULL);
48
bf5b66e5 49 triggerhook(HOOK_TRUSTS_DB_LOADED, NULL);
be2823bc
CP
50}
51
be2823bc
CP
52static 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
9bf9e8a1 66 if(result->fields != 5) {
be2823bc
CP
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)) {
9bf9e8a1 75 unsigned int groupid, id;
5ada3782 76 char *host;
4be1aaf2 77 unsigned int maxusage, lastseen;
be2823bc
CP
78 trustgroup *tg;
79
9bf9e8a1
CP
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);
be2823bc
CP
85
86 tg = tg_getbyid(groupid);
87 if(!tg) {
88 Error("trusts", ERR_WARNING, "Orphaned trust group host: %d", groupid);
89 continue;
90 }
91
9bf9e8a1
CP
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);
be2823bc 96
9bf9e8a1 97 if(!th_add(tg, id, host, maxusage, lastseen))
5ada3782 98 Error("trusts", ERR_WARNING, "Error adding host to trust %d: %s", groupid, host);
be2823bc
CP
99 }
100
101 result->clear(result);
102
bf5b66e5 103 loadcomplete();
be2823bc
CP
104}
105
106static void loadhosts_fini(const DBAPIResult *result, void *tag) {
9bf9e8a1 107 Error("trusts", ERR_INFO, "Finished loading hosts, maximum id: %d", thmaxid);
be2823bc
CP
108}
109
110static 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;
5ada3782 134 sstring *name, *createdby, *contact, *comment;
4be1aaf2 135 unsigned int trustedfor, mode, maxperident, maxusage;
5ada3782 136 time_t expires, lastseen, lastmaxuserreset;
be2823bc
CP
137
138 id = strtoul(result->get(result, 0), NULL, 10);
139 if(id > tgmaxid)
140 tgmaxid = id;
141
5ada3782
CP
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);
4be1aaf2 146 maxusage = strtoul(result->get(result, 5), NULL, 10);
5ada3782
CP
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) {
4be1aaf2 155 if(!tg_add(id, name->content, trustedfor, mode, maxperident, maxusage, expires, lastseen, lastmaxuserreset, createdby->content, contact->content, comment->content))
5ada3782
CP
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 }
be2823bc 160
5ada3782
CP
161 freesstring(name);
162 freesstring(createdby);
163 freesstring(contact);
164 freesstring(comment);
be2823bc
CP
165 }
166
167 result->clear(result);
168}
169
170static void loadgroups_fini(const DBAPIResult *result, void *tag) {
171 Error("trusts", ERR_INFO, "Finished loading groups, maximum id: %d.", tgmaxid);
2b6e02e2
CP
172}
173
bf5b66e5
CP
174int 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);
2b6e02e2 182
be2823bc 183 loaderror = 0;
2b6e02e2 184
be2823bc
CP
185 trustsdb->loadtable(trustsdb, NULL, loadgroups_data, loadgroups_fini, NULL, "groups");
186 trustsdb->loadtable(trustsdb, NULL, loadhosts_data, loadhosts_fini, NULL, "hosts");
bf5b66e5
CP
187
188 return 1;
2b6e02e2
CP
189}
190
191void trusts_closedb(void) {
192 if(!trustsdb)
193 return;
194
4be1aaf2
CP
195 deleteschedule(flushschedule, flushdatabase, NULL);
196 flushdatabase(NULL);
197
bf5b66e5
CP
198 trusts_freeall();
199 trustsdbloaded = 0;
9bf9e8a1 200 thmaxid = tgmaxid = 0;
bf5b66e5 201
2b6e02e2
CP
202 trustsdb->close(trustsdb);
203 trustsdb = NULL;
204}
4be1aaf2
CP
205
206void th_dbupdatecounts(trusthost *th) {
9bf9e8a1 207 trustsdb->squery(trustsdb, "UPDATE ? SET lastseen = ?, maxusage = ? WHERE id = ?", "Ttuus", "hosts", th->lastseen, th->maxusage, th->id);
4be1aaf2
CP
208}
209
210void tg_dbupdatecounts(trustgroup *tg) {
211 trustsdb->squery(trustsdb, "UPDATE ? SET lastseen = ?, maxusage = ? WHERE id = ?", "Ttuus", "groups", tg->lastseen, tg->maxusage, tg->id);
212}