]> jfr.im git - irc/quakenet/newserv.git/blame - trusts/migration.c
Add trust group extensions and example.
[irc/quakenet/newserv.git] / trusts / migration.c
CommitLineData
c2b5c1de 1#include "../nterfacer/nterfacer.h"
c2b5c1de 2#include "../lib/strlfunc.h"
2b6e02e2 3#include "trusts.h"
c2b5c1de
CP
4#include <stdio.h>
5#include <string.h>
6
7#define Stringify(x) __Stringify(x)
8#define __Stringify(x) #x
9
10static void tm_trustdump(trustmigration *tm);
11
12static void tm_fini(trustmigration *tm, int errcode) {
2b6e02e2 13 tm->fini(tm->tag, errcode);
c2b5c1de 14
2b6e02e2
CP
15 if(tm->schedule) {
16 nterfacer_freeline(tm->schedule);
17 tm->schedule = NULL;
18 }
19
20 free(tm);
21}
22
23void migration_stop(trustmigration *tm) {
24 tm_fini(tm, MIGRATION_STOPPED);
c2b5c1de
CP
25}
26
27static int tm_parsegroup(trustmigration *tm, unsigned int id, const char *oline) {
28 char *line, *createdby, *contact, *comment, *name;
4be1aaf2 29 unsigned int trustedfor, maxperident, mode, maxusage;
c2b5c1de
CP
30 unsigned long expires, lastseen, lastmaxusereset;
31 char xbuf[1024];
32 int pos;
33
34/* ticket35153,14,20,1,1,17,1879854575,1222639249,0,nterfacer,Qwhois&2120764,Non-Commercial Bouncer (Created by: doomie)
35 name ,current
36 ,trustedfor
37 ,mode
38 ,maxperident
4be1aaf2 39 ,maxusage
c2b5c1de
CP
40 ,expires ,lastseen ,lastmaxusereset
41 ,createdby,contact ,comment
42*/
43 int r;
44
45 strlcpy(xbuf, oline, sizeof(xbuf));
46 name = xbuf;
47
48 line = strchr(name, ',');
49 if(!line)
50 return 1;
51 *line++ = '\0';
52
53 r = sscanf(line, "%*u,%u,%u,%u,%u,%lu,%lu,%lu,%n",
54 /*current, */ &trustedfor, &mode, &maxperident,
4be1aaf2 55 &maxusage, &expires, &lastseen, &lastmaxusereset, &pos);
c2b5c1de
CP
56 if(r != 7)
57 return 2;
58
59 createdby = &line[pos];
60 contact = strchr(createdby, ',');
61 if(!contact)
62 return 3;
63 *contact++ = '\0';
64
65 comment = strchr(contact, ',');
66 if(!comment)
67 return 4;
68 *comment++ = '\0';
69
4be1aaf2 70 tm->group(tm->tag, id, name, trustedfor, mode, maxperident, maxusage, (time_t)expires, (time_t)lastseen, (time_t)lastmaxusereset, createdby, contact, comment);
c2b5c1de
CP
71 return 0;
72}
73
74static int tm_parsehost(trustmigration *tm, unsigned int id, char *line) {
75 unsigned int max;
76 unsigned long lastseen;
77 char *ip, xbuf[1024];
78
79/* 213.230.192.128/26,20,23,1222732944
80 ip ,cur,max,lastseen */
81
82 strlcpy(xbuf, line, sizeof(xbuf));
83 ip = line = xbuf;
84
85 line = strchr(line, ',');
86 if(!line)
87 return 5;
88 *line++ = '\0';
89
90 if(sscanf(line, "%*u,%u,%lu", /*current, */&max, &lastseen) != 2)
3f7ca181 91 return 6;
c2b5c1de 92
2b6e02e2 93 tm->host(tm->tag, id, ip, max, lastseen);
c2b5c1de
CP
94 return 0;
95}
96
97static void tm_stage2(int failure, int linec, char **linev, void *tag) {
98 trustmigration *tm = tag;
99 char *finishline;
100 unsigned int groupcount, totallines, i, dummy;
101
c8984d19 102#ifdef TRUSTS_MIGRATION_DEBUG
2b6e02e2 103 Error("trusts", ERR_INFO, "Migration total lines: %d", linec);
3f7ca181
CP
104
105 for(i=0;i<linec;i++)
2b6e02e2 106 Error("trusts", ERR_INFO, "Migration line %d: |%s|", i, linev[i]);
3f7ca181
CP
107#endif
108
c2b5c1de
CP
109 tm->schedule = NULL;
110 if(failure || (linec < 1)) {
3f7ca181 111 tm_fini(tm, 7);
c2b5c1de
CP
112 return;
113 }
114
115 finishline = linev[linec - 1];
116 if(sscanf(finishline, "Start ID cannot exceed current maximum group ID (#%u).", &dummy) == 1) {
117 /* the list was truncated while we were reading it, we're done! */
118 tm_fini(tm, 0);
119 return;
120 }
121
122 if(sscanf(finishline, "End of list, %u groups and %u lines returned.", &groupcount, &totallines) != 2) {
3f7ca181 123 tm_fini(tm, 8);
c2b5c1de
CP
124 return;
125 }
126
127 if(totallines != linec - 1) {
3f7ca181 128 tm_fini(tm, 9);
c2b5c1de
CP
129 return;
130 }
131
132 for(i=0;i<linec-1;i++) {
133 char *linestart = &linev[i][2], type = linev[i][0];
134 if(type == 'G' || type == 'H') {
135 char *realline;
136 unsigned int id;
137 int pos, ret;
138
139 if(sscanf(linestart, "#%u,%n", &id, &pos) != 1) {
3f7ca181 140 tm_fini(tm, 10);
c2b5c1de
CP
141 return;
142 }
143
ff63003a
CP
144 if(id > tm->cur) {
145 /* this one is missing and we've received a later one instead, update tm->cur to point to this one */
146 tm->cur = id;
147 } else if(id < tm->cur) {
148 tm_fini(tm, 11);
149 return;
c2b5c1de
CP
150 }
151
152 realline = &linestart[pos];
153 if(type == 'G') {
154 ret = tm_parsegroup(tm, id, realline);
155 } else {
156 ret = tm_parsehost(tm, id, realline);
157 }
158 if(ret) {
159 tm_fini(tm, ret);
160 return;
161 }
162 } else {
163 tm_fini(tm, 11);
164 return;
165 }
166 }
167
168 tm_trustdump(tm);
169}
170
171static void tm_trustdump(trustmigration *tm) {
172 char buf[100];
173
174 if(tm->cur >= tm->count) {
2b6e02e2 175 tm->fini(tm->tag, 0);
c2b5c1de
CP
176 return;
177 }
178
179 tm->cur++;
180
181 snprintf(buf, sizeof(buf), "trustdump #%d 1", tm->cur);
c8984d19 182 tm->schedule = nterfacer_sendline("R", "relay", 4, (char *[]){"2", "^(Start ID cannot exceed current maximum group ID \\(#\\d+\\)|End of list, 1 groups and \\d+ lines returned\\.)$", "O", buf}, tm_stage2, tm);
c2b5c1de
CP
183}
184
185static void tm_stage1(int failure, int linec, char **linev, void *tag) {
186 int count;
187 trustmigration *tm = tag;
188
189 tm->schedule = NULL;
190
191 if(failure || (linec != 1)) {
192 tm_fini(tm, 12);
193 return;
194 }
195
196 if(sscanf(linev[0], "Start ID cannot exceed current maximum group ID (#%u).", &count) != 1) {
197 tm_fini(tm, 13);
198 return;
199 }
200
2b6e02e2 201 Error("trusts", ERR_INFO, "Migration in progress, total groups: %d", count);
c2b5c1de
CP
202
203 tm->count = count;
204
205 tm_trustdump(tm);
206}
207
2b6e02e2 208trustmigration *migration_start(TrustMigrationGroup group, TrustMigrationHost host, TrustMigrationFini fini, void *tag) {
c2b5c1de
CP
209 trustmigration *tm = malloc(sizeof(trustmigration));
210 if(!tm)
211 return NULL;
212
213 tm->group = group;
214 tm->host = host;
215 tm->fini = fini;
216 tm->count = 0;
217 tm->cur = 0;
2b6e02e2 218 tm->tag = tag;
c2b5c1de
CP
219
220 tm->schedule = nterfacer_sendline("R", "relay", 4, (char *[]){"1", "1", "O", "trustdump #9999999 1"}, tm_stage1, tm);
221 return tm;
222}