00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <stdlib.h>
00037 #include <string.h>
00038 #include <stdio.h>
00039 #include <fcntl.h>
00040 #include <ctype.h>
00041 #include <time.h>
00042
00043 #ifndef _WIN32
00044 #include <unistd.h>
00045 #else
00046 #include "sysconf.h"
00047 #include <windows.h>
00048 #endif
00049
00050
00051 #ifdef __sun
00052
00053
00054
00055 #undef u_int8_t
00056 #undef u_int16_t
00057 #undef u_int32_t
00058 #undef u_int_64_t
00059 #define u_int8_t uint8_t
00060 #define u_int16_t uint16_t
00061 #define u_int32_t uint32_t
00062 #define u_int64_t uint64_t
00063
00064 #ifndef INADDR_NONE
00065 #define INADDR_NONE (-1)
00066 #endif
00067
00068 #endif
00069
00070
00071
00072
00073 #define NICK_DB_1 "nick1.db"
00074 #define NICK_DB_2 "nick2.db"
00075 #define NICK_DB_NEW "nick.db"
00076
00077 #define CHAN_DB_1 "chan1.db"
00078 #define CHAN_DB_2 "chan2.db"
00079 #define CHAN_DB_NEW "chan.db"
00080
00081 #define BOT_DB_1 "bot1.db"
00082 #define BOT_DB_2 "bot2.db"
00083 #define BOT_DB_NEW "bot.db"
00084
00085 #define HOST_DB_1 "hosts1.db"
00086 #define HOST_DB_2 "hosts2.db"
00087 #define HOST_DB_NEW "hosts.db"
00088
00089
00090
00091 #ifndef _WIN32
00092 #define C_LBLUE "\033[1;34m"
00093 #define C_NONE "\033[m"
00094 #else
00095 #define C_LBLUE ""
00096 #define C_NONE ""
00097 #endif
00098
00099 #define getc_db(f) (fgetc((f)->fp))
00100 #define HASH(nick) ((tolower((nick)[0])&31)<<5 | (tolower((nick)[1])&31))
00101 #define HASH2(chan) ((chan)[1] ? ((chan)[1]&31)<<5 | ((chan)[2]&31) : 0)
00102 #define read_buffer(buf,f) (read_db((f),(buf),sizeof(buf)) == sizeof(buf))
00103 #define write_buffer(buf,f) (write_db((f),(buf),sizeof(buf)) == sizeof(buf))
00104 #define read_db(f,buf,len) (fread((buf),1,(len),(f)->fp))
00105 #define write_db(f,buf,len) (fwrite((buf),1,(len),(f)->fp))
00106 #define read_int8(ret,f) ((*(ret)=fgetc((f)->fp))==EOF ? -1 : 0)
00107 #define write_int8(val,f) (fputc((val),(f)->fp)==EOF ? -1 : 0)
00108 #define SAFE(x) do { \
00109 if ((x) < 0) { \
00110 printf("Error, the database is broken, trying to continue... no guarantee.\n"); \
00111 } \
00112 } while (0)
00113 #define READ(x) do { \
00114 if ((x) < 0) { \
00115 printf("Error, the database is broken, trying to continue... no guarantee.\n"); \
00116 exit(0); \
00117 } \
00118 } while (0)
00119
00120 typedef int16_t int16;
00121 typedef u_int16_t uint16;
00122 typedef int32_t int32;
00123 typedef u_int32_t uint32;
00124 typedef struct memo_ Memo;
00125 typedef struct dbFILE_ dbFILE;
00126 typedef struct nickalias_ NickAlias;
00127 typedef struct nickcore_ NickCore;
00128 typedef struct chaninfo_ ChannelInfo;
00129 typedef struct botinfo_ BotInfo;
00130 typedef struct badword_ BadWord;
00131 typedef struct hostcore_ HostCore;
00132
00133 struct memo_ {
00134 uint32 number;
00135 uint16 flags;
00136 time_t time;
00137 char sender[32];
00138 char *text;
00139 };
00140
00141 struct dbFILE_ {
00142 int mode;
00143 FILE *fp;
00144 char filename[1024];
00145 };
00146
00147 typedef struct {
00148 int16 memocount;
00149 int16 memomax;
00150 Memo *memos;
00151 } MemoInfo;
00152
00153 typedef struct {
00154 uint16 in_use;
00155 int16 level;
00156 NickCore *nc;
00157 time_t last_seen;
00158 } ChanAccess;
00159
00160 typedef struct {
00161 int16 in_use;
00162 int16 is_nick;
00163 uint16 flags;
00164 union {
00165 char *mask;
00166 NickCore *nc;
00167 } u;
00168 char *reason;
00169 char *creator;
00170 time_t addtime;
00171 } AutoKick;
00172
00173 struct nickalias_ {
00174 NickAlias *next, *prev;
00175 char *nick;
00176 char *last_quit;
00177 char *last_realname;
00178 char *last_usermask;
00179 time_t time_registered;
00180 time_t last_seen;
00181 uint16 status;
00182 NickCore *nc;
00183 };
00184
00185 struct nickcore_ {
00186 NickCore *next, *prev;
00187
00188 char *display;
00189 char pass[32];
00190 char *email;
00191 char *greet;
00192 uint32 icq;
00193 char *url;
00194 uint32 flags;
00195 uint16 language;
00196 uint16 accesscount;
00197 char **access;
00198 MemoInfo memos;
00199 uint16 channelcount;
00200 uint16 channelmax;
00201 int unused;
00202 int aliascount;
00203 };
00204
00205 struct chaninfo_ {
00206 ChannelInfo *next, *prev;
00207
00208 char name[64];
00209 char *founder;
00210 char *successor;
00211 char founderpass[32];
00212 char *desc;
00213 char *url;
00214 char *email;
00215 time_t time_registered;
00216 time_t last_used;
00217 char *last_topic;
00218 char last_topic_setter[32];
00219 time_t last_topic_time;
00220 uint32 flags;
00221 char *forbidby;
00222 char *forbidreason;
00223 int16 bantype;
00224 int16 *levels;
00225 uint16 accesscount;
00226 ChanAccess *access;
00227 uint16 akickcount;
00228 AutoKick *akick;
00229 uint32 mlock_on, mlock_off;
00230 uint32 mlock_limit;
00231 char *mlock_key;
00232 char *mlock_flood;
00233 char *mlock_redirect;
00234 char *entry_message;
00235 MemoInfo memos;
00236 char *bi;
00237 uint32 botflags;
00238 int16 *ttb;
00239 uint16 bwcount;
00240 BadWord *badwords;
00241 int16 capsmin, capspercent;
00242 int16 floodlines, floodsecs;
00243 int16 repeattimes;
00244 };
00245
00246 struct botinfo_ {
00247 BotInfo *next, *prev;
00248 char *nick;
00249 char *user;
00250 char *host;
00251 char *real;
00252 int16 flags;
00253 time_t created;
00254 int16 chancount;
00255 };
00256
00257 struct badword_ {
00258 uint16 in_use;
00259 char *word;
00260 uint16 type;
00261 };
00262
00263 struct hostcore_ {
00264 HostCore *next, *last;
00265 char *nick;
00266 char *vIdent;
00267 char *vHost;
00268 char *creator;
00269 time_t time;
00270 };
00271
00272 dbFILE *open_db_write(const char *service, const char *filename, int version);
00273 dbFILE *open_db_read(const char *service, const char *filename, int version);
00274 NickCore *findcore(const char *nick, int version);
00275 NickAlias *findnick(const char *nick);
00276 BotInfo *findbot(char *nick);
00277 ChannelInfo *cs_findchan(const char *chan);
00278 char *strscpy(char *d, const char *s, size_t len);
00279 int write_file_version(dbFILE * f, uint32 version);
00280 int mystricmp(const char *s1, const char *s2);
00281 int delnick(NickAlias *na, int donttouchthelist);
00282 int write_string(const char *s, dbFILE * f);
00283 int write_ptr(const void *ptr, dbFILE * f);
00284 int read_int16(int16 * ret, dbFILE * f);
00285 int read_int32(int32 * ret, dbFILE * f);
00286 int read_uint16(uint16 * ret, dbFILE * f);
00287 int read_uint32(uint32 * ret, dbFILE * f);
00288 int read_string(char **ret, dbFILE * f);
00289 int write_int16(uint16 val, dbFILE * f);
00290 int write_int32(uint32 val, dbFILE * f);
00291 int read_ptr(void **ret, dbFILE * f);
00292 int delcore(NickCore *nc);
00293 void alpha_insert_chan(ChannelInfo * ci);
00294 void insert_bot(BotInfo * bi);
00295 void close_db(dbFILE * f);
00296
00297 ChannelInfo *chanlists[256];
00298 NickAlias *nalists[1024];
00299 NickCore *nclists[1024];
00300 BotInfo *botlists[256];
00301
00302 int preferfirst = 0, prefersecond = 0, preferoldest = 0, prefernewest = 0;
00303 int nonick = 0, nochan = 0, nobot = 0, nohost = 0;
00304
00305 int main(int argc, char *argv[])
00306 {
00307 dbFILE *f;
00308 int i;
00309 NickCore *nc, *ncnext;
00310 HostCore *firsthc = NULL;
00311
00312 printf("\n"C_LBLUE"DB Merger for Anope IRC Services"C_NONE"\n");
00313
00314 if (argc >= 2) {
00315 if (!mystricmp(argv[1], "--PREFEROLDEST")) {
00316 printf("Preferring oldest database entries on collision.\n");
00317 preferoldest = 1;
00318 } else if (!mystricmp(argv[1], "--PREFERFIRST")) {
00319 printf("Preferring first database's entries on collision .\n");
00320 preferfirst = 1;
00321 } else if (!mystricmp(argv[1], "--PREFERSECOND")) {
00322 printf("Preferring second database's entries on collision.\n");
00323 prefersecond = 1;
00324 } else if (!mystricmp(argv[1], "--PREFERNEWEST")) {
00325 printf("Preferring newest database entries on collision.\n");
00326 prefernewest = 1;
00327 }
00328 }
00329
00330
00331
00332 if ((f = open_db_read("NickServ", NICK_DB_1, 14))) {
00333
00334 NickAlias *na, **nalast, *naprev;
00335 NickCore *nc, **nclast, *ncprev;
00336 int16 tmp16;
00337 int32 tmp32;
00338 int i, j, c;
00339
00340 printf("Trying to merge nicks...\n");
00341
00342
00343 for (i = 0; i < 1024; i++) {
00344 nclast = &nclists[i];
00345 ncprev = NULL;
00346
00347 while ((c = getc_db(f)) == 1) {
00348 if (c != 1) {
00349 printf("Invalid format in %s.\n", NICK_DB_1);
00350 exit(0);
00351 }
00352
00353 nc = calloc(1, sizeof(NickCore));
00354 nc->aliascount = 0;
00355 nc->unused = 0;
00356
00357 *nclast = nc;
00358 nclast = &nc->next;
00359 nc->prev = ncprev;
00360 ncprev = nc;
00361
00362 READ(read_string(&nc->display, f));
00363 READ(read_buffer(nc->pass, f));
00364 READ(read_string(&nc->email, f));
00365 READ(read_string(&nc->greet, f));
00366 READ(read_uint32(&nc->icq, f));
00367 READ(read_string(&nc->url, f));
00368 READ(read_uint32(&nc->flags, f));
00369 READ(read_uint16(&nc->language, f));
00370 READ(read_uint16(&nc->accesscount, f));
00371 if (nc->accesscount) {
00372 char **access;
00373 access = calloc(sizeof(char *) * nc->accesscount, 1);
00374 nc->access = access;
00375 for (j = 0; j < nc->accesscount; j++, access++)
00376 READ(read_string(access, f));
00377 }
00378 READ(read_int16(&nc->memos.memocount, f));
00379 READ(read_int16(&nc->memos.memomax, f));
00380 if (nc->memos.memocount) {
00381 Memo *memos;
00382 memos = calloc(sizeof(Memo) * nc->memos.memocount, 1);
00383 nc->memos.memos = memos;
00384 for (j = 0; j < nc->memos.memocount; j++, memos++) {
00385 READ(read_uint32(&memos->number, f));
00386 READ(read_uint16(&memos->flags, f));
00387 READ(read_int32(&tmp32, f));
00388 memos->time = tmp32;
00389 READ(read_buffer(memos->sender, f));
00390 READ(read_string(&memos->text, f));
00391 }
00392 }
00393 READ(read_uint16(&nc->channelcount, f));
00394 READ(read_int16(&tmp16, f));
00395 }
00396 *nclast = NULL;
00397 }
00398
00399
00400 for (i = 0; i < 1024; i++) {
00401 char *s = NULL;
00402
00403 nalast = &nalists[i];
00404 naprev = NULL;
00405
00406 while ((c = getc_db(f)) == 1) {
00407 if (c != 1) {
00408 printf("Invalid format in %s.\n", NICK_DB_1);
00409 exit(0);
00410 }
00411
00412 na = calloc(1, sizeof(NickAlias));
00413
00414 READ(read_string(&na->nick, f));
00415 READ(read_string(&na->last_usermask, f));
00416 READ(read_string(&na->last_realname, f));
00417 READ(read_string(&na->last_quit, f));
00418
00419 READ(read_int32(&tmp32, f));
00420 na->time_registered = tmp32;
00421 READ(read_int32(&tmp32, f));
00422 na->last_seen = tmp32;
00423 READ(read_uint16(&na->status, f));
00424 READ(read_string(&s, f));
00425 na->nc = findcore(s, 0);
00426 na->nc->aliascount++;
00427 free(s);
00428
00429 *nalast = na;
00430 nalast = &na->next;
00431 na->prev = naprev;
00432 naprev = na;
00433 }
00434 *nalast = NULL;
00435 }
00436 close_db(f);
00437 } else
00438 nonick = 1;
00439
00440
00441 if (!nonick) {
00442 if ((f = open_db_read("NickServ", NICK_DB_2, 14))) {
00443
00444 NickAlias *na, *naptr;
00445 NickCore *nc;
00446 int16 tmp16;
00447 int32 tmp32;
00448 int i, j, index, c;
00449
00450
00451 for (i = 0; i < 1024; i++) {
00452
00453 while ((c = getc_db(f)) == 1) {
00454 if (c != 1) {
00455 printf("Invalid format in %s.\n", NICK_DB_2);
00456 exit(0);
00457 }
00458
00459 nc = calloc(1, sizeof(NickCore));
00460 READ(read_string(&nc->display, f));
00461 READ(read_buffer(nc->pass, f));
00462 READ(read_string(&nc->email, f));
00463
00464 naptr = findnick(nc->display);
00465 if (naptr)
00466 nc->unused = 1;
00467 else
00468 nc->unused = 0;
00469
00470 nc->aliascount = 0;
00471
00472 index = HASH(nc->display);
00473 nc->prev = NULL;
00474 nc->next = nclists[index];
00475 if (nc->next)
00476 nc->next->prev = nc;
00477 nclists[index] = nc;
00478
00479 READ(read_string(&nc->greet, f));
00480 READ(read_uint32(&nc->icq, f));
00481 READ(read_string(&nc->url, f));
00482 READ(read_uint32(&nc->flags, f));
00483 READ(read_uint16(&nc->language, f));
00484 READ(read_uint16(&nc->accesscount, f));
00485 if (nc->accesscount) {
00486 char **access;
00487 access = calloc(sizeof(char *) * nc->accesscount, 1);
00488 nc->access = access;
00489 for (j = 0; j < nc->accesscount; j++, access++)
00490 READ(read_string(access, f));
00491 }
00492 READ(read_int16(&nc->memos.memocount, f));
00493 READ(read_int16(&nc->memos.memomax, f));
00494 if (nc->memos.memocount) {
00495 Memo *memos;
00496 memos = calloc(sizeof(Memo) * nc->memos.memocount, 1);
00497 nc->memos.memos = memos;
00498 for (j = 0; j < nc->memos.memocount; j++, memos++) {
00499 READ(read_uint32(&memos->number, f));
00500 READ(read_uint16(&memos->flags, f));
00501 READ(read_int32(&tmp32, f));
00502 memos->time = tmp32;
00503 READ(read_buffer(memos->sender, f));
00504 READ(read_string(&memos->text, f));
00505 }
00506 }
00507 READ(read_uint16(&nc->channelcount, f));
00508 READ(read_int16(&tmp16, f));
00509 }
00510 }
00511
00512
00513 for (i = 0; i < 1024; i++) {
00514 char *s = NULL;
00515 NickAlias *ptr, *prev, *naptr;
00516
00517 while ((c = getc_db(f)) == 1) {
00518 if (c != 1) {
00519 printf("Invalid format in %s.\n", NICK_DB_2);
00520 exit(0);
00521 }
00522
00523 na = calloc(1, sizeof(NickAlias));
00524
00525 READ(read_string(&na->nick, f));
00526 READ(read_string(&na->last_usermask, f));
00527 READ(read_string(&na->last_realname, f));
00528 READ(read_string(&na->last_quit, f));
00529 READ(read_int32(&tmp32, f));
00530 na->time_registered = tmp32;
00531 READ(read_int32(&tmp32, f));
00532 na->last_seen = tmp32;
00533 READ(read_uint16(&na->status, f));
00534 READ(read_string(&s, f));
00535
00536 naptr = findnick(na->nick);
00537 if (naptr) {
00538 char input[1024];
00539 NickCore *ncptr = findcore(na->nick, 1); ;
00540
00541 if (!ncptr) {
00542 printf("\n\n WARNING! Malformed database. No nickcore for nick %s, droping it.\n\n\n", na->nick);
00543 delnick(na, 1);
00544 } else {
00545 if (!preferoldest && !preferfirst && !prefersecond && !prefernewest) {
00546 printf("Nick collision for nick %s:\n\n", na->nick);
00547 printf("Group 1: %s (%s)\n", naptr->nc->display, naptr->nc->email);
00548 printf("Time registered: %s\n", ctime(&naptr->time_registered));
00549 printf("Group 2: %s (%s)\n", ncptr->display, ncptr->email);
00550 printf("Time registered: %s\n", ctime(&na->time_registered));
00551 printf("What group do you want to keep? Enter the related group number \"1\" or \"2\".\n");
00552 }
00553
00554 if (preferoldest) {
00555 input[0] = (na->time_registered > naptr->time_registered) ? '1' : '2';
00556 } else if (prefernewest) {
00557 input[0] = (na->time_registered > naptr->time_registered) ? '2' : '1';
00558 } else if (preferfirst) {
00559 input[0] = '1';
00560 } else if (prefersecond) {
00561 input[0] = '2';
00562 } else {
00563 waiting_for_input:
00564 scanf("%s", input);
00565 }
00566 if (input[0] == '1') {
00567 printf("Deleting nick alias %s (#2).\n", na->nick);
00568 delnick(na, 1);
00569 } else if (input[0] == '2') {
00570 printf("Deleting nick alias %s (#1).\n", naptr->nick);
00571 naptr->nc->aliascount--;
00572 delnick(naptr, 0);
00573 na->nc = ncptr;
00574 na->nc->aliascount++;
00575 index = HASH(na->nick);
00576 for (prev = NULL, ptr = nalists[index]; ptr && mystricmp(ptr->nick, na->nick) < 0; prev = ptr, ptr = ptr->next);
00577 na->prev = prev;
00578 na->next = ptr;
00579 if (!prev)
00580 nalists[index] = na;
00581 else
00582 prev->next = na;
00583 if (ptr)
00584 ptr->prev = na;
00585 } else {
00586 printf("Invalid number, give us a valid one (1 or 2).\n");
00587 goto waiting_for_input;
00588 }
00589 }
00590 } else {
00591 na->nc = findcore(s, 0);
00592 if (!na->nc) {
00593 printf("\n\n WARNING! Malformed database. No nickcore for nick %s, droping it.\n\n\n", na->nick);
00594 delnick(na, 1);
00595 } else {
00596 na->nc->aliascount++;
00597 index = HASH(na->nick);
00598 for (prev = NULL, ptr = nalists[index]; ptr && mystricmp(ptr->nick, na->nick) < 0; prev = ptr, ptr = ptr->next);
00599 na->prev = prev;
00600 na->next = ptr;
00601 if (!prev)
00602 nalists[index] = na;
00603 else
00604 prev->next = na;
00605 if (ptr)
00606 ptr->prev = na;
00607 }
00608 }
00609 free(s);
00610 }
00611 }
00612 close_db(f);
00613 } else
00614 nonick = 1;
00615 }
00616
00617
00618
00619 for (i = 0; i < 1024; i++) {
00620 for (nc = nclists[i]; nc; nc = ncnext) {
00621 ncnext = nc->next;
00622 if (nc->aliascount < 1) {
00623 printf("Deleting core %s (%s).\n", nc->display, nc->email);
00624 delcore(nc);
00625 }
00626 }
00627 }
00628
00629
00630 if (!nonick) {
00631 if ((f = open_db_write("NickServ", NICK_DB_NEW, 14))) {
00632
00633 NickAlias *na;
00634 NickCore *nc;
00635 char **access;
00636 Memo *memos;
00637 int i, j;
00638
00639
00640 for (i = 0; i < 1024; i++) {
00641 for (nc = nclists[i]; nc; nc = nc->next) {
00642 SAFE(write_int8(1, f));
00643 SAFE(write_string(nc->display, f));
00644 SAFE(write_buffer(nc->pass, f));
00645 SAFE(write_string(nc->email, f));
00646 SAFE(write_string(nc->greet, f));
00647 SAFE(write_int32(nc->icq, f));
00648 SAFE(write_string(nc->url, f));
00649 SAFE(write_int32(nc->flags, f));
00650 SAFE(write_int16(nc->language, f));
00651 SAFE(write_int16(nc->accesscount, f));
00652 for (j = 0, access = nc->access; j < nc->accesscount; j++, access++)
00653 SAFE(write_string(*access, f));
00654
00655 SAFE(write_int16(nc->memos.memocount, f));
00656 SAFE(write_int16(nc->memos.memomax, f));
00657 memos = nc->memos.memos;
00658 for (j = 0; j < nc->memos.memocount; j++, memos++) {
00659 SAFE(write_int32(memos->number, f));
00660 SAFE(write_int16(memos->flags, f));
00661 SAFE(write_int32(memos->time, f));
00662 SAFE(write_buffer(memos->sender, f));
00663 SAFE(write_string(memos->text, f));
00664 }
00665 SAFE(write_int16(nc->channelcount, f));
00666 SAFE(write_int16(nc->channelmax, f));
00667 }
00668 SAFE(write_int8(0, f));
00669 }
00670
00671
00672 for (i = 0; i < 1024; i++) {
00673 for (na = nalists[i]; na; na = na->next) {
00674 SAFE(write_int8(1, f));
00675 SAFE(write_string(na->nick, f));
00676 SAFE(write_string(na->last_usermask, f));
00677 SAFE(write_string(na->last_realname, f));
00678 SAFE(write_string(na->last_quit, f));
00679 SAFE(write_int32(na->time_registered, f));
00680 SAFE(write_int32(na->last_seen, f));
00681 SAFE(write_int16(na->status, f));
00682 SAFE(write_string(na->nc->display, f));
00683
00684 }
00685 SAFE(write_int8(0, f));
00686 }
00687 close_db(f);
00688 printf("Nick merging done. New database saved as %s.\n", NICK_DB_NEW);
00689 }
00690 }
00691
00692
00693
00694 if ((f = open_db_read("ChanServ", CHAN_DB_1, 16))) {
00695 ChannelInfo *ci, **last, *prev;
00696 int c;
00697
00698 printf("Trying to merge channels...\n");
00699
00700 for (i = 0; i < 256; i++) {
00701 int16 tmp16;
00702 int32 tmp32;
00703 int n_levels;
00704 char *s;
00705 int n_ttb;
00706
00707
00708
00709
00710 last = &chanlists[i];
00711 prev = NULL;
00712
00713 while ((c = getc_db(f)) == 1) {
00714 int j;
00715
00716 if (c != 1) {
00717 printf("Invalid format in %s.\n", CHAN_DB_1);
00718 exit(0);
00719 }
00720
00721 ci = calloc(sizeof(ChannelInfo), 1);
00722 *last = ci;
00723 last = &ci->next;
00724 ci->prev = prev;
00725 prev = ci;
00726 READ(read_buffer(ci->name, f));
00727 READ(read_string(&ci->founder, f));
00728 READ(read_string(&ci->successor, f));
00729 READ(read_buffer(ci->founderpass, f));
00730 READ(read_string(&ci->desc, f));
00731 if (!ci->desc)
00732 ci->desc = strdup("");
00733 READ(read_string(&ci->url, f));
00734 READ(read_string(&ci->email, f));
00735 READ(read_int32(&tmp32, f));
00736 ci->time_registered = tmp32;
00737 READ(read_int32(&tmp32, f));
00738 ci->last_used = tmp32;
00739 READ(read_string(&ci->last_topic, f));
00740 READ(read_buffer(ci->last_topic_setter, f));
00741 READ(read_int32(&tmp32, f));
00742 ci->last_topic_time = tmp32;
00743 READ(read_uint32(&ci->flags, f));
00744
00745 ci->flags &= ~0x80000000;
00746 READ(read_string(&ci->forbidby, f));
00747 READ(read_string(&ci->forbidreason, f));
00748 READ(read_int16(&tmp16, f));
00749 ci->bantype = tmp16;
00750 READ(read_int16(&tmp16, f));
00751 n_levels = tmp16;
00752 ci->levels = calloc(36 * sizeof(*ci->levels), 1);
00753 for (j = 0; j < n_levels; j++) {
00754 if (j < 36)
00755 READ(read_int16(&ci->levels[j], f));
00756 else
00757 READ(read_int16(&tmp16, f));
00758 }
00759 READ(read_uint16(&ci->accesscount, f));
00760 if (ci->accesscount) {
00761 ci->access = calloc(ci->accesscount, sizeof(ChanAccess));
00762 for (j = 0; j < ci->accesscount; j++) {
00763 READ(read_uint16(&ci->access[j].in_use, f));
00764 if (ci->access[j].in_use) {
00765 READ(read_int16(&ci->access[j].level, f));
00766 READ(read_string(&s, f));
00767 if (s) {
00768 ci->access[j].nc = findcore(s, 0);
00769 free(s);
00770 }
00771 if (ci->access[j].nc == NULL)
00772 ci->access[j].in_use = 0;
00773 READ(read_int32(&tmp32, f));
00774 ci->access[j].last_seen = tmp32;
00775 }
00776 }
00777 } else {
00778 ci->access = NULL;
00779 }
00780 READ(read_uint16(&ci->akickcount, f));
00781 if (ci->akickcount) {
00782 ci->akick = calloc(ci->akickcount, sizeof(AutoKick));
00783 for (j = 0; j < ci->akickcount; j++) {
00784 SAFE(read_uint16(&ci->akick[j].flags, f));
00785 if (ci->akick[j].flags & 0x0001) {
00786 SAFE(read_string(&s, f));
00787 if (ci->akick[j].flags & 0x0002) {
00788 ci->akick[j].u.nc = findcore(s, 0);
00789 if (!ci->akick[j].u.nc)
00790 ci->akick[j].flags &= ~0x0001;
00791 free(s);
00792 } else {
00793 ci->akick[j].u.mask = s;
00794 }
00795 SAFE(read_string(&s, f));
00796 if (ci->akick[j].flags & 0x0001)
00797 ci->akick[j].reason = s;
00798 else if (s)
00799 free(s);
00800 SAFE(read_string(&s, f));
00801 if (ci->akick[j].flags & 0x0001) {
00802 ci->akick[j].creator = s;
00803 } else if (s) {
00804 free(s);
00805 }
00806 SAFE(read_int32(&tmp32, f));
00807 if (ci->akick[j].flags & 0x0001)
00808 ci->akick[j].addtime = tmp32;
00809 }
00810 }
00811 } else {
00812 ci->akick = NULL;
00813 }
00814 READ(read_uint32(&ci->mlock_on, f));
00815 READ(read_uint32(&ci->mlock_off, f));
00816 READ(read_uint32(&ci->mlock_limit, f));
00817 READ(read_string(&ci->mlock_key, f));
00818 READ(read_string(&ci->mlock_flood, f));
00819 READ(read_string(&ci->mlock_redirect, f));
00820 READ(read_int16(&ci->memos.memocount, f));
00821 READ(read_int16(&ci->memos.memomax, f));
00822 if (ci->memos.memocount) {
00823 Memo *memos;
00824 memos = calloc(sizeof(Memo) * ci->memos.memocount, 1);
00825 ci->memos.memos = memos;
00826 for (j = 0; j < ci->memos.memocount; j++, memos++) {
00827 READ(read_uint32(&memos->number, f));
00828 READ(read_uint16(&memos->flags, f));
00829 READ(read_int32(&tmp32, f));
00830 memos->time = tmp32;
00831 READ(read_buffer(memos->sender, f));
00832 READ(read_string(&memos->text, f));
00833 }
00834 }
00835 READ(read_string(&ci->entry_message, f));
00836
00837
00838 READ(read_string(&ci->bi, f));
00839 READ(read_int32(&tmp32, f));
00840 ci->botflags = tmp32;
00841 READ(read_int16(&tmp16, f));
00842 n_ttb = tmp16;
00843 ci->ttb = calloc(2 * 8, 1);
00844 for (j = 0; j < n_ttb; j++) {
00845 if (j < 8)
00846 READ(read_int16(&ci->ttb[j], f));
00847 else
00848 READ(read_int16(&tmp16, f));
00849 }
00850 for (j = n_ttb; j < 8; j++)
00851 ci->ttb[j] = 0;
00852 READ(read_int16(&tmp16, f));
00853 ci->capsmin = tmp16;
00854 READ(read_int16(&tmp16, f));
00855 ci->capspercent = tmp16;
00856 READ(read_int16(&tmp16, f));
00857 ci->floodlines = tmp16;
00858 READ(read_int16(&tmp16, f));
00859 ci->floodsecs = tmp16;
00860 READ(read_int16(&tmp16, f));
00861 ci->repeattimes = tmp16;
00862
00863 READ(read_uint16(&ci->bwcount, f));
00864 if (ci->bwcount) {
00865 ci->badwords = calloc(ci->bwcount, sizeof(BadWord));
00866 for (j = 0; j < ci->bwcount; j++) {
00867 SAFE(read_uint16(&ci->badwords[j].in_use, f));
00868 if (ci->badwords[j].in_use) {
00869 SAFE(read_string(&ci->badwords[j].word, f));
00870 SAFE(read_uint16(&ci->badwords[j].type, f));
00871 }
00872 }
00873 } else {
00874 ci->badwords = NULL;
00875 }
00876 }
00877 *last = NULL;
00878 }
00879 close_db(f);
00880 } else
00881 nochan = 1;
00882
00883
00884 if (!nochan) {
00885 if ((f = open_db_read("ChanServ", CHAN_DB_2, 16))) {
00886 int c;
00887
00888 for (i = 0; i < 256; i++) {
00889 int16 tmp16;
00890 int32 tmp32;
00891 int n_levels;
00892 char *s;
00893 int n_ttb;
00894
00895
00896
00897
00898
00899
00900 while ((c = getc_db(f)) == 1) {
00901 ChannelInfo *ci = NULL, *ciptr = NULL;
00902 int j;
00903
00904 if (c != 1) {
00905 printf("Invalid format in %s.\n", CHAN_DB_2);
00906 exit(0);
00907 }
00908
00909 ci = calloc(sizeof(ChannelInfo), 1);
00910 READ(read_buffer(ci->name, f));
00911 READ(read_string(&ci->founder, f));
00912 READ(read_string(&ci->successor, f));
00913 READ(read_buffer(ci->founderpass, f));
00914 READ(read_string(&ci->desc, f));
00915 if (!ci->desc)
00916 ci->desc = strdup("");
00917 READ(read_string(&ci->url, f));
00918 READ(read_string(&ci->email, f));
00919 READ(read_int32(&tmp32, f));
00920 ci->time_registered = tmp32;
00921 READ(read_int32(&tmp32, f));
00922 ci->last_used = tmp32;
00923 READ(read_string(&ci->last_topic, f));
00924 READ(read_buffer(ci->last_topic_setter, f));
00925 READ(read_int32(&tmp32, f));
00926 ci->last_topic_time = tmp32;
00927 READ(read_uint32(&ci->flags, f));
00928
00929 ci->flags &= ~0x80000000;
00930 READ(read_string(&ci->forbidby, f));
00931 READ(read_string(&ci->forbidreason, f));
00932 READ(read_int16(&tmp16, f));
00933 ci->bantype = tmp16;
00934 READ(read_int16(&tmp16, f));
00935 n_levels = tmp16;
00936 ci->levels = calloc(36 * sizeof(*ci->levels), 1);
00937 for (j = 0; j < n_levels; j++) {
00938 if (j < 36)
00939 READ(read_int16(&ci->levels[j], f));
00940 else
00941 READ(read_int16(&tmp16, f));
00942 }
00943 READ(read_uint16(&ci->accesscount, f));
00944 if (ci->accesscount) {
00945 ci->access = calloc(ci->accesscount, sizeof(ChanAccess));
00946 for (j = 0; j < ci->accesscount; j++) {
00947 READ(read_uint16(&ci->access[j].in_use, f));
00948 if (ci->access[j].in_use) {
00949 READ(read_int16(&ci->access[j].level, f));
00950 READ(read_string(&s, f));
00951 if (s) {
00952 ci->access[j].nc = findcore(s, 0);
00953 free(s);
00954 }
00955 if (ci->access[j].nc == NULL)
00956 ci->access[j].in_use = 0;
00957 READ(read_int32(&tmp32, f));
00958 ci->access[j].last_seen = tmp32;
00959 }
00960 }
00961 } else {
00962 ci->access = NULL;
00963 }
00964 READ(read_uint16(&ci->akickcount, f));
00965 if (ci->akickcount) {
00966 ci->akick = calloc(ci->akickcount, sizeof(AutoKick));
00967 for (j = 0; j < ci->akickcount; j++) {
00968 SAFE(read_uint16(&ci->akick[j].flags, f));
00969 if (ci->akick[j].flags & 0x0001) {
00970 SAFE(read_string(&s, f));
00971 if (ci->akick[j].flags & 0x0002) {
00972 ci->akick[j].u.nc = findcore(s, 0);
00973 if (!ci->akick[j].u.nc)
00974 ci->akick[j].flags &= ~0x0001;
00975 free(s);
00976 } else {
00977 ci->akick[j].u.mask = s;
00978 }
00979 SAFE(read_string(&s, f));
00980 if (ci->akick[j].flags & 0x0001)
00981 ci->akick[j].reason = s;
00982 else if (s)
00983 free(s);
00984 SAFE(read_string(&s, f));
00985 if (ci->akick[j].flags & 0x0001) {
00986 ci->akick[j].creator = s;
00987 } else if (s) {
00988 free(s);
00989 }
00990 SAFE(read_int32(&tmp32, f));
00991 if (ci->akick[j].flags & 0x0001)
00992 ci->akick[j].addtime = tmp32;
00993 }
00994 }
00995 } else {
00996 ci->akick = NULL;
00997 }
00998 READ(read_uint32(&ci->mlock_on, f));
00999 READ(read_uint32(&ci->mlock_off, f));
01000 READ(read_uint32(&ci->mlock_limit, f));
01001 READ(read_string(&ci->mlock_key, f));
01002 READ(read_string(&ci->mlock_flood, f));
01003 READ(read_string(&ci->mlock_redirect, f));
01004 READ(read_int16(&ci->memos.memocount, f));
01005 READ(read_int16(&ci->memos.memomax, f));
01006 if (ci->memos.memocount) {
01007 Memo *memos;
01008 memos = calloc(sizeof(Memo) * ci->memos.memocount, 1);
01009 ci->memos.memos = memos;
01010 for (j = 0; j < ci->memos.memocount; j++, memos++) {
01011 READ(read_uint32(&memos->number, f));
01012 READ(read_uint16(&memos->flags, f));
01013 READ(read_int32(&tmp32, f));
01014 memos->time = tmp32;
01015 READ(read_buffer(memos->sender, f));
01016 READ(read_string(&memos->text, f));
01017 }
01018 }
01019 READ(read_string(&ci->entry_message, f));
01020
01021
01022 READ(read_string(&ci->bi, f));
01023 READ(read_int32(&tmp32, f));
01024 ci->botflags = tmp32;
01025 READ(read_int16(&tmp16, f));
01026 n_ttb = tmp16;
01027 ci->ttb = calloc(32, 1);
01028 for (j = 0; j < n_ttb; j++) {
01029 if (j < 8)
01030 READ(read_int16(&ci->ttb[j], f));
01031 else
01032 READ(read_int16(&tmp16, f));
01033 }
01034 for (j = n_ttb; j < 8; j++)
01035 ci->ttb[j] = 0;
01036 READ(read_int16(&tmp16, f));
01037 ci->capsmin = tmp16;
01038 READ(read_int16(&tmp16, f));
01039 ci->capspercent = tmp16;
01040 READ(read_int16(&tmp16, f));
01041 ci->floodlines = tmp16;
01042 READ(read_int16(&tmp16, f));
01043 ci->floodsecs = tmp16;
01044 READ(read_int16(&tmp16, f));
01045 ci->repeattimes = tmp16;
01046
01047 READ(read_uint16(&ci->bwcount, f));
01048 if (ci->bwcount) {
01049 ci->badwords = calloc(ci->bwcount, sizeof(BadWord));
01050 for (j = 0; j < ci->bwcount; j++) {
01051 SAFE(read_uint16(&ci->badwords[j].in_use, f));
01052 if (ci->badwords[j].in_use) {
01053 SAFE(read_string(&ci->badwords[j].word, f));
01054 SAFE(read_uint16(&ci->badwords[j].type, f));
01055 }
01056 }
01057 } else {
01058 ci->badwords = NULL;
01059 }
01060
01061 ciptr = cs_findchan(ci->name);
01062 if (ciptr) {
01063 char input[1024];
01064
01065 if (!preferoldest && !preferfirst && !prefersecond && !prefernewest) {
01066 printf("Chan collision for channel %s:\n\n", ci->name);
01067
01068 printf("Owner of channel 1: %s (%s)\n", (ciptr->founder) ? ciptr->founder : "none", (ciptr->email) ? ciptr->email : "no valid email");
01069 printf("Accesscount: %u\n", ciptr->accesscount);
01070 if (ciptr->flags & 0x00000080) {
01071 printf("Status: Channel is forbidden");
01072 } else if (ciptr->flags & 0x00010000) {
01073 printf("Status: Channel is suspended");
01074 }
01075 printf("Time registered: %s\n", ctime(&ciptr->time_registered));
01076
01077 printf("Owner of channel 2: %s (%s)\n", (ci->founder) ? ci->founder : "none", (ci->email) ? ci->email : "no valid email");
01078 printf("Accesscount: %u\n", ci->accesscount);
01079 if (ci->flags & 0x00000080) {
01080 printf("Status: Channel is forbidden");
01081 } else if (ci->flags & 0x00010000) {
01082 printf("Status: Channel is suspended");
01083 }
01084 printf("Time registered: %s\n", ctime(&ci->time_registered));
01085
01086 printf("What channel do you want to keep? Enter the related number \"1\" or \"2\".\n");
01087 }
01088
01089 if (preferoldest) {
01090 input[0] = (ci->time_registered > ciptr->time_registered) ? '1' : '2';
01091 } else if (prefernewest) {
01092 input[0] = (ci->time_registered > ciptr->time_registered) ? '2' : '1';
01093 } else if (preferfirst) {
01094 input[0] = '1';
01095 } else if (prefersecond) {
01096 input[0] = '2';
01097 } else {
01098 waiting_for_input4:
01099 scanf("%s", input);
01100 }
01101 if (input[0] == '1') {
01102 NickCore *nc = NULL;
01103 int i;
01104 printf("Deleting chan %s (#2).\n", ci->name);
01105
01106 if (ci->founder) {
01107 nc = findcore(ci->founder, 0);
01108 if (nc)
01109 nc->channelcount--;
01110 }
01111 free(ci->desc);
01112 free(ci->founder);
01113 free(ci->successor);
01114 if (ci->url)
01115 free(ci->url);
01116 if (ci->email)
01117 free(ci->email);
01118 if (ci->last_topic)
01119 free(ci->last_topic);
01120 if (ci->forbidby)
01121 free(ci->forbidby);
01122 if (ci->forbidreason)
01123 free(ci->forbidreason);
01124 if (ci->mlock_key)
01125 free(ci->mlock_key);
01126 if (ci->mlock_flood)
01127 free(ci->mlock_flood);
01128 if (ci->mlock_redirect)
01129 free(ci->mlock_redirect);
01130 if (ci->entry_message)
01131 free(ci->entry_message);
01132 if (ci->access)
01133 free(ci->access);
01134 for (i = 0; i < ci->akickcount; i++) {
01135 if (!(ci->akick[i].flags & 0x0002) && ci->akick[i].u.mask)
01136 free(ci->akick[i].u.mask);
01137 if (ci->akick[i].reason)
01138 free(ci->akick[i].reason);
01139 if (ci->akick[i].creator)
01140 free(ci->akick[i].creator);
01141 }
01142 if (ci->akick)
01143 free(ci->akick);
01144 if (ci->levels)
01145 free(ci->levels);
01146 if (ci->memos.memos) {
01147 for (i = 0; i < ci->memos.memocount; i++) {
01148 if (ci->memos.memos[i].text)
01149 free(ci->memos.memos[i].text);
01150 }
01151 free(ci->memos.memos);
01152 }
01153 if (ci->ttb)
01154 free(ci->ttb);
01155 for (i = 0; i < ci->bwcount; i++) {
01156 if (ci->badwords[i].word)
01157 free(ci->badwords[i].word);
01158 }
01159 if (ci->badwords)
01160 free(ci->badwords);
01161 if (ci->bi)
01162 free(ci->bi);
01163 free(ci);
01164
01165 } else if (input[0] == '2') {
01166 NickCore *nc = NULL;
01167 printf("Deleting chan %s (#1).\n", ciptr->name);
01168
01169 if (ciptr->next)
01170 ciptr->next->prev = ciptr->prev;
01171 if (ciptr->prev)
01172 ciptr->prev->next = ciptr->next;
01173 else
01174 chanlists[tolower(ciptr->name[1])] = ciptr->next;
01175
01176 if (ciptr->founder) {
01177 nc = findcore(ciptr->founder, 0);
01178 if (nc)
01179 nc->channelcount--;
01180 }
01181 free(ciptr->desc);
01182 if (ciptr->url)
01183 free(ciptr->url);
01184 if (ciptr->email)
01185 free(ciptr->email);
01186 if (ciptr->last_topic)
01187 free(ciptr->last_topic);
01188 if (ciptr->forbidby)
01189 free(ciptr->forbidby);
01190 if (ciptr->forbidreason)
01191 free(ciptr->forbidreason);
01192 if (ciptr->mlock_key)
01193 free(ciptr->mlock_key);
01194 if (ciptr->mlock_flood)
01195 free(ciptr->mlock_flood);
01196 if (ciptr->mlock_redirect)
01197 free(ciptr->mlock_redirect);
01198 if (ciptr->entry_message)
01199 free(ciptr->entry_message);
01200 if (ciptr->access)
01201 free(ciptr->access);
01202 for (i = 0; i < ciptr->akickcount; i++) {
01203 if (!(ciptr->akick[i].flags & 0x0002) && ciptr->akick[i].u.mask)
01204 free(ciptr->akick[i].u.mask);
01205 if (ciptr->akick[i].reason)
01206 free(ciptr->akick[i].reason);
01207 if (ciptr->akick[i].creator)
01208 free(ciptr->akick[i].creator);
01209 }
01210 if (ciptr->akick)
01211 free(ciptr->akick);
01212 if (ciptr->levels)
01213 free(ciptr->levels);
01214 if (ciptr->memos.memos) {
01215 for (i = 0; i < ciptr->memos.memocount; i++) {
01216 if (ciptr->memos.memos[i].text)
01217 free(ciptr->memos.memos[i].text);
01218 }
01219 free(ciptr->memos.memos);
01220 }
01221 if (ciptr->ttb)
01222 free(ciptr->ttb);
01223 for (i = 0; i < ciptr->bwcount; i++) {
01224 if (ciptr->badwords[i].word)
01225 free(ciptr->badwords[i].word);
01226 }
01227 if (ciptr->badwords)
01228 free(ciptr->badwords);
01229 free(ciptr);
01230
01231 alpha_insert_chan(ci);
01232
01233 } else {
01234 printf("Invalid number, give us a valid one (1 or 2).\n");
01235 goto waiting_for_input4;
01236 }
01237 } else {
01238 alpha_insert_chan(ci);
01239 }
01240 }
01241 }
01242 close_db(f);
01243 } else
01244 nochan = 1;
01245 }
01246
01247
01248 if (!nochan) {
01249 if ((f = open_db_write("ChanServ", CHAN_DB_NEW, 16))) {
01250 ChannelInfo *ci;
01251 Memo *memos;
01252
01253
01254
01255
01256 for (i = 0; i < 256; i++) {
01257 int16 tmp16;
01258 for (ci = chanlists[i]; ci; ci = ci->next) {
01259 int j;
01260 SAFE(write_int8(1, f));
01261 SAFE(write_buffer(ci->name, f));
01262 if (ci->founder)
01263 SAFE(write_string(ci->founder, f));
01264 else
01265 SAFE(write_string(NULL, f));
01266 if (ci->successor)
01267 SAFE(write_string(ci->successor, f));
01268 else
01269 SAFE(write_string(NULL, f));
01270 SAFE(write_buffer(ci->founderpass, f));
01271 SAFE(write_string(ci->desc, f));
01272 SAFE(write_string(ci->url, f));
01273 SAFE(write_string(ci->email, f));
01274 SAFE(write_int32(ci->time_registered, f));
01275 SAFE(write_int32(ci->last_used, f));
01276 SAFE(write_string(ci->last_topic, f));
01277 SAFE(write_buffer(ci->last_topic_setter, f));
01278 SAFE(write_int32(ci->last_topic_time, f));
01279 SAFE(write_int32(ci->flags, f));
01280 SAFE(write_string(ci->forbidby, f));
01281 SAFE(write_string(ci->forbidreason, f));
01282 SAFE(write_int16(ci->bantype, f));
01283 tmp16 = 36;
01284 SAFE(write_int16(tmp16, f));
01285 for (j = 0; j < 36; j++)
01286 SAFE(write_int16(ci->levels[j], f));
01287
01288 SAFE(write_int16(ci->accesscount, f));
01289 for (j = 0; j < ci->accesscount; j++) {
01290 SAFE(write_int16(ci->access[j].in_use, f));
01291 if (ci->access[j].in_use) {
01292 SAFE(write_int16(ci->access[j].level, f));
01293 SAFE(write_string(ci->access[j].nc->display, f));
01294 SAFE(write_int32(ci->access[j].last_seen, f));
01295 }
01296 }
01297 SAFE(write_int16(ci->akickcount, f));
01298 for (j = 0; j < ci->akickcount; j++) {
01299 SAFE(write_int16(ci->akick[j].flags, f));
01300 if (ci->akick[j].flags & 0x0001) {
01301 if (ci->akick[j].flags & 0x0002)
01302 SAFE(write_string(ci->akick[j].u.nc->display, f));
01303 else
01304 SAFE(write_string(ci->akick[j].u.mask, f));
01305 SAFE(write_string(ci->akick[j].reason, f));
01306 SAFE(write_string(ci->akick[j].creator, f));
01307 SAFE(write_int32(ci->akick[j].addtime, f));
01308 }
01309 }
01310
01311 SAFE(write_int32(ci->mlock_on, f));
01312 SAFE(write_int32(ci->mlock_off, f));
01313 SAFE(write_int32(ci->mlock_limit, f));
01314 SAFE(write_string(ci->mlock_key, f));
01315 SAFE(write_string(ci->mlock_flood, f));
01316 SAFE(write_string(ci->mlock_redirect, f));
01317 SAFE(write_int16(ci->memos.memocount, f));
01318 SAFE(write_int16(ci->memos.memomax, f));
01319 memos = ci->memos.memos;
01320 for (j = 0; j < ci->memos.memocount; j++, memos++) {
01321 SAFE(write_int32(memos->number, f));
01322 SAFE(write_int16(memos->flags, f));
01323 SAFE(write_int32(memos->time, f));
01324 SAFE(write_buffer(memos->sender, f));
01325 SAFE(write_string(memos->text, f));
01326 }
01327 SAFE(write_string(ci->entry_message, f));
01328 if (ci->bi)
01329 SAFE(write_string(ci->bi, f));
01330 else
01331 SAFE(write_string(NULL, f));
01332 SAFE(write_int32(ci->botflags, f));
01333 tmp16 = 8;
01334 SAFE(write_int16(tmp16, f));
01335 for (j = 0; j < 8; j++)
01336 SAFE(write_int16(ci->ttb[j], f));
01337 SAFE(write_int16(ci->capsmin, f));
01338 SAFE(write_int16(ci->capspercent, f));
01339 SAFE(write_int16(ci->floodlines, f));
01340 SAFE(write_int16(ci->floodsecs, f));
01341 SAFE(write_int16(ci->repeattimes, f));
01342
01343 SAFE(write_int16(ci->bwcount, f));
01344 for (j = 0; j < ci->bwcount; j++) {
01345 SAFE(write_int16(ci->badwords[j].in_use, f));
01346 if (ci->badwords[j].in_use) {
01347 SAFE(write_string(ci->badwords[j].word, f));
01348 SAFE(write_int16(ci->badwords[j].type, f));
01349 }
01350 }
01351 }
01352 SAFE(write_int8(0, f));
01353 }
01354 close_db(f);
01355 printf("Chan merging done. New database saved as %s.\n", CHAN_DB_NEW);
01356 }
01357 }
01358
01359
01360
01361 if ((f = open_db_read("Botserv", BOT_DB_1, 10))) {
01362 BotInfo *bi;
01363 int c;
01364 int32 tmp32;
01365 int16 tmp16;
01366
01367 printf("Trying to merge bots...\n");
01368
01369 while ((c = getc_db(f)) == 1) {
01370 if (c != 1) {
01371 printf("Invalid format in %s.\n", BOT_DB_1);
01372 exit(0);
01373 }
01374
01375 bi = calloc(sizeof(BotInfo), 1);
01376 READ(read_string(&bi->nick, f));
01377 READ(read_string(&bi->user, f));
01378 READ(read_string(&bi->host, f));
01379 READ(read_string(&bi->real, f));
01380 SAFE(read_int16(&tmp16, f));
01381 bi->flags = tmp16;
01382 READ(read_int32(&tmp32, f));
01383 bi->created = tmp32;
01384 READ(read_int16(&tmp16, f));
01385 bi->chancount = tmp16;
01386 insert_bot(bi);
01387 }
01388 } else
01389 nobot = 1;
01390
01391
01392 if (!nobot) {
01393 if ((f = open_db_read("Botserv", BOT_DB_2, 10))) {
01394 BotInfo *bi, *biptr;
01395 int c;
01396 int32 tmp32;
01397 int16 tmp16;
01398 char input[1024];
01399
01400 while ((c = getc_db(f)) == 1) {
01401 if (c != 1) {
01402 printf("Invalid format in %s.\n", BOT_DB_2);
01403 exit(0);
01404 }
01405
01406 bi = calloc(sizeof(BotInfo), 1);
01407 READ(read_string(&bi->nick, f));
01408 READ(read_string(&bi->user, f));
01409 READ(read_string(&bi->host, f));
01410 READ(read_string(&bi->real, f));
01411 SAFE(read_int16(&tmp16, f));
01412 bi->flags = tmp16;
01413 READ(read_int32(&tmp32, f));
01414 bi->created = tmp32;
01415 READ(read_int16(&tmp16, f));
01416 bi->chancount = tmp16;
01417 biptr = findbot(bi->nick);
01418 if (biptr) {
01419 if (!preferoldest && !preferfirst && !prefersecond && !prefernewest) {
01420 printf("Bot collision for botnick %s:\n\n", biptr->nick);
01421 printf("Bot 1: %s@%s (%s) is assigned to %d chans\n", biptr->user, biptr->host, biptr->real, biptr->chancount);
01422 printf("Time registered: %s\n", ctime(&biptr->created));
01423 printf("Bot 2: %s@%s (%s) is assigned to %d chans\n", bi->user, bi->host, bi->real, bi->chancount);
01424 printf("Time registered: %s\n", ctime(&bi->created));
01425 printf("What bot do you want to keep? Enter the related bot number \"1\" or \"2\".\n");
01426 }
01427
01428 if (preferoldest) {
01429 input[0] = (biptr->created > bi->created) ? '1' : '2';
01430 } else if (prefernewest) {
01431 input[0] = (biptr->created > bi->created) ? '2' : '1';
01432 } else if (preferfirst) {
01433 input[0] = '2';
01434 } else if (prefersecond) {
01435 input[0] = '1';
01436 } else {
01437 waiting_for_input3:
01438 scanf("%s", input);
01439 }
01440 if (input[0] == '1') {
01441 printf("Deleting Bot %s!%s@%s (%s) (#2).\n", bi->nick, bi->user, bi->host, bi->real);
01442 free(bi->nick);
01443 free(bi->user);
01444 free(bi->host);
01445 free(bi->real);
01446 free(bi);
01447 } else if (input[0] == '2') {
01448 printf("Deleting Bot %s!%s@%s (%s) (#1).\n", biptr->nick, biptr->user, biptr->host, biptr->real);
01449 if (biptr->next)
01450 biptr->next->prev = biptr->prev;
01451 if (biptr->prev)
01452 biptr->prev->next = biptr->next;
01453 else
01454 botlists[tolower(*biptr->nick)] = biptr->next;
01455 free(biptr->nick);
01456 free(biptr->user);
01457 free(biptr->host);
01458 free(biptr->real);
01459 free(biptr);
01460 insert_bot(bi);
01461 } else {
01462 printf("Invalid number, give us a valid one (1 or 2).\n");
01463 goto waiting_for_input3;
01464 }
01465 }
01466 else
01467 insert_bot(bi);
01468 }
01469 } else
01470 nobot = 1;
01471 }
01472
01473
01474 if (!nobot) {
01475 if ((f = open_db_write("Botserv", BOT_DB_NEW, 10))) {
01476 BotInfo *bi;
01477 for (i = 0; i < 256; i++) {
01478 for (bi = botlists[i]; bi; bi = bi->next) {
01479 SAFE(write_int8(1, f));
01480 SAFE(write_string(bi->nick, f));
01481 SAFE(write_string(bi->user, f));
01482 SAFE(write_string(bi->host, f));
01483 SAFE(write_string(bi->real, f));
01484 SAFE(write_int16(bi->flags, f));
01485 SAFE(write_int32(bi->created, f));
01486 SAFE(write_int16(bi->chancount, f));
01487 }
01488 }
01489 SAFE(write_int8(0, f));
01490 close_db(f);
01491 printf("Bot merging done. New database saved as %s.\n", BOT_DB_NEW);
01492 }
01493 }
01494
01495
01496
01497 if ((f = open_db_read("HostServ", HOST_DB_1, 3))) {
01498 HostCore *hc;
01499 int c;
01500 int32 tmp32;
01501
01502 printf("Trying to merge hosts...\n");
01503
01504 while ((c = getc_db(f)) == 1) {
01505 if (c != 1) {
01506 printf("Invalid format in %s.\n", HOST_DB_1);
01507 exit(0);
01508 }
01509 hc = calloc(1, sizeof(HostCore));
01510 READ(read_string(&hc->nick, f));
01511 READ(read_string(&hc->vIdent, f));
01512 READ(read_string(&hc->vHost, f));
01513 READ(read_string(&hc->creator, f));
01514 READ(read_int32(&tmp32, f));
01515 hc->time = tmp32;
01516 hc->next = firsthc;
01517 if (firsthc)
01518 firsthc->last = hc;
01519 hc->last = NULL;
01520 firsthc = hc;
01521 }
01522 } else
01523 nohost = 1;
01524
01525
01526 if (!nohost) {
01527 if ((f = open_db_read("HostServ", HOST_DB_2, 3))) {
01528 HostCore *hc, *hcptr;
01529 char input[1024];
01530 int32 tmp32;
01531 int c;
01532 int collision = 0;
01533
01534 while ((c = getc_db(f)) == 1) {
01535 if (c != 1) {
01536 printf("Invalid format in %s.\n", HOST_DB_2);
01537 exit(0);
01538 }
01539 collision = 0;
01540 hc = calloc(1, sizeof(HostCore));
01541 READ(read_string(&hc->nick, f));
01542 READ(read_string(&hc->vIdent, f));
01543 READ(read_string(&hc->vHost, f));
01544 READ(read_string(&hc->creator, f));
01545 READ(read_int32(&tmp32, f));
01546 hc->time = tmp32;
01547
01548 for (hcptr = firsthc; hcptr; hcptr = hcptr->next) {
01549 if (!mystricmp(hcptr->nick, hc->nick)) {
01550 collision++;
01551 if (!preferoldest && !preferfirst && !prefersecond && !prefernewest) {
01552 printf("vHost collision for nick %s:\n\n", hcptr->nick);
01553 printf("vHost 1: %s (vIdent: %s)\n", hcptr->vHost, (hcptr->vIdent) ? hcptr->vIdent : "none");
01554 printf("Time set: %s\n", ctime(&hcptr->time));
01555 printf("vHost 2: %s (vIdent: %s)\n", hc->vHost, (hc->vIdent) ? hc->vIdent : "none");
01556 printf("Time set: %s\n", ctime(&hc->time));
01557 printf("What vhost do you want to keep? Enter the related number \"1\" or \"2\".\n");
01558 }
01559 if (preferoldest) {
01560 input[0] = (hcptr->time > hc->time) ? '1' : '2';
01561 } else if (prefernewest) {
01562 input[0] = (hcptr->time > hc->time) ? '2' : '1';
01563 } else if (preferfirst) {
01564 input[0] = '1';
01565 } else if (prefersecond) {
01566 input[0] = '2';
01567 } else {
01568 waiting_for_input2:
01569 scanf("%s", input);
01570 }
01571 if (input[0] == '2') {
01572 printf("Deleting vHost %s (vIdent: %s) for nick %s (#1).\n", hcptr->vHost, (hcptr->vIdent) ? hcptr->vIdent : "none", hcptr->nick);
01573 free(hcptr->nick);
01574 hcptr->nick = hc->nick;
01575 free(hcptr->vHost);
01576 hcptr->vHost = hc->vHost;
01577 free(hcptr->vIdent);
01578 hcptr->vIdent = hc->vIdent;
01579 free(hcptr->creator);
01580 hcptr->creator = hc->creator;
01581 hcptr->time = hc->time;
01582 free(hc);
01583 } else if (input[0] == '1') {
01584 printf("Deleting vHost %s (vIdent: %s) for nick %s (#2).\n", hc->vHost, (hc->vIdent) ? hc->vIdent : "none", hc->nick);
01585 free(hc->nick);
01586 free(hc->vHost);
01587 free(hc->vIdent);
01588 free(hc->creator);
01589 free(hc);
01590 } else {
01591 printf("Invalid number, give us a valid one (1 or 2).\n");
01592 goto waiting_for_input2;
01593 }
01594 }
01595 }
01596 if (!collision) {
01597 hc->next = firsthc;
01598 if (firsthc)
01599 firsthc->last = hc;
01600 hc->last = NULL;
01601 firsthc = hc;
01602 }
01603 }
01604 } else
01605 nohost = 1;
01606 }
01607
01608
01609 if (!nohost) {
01610 if ((f = open_db_write("HostServ", HOST_DB_NEW, 3))) {
01611 HostCore *hcptr;
01612 for (hcptr = firsthc; hcptr; hcptr = hcptr->next) {
01613 SAFE(write_int8(1, f));
01614 SAFE(write_string(hcptr->nick, f));
01615 SAFE(write_string(hcptr->vIdent, f));
01616 SAFE(write_string(hcptr->vHost, f));
01617 SAFE(write_string(hcptr->creator, f));
01618 SAFE(write_int32(hcptr->time, f));
01619 }
01620 SAFE(write_int8(0, f));
01621 close_db(f);
01622 printf("Host merging done. New database saved as %s.\n", HOST_DB_NEW);
01623 }
01624 }
01625
01626
01627
01628 printf("\n\nMerging is now done. I give NO guarantee for your DBs.\n");
01629 return 0;
01630 }
01631
01632
01633 dbFILE *open_db_read(const char *service, const char *filename, int version)
01634 {
01635 dbFILE *f;
01636 FILE *fp;
01637 int myversion;
01638
01639 f = calloc(sizeof(*f), 1);
01640 if (!f) {
01641 printf("Can't allocate memory for %s database %s.\n", service, filename);
01642 exit(0);
01643 }
01644 strscpy(f->filename, filename, sizeof(f->filename));
01645 f->mode = 'r';
01646 fp = fopen(f->filename, "rb");
01647 if (!fp) {
01648 printf("Can't read %s database %s.\n", service, f->filename);
01649 free(f);
01650 return NULL;
01651 }
01652 f->fp = fp;
01653 myversion = fgetc(fp) << 24 | fgetc(fp) << 16 | fgetc(fp) << 8 | fgetc(fp);
01654 if (feof(fp)) {
01655 printf("Error reading version number on %s: End of file detected.\n", f->filename);
01656 exit(0);
01657 } else if (myversion < version) {
01658 printf("Unsuported database version (%d) on %s.\n", myversion, f->filename);
01659 exit(0);
01660 }
01661 return f;
01662 }
01663
01664
01665 dbFILE *open_db_write(const char *service, const char *filename, int version)
01666 {
01667 dbFILE *f;
01668 int fd;
01669
01670 f = calloc(sizeof(*f), 1);
01671 if (!f) {
01672 printf("Can't allocate memory for %s database %s.\n", service, filename);
01673 exit(0);
01674 }
01675 strscpy(f->filename, filename, sizeof(f->filename));
01676 filename = f->filename;
01677 #ifndef _WIN32
01678 unlink(filename);
01679 #else
01680 DeleteFile(filename);
01681 #endif
01682 f->mode = 'w';
01683 #ifndef _WIN32
01684 fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0666);
01685 #else
01686 fd = open(filename, O_WRONLY | O_CREAT | O_EXCL | _O_BINARY, 0666);
01687 #endif
01688 f->fp = fdopen(fd, "wb");
01689 if (!f->fp || !write_file_version(f, version)) {
01690 printf("Can't write to %s database %s.\n", service, filename);
01691 if (f->fp) {
01692 fclose(f->fp);
01693 #ifndef _WIN32
01694 unlink(filename);
01695 #else
01696 DeleteFile(filename);
01697 #endif
01698 }
01699 free(f);
01700 return NULL;
01701 }
01702 return f;
01703 }
01704
01705
01706 void close_db(dbFILE * f)
01707 {
01708 fclose(f->fp);
01709 free(f);
01710 }
01711
01712 int read_int16(int16 * ret, dbFILE * f)
01713 {
01714 int c1, c2;
01715
01716 c1 = fgetc(f->fp);
01717 c2 = fgetc(f->fp);
01718 if (c1 == EOF || c2 == EOF)
01719 return -1;
01720 *ret = c1 << 8 | c2;
01721 return 0;
01722 }
01723
01724 int read_uint16(uint16 * ret, dbFILE * f)
01725 {
01726 int c1, c2;
01727
01728 c1 = fgetc(f->fp);
01729 c2 = fgetc(f->fp);
01730 if (c1 == EOF || c2 == EOF)
01731 return -1;
01732 *ret = c1 << 8 | c2;
01733 return 0;
01734 }
01735
01736
01737 int write_int16(uint16 val, dbFILE * f)
01738 {
01739 if (fputc((val >> 8) & 0xFF, f->fp) == EOF
01740 || fputc(val & 0xFF, f->fp) == EOF)
01741 return -1;
01742 return 0;
01743 }
01744
01745 int read_int32(int32 * ret, dbFILE * f)
01746 {
01747 int c1, c2, c3, c4;
01748
01749 c1 = fgetc(f->fp);
01750 c2 = fgetc(f->fp);
01751 c3 = fgetc(f->fp);
01752 c4 = fgetc(f->fp);
01753 if (c1 == EOF || c2 == EOF || c3 == EOF || c4 == EOF)
01754 return -1;
01755 *ret = c1 << 24 | c2 << 16 | c3 << 8 | c4;
01756 return 0;
01757 }
01758
01759 int read_uint32(uint32 * ret, dbFILE * f)
01760 {
01761 int c1, c2, c3, c4;
01762
01763 c1 = fgetc(f->fp);
01764 c2 = fgetc(f->fp);
01765 c3 = fgetc(f->fp);
01766 c4 = fgetc(f->fp);
01767 if (c1 == EOF || c2 == EOF || c3 == EOF || c4 == EOF)
01768 return -1;
01769 *ret = c1 << 24 | c2 << 16 | c3 << 8 | c4;
01770 return 0;
01771 }
01772
01773 int write_int32(uint32 val, dbFILE * f)
01774 {
01775 if (fputc((val >> 24) & 0xFF, f->fp) == EOF)
01776 return -1;
01777 if (fputc((val >> 16) & 0xFF, f->fp) == EOF)
01778 return -1;
01779 if (fputc((val >> 8) & 0xFF, f->fp) == EOF)
01780 return -1;
01781 if (fputc((val) & 0xFF, f->fp) == EOF)
01782 return -1;
01783 return 0;
01784 }
01785
01786
01787 int read_ptr(void **ret, dbFILE * f)
01788 {
01789 int c;
01790
01791 c = fgetc(f->fp);
01792 if (c == EOF)
01793 return -1;
01794 *ret = (c ? (void *) 1 : (void *) 0);
01795 return 0;
01796 }
01797
01798 int write_ptr(const void *ptr, dbFILE * f)
01799 {
01800 if (fputc(ptr ? 1 : 0, f->fp) == EOF)
01801 return -1;
01802 return 0;
01803 }
01804
01805
01806 int read_string(char **ret, dbFILE * f)
01807 {
01808 char *s;
01809 uint16 len;
01810
01811 if (read_uint16(&len, f) < 0)
01812 return -1;
01813 if (len == 0) {
01814 *ret = NULL;
01815 return 0;
01816 }
01817 s = calloc(len, 1);
01818 if (len != fread(s, 1, len, f->fp)) {
01819 free(s);
01820 return -1;
01821 }
01822 *ret = s;
01823 return 0;
01824 }
01825
01826 int write_string(const char *s, dbFILE * f)
01827 {
01828 uint32 len;
01829
01830 if (!s)
01831 return write_int16(0, f);
01832 len = strlen(s);
01833 if (len > 65534)
01834 len = 65534;
01835 if (write_int16((uint16) (len + 1), f) < 0)
01836 return -1;
01837 if (len > 0 && fwrite(s, 1, len, f->fp) != len)
01838 return -1;
01839 if (fputc(0, f->fp) == EOF)
01840 return -1;
01841 return 0;
01842 }
01843
01844 NickCore *findcore(const char *nick, int unused)
01845 {
01846 NickCore *nc;
01847
01848 for (nc = nclists[HASH(nick)]; nc; nc = nc->next) {
01849 if (!mystricmp(nc->display, nick))
01850 if ((nc->unused && unused) || (!nc->unused && !unused))
01851 return nc;
01852 }
01853
01854 return NULL;
01855 }
01856
01857 NickAlias *findnick(const char *nick)
01858 {
01859 NickAlias *na;
01860
01861 for (na = nalists[HASH(nick)]; na; na = na->next) {
01862 if (!mystricmp(na->nick, nick))
01863 return na;
01864 }
01865
01866 return NULL;
01867 }
01868
01869 int write_file_version(dbFILE * f, uint32 version)
01870 {
01871 FILE *fp = f->fp;
01872 if (fputc(version >> 24 & 0xFF, fp) < 0 ||
01873 fputc(version >> 16 & 0xFF, fp) < 0 ||
01874 fputc(version >> 8 & 0xFF, fp) < 0 ||
01875 fputc(version & 0xFF, fp) < 0) {
01876 printf("Error writing version number on %s.\n", f->filename);
01877 exit(0);
01878 }
01879 return 1;
01880 }
01881
01882
01883
01884
01885
01886 char *strscpy(char *d, const char *s, size_t len)
01887 {
01888 char *d_orig = d;
01889
01890 if (!len)
01891 return d;
01892 while (--len && (*d++ = *s++));
01893 *d = '\0';
01894 return d_orig;
01895 }
01896
01897 int mystricmp(const char *s1, const char *s2)
01898 {
01899 register int c;
01900
01901 while ((c = tolower(*s1)) == tolower(*s2)) {
01902 if (c == 0)
01903 return 0;
01904 s1++;
01905 s2++;
01906 }
01907 if (c < tolower(*s2))
01908 return -1;
01909 return 1;
01910 }
01911
01912 int delnick(NickAlias *na, int donttouchthelist)
01913 {
01914 if (!donttouchthelist) {
01915
01916 if (na->next)
01917 na->next->prev = na->prev;
01918 if (na->prev)
01919 na->prev->next = na->next;
01920 else
01921 nalists[HASH(na->nick)] = na->next;
01922 }
01923
01924
01925 free(na->nick);
01926 if (na->last_usermask)
01927 free(na->last_usermask);
01928 if (na->last_realname)
01929 free(na->last_realname);
01930 if (na->last_quit)
01931 free(na->last_quit);
01932 free(na);
01933 return 1;
01934 }
01935
01936 int delcore(NickCore *nc)
01937 {
01938 int i;
01939
01940 if (nc->next)
01941 nc->next->prev = nc->prev;
01942 if (nc->prev)
01943 nc->prev->next = nc->next;
01944 else
01945 nclists[HASH(nc->display)] = nc->next;
01946
01947 free(nc->display);
01948 if (nc->email)
01949 free(nc->email);
01950 if (nc->greet)
01951 free(nc->greet);
01952 if (nc->url)
01953 free(nc->url);
01954 if (nc->access) {
01955 for (i = 0; i < nc->accesscount; i++) {
01956 if (nc->access[i])
01957 free(nc->access[i]);
01958 }
01959 free(nc->access);
01960 }
01961 if (nc->memos.memos) {
01962 for (i = 0; i < nc->memos.memocount; i++) {
01963 if (nc->memos.memos[i].text)
01964 free(nc->memos.memos[i].text);
01965 }
01966 free(nc->memos.memos);
01967 }
01968 free(nc);
01969 return 1;
01970 }
01971
01972 void insert_bot(BotInfo * bi)
01973 {
01974 BotInfo *ptr, *prev;
01975
01976 for (prev = NULL, ptr = botlists[tolower(*bi->nick)];
01977 ptr != NULL && mystricmp(ptr->nick, bi->nick) < 0;
01978 prev = ptr, ptr = ptr->next);
01979 bi->prev = prev;
01980 bi->next = ptr;
01981 if (!prev)
01982 botlists[tolower(*bi->nick)] = bi;
01983 else
01984 prev->next = bi;
01985 if (ptr)
01986 ptr->prev = bi;
01987 }
01988
01989 BotInfo *findbot(char *nick)
01990 {
01991 BotInfo *bi;
01992
01993 for (bi = botlists[tolower(*nick)]; bi; bi = bi->next)
01994 if (!mystricmp(nick, bi->nick))
01995 return bi;
01996
01997 return NULL;
01998 }
01999
02000 ChannelInfo *cs_findchan(const char *chan)
02001 {
02002 ChannelInfo *ci;
02003 for (ci = chanlists[tolower(chan[1])]; ci; ci = ci->next) {
02004 if (!mystricmp(ci->name, chan))
02005 return ci;
02006 }
02007 return NULL;
02008 }
02009
02010 void alpha_insert_chan(ChannelInfo * ci)
02011 {
02012 ChannelInfo *ptr, *prev;
02013 char *chan = ci->name;
02014
02015 for (prev = NULL, ptr = chanlists[tolower(chan[1])];
02016 ptr != NULL && mystricmp(ptr->name, chan) < 0;
02017 prev = ptr, ptr = ptr->next);
02018 ci->prev = prev;
02019 ci->next = ptr;
02020 if (!prev)
02021 chanlists[tolower(chan[1])] = ci;
02022 else
02023 prev->next = ci;
02024 if (ptr)
02025 ptr->prev = ci;
02026 }
02027