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