]>
Commit | Line | Data |
---|---|---|
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 | ||
10 | static void tm_trustdump(trustmigration *tm); | |
11 | ||
12 | static 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 | ||
23 | void migration_stop(trustmigration *tm) { | |
24 | tm_fini(tm, MIGRATION_STOPPED); | |
c2b5c1de CP |
25 | } |
26 | ||
27 | static 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 | ||
74 | static 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 | ||
97 | static 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 | ||
171 | static 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 | ||
185 | static 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 | 208 | trustmigration *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 | } |