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
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #include <stdlib.h>
00049 #include <string.h>
00050 #include <stdio.h>
00051 #include <fcntl.h>
00052 #include <ctype.h>
00053 #include <time.h>
00054
00055 #ifndef _WIN32
00056 #include <unistd.h>
00057 #else
00058 #include "sysconf.h"
00059 #include <windows.h>
00060 #endif
00061
00062
00063 #ifdef __sun
00064
00065
00066
00067 #undef u_int8_t
00068 #undef u_int16_t
00069 #undef u_int32_t
00070 #undef u_int_64_t
00071 #define u_int8_t uint8_t
00072 #define u_int16_t uint16_t
00073 #define u_int32_t uint32_t
00074 #define u_int64_t uint64_t
00075
00076 #ifndef INADDR_NONE
00077 #define INADDR_NONE (-1)
00078 #endif
00079
00080 #endif
00081
00082
00083
00084
00085 #define NICK_DB_1 "nick1.db"
00086 #define NICK_DB_2 "nick2.db"
00087 #define NICK_DB_NEW "nick.db"
00088
00089 #define CHAN_DB_1 "chan1.db"
00090 #define CHAN_DB_2 "chan2.db"
00091 #define CHAN_DB_NEW "chan.db"
00092
00093 #define BOT_DB_1 "bot1.db"
00094 #define BOT_DB_2 "bot2.db"
00095 #define BOT_DB_NEW "bot.db"
00096
00097 #define HOST_DB_1 "hosts1.db"
00098 #define HOST_DB_2 "hosts2.db"
00099 #define HOST_DB_NEW "hosts.db"
00100
00101
00102
00103 #ifndef _WIN32
00104 #define C_LBLUE "\033[1;34m"
00105 #define C_NONE "\033[m"
00106 #else
00107 #define C_LBLUE ""
00108 #define C_NONE ""
00109 #endif
00110
00111 #define getc_db(f) (fgetc((f)->fp))
00112 #define HASH(nick) ((tolower((nick)[0])&31)<<5 | (tolower((nick)[1])&31))
00113 #define HASH2(chan) ((chan)[1] ? ((chan)[1]&31)<<5 | ((chan)[2]&31) : 0)
00114 #define read_buffer(buf,f) (read_db((f),(buf),sizeof(buf)) == sizeof(buf))
00115 #define write_buffer(buf,f) (write_db((f),(buf),sizeof(buf)) == sizeof(buf))
00116 #define read_db(f,buf,len) (fread((buf),1,(len),(f)->fp))
00117 #define write_db(f,buf,len) (fwrite((buf),1,(len),(f)->fp))
00118 #define read_int8(ret,f) ((*(ret)=fgetc((f)->fp))==EOF ? -1 : 0)
00119 #define write_int8(val,f) (fputc((val),(f)->fp)==EOF ? -1 : 0)
00120 #define SAFE(x) do { \
00121 if ((x) < 0) { \
00122 printf("Error, the database is broken, trying to continue... no guarantee.\n"); \
00123 } \
00124 } while (0)
00125 #define READ(x) do { \
00126 if ((x) < 0) { \
00127 printf("Error, the database is broken, trying to continue... no guarantee.\n"); \
00128 exit(0); \
00129 } \
00130 } while (0)
00131
00132 typedef int16_t int16;
00133 typedef u_int16_t uint16;
00134 typedef int32_t int32;
00135 typedef u_int32_t uint32;
00136 typedef struct memo_ Memo;
00137 typedef struct dbFILE_ dbFILE;
00138 typedef struct nickalias_ NickAlias;
00139 typedef struct nickcore_ NickCore;
00140 typedef struct chaninfo_ ChannelInfo;
00141 typedef struct botinfo_ BotInfo;
00142 typedef struct badword_ BadWord;
00143 typedef struct hostcore_ HostCore;
00144
00145 struct memo_ {
00146 uint32 number;
00147 uint16 flags;
00148 time_t time;
00149 char sender[32];
00150 char *text;
00151 };
00152
00153 struct dbFILE_ {
00154 int mode;
00155 FILE *fp;
00156 char filename[1024];
00157 };
00158
00159 typedef struct {
00160 int16 memocount;
00161 int16 memomax;
00162 Memo *memos;
00163 } MemoInfo;
00164
00165 typedef struct {
00166 uint16 in_use;
00167 int16 level;
00168 NickCore *nc;
00169 time_t last_seen;
00170 } ChanAccess;
00171
00172 typedef struct {
00173 int16 in_use;
00174 int16 is_nick;
00175 uint16 flags;
00176 union {
00177 char *mask;
00178 NickCore *nc;
00179 } u;
00180 char *reason;
00181 char *creator;
00182 time_t addtime;
00183 } AutoKick;
00184
00185 struct nickalias_ {
00186 NickAlias *next, *prev;
00187 char *nick;
00188 char *last_quit;
00189 char *last_realname;
00190 char *last_usermask;
00191 time_t time_registered;
00192 time_t last_seen;
00193 uint16 status;
00194 NickCore *nc;
00195 };
00196
00197 struct nickcore_ {
00198 NickCore *next, *prev;
00199
00200 char *display;
00201 char *pass;
00202 char *email;
00203 char *greet;
00204 uint32 icq;
00205 char *url;
00206 uint32 flags;
00207 uint16 language;
00208 uint16 accesscount;
00209 char **access;
00210 MemoInfo memos;
00211 uint16 channelcount;
00212 uint16 channelmax;
00213 int unused;
00214 int aliascount;
00215 };
00216
00217 struct chaninfo_ {
00218 ChannelInfo *next, *prev;
00219
00220 char name[64];
00221 char *founder;
00222 char *successor;
00223 char founderpass[32];
00224 char *desc;
00225 char *url;
00226 char *email;
00227 time_t time_registered;
00228 time_t last_used;
00229 char *last_topic;
00230 char last_topic_setter[32];
00231 time_t last_topic_time;
00232 uint32 flags;
00233 char *forbidby;
00234 char *forbidreason;
00235 int16 bantype;
00236 int16 *levels;
00237 uint16 accesscount;
00238 ChanAccess *access;
00239 uint16 akickcount;
00240 AutoKick *akick;
00241 uint32 mlock_on, mlock_off;
00242 uint32 mlock_limit;
00243 char *mlock_key;
00244 char *mlock_flood;
00245 char *mlock_redirect;
00246 char *entry_message;
00247 MemoInfo memos;
00248 char *bi;
00249 uint32 botflags;
00250 int16 *ttb;
00251 uint16 bwcount;
00252 BadWord *badwords;
00253 int16 capsmin, capspercent;
00254 int16 floodlines, floodsecs;
00255 int16 repeattimes;
00256 };
00257
00258 struct botinfo_ {
00259 BotInfo *next, *prev;
00260 char *nick;
00261 char *user;
00262 char *host;
00263 char *real;
00264 int16 flags;
00265 time_t created;
00266 int16 chancount;
00267 };
00268
00269 struct badword_ {
00270 uint16 in_use;
00271 char *word;
00272 uint16 type;
00273 };
00274
00275 struct hostcore_ {
00276 HostCore *next, *last;
00277 char *nick;
00278 char *vIdent;
00279 char *vHost;
00280 char *creator;
00281 time_t time;
00282 };
00283
00284 dbFILE *open_db_write(const char *service, const char *filename, int version);
00285 dbFILE *open_db_read(const char *service, const char *filename, int version);
00286 NickCore *findcore(const char *nick, int version);
00287 NickAlias *findnick(const char *nick);
00288 BotInfo *findbot(char *nick);
00289 ChannelInfo *cs_findchan(const char *chan);
00290 char *strscpy(char *d, const char *s, size_t len);
00291 int write_file_version(dbFILE * f, uint32 version);
00292 int mystricmp(const char *s1, const char *s2);
00293 int delnick(NickAlias *na, int donttouchthelist);
00294 int write_string(const char *s, dbFILE * f);
00295 int write_ptr(const void *ptr, dbFILE * f);
00296 int read_int16(int16 * ret, dbFILE * f);
00297 int read_int32(int32 * ret, dbFILE * f);
00298 int read_uint16(uint16 * ret, dbFILE * f);
00299 int read_uint32(uint32 * ret, dbFILE * f);
00300 int read_string(char **ret, dbFILE * f);
00301 int write_int16(uint16 val, dbFILE * f);
00302 int write_int32(uint32 val, dbFILE * f);
00303 int read_ptr(void **ret, dbFILE * f);
00304 int delcore(NickCore *nc);
00305 void alpha_insert_chan(ChannelInfo * ci);
00306 void insert_bot(BotInfo * bi);
00307 void close_db(dbFILE * f);
00308
00309 ChannelInfo *chanlists[256];
00310 NickAlias *nalists[1024];
00311 NickCore *nclists[1024];
00312 BotInfo *botlists[256];
00313
00314 int preferfirst = 0, prefersecond = 0, preferoldest = 0, prefernewest = 0;
00315 int nonick = 0, nochan = 0, nobot = 0, nohost = 0;
00316
00317 int main(int argc, char *argv[])
00318 {
00319 dbFILE *f;
00320 int i;
00321 NickCore *nc, *ncnext;
00322 HostCore *firsthc = NULL;
00323
00324 printf("\n"C_LBLUE"DB Merger v0.4 beta for Anope IRC Services by Certus"C_NONE"\n\n");
00325
00326 if (argc >= 2) {
00327 if (!mystricmp(argv[1], "--PREFEROLDEST")) {
00328 printf("Preferring oldest database entries on collision.\n");
00329 preferoldest = 1;
00330 } else if (!mystricmp(argv[1], "--PREFERFIRST")) {
00331 printf("Preferring first database's entries on collision .\n");
00332 preferfirst = 1;
00333 } else if (!mystricmp(argv[1], "--PREFERSECOND")) {
00334 printf("Preferring second database's entries on collision.\n");
00335 prefersecond = 1;
00336 } else if (!mystricmp(argv[1], "--PREFERNEWEST")) {
00337 printf("Preferring newest database entries on collision.\n");
00338 prefernewest = 1;
00339 }
00340 }
00341
00342
00343
00344 if ((f = open_db_read("NickServ", NICK_DB_1, 13))) {
00345
00346 NickAlias *na, **nalast, *naprev;
00347 NickCore *nc, **nclast, *ncprev;
00348 int16 tmp16;
00349 int32 tmp32;
00350 int i, j, c;
00351
00352 printf("Trying to merge nicks...\n");
00353
00354
00355 for (i = 0; i < 1024; i++) {
00356 nclast = &nclists[i];
00357 ncprev = NULL;
00358
00359 while ((c = getc_db(f)) == 1) {
00360 if (c != 1) {
00361 printf("Invalid format in %s.\n", NICK_DB_1);
00362 exit(0);
00363 }
00364
00365 nc = calloc(1, sizeof(NickCore));
00366 nc->aliascount = 0;
00367 nc->unused = 0;
00368
00369 *nclast = nc;
00370 nclast = &nc->next;
00371 nc->prev = ncprev;
00372 ncprev = nc;
00373
00374 READ(read_string(&nc->display, f));
00375 READ(read_string(&nc->pass, f));
00376 READ(read_string(&nc->email, f));
00377 READ(read_string(&nc->greet, f));
00378 READ(read_uint32(&nc->icq, f));
00379 READ(read_string(&nc->url, f));
00380 READ(read_uint32(&nc->flags, f));
00381 READ(read_uint16(&nc->language, f));
00382 READ(read_uint16(&nc->accesscount, f));
00383 if (nc->accesscount) {
00384 char **access;
00385 access = calloc(sizeof(char *) * nc->accesscount, 1);
00386 nc->access = access;
00387 for (j = 0; j < nc->accesscount; j++, access++)
00388 READ(read_string(access, f));
00389 }
00390 READ(read_int16(&nc->memos.memocount, f));
00391 READ(read_int16(&nc->memos.memomax, f));
00392 if (nc->memos.memocount) {
00393 Memo *memos;
00394 memos = calloc(sizeof(Memo) * nc->memos.memocount, 1);
00395 nc->memos.memos = memos;
00396 for (j = 0; j < nc->memos.memocount; j++, memos++) {
00397 READ(read_uint32(&memos->number, f));
00398 READ(read_uint16(&memos->flags, f));
00399 READ(read_int32(&tmp32, f));
00400 memos->time = tmp32;
00401 READ(read_buffer(memos->sender, f));
00402 READ(read_string(&memos->text, f));
00403 }
00404 }
00405 READ(read_uint16(&nc->channelcount, f));
00406 READ(read_int16(&tmp16, f));
00407 }
00408 *nclast = NULL;
00409 }
00410
00411
00412 for (i = 0; i < 1024; i++) {
00413 char *s = NULL;
00414
00415 nalast = &nalists[i];
00416 naprev = NULL;
00417
00418 while ((c = getc_db(f)) == 1) {
00419 if (c != 1) {
00420 printf("Invalid format in %s.\n", NICK_DB_1);
00421 exit(0);
00422 }
00423
00424 na = calloc(1, sizeof(NickAlias));
00425
00426 READ(read_string(&na->nick, f));
00427 READ(read_string(&na->last_usermask, f));
00428 READ(read_string(&na->last_realname, f));
00429 READ(read_string(&na->last_quit, f));
00430
00431 READ(read_int32(&tmp32, f));
00432 na->time_registered = tmp32;
00433 READ(read_int32(&tmp32, f));
00434 na->last_seen = tmp32;
00435 READ(read_uint16(&na->status, f));
00436 READ(read_string(&s, f));
00437 na->nc = findcore(s, 0);
00438 na->nc->aliascount++;
00439 free(s);
00440
00441 *nalast = na;
00442 nalast = &na->next;
00443 na->prev = naprev;
00444 naprev = na;
00445 }
00446 *nalast = NULL;
00447 }
00448 close_db(f);
00449 } else
00450 nonick = 1;
00451
00452
00453 if (!nonick) {
00454 if ((f = open_db_read("NickServ", NICK_DB_2, 13))) {
00455
00456 NickAlias *na, *naptr;
00457 NickCore *nc;
00458 int16 tmp16;
00459 int32 tmp32;
00460 int i, j, index, c;
00461
00462
00463 for (i = 0; i < 1024; i++) {
00464
00465 while ((c = getc_db(f)) == 1) {
00466 if (c != 1) {
00467 printf("Invalid format in %s.\n", NICK_DB_2);
00468 exit(0);
00469 }
00470
00471 nc = calloc(1, sizeof(NickCore));
00472 READ(read_string(&nc->display, f));
00473 READ(read_string(&nc->pass, f));
00474 READ(read_string(&nc->email, f));
00475
00476 naptr = findnick(nc->display);
00477 if (naptr)
00478 nc->unused = 1;
00479 else
00480 nc->unused = 0;
00481
00482 nc->aliascount = 0;
00483
00484 index = HASH(nc->display);
00485 nc->prev = NULL;
00486 nc->next = nclists[index];
00487 if (nc->next)
00488 nc->next->prev = nc;
00489 nclists[index] = nc;
00490
00491 READ(read_string(&nc->greet, f));
00492 READ(read_uint32(&nc->icq, f));
00493 READ(read_string(&nc->url, f));
00494 READ(read_uint32(&nc->flags, f));
00495 READ(read_uint16(&nc->language, f));
00496 READ(read_uint16(&nc->accesscount, f));
00497 if (nc->accesscount) {
00498 char **access;
00499 access = calloc(sizeof(char *) * nc->accesscount, 1);
00500 nc->access = access;
00501 for (j = 0; j < nc->accesscount; j++, access++)
00502 READ(read_string(access, f));
00503 }
00504 READ(read_int16(&nc->memos.memocount, f));
00505 READ(read_int16(&nc->memos.memomax, f));
00506 if (nc->memos.memocount) {
00507 Memo *memos;
00508 memos = calloc(sizeof(Memo) * nc->memos.memocount, 1);
00509 nc->memos.memos = memos;
00510 for (j = 0; j < nc->memos.memocount; j++, memos++) {
00511 READ(read_uint32(&memos->number, f));
00512 READ(read_uint16(&memos->flags, f));
00513 READ(read_int32(&tmp32, f));
00514 memos->time = tmp32;
00515 READ(read_buffer(memos->sender, f));
00516 READ(read_string(&memos->text, f));
00517 }
00518 }
00519 READ(read_uint16(&nc->channelcount, f));
00520 READ(read_int16(&tmp16, f));
00521 }
00522 }
00523
00524
00525 for (i = 0; i < 1024; i++) {
00526 char *s = NULL;
00527 NickAlias *ptr, *prev, *naptr;
00528
00529 while ((c = getc_db(f)) == 1) {
00530 if (c != 1) {
00531 printf("Invalid format in %s.\n", NICK_DB_1);
00532 exit(0);
00533 }
00534
00535 na = calloc(1, sizeof(NickAlias));
00536
00537 READ(read_string(&na->nick, f));
00538 READ(read_string(&na->last_usermask, f));
00539 READ(read_string(&na->last_realname, f));
00540 READ(read_string(&na->last_quit, f));
00541 READ(read_int32(&tmp32, f));
00542 na->time_registered = tmp32;
00543 READ(read_int32(&tmp32, f));
00544 na->last_seen = tmp32;
00545 READ(read_uint16(&na->status, f));
00546 READ(read_string(&s, f));
00547
00548 naptr = findnick(na->nick);
00549 if (naptr) {
00550 char input[1024];
00551 NickCore *ncptr = findcore(na->nick, 1); ;
00552
00553 if (!ncptr) {
00554 printf("\n\n WARNING! Malformed database. No nickcore for nick %s, droping it.\n\n\n", na->nick);
00555 delnick(na, 1);
00556 } else {
00557 if (!preferoldest && !preferfirst && !prefersecond && !prefernewest) {
00558 printf("Nick collision for nick %s:\n\n", na->nick);
00559 printf("Group 1: %s (%s)\n", ncptr->display, ncptr->email);
00560 printf("Time registered: %s\n", ctime(&na->time_registered));
00561 printf("Group 2: %s (%s)\n", naptr->nc->display, naptr->nc->email);
00562 printf("Time registered: %s\n", ctime(&naptr->time_registered));
00563 printf("What group do you want to keep? Enter the related group number \"1\" or \"2\".\n");
00564 }
00565
00566 if (preferoldest) {
00567 input[0] = (na->time_registered > naptr->time_registered) ? '1' : '2';
00568 } else if (prefernewest) {
00569 input[0] = (na->time_registered > naptr->time_registered) ? '2' : '1';
00570 } else if (preferfirst) {
00571 input[0] = '2';
00572 } else if (prefersecond) {
00573 input[0] = '1';
00574 } else {
00575 waiting_for_input:
00576 scanf("%s", input);
00577 }
00578 if (input[0] == '1') {
00579 printf("Deleting nick alias %s (#2).\n", naptr->nick);
00580 naptr->nc->aliascount--;
00581 delnick(naptr, 0);
00582 na->nc = ncptr;
00583 na->nc->aliascount++;
00584 index = HASH(na->nick);
00585 for (prev = NULL, ptr = nalists[index]; ptr && mystricmp(ptr->nick, na->nick) < 0; prev = ptr, ptr = ptr->next);
00586 na->prev = prev;
00587 na->next = ptr;
00588 if (!prev)
00589 nalists[index] = na;
00590 else
00591 prev->next = na;
00592 if (ptr)
00593 ptr->prev = na;
00594 } else if (input[0] == '2') {
00595 printf("Deleting nick alias %s (#1).\n", na->nick);
00596 delnick(na, 1);
00597 } else {
00598 printf("Invalid number, give us a valid one (1 or 2).\n");
00599 goto waiting_for_input;
00600 }
00601 }
00602 } else {
00603 na->nc = findcore(s, 0);
00604 if (!na->nc) {
00605 printf("\n\n WARNING! Malformed database. No nickcore for nick %s, droping it.\n\n\n", na->nick);
00606 delnick(na, 1);
00607 } else {
00608 na->nc->aliascount++;
00609 index = HASH(na->nick);
00610 for (prev = NULL, ptr = nalists[index]; ptr && mystricmp(ptr->nick, na->nick) < 0; prev = ptr, ptr = ptr->next);
00611 na->prev = prev;
00612 na->next = ptr;
00613 if (!prev)
00614 nalists[index] = na;
00615 else
00616 prev->next = na;
00617 if (ptr)
00618 ptr->prev = na;
00619 }
00620 }
00621 free(s);
00622 }
00623 }
00624 close_db(f);
00625 } else
00626 nonick = 1;
00627 }
00628
00629
00630
00631 for (i = 0; i < 1024; i++) {
00632 for (nc = nclists[i]; nc; nc = ncnext) {
00633 ncnext = nc->next;
00634 if (nc->aliascount < 1) {
00635 printf("Deleting core %s (%s).\n", nc->display, nc->email);
00636 delcore(nc);
00637 }
00638 }
00639 }
00640
00641
00642 if (!nonick) {
00643 if ((f = open_db_write("NickServ", NICK_DB_NEW, 13))) {
00644
00645 NickAlias *na;
00646 NickCore *nc;
00647 char **access;
00648 Memo *memos;
00649 int i, j;
00650
00651
00652 for (i = 0; i < 1024; i++) {
00653 for (nc = nclists[i]; nc; nc = nc->next) {
00654 SAFE(write_int8(1, f));
00655 SAFE(write_string(nc->display, f));
00656 SAFE(write_string(nc->pass, f));
00657 SAFE(write_string(nc->email, f));
00658 SAFE(write_string(nc->greet, f));
00659 SAFE(write_int32(nc->icq, f));
00660 SAFE(write_string(nc->url, f));
00661 SAFE(write_int32(nc->flags, f));
00662 SAFE(write_int16(nc->language, f));
00663 SAFE(write_int16(nc->accesscount, f));
00664 for (j = 0, access = nc->access; j < nc->accesscount; j++, access++)
00665 SAFE(write_string(*access, f));
00666
00667 SAFE(write_int16(nc->memos.memocount, f));
00668 SAFE(write_int16(nc->memos.memomax, f));
00669 memos = nc->memos.memos;
00670 for (j = 0; j < nc->memos.memocount; j++, memos++) {
00671 SAFE(write_int32(memos->number, f));
00672 SAFE(write_int16(memos->flags, f));
00673 SAFE(write_int32(memos->time, f));
00674 SAFE(write_buffer(memos->sender, f));
00675 SAFE(write_string(memos->text, f));
00676 }
00677 SAFE(write_int16(nc->channelcount, f));
00678 SAFE(write_int16(nc->channelmax, f));
00679 }
00680 SAFE(write_int8(0, f));
00681 }
00682
00683
00684 for (i = 0; i < 1024; i++) {
00685 for (na = nalists[i]; na; na = na->next) {
00686 SAFE(write_int8(1, f));
00687 SAFE(write_string(na->nick, f));
00688 SAFE(write_string(na->last_usermask, f));
00689 SAFE(write_string(na->last_realname, f));
00690 SAFE(write_string(na->last_quit, f));
00691 SAFE(write_int32(na->time_registered, f));
00692 SAFE(write_int32(na->last_seen, f));
00693 SAFE(write_int16(na->status, f));
00694 SAFE(write_string(na->nc->display, f));
00695
00696 }
00697 SAFE(write_int8(0, f));
00698 }
00699 close_db(f);
00700 printf("Nick merging done. New database saved as %s.\n", NICK_DB_NEW);
00701 }
00702 }
00703
00704
00705
00706 if ((f = open_db_read("ChanServ", CHAN_DB_1, 16))) {
00707 ChannelInfo *ci, **last, *prev;
00708 int c;
00709
00710 printf("Trying to merge channels...\n");
00711
00712 for (i = 0; i < 256; i++) {
00713 int16 tmp16;
00714 int32 tmp32;
00715 int n_levels;
00716 char *s;
00717 int n_ttb;
00718
00719
00720
00721
00722 last = &chanlists[i];
00723 prev = NULL;
00724
00725 while ((c = getc_db(f)) == 1) {
00726 int j;
00727
00728 if (c != 1) {
00729 printf("Invalid format in %s.\n", CHAN_DB_1);
00730 exit(0);
00731 }
00732
00733 ci = calloc(sizeof(ChannelInfo), 1);
00734 *last = ci;
00735 last = &ci->next;
00736 ci->prev = prev;
00737 prev = ci;
00738 READ(read_buffer(ci->name, f));
00739 READ(read_string(&ci->founder, f));
00740 READ(read_string(&ci->successor, f));
00741 READ(read_buffer(ci->founderpass, f));
00742 READ(read_string(&ci->desc, f));
00743 if (!ci->desc)
00744 ci->desc = strdup("");
00745 READ(read_string(&ci->url, f));
00746 READ(read_string(&ci->email, f));
00747 READ(read_int32(&tmp32, f));
00748 ci->time_registered = tmp32;
00749 READ(read_int32(&tmp32, f));
00750 ci->last_used = tmp32;
00751 READ(read_string(&ci->last_topic, f));
00752 READ(read_buffer(ci->last_topic_setter, f));
00753 READ(read_int32(&tmp32, f));
00754 ci->last_topic_time = tmp32;
00755 READ(read_uint32(&ci->flags, f));
00756
00757 ci->flags &= ~0x80000000;
00758 READ(read_string(&ci->forbidby, f));
00759 READ(read_string(&ci->forbidreason, f));
00760