ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/vendor/ircservices-5.1.24/tools/convert-ptlink.c
Revision: 3389
Committed: Fri Apr 25 14:12:15 2014 UTC (11 years, 4 months ago) by michael
Content type: text/x-csrc
File size: 28505 byte(s)
Log Message:
- Imported ircservices-5.1.24

File Contents

# Content
1 /* Conversion routines for PTlink >= 2.13.x databases.
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 ptlink_load_nick(const char *dir)
23 {
24 char filename[PATH_MAX+1];
25 dbFILE *f;
26 int i, j, c, delete;
27 int16 tmp16, ver;
28 int32 tmp32, total, count;
29 NickInfo *ni;
30 NickGroupInfo *ngi;
31 char *s;
32 signed char ch;
33
34 snprintf(filename, sizeof(filename), "%s/nick.db", dir);
35 if (!(f = open_db(filename, "r", 0)))
36 return;
37 SAFE(read_int8(&ch, f));
38 SAFE(read_int16(&ver, f));
39 if (ch != -1 || ver < 6 || ver > 11) {
40 fprintf(stderr, "Wrong version number on %s\n", filename);
41 exit(1);
42 }
43
44 SAFE(read_int32(&total, f));
45 count = 0;
46 #if CLEAN_COMPILE
47 c = 0;
48 #endif
49 for (i = 0; i < 256; i++) {
50 while (ver >= 10 || (c = getc_db(f)) == 1) {
51 char nickbuf[32], passbuf[32], authbuf[16];
52 if (ver >= 9) {
53 int res = read_int32(&tmp32, f); /* SUID (broken) / SNID */
54 if (res < 0) {
55 if (ver >= 10) /* v10: no more int8 markers */
56 break;
57 else
58 SAFE(res);
59 }
60 }
61 SAFE(read_buffer(nickbuf, f));
62 /* The source (v2.26-eol.1) claims that duplicate nicknames can
63 * get stored in the database for unknown reasons, so watch for
64 * and delete them as needed */
65 delete = (get_nickinfo(nickbuf) != NULL);
66 ni = makenick(nickbuf, &ngi);
67 /* Use the SNID (file version 11) as a nickname group ID only
68 * if it's nonzero and unique. Never use the SUID (versions 9
69 * and 10) as the source code claims that it's broken. */
70 if (ver >= 11 && tmp32 && !get_nickgroupinfo(tmp32))
71 ni->nickgroup = ngi->id = (uint32)tmp32;
72 SAFE(read_buffer(passbuf, f));
73 init_password(&ngi->pass);
74 memcpy(ngi->pass.password, passbuf, sizeof(passbuf));
75 if (ver >= 7)
76 SAFE(read_buffer(authbuf, f));
77 SAFE(read_string(&ngi->url, f));
78 if (ver >= 7)
79 SAFE(read_string(&s, f)); /* temporary, unauthed E-mail */
80 else
81 s = NULL;
82 SAFE(read_string(&ngi->email, f));
83 if (s) {
84 ngi->last_email = ngi->email;
85 ngi->email = s;
86 }
87 SAFE(read_string(&s, f)); /* icq_number */
88 SAFE(read_string(&s, f)); /* location */
89 SAFE(read_string(&ni->last_usermask, f));
90 if (!ni->last_usermask)
91 ni->last_usermask = (char *)"@";
92 SAFE(read_string(&ni->last_realname, f));
93 if (!ni->last_realname)
94 ni->last_realname = (char *)"";
95 SAFE(read_string(&ni->last_quit, f));
96 SAFE(read_int32(&tmp32, f));
97 ni->time_registered = tmp32;
98 SAFE(read_int32(&tmp32, f)); /* last_identify */
99 SAFE(read_int32(&tmp32, f));
100 ni->last_seen = tmp32;
101 if (ver >= 7)
102 SAFE(read_int32(&tmp32, f)); /* last_email_request */
103 SAFE(read_int32(&tmp32, f)); /* birth_date */
104 SAFE(read_int16(&tmp16, f)); /* status */
105 if (tmp16 & 0x0002) {
106 ni->status |= NS_VERBOTEN;
107 del_nickgroupinfo(ngi);
108 ni->nickgroup = 0;
109 }
110 if (tmp16 & 0x0004)
111 ni->status |= NS_NOEXPIRE;
112 SAFE(read_int16(&tmp16, f)); /* crypt_method */
113 switch (tmp16) {
114 case 0: break;
115 case 2: ngi->pass.cipher = sstrdup("unix-crypt"); break;
116 case 3: ngi->pass.cipher = sstrdup("md5"); break;
117 case 1:
118 fprintf(stderr, "%s: `%s' password encrypted with"
119 " unsupported method JP2, resetting password"
120 " to nickname", filename, nickbuf);
121 /* fall through */
122 default:
123 if (tmp16 != 1) {
124 fprintf(stderr, "%s: `%s' password encrypted with"
125 " unsupported method %d, resetting password"
126 " to nickname", filename, nickbuf, tmp16);
127 }
128 strbcpy(ngi->pass.password, nickbuf);
129 break;
130 }
131 SAFE(read_int32(&tmp32, f)); /* news_mask */
132 SAFE(read_int16(&tmp16, f)); /* news_status */
133 SAFE(read_string(&ni->last_realmask, f)); /* link */
134 SAFE(read_int16(&tmp16, f)); /* linkcount */
135 if (ni->last_realmask) {
136 ni->nickgroup = 0;
137 SAFE(read_int16(&tmp16, f)); /* channelcount */
138 } else {
139 SAFE(read_int32(&tmp32, f)); /* flags */
140 if (tmp32 & 0x00000001)
141 ngi->flags |= NF_KILLPROTECT;
142 if (tmp32 & 0x00004002)
143 ngi->flags |= 0x80000000; /* suspended */
144 if (tmp32 & 0x00000008)
145 ngi->flags |= NF_MEMO_HARDMAX;
146 if (tmp32 & 0x00000010)
147 ngi->flags |= NF_MEMO_SIGNON;
148 if (tmp32 & 0x00000020)
149 ngi->flags |= NF_MEMO_RECEIVE;
150 if (tmp32 & 0x00000040)
151 ngi->flags |= NF_PRIVATE;
152 if (tmp32 & 0x00000080)
153 ngi->flags |= NF_HIDE_EMAIL;
154 if (tmp32 & 0x00000100)
155 ngi->flags |= NF_HIDE_MASK;
156 if (tmp32 & 0x00000200)
157 ngi->flags |= NF_HIDE_QUIT;
158 if (tmp32 & 0x00000400)
159 ngi->flags |= NF_KILL_QUICK;
160 if (tmp32 & 0x00000800)
161 ngi->flags |= NF_KILL_IMMED;
162 SAFE(read_int32(&tmp32, f)); /* online */
163 if (ngi->flags & 0x80000000) {
164 ngi->flags &= ~0x80000000;
165 SAFE(read_int32(&tmp32, f)); /* expires */
166 strbcpy(ngi->suspend_who, "<unknown>");
167 ngi->suspend_reason =
168 (char *)"Unknown (imported from PTlink IRC Services)";
169 ngi->suspend_time = time(NULL);
170 ngi->suspend_expires = tmp32;
171 ngi->flags |= NF_SUSPENDED;
172 }
173 SAFE(read_int16(&ngi->ajoin_count, f));
174 ngi->ajoin = scalloc(sizeof(char *), ngi->ajoin_count);
175 for (j = 0; j < ngi->ajoin_count; j++)
176 SAFE(read_string(&ngi->ajoin[j], f));
177 SAFE(read_int16(&ngi->memos.memos_count, f));
178 SAFE(read_int16(&ngi->memos.memomax, f));
179 if (ngi->memos.memos_count) {
180 Memo *memos;
181 memos = scalloc(sizeof(*memos), ngi->memos.memos_count);
182 ngi->memos.memos = memos;
183 for (j = 0; j < ngi->memos.memos_count; j++, memos++) {
184 SAFE(read_uint32(&memos->number, f));
185 SAFE(read_int16(&tmp16, f));
186 if (tmp16 & 1)
187 memos->flags |= MF_UNREAD;
188 SAFE(read_int32(&tmp32, f));
189 memos->time = tmp32;
190 SAFE(read_buffer(nickbuf, f));
191 strbcpy(memos->sender, nickbuf);
192 SAFE(read_string(&memos->text, f));
193 }
194 }
195 SAFE(read_int16(&tmp16, f)); /* notes.count */
196 j = tmp16;
197 SAFE(read_int16(&tmp16, f)); /* notes.max */
198 while (j--) /* notes.note[] */
199 SAFE(read_string(&s, f));
200 SAFE(read_int16(&tmp16, f)); /* channelcount */
201 SAFE(read_int16(&tmp16, f)); /* channelmax */
202 SAFE(read_int16(&tmp16, f));
203 switch (tmp16) {
204 case 0: ngi->language = LANG_EN_US; break;
205 case 1: ngi->language = LANG_PT; break;
206 case 2: ngi->language = LANG_TR; break;
207 case 3: ngi->language = LANG_DE; break;
208 case 4: ngi->language = LANG_IT; break;
209 }
210 }
211 if (delete) {
212 del_nickgroupinfo(ngi);
213 del_nickinfo(ni);
214 }
215 count++;
216 } /* while (getc_db(f) == 1) */
217 if (ver < 10 && c != 0) {
218 fprintf(stderr, "%s is corrupt, aborting.\n", f->filename);
219 exit(1);
220 }
221 } /* for (i) */
222 close_db(f);
223 if (count != total) {
224 fprintf(stderr, "%s: warning: expected %d nicks, got %d\n",
225 filename, total, count);
226 fprintf(stderr, " This means that your data files may be corrupt."
227 " It may also be the\n"
228 " result of a bug in some versions of PTlink Services.\n");
229 }
230
231 /* Resolve links */
232 for (ni = first_nickinfo(); ni; ni = next_nickinfo()) {
233 NickInfo *ni2;
234 const char *last_nick;
235 if (ni->last_realmask) {
236 ni2 = ni;
237 /* Find root nick (this will actually stop at the first nick
238 * in the path to the root that isn't marked as linked, but
239 * that's okay because such a nick will already have its
240 * nickgroup ID set correctly) */
241 do {
242 last_nick = ni2->last_realmask;
243 ni2 = get_nickinfo(last_nick);
244 } while (ni2 && ni2 != ni && ni2->last_realmask);
245 ni->last_realmask = NULL;
246 /* Set nickgroup, or delete nick if an error occurred */
247 if (ni2 == ni) {
248 fprintf(stderr,
249 "Warning: dropping nick %s with circular link\n",
250 ni->nick);
251 del_nickinfo(ni);
252 } else if (!ni2) {
253 fprintf(stderr, "Warning: dropping nick %s linked to"
254 " nonexistent nick %s\n", ni->nick, last_nick);
255 del_nickinfo(ni);
256 } else {
257 ngi = get_nickgroupinfo(ni->nickgroup);
258 if (ngi)
259 del_nickgroupinfo(ngi);
260 ni->nickgroup = ni2->nickgroup;
261 ngi = get_nickgroupinfo(ni->nickgroup);
262 if (ngi) {
263 ARRAY_EXTEND(ngi->nicks);
264 strbcpy(ngi->nicks[ngi->nicks_count-1], ni->nick);
265 } else if (ni->nickgroup != 0) {
266 fprintf(stderr, "Warning: Nick group %d for nick %s not"
267 " found -- program bug? Output may be corrupt.",
268 ni->nickgroup, ni->nick);
269 }
270 }
271 }
272 }
273 }
274
275 /*************************************************************************/
276
277 static struct {
278 int32 flag;
279 char mode;
280 } ptlink_cmodes[] = {
281 { 0x00000001, 'i' },
282 { 0x00000002, 'm' },
283 { 0x00000004, 'n' },
284 { 0x00000008, 'p' },
285 { 0x00000010, 's' },
286 { 0x00000020, 't' },
287 { 0x00000040, 'k' },
288 { 0x00000080, 'l' },
289 { 0x00000200, 'R' },
290 { 0x00000400, 'c' },
291 { 0x00001000, 'O' },
292 { 0x00002000, 'A' },
293 { 0x00008000, 0 }, /* Like Unreal 'f': no dup lines within 10 secs */
294 { 0, 0 }
295 };
296
297 static void ptlink_load_chan(const char *dir)
298 {
299 char filename[PATH_MAX+1];
300 dbFILE *f;
301 int i, j, c, C_MAX;
302 ChannelInfo *ci;
303 NickInfo *ni;
304 signed char ch;
305 int16 tmp16, ver;
306 int32 tmp32, total, count, mlock_on, mlock_off;
307 char *on, *off;
308 MemoInfo tmpmi;
309
310 snprintf(filename, sizeof(filename), "%s/chan.db", dir);
311 if (!(f = open_db(filename, "r", 0)))
312 return;
313 SAFE(read_int8(&ch, f));
314 SAFE(read_int16(&ver, f));
315 if (ch != -1 || ver < 7 || ver > 10) {
316 fprintf(stderr, "Wrong version number on %s\n", filename);
317 exit(1);
318 }
319
320 if (ver >= 9)
321 SAFE(read_int32(&total, f));
322 count = 0;
323
324 C_MAX = (ver<9 ? 256 : 65535);
325 for (i = 0; i < C_MAX; i++) {
326 char *s;
327
328 while ((c = getc_db(f)) == 1) {
329 char namebuf[64], passbuf[32], nickbuf[32];
330 if (ver >= 10)
331 SAFE(read_int32(&tmp32, f)); /* SCID */
332 SAFE(read_buffer(namebuf, f));
333 ci = makechan(namebuf);
334 SAFE(read_string(&s, f));
335 if (s) {
336 ni = get_nickinfo(s);
337 if (!ni) {
338 fprintf(stderr,
339 "Warning: Founder %s for channel %s not found\n",
340 s, ci->name);
341 } else if (!ni->nickgroup) {
342 fprintf(stderr, "Warning: Founder %s for channel %s is a"
343 " forbidden nick\n", s, ci->name);
344 } else {
345 ci->founder = ni->nickgroup;
346 }
347 }
348 SAFE(read_string(&s, f));
349 if (s) {
350 ni = get_nickinfo(s);
351 if (!ni) {
352 fprintf(stderr, "Warning: Successor %s for channel %s"
353 " not found\n", s, ci->name);
354 } else if (!ni->nickgroup) {
355 fprintf(stderr, "Warning: Successor %s for channel %s"
356 " is a forbidden nick\n", s, ci->name);
357 } else if (ni->nickgroup == ci->founder) {
358 fprintf(stderr, "Warning: Successor %s for channel %s"
359 " is the same as the founder, clearing\n",
360 s, ci->name);
361 } else {
362 ci->successor = ni->nickgroup;
363 }
364 }
365 SAFE(read_int16(&tmp16, f)); /* maxusers */
366 SAFE(read_int32(&tmp32, f)); /* maxtime */
367 SAFE(read_buffer(passbuf, f));
368 init_password(&ci->founderpass);
369 memcpy(ci->founderpass.password, passbuf, sizeof(passbuf));
370 SAFE(read_string(&ci->desc, f));
371 if (!ci->desc)
372 ci->desc = (char *)"";
373 SAFE(read_string(&ci->url, f));
374 SAFE(read_string(&ci->email, f));
375 SAFE(read_int32(&tmp32, f));
376 ci->time_registered = tmp32;
377 SAFE(read_int32(&tmp32, f));
378 ci->last_used = tmp32;
379 SAFE(read_string(&ci->last_topic, f));
380 SAFE(read_buffer(nickbuf, f));
381 strbcpy(ci->last_topic_setter, nickbuf);
382 SAFE(read_int32(&tmp32, f));
383 ci->last_topic_time = tmp32;
384 SAFE(read_int32(&tmp32, f)); /* flags */
385 if (tmp32 & 0x00000001)
386 ci->flags |= CF_KEEPTOPIC;
387 if (tmp32 & 0x00000002)
388 ci->flags |= CF_SECUREOPS;
389 if (tmp32 & 0x00000004)
390 ci->flags |= CF_PRIVATE;
391 if (tmp32 & 0x00000008)
392 ci->flags |= CF_TOPICLOCK;
393 if (tmp32 & 0x00000010)
394 ci->flags |= CF_RESTRICTED;
395 if (tmp32 & 0x00000020)
396 ci->flags |= CF_LEAVEOPS;
397 if (tmp32 & 0x00000080)
398 ci->flags |= CF_VERBOTEN;
399 if (tmp32 & 0x00000200)
400 ci->flags |= CF_NOEXPIRE;
401 if (tmp32 & 0x00000800)
402 ci->flags |= CF_OPNOTICE;
403 SAFE(read_int16(&tmp16, f)); /* crypt_method */
404 switch (tmp16) {
405 case 0: break;
406 case 2: ci->founderpass.cipher = sstrdup("unix-crypt"); break;
407 case 3: ci->founderpass.cipher = sstrdup("md5"); break;
408 case 1:
409 fprintf(stderr, "%s: `%s' password encrypted with"
410 " unsupported method JP2, resetting password"
411 " to channel name", filename, namebuf);
412 /* fall through */
413 default:
414 if (tmp16 != 1) {
415 fprintf(stderr, "%s: `%s' password encrypted with"
416 " unsupported method %d, resetting password"
417 " to channel name", filename, namebuf, tmp16);
418 }
419 strbcpy(ci->founderpass.password, namebuf);
420 break;
421 }
422 if (tmp32 & 0x1000)
423 SAFE(read_int32(&tmp32, f)); /* drop_time */
424
425 SAFE(read_int16(&tmp16, f)); /* levels[] */
426 for (j = tmp16; j > 0; j--)
427 SAFE(read_int16(&tmp16, f));
428
429 SAFE(read_int16(&ci->access_count, f));
430 if (ci->access_count) {
431 ci->access = scalloc(ci->access_count, sizeof(ChanAccess));
432 for (j = 0; j < ci->access_count; j++) {
433 SAFE(read_int16(&tmp16, f)); /* in_use */
434 if (tmp16) {
435 SAFE(read_int16(&ci->access[j].level, f));
436 SAFE(read_string(&s, f));
437 ci->access[j].level =
438 convert_acclev(ci->access[j].level);
439 if (s) {
440 ni = get_nickinfo(s);
441 if (ni)
442 ci->access[j].nickgroup = ni->nickgroup;
443 }
444 SAFE(read_string(&s, f)); /* who */
445 }
446 }
447 }
448
449 SAFE(read_int16(&ci->akick_count, f));
450 if (ci->akick_count) {
451 ci->akick = scalloc(ci->akick_count, sizeof(AutoKick));
452 for (j = 0; j < ci->akick_count; j++) {
453 SAFE(read_int16(&tmp16, f)); /* in_use */
454 if (tmp16) {
455 SAFE(read_string(&ci->akick[j].mask, f));
456 SAFE(read_string(&ci->akick[j].reason, f));
457 SAFE(read_string(&s, f)); /* who */
458 strbcpy(ci->akick[j].who, s);
459 ci->akick[j].set = time(NULL);
460 SAFE(read_int32(&tmp32, f)); /* last_kick */
461 ci->akick[j].lastused = tmp32;
462 }
463 }
464 }
465
466 if (ver < 8) {
467 SAFE(read_int16(&tmp16, f));
468 mlock_on = (int32)tmp16 & 0xFFFF;
469 SAFE(read_int16(&tmp16, f));
470 mlock_off = (int32)tmp16 & 0xFFFF;
471 } else {
472 SAFE(read_int32(&mlock_on, f));
473 SAFE(read_int32(&mlock_off, f));
474 }
475 ci->mlock.on = on = scalloc(64, 1);
476 ci->mlock.off = off = scalloc(64, 1);
477 for (j = 0; ptlink_cmodes[j].flag != 0; j++) {
478 if (mlock_on & ptlink_cmodes[j].flag)
479 *on++ = ptlink_cmodes[j].mode;
480 if (mlock_off & ptlink_cmodes[j].flag)
481 *off++ = ptlink_cmodes[j].mode;
482 }
483 *on = 0;
484 *off = 0;
485 SAFE(read_int32(&ci->mlock.limit, f));
486 SAFE(read_string(&ci->mlock.key, f));
487
488 SAFE(read_int16(&tmpmi.memos_count, f));
489 SAFE(read_int16(&tmp16, f)); /* memomax */
490 if (tmpmi.memos_count) {
491 Memo *memos;
492 memos = scalloc(sizeof(Memo), tmpmi.memos_count);
493 tmpmi.memos = memos;
494 for (j = 0; j < tmpmi.memos_count; j++, memos++) {
495 SAFE(read_uint32(&memos->number, f));
496 SAFE(read_int16(&tmp16, f));
497 if (tmp16 & 1)
498 memos->flags |= MF_UNREAD;
499 SAFE(read_int32(&tmp32, f));
500 memos->time = tmp32;
501 SAFE(read_buffer(nickbuf, f));
502 strbcpy(memos->sender, nickbuf);
503 SAFE(read_string(&memos->text, f));
504 }
505 }
506
507 SAFE(read_string(&ci->entry_message, f));
508
509 if (!(ci->flags & CF_VERBOTEN) && !ci->founder) {
510 fprintf(stderr, "Ignoring channel %s (missing founder)\n",
511 ci->name);
512 del_channelinfo(ci);
513 }
514
515 count++;
516
517 } /* while (getc_db(f) == 1) */
518
519 if (c != 0) {
520 fprintf(stderr, "%s is corrupt, aborting.\n", f->filename);
521 exit(1);
522 }
523 } /* for (i) */
524 close_db(f);
525
526 if (ver >= 9 && count != total) {
527 fprintf(stderr, "%s: warning: expected %d channels, got %d\n",
528 filename, total, count);
529 fprintf(stderr, " This means that your data files may be corrupt."
530 " It may also be the\n"
531 " result of a bug in some versions of PTlink Services.\n");
532 }
533 }
534
535 /*************************************************************************/
536
537 static void ptlink_load_oper(const char *dir)
538 {
539 char filename[PATH_MAX+1];
540 dbFILE *f;
541 int16 i, n, tmp16;
542 int32 tmp32;
543 char *s;
544 signed char ch;
545
546 snprintf(filename, sizeof(filename), "%s/oper.db", dir);
547 if (!(f = open_db(filename, "r", 0)))
548 return;
549 SAFE(read_int8(&ch, f));
550 SAFE(read_int16(&tmp16, f));
551 if (ch != -1 || tmp16 < 1 || tmp16 > 2) {
552 fprintf(stderr, "Wrong version number on %s\n", filename);
553 exit(1);
554 }
555 SAFE(read_int16(&n, f));
556 for (i = 0; i < n; i++) {
557 SAFE(read_string(&s, f));
558 set_os_priv(s, NP_SERVADMIN);
559 }
560 SAFE(read_int16(&n, f));
561 for (i = 0; i < n; i++) {
562 SAFE(read_string(&s, f));
563 set_os_priv(s, NP_SERVOPER);
564 }
565 SAFE(read_int32(&maxusercnt, f));
566 SAFE(read_int32(&tmp32, f));
567 maxusertime = tmp32;
568 close_db(f);
569 }
570
571 /*************************************************************************/
572
573 static void ptlink_load_akill(const char *dir)
574 {
575 char filename[PATH_MAX+1];
576 dbFILE *f;
577 int16 tmp16, i, n;
578 int32 tmp32;
579 signed char ch;
580 MaskData *md;
581
582 snprintf(filename, sizeof(filename), "%s/akill.db", dir);
583 if (!(f = open_db(filename, "r", 0)))
584 return;
585 SAFE(read_int8(&ch, f));
586 SAFE(read_int16(&tmp16, f));
587 if (ch != -1 || tmp16 != 1) {
588 fprintf(stderr, "Wrong version number on %s\n", filename);
589 exit(1);
590 }
591 SAFE(read_int16(&n, f));
592 md = scalloc(sizeof(*md), n);
593 for (i = 0; i < n; i++) {
594 char nickbuf[32];
595 SAFE(read_string(&md[i].mask, f));
596 SAFE(read_string(&md[i].reason, f));
597 SAFE(read_buffer(nickbuf, f));
598 strbcpy(md[i].who, nickbuf);
599 SAFE(read_int32(&tmp32, f));
600 md[i].time = tmp32;
601 SAFE(read_int32(&tmp32, f));
602 md[i].expires = tmp32;
603 if (md[i].mask)
604 add_maskdata(MD_AKILL, &md[i]);
605 }
606 close_db(f);
607 }
608
609 /*************************************************************************/
610
611 static void ptlink_load_sqline(const char *dir)
612 {
613 char filename[PATH_MAX+1];
614 dbFILE *f;
615 int16 tmp16, i, n;
616 int32 tmp32;
617 signed char ch;
618 MaskData *md;
619
620 snprintf(filename, sizeof(filename), "%s/sqline.db", dir);
621 if (!(f = open_db(filename, "r", 0)))
622 return;
623 SAFE(read_int8(&ch, f));
624 SAFE(read_int16(&tmp16, f));
625 if (ch != -1 || tmp16 != 1) {
626 fprintf(stderr, "Wrong version number on %s\n", filename);
627 exit(1);
628 }
629 SAFE(read_int16(&n, f));
630 md = scalloc(sizeof(*md), n);
631 for (i = 0; i < n; i++) {
632 char nickbuf[32];
633 SAFE(read_string(&md[i].mask, f));
634 SAFE(read_string(&md[i].reason, f));
635 SAFE(read_buffer(nickbuf, f));
636 strbcpy(md[i].who, nickbuf);
637 SAFE(read_int32(&tmp32, f));
638 md[i].time = tmp32;
639 SAFE(read_int32(&tmp32, f));
640 md[i].expires = tmp32;
641 if (md[i].mask)
642 add_maskdata(MD_SQLINE, &md[i]);
643 }
644 close_db(f);
645 }
646
647 /*************************************************************************/
648
649 static void ptlink_load_sxline(const char *dir)
650 {
651 char filename[PATH_MAX+1];
652 dbFILE *f;
653 int16 tmp16, i, n;
654 int32 tmp32;
655 signed char ch;
656 MaskData *md;
657
658 snprintf(filename, sizeof(filename), "%s/sxline.db", dir);
659 if (!(f = open_db(filename, "r", 0)))
660 return;
661 SAFE(read_int8(&ch, f));
662 SAFE(read_int16(&tmp16, f));
663 if (ch != -1 || tmp16 != 1) {
664 fprintf(stderr, "Wrong version number on %s\n", filename);
665 exit(1);
666 }
667 SAFE(read_int16(&n, f));
668 md = scalloc(sizeof(*md), n);
669 for (i = 0; i < n; i++) {
670 char nickbuf[32];
671 SAFE(read_string(&md[i].mask, f));
672 SAFE(read_string(&md[i].reason, f));
673 SAFE(read_buffer(nickbuf, f));
674 strbcpy(md[i].who, nickbuf);
675 SAFE(read_int32(&tmp32, f));
676 md[i].time = tmp32;
677 SAFE(read_int32(&tmp32, f));
678 md[i].expires = tmp32;
679 if (md[i].mask)
680 add_maskdata(MD_SGLINE, &md[i]);
681 }
682 close_db(f);
683 }
684
685 /*************************************************************************/
686
687 static void ptlink_load_news(const char *dir)
688 {
689 char filename[PATH_MAX+1];
690 dbFILE *f;
691 int16 tmp16, i, n;
692 int32 tmp32;
693 signed char ch;
694 NewsItem *news;
695
696 snprintf(filename, sizeof(filename), "%s/news.db", dir);
697 if (!(f = open_db(filename, "r", 0)))
698 return;
699 SAFE(read_int8(&ch, f));
700 SAFE(read_int16(&tmp16, f));
701 if (ch != -1 || tmp16 != 1) {
702 fprintf(stderr, "Wrong version number on %s\n", filename);
703 exit(1);
704 }
705 SAFE(read_int16(&n, f));
706 news = scalloc(sizeof(*news), n);
707 for (i = 0; i < n; i++) {
708 char nickbuf[32];
709 SAFE(read_int16(&news[i].type, f));
710 SAFE(read_int32(&news[i].num, f));
711 SAFE(read_string(&news[i].text, f));
712 SAFE(read_buffer(nickbuf, f));
713 strbcpy(news[i].who, nickbuf);
714 SAFE(read_int32(&tmp32, f));
715 news[i].time = tmp32;
716 add_news(&news[i]);
717 }
718 close_db(f);
719 }
720
721 /*************************************************************************/
722 /*************************************************************************/
723
724 static const char *check_ptlink(const char *dir)
725 {
726 char buf[PATH_MAX+1];
727
728 snprintf(buf, sizeof(buf), "%s/vline.db", dir);
729 if (access(buf, R_OK) == 0)
730 return "PTlink";
731 return NULL;
732 }
733
734 static void load_ptlink(const char *dir, int verbose, int ac, char **av)
735 {
736 if (ac > 1) {
737 fprintf(stderr, "Unrecognized option %s\n", av[1]);
738 usage(av[0]);
739 }
740 if (verbose)
741 fprintf(stderr, "Loading nick.db...\n");
742 ptlink_load_nick(dir);
743 if (verbose)
744 fprintf(stderr, "Loading chan.db...\n");
745 ptlink_load_chan(dir);
746 if (verbose)
747 fprintf(stderr, "Loading oper.db...\n");
748 ptlink_load_oper(dir);
749 if (verbose)
750 fprintf(stderr, "Loading akill.db...\n");
751 ptlink_load_akill(dir);
752 if (verbose)
753 fprintf(stderr, "Loading sqline.db...\n");
754 ptlink_load_sqline(dir);
755 if (verbose)
756 fprintf(stderr, "Loading sxline.db...\n");
757 ptlink_load_sxline(dir);
758 if (verbose)
759 fprintf(stderr, "Loading news.db...\n");
760 ptlink_load_news(dir);
761 }
762
763 /*************************************************************************/
764 /*************************************************************************/
765
766 DBTypeInfo dbtype_ptlink = {
767 "ptlink",
768 check_ptlink,
769 load_ptlink
770 };
771
772 /*************************************************************************/
773
774 /*
775 * Local variables:
776 * c-file-style: "stroustrup"
777 * c-file-offsets: ((case-label . *) (statement-case-intro . *))
778 * indent-tabs-mode: nil
779 * End:
780 *
781 * vim: expandtab shiftwidth=4:
782 */