ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/vendor/ircservices-5.1.24/tools/convert-magick.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: 22102 byte(s)
Log Message:
- Imported ircservices-5.1.24

File Contents

# Content
1 /* Conversion routines for Magick 1.4b2 and Wrecked 1.2 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 m14_load_nick(const char *dir, int32 version)
23 {
24 dbFILE *f;
25 long i, j;
26 int c;
27 NickInfo *ni;
28 NickGroupInfo *ngi;
29 struct oldni_ {
30 struct oldni_ *next, *prev;
31 char nick[32];
32 char pass[32];
33 char *email;
34 char *url;
35 char *usermask;
36 char *realname;
37 time_t reg;
38 time_t seen;
39 long naccess;
40 char **access;
41 long nignore;
42 char **ignore;
43 long flags;
44 long resv[4];
45 } oldni;
46
47 f = open_db_ver(dir, "nick.db", version, version, NULL);
48 for (i = 33; i < 256; i++) {
49 while ((c = getc_db(f)) == 1) {
50 SAFE(read_variable(oldni, f));
51 if (version == 6) {
52 time_t last_signon;
53 long uin;
54 SAFE(read_variable(last_signon, f));
55 SAFE(read_variable(uin, f));
56 }
57 if (oldni.email)
58 SAFE(read_string(&oldni.email, f));
59 if (oldni.url)
60 SAFE(read_string(&oldni.url, f));
61 SAFE(read_string(&oldni.usermask, f));
62 SAFE(read_string(&oldni.realname, f));
63 ni = makenick(oldni.nick, &ngi);
64 ni->last_usermask = oldni.usermask;
65 ni->last_realname = oldni.realname;
66 ni->last_quit = NULL;
67 ni->time_registered = oldni.reg;
68 ni->last_seen = oldni.seen;
69 init_password(&ngi->pass);
70 strbcpy(ngi->pass.password, oldni.pass);
71 ngi->url = oldni.url;
72 ngi->email = oldni.email;
73 ngi->access_count = oldni.naccess;
74 ngi->ignore_count = oldni.nignore;
75 if (version == 5)
76 oldni.flags &= 0x000000FF;
77 if (oldni.flags & 0x00000001)
78 ngi->flags |= NF_KILLPROTECT;
79 if (oldni.flags & 0x00000002)
80 ngi->flags |= NF_SECURE;
81 if (oldni.flags & 0x00000004) {
82 ni->status |= NS_VERBOTEN;
83 ni->nickgroup = 0;
84 }
85 if (oldni.flags & 0x00004008)
86 ni->status |= NS_NOEXPIRE;
87 if (oldni.flags & 0x00000010)
88 ngi->flags |= NF_PRIVATE;
89 if (oldni.flags & 0x00000020) {
90 strbcpy(ngi->suspend_who, "<unknown>");
91 ngi->suspend_reason = (char *)(
92 version==6 ? "Unknown (imported from Wrecked IRC Services)"
93 : "Unknown (imported from Magick IRC Services)"
94 );
95 ngi->suspend_time = time(NULL);
96 ngi->suspend_expires = 0;
97 ngi->flags |= NF_SUSPENDED;
98 }
99 if (oldni.flags & 0x00000080) {
100 ni->status |= 0x8000; /* Flag: this is a linked nick */
101 ni->nickgroup = 0;
102 }
103 if (oldni.flags & 0x00000100)
104 ngi->memos.memomax = 0;
105 if (oldni.flags & 0x00000200)
106 ngi->flags |= NF_HIDE_EMAIL;
107 ngi->access = smalloc(ngi->access_count * sizeof(char *));
108 for (j = 0; j < ngi->access_count; j++)
109 SAFE(read_string(&ngi->access[j], f));
110 ngi->ignore = smalloc(ngi->ignore_count * sizeof(char *));
111 for (j = 0; j < ngi->ignore_count; j++)
112 SAFE(read_string(&ngi->ignore[j], f));
113 } /* while more entries */
114 if (c != 0) {
115 fprintf(stderr, "%s is corrupt, aborting.\n", f->filename);
116 exit(1);
117 }
118 } /* for 33..256 */
119 close_db(f);
120
121 /* Resolve links */
122 for (ni = first_nickinfo(); ni; ni = next_nickinfo()) {
123 NickInfo *ni2;
124 const char *last_nick;
125 if (ni->status & 0x8000) {
126 ni->status &= ~0x8000;
127 ni2 = ni;
128 /* Find root nick (this will actually stop at the first nick
129 * in the path to the root that isn't marked as linked, but
130 * that's okay because such a nick will already have its
131 * nickgroup ID set correctly) */
132 do {
133 last_nick = ni2->last_usermask;
134 ni2 = get_nickinfo(last_nick);
135 } while (ni2 && (ni2->status & 0x8000));
136 /* Set nickgroup and last usermask field, or delete nick if an
137 * error occurred */
138 if (ni2 == ni) {
139 fprintf(stderr,
140 "Warning: dropping nick %s with circular link\n",
141 ni->nick);
142 del_nickinfo(ni);
143 } else if (!ni2) {
144 fprintf(stderr, "Warning: dropping nick %s linked to"
145 " nonexistent nick %s\n", ni->nick, last_nick);
146 del_nickinfo(ni);
147 } else {
148 ngi = get_nickgroupinfo(ni->nickgroup);
149 if (ngi)
150 del_nickgroupinfo(ngi);
151 ni->nickgroup = ni2->nickgroup;
152 ni->last_usermask = ni2->last_usermask;
153 ngi = get_nickgroupinfo(ni->nickgroup);
154 if (ngi) {
155 ARRAY_EXTEND(ngi->nicks);
156 strbcpy(ngi->nicks[ngi->nicks_count-1], ni->nick);
157 } else if (ni->nickgroup != 0) {
158 fprintf(stderr, "Warning: Nick group %d for nick %s not"
159 " found -- program bug? Output may be corrupt.",
160 ni->nickgroup, ni->nick);
161 }
162 }
163 }
164 }
165 }
166
167 /*************************************************************************/
168
169 static int16 magick_convert_level(int16 lev) {
170 if (lev >= 20)
171 return lev-10;
172 else if (lev >= 5)
173 return lev/2;
174 else if (lev >= 1)
175 return (lev+1)/2;
176 else
177 return lev;
178 };
179
180 static int16 wrecked_convert_level(int16 lev) {
181 if (lev >= 25)
182 return lev-15;
183 else if (lev >= 15)
184 return (lev-5)/10;
185 else if (lev >= 10)
186 return 4;
187 else if (lev >= 5)
188 return 3;
189 else if (lev >= 1)
190 return (lev+1) / 2;
191 else
192 return lev;
193 };
194
195
196 static void m14_load_chan(const char *dir, int32 version)
197 {
198 char *s;
199 dbFILE *f;
200 long i, j;
201 int c;
202 int16 tmp16;
203 int16 (*my_convert_level)(int16);
204 ChannelInfo *ci;
205 NickInfo *ni;
206 struct access_ {
207 short level;
208 short is_nick;
209 char *name;
210 } access;
211 struct akick_ {
212 short is_nick;
213 short pad;
214 char *name;
215 char *reason;
216 } akick;
217 struct oldci_ {
218 struct oldci_ *next, *prev;
219 char name[64];
220 char founder[32];
221 char pass[32];
222 char *desc;
223 char *url;
224 time_t reg;
225 time_t used;
226 long naccess;
227 struct access_ *access;
228 long nakick;
229 struct akick_ *akick;
230 char mlock_on[64], mlock_off[64];
231 long mlock_limit;
232 char *mlock_key;
233 char *topic;
234 char topic_setter[32];
235 time_t topic_time;
236 long flags;
237 short *levels;
238 long resv[3];
239 } oldci;
240
241 if (version == 6)
242 my_convert_level = wrecked_convert_level;
243 else
244 my_convert_level = magick_convert_level;
245
246 f = open_db_ver(dir, "chan.db", version, version, NULL);
247 for (i = 33; i < 256; i++) {
248 while ((c = getc_db(f)) == 1) {
249 SAFE(read_variable(oldci, f));
250 SAFE(read_string(&oldci.desc, f));
251 if (oldci.url)
252 SAFE(read_string(&oldci.url, f));
253 if (oldci.mlock_key)
254 SAFE(read_string(&oldci.mlock_key, f));
255 if (oldci.topic)
256 SAFE(read_string(&oldci.topic, f));
257 ci = makechan(oldci.name);
258 if (*oldci.founder) {
259 ni = get_nickinfo(oldci.founder);
260 if (!ni) {
261 fprintf(stderr,
262 "Warning: Founder %s for channel %s not found\n",
263 oldci.founder, oldci.name);
264 } else if (ni->status & NS_VERBOTEN) {
265 fprintf(stderr, "Warning: Founder %s for channel %s is a"
266 " forbidden nick\n", oldci.founder, oldci.name);
267 } else if (!ni->nickgroup) {
268 fprintf(stderr, "Warning: Founder %s for channel %s has"
269 " an invalid nickname record (bug?)\n",
270 oldci.founder, oldci.name);
271 } else {
272 ci->founder = ni->nickgroup;
273 }
274 }
275 init_password(&ci->founderpass);
276 strbcpy(ci->founderpass.password, oldci.pass);
277 ci->desc = oldci.desc;
278 ci->url = oldci.url;
279 ci->time_registered = oldci.reg;
280 ci->last_used = oldci.used;
281 ci->access_count = oldci.naccess;
282 ci->akick_count = oldci.nakick;
283 ci->mlock.on = scalloc(64, 1);
284 strscpy(ci->mlock.on, oldci.mlock_on, 64);
285 ci->mlock.off = scalloc(64, 1);
286 strscpy(ci->mlock.off, oldci.mlock_off, 64);
287 ci->mlock.limit = oldci.mlock_limit;
288 ci->mlock.key = oldci.mlock_key;
289 ci->last_topic = oldci.topic;
290 strbcpy(ci->last_topic_setter, oldci.topic_setter);
291 ci->last_topic_time = oldci.topic_time;
292 if (version == 5)
293 oldci.flags &= 0x000003FF;
294 if (oldci.flags & 0x00000001)
295 ci->flags |= CF_KEEPTOPIC;
296 if (oldci.flags & 0x00000002)
297 ci->flags |= CF_SECUREOPS;
298 if (oldci.flags & 0x00000004)
299 ci->flags |= CF_PRIVATE;
300 if (oldci.flags & 0x00000008)
301 ci->flags |= CF_TOPICLOCK;
302 if (oldci.flags & 0x00000010)
303 ci->flags |= CF_RESTRICTED;
304 if (oldci.flags & 0x00000020)
305 ci->flags |= CF_LEAVEOPS;
306 if (oldci.flags & 0x00000040)
307 ci->flags |= CF_SECURE;
308 if (oldci.flags & 0x00000080)
309 ci->flags |= CF_VERBOTEN;
310 if (oldci.flags & 0x00000100) {
311 ci->flags |= CF_SUSPENDED;
312 strbcpy(ci->suspend_who, "<unknown>");
313 ci->suspend_reason = (char *)(
314 version==6 ? "Unknown (imported from Wrecked IRC Services)"
315 : "Unknown (imported from Magick IRC Services)"
316 );
317 ci->suspend_time = time(NULL);
318 ci->suspend_expires = 0;
319 }
320 if (oldci.flags & 0x00000400)
321 ci->flags |= CF_NOEXPIRE;
322
323 ci->access = scalloc(sizeof(ChanAccess), ci->access_count);
324 for (j = 0; j < oldci.naccess; j++) {
325 SAFE(read_variable(access, f));
326 ci->access[j].nickgroup = (access.is_nick == 1); /* in_use */
327 ci->access[j].level =
328 convert_acclev(my_convert_level(access.level));
329 }
330 for (j = 0; j < oldci.naccess; j++) {
331 SAFE(read_string(&s, f));
332 if (!s) {
333 ci->access[j].nickgroup = 0;
334 continue;
335 }
336 if (ci->access[j].nickgroup) {
337 ni = get_nickinfo(s);
338 ci->access[j].nickgroup = ni ? ni->nickgroup : 0;
339 }
340 }
341
342 ci->akick = scalloc(sizeof(AutoKick), oldci.nakick);
343 for (j = 0; j < oldci.nakick; j++) {
344 SAFE(read_variable(akick, f));
345 /* `lastused' field temporarily used to hold `is_nick' */
346 ci->akick[j].lastused = akick.is_nick;
347 ci->akick[j].reason = akick.reason;
348 strbcpy(ci->akick[j].who, "<unknown>");
349 ci->akick[j].set = time(NULL);
350 }
351 for (j = 0; j < oldci.nakick; j++) {
352 SAFE(read_string(&ci->akick[j].mask, f));
353 if (ci->akick[j].lastused) { /* was `is_nick' */
354 char *s = smalloc(strlen(ci->akick[j].mask)+5);
355 sprintf(s, "%s!*@*", ci->akick[j].mask);
356 free(ci->akick[j].mask);
357 ci->akick[j].mask = s;
358 }
359 ci->akick[j].lastused = 0;
360 if (ci->akick[j].reason) {
361 SAFE(read_string(&ci->akick[j].reason, f));
362 if (!ci->akick[j].mask && ci->akick[j].reason)
363 ci->akick[j].reason = NULL;
364 }
365 }
366
367 SAFE(read_int16(&tmp16, f));
368 for (j = tmp16; j > 0; j--)
369 SAFE(read_int16(&tmp16, f));
370
371 /* Remove from list if founder does not exist and channel is
372 * not forbidden */
373 if (!(ci->flags & CF_VERBOTEN) && !ci->founder) {
374 fprintf(stderr, "Ignoring channel %s (missing founder)\n",
375 ci->name);
376 del_channelinfo(ci);
377 }
378
379 } /* while more entries */
380
381 if (c != 0) {
382 fprintf(stderr, "%s is corrupt, aborting.\n", f->filename);
383 exit(1);
384 }
385 } /* for 33..256 */
386
387 close_db(f);
388 }
389
390 /*************************************************************************/
391
392 static void m14_load_memo(const char *dir, int32 version)
393 {
394 char *s;
395 dbFILE *f;
396 struct memo_ {
397 char sender[32];
398 long number;
399 time_t time;
400 char *text;
401 long resv[4];
402 } memo;
403 struct memolist_ {
404 struct memolist_ *next, *prev;
405 char nick[32];
406 long n_memos;
407 Memo *memos;
408 long resv[4];
409 } memolist;
410 NickGroupInfo *ngi;
411 Memo *m = NULL;
412 long i, j, flags = 0;
413 int c;
414
415 f = open_db_ver(dir, "memo.db", version, version, NULL);
416 for (i = 33; i < 256; i++) {
417 while ((c = getc_db(f)) == 1) {
418 SAFE(read_variable(memolist, f));
419 ngi = get_nickgroupinfo_by_nick(memolist.nick);
420 if (ngi) {
421 ngi->memos.memos_count = memolist.n_memos;
422 m = scalloc(sizeof(*m), ngi->memos.memos_count);
423 ngi->memos.memos = m;
424 }
425 for (j = 0; j < memolist.n_memos; j++) {
426 SAFE(read_variable(memo, f));
427 if (version == 6) {
428 SAFE(read_variable(flags, f));
429 flags = memo.resv[0] & 1;
430 }
431 if (ngi) {
432 m[j].number = memo.number;
433 if (flags & 1)
434 m[j].flags |= MF_UNREAD;
435 m[j].time = memo.time;
436 strbcpy(m[j].sender, memo.sender);
437 }
438 }
439 for (j = 0; j < memolist.n_memos; j++) {
440 SAFE(read_string(&s, f));
441 if (ngi)
442 m[j].text = s;
443 }
444 }
445 if (c != 0) {
446 fprintf(stderr, "%s is corrupt, aborting.\n", f->filename);
447 exit(1);
448 }
449 }
450 close_db(f);
451 }
452
453 /*************************************************************************/
454
455 static void m14_load_sop(const char *dir, int32 version)
456 {
457 char nick[32];
458 dbFILE *f;
459 int16 n, i;
460
461 f = open_db_ver(dir, "sop.db", version, version, NULL);
462 SAFE(read_int16(&n, f));
463 for (i = 0; i < n; i++) {
464 SAFE(read_buffer(nick, f));
465 set_os_priv(nick, NP_SERVADMIN);
466 }
467 close_db(f);
468 }
469
470 /*************************************************************************/
471
472 static void m14_load_akill(const char *dir, int32 version)
473 {
474 dbFILE *f;
475 int16 i, n;
476 MaskData *md;
477 struct akill_ {
478 char *mask;
479 char *reason;
480 char who[32];
481 time_t time;
482 } akill;
483
484 f = open_db_ver(dir, "akill.db", version, version, NULL);
485 SAFE(read_int16(&n, f));
486 md = scalloc(sizeof(*md), n);
487 for (i = 0; i < n; i++) {
488 SAFE(read_variable(akill, f));
489 strbcpy(md[i].who, akill.who);
490 md[i].time = akill.time;
491 md[i].expires = 0;
492 }
493 for (i = 0; i < n; i++) {
494 SAFE(read_string(&md[i].mask, f));
495 SAFE(read_string(&md[i].reason, f));
496 add_maskdata(MD_AKILL, &md[i]);
497 }
498 close_db(f);
499 }
500
501 /*************************************************************************/
502
503 static void m14_load_clone(const char *dir, int32 version)
504 {
505 dbFILE *f;
506 int16 i, n;
507 MaskData *md;
508 struct allow_ {
509 char *host;
510 int amount;
511 char *reason;
512 char who[32];
513 time_t time;
514 } allow;
515
516 f = open_db_ver(dir, "clone.db", version, version, NULL);
517 SAFE(read_int16(&n, f));
518 md = scalloc(sizeof(*md), n);
519 for (i = 0; i < n; i++) {
520 SAFE(read_variable(allow, f));
521 strbcpy(md[i].who, allow.who);
522 md[i].limit = allow.amount;
523 md[i].time = allow.time;
524 md[i].expires = 0;
525 md[i].num = i+1;
526 }
527 for (i = 0; i < n; i++) {
528 SAFE(read_string(&md[i].mask, f));
529 SAFE(read_string(&md[i].reason, f));
530 add_maskdata(MD_EXCEPTION, &md[i]);
531 }
532 close_db(f);
533 }
534
535 /*************************************************************************/
536
537 static void m14_load_message(const char *dir, int32 version)
538 {
539 dbFILE *f;
540 int16 i, n;
541 NewsItem *news;
542 struct message_ {
543 char *text;
544 int type;
545 char who[32];
546 time_t time;
547 } msg;
548
549 f = open_db_ver(dir, "message.db", version, version, NULL);
550 SAFE(read_int16(&n, f));
551 news = scalloc(sizeof(*news), n);
552 for (i = 0; i < n; i++) {
553 SAFE(read_variable(msg, f));
554 news[i].type = msg.type;
555 strbcpy(news[i].who, msg.who);
556 news[i].time = msg.time;
557 }
558 for (i = 0; i < n; i++) {
559 SAFE(read_string(&news[i].text, f));
560 add_news(&news[i]);
561 }
562 close_db(f);
563 }
564
565 /*************************************************************************/
566 /*************************************************************************/
567
568 static const char *check_magick_14b2(const char *dir)
569 {
570 FILE *f;
571 char buf[PATH_MAX+1];
572
573 snprintf(buf, sizeof(buf), "%s/message.db", dir);
574 f = fopen(buf, "rb");
575 if (f) {
576 int ver;
577 ver = fgetc(f)<<24;
578 ver |= fgetc(f)<<16;
579 ver |= fgetc(f)<<8;
580 ver |= fgetc(f);
581 fclose(f);
582 if (ver == 5)
583 return "Magick 1.4b2";
584 }
585 return NULL;
586 }
587
588 static void load_magick_14b2(const char *dir, int verbose, int ac,
589 char **av)
590 {
591 if (ac > 1) {
592 fprintf(stderr, "Unrecognized option %s\n", av[1]);
593 usage(av[0]);
594 }
595 if (verbose)
596 fprintf(stderr, "Loading nick.db...\n");
597 m14_load_nick(dir, 5);
598 if (verbose)
599 fprintf(stderr, "Loading chan.db...\n");
600 m14_load_chan(dir, 5);
601 if (verbose)
602 fprintf(stderr, "Loading memo.db...\n");
603 m14_load_memo(dir, 5);
604 if (verbose)
605 fprintf(stderr, "Loading sop.db...\n");
606 m14_load_sop(dir, 5);
607 if (verbose)
608 fprintf(stderr, "Loading akill.db...\n");
609 m14_load_akill(dir, 5);
610 if (verbose)
611 fprintf(stderr, "Loading clone.db...\n");
612 m14_load_clone(dir, 5);
613 if (verbose)
614 fprintf(stderr, "Loading message.db...\n");
615 m14_load_message(dir, 5);
616 }
617
618 /*************************************************************************/
619 /*************************************************************************/
620
621 static const char *check_wrecked_1_2(const char *dir)
622 {
623 FILE *f;
624 char buf[PATH_MAX+1];
625
626 snprintf(buf, sizeof(buf), "%s/message.db", dir);
627 f = fopen(buf, "rb");
628 if (f) {
629 int ver;
630 ver = fgetc(f)<<24;
631 ver |= fgetc(f)<<16;
632 ver |= fgetc(f)<<8;
633 ver |= fgetc(f);
634 fclose(f);
635 if (ver == 6)
636 return "Wrecked 1.2.0";
637 }
638 return NULL;
639 }
640
641 static void load_wrecked_1_2(const char *dir, int verbose, int ac,
642 char **av)
643 {
644 if (ac > 1) {
645 fprintf(stderr, "Unrecognized option %s\n", av[1]);
646 usage(av[0]);
647 }
648 if (verbose)
649 fprintf(stderr, "Loading nick.db...\n");
650 m14_load_nick(dir, 6);
651 if (verbose)
652 fprintf(stderr, "Loading chan.db...\n");
653 m14_load_chan(dir, 6);
654 if (verbose)
655 fprintf(stderr, "Loading memo.db...\n");
656 m14_load_memo(dir, 6);
657 if (verbose)
658 fprintf(stderr, "Loading sop.db...\n");
659 m14_load_sop(dir, 6);
660 if (verbose)
661 fprintf(stderr, "Loading akill.db...\n");
662 m14_load_akill(dir, 6);
663 if (verbose)
664 fprintf(stderr, "Loading clone.db...\n");
665 m14_load_clone(dir, 6);
666 if (verbose)
667 fprintf(stderr, "Loading message.db...\n");
668 m14_load_message(dir, 6);
669 }
670
671 /*************************************************************************/
672 /*************************************************************************/
673
674 DBTypeInfo dbtype_magick_14b2 = {
675 "magick-1.4",
676 check_magick_14b2,
677 load_magick_14b2
678 };
679
680 DBTypeInfo dbtype_wrecked_1_2 = {
681 "wrecked-1.2",
682 check_wrecked_1_2,
683 load_wrecked_1_2
684 };
685
686 /*************************************************************************/
687
688 /*
689 * Local variables:
690 * c-file-style: "stroustrup"
691 * c-file-offsets: ((case-label . *) (statement-case-intro . *))
692 * indent-tabs-mode: nil
693 * End:
694 *
695 * vim: expandtab shiftwidth=4:
696 */