init.c

Go to the documentation of this file.
00001 /* Initalization and related routines.
00002  *
00003  * (C) 2003-2007 Anope Team
00004  * Contact us at info@anope.org
00005  *
00006  * Please read COPYING and README for further details.
00007  *
00008  * Based on the original code of Epona by Lara.
00009  * Based on the original code of Services by Andy Church. 
00010  * 
00011  * $Id: init.c 1322 2007-12-28 19:12:02Z geniusdex $ 
00012  *
00013  */
00014 
00015 #include "services.h"
00016 #include "pseudo.h"
00017 int servernum = 0;
00018 
00019 extern void moduleAddMsgs(void);
00020 extern void moduleAddIRCDMsgs(void);
00021 
00022 /*************************************************************************/
00023 
00024 void introduce_user(const char *user)
00025 {
00026 
00027     /* Watch out for infinite loops... */
00028 #define LTSIZE 20
00029     static int lasttimes[LTSIZE];
00030     if (lasttimes[0] >= time(NULL) - 3)
00031         fatal("introduce_user() loop detected");
00032     memmove(lasttimes, lasttimes + 1, sizeof(lasttimes) - sizeof(int));
00033     lasttimes[LTSIZE - 1] = time(NULL);
00034 #undef LTSIZE
00035 
00036     /* NickServ */
00037     if (!user || stricmp(user, s_NickServ) == 0) {
00038         anope_cmd_nick(s_NickServ, desc_NickServ, ircd->nickservmode);
00039     }
00040 
00041     /* ChanServ */
00042     if (!user || stricmp(user, s_ChanServ) == 0) {
00043         anope_cmd_nick(s_ChanServ, desc_ChanServ, ircd->chanservmode);
00044     }
00045     if (s_HostServ && ircd->vhost
00046         && (!user || stricmp(user, s_HostServ) == 0)) {
00047         anope_cmd_nick(s_HostServ, desc_HostServ, ircd->hostservmode);
00048     }
00049 
00050     if (!user || stricmp(user, s_MemoServ) == 0) {
00051         anope_cmd_nick(s_MemoServ, desc_MemoServ, ircd->memoservmode);
00052     }
00053 
00054     if (s_BotServ && (!user || stricmp(user, s_BotServ) == 0)) {
00055         anope_cmd_nick(s_BotServ, desc_BotServ, ircd->botservmode);
00056     }
00057 
00058     if (!user || stricmp(user, s_HelpServ) == 0) {
00059         anope_cmd_nick(s_HelpServ, desc_HelpServ, ircd->helpservmode);
00060     }
00061 
00062     if (!user || stricmp(user, s_OperServ) == 0) {
00063         anope_cmd_nick(s_OperServ, desc_OperServ, ircd->operservmode);
00064     }
00065 
00066     if (s_DevNull && (!user || stricmp(user, s_DevNull) == 0)) {
00067         anope_cmd_nick(s_DevNull, desc_DevNull, ircd->devnullmode);
00068     }
00069 
00070     if (!user || stricmp(user, s_GlobalNoticer) == 0) {
00071         anope_cmd_nick(s_GlobalNoticer, desc_GlobalNoticer,
00072                        ircd->globalmode);
00073     }
00074 
00075     /* We make aliases go online */
00076     if (s_NickServAlias && (!user || stricmp(user, s_NickServAlias) == 0)) {
00077         anope_cmd_nick(s_NickServAlias, desc_NickServAlias,
00078                        ircd->nickservaliasmode);
00079     }
00080 
00081     if (s_ChanServAlias && (!user || stricmp(user, s_ChanServAlias) == 0)) {
00082         anope_cmd_nick(s_ChanServAlias, desc_ChanServAlias,
00083                        ircd->chanservaliasmode);
00084     }
00085 
00086     if (s_MemoServAlias && (!user || stricmp(user, s_MemoServAlias) == 0)) {
00087         anope_cmd_nick(s_MemoServAlias, desc_MemoServAlias,
00088                        ircd->memoservaliasmode);
00089     }
00090 
00091     if (s_BotServAlias && (!user || stricmp(user, s_BotServAlias) == 0)) {
00092         anope_cmd_nick(s_BotServAlias, desc_BotServAlias,
00093                        ircd->botservaliasmode);
00094     }
00095 
00096     if (s_HelpServAlias && (!user || stricmp(user, s_HelpServAlias) == 0)) {
00097         anope_cmd_nick(s_HelpServAlias, desc_HelpServAlias,
00098                        ircd->helpservaliasmode);
00099     }
00100 
00101     if (s_OperServAlias && (!user || stricmp(user, s_OperServAlias) == 0)) {
00102         anope_cmd_nick(s_OperServAlias, desc_OperServAlias,
00103                        ircd->operservaliasmode);
00104     }
00105 
00106     if (s_DevNullAlias && (!user || stricmp(user, s_DevNullAlias) == 0)) {
00107         anope_cmd_nick(s_DevNullAlias, desc_DevNullAlias,
00108                        ircd->devnullvaliasmode);
00109     }
00110     if (s_HostServAlias && ircd->vhost
00111         && (!user || stricmp(user, s_HostServAlias) == 0)) {
00112         anope_cmd_nick(s_HostServAlias, desc_HostServAlias,
00113                        ircd->hostservaliasmode);
00114     }
00115     if (s_GlobalNoticerAlias
00116         && (!user || stricmp(user, s_GlobalNoticerAlias) == 0)) {
00117         anope_cmd_nick(s_GlobalNoticerAlias, desc_GlobalNoticerAlias,
00118                        ircd->globalaliasmode);
00119     }
00120 
00121     /* We make the bots go online */
00122     if (s_BotServ) {
00123         BotInfo *bi;
00124         int i;
00125 
00126         for (i = 0; i < 256; i++)
00127             for (bi = botlists[i]; bi; bi = bi->next) {
00128 
00129                 if (!user || !stricmp(user, bi->nick))
00130                     anope_cmd_bot_nick(bi->nick, bi->user, bi->host,
00131                                        bi->real, ircd->botserv_bot_mode);
00132             }
00133     }
00134 }
00135 
00136 /*************************************************************************/
00137 
00138 /* Set GID if necessary.  Return 0 if successful (or if RUNGROUP not
00139  * defined), else print an error message to logfile and return -1.
00140  */
00141 
00142 static int set_group(void)
00143 {
00144 #if defined(RUNGROUP) && defined(HAVE_SETGRENT)
00145     struct group *gr;
00146 
00147     setgrent();
00148     while ((gr = getgrent()) != NULL) {
00149         if (strcmp(gr->gr_name, RUNGROUP) == 0)
00150             break;
00151     }
00152     endgrent();
00153     if (gr) {
00154         setgid(gr->gr_gid);
00155         return 0;
00156     } else {
00157         alog("Unknown group `%s'\n", RUNGROUP);
00158         return -1;
00159     }
00160 #else
00161     return 0;
00162 #endif
00163 }
00164 
00165 /*************************************************************************/
00166 
00167 /* Parse command-line options for the "-dir" option only.  Return 0 if all
00168  * went well or -1 for a syntax error.
00169  */
00170 
00171 /* XXX this could fail if we have "-some-option-taking-an-argument -dir" */
00172 
00173 static int parse_dir_options(int ac, char **av)
00174 {
00175     int i;
00176     char *s;
00177 
00178     for (i = 1; i < ac; i++) {
00179         s = av[i];
00180         if (*s == '-') {
00181             s++;
00182             if (strcmp(s, "dir") == 0) {
00183                 if (++i >= ac) {
00184                     fprintf(stderr, "-dir requires a parameter\n");
00185                     return -1;
00186                 }
00187                 services_dir = av[i];
00188             } else if (strcmp(s, "log") == 0) {
00189                 if (++i >= ac) {
00190                     fprintf(stderr, "-log requires a parameter\n");
00191                     return -1;
00192                 }
00193                 log_filename = av[i];
00194             } else if (strcmp(s, "version") == 0) {
00195                 fprintf(stdout, "Anope-%s %s -- %s\n", version_number,
00196                         version_flags, version_build);
00197                 exit(EXIT_SUCCESS);
00198             }
00199         }
00200     }
00201     return 0;
00202 }
00203 
00204 /*************************************************************************/
00205 
00206 /* Parse command-line options.  Return 0 if all went well, -1 for an error
00207  * with an option, or 1 for -help.
00208  */
00209 
00210 static int parse_options(int ac, char **av)
00211 {
00212     int i;
00213     char *s, *t;
00214 
00215     for (i = 1; i < ac; i++) {
00216         s = av[i];
00217         if (*s == '-') {
00218             s++;
00219             if (strcmp(s, "remote") == 0) {
00220                 if (++i >= ac) {
00221                     fprintf(stderr, "-remote requires hostname[:port]\n");
00222                     return -1;
00223                 }
00224                 s = av[i];
00225                 t = strchr(s, ':');
00226                 if (t) {
00227                     int portnum;
00228                     *t++ = 0;
00229                     portnum = atoi(t);
00230                     if ((portnum > 0) && (portnum < 65535))
00231                         RemotePort = portnum;
00232                     else {
00233                         fprintf(stderr,
00234                                 "-remote: Port numbers must be in the range 1..65535. Using default.\n");
00235                         return -1;
00236                     }
00237                 }
00238                 RemoteServer = s;
00239             } else if (strcmp(s, "local") == 0) {
00240                 if (++i >= ac) {
00241                     fprintf(stderr,
00242                             "-local requires hostname or [hostname]:[port]\n");
00243                     return -1;
00244                 }
00245                 s = av[i];
00246                 t = strchr(s, ':');
00247                 if (t) {
00248                     int portnum;
00249                     *t++ = 0;
00250                     portnum = atoi(t);
00251                     if ((portnum >= 0) && (portnum < 65535))
00252                         LocalPort = portnum;
00253                     else {
00254                         fprintf(stderr,
00255                                 "-local: Port numbers must be in the range 1..65535 or 0. Using default.\n");
00256                         return -1;
00257                     }
00258                 }
00259                 LocalHost = s;
00260             } else if (strcmp(s, "name") == 0) {
00261                 if (++i >= ac) {
00262                     fprintf(stderr, "-name requires a parameter\n");
00263                     return -1;
00264                 }
00265                 ServerName = av[i];
00266             } else if (strcmp(s, "desc") == 0) {
00267                 if (++i >= ac) {
00268                     fprintf(stderr, "-desc requires a parameter\n");
00269                     return -1;
00270                 }
00271                 ServerDesc = av[i];
00272             } else if (strcmp(s, "user") == 0) {
00273                 if (++i >= ac) {
00274                     fprintf(stderr, "-user requires a parameter\n");
00275                     return -1;
00276                 }
00277                 ServiceUser = av[i];
00278             } else if (strcmp(s, "host") == 0) {
00279                 if (++i >= ac) {
00280                     fprintf(stderr, "-host requires a parameter\n");
00281                     return -1;
00282                 }
00283                 ServiceHost = av[i];
00284             } else if (strcmp(s, "dir") == 0) {
00285                 /* Handled by parse_dir_options() */
00286                 i++;            /* Skip parameter */
00287             } else if (strcmp(s, "log") == 0) {
00288                 /* Handled by parse_dir_options(), too */
00289                 i++;            /* Skip parameter */
00290             } else if (strcmp(s, "update") == 0) {
00291                 if (++i >= ac) {
00292                     fprintf(stderr, "-update requires a parameter\n");
00293                     return -1;
00294                 }
00295                 s = av[i];
00296                 if (atoi(s) <= 0) {
00297                     fprintf(stderr,
00298                             "-update: number of seconds must be positive");
00299                     return -1;
00300                 } else
00301                     UpdateTimeout = atol(s);
00302             } else if (strcmp(s, "expire") == 0) {
00303                 if (++i >= ac) {
00304                     fprintf(stderr, "-expire requires a parameter\n");
00305                     return -1;
00306                 }
00307                 s = av[i];
00308                 if (atoi(s) <= 0) {
00309                     fprintf(stderr,
00310                             "-expire: number of seconds must be positive");
00311                     return -1;
00312                 } else
00313                     ExpireTimeout = atol(s);
00314             } else if (strcmp(s, "debug") == 0) {
00315                 debug++;
00316             } else if (strcmp(s, "readonly") == 0) {
00317                 readonly = 1;
00318                 skeleton = 0;
00319             } else if (strcmp(s, "skeleton") == 0) {
00320                 readonly = 0;
00321                 skeleton = 1;
00322             } else if (strcmp(s, "nofork") == 0) {
00323                 nofork = 1;
00324             } else if (strcmp(s, "logchan") == 0) {
00325                 logchan = 1;
00326             } else if (strcmp(s, "forceload") == 0) {
00327                 forceload = 1;
00328             } else if (strcmp(s, "nothird") == 0) {
00329                 nothird = 1;
00330             } else if (strcmp(s, "protocoldebug") == 0) {
00331                 protocoldebug = 1;
00332             } else if (strcmp(s, "support") == 0) {
00333                 nofork = 1;
00334                 debug++;
00335                 nothird = 1;
00336             } else if (!strcmp(s, "noexpire")) {
00337                 noexpire = 1;
00338             } else if (!strcmp(s, "help")) {
00339                 fprintf(stdout, "Anope-%s %s -- %s\n", version_number,
00340                         version_flags, version_build);
00341                 fprintf(stdout,
00342                         "Anope IRC Services (http://www.anope.org)\n");
00343                 fprintf(stdout, "Usage ./services [options] ...\n");
00344                 fprintf(stdout,
00345                         "-remote        -remote hostname[:port]\n");
00346                 fprintf(stdout, "-local         -local hostname[:port]\n");
00347                 fprintf(stdout, "-name          -name servername\n");
00348                 fprintf(stdout, "-desc          -desc serverdesc\n");
00349                 fprintf(stdout, "-user          -user serviceuser\n");
00350                 fprintf(stdout, "-host          -host servicehost\n");
00351                 fprintf(stdout,
00352                         "-update        -update updatetime(secs)\n");
00353                 fprintf(stdout,
00354                         "-expire        -expire expiretime(secs)\n");
00355                 fprintf(stdout, "-debug         -debug\n");
00356                 fprintf(stdout, "-nofork        -nofork\n");
00357                 fprintf(stdout, "-logchan       -logchan channelname\n");
00358                 fprintf(stdout, "-skeleton      -skeleton\n");
00359                 fprintf(stdout, "-forceload     -forceload\n");
00360                 fprintf(stdout, "-nothird       -nothird\n");
00361                 fprintf(stdout, "-support       -support\n");
00362                 fprintf(stdout, "-readonly      -readonly\n");
00363                 fprintf(stdout, "-noexpire      -noexpire\n");
00364                 fprintf(stdout, "-version       -version\n");
00365                 fprintf(stdout, "-help          -help\n");
00366                 fprintf(stdout, "-log           -log logfilename\n");
00367                 fprintf(stdout,
00368                         "-dir           -dir servicesdirectory\n\n");
00369                 fprintf(stdout,
00370                         "Further support is available from http://www.anope.org\n");
00371                 fprintf(stdout,
00372                         "Or visit US on IRC at irc.anope.org #anope\n");
00373                 exit(EXIT_SUCCESS);
00374             } else {
00375                 fprintf(stderr, "Unknown option -%s\n", s);
00376                 return -1;
00377             }
00378         } else {
00379             fprintf(stderr, "Non-option arguments not allowed\n");
00380             return -1;
00381         }
00382     }
00383     return 0;
00384 }
00385 
00386 /*************************************************************************/
00387 
00388 /* Remove our PID file.  Done at exit. */
00389 
00390 static void remove_pidfile(void)
00391 {
00392     remove(PIDFilename);
00393 }
00394 
00395 /*************************************************************************/
00396 
00397 /* Create our PID file and write the PID to it. */
00398 
00399 static void write_pidfile(void)
00400 {
00401     FILE *pidfile;
00402 
00403     pidfile = fopen(PIDFilename, "w");
00404     if (pidfile) {
00405         fprintf(pidfile, "%d\n", (int) getpid());
00406         fclose(pidfile);
00407         atexit(remove_pidfile);
00408     } else {
00409         log_perror("Warning: cannot write to PID file %s", PIDFilename);
00410     }
00411 }
00412 
00413 /*************************************************************************/
00414 
00415 /* Overall initialization routines.  Return 0 on success, -1 on failure. */
00416 
00417 int openlog_failed = 0, openlog_errno = 0;
00418 
00419 int init_primary(int ac, char **av)
00420 {
00421     int started_from_term = isatty(0) && isatty(1) && isatty(2);
00422 
00423     /* Set file creation mask and group ID. */
00424 #if defined(DEFUMASK) && HAVE_UMASK
00425     umask(DEFUMASK);
00426 #endif
00427     if (set_group() < 0)
00428         return -1;
00429 
00430     /* Parse command line for -dir and -version options. */
00431     parse_dir_options(ac, av);
00432 
00433     /* Chdir to Services data directory. */
00434     if (chdir(services_dir) < 0) {
00435         fprintf(stderr, "chdir(%s): %s\n", services_dir, strerror(errno));
00436         return -1;
00437     }
00438 
00439     /* Open logfile, and complain if we didn't. */
00440     if (open_log() < 0) {
00441         openlog_errno = errno;
00442         if (started_from_term) {
00443             fprintf(stderr, "Warning: unable to open log file %s: %s\n",
00444                     log_filename, strerror(errno));
00445         } else {
00446             openlog_failed = 1;
00447         }
00448     }
00449 
00450     /* Read configuration file; exit if there are problems. */
00451     if (!read_config(0)) {
00452         return -1;
00453     }
00454 
00455     /* Add IRCD Protocol Module; exit if there are errors */
00456     if (protocol_module_init()) {
00457         return -1;
00458     }
00459 
00460     /* Add Encryption Module; exit if there are errors */
00461     if (encryption_module_init()) {
00462         return -1;
00463     }
00464     return 0;
00465 }
00466 
00467 int init_secondary(int ac, char **av)
00468 {
00469     int i;
00470     int started_from_term = isatty(0) && isatty(1) && isatty(2);
00471 
00472     /* Add Core MSG handles */
00473     moduleAddMsgs();
00474 
00475     /* Parse all remaining command-line options. */
00476     parse_options(ac, av);
00477 
00478     /* Parse the defcon mode string if needed */
00479     if (DefConLevel) {
00480         int defconCount;
00481         for (defconCount = 1; defconCount <= 5; defconCount++) {
00482             if (!defconParseModeString(DefConChanModes)) {
00483                 fprintf(stderr,
00484                         "services.conf: The given DefConChanModes mode string was incorrect (see log for exact errors)\n");
00485                 return -1;
00486             }
00487         }
00488     }
00489 #ifndef _WIN32
00490     if (!nofork) {
00491         if ((i = fork()) < 0) {
00492             perror("fork()");
00493             return -1;
00494         } else if (i != 0) {
00495             exit(0);
00496         }
00497         if (started_from_term) {
00498             close(0);
00499             close(1);
00500             close(2);
00501         }
00502         if (setpgid(0, 0) < 0) {
00503             perror("setpgid()");
00504             return -1;
00505         }
00506     }
00507 #else
00508     /* Initialize winsocks -- codemastr */
00509     {
00510         WSADATA wsa;
00511         if (WSAStartup(MAKEWORD(1, 1), &wsa)) {
00512             alog("Failed to initialized WinSock library");
00513             return -1;
00514         }
00515     }
00516     if (!SupportedWindowsVersion()) {
00517 
00518         char *winver = GetWindowsVersion();
00519 
00520         alog("%s is not a supported version of Windows", winver);
00521 
00522         free(winver);
00523 
00524         return -1;
00525 
00526     }
00527     if (!nofork) {
00528         alog("Launching Anope into the background");
00529         FreeConsole();
00530     }
00531 #endif
00532 
00533     /* Write our PID to the PID file. */
00534     write_pidfile();
00535 
00536     /* Announce ourselves to the logfile. */
00537     if (debug || readonly || skeleton) {
00538         alog("Anope %s (ircd protocol: %s) starting up (options:%s%s%s)",
00539              version_number, version_protocol,
00540              debug ? " debug" : "", readonly ? " readonly" : "",
00541              skeleton ? " skeleton" : "");
00542     } else {
00543         alog("Anope %s (ircd protocol: %s) starting up",
00544              version_number, version_protocol);
00545     }
00546     start_time = time(NULL);
00547 
00548 
00549 
00550     /* If in read-only mode, close the logfile again. */
00551     if (readonly)
00552         close_log();
00553 
00554     /* Set signal handlers.  Catch certain signals to let us do things or
00555      * panic as necessary, and ignore all others.
00556      */
00557 
00558 #ifndef _WIN32
00559 #if defined(NSIG)
00560     for (i = 1; i <= NSIG - 1; i++) {
00561 #else
00562     for (i = 1; i <= 31; i++) {
00563 #endif
00564         signal(i, SIG_IGN);
00565     }
00566 #else
00567     /* work around to bug #527 */
00568     signal(SIGILL, SIG_IGN);
00569     signal(SIGBREAK, SIG_IGN);
00570     signal(SIGABRT, SIG_IGN);
00571 #endif
00572 
00573     signal(SIGINT, sighandler);
00574     signal(SIGTERM, sighandler);
00575 #ifndef _WIN32
00576     signal(SIGQUIT, sighandler);
00577 #endif
00578     if (!DumpCore) {
00579         signal(SIGSEGV, sighandler);
00580 #ifndef _WIN32
00581         signal(SIGBUS, sighandler);
00582         signal(SIGTRAP, sighandler);
00583 #endif
00584     } else {
00585         signal(SIGSEGV, SIG_DFL);
00586 #ifndef _WIN32
00587         signal(SIGBUS, sighandler);
00588         signal(SIGTRAP, sighandler);
00589 #endif
00590     }
00591 #ifndef _WIN32
00592     signal(SIGQUIT, sighandler);
00593     signal(SIGHUP, sighandler);
00594     signal(SIGUSR2, sighandler);
00595 #endif
00596 
00597 #ifdef SIGIOT
00598     signal(SIGIOT, sighandler);
00599 #endif
00600     signal(SIGFPE, sighandler);
00601 
00602 #ifndef _WIN32
00603     signal(SIGUSR1, sighandler);        /* This is our "out-of-memory" panic switch */
00604 #endif
00605 
00606     /* Initialize multi-language support */
00607     lang_init();
00608     if (debug)
00609         alog("debug: Loaded languages");
00610 
00611 
00612     /* Initialize subservices */
00613     ns_init();
00614     cs_init();
00615     ms_init();
00616     bs_init();
00617     os_init();
00618     hostserv_init();
00619     helpserv_init();
00620 
00621 #ifdef USE_RDB
00622     if (!rdb_init()) {
00623         if (UseRDB) {
00624             UseRDB = 0;
00625             alog("Error: Disabling UseRDB due to errors with SQL");
00626         }
00627     } else {
00628         if (MysqlSecure && UseRDB) {
00629             UseRDB = 0;
00630             alog("Error: MySQL password are encrypted using method in MysqlSecure disabling UseRDB");
00631         }
00632     }
00633 #endif
00634 
00635     /* load any custom modules */
00636     modules_init();
00637 
00638     /* Initialize random number generator */
00639     rand_init();
00640     add_entropy_userkeys();
00641 
00642     /* Load up databases */
00643 #ifdef USE_RDB
00644     if (UseRDB)
00645         rdb_load_dbases();
00646     /* Need a better way to handle this -dane */
00647     if (!UseRDB) {
00648 #endif
00649         if (!skeleton) {
00650             load_ns_dbase();
00651             if (debug)
00652                 alog("debug: Loaded %s database (1/%d)", s_NickServ,
00653                      (PreNickDBName ? 8 : 7));
00654             if (s_HostServ) {
00655                 load_hs_dbase();
00656                 if (debug)
00657                     alog("debug: Loaded %s database (2/%d)", s_HostServ,
00658                          (PreNickDBName ? 8 : 7));
00659             }
00660             if (s_BotServ) {
00661                 load_bs_dbase();
00662                 if (debug)
00663                     alog("debug: Loaded %s database (3/%d)", s_BotServ,
00664                          (PreNickDBName ? 8 : 7));
00665             } else if (debug)
00666                 alog("debug: BotServ database (3/%d) not loaded because BotServ is disabled", (PreNickDBName ? 8 : 7));
00667             load_cs_dbase();
00668             if (debug)
00669                 alog("debug: Loaded %s database (4/%d)", s_ChanServ,
00670                      (PreNickDBName ? 8 : 7));
00671         }
00672         load_os_dbase();
00673         if (debug)
00674             alog("debug: Loaded %s database (5/%d)", s_OperServ,
00675                  (PreNickDBName ? 8 : 7));
00676         load_news();
00677         if (debug)
00678             alog("debug: Loaded news database (6/%d)",
00679                  (PreNickDBName ? 8 : 7));
00680         load_exceptions();
00681         if (debug)
00682             alog("debug: Loaded exception database (7/%d)",
00683                  (PreNickDBName ? 8 : 7));
00684         if (PreNickDBName) {
00685             load_ns_req_db();
00686             if (debug)
00687                 alog("debug: Loaded PreNick database (8/8)");
00688         }
00689 #ifdef USE_RDB
00690     }
00691 #endif
00692     alog("Databases loaded");
00693 
00694     /* Save the databases back to file/mysql to reflect any changes */
00695 #ifdef USE_RDB
00696     if (!UseRDB) {              /* Only save if we are not using remote databases
00697                                  * to avoid floods. As a side effects our nice
00698                                  * FFF databases won't get overwritten if the
00699                                  * mysql db is broken (empty etc.) */
00700 #endif
00701         alog("Info: Reflecting database records.");
00702         save_databases();
00703 #ifdef USE_RDB
00704     } else {
00705         alog("Info: Not reflecting database records.");
00706     }
00707 #endif
00708     send_event(EVENT_CONNECT, 1, EVENT_START);
00709 
00710     /* Connect to the remote server */
00711     servsock = conn(RemoteServer, RemotePort, LocalHost, LocalPort);
00712     if (servsock < 0 && RemoteServer2) {
00713         servsock = conn(RemoteServer2, RemotePort2, LocalHost, LocalPort);
00714         if (servsock < 0 && RemoteServer3) {
00715             servsock =
00716                 conn(RemoteServer3, RemotePort3, LocalHost, LocalPort);
00717             if (servsock < 0) {
00718                 fatal_perror("Can't connect to server");
00719             } else {
00720                 servernum = 3;
00721                 alog("Connected to Server %d (%s:%d)", servernum,
00722                      RemoteServer3, RemotePort3);
00723             }
00724         } else {
00725             if (servsock < 0) {
00726                 fatal_perror("Can't connect to server");
00727             }
00728             servernum = 2;
00729             alog("Connected to Server %d (%s:%d)", servernum,
00730                  RemoteServer2, RemotePort2);
00731         }
00732     } else {
00733         if (servsock < 0) {
00734             fatal_perror("Can't connect to server");
00735         }
00736         servernum = 1;
00737         alog("Connected to Server %d (%s:%d)", servernum, RemoteServer,
00738              RemotePort);
00739     }
00740 
00741     anope_cmd_connect(servernum);
00742     send_event(EVENT_CONNECT, 1, EVENT_STOP);
00743 
00744     sgets2(inbuf, sizeof(inbuf), servsock);
00745     if (strnicmp(inbuf, "ERROR", 5) == 0) {
00746         /* Close server socket first to stop wallops, since the other
00747          * server doesn't want to listen to us anyway */
00748         disconn(servsock);
00749         servsock = -1;
00750         fatal("Remote server returned: %s", inbuf);
00751     }
00752 
00753     /* Announce a logfile error if there was one */
00754     if (openlog_failed) {
00755         anope_cmd_global(NULL, "Warning: couldn't open logfile: %s",
00756                          strerror(openlog_errno));
00757     }
00758 
00759     /* Bring in our pseudo-clients */
00760     introduce_user(NULL);
00761 
00762     /* And hybrid needs Global joined in the logchan */
00763     if (logchan && ircd->join2msg) {
00764         /* XXX might desync */
00765         anope_cmd_join(s_GlobalNoticer, LogChannel, time(NULL));
00766     }
00767 
00768     anope_cmd_eob();
00769 
00774     modules_delayed_init();
00775 
00776     /* Success! */
00777     return 0;
00778 }
00779 
00780 /*************************************************************************/

Generated on Sun Dec 30 09:26:49 2007 for Anope by  doxygen 1.5.1-20070107