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