1 |
/* Conversion routines for trircd Services program (version 4.26). |
2 |
* |
3 |
* IRC Services is copyright (c) 1996-2009 Andrew Church. |
4 |
* E-mail: <achurch@achurch.org> |
5 |
* Parts written by Andrew Kempe and others. |
6 |
* This program is free but copyrighted software; see the file GPL.txt for |
7 |
* details. |
8 |
*/ |
9 |
|
10 |
#include "convert-db.h" |
11 |
|
12 |
#if NICKMAX < 32 |
13 |
# error NICKMAX too small (must be >=32) |
14 |
#elif CHANMAX < 64 |
15 |
# error CHANMAX too small (must be >=64) |
16 |
#elif PASSMAX < 32 |
17 |
# error PASSMAX too small (must be >=32) |
18 |
#endif |
19 |
|
20 |
/*************************************************************************/ |
21 |
|
22 |
static void trircd_load_nick(const char *dir) |
23 |
{ |
24 |
dbFILE *f; |
25 |
int i, j, c; |
26 |
int16 tmp16; |
27 |
int32 tmp32; |
28 |
NickInfo *ni; |
29 |
NickGroupInfo *ngi; |
30 |
|
31 |
f = open_db_ver(dir, "nick.db", 22, 25, NULL); |
32 |
for (i = 0; i < 256; i++) { |
33 |
while ((c = getc_db(f)) == 1) { |
34 |
char nickbuf[32], passbuf[32]; |
35 |
SAFE(read_buffer(nickbuf, f)); |
36 |
ni = makenick(nickbuf, &ngi); |
37 |
SAFE(read_buffer(passbuf, f)); |
38 |
init_password(&ngi->pass); |
39 |
memcpy(ngi->pass.password, passbuf, sizeof(passbuf)); |
40 |
SAFE(read_string(&ngi->url, f)); |
41 |
SAFE(read_string(&ngi->email, f)); |
42 |
SAFE(read_string(&ni->last_usermask, f)); |
43 |
if (!ni->last_usermask) |
44 |
ni->last_usermask = (char *)"@"; |
45 |
SAFE(read_string(&ni->last_realname, f)); |
46 |
if (!ni->last_realname) |
47 |
ni->last_realname = (char *)""; |
48 |
SAFE(read_string(&ni->last_quit, f)); |
49 |
SAFE(read_int32(&tmp32, f)); |
50 |
ni->time_registered = tmp32; |
51 |
SAFE(read_int32(&tmp32, f)); |
52 |
ni->last_seen = tmp32; |
53 |
SAFE(read_int16(&tmp16, f)); /* status */ |
54 |
if (tmp16 & 0x0001) |
55 |
ngi->pass.cipher = sstrdup("md5"); |
56 |
if (tmp16 & 0x0002) { |
57 |
ni->status |= NS_VERBOTEN; |
58 |
del_nickgroupinfo(ngi); |
59 |
ni->nickgroup = 0; |
60 |
} |
61 |
if (tmp16 & 0x0004) |
62 |
ni->status |= NS_NOEXPIRE; |
63 |
SAFE(read_string(&ni->last_realmask, f)); /* link */ |
64 |
SAFE(read_int16(&tmp16, f)); /* linkcount */ |
65 |
if (ni->last_realmask) { |
66 |
ni->nickgroup = 0; |
67 |
SAFE(read_int16(&tmp16, f)); /* channelcount */ |
68 |
} else { |
69 |
void *tmpptr; |
70 |
SAFE(read_int32(&tmp32, f)); /* flags */ |
71 |
if (tmp32 & 0x00000001) |
72 |
ngi->flags |= NF_KILLPROTECT; |
73 |
if (tmp32 & 0x00000002) |
74 |
ngi->flags |= NF_SECURE; |
75 |
if (tmp32 & 0x00000008) |
76 |
ngi->flags |= NF_MEMO_HARDMAX; |
77 |
if (tmp32 & 0x00000010) |
78 |
ngi->flags |= NF_MEMO_SIGNON; |
79 |
if (tmp32 & 0x00000020) |
80 |
ngi->flags |= NF_MEMO_RECEIVE; |
81 |
if (tmp32 & 0x00000040) |
82 |
ngi->flags |= NF_PRIVATE; |
83 |
if (tmp32 & 0x00000080) |
84 |
ngi->flags |= NF_HIDE_EMAIL; |
85 |
if (tmp32 & 0x00000100) |
86 |
ngi->flags |= NF_HIDE_MASK; |
87 |
if (tmp32 & 0x00000200) |
88 |
ngi->flags |= NF_HIDE_QUIT; |
89 |
if (tmp32 & 0x00000400) |
90 |
ngi->flags |= NF_KILL_QUICK; |
91 |
if (tmp32 & 0x00000800) |
92 |
ngi->flags |= NF_KILL_IMMED; |
93 |
if (tmp32 & 0x80000000) |
94 |
ngi->flags |= NF_MEMO_FWD | NF_MEMO_FWDCOPY; |
95 |
SAFE(read_ptr(&tmpptr, f)); |
96 |
if (tmpptr) { |
97 |
SAFE(read_buffer(nickbuf, f)); |
98 |
strbcpy(ngi->suspend_who, nickbuf); |
99 |
SAFE(read_string(&ngi->suspend_reason, f)); |
100 |
SAFE(read_int32(&tmp32, f)); |
101 |
ngi->suspend_time = tmp32; |
102 |
SAFE(read_int32(&tmp32, f)); |
103 |
ngi->suspend_expires = tmp32; |
104 |
ngi->flags |= NF_SUSPENDED; |
105 |
} |
106 |
SAFE(read_int16(&ngi->access_count, f)); |
107 |
if (ngi->access_count) { |
108 |
char **access; |
109 |
access = scalloc(sizeof(char *), ngi->access_count); |
110 |
ngi->access = access; |
111 |
for (j = 0; j < ngi->access_count; j++, access++) |
112 |
SAFE(read_string(access, f)); |
113 |
} |
114 |
SAFE(read_int16(&ngi->memos.memos_count, f)); |
115 |
SAFE(read_int16(&ngi->memos.memomax, f)); |
116 |
if (ngi->memos.memos_count) { |
117 |
Memo *memos; |
118 |
memos = scalloc(sizeof(Memo), ngi->memos.memos_count); |
119 |
ngi->memos.memos = memos; |
120 |
for (j = 0; j < ngi->memos.memos_count; j++, memos++) { |
121 |
SAFE(read_uint32(&memos->number, f)); |
122 |
SAFE(read_int16(&tmp16, f)); |
123 |
if (tmp16 & 1) |
124 |
memos->flags |= MF_UNREAD; |
125 |
SAFE(read_int32(&tmp32, f)); |
126 |
memos->time = tmp32; |
127 |
SAFE(read_buffer(nickbuf, f)); |
128 |
strbcpy(memos->sender, nickbuf); |
129 |
SAFE(read_string(&memos->text, f)); |
130 |
} |
131 |
} |
132 |
SAFE(read_int16(&tmp16, f)); /* channelcount */ |
133 |
SAFE(read_int16(&tmp16, f)); /* channelmax */ |
134 |
SAFE(read_int16(&ngi->language, f)); |
135 |
} |
136 |
} /* while (getc_db(f) == 1) */ |
137 |
if (c != 0) { |
138 |
fprintf(stderr, "%s is corrupt, aborting.\n", f->filename); |
139 |
exit(1); |
140 |
} |
141 |
} /* for (i) */ |
142 |
close_db(f); |
143 |
|
144 |
/* Resolve links */ |
145 |
for (ni = first_nickinfo(); ni; ni = next_nickinfo()) { |
146 |
NickInfo *ni2; |
147 |
const char *last_nick; |
148 |
if (ni->last_realmask) { |
149 |
ni2 = ni; |
150 |
/* Find root nick (this will actually stop at the first nick |
151 |
* in the path to the root that isn't marked as linked, but |
152 |
* that's okay because such a nick will already have its |
153 |
* nickgroup ID set correctly) */ |
154 |
do { |
155 |
last_nick = ni2->last_realmask; |
156 |
ni2 = get_nickinfo(last_nick); |
157 |
} while (ni2 && ni2 != ni && ni2->last_realmask); |
158 |
ni->last_realmask = NULL; |
159 |
/* Set nickgroup, or delete nick if an error occurred */ |
160 |
if (ni2 == ni) { |
161 |
fprintf(stderr, |
162 |
"Warning: dropping nick %s with circular link\n", |
163 |
ni->nick); |
164 |
del_nickinfo(ni); |
165 |
} else if (!ni2) { |
166 |
fprintf(stderr, "Warning: dropping nick %s linked to" |
167 |
" nonexistent nick %s\n", ni->nick, last_nick); |
168 |
del_nickinfo(ni); |
169 |
} else { |
170 |
ngi = get_nickgroupinfo(ni->nickgroup); |
171 |
if (ngi) |
172 |
del_nickgroupinfo(ngi); |
173 |
ni->nickgroup = ni2->nickgroup; |
174 |
ngi = get_nickgroupinfo(ni->nickgroup); |
175 |
if (ngi) { |
176 |
ARRAY_EXTEND(ngi->nicks); |
177 |
strbcpy(ngi->nicks[ngi->nicks_count-1], ni->nick); |
178 |
} else if (ni->nickgroup != 0) { |
179 |
fprintf(stderr, "Warning: Nick group %d for nick %s not" |
180 |
" found -- program bug? Output may be corrupt.", |
181 |
ni->nickgroup, ni->nick); |
182 |
} |
183 |
} |
184 |
} |
185 |
} |
186 |
} |
187 |
|
188 |
/*************************************************************************/ |
189 |
|
190 |
static void trircd_load_ajoin(const char *dir) |
191 |
{ |
192 |
dbFILE *f; |
193 |
int c; |
194 |
int16 j, tmp16; |
195 |
int32 tmp32; |
196 |
void *tmpptr; |
197 |
char *s; |
198 |
NickGroupInfo *ngi; |
199 |
|
200 |
f = open_db_ver(dir, "ajoin.db", 25, 25, NULL); |
201 |
while ((c = getc_db(f)) == 1) { |
202 |
int is_root; /* is this a root nick (should we store data)? */ |
203 |
char nickbuf[32]; |
204 |
|
205 |
SAFE(read_buffer(nickbuf, f)); |
206 |
ngi = get_nickgroupinfo_by_nick(nickbuf); |
207 |
is_root = ngi && stricmp(nickbuf, ngi_mainnick(ngi)) == 0; |
208 |
SAFE(read_int16(&tmp16, f)); /* ajoincount */ |
209 |
if (is_root) { |
210 |
ngi->ajoin_count = tmp16; |
211 |
ngi->ajoin = scalloc(sizeof(char *), tmp16); |
212 |
for (j = 0; j < tmp16; j++) |
213 |
SAFE(read_string(&ngi->ajoin[j], f)); |
214 |
} else { |
215 |
for (j = 0; j < tmp16; j++) |
216 |
SAFE(read_string(&s, f)); |
217 |
} |
218 |
SAFE(read_ptr((void *)&tmpptr, f)); /* forbidinfo */ |
219 |
if (tmpptr) { |
220 |
SAFE(read_buffer(nickbuf, f)); /* forbidder */ |
221 |
SAFE(read_string(&s, f)); /* forbid_message */ |
222 |
} |
223 |
SAFE(read_int32(&tmp32, f)); /* authcode */ |
224 |
SAFE(read_int16(&tmp16, f)); /* authmode */ |
225 |
if (tmp16 & 3) /* NH_AUTHENTIC | NH_OLDAUTH */ |
226 |
tmp32 = 0; |
227 |
if (is_root) { |
228 |
ngi->authcode = tmp32; |
229 |
ngi->authset = time(NULL); |
230 |
} |
231 |
SAFE(read_int16(&tmp16, f)); /* ignorecount */ |
232 |
if (is_root) { |
233 |
ngi->ignore_count = tmp16; |
234 |
ngi->ignore = scalloc(sizeof(char *), tmp16); |
235 |
for (j = 0; j < ngi->ignore_count; j++) { |
236 |
SAFE(read_int16(&tmp16, f)); |
237 |
if (tmp16) |
238 |
SAFE(read_string(&ngi->ignore[j], f)); |
239 |
} |
240 |
} else { |
241 |
for (j = tmp16; j > 0; j--) { |
242 |
SAFE(read_int16(&tmp16, f)); |
243 |
if (tmp16) |
244 |
SAFE(read_string(&s, f)); |
245 |
} |
246 |
} |
247 |
SAFE(read_string(&s, f)); /* infomsg */ |
248 |
if (is_root) |
249 |
ngi->info = s; |
250 |
SAFE(read_int32(&tmp32, f)); /* expiredelay */ |
251 |
SAFE(read_int16(&tmp16, f)); /* count for memo expire */ |
252 |
for (j = 0; j < tmp16; j++) |
253 |
SAFE(read_int32(&tmp32, f)); /* memo.expiration */ |
254 |
} /* while (getc_db(f) == 1) */ |
255 |
if (c != -1) |
256 |
fprintf(stderr, "Warning: %s may be corrupt.\n", f->filename); |
257 |
close_db(f); |
258 |
} |
259 |
|
260 |
/*************************************************************************/ |
261 |
|
262 |
static struct { |
263 |
int32 flag; |
264 |
char mode; |
265 |
} cmodes[] = { |
266 |
{ 0x00000001, 'i' }, |
267 |
{ 0x00000002, 'm' }, |
268 |
{ 0x00000004, 'n' }, |
269 |
{ 0x00000008, 'p' }, |
270 |
{ 0x00000010, 's' }, |
271 |
{ 0x00000020, 't' }, |
272 |
{ 0x00000040, 'k' }, |
273 |
{ 0x00000080, 'l' }, |
274 |
{ 0x00000100, 'R' }, |
275 |
{ 0x00000200, 0 }, /* 'r', never set in mlock */ |
276 |
{ 0x00000400, 'c' }, |
277 |
{ 0x00000800, 'O' }, |
278 |
{ 0x00001000, 'A' }, |
279 |
{ 0x00002000, 'z' }, |
280 |
{ 0x00004000, 'Q' }, |
281 |
{ 0x00008000, 'K' }, |
282 |
{ 0x00010000, 'V' }, |
283 |
{ 0x00020000, 'H' }, |
284 |
{ 0x00040000, 'C' }, |
285 |
{ 0x00080000, 'N' }, |
286 |
{ 0x00100000, 'S' }, |
287 |
{ 0x00200000, 'G' }, |
288 |
{ 0x00400000, 'u' }, |
289 |
{ 0x00800000, 'f' }, |
290 |
{ 0x01000000, 'M' }, |
291 |
{ 0, 0 } |
292 |
}; |
293 |
|
294 |
static void trircd_load_chan(const char *dir) |
295 |
{ |
296 |
dbFILE *f; |
297 |
int i, j, c; |
298 |
ChannelInfo *ci; |
299 |
NickInfo *ni; |
300 |
int32 tmp32, mlock_on, mlock_off; |
301 |
MemoInfo tmpmi; |
302 |
void *tmpptr; |
303 |
|
304 |
f = open_db_ver(dir, "chan.db", 22, 25, NULL); |
305 |
|
306 |
for (i = 0; i < 256; i++) { |
307 |
int16 tmp16; |
308 |
char *s, *on, *off; |
309 |
char namebuf[64], passbuf[32], nickbuf[32]; |
310 |
|
311 |
while ((c = getc_db(f)) == 1) { |
312 |
SAFE(read_buffer(namebuf, f)); |
313 |
ci = makechan(namebuf); |
314 |
SAFE(read_string(&s, f)); |
315 |
if (s) { |
316 |
ni = get_nickinfo(s); |
317 |
if (!ni) { |
318 |
fprintf(stderr, |
319 |
"Warning: Founder %s for channel %s not found\n", |
320 |
s, ci->name); |
321 |
} else if (!ni->nickgroup) { |
322 |
fprintf(stderr, "Warning: Founder %s for channel %s is a" |
323 |
" forbidden nick\n", s, ci->name); |
324 |
} else { |
325 |
ci->founder = ni->nickgroup; |
326 |
} |
327 |
} |
328 |
SAFE(read_string(&s, f)); |
329 |
if (s) { |
330 |
ni = get_nickinfo(s); |
331 |
if (!ni) { |
332 |
fprintf(stderr, "Warning: Successor %s for channel %s" |
333 |
" not found\n", s, ci->name); |
334 |
} else if (!ni->nickgroup) { |
335 |
fprintf(stderr, "Warning: Successor %s for channel %s" |
336 |
" is a forbidden nick\n", s, ci->name); |
337 |
} else if (ni->nickgroup == ci->founder) { |
338 |
fprintf(stderr, "Warning: Successor %s for channel %s" |
339 |
" is the same as the founder, clearing\n", |
340 |
s, ci->name); |
341 |
} else { |
342 |
ci->successor = ni->nickgroup; |
343 |
} |
344 |
} |
345 |
SAFE(read_buffer(passbuf, f)); |
346 |
init_password(&ci->founderpass); |
347 |
memcpy(ci->founderpass.password, passbuf, sizeof(passbuf)); |
348 |
SAFE(read_string(&ci->desc, f)); |
349 |
if (!ci->desc) |
350 |
ci->desc = (char *)""; |
351 |
SAFE(read_string(&ci->url, f)); |
352 |
SAFE(read_string(&ci->email, f)); |
353 |
SAFE(read_int32(&tmp32, f)); |
354 |
ci->time_registered = tmp32; |
355 |
SAFE(read_int32(&tmp32, f)); |
356 |
ci->last_used = tmp32; |
357 |
SAFE(read_string(&ci->last_topic, f)); |
358 |
SAFE(read_buffer(nickbuf, f)); |
359 |
strbcpy(ci->last_topic_setter, nickbuf); |
360 |
SAFE(read_int32(&tmp32, f)); |
361 |
ci->last_topic_time = tmp32; |
362 |
|
363 |
SAFE(read_int32(&tmp32, f)); /* flags */ |
364 |
if (tmp32 & 0x00000001) |
365 |
ci->flags |= CF_KEEPTOPIC; |
366 |
if (tmp32 & 0x00000002) |
367 |
ci->flags |= CF_SECUREOPS; |
368 |
if (tmp32 & 0x00000004) |
369 |
ci->flags |= CF_PRIVATE; |
370 |
if (tmp32 & 0x00000008) |
371 |
ci->flags |= CF_TOPICLOCK; |
372 |
if (tmp32 & 0x00000010) |
373 |
ci->flags |= CF_RESTRICTED; |
374 |
if (tmp32 & 0x00000020) |
375 |
ci->flags |= CF_LEAVEOPS; |
376 |
if (tmp32 & 0x00000040) |
377 |
ci->flags |= CF_SECURE; |
378 |
if (tmp32 & 0x00000080) |
379 |
ci->flags |= CF_VERBOTEN; |
380 |
if (tmp32 & 0x00000100) |
381 |
ci->founderpass.cipher = sstrdup("md5"); |
382 |
if (tmp32 & 0x00000200) |
383 |
ci->flags |= CF_NOEXPIRE; |
384 |
if (tmp32 & 0x01000000) |
385 |
ci->flags |= CF_HIDE_TOPIC; |
386 |
if (tmp32 & 0x04000000) |
387 |
ci->flags |= CF_HIDE_MLOCK; |
388 |
if (tmp32 & 0x80000000) |
389 |
ci->flags |= CF_HIDE_EMAIL; |
390 |
|
391 |
SAFE(read_ptr((void **)&tmpptr, f)); |
392 |
if (tmpptr) { |
393 |
SAFE(read_buffer(nickbuf, f)); |
394 |
strbcpy(ci->suspend_who, nickbuf); |
395 |
SAFE(read_string(&ci->suspend_reason, f)); |
396 |
SAFE(read_int32(&tmp32, f)); |
397 |
ci->suspend_time = tmp32; |
398 |
SAFE(read_int32(&tmp32, f)); |
399 |
ci->suspend_expires = tmp32; |
400 |
ci->flags |= CF_SUSPENDED; |
401 |
} |
402 |
|
403 |
SAFE(read_int16(&tmp16, f)); /* n_levels */ |
404 |
for (j = tmp16; j > 0; j--) |
405 |
SAFE(read_int16(&tmp16, f)); /* levels */ |
406 |
|
407 |
SAFE(read_int16(&ci->access_count, f)); |
408 |
if (ci->access_count) { |
409 |
ci->access = scalloc(ci->access_count, sizeof(ChanAccess)); |
410 |
for (j = 0; j < ci->access_count; j++) { |
411 |
SAFE(read_int16(&tmp16, f)); /* in_use */ |
412 |
if (tmp16) { |
413 |
SAFE(read_int16(&ci->access[j].level, f)); |
414 |
SAFE(read_string(&s, f)); |
415 |
ci->access[j].level = |
416 |
convert_acclev(ci->access[j].level); |
417 |
if (s) { |
418 |
ni = get_nickinfo(s); |
419 |
if (ni) |
420 |
ci->access[j].nickgroup = ni->nickgroup; |
421 |
} |
422 |
} |
423 |
} |
424 |
} |
425 |
|
426 |
SAFE(read_int16(&ci->akick_count, f)); |
427 |
if (ci->akick_count) { |
428 |
ci->akick = scalloc(ci->akick_count, sizeof(AutoKick)); |
429 |
for (j = 0; j < ci->akick_count; j++) { |
430 |
SAFE(read_int16(&tmp16, f)); /* in_use */ |
431 |
if (tmp16) { |
432 |
SAFE(read_int16(&tmp16, f)); /* is_nick */ |
433 |
SAFE(read_string(&s, f)); |
434 |
if (tmp16 && s) { |
435 |
ci->akick[j].mask = smalloc(strlen(s)+5); |
436 |
sprintf(ci->akick[j].mask, "%s!*@*", s); |
437 |
} else { |
438 |
ci->akick[j].mask = s; |
439 |
} |
440 |
SAFE(read_string(&s, f)); |
441 |
SAFE(read_buffer(nickbuf, f)); |
442 |
if (ci->akick[j].mask) { |
443 |
ci->akick[j].reason = s; |
444 |
strbcpy(ci->akick[j].who, nickbuf); |
445 |
ci->akick[j].set = time(NULL); |
446 |
} |
447 |
} |
448 |
} |
449 |
} |
450 |
|
451 |
SAFE(read_int32(&mlock_on, f)); |
452 |
SAFE(read_int32(&mlock_off, f)); |
453 |
ci->mlock.on = on = scalloc(64, 1); |
454 |
ci->mlock.off = off = scalloc(64, 1); |
455 |
for (j = 0; cmodes[j].flag != 0; j++) { |
456 |
if (mlock_on & cmodes[j].flag) |
457 |
*on++ = cmodes[j].mode; |
458 |
if (mlock_off & cmodes[j].flag) |
459 |
*off++ = cmodes[j].mode; |
460 |
} |
461 |
*on = 0; |
462 |
*off = 0; |
463 |
SAFE(read_int32(&ci->mlock.limit, f)); |
464 |
SAFE(read_string(&ci->mlock.key, f)); |
465 |
|
466 |
SAFE(read_int16(&tmpmi.memos_count, f)); |
467 |
SAFE(read_int16(&tmp16, f)); /* memomax */ |
468 |
if (tmpmi.memos_count) { |
469 |
Memo *memos; |
470 |
memos = scalloc(sizeof(Memo), tmpmi.memos_count); |
471 |
tmpmi.memos = memos; |
472 |
for (j = 0; j < tmpmi.memos_count; j++, memos++) { |
473 |
SAFE(read_uint32(&memos->number, f)); |
474 |
SAFE(read_int16(&memos->flags, f)); |
475 |
SAFE(read_int32(&tmp32, f)); |
476 |
memos->time = tmp32; |
477 |
SAFE(read_buffer(nickbuf, f)); |
478 |
strbcpy(memos->sender, nickbuf); |
479 |
SAFE(read_string(&memos->text, f)); |
480 |
} |
481 |
} |
482 |
|
483 |
SAFE(read_string(&ci->entry_message, f)); |
484 |
|
485 |
if (!(ci->flags & CF_VERBOTEN) && !ci->founder) { |
486 |
fprintf(stderr, "Ignoring channel %s (missing founder)\n", |
487 |
ci->name); |
488 |
del_channelinfo(ci); |
489 |
} |
490 |
|
491 |
} /* while (getc_db(f) == 1) */ |
492 |
|
493 |
if (c != 0) { |
494 |
fprintf(stderr, "%s is corrupt, aborting.\n", f->filename); |
495 |
exit(1); |
496 |
} |
497 |
} /* for (i) */ |
498 |
close_db(f); |
499 |
} |
500 |
|
501 |
/*************************************************************************/ |
502 |
|
503 |
static void trircd_load_cforbid(const char *dir) |
504 |
{ |
505 |
dbFILE *f; |
506 |
int c; |
507 |
|
508 |
f = open_db_ver(dir, "cforbid.db", 25, 25, NULL); |
509 |
while ((c = getc_db(f)) == 1) { |
510 |
char chanbuf[64]; |
511 |
void *tmpptr; |
512 |
int8 tmp8; |
513 |
int16 i, tmp16; |
514 |
int32 tmp32; |
515 |
char *s; |
516 |
ChannelInfo *ci; |
517 |
|
518 |
SAFE(read_buffer(chanbuf, f)); |
519 |
ci = get_channelinfo(chanbuf); |
520 |
if (!ci) { |
521 |
fprintf(stderr, "Warning: cforbid data for nonexistent channel" |
522 |
" %s, ignoring\n", chanbuf); |
523 |
} |
524 |
SAFE(read_ptr(&tmpptr, f)); /* forbidinfo */ |
525 |
if (tmpptr) { |
526 |
char nickbuf[32]; |
527 |
SAFE(read_buffer(nickbuf, f)); /* forbidder */ |
528 |
SAFE(read_string(&s, f)); /* forbid_message */ |
529 |
} |
530 |
SAFE(read_int16(&tmp16, f)); /* akickcount */ |
531 |
if (ci && tmp16 != ci->akick_count) { |
532 |
fprintf(stderr, "Warning: autokick count mismatch (chan.db: %d," |
533 |
" cforbid.db: %d); databases may be corrupt\n", |
534 |
ci->akick_count, tmp16); |
535 |
} |
536 |
for (i = 0; i < tmp16; i++) { |
537 |
int16 in_use; |
538 |
SAFE(read_int16(&in_use, f)); |
539 |
if (in_use) { |
540 |
if (ci && i < ci->akick_count) { |
541 |
SAFE(read_int32(&tmp32, f)); |
542 |
ci->akick[i].set = tmp32; |
543 |
SAFE(read_int32(&tmp32, f)); |
544 |
ci->akick[i].lastused = tmp32; |
545 |
} else { |
546 |
SAFE(read_int32(&tmp32, f)); |
547 |
SAFE(read_int32(&tmp32, f)); |
548 |
} |
549 |
SAFE(read_int32(&tmp32, f)); /* expires */ |
550 |
} |
551 |
} |
552 |
SAFE(read_int16(&tmp16, f)); /* accesscount */ |
553 |
for (i = tmp16; i > 0; i--) { |
554 |
SAFE(read_int16(&tmp16, f)); /* in_use */ |
555 |
if (tmp16) |
556 |
SAFE(read_int32(&tmp32, f)); /* last_used */ |
557 |
} |
558 |
SAFE(read_int8(&tmp8, f)); |
559 |
if (tmp8 != 0) { |
560 |
fprintf(stderr, "%s is corrupt, aborting.\n", f->filename); |
561 |
exit(1); |
562 |
} |
563 |
} /* while (getc_db(f) == 1) */ |
564 |
if (c != -1) |
565 |
fprintf(stderr, "Warning: %s may be corrupt.\n", f->filename); |
566 |
close_db(f); |
567 |
} |
568 |
|
569 |
/*************************************************************************/ |
570 |
|
571 |
static void trircd_load_oper(const char *dir) |
572 |
{ |
573 |
dbFILE *f; |
574 |
int16 i, n; |
575 |
int32 tmp32; |
576 |
int8 tmp8; |
577 |
char *s; |
578 |
|
579 |
f = open_db_ver(dir, "oper.db", 22, 25, NULL); |
580 |
/* servadmin */ |
581 |
SAFE(read_int16(&n, f)); |
582 |
for (i = 0; i < n; i++) { |
583 |
SAFE(read_string(&s, f)); |
584 |
set_os_priv(s, NP_SERVADMIN); |
585 |
} |
586 |
/* servoper */ |
587 |
SAFE(read_int16(&n, f)); |
588 |
for (i = 0; i < n; i++) { |
589 |
SAFE(read_string(&s, f)); |
590 |
set_os_priv(s, NP_SERVOPER); |
591 |
} |
592 |
SAFE(read_int32(&maxusercnt, f)); |
593 |
SAFE(read_int32(&tmp32, f)); |
594 |
maxusertime = tmp32; |
595 |
SAFE(read_int8(&tmp8, f)); |
596 |
no_supass = tmp8; |
597 |
if (!no_supass) { |
598 |
char passbuf[32]; |
599 |
SAFE(read_buffer(passbuf, f)); |
600 |
memcpy(supass.password, passbuf, sizeof(passbuf)); |
601 |
} |
602 |
close_db(f); |
603 |
} |
604 |
|
605 |
/*************************************************************************/ |
606 |
|
607 |
static void trircd_load_akill(const char *dir) |
608 |
{ |
609 |
dbFILE *f; |
610 |
int16 i, n; |
611 |
MaskData *md; |
612 |
|
613 |
f = open_db_ver(dir, "akill.db", 22, 25, NULL); |
614 |
SAFE(read_int16(&n, f)); |
615 |
md = scalloc(sizeof(*md), n); |
616 |
for (i = 0; i < n; i++) { |
617 |
char nick[32]; |
618 |
int32 tmp32; |
619 |
SAFE(read_string(&md[i].mask, f)); |
620 |
SAFE(read_string(&md[i].reason, f)); |
621 |
SAFE(read_buffer(nick, f)); |
622 |
strbcpy(md[i].who, nick); |
623 |
SAFE(read_int32(&tmp32, f)); |
624 |
md[i].time = tmp32; |
625 |
SAFE(read_int32(&tmp32, f)); |
626 |
md[i].expires = tmp32; |
627 |
if (md[i].mask) |
628 |
add_maskdata(MD_AKILL, &md[i]); |
629 |
} |
630 |
close_db(f); |
631 |
} |
632 |
|
633 |
/*************************************************************************/ |
634 |
|
635 |
static void trircd_load_exclude(const char *dir) |
636 |
{ |
637 |
dbFILE *f; |
638 |
int16 i, n; |
639 |
MaskData *md; |
640 |
|
641 |
f = open_db_ver(dir, "exclude.db", 22, 25, NULL); |
642 |
SAFE(read_int16(&n, f)); |
643 |
md = scalloc(sizeof(*md), n); |
644 |
for (i = 0; i < n; i++) { |
645 |
char nick[32]; |
646 |
int32 tmp32; |
647 |
SAFE(read_string(&md[i].mask, f)); |
648 |
SAFE(read_string(&md[i].reason, f)); |
649 |
SAFE(read_buffer(nick, f)); |
650 |
strbcpy(md[i].who, nick); |
651 |
SAFE(read_int32(&tmp32, f)); |
652 |
md[i].time = tmp32; |
653 |
SAFE(read_int32(&tmp32, f)); |
654 |
md[i].expires = tmp32; |
655 |
if (md[i].mask) |
656 |
add_maskdata(MD_EXCLUDE, &md[i]); |
657 |
} |
658 |
close_db(f); |
659 |
} |
660 |
|
661 |
/*************************************************************************/ |
662 |
|
663 |
static void trircd_load_exception(const char *dir) |
664 |
{ |
665 |
dbFILE *f; |
666 |
int16 i, n; |
667 |
MaskData *md; |
668 |
|
669 |
f = open_db_ver(dir, "exception.db", 22, 25, NULL); |
670 |
SAFE(read_int16(&n, f)); |
671 |
md = scalloc(sizeof(*md), n); |
672 |
for (i = 0; i < n; i++) { |
673 |
char nick[32]; |
674 |
int32 tmp32; |
675 |
SAFE(read_string(&md[i].mask, f)); |
676 |
SAFE(read_int16(&md[i].limit, f)); |
677 |
SAFE(read_buffer(nick, f)); |
678 |
strbcpy(md[i].who, nick); |
679 |
SAFE(read_string(&md[i].reason, f)); |
680 |
SAFE(read_int32(&tmp32, f)); |
681 |
md[i].time = tmp32; |
682 |
SAFE(read_int32(&tmp32, f)); |
683 |
md[i].expires = tmp32; |
684 |
if (md[i].mask) |
685 |
add_maskdata(MD_AKILL, &md[i]); |
686 |
} |
687 |
close_db(f); |
688 |
} |
689 |
|
690 |
/*************************************************************************/ |
691 |
|
692 |
static void trircd_load_news(const char *dir) |
693 |
{ |
694 |
dbFILE *f; |
695 |
int16 i, n; |
696 |
NewsItem *news; |
697 |
|
698 |
f = open_db_ver(dir, "news.db", 22, 25, NULL); |
699 |
SAFE(read_int16(&n, f)); |
700 |
news = scalloc(sizeof(*news), n); |
701 |
for (i = 0; i < n; i++) { |
702 |
char nick[32]; |
703 |
int32 tmp32; |
704 |
SAFE(read_int16(&news[i].type, f)); |
705 |
SAFE(read_int32(&news[i].num, f)); |
706 |
SAFE(read_string(&news[i].text, f)); |
707 |
SAFE(read_buffer(nick, f)); |
708 |
strbcpy(news[i].who, nick); |
709 |
SAFE(read_int32(&tmp32, f)); |
710 |
news[i].time = tmp32; |
711 |
add_news(&news[i]); |
712 |
} |
713 |
close_db(f); |
714 |
} |
715 |
|
716 |
/*************************************************************************/ |
717 |
|
718 |
static void trircd_load_sline(const char *dir, const unsigned char type) |
719 |
{ |
720 |
char filenamebuf[16]; |
721 |
dbFILE *f; |
722 |
int32 ver; |
723 |
int16 i, n; |
724 |
MaskData *md; |
725 |
|
726 |
snprintf(filenamebuf, sizeof(filenamebuf), "s%cline.db", type); |
727 |
f = open_db_ver(dir, filenamebuf, 22, 25, &ver); |
728 |
read_int16(&n, f); |
729 |
md = scalloc(sizeof(*md), n); |
730 |
for (i = 0; i < n; i++) { |
731 |
char nickbuf[32]; |
732 |
int32 tmp32; |
733 |
SAFE(read_string(&md[i].mask, f)); |
734 |
SAFE(read_string(&md[i].reason, f)); |
735 |
SAFE(read_buffer(nickbuf, f)); |
736 |
strbcpy(md[i].who, nickbuf); |
737 |
if (ver >= 23) { |
738 |
SAFE(read_int32(&tmp32, f)); |
739 |
md[i].time = tmp32; |
740 |
SAFE(read_int32(&tmp32, f)); |
741 |
md[i].expires = tmp32; |
742 |
} else { |
743 |
md[i].time = time(NULL); |
744 |
} |
745 |
if (md[i].mask) |
746 |
add_maskdata(type, &md[i]); |
747 |
} |
748 |
close_db(f); |
749 |
} |
750 |
|
751 |
/*************************************************************************/ |
752 |
/*************************************************************************/ |
753 |
|
754 |
static const char *check_trircd(const char *dir) |
755 |
{ |
756 |
char buf[PATH_MAX+1]; |
757 |
FILE *f; |
758 |
|
759 |
snprintf(buf, sizeof(buf), "%s/cforbid.db", dir); |
760 |
if ((f = fopen(buf, "rb")) != NULL) { |
761 |
int32 ver; |
762 |
ver = fgetc(f)<<24; |
763 |
ver |= fgetc(f)<<16; |
764 |
ver |= fgetc(f)<< 8; |
765 |
ver |= fgetc(f); |
766 |
fclose(f); |
767 |
if (ver == 25) |
768 |
return "trircd-4.26"; |
769 |
} |
770 |
return NULL; |
771 |
} |
772 |
|
773 |
static void load_trircd(const char *dir, int verbose, int ac, char **av) |
774 |
{ |
775 |
if (ac > 1) { |
776 |
fprintf(stderr, "Unrecognized option %s\n", av[1]); |
777 |
usage(av[0]); |
778 |
} |
779 |
if (verbose) |
780 |
fprintf(stderr, "Loading nick.db...\n"); |
781 |
trircd_load_nick(dir); |
782 |
if (verbose) |
783 |
fprintf(stderr, "Loading ajoin.db...\n"); |
784 |
trircd_load_ajoin(dir); |
785 |
if (verbose) |
786 |
fprintf(stderr, "Loading chan.db...\n"); |
787 |
trircd_load_chan(dir); |
788 |
if (verbose) |
789 |
fprintf(stderr, "Loading cforbid.db...\n"); |
790 |
trircd_load_cforbid(dir); |
791 |
if (verbose) |
792 |
fprintf(stderr, "Loading oper.db...\n"); |
793 |
trircd_load_oper(dir); |
794 |
if (verbose) |
795 |
fprintf(stderr, "Loading akill.db...\n"); |
796 |
trircd_load_akill(dir); |
797 |
if (verbose) |
798 |
fprintf(stderr, "Loading exclude.db...\n"); |
799 |
trircd_load_exclude(dir); |
800 |
if (verbose) |
801 |
fprintf(stderr, "Loading exception.db...\n"); |
802 |
trircd_load_exception(dir); |
803 |
if (verbose) |
804 |
fprintf(stderr, "Loading news.db...\n"); |
805 |
trircd_load_news(dir); |
806 |
if (verbose) |
807 |
fprintf(stderr, "Loading sgline.db...\n"); |
808 |
trircd_load_sline(dir, 'g'); |
809 |
if (verbose) |
810 |
fprintf(stderr, "Loading sqline.db...\n"); |
811 |
trircd_load_sline(dir, 'q'); |
812 |
if (verbose) |
813 |
fprintf(stderr, "Loading szline.db...\n"); |
814 |
trircd_load_sline(dir, 'z'); |
815 |
} |
816 |
|
817 |
/*************************************************************************/ |
818 |
/*************************************************************************/ |
819 |
|
820 |
DBTypeInfo dbtype_trircd_4_26 = { |
821 |
"trircd-4.26", |
822 |
check_trircd, |
823 |
load_trircd |
824 |
}; |
825 |
|
826 |
/*************************************************************************/ |
827 |
|
828 |
/* |
829 |
* Local variables: |
830 |
* c-file-style: "stroustrup" |
831 |
* c-file-offsets: ((case-label . *) (statement-case-intro . *)) |
832 |
* indent-tabs-mode: nil |
833 |
* End: |
834 |
* |
835 |
* vim: expandtab shiftwidth=4: |
836 |
*/ |