Anope IRC Services  Version 1.8
db-merger.c
Go to the documentation of this file.
1 /*
2  * Anope Database Merger
3  * (C) 2003-2014 Anope Team
4  * Contact us at team@anope.org
5  *
6  * Please read COPYING and README for further details.
7  *
8  *****
9  *
10  * Based on the original IRC, db-merger.c
11  * (C) Copyright 2005-2006, Florian Schulze (Certus)
12  * Based on the original code of Anope, (C) 2003-2014 Anope Team
13  *
14  */
15 
16 /*
17  * Known issues:
18  * - When merging it is possible that ownership of a channel is transferred
19  * to another nickgroup if the founder's main nick is dropped and granted
20  * to another user in the other database. This user will then become
21  * founder of the channel.
22  *
23  * - The count of channels a nickgroup has registered is not recalculated
24  * after the merge. This means that if a channel was dropped, the owner may
25  * have an incorrect counter and may sooner reach the maximum number of
26  * allowed registered channels.
27  *
28  * Ideally, this should be rewritten from scratch to only merge after both
29  * database sets are fully loaded, however since we will be migrating to
30  * another database architecture, this is unlikely to be done for the
31  * current "stable" DB architecture.
32  *
33  * ~ Viper
34  */
35 
36 #include <stdlib.h>
37 #include <string.h>
38 #include <stdio.h>
39 #include <fcntl.h>
40 #include <ctype.h>
41 #include <time.h>
42 
43 #ifndef _WIN32
44 #include <unistd.h>
45 #else
46 #include "sysconf.h"
47 #include <windows.h>
48 #endif
49 
50 /* Some SUN fixs */
51 #ifdef __sun
52 /* Solaris specific code, types that do not exist in Solaris'
53  * sys/types.h
54  **/
55 #undef u_int8_t
56 #undef u_int16_t
57 #undef u_int32_t
58 #undef u_int_64_t
59 #define u_int8_t uint8_t
60 #define u_int16_t uint16_t
61 #define u_int32_t uint32_t
62 #define u_int64_t uint64_t
63 
64 #ifndef INADDR_NONE
65 #define INADDR_NONE (-1)
66 #endif
67 
68 #endif
69 
70 
71 /* CONFIGURATION BLOCK */
72 
73 #define NICK_DB_1 "nick1.db"
74 #define NICK_DB_2 "nick2.db"
75 #define NICK_DB_NEW "nick.db"
76 
77 #define CHAN_DB_1 "chan1.db"
78 #define CHAN_DB_2 "chan2.db"
79 #define CHAN_DB_NEW "chan.db"
80 
81 #define BOT_DB_1 "bot1.db"
82 #define BOT_DB_2 "bot2.db"
83 #define BOT_DB_NEW "bot.db"
84 
85 #define HOST_DB_1 "hosts1.db"
86 #define HOST_DB_2 "hosts2.db"
87 #define HOST_DB_NEW "hosts.db"
88 
89 /* END OF CONFIGURATION BLOCK */
90 
91 #ifndef _WIN32
92 #define C_LBLUE "\033[1;34m"
93 #define C_NONE "\033[m"
94 #else
95 #define C_LBLUE ""
96 #define C_NONE ""
97 #endif
98 
99 #define getc_db(f) (fgetc((f)->fp))
100 #define HASH(nick) ((tolower((nick)[0])&31)<<5 | (tolower((nick)[1])&31))
101 #define HASH2(chan) ((chan)[1] ? ((chan)[1]&31)<<5 | ((chan)[2]&31) : 0)
102 #define read_buffer(buf,f) (read_db((f),(buf),sizeof(buf)) == sizeof(buf))
103 #define write_buffer(buf,f) (write_db((f),(buf),sizeof(buf)) == sizeof(buf))
104 #define read_db(f,buf,len) (fread((buf),1,(len),(f)->fp))
105 #define write_db(f,buf,len) (fwrite((buf),1,(len),(f)->fp))
106 #define read_int8(ret,f) ((*(ret)=fgetc((f)->fp))==EOF ? -1 : 0)
107 #define write_int8(val,f) (fputc((val),(f)->fp)==EOF ? -1 : 0)
108 #define SAFE(x) do { \
109  if ((x) < 0) { \
110  printf("Error, the database is broken, trying to continue... no guarantee.\n"); \
111  } \
112 } while (0)
113 #define READ(x) do { \
114  if ((x) < 0) { \
115  printf("Error, the database is broken, trying to continue... no guarantee.\n"); \
116  exit(0); \
117  } \
118 } while (0)
119 
120 typedef int16_t int16;
121 typedef u_int16_t uint16;
122 typedef int32_t int32;
123 typedef u_int32_t uint32;
124 typedef struct memo_ Memo;
125 typedef struct dbFILE_ dbFILE;
126 typedef struct nickalias_ NickAlias;
127 typedef struct nickcore_ NickCore;
128 typedef struct chaninfo_ ChannelInfo;
129 typedef struct botinfo_ BotInfo;
130 typedef struct badword_ BadWord;
131 typedef struct hostcore_ HostCore;
132 
133 struct memo_ {
134  uint32 number; /* Index number -- not necessarily array position! */
135  uint16 flags; /* Flags */
136  time_t time; /* When was it sent? */
137  char sender[32]; /* Name of the sender */
138  char *text;
139 };
140 
141 struct dbFILE_ {
142  int mode; /* 'r' for reading, 'w' for writing */
143  FILE *fp; /* The normal file descriptor */
144  char filename[1024]; /* Name of the database file */
145 };
146 
147 typedef struct {
148  int16 memocount; /* Current # of memos */
149  int16 memomax; /* Max # of memos one can hold*/
150  Memo *memos; /* Pointer to original memos */
151 } MemoInfo;
152 
153 typedef struct {
154  uint16 in_use; /* 1 if this entry is in use, else 0 */
155  int16 level;
156  NickCore *nc; /* Guaranteed to be non-NULL if in use, NULL if not */
157  time_t last_seen;
158 } ChanAccess;
159 
160 typedef struct {
161  int16 in_use; /* Always 0 if not in use */
162  int16 is_nick; /* 1 if a regged nickname, 0 if a nick!user@host mask */
163  uint16 flags;
164  union {
165  char *mask; /* Guaranteed to be non-NULL if in use, NULL if not */
166  NickCore *nc; /* Same */
167  } u;
168  char *reason;
169  char *creator;
170  time_t addtime;
171 } AutoKick;
172 
173 struct nickalias_ {
174  NickAlias *next, *prev;
175  char *nick; /* Nickname */
176  char *last_quit; /* Last quit message */
177  char *last_realname; /* Last realname */
178  char *last_usermask; /* Last usermask */
179  time_t time_registered; /* When the nick was registered */
180  time_t last_seen; /* When it was seen online for the last time */
181  uint16 status; /* See NS_* below */
182  NickCore *nc; /* I'm an alias of this */
183 };
184 
185 struct nickcore_ {
186  NickCore *next, *prev;
187 
188  char *display; /* How the nick is displayed */
189  char pass[32]; /* Password of the nicks */
190  char *email; /* E-mail associated to the nick */
191  char *greet; /* Greet associated to the nick */
192  uint32 icq; /* ICQ # associated to the nick */
193  char *url; /* URL associated to the nick */
194  uint32 flags; /* See NI_* below */
195  uint16 language; /* Language selected by nickname owner (LANG_*) */
196  uint16 accesscount; /* # of entries */
197  char **access; /* Array of strings */
198  MemoInfo memos; /* Memo information */
199  uint16 channelcount; /* Number of channels currently registered */
200  uint16 channelmax; /* Maximum number of channels allowed */
201  int unused; /* Used for nick collisions */
202  int aliascount; /* How many aliases link to us? Remove the core if 0 */
203 };
204 
205 struct chaninfo_ {
206  ChannelInfo *next, *prev;
207 
208  char name[64]; /* Channel name */
209  char *founder; /* Who registered the channel */
210  char *successor; /* Who gets the channel if the founder nick is dropped or expires */
211  char founderpass[32]; /* Channel password */
212  char *desc; /* Description */
213  char *url; /* URL */
214  char *email; /* Email address */
215  time_t time_registered; /* When was it registered */
216  time_t last_used; /* When was it used hte last time */
217  char *last_topic; /* Last topic on the channel */
218  char last_topic_setter[32]; /* Who set the last topic */
219  time_t last_topic_time; /* When the last topic was set */
220  uint32 flags; /* Flags */
221  char *forbidby; /* if forbidden: who did it */
222  char *forbidreason; /* if forbidden: why */
223  int16 bantype; /* Bantype */
224  int16 *levels; /* Access levels for commands */
225  uint16 accesscount; /* # of pple with access */
226  ChanAccess *access; /* List of authorized users */
227  uint16 akickcount; /* # of akicked pple */
228  AutoKick *akick; /* List of users to kickban */
229  uint32 mlock_on, mlock_off; /* See channel modes below */
230  uint32 mlock_limit; /* 0 if no limit */
231  char *mlock_key; /* NULL if no key */
232  char *mlock_flood; /* NULL if no +f */
233  char *mlock_redirect; /* NULL if no +L */
234  char *entry_message; /* Notice sent on entering channel */
235  MemoInfo memos; /* Memos */
236  char *bi; /* Bot used on this channel */
237  uint32 botflags; /* BS_* below */
238  int16 *ttb; /* Times to ban for each kicker */
239  uint16 bwcount; /* Badword count */
240  BadWord *badwords; /* For BADWORDS kicker */
241  int16 capsmin, capspercent; /* For CAPS kicker */
242  int16 floodlines, floodsecs; /* For FLOOD kicker */
243  int16 repeattimes; /* For REPEAT kicker */
244 };
245 
246 struct botinfo_ {
247  BotInfo *next, *prev;
248  char *nick; /* Nickname of the bot */
249  char *user; /* Its user name */
250  char *host; /* Its hostname */
251  char *real; /* Its real name */
252  int16 flags; /* Bot flags */
253  time_t created; /* Birth date */
254  int16 chancount; /* Number of channels that use the bot. */
255 };
256 
257 struct badword_ {
258  uint16 in_use;
259  char *word;
260  uint16 type;
261 };
262 
263 struct hostcore_ {
265  char *nick; /* Owner of the vHost */
266  char *vIdent; /* vIdent for the user */
267  char *vHost; /* Vhost for this user */
268  char *creator; /* Oper Nick of the oper who set the vhost */
269  time_t time; /* Date/Time vHost was set */
270 };
271 
272 dbFILE *open_db_write(const char *service, const char *filename, int version);
273 dbFILE *open_db_read(const char *service, const char *filename, int version);
274 NickCore *findcore(const char *nick, int version);
275 NickAlias *findnick(const char *nick);
276 BotInfo *findbot(char *nick);
277 ChannelInfo *cs_findchan(const char *chan);
278 char *strscpy(char *d, const char *s, size_t len);
280 int mystricmp(const char *s1, const char *s2);
281 int delnick(NickAlias *na, int donttouchthelist);
282 int write_string(const char *s, dbFILE * f);
283 int write_ptr(const void *ptr, dbFILE * f);
284 int read_int16(int16 * ret, dbFILE * f);
285 int read_int32(int32 * ret, dbFILE * f);
286 int read_uint16(uint16 * ret, dbFILE * f);
287 int read_uint32(uint32 * ret, dbFILE * f);
288 int read_string(char **ret, dbFILE * f);
289 int write_int16(uint16 val, dbFILE * f);
290 int write_int32(uint32 val, dbFILE * f);
291 int read_ptr(void **ret, dbFILE * f);
292 int delcore(NickCore *nc);
293 void alpha_insert_chan(ChannelInfo * ci);
294 void insert_bot(BotInfo * bi);
295 void close_db(dbFILE * f);
296 
301 
303 int nonick = 0, nochan = 0, nobot = 0, nohost = 0;
304 
305 int main(int argc, char *argv[])
306 {
307  dbFILE *f;
308  int i;
309  NickCore *nc, *ncnext;
310  HostCore *firsthc = NULL;
311 
312  printf("\n"C_LBLUE"DB Merger for Anope IRC Services"C_NONE"\n");
313 
314  if (argc >= 2) {
315  if (!mystricmp(argv[1], "--PREFEROLDEST")) {
316  printf("Preferring oldest database entries on collision.\n");
317  preferoldest = 1;
318  } else if (!mystricmp(argv[1], "--PREFERFIRST")) {
319  printf("Preferring first database's entries on collision .\n");
320  preferfirst = 1;
321  } else if (!mystricmp(argv[1], "--PREFERSECOND")) {
322  printf("Preferring second database's entries on collision.\n");
323  prefersecond = 1;
324  } else if (!mystricmp(argv[1], "--PREFERNEWEST")) {
325  printf("Preferring newest database entries on collision.\n");
326  prefernewest = 1;
327  }
328  }
329 
330  /* Section I: Nicks */
331  /* Ia: First database */
332  if ((f = open_db_read("NickServ", NICK_DB_1, 14))) {
333 
334  NickAlias *na, **nalast, *naprev;
335  NickCore *nc, **nclast, *ncprev;
336  int16 tmp16;
337  int32 tmp32;
338  int i, j, c;
339 
340  printf("Trying to merge nicks...\n");
341 
342  /* Nick cores */
343  for (i = 0; i < 1024; i++) {
344  nclast = &nclists[i];
345  ncprev = NULL;
346 
347  while ((c = getc_db(f)) == 1) {
348  if (c != 1) {
349  printf("Invalid format in %s.\n", NICK_DB_1);
350  exit(0);
351  }
352 
353  nc = calloc(1, sizeof(NickCore));
354  nc->aliascount = 0;
355  nc->unused = 0;
356 
357  *nclast = nc;
358  nclast = &nc->next;
359  nc->prev = ncprev;
360  ncprev = nc;
361 
362  READ(read_string(&nc->display, f));
363  READ(read_buffer(nc->pass, f));
364  READ(read_string(&nc->email, f));
365  READ(read_string(&nc->greet, f));
366  READ(read_uint32(&nc->icq, f));
367  READ(read_string(&nc->url, f));
368  READ(read_uint32(&nc->flags, f));
369  READ(read_uint16(&nc->language, f));
370  READ(read_uint16(&nc->accesscount, f));
371  if (nc->accesscount) {
372  char **access;
373  access = calloc(sizeof(char *) * nc->accesscount, 1);
374  nc->access = access;
375  for (j = 0; j < nc->accesscount; j++, access++)
376  READ(read_string(access, f));
377  }
378  READ(read_int16(&nc->memos.memocount, f));
379  READ(read_int16(&nc->memos.memomax, f));
380  if (nc->memos.memocount) {
381  Memo *memos;
382  memos = calloc(sizeof(Memo) * nc->memos.memocount, 1);
383  nc->memos.memos = memos;
384  for (j = 0; j < nc->memos.memocount; j++, memos++) {
385  READ(read_uint32(&memos->number, f));
386  READ(read_uint16(&memos->flags, f));
387  READ(read_int32(&tmp32, f));
388  memos->time = tmp32;
389  READ(read_buffer(memos->sender, f));
390  READ(read_string(&memos->text, f));
391  }
392  }
393  READ(read_uint16(&nc->channelcount, f));
394  READ(read_int16(&tmp16, f));
395  } /* getc_db() */
396  *nclast = NULL;
397  } /* for() loop */
398 
399  /* Nick aliases */
400  for (i = 0; i < 1024; i++) {
401  char *s = NULL;
402 
403  nalast = &nalists[i];
404  naprev = NULL;
405 
406  while ((c = getc_db(f)) == 1) {
407  if (c != 1) {
408  printf("Invalid format in %s.\n", NICK_DB_1);
409  exit(0);
410  }
411 
412  na = calloc(1, sizeof(NickAlias));
413 
414  READ(read_string(&na->nick, f));
415  READ(read_string(&na->last_usermask, f));
416  READ(read_string(&na->last_realname, f));
417  READ(read_string(&na->last_quit, f));
418 
419  READ(read_int32(&tmp32, f));
420  na->time_registered = tmp32;
421  READ(read_int32(&tmp32, f));
422  na->last_seen = tmp32;
423  READ(read_uint16(&na->status, f));
424  READ(read_string(&s, f));
425  na->nc = findcore(s, 0);
426  na->nc->aliascount++;
427  free(s);
428 
429  *nalast = na;
430  nalast = &na->next;
431  na->prev = naprev;
432  naprev = na;
433  } /* getc_db() */
434  *nalast = NULL;
435  } /* for() loop */
436  close_db(f); /* End of section Ia */
437  } else
438  nonick = 1;
439 
440  /* Ib: Second database */
441  if (!nonick) {
442  if ((f = open_db_read("NickServ", NICK_DB_2, 14))) {
443 
444  NickAlias *na, *naptr;
445  NickCore *nc;
446  int16 tmp16;
447  int32 tmp32;
448  int i, j, index, c;
449 
450  /* Nick cores */
451  for (i = 0; i < 1024; i++) {
452 
453  while ((c = getc_db(f)) == 1) {
454  if (c != 1) {
455  printf("Invalid format in %s.\n", NICK_DB_2);
456  exit(0);
457  }
458 
459  nc = calloc(1, sizeof(NickCore));
460  READ(read_string(&nc->display, f));
461  READ(read_buffer(nc->pass, f));
462  READ(read_string(&nc->email, f));
463 
464  naptr = findnick(nc->display);
465  if (naptr)
466  nc->unused = 1;
467  else
468  nc->unused = 0;
469 
470  nc->aliascount = 0;
471 
472  index = HASH(nc->display);
473  nc->prev = NULL;
474  nc->next = nclists[index];
475  if (nc->next)
476  nc->next->prev = nc;
477  nclists[index] = nc;
478 
479  READ(read_string(&nc->greet, f));
480  READ(read_uint32(&nc->icq, f));
481  READ(read_string(&nc->url, f));
482  READ(read_uint32(&nc->flags, f));
483  READ(read_uint16(&nc->language, f));
484  READ(read_uint16(&nc->accesscount, f));
485  if (nc->accesscount) {
486  char **access;
487  access = calloc(sizeof(char *) * nc->accesscount, 1);
488  nc->access = access;
489  for (j = 0; j < nc->accesscount; j++, access++)
490  READ(read_string(access, f));
491  }
492  READ(read_int16(&nc->memos.memocount, f));
493  READ(read_int16(&nc->memos.memomax, f));
494  if (nc->memos.memocount) {
495  Memo *memos;
496  memos = calloc(sizeof(Memo) * nc->memos.memocount, 1);
497  nc->memos.memos = memos;
498  for (j = 0; j < nc->memos.memocount; j++, memos++) {
499  READ(read_uint32(&memos->number, f));
500  READ(read_uint16(&memos->flags, f));
501  READ(read_int32(&tmp32, f));
502  memos->time = tmp32;
503  READ(read_buffer(memos->sender, f));
504  READ(read_string(&memos->text, f));
505  }
506  }
507  READ(read_uint16(&nc->channelcount, f));
508  READ(read_int16(&tmp16, f));
509  } /* getc_db() */
510  } /* for() loop */
511 
512  /* Nick aliases */
513  for (i = 0; i < 1024; i++) {
514  char *s = NULL;
515  NickAlias *ptr, *prev, *naptr;
516 
517  while ((c = getc_db(f)) == 1) {
518  if (c != 1) {
519  printf("Invalid format in %s.\n", NICK_DB_2);
520  exit(0);
521  }
522 
523  na = calloc(1, sizeof(NickAlias));
524 
525  READ(read_string(&na->nick, f));
526  READ(read_string(&na->last_usermask, f));
527  READ(read_string(&na->last_realname, f));
528  READ(read_string(&na->last_quit, f));
529  READ(read_int32(&tmp32, f));
530  na->time_registered = tmp32;
531  READ(read_int32(&tmp32, f));
532  na->last_seen = tmp32;
533  READ(read_uint16(&na->status, f));
534  READ(read_string(&s, f));
535 
536  naptr = findnick(na->nick);
537  if (naptr) { /* COLLISION! na = collision #2 = new (na->nc doesn't exist yet), naptr = collision #1 = old (naptr->nc exists) */
538  char input[1024];
539  NickCore *ncptr = findcore(na->nick, 1); /* Find core for #2, ncptr MUST exist since we've read all cores, if it doesn't eixst, we have a malformed db */;
540 
541  if (!ncptr) { /* malformed */
542  printf("\n\n WARNING! Malformed database. No nickcore for nick %s, droping it.\n\n\n", na->nick);
543  delnick(na, 1);
544  } else { /* not malformed */
546  printf("Nick collision for nick %s:\n\n", na->nick);
547  printf("Group 1: %s (%s)\n", naptr->nc->display, naptr->nc->email);
548  printf("Time registered: %s\n", ctime(&naptr->time_registered));
549  printf("Group 2: %s (%s)\n", ncptr->display, ncptr->email);
550  printf("Time registered: %s\n", ctime(&na->time_registered));
551  printf("What group do you want to keep? Enter the related group number \"1\" or \"2\".\n");
552  }
553 
554  if (preferoldest) {
555  input[0] = (na->time_registered > naptr->time_registered) ? '1' : '2';
556  } else if (prefernewest) {
557  input[0] = (na->time_registered > naptr->time_registered) ? '2' : '1';
558  } else if (preferfirst) {
559  input[0] = '1';
560  } else if (prefersecond) {
561  input[0] = '2';
562  } else {
563  waiting_for_input:
564  scanf("%s", input);
565  }
566  if (input[0] == '1') { /* #2 isn't in the list yet, #1 is. free #2 alias. */
567  printf("Deleting nick alias %s (#2).\n", na->nick);
568  delnick(na, 1); /* free()s the alias without touching the list since na isn't in the list */
569  } else if (input[0] == '2') { /* get alias #1 out of the list, then free() it, then add #2 to the list */
570  printf("Deleting nick alias %s (#1).\n", naptr->nick);
571  naptr->nc->aliascount--; /* tell the core it has one alias less */
572  delnick(naptr, 0); /* removes the alias from the list and free()s it */
573  na->nc = ncptr;
574  na->nc->aliascount++;
575  index = HASH(na->nick);
576  for (prev = NULL, ptr = nalists[index]; ptr && mystricmp(ptr->nick, na->nick) < 0; prev = ptr, ptr = ptr->next);
577  na->prev = prev;
578  na->next = ptr;
579  if (!prev)
580  nalists[index] = na;
581  else
582  prev->next = na;
583  if (ptr)
584  ptr->prev = na;
585  } else {
586  printf("Invalid number, give us a valid one (1 or 2).\n");
587  goto waiting_for_input;
588  }
589  } /* not malformed */
590  } else { /* No collision, add the core pointer and put the alias in the list */
591  na->nc = findcore(s, 0);
592  if (!na->nc) {
593  printf("\n\n WARNING! Malformed database. No nickcore for nick %s, droping it.\n\n\n", na->nick);
594  delnick(na, 1);
595  } else {
596  na->nc->aliascount++;
597  index = HASH(na->nick);
598  for (prev = NULL, ptr = nalists[index]; ptr && mystricmp(ptr->nick, na->nick) < 0; prev = ptr, ptr = ptr->next);
599  na->prev = prev;
600  na->next = ptr;
601  if (!prev)
602  nalists[index] = na;
603  else
604  prev->next = na;
605  if (ptr)
606  ptr->prev = na;
607  }
608  }
609  free(s);
610  } /* getc_db() */
611  } /* for() loop */
612  close_db(f); /* End of section Ib */
613  } else
614  nonick = 1;
615  }
616 
617  /* CLEAN THE CORES */
618 
619  for (i = 0; i < 1024; i++) {
620  for (nc = nclists[i]; nc; nc = ncnext) {
621  ncnext = nc->next;
622  if (nc->aliascount < 1) {
623  printf("Deleting core %s (%s).\n", nc->display, nc->email);
624  delcore(nc);
625  }
626  }
627  }
628 
629  /* Ic: Saving */
630  if (!nonick) {
631  if ((f = open_db_write("NickServ", NICK_DB_NEW, 14))) {
632 
633  NickAlias *na;
634  NickCore *nc;
635  char **access;
636  Memo *memos;
637  int i, j;
638 
639  /* Nick cores */
640  for (i = 0; i < 1024; i++) {
641  for (nc = nclists[i]; nc; nc = nc->next) {
642  SAFE(write_int8(1, f));
643  SAFE(write_string(nc->display, f));
644  SAFE(write_buffer(nc->pass, f));
645  SAFE(write_string(nc->email, f));
646  SAFE(write_string(nc->greet, f));
647  SAFE(write_int32(nc->icq, f));
648  SAFE(write_string(nc->url, f));
649  SAFE(write_int32(nc->flags, f));
650  SAFE(write_int16(nc->language, f));
651  SAFE(write_int16(nc->accesscount, f));
652  for (j = 0, access = nc->access; j < nc->accesscount; j++, access++)
653  SAFE(write_string(*access, f));
654 
655  SAFE(write_int16(nc->memos.memocount, f));
656  SAFE(write_int16(nc->memos.memomax, f));
657  memos = nc->memos.memos;
658  for (j = 0; j < nc->memos.memocount; j++, memos++) {
659  SAFE(write_int32(memos->number, f));
660  SAFE(write_int16(memos->flags, f));
661  SAFE(write_int32(memos->time, f));
662  SAFE(write_buffer(memos->sender, f));
663  SAFE(write_string(memos->text, f));
664  }
665  SAFE(write_int16(nc->channelcount, f));
666  SAFE(write_int16(nc->channelmax, f));
667  } /* for (nc) */
668  SAFE(write_int8(0, f));
669  } /* for (i) */
670 
671  /* Nick aliases */
672  for (i = 0; i < 1024; i++) {
673  for (na = nalists[i]; na; na = na->next) {
674  SAFE(write_int8(1, f));
675  SAFE(write_string(na->nick, f));
678  SAFE(write_string(na->last_quit, f));
680  SAFE(write_int32(na->last_seen, f));
681  SAFE(write_int16(na->status, f));
682  SAFE(write_string(na->nc->display, f));
683 
684  } /* for (na) */
685  SAFE(write_int8(0, f));
686  } /* for (i) */
687  close_db(f); /* End of section Ic */
688  printf("Nick merging done. New database saved as %s.\n", NICK_DB_NEW);
689  }
690  } /* End of section I */
691 
692  /* Section II: Chans */
693  /* IIa: First database */
694  if ((f = open_db_read("ChanServ", CHAN_DB_1, 16))) {
695  ChannelInfo *ci, **last, *prev;
696  int c;
697 
698  printf("Trying to merge channels...\n");
699 
700  for (i = 0; i < 256; i++) {
701  int16 tmp16;
702  int32 tmp32;
703  int n_levels;
704  char *s;
705  int n_ttb;
706  /* Unused variable - why? -GD
707  int J;
708  */
709 
710  last = &chanlists[i];
711  prev = NULL;
712 
713  while ((c = getc_db(f)) == 1) {
714  int j;
715 
716  if (c != 1) {
717  printf("Invalid format in %s.\n", CHAN_DB_1);
718  exit(0);
719  }
720 
721  ci = calloc(sizeof(ChannelInfo), 1);
722  *last = ci;
723  last = &ci->next;
724  ci->prev = prev;
725  prev = ci;
726  READ(read_buffer(ci->name, f));
727  READ(read_string(&ci->founder, f));
728  READ(read_string(&ci->successor, f));
729  READ(read_buffer(ci->founderpass, f));
730  READ(read_string(&ci->desc, f));
731  if (!ci->desc)
732  ci->desc = strdup("");
733  READ(read_string(&ci->url, f));
734  READ(read_string(&ci->email, f));
735  READ(read_int32(&tmp32, f));
736  ci->time_registered = tmp32;
737  READ(read_int32(&tmp32, f));
738  ci->last_used = tmp32;
739  READ(read_string(&ci->last_topic, f));
741  READ(read_int32(&tmp32, f));
742  ci->last_topic_time = tmp32;
743  READ(read_uint32(&ci->flags, f));
744  /* Temporary flags cleanup */
745  ci->flags &= ~0x80000000;
746  READ(read_string(&ci->forbidby, f));
747  READ(read_string(&ci->forbidreason, f));
748  READ(read_int16(&tmp16, f));
749  ci->bantype = tmp16;
750  READ(read_int16(&tmp16, f));
751  n_levels = tmp16;
752  ci->levels = calloc(36 * sizeof(*ci->levels), 1);
753  for (j = 0; j < n_levels; j++) {
754  if (j < 36)
755  READ(read_int16(&ci->levels[j], f));
756  else
757  READ(read_int16(&tmp16, f));
758  }
759  READ(read_uint16(&ci->accesscount, f));
760  if (ci->accesscount) {
761  ci->access = calloc(ci->accesscount, sizeof(ChanAccess));
762  for (j = 0; j < ci->accesscount; j++) {
763  READ(read_uint16(&ci->access[j].in_use, f));
764  if (ci->access[j].in_use) {
765  READ(read_int16(&ci->access[j].level, f));
766  READ(read_string(&s, f));
767  if (s) {
768  ci->access[j].nc = findcore(s, 0);
769  free(s);
770  }
771  if (ci->access[j].nc == NULL)
772  ci->access[j].in_use = 0;
773  READ(read_int32(&tmp32, f));
774  ci->access[j].last_seen = tmp32;
775  }
776  }
777  } else {
778  ci->access = NULL;
779  }
780  READ(read_uint16(&ci->akickcount, f));
781  if (ci->akickcount) {
782  ci->akick = calloc(ci->akickcount, sizeof(AutoKick));
783  for (j = 0; j < ci->akickcount; j++) {
784  SAFE(read_uint16(&ci->akick[j].flags, f));
785  if (ci->akick[j].flags & 0x0001) {
786  SAFE(read_string(&s, f));
787  if (ci->akick[j].flags & 0x0002) {
788  ci->akick[j].u.nc = findcore(s, 0);
789  if (!ci->akick[j].u.nc)
790  ci->akick[j].flags &= ~0x0001;
791  free(s);
792  } else {
793  ci->akick[j].u.mask = s;
794  }
795  SAFE(read_string(&s, f));
796  if (ci->akick[j].flags & 0x0001)
797  ci->akick[j].reason = s;
798  else if (s)
799  free(s);
800  SAFE(read_string(&s, f));
801  if (ci->akick[j].flags & 0x0001) {
802  ci->akick[j].creator = s;
803  } else if (s) {
804  free(s);
805  }
806  SAFE(read_int32(&tmp32, f));
807  if (ci->akick[j].flags & 0x0001)
808  ci->akick[j].addtime = tmp32;
809  }
810  }
811  } else {
812  ci->akick = NULL;
813  }
814  READ(read_uint32(&ci->mlock_on, f));
815  READ(read_uint32(&ci->mlock_off, f));
816  READ(read_uint32(&ci->mlock_limit, f));
817  READ(read_string(&ci->mlock_key, f));
818  READ(read_string(&ci->mlock_flood, f));
819  READ(read_string(&ci->mlock_redirect, f));
820  READ(read_int16(&ci->memos.memocount, f));
821  READ(read_int16(&ci->memos.memomax, f));
822  if (ci->memos.memocount) {
823  Memo *memos;
824  memos = calloc(sizeof(Memo) * ci->memos.memocount, 1);
825  ci->memos.memos = memos;
826  for (j = 0; j < ci->memos.memocount; j++, memos++) {
827  READ(read_uint32(&memos->number, f));
828  READ(read_uint16(&memos->flags, f));
829  READ(read_int32(&tmp32, f));
830  memos->time = tmp32;
831  READ(read_buffer(memos->sender, f));
832  READ(read_string(&memos->text, f));
833  }
834  }
835  READ(read_string(&ci->entry_message, f));
836 
837  /* BotServ options */
838  READ(read_string(&ci->bi, f));
839  READ(read_int32(&tmp32, f));
840  ci->botflags = tmp32;
841  READ(read_int16(&tmp16, f));
842  n_ttb = tmp16;
843  ci->ttb = calloc(2 * 8, 1);
844  for (j = 0; j < n_ttb; j++) {
845  if (j < 8)
846  READ(read_int16(&ci->ttb[j], f));
847  else
848  READ(read_int16(&tmp16, f));
849  }
850  for (j = n_ttb; j < 8; j++)
851  ci->ttb[j] = 0;
852  READ(read_int16(&tmp16, f));
853  ci->capsmin = tmp16;
854  READ(read_int16(&tmp16, f));
855  ci->capspercent = tmp16;
856  READ(read_int16(&tmp16, f));
857  ci->floodlines = tmp16;
858  READ(read_int16(&tmp16, f));
859  ci->floodsecs = tmp16;
860  READ(read_int16(&tmp16, f));
861  ci->repeattimes = tmp16;
862 
863  READ(read_uint16(&ci->bwcount, f));
864  if (ci->bwcount) {
865  ci->badwords = calloc(ci->bwcount, sizeof(BadWord));
866  for (j = 0; j < ci->bwcount; j++) {
867  SAFE(read_uint16(&ci->badwords[j].in_use, f));
868  if (ci->badwords[j].in_use) {
869  SAFE(read_string(&ci->badwords[j].word, f));
870  SAFE(read_uint16(&ci->badwords[j].type, f));
871  }
872  }
873  } else {
874  ci->badwords = NULL;
875  }
876  } /* getc_db() */
877  *last = NULL;
878  } /* for() loop */
879  close_db(f);
880  } else
881  nochan = 1;
882 
883  /* IIb: Second database */
884  if (!nochan) {
885  if ((f = open_db_read("ChanServ", CHAN_DB_2, 16))) {
886  int c;
887 
888  for (i = 0; i < 256; i++) {
889  int16 tmp16;
890  int32 tmp32;
891  int n_levels;
892  char *s;
893  int n_ttb;
894  /* Unused variables - why? -GD
895  char input[1024];
896  NickAlias *na;
897  int J;
898  */
899 
900  while ((c = getc_db(f)) == 1) {
901  ChannelInfo *ci = NULL, *ciptr = NULL;
902  int j;
903 
904  if (c != 1) {
905  printf("Invalid format in %s.\n", CHAN_DB_2);
906  exit(0);
907  }
908 
909  ci = calloc(sizeof(ChannelInfo), 1);
910  READ(read_buffer(ci->name, f));
911  READ(read_string(&ci->founder, f));
912  READ(read_string(&ci->successor, f));
913  READ(read_buffer(ci->founderpass, f));
914  READ(read_string(&ci->desc, f));
915  if (!ci->desc)
916  ci->desc = strdup("");
917  READ(read_string(&ci->url, f));
918  READ(read_string(&ci->email, f));
919  READ(read_int32(&tmp32, f));
920  ci->time_registered = tmp32;
921  READ(read_int32(&tmp32, f));
922  ci->last_used = tmp32;
923  READ(read_string(&ci->last_topic, f));
925  READ(read_int32(&tmp32, f));
926  ci->last_topic_time = tmp32;
927  READ(read_uint32(&ci->flags, f));
928  /* Temporary flags cleanup */
929  ci->flags &= ~0x80000000;
930  READ(read_string(&ci->forbidby, f));
931  READ(read_string(&ci->forbidreason, f));
932  READ(read_int16(&tmp16, f));
933  ci->bantype = tmp16;
934  READ(read_int16(&tmp16, f));
935  n_levels = tmp16;
936  ci->levels = calloc(36 * sizeof(*ci->levels), 1);
937  for (j = 0; j < n_levels; j++) {
938  if (j < 36)
939  READ(read_int16(&ci->levels[j], f));
940  else
941  READ(read_int16(&tmp16, f));
942  }
943  READ(read_uint16(&ci->accesscount, f));
944  if (ci->accesscount) {
945  ci->access = calloc(ci->accesscount, sizeof(ChanAccess));
946  for (j = 0; j < ci->accesscount; j++) {
947  READ(read_uint16(&ci->access[j].in_use, f));
948  if (ci->access[j].in_use) {
949  READ(read_int16(&ci->access[j].level, f));
950  READ(read_string(&s, f));
951  if (s) {
952  ci->access[j].nc = findcore(s, 0);
953  free(s);
954  }
955  if (ci->access[j].nc == NULL)
956  ci->access[j].in_use = 0;
957  READ(read_int32(&tmp32, f));
958  ci->access[j].last_seen = tmp32;
959  }
960  }
961  } else {
962  ci->access = NULL;
963  }
964  READ(read_uint16(&ci->akickcount, f));
965  if (ci->akickcount) {
966  ci->akick = calloc(ci->akickcount, sizeof(AutoKick));
967  for (j = 0; j < ci->akickcount; j++) {
968  SAFE(read_uint16(&ci->akick[j].flags, f));
969  if (ci->akick[j].flags & 0x0001) {
970  SAFE(read_string(&s, f));
971  if (ci->akick[j].flags & 0x0002) {
972  ci->akick[j].u.nc = findcore(s, 0);
973  if (!ci->akick[j].u.nc)
974  ci->akick[j].flags &= ~0x0001;
975  free(s);
976  } else {
977  ci->akick[j].u.mask = s;
978  }
979  SAFE(read_string(&s, f));
980  if (ci->akick[j].flags & 0x0001)
981  ci->akick[j].reason = s;
982  else if (s)
983  free(s);
984  SAFE(read_string(&s, f));
985  if (ci->akick[j].flags & 0x0001) {
986  ci->akick[j].creator = s;
987  } else if (s) {
988  free(s);
989  }
990  SAFE(read_int32(&tmp32, f));
991  if (ci->akick[j].flags & 0x0001)
992  ci->akick[j].addtime = tmp32;
993  }
994  }
995  } else {
996  ci->akick = NULL;
997  }
998  READ(read_uint32(&ci->mlock_on, f));
999  READ(read_uint32(&ci->mlock_off, f));
1000  READ(read_uint32(&ci->mlock_limit, f));
1001  READ(read_string(&ci->mlock_key, f));
1002  READ(read_string(&ci->mlock_flood, f));
1003  READ(read_string(&ci->mlock_redirect, f));
1004  READ(read_int16(&ci->memos.memocount, f));
1005  READ(read_int16(&ci->memos.memomax, f));
1006  if (ci->memos.memocount) {
1007  Memo *memos;
1008  memos = calloc(sizeof(Memo) * ci->memos.memocount, 1);
1009  ci->memos.memos = memos;
1010  for (j = 0; j < ci->memos.memocount; j++, memos++) {
1011  READ(read_uint32(&memos->number, f));
1012  READ(read_uint16(&memos->flags, f));
1013  READ(read_int32(&tmp32, f));
1014  memos->time = tmp32;
1015  READ(read_buffer(memos->sender, f));
1016  READ(read_string(&memos->text, f));
1017  }
1018  }
1019  READ(read_string(&ci->entry_message, f));
1020 
1021  /* BotServ options */
1022  READ(read_string(&ci->bi, f));
1023  READ(read_int32(&tmp32, f));
1024  ci->botflags = tmp32;
1025  READ(read_int16(&tmp16, f));
1026  n_ttb = tmp16;
1027  ci->ttb = calloc(32, 1);
1028  for (j = 0; j < n_ttb; j++) {
1029  if (j < 8)
1030  READ(read_int16(&ci->ttb[j], f));
1031  else
1032  READ(read_int16(&tmp16, f));
1033  }
1034  for (j = n_ttb; j < 8; j++)
1035  ci->ttb[j] = 0;
1036  READ(read_int16(&tmp16, f));
1037  ci->capsmin = tmp16;
1038  READ(read_int16(&tmp16, f));
1039  ci->capspercent = tmp16;
1040  READ(read_int16(&tmp16, f));
1041  ci->floodlines = tmp16;
1042  READ(read_int16(&tmp16, f));
1043  ci->floodsecs = tmp16;
1044  READ(read_int16(&tmp16, f));
1045  ci->repeattimes = tmp16;
1046 
1047  READ(read_uint16(&ci->bwcount, f));
1048  if (ci->bwcount) {
1049  ci->badwords = calloc(ci->bwcount, sizeof(BadWord));
1050  for (j = 0; j < ci->bwcount; j++) {
1051  SAFE(read_uint16(&ci->badwords[j].in_use, f));
1052  if (ci->badwords[j].in_use) {
1053  SAFE(read_string(&ci->badwords[j].word, f));
1054  SAFE(read_uint16(&ci->badwords[j].type, f));
1055  }
1056  }
1057  } else {
1058  ci->badwords = NULL;
1059  }
1060  /* READING DONE */
1061  ciptr = cs_findchan(ci->name);
1062  if (ciptr) { /* COLLISION! ciptr = old = 1; ci = new = 2*/
1063  char input[1024];
1064 
1066  printf("Chan collision for channel %s:\n\n", ci->name);
1067 
1068  printf("Owner of channel 1: %s (%s)\n", (ciptr->founder) ? ciptr->founder : "none", (ciptr->email) ? ciptr->email : "no valid email");
1069  printf("Accesscount: %u\n", ciptr->accesscount);
1070  if (ciptr->flags & 0x00000080) {
1071  printf("Status: Channel is forbidden");
1072  } else if (ciptr->flags & 0x00010000) {
1073  printf("Status: Channel is suspended");
1074  }
1075  printf("Time registered: %s\n", ctime(&ciptr->time_registered));
1076 
1077  printf("Owner of channel 2: %s (%s)\n", (ci->founder) ? ci->founder : "none", (ci->email) ? ci->email : "no valid email");
1078  printf("Accesscount: %u\n", ci->accesscount);
1079  if (ci->flags & 0x00000080) {
1080  printf("Status: Channel is forbidden");
1081  } else if (ci->flags & 0x00010000) {
1082  printf("Status: Channel is suspended");
1083  }
1084  printf("Time registered: %s\n", ctime(&ci->time_registered));
1085 
1086  printf("What channel do you want to keep? Enter the related number \"1\" or \"2\".\n");
1087  }
1088 
1089  if (preferoldest) {
1090  input[0] = (ci->time_registered > ciptr->time_registered) ? '1' : '2';
1091  } else if (prefernewest) {
1092  input[0] = (ci->time_registered > ciptr->time_registered) ? '2' : '1';
1093  } else if (preferfirst) {
1094  input[0] = '1';
1095  } else if (prefersecond) {
1096  input[0] = '2';
1097  } else {
1098  waiting_for_input4:
1099  scanf("%s", input);
1100  }
1101  if (input[0] == '1') { /* #2 isn't in the list yet, #1 is. -> free() #2 [ci] */
1102  NickCore *nc = NULL;
1103  int i;
1104  printf("Deleting chan %s (#2).\n", ci->name);
1105 
1106  if (ci->founder) {
1107  nc = findcore(ci->founder, 0);
1108  if (nc)
1109  nc->channelcount--;
1110  }
1111  free(ci->desc);
1112  free(ci->founder);
1113  free(ci->successor);
1114  if (ci->url)
1115  free(ci->url);
1116  if (ci->email)
1117  free(ci->email);
1118  if (ci->last_topic)
1119  free(ci->last_topic);
1120  if (ci->forbidby)
1121  free(ci->forbidby);
1122  if (ci->forbidreason)
1123  free(ci->forbidreason);
1124  if (ci->mlock_key)
1125  free(ci->mlock_key);
1126  if (ci->mlock_flood)
1127  free(ci->mlock_flood);
1128  if (ci->mlock_redirect)
1129  free(ci->mlock_redirect);
1130  if (ci->entry_message)
1131  free(ci->entry_message);
1132  if (ci->access)
1133  free(ci->access);
1134  for (i = 0; i < ci->akickcount; i++) {
1135  if (!(ci->akick[i].flags & 0x0002) && ci->akick[i].u.mask)
1136  free(ci->akick[i].u.mask);
1137  if (ci->akick[i].reason)
1138  free(ci->akick[i].reason);
1139  if (ci->akick[i].creator)
1140  free(ci->akick[i].creator);
1141  }
1142  if (ci->akick)
1143  free(ci->akick);
1144  if (ci->levels)
1145  free(ci->levels);
1146  if (ci->memos.memos) {
1147  for (i = 0; i < ci->memos.memocount; i++) {
1148  if (ci->memos.memos[i].text)
1149  free(ci->memos.memos[i].text);
1150  }
1151  free(ci->memos.memos);
1152  }
1153  if (ci->ttb)
1154  free(ci->ttb);
1155  for (i = 0; i < ci->bwcount; i++) {
1156  if (ci->badwords[i].word)
1157  free(ci->badwords[i].word);
1158  }
1159  if (ci->badwords)
1160  free(ci->badwords);
1161  if (ci->bi)
1162  free(ci->bi);
1163  free(ci);
1164 
1165  } else if (input[0] == '2') { /* get #1 out of the list, free() it and add #2 to the list */
1166  NickCore *nc = NULL;
1167  printf("Deleting chan %s (#1).\n", ciptr->name);
1168 
1169  if (ciptr->next)
1170  ciptr->next->prev = ciptr->prev;
1171  if (ciptr->prev)
1172  ciptr->prev->next = ciptr->next;
1173  else
1174  chanlists[tolower(ciptr->name[1])] = ciptr->next;
1175 
1176  if (ciptr->founder) {
1177  nc = findcore(ciptr->founder, 0);
1178  if (nc)
1179  nc->channelcount--;
1180  }
1181  free(ciptr->desc);
1182  if (ciptr->url)
1183  free(ciptr->url);
1184  if (ciptr->email)
1185  free(ciptr->email);
1186  if (ciptr->last_topic)
1187  free(ciptr->last_topic);
1188  if (ciptr->forbidby)
1189  free(ciptr->forbidby);
1190  if (ciptr->forbidreason)
1191  free(ciptr->forbidreason);
1192  if (ciptr->mlock_key)
1193  free(ciptr->mlock_key);
1194  if (ciptr->mlock_flood)
1195  free(ciptr->mlock_flood);
1196  if (ciptr->mlock_redirect)
1197  free(ciptr->mlock_redirect);
1198  if (ciptr->entry_message)
1199  free(ciptr->entry_message);
1200  if (ciptr->access)
1201  free(ciptr->access);
1202  for (i = 0; i < ciptr->akickcount; i++) {
1203  if (!(ciptr->akick[i].flags & 0x0002) && ciptr->akick[i].u.mask)
1204  free(ciptr->akick[i].u.mask);
1205  if (ciptr->akick[i].reason)
1206  free(ciptr->akick[i].reason);
1207  if (ciptr->akick[i].creator)
1208  free(ciptr->akick[i].creator);
1209  }
1210  if (ciptr->akick)
1211  free(ciptr->akick);
1212  if (ciptr->levels)
1213  free(ciptr->levels);
1214  if (ciptr->memos.memos) {
1215  for (i = 0; i < ciptr->memos.memocount; i++) {
1216  if (ciptr->memos.memos[i].text)
1217  free(ciptr->memos.memos[i].text);
1218  }
1219  free(ciptr->memos.memos);
1220  }
1221  if (ciptr->ttb)
1222  free(ciptr->ttb);
1223  for (i = 0; i < ciptr->bwcount; i++) {
1224  if (ciptr->badwords[i].word)
1225  free(ciptr->badwords[i].word);
1226  }
1227  if (ciptr->badwords)
1228  free(ciptr->badwords);
1229  free(ciptr);
1230 
1231  alpha_insert_chan(ci);
1232 
1233  } else {
1234  printf("Invalid number, give us a valid one (1 or 2).\n");
1235  goto waiting_for_input4;
1236  }
1237  } else { /* no collision, put the chan into the list */
1238  alpha_insert_chan(ci);
1239  }
1240  } /* getc_db() */
1241  } /* for() loop */
1242  close_db(f);
1243  } else
1244  nochan = 1;
1245  }
1246 
1247  /* IIc: Saving */
1248  if (!nochan) {
1249  if ((f = open_db_write("ChanServ", CHAN_DB_NEW, 16))) {
1250  ChannelInfo *ci;
1251  Memo *memos;
1252  /* Unused variable - why? -GD
1253  static time_t lastwarn = 0;
1254  */
1255 
1256  for (i = 0; i < 256; i++) {
1257  int16 tmp16;
1258  for (ci = chanlists[i]; ci; ci = ci->next) {
1259  int j;
1260  SAFE(write_int8(1, f));
1261  SAFE(write_buffer(ci->name, f));
1262  if (ci->founder)
1263  SAFE(write_string(ci->founder, f));
1264  else
1265  SAFE(write_string(NULL, f));
1266  if (ci->successor)
1267  SAFE(write_string(ci->successor, f));
1268  else
1269  SAFE(write_string(NULL, f));
1270  SAFE(write_buffer(ci->founderpass, f));
1271  SAFE(write_string(ci->desc, f));
1272  SAFE(write_string(ci->url, f));
1273  SAFE(write_string(ci->email, f));
1274  SAFE(write_int32(ci->time_registered, f));
1275  SAFE(write_int32(ci->last_used, f));
1276  SAFE(write_string(ci->last_topic, f));
1278  SAFE(write_int32(ci->last_topic_time, f));
1279  SAFE(write_int32(ci->flags, f));
1280  SAFE(write_string(ci->forbidby, f));
1281  SAFE(write_string(ci->forbidreason, f));
1282  SAFE(write_int16(ci->bantype, f));
1283  tmp16 = 36;
1284  SAFE(write_int16(tmp16, f));
1285  for (j = 0; j < 36; j++)
1286  SAFE(write_int16(ci->levels[j], f));
1287 
1288  SAFE(write_int16(ci->accesscount, f));
1289  for (j = 0; j < ci->accesscount; j++) {
1290  SAFE(write_int16(ci->access[j].in_use, f));
1291  if (ci->access[j].in_use) {
1292  SAFE(write_int16(ci->access[j].level, f));
1293  SAFE(write_string(ci->access[j].nc->display, f));
1294  SAFE(write_int32(ci->access[j].last_seen, f));
1295  }
1296  }
1297  SAFE(write_int16(ci->akickcount, f));
1298  for (j = 0; j < ci->akickcount; j++) {
1299  SAFE(write_int16(ci->akick[j].flags, f));
1300  if (ci->akick[j].flags & 0x0001) {
1301  if (ci->akick[j].flags & 0x0002)
1302  SAFE(write_string(ci->akick[j].u.nc->display, f));
1303  else
1304  SAFE(write_string(ci->akick[j].u.mask, f));
1305  SAFE(write_string(ci->akick[j].reason, f));
1306  SAFE(write_string(ci->akick[j].creator, f));
1307  SAFE(write_int32(ci->akick[j].addtime, f));
1308  }
1309  }
1310 
1311  SAFE(write_int32(ci->mlock_on, f));
1312  SAFE(write_int32(ci->mlock_off, f));
1313  SAFE(write_int32(ci->mlock_limit, f));
1314  SAFE(write_string(ci->mlock_key, f));
1315  SAFE(write_string(ci->mlock_flood, f));
1316  SAFE(write_string(ci->mlock_redirect, f));
1317  SAFE(write_int16(ci->memos.memocount, f));
1318  SAFE(write_int16(ci->memos.memomax, f));
1319  memos = ci->memos.memos;
1320  for (j = 0; j < ci->memos.memocount; j++, memos++) {
1321  SAFE(write_int32(memos->number, f));
1322  SAFE(write_int16(memos->flags, f));
1323  SAFE(write_int32(memos->time, f));
1324  SAFE(write_buffer(memos->sender, f));
1325  SAFE(write_string(memos->text, f));
1326  }
1327  SAFE(write_string(ci->entry_message, f));
1328  if (ci->bi)
1329  SAFE(write_string(ci->bi, f));
1330  else
1331  SAFE(write_string(NULL, f));
1332  SAFE(write_int32(ci->botflags, f));
1333  tmp16 = 8;
1334  SAFE(write_int16(tmp16, f));
1335  for (j = 0; j < 8; j++)
1336  SAFE(write_int16(ci->ttb[j], f));
1337  SAFE(write_int16(ci->capsmin, f));
1338  SAFE(write_int16(ci->capspercent, f));
1339  SAFE(write_int16(ci->floodlines, f));
1340  SAFE(write_int16(ci->floodsecs, f));
1341  SAFE(write_int16(ci->repeattimes, f));
1342 
1343  SAFE(write_int16(ci->bwcount, f));
1344  for (j = 0; j < ci->bwcount; j++) {
1345  SAFE(write_int16(ci->badwords[j].in_use, f));
1346  if (ci->badwords[j].in_use) {
1347  SAFE(write_string(ci->badwords[j].word, f));
1348  SAFE(write_int16(ci->badwords[j].type, f));
1349  }
1350  }
1351  } /* for (chanlists[i]) */
1352  SAFE(write_int8(0, f));
1353  } /* for (i) */
1354  close_db(f);
1355  printf("Chan merging done. New database saved as %s.\n", CHAN_DB_NEW);
1356  }
1357  }
1358 
1359  /* Section III: Bots */
1360  /* IIIa: First database */
1361  if ((f = open_db_read("Botserv", BOT_DB_1, 10))) {
1362  BotInfo *bi;
1363  int c;
1364  int32 tmp32;
1365  int16 tmp16;
1366 
1367  printf("Trying to merge bots...\n");
1368 
1369  while ((c = getc_db(f)) == 1) {
1370  if (c != 1) {
1371  printf("Invalid format in %s.\n", BOT_DB_1);
1372  exit(0);
1373  }
1374 
1375  bi = calloc(sizeof(BotInfo), 1);
1376  READ(read_string(&bi->nick, f));
1377  READ(read_string(&bi->user, f));
1378  READ(read_string(&bi->host, f));
1379  READ(read_string(&bi->real, f));
1380  SAFE(read_int16(&tmp16, f));
1381  bi->flags = tmp16;
1382  READ(read_int32(&tmp32, f));
1383  bi->created = tmp32;
1384  READ(read_int16(&tmp16, f));
1385  bi->chancount = tmp16;
1386  insert_bot(bi);
1387  }
1388  } else
1389  nobot = 1;
1390 
1391  /* IIIb: Second database */
1392  if (!nobot) {
1393  if ((f = open_db_read("Botserv", BOT_DB_2, 10))) {
1394  BotInfo *bi, *biptr;
1395  int c;
1396  int32 tmp32;
1397  int16 tmp16;
1398  char input[1024];
1399 
1400  while ((c = getc_db(f)) == 1) {
1401  if (c != 1) {
1402  printf("Invalid format in %s.\n", BOT_DB_2);
1403  exit(0);
1404  }
1405 
1406  bi = calloc(sizeof(BotInfo), 1);
1407  READ(read_string(&bi->nick, f));
1408  READ(read_string(&bi->user, f));
1409  READ(read_string(&bi->host, f));
1410  READ(read_string(&bi->real, f));
1411  SAFE(read_int16(&tmp16, f));
1412  bi->flags = tmp16;
1413  READ(read_int32(&tmp32, f));
1414  bi->created = tmp32;
1415  READ(read_int16(&tmp16, f));
1416  bi->chancount = tmp16;
1417  biptr = findbot(bi->nick);
1418  if (biptr) { /* BOT COLLISION! #1 is biptr-> (db1), #2 is bi-> (db2) */
1420  printf("Bot collision for botnick %s:\n\n", biptr->nick);
1421  printf("Bot 1: %s@%s (%s) is assigned to %d chans\n", biptr->user, biptr->host, biptr->real, biptr->chancount);
1422  printf("Time registered: %s\n", ctime(&biptr->created));
1423  printf("Bot 2: %s@%s (%s) is assigned to %d chans\n", bi->user, bi->host, bi->real, bi->chancount);
1424  printf("Time registered: %s\n", ctime(&bi->created));
1425  printf("What bot do you want to keep? Enter the related bot number \"1\" or \"2\".\n");
1426  }
1427 
1428  if (preferoldest) {
1429  input[0] = (biptr->created > bi->created) ? '1' : '2';
1430  } else if (prefernewest) {
1431  input[0] = (biptr->created > bi->created) ? '2' : '1';
1432  } else if (preferfirst) {
1433  input[0] = '2';
1434  } else if (prefersecond) {
1435  input[0] = '1';
1436  } else {
1437  waiting_for_input3:
1438  scanf("%s", input);
1439  }
1440  if (input[0] == '1') { /* free() bot #2 (bi) */
1441  printf("Deleting Bot %s!%s@%s (%s) (#2).\n", bi->nick, bi->user, bi->host, bi->real);
1442  free(bi->nick);
1443  free(bi->user);
1444  free(bi->host);
1445  free(bi->real);
1446  free(bi);
1447  } else if (input[0] == '2') { /* get bot #1 (biptr) out of the list, free() it and add #2 to the list */
1448  printf("Deleting Bot %s!%s@%s (%s) (#1).\n", biptr->nick, biptr->user, biptr->host, biptr->real);
1449  if (biptr->next)
1450  biptr->next->prev = biptr->prev;
1451  if (biptr->prev)
1452  biptr->prev->next = biptr->next;
1453  else
1454  botlists[tolower(*biptr->nick)] = biptr->next;
1455  free(biptr->nick);
1456  free(biptr->user);
1457  free(biptr->host);
1458  free(biptr->real);
1459  free(biptr);
1460  insert_bot(bi);
1461  } else {
1462  printf("Invalid number, give us a valid one (1 or 2).\n");
1463  goto waiting_for_input3;
1464  }
1465  } /* NO COLLISION (biptr) */
1466  else
1467  insert_bot(bi);
1468  }
1469  } else
1470  nobot = 1;
1471  }
1472 
1473  /* IIIc: Saving */
1474  if (!nobot) {
1475  if ((f = open_db_write("Botserv", BOT_DB_NEW, 10))) {
1476  BotInfo *bi;
1477  for (i = 0; i < 256; i++) {
1478  for (bi = botlists[i]; bi; bi = bi->next) {
1479  SAFE(write_int8(1, f));
1480  SAFE(write_string(bi->nick, f));
1481  SAFE(write_string(bi->user, f));
1482  SAFE(write_string(bi->host, f));
1483  SAFE(write_string(bi->real, f));
1484  SAFE(write_int16(bi->flags, f));
1485  SAFE(write_int32(bi->created, f));
1486  SAFE(write_int16(bi->chancount, f));
1487  }
1488  }
1489  SAFE(write_int8(0, f));
1490  close_db(f);
1491  printf("Bot merging done. New database saved as %s.\n", BOT_DB_NEW);
1492  }
1493  } /* End of section III */
1494 
1495  /* Section IV: Hosts */
1496  /* IVa: First database */
1497  if ((f = open_db_read("HostServ", HOST_DB_1, 3))) {
1498  HostCore *hc;
1499  int c;
1500  int32 tmp32;
1501 
1502  printf("Trying to merge hosts...\n");
1503 
1504  while ((c = getc_db(f)) == 1) {
1505  if (c != 1) {
1506  printf("Invalid format in %s.\n", HOST_DB_1);
1507  exit(0);
1508  }
1509  hc = calloc(1, sizeof(HostCore));
1510  READ(read_string(&hc->nick, f));
1511  READ(read_string(&hc->vIdent, f));
1512  READ(read_string(&hc->vHost, f));
1513  READ(read_string(&hc->creator, f));
1514  READ(read_int32(&tmp32, f));
1515  hc->time = tmp32;
1516  hc->next = firsthc;
1517  if (firsthc)
1518  firsthc->last = hc;
1519  hc->last = NULL;
1520  firsthc = hc;
1521  }
1522  } else
1523  nohost = 1;
1524 
1525  /* IVb: Second database */
1526  if (!nohost) {
1527  if ((f = open_db_read("HostServ", HOST_DB_2, 3))) {
1528  HostCore *hc, *hcptr;
1529  char input[1024];
1530  int32 tmp32;
1531  int c;
1532  int collision = 0;
1533 
1534  while ((c = getc_db(f)) == 1) {
1535  if (c != 1) {
1536  printf("Invalid format in %s.\n", HOST_DB_2);
1537  exit(0);
1538  }
1539  collision = 0;
1540  hc = calloc(1, sizeof(HostCore));
1541  READ(read_string(&hc->nick, f));
1542  READ(read_string(&hc->vIdent, f));
1543  READ(read_string(&hc->vHost, f));
1544  READ(read_string(&hc->creator, f));
1545  READ(read_int32(&tmp32, f));
1546  hc->time = tmp32;
1547 
1548  for (hcptr = firsthc; hcptr; hcptr = hcptr->next) {
1549  if (!mystricmp(hcptr->nick, hc->nick)) { /* COLLISION: #1 is from db1 (hcptr), #2 is from db2 (hc) */
1550  collision++;
1552  printf("vHost collision for nick %s:\n\n", hcptr->nick);
1553  printf("vHost 1: %s (vIdent: %s)\n", hcptr->vHost, (hcptr->vIdent) ? hcptr->vIdent : "none");
1554  printf("Time set: %s\n", ctime(&hcptr->time));
1555  printf("vHost 2: %s (vIdent: %s)\n", hc->vHost, (hc->vIdent) ? hc->vIdent : "none");
1556  printf("Time set: %s\n", ctime(&hc->time));
1557  printf("What vhost do you want to keep? Enter the related number \"1\" or \"2\".\n");
1558  }
1559  if (preferoldest) {
1560  input[0] = (hcptr->time > hc->time) ? '1' : '2';
1561  } else if (prefernewest) {
1562  input[0] = (hcptr->time > hc->time) ? '2' : '1';
1563  } else if (preferfirst) {
1564  input[0] = '1';
1565  } else if (prefersecond) {
1566  input[0] = '2';
1567  } else {
1568  waiting_for_input2:
1569  scanf("%s", input);
1570  }
1571  if (input[0] == '2') { /* free() hcptr and get it out of the list, put hc into the list */
1572  printf("Deleting vHost %s (vIdent: %s) for nick %s (#1).\n", hcptr->vHost, (hcptr->vIdent) ? hcptr->vIdent : "none", hcptr->nick);
1573  free(hcptr->nick);
1574  hcptr->nick = hc->nick;
1575  free(hcptr->vHost);
1576  hcptr->vHost = hc->vHost;
1577  free(hcptr->vIdent);
1578  hcptr->vIdent = hc->vIdent;
1579  free(hcptr->creator);
1580  hcptr->creator = hc->creator;
1581  hcptr->time = hc->time;
1582  free(hc);
1583  } else if (input[0] == '1') { /* free() hc */
1584  printf("Deleting vHost %s (vIdent: %s) for nick %s (#2).\n", hc->vHost, (hc->vIdent) ? hc->vIdent : "none", hc->nick);
1585  free(hc->nick);
1586  free(hc->vHost);
1587  free(hc->vIdent);
1588  free(hc->creator);
1589  free(hc);
1590  } else {
1591  printf("Invalid number, give us a valid one (1 or 2).\n");
1592  goto waiting_for_input2;
1593  } /* input[0] */
1594  } /* mystricmp */
1595  } /* for (hcptr...) */
1596  if (!collision) { /* No collision */
1597  hc->next = firsthc;
1598  if (firsthc)
1599  firsthc->last = hc;
1600  hc->last = NULL;
1601  firsthc = hc;
1602  }
1603  } /* while */
1604  } else
1605  nohost = 1;
1606  }
1607 
1608  /* IVc: Saving */
1609  if (!nohost) {
1610  if ((f = open_db_write("HostServ", HOST_DB_NEW, 3))) {
1611  HostCore *hcptr;
1612  for (hcptr = firsthc; hcptr; hcptr = hcptr->next) {
1613  SAFE(write_int8(1, f));
1614  SAFE(write_string(hcptr->nick, f));
1615  SAFE(write_string(hcptr->vIdent, f));
1616  SAFE(write_string(hcptr->vHost, f));
1617  SAFE(write_string(hcptr->creator, f));
1618  SAFE(write_int32(hcptr->time, f));
1619  }
1620  SAFE(write_int8(0, f));
1621  close_db(f);
1622  printf("Host merging done. New database saved as %s.\n", HOST_DB_NEW);
1623  }
1624  } /* End of section IV */
1625 
1626  /* MERGING DONE \o/ HURRAY! */
1627 
1628  printf("\n\nMerging is now done. I give NO guarantee for your DBs.\n");
1629  return 0;
1630 } /* End of main() */
1631 
1632 /* Open a database file for reading and check for the version */
1633 dbFILE *open_db_read(const char *service, const char *filename, int version)
1634 {
1635  dbFILE *f;
1636  FILE *fp;
1637  int myversion;
1638 
1639  f = calloc(sizeof(*f), 1);
1640  if (!f) {
1641  printf("Can't allocate memory for %s database %s.\n", service, filename);
1642  exit(0);
1643  }
1644  strscpy(f->filename, filename, sizeof(f->filename));
1645  f->mode = 'r';
1646  fp = fopen(f->filename, "rb");
1647  if (!fp) {
1648  printf("Can't read %s database %s.\n", service, f->filename);
1649  free(f);
1650  return NULL;
1651  }
1652  f->fp = fp;
1653  myversion = fgetc(fp) << 24 | fgetc(fp) << 16 | fgetc(fp) << 8 | fgetc(fp);
1654  if (feof(fp)) {
1655  printf("Error reading version number on %s: End of file detected.\n", f->filename);
1656  exit(0);
1657  } else if (myversion < version) {
1658  printf("Unsuported database version (%d) on %s.\n", myversion, f->filename);
1659  exit(0);
1660  }
1661  return f;
1662 }
1663 
1664 /* Open a database file for reading and check for the version */
1665 dbFILE *open_db_write(const char *service, const char *filename, int version)
1666 {
1667  dbFILE *f;
1668  int fd;
1669 
1670  f = calloc(sizeof(*f), 1);
1671  if (!f) {
1672  printf("Can't allocate memory for %s database %s.\n", service, filename);
1673  exit(0);
1674  }
1675  strscpy(f->filename, filename, sizeof(f->filename));
1676  filename = f->filename;
1677 #ifndef _WIN32
1678  unlink(filename);
1679 #else
1680  DeleteFile(filename);
1681 #endif
1682  f->mode = 'w';
1683 #ifndef _WIN32
1684  fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0666);
1685 #else
1686  fd = open(filename, O_WRONLY | O_CREAT | O_EXCL | _O_BINARY, 0666);
1687 #endif
1688  f->fp = fdopen(fd, "wb"); /* will fail and return NULL if fd < 0 */
1689  if (!f->fp || !write_file_version(f, version)) {
1690  printf("Can't write to %s database %s.\n", service, filename);
1691  if (f->fp) {
1692  fclose(f->fp);
1693 #ifndef _WIN32
1694  unlink(filename);
1695 #else
1696  DeleteFile(filename);
1697 #endif
1698  }
1699  free(f);
1700  return NULL;
1701  }
1702  return f;
1703 }
1704 
1705 /* Close it */
1706 void close_db(dbFILE * f)
1707 {
1708  fclose(f->fp);
1709  free(f);
1710 }
1711 
1712 int read_int16(int16 * ret, dbFILE * f)
1713 {
1714  int c1, c2;
1715 
1716  c1 = fgetc(f->fp);
1717  c2 = fgetc(f->fp);
1718  if (c1 == EOF || c2 == EOF)
1719  return -1;
1720  *ret = c1 << 8 | c2;
1721  return 0;
1722 }
1723 
1724 int read_uint16(uint16 * ret, dbFILE * f)
1725 {
1726  int c1, c2;
1727 
1728  c1 = fgetc(f->fp);
1729  c2 = fgetc(f->fp);
1730  if (c1 == EOF || c2 == EOF)
1731  return -1;
1732  *ret = c1 << 8 | c2;
1733  return 0;
1734 }
1735 
1736 
1738 {
1739  if (fputc((val >> 8) & 0xFF, f->fp) == EOF
1740  || fputc(val & 0xFF, f->fp) == EOF)
1741  return -1;
1742  return 0;
1743 }
1744 
1745 int read_int32(int32 * ret, dbFILE * f)
1746 {
1747  int c1, c2, c3, c4;
1748 
1749  c1 = fgetc(f->fp);
1750  c2 = fgetc(f->fp);
1751  c3 = fgetc(f->fp);
1752  c4 = fgetc(f->fp);
1753  if (c1 == EOF || c2 == EOF || c3 == EOF || c4 == EOF)
1754  return -1;
1755  *ret = c1 << 24 | c2 << 16 | c3 << 8 | c4;
1756  return 0;
1757 }
1758 
1759 int read_uint32(uint32 * ret, dbFILE * f)
1760 {
1761  int c1, c2, c3, c4;
1762 
1763  c1 = fgetc(f->fp);
1764  c2 = fgetc(f->fp);
1765  c3 = fgetc(f->fp);
1766  c4 = fgetc(f->fp);
1767  if (c1 == EOF || c2 == EOF || c3 == EOF || c4 == EOF)
1768  return -1;
1769  *ret = c1 << 24 | c2 << 16 | c3 << 8 | c4;
1770  return 0;
1771 }
1772 
1774 {
1775  if (fputc((val >> 24) & 0xFF, f->fp) == EOF)
1776  return -1;
1777  if (fputc((val >> 16) & 0xFF, f->fp) == EOF)
1778  return -1;
1779  if (fputc((val >> 8) & 0xFF, f->fp) == EOF)
1780  return -1;
1781  if (fputc((val) & 0xFF, f->fp) == EOF)
1782  return -1;
1783  return 0;
1784 }
1785 
1786 
1787 int read_ptr(void **ret, dbFILE * f)
1788 {
1789  int c;
1790 
1791  c = fgetc(f->fp);
1792  if (c == EOF)
1793  return -1;
1794  *ret = (c ? (void *) 1 : (void *) 0);
1795  return 0;
1796 }
1797 
1798 int write_ptr(const void *ptr, dbFILE * f)
1799 {
1800  if (fputc(ptr ? 1 : 0, f->fp) == EOF)
1801  return -1;
1802  return 0;
1803 }
1804 
1805 
1806 int read_string(char **ret, dbFILE * f)
1807 {
1808  char *s;
1809  uint16 len;
1810 
1811  if (read_uint16(&len, f) < 0)
1812  return -1;
1813  if (len == 0) {
1814  *ret = NULL;
1815  return 0;
1816  }
1817  s = calloc(len, 1);
1818  if (len != fread(s, 1, len, f->fp)) {
1819  free(s);
1820  return -1;
1821  }
1822  *ret = s;
1823  return 0;
1824 }
1825 
1826 int write_string(const char *s, dbFILE * f)
1827 {
1828  uint32 len;
1829 
1830  if (!s)
1831  return write_int16(0, f);
1832  len = strlen(s);
1833  if (len > 65534)
1834  len = 65534;
1835  if (write_int16((uint16) (len + 1), f) < 0)
1836  return -1;
1837  if (len > 0 && fwrite(s, 1, len, f->fp) != len)
1838  return -1;
1839  if (fputc(0, f->fp) == EOF)
1840  return -1;
1841  return 0;
1842 }
1843 
1844 NickCore *findcore(const char *nick, int unused)
1845 {
1846  NickCore *nc;
1847 
1848  for (nc = nclists[HASH(nick)]; nc; nc = nc->next) {
1849  if (!mystricmp(nc->display, nick))
1850  if ((nc->unused && unused) || (!nc->unused && !unused))
1851  return nc;
1852  }
1853 
1854  return NULL;
1855 }
1856 
1857 NickAlias *findnick(const char *nick)
1858 {
1859  NickAlias *na;
1860 
1861  for (na = nalists[HASH(nick)]; na; na = na->next) {
1862  if (!mystricmp(na->nick, nick))
1863  return na;
1864  }
1865 
1866  return NULL;
1867 }
1868 
1870 {
1871  FILE *fp = f->fp;
1872  if (fputc(version >> 24 & 0xFF, fp) < 0 ||
1873  fputc(version >> 16 & 0xFF, fp) < 0 ||
1874  fputc(version >> 8 & 0xFF, fp) < 0 ||
1875  fputc(version & 0xFF, fp) < 0) {
1876  printf("Error writing version number on %s.\n", f->filename);
1877  exit(0);
1878  }
1879  return 1;
1880 }
1881 
1882 /* strscpy: Copy at most len-1 characters from a string to a buffer, and
1883  * add a null terminator after the last character copied.
1884  */
1885 
1886 char *strscpy(char *d, const char *s, size_t len)
1887 {
1888  char *d_orig = d;
1889 
1890  if (!len)
1891  return d;
1892  while (--len && (*d++ = *s++));
1893  *d = '\0';
1894  return d_orig;
1895 }
1896 
1897 int mystricmp(const char *s1, const char *s2)
1898 {
1899  register int c;
1900 
1901  while ((c = tolower(*s1)) == tolower(*s2)) {
1902  if (c == 0)
1903  return 0;
1904  s1++;
1905  s2++;
1906  }
1907  if (c < tolower(*s2))
1908  return -1;
1909  return 1;
1910 }
1911 
1912 int delnick(NickAlias *na, int donttouchthelist)
1913 {
1914  if (!donttouchthelist) {
1915  /* Remove us from the aliases list */
1916  if (na->next)
1917  na->next->prev = na->prev;
1918  if (na->prev)
1919  na->prev->next = na->next;
1920  else
1921  nalists[HASH(na->nick)] = na->next;
1922  }
1923 
1924  /* free() us */
1925  free(na->nick);
1926  if (na->last_usermask)
1927  free(na->last_usermask);
1928  if (na->last_realname)
1929  free(na->last_realname);
1930  if (na->last_quit)
1931  free(na->last_quit);
1932  free(na);
1933  return 1;
1934 }
1935 
1937 {
1938  int i;
1939  /* Remove the core from the list */
1940  if (nc->next)
1941  nc->next->prev = nc->prev;
1942  if (nc->prev)
1943  nc->prev->next = nc->next;
1944  else
1945  nclists[HASH(nc->display)] = nc->next;
1946 
1947  free(nc->display);
1948  if (nc->email)
1949  free(nc->email);
1950  if (nc->greet)
1951  free(nc->greet);
1952  if (nc->url)
1953  free(nc->url);
1954  if (nc->access) {
1955  for (i = 0; i < nc->accesscount; i++) {
1956  if (nc->access[i])
1957  free(nc->access[i]);
1958  }
1959  free(nc->access);
1960  }
1961  if (nc->memos.memos) {
1962  for (i = 0; i < nc->memos.memocount; i++) {
1963  if (nc->memos.memos[i].text)
1964  free(nc->memos.memos[i].text);
1965  }
1966  free(nc->memos.memos);
1967  }
1968  free(nc);
1969  return 1;
1970 }
1971 
1973 {
1974  BotInfo *ptr, *prev;
1975 
1976  for (prev = NULL, ptr = botlists[tolower(*bi->nick)];
1977  ptr != NULL && mystricmp(ptr->nick, bi->nick) < 0;
1978  prev = ptr, ptr = ptr->next);
1979  bi->prev = prev;
1980  bi->next = ptr;
1981  if (!prev)
1982  botlists[tolower(*bi->nick)] = bi;
1983  else
1984  prev->next = bi;
1985  if (ptr)
1986  ptr->prev = bi;
1987 }
1988 
1989 BotInfo *findbot(char *nick)
1990 {
1991  BotInfo *bi;
1992 
1993  for (bi = botlists[tolower(*nick)]; bi; bi = bi->next)
1994  if (!mystricmp(nick, bi->nick))
1995  return bi;
1996 
1997  return NULL;
1998 }
1999 
2000 ChannelInfo *cs_findchan(const char *chan)
2001 {
2002  ChannelInfo *ci;
2003  for (ci = chanlists[tolower(chan[1])]; ci; ci = ci->next) {
2004  if (!mystricmp(ci->name, chan))
2005  return ci;
2006  }
2007  return NULL;
2008 }
2009 
2011 {
2012  ChannelInfo *ptr, *prev;
2013  char *chan = ci->name;
2014 
2015  for (prev = NULL, ptr = chanlists[tolower(chan[1])];
2016  ptr != NULL && mystricmp(ptr->name, chan) < 0;
2017  prev = ptr, ptr = ptr->next);
2018  ci->prev = prev;
2019  ci->next = ptr;
2020  if (!prev)
2021  chanlists[tolower(chan[1])] = ci;
2022  else
2023  prev->next = ci;
2024  if (ptr)
2025  ptr->prev = ci;
2026 }
2027 
char * url
Definition: services.h:660
time_t time
Definition: services.h:1113
NickCore * nclists[1024]
Definition: db-merger.c:299
NickAlias * findnick(const char *nick)
Definition: db-merger.c:1857
E char * strdup(const char *s)
Definition: compat.c:94
NickCore * prev
Definition: services.h:540
int nonick
Definition: db-merger.c:303
int read_uint16(uint16 *ret, dbFILE *f)
Definition: db-merger.c:1724
uint16 akickcount
Definition: services.h:678
char filename[MAXPATHLEN]
Definition: datafiles.h:29
char sender[NICKMAX]
Definition: services.h:494
int write_file_version(dbFILE *f, uint32 version)
Definition: db-merger.c:1869
char ** access
Definition: services.h:551
void alpha_insert_chan(ChannelInfo *ci)
Definition: db-merger.c:2010
int unused
Definition: db-merger.c:201
uint32 botflags
Definition: services.h:700
#define CHAN_DB_1
Definition: db-merger.c:77
char * url
Definition: services.h:547
char * successor
Definition: db-merger.c:210
char * word
Definition: services.h:642
int16 capspercent
Definition: services.h:705
uint16 type
Definition: services.h:643
char * mlock_redirect
Definition: services.h:685
time_t last_used
Definition: services.h:664
dbFILE * open_db_read(const char *service, const char *filename, int version)
Definition: db-merger.c:1633
char * last_quit
Definition: services.h:527
void insert_bot(BotInfo *bi)
Definition: db-merger.c:1972
char * mlock_flood
Definition: services.h:684
ChannelInfo * prev
Definition: services.h:653
int read_int32(int32 *ret, dbFILE *f)
Definition: db-merger.c:1745
#define BOT_DB_2
Definition: db-merger.c:82
#define HOST_DB_1
Definition: db-merger.c:85
char founderpass[PASSMAX]
Definition: services.h:658
#define C_NONE
Definition: db-merger.c:93
int prefernewest
Definition: db-merger.c:302
int16 level
Definition: services.h:594
NickAlias * next
Definition: services.h:525
int16 chancount
Definition: services.h:579
uint16 language
Definition: services.h:549
int write_int16(uint16 val, dbFILE *f)
Definition: db-merger.c:1737
int preferoldest
Definition: db-merger.c:302
int write_string(const char *s, dbFILE *f)
Definition: db-merger.c:1826
uint16 accesscount
Definition: services.h:550
#define READ(x)
Definition: db-merger.c:113
MemoInfo memos
Definition: services.h:552
int16 memocount
Definition: services.h:505
union AutoKick::@1 u
#define read_buffer(buf, f)
Definition: db-merger.c:102
int read_int16(int16 *ret, dbFILE *f)
Definition: db-merger.c:1712
#define getc_db(f)
Definition: db-merger.c:99
#define NICK_DB_NEW
Definition: db-merger.c:75
char name[CHANMAX]
Definition: services.h:654
time_t last_topic_time
Definition: services.h:667
char last_topic_setter[NICKMAX]
Definition: services.h:666
char * forbidreason
Definition: services.h:671
char * last_topic
Definition: services.h:665
#define BOT_DB_1
Definition: db-merger.c:81
NickCore * nc
Definition: services.h:533
int16 bantype
Definition: services.h:673
char * email
Definition: services.h:661
time_t last_seen
Definition: services.h:596
char * display
Definition: services.h:542
uint16 flags
Definition: services.h:492
#define NICK_DB_1
Definition: db-merger.c:73
int mystricmp(const char *s1, const char *s2)
Definition: db-merger.c:1897
BadWord * badwords
Definition: services.h:704
FILE * fp
Definition: datafiles.h:26
uint32 flags
Definition: services.h:669
char * entry_message
Definition: services.h:688
int16 memomax
Definition: services.h:505
char * text
Definition: services.h:495
#define NICK_DB_2
Definition: db-merger.c:74
int16 flags
Definition: services.h:577
int main(int argc, char *argv[])
Definition: db-merger.c:305
uint16 bwcount
Definition: services.h:703
int delnick(NickAlias *na, int donttouchthelist)
Definition: db-merger.c:1912
NickCore * next
Definition: services.h:540
int nochan
Definition: db-merger.c:303
int32_t int32
Definition: db-merger.c:122
uint16 status
Definition: services.h:532
BotInfo * botlists[256]
Definition: db-merger.c:300
char * strscpy(char *d, const char *s, size_t len)
Definition: db-merger.c:1886
char * reason
Definition: services.h:628
#define write_buffer(buf, f)
Definition: db-merger.c:103
uint16 channelcount
Definition: services.h:553
uint16 accesscount
Definition: services.h:676
HostCore * next
Definition: services.h:1108
#define C_LBLUE
Definition: db-merger.c:92
BotInfo * prev
Definition: services.h:571
uint32 mlock_off
Definition: services.h:681
#define CHAN_DB_2
Definition: db-merger.c:78
int write_ptr(const void *ptr, dbFILE *f)
Definition: db-merger.c:1798
int delcore(NickCore *nc)
Definition: db-merger.c:1936
Command * c
Definition: ns_recover.c:17
#define HASH(nick)
Definition: db-merger.c:100
char * real
Definition: services.h:576
u_int32_t uint32
Definition: db-merger.c:123
#define write_int8(val, f)
Definition: db-merger.c:107
NickCore * nc
Definition: services.h:626
#define BOT_DB_NEW
Definition: db-merger.c:83
char * bi
Definition: db-merger.c:236
uint32 number
Definition: services.h:491
NickCore * nc
Definition: services.h:595
uint32 mlock_limit
Definition: services.h:682
int16_t int16
Definition: db-merger.c:120
time_t time_registered
Definition: services.h:530
int read_uint32(uint32 *ret, dbFILE *f)
Definition: db-merger.c:1759
char * vHost
Definition: services.h:1111
int mode
Definition: datafiles.h:25
char * mask
Definition: services.h:625
BotInfo * findbot(char *nick)
Definition: db-merger.c:1989
int16 floodlines
Definition: services.h:706
char * nick
Definition: services.h:526
int nobot
Definition: db-merger.c:303
uint16 channelmax
Definition: services.h:554
NickAlias * nalists[1024]
Definition: db-merger.c:298
time_t created
Definition: services.h:578
char * last_realname
Definition: services.h:528
int read_ptr(void **ret, dbFILE *f)
Definition: db-merger.c:1787
int preferfirst
Definition: db-merger.c:302
char * vIdent
Definition: services.h:1110
char * founder
Definition: db-merger.c:209
#define tolower
Definition: services.h:190
dbFILE * open_db_write(const char *service, const char *filename, int version)
Definition: db-merger.c:1665
int read_string(char **ret, dbFILE *f)
Definition: db-merger.c:1806
char * host
Definition: services.h:575
BotInfo * next
Definition: services.h:571
int prefersecond
Definition: db-merger.c:302
char * mlock_key
Definition: services.h:683
char pass[PASSMAX]
Definition: services.h:543
MemoInfo memos
Definition: services.h:690
int16 floodsecs
Definition: services.h:706
int16 * ttb
Definition: services.h:701
int write_int32(uint32 val, dbFILE *f)
Definition: db-merger.c:1773
char * nick
Definition: services.h:573
time_t time_registered
Definition: services.h:663
time_t addtime
Definition: services.h:631
ChannelInfo * chanlists[256]
Definition: db-merger.c:297
AutoKick * akick
Definition: services.h:679
int nohost
Definition: db-merger.c:303
uint32 flags
Definition: services.h:548
ChanAccess * access
Definition: services.h:677
#define CHAN_DB_NEW
Definition: db-merger.c:79
int16 capsmin
Definition: services.h:705
char * creator
Definition: services.h:630
uint16 in_use
Definition: services.h:641
int16 * levels
Definition: services.h:674
char version[1024]
Definition: version.sh.c:24
NickAlias * prev
Definition: services.h:525
time_t time
Definition: services.h:493
uint16 flags
Definition: services.h:623
int16 repeattimes
Definition: services.h:707
time_t last_seen
Definition: services.h:531
char * greet
Definition: services.h:545
char * desc
Definition: services.h:659
char * creator
Definition: services.h:1112
Memo * memos
Definition: services.h:506
NickCore * findcore(const char *nick, int version)
Definition: db-merger.c:1844
uint16 in_use
Definition: services.h:593
BotInfo * bi
Definition: services.h:699
NickCore * founder
Definition: services.h:655
char * last_usermask
Definition: services.h:529
HostCore * last
Definition: db-merger.c:264
int aliascount
Definition: db-merger.c:202
char * user
Definition: services.h:574
char * forbidby
Definition: services.h:670
ChannelInfo * next
Definition: services.h:653
#define HOST_DB_2
Definition: db-merger.c:86
uint32 icq
Definition: services.h:546
char * nick
Definition: services.h:1109
#define SAFE(x)
Definition: db-merger.c:108
uint32 mlock_on
Definition: services.h:681
char * email
Definition: services.h:544
NickCore * successor
Definition: services.h:656
void close_db(dbFILE *f)
Definition: db-merger.c:1706
#define HOST_DB_NEW
Definition: db-merger.c:87
ChannelInfo * cs_findchan(const char *chan)
Definition: db-merger.c:2000
u_int16_t uint16
Definition: db-merger.c:121