diff options
author | svn svn@31f1291d-b8d6-0310-a050-a5561fc1590b <svn svn@31f1291d-b8d6-0310-a050-a5561fc1590b@5417fbe8-f217-4b02-8779-1006273d7864> | 2004-03-28 21:59:56 +0000 |
---|---|---|
committer | svn svn@31f1291d-b8d6-0310-a050-a5561fc1590b <svn svn@31f1291d-b8d6-0310-a050-a5561fc1590b@5417fbe8-f217-4b02-8779-1006273d7864> | 2004-03-28 21:59:56 +0000 |
commit | 55bf4dbcabf378e9472b7d31d6edf87f6ac853e9 (patch) | |
tree | 7a9454ea6b8750256e242cf6d5fba3ca7a4b5044 /init.c |
Initial Anope Import
git-svn-id: svn://svn.anope.org/anope/trunk@1 31f1291d-b8d6-0310-a050-a5561fc1590b
git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@1 5417fbe8-f217-4b02-8779-1006273d7864
Diffstat (limited to 'init.c')
-rw-r--r-- | init.c | 807 |
1 files changed, 807 insertions, 0 deletions
@@ -0,0 +1,807 @@ +/* Initalization and related routines. + * + * (C) 2003 Anope Team + * Contact us at info@anope.org + * + * Please read COPYING and README for furhter details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id: init.c,v 1.40 2004/03/13 13:55:59 dane Exp $ + * + */ + +#include "services.h" +#include "pseudo.h" +int servernum = 0; + +extern void moduleAddMsgs(void); +/*************************************************************************/ + +/* Send a NICK command for the given pseudo-client. If `user' is NULL, + * send NICK commands for all the pseudo-clients. + * + * Now also sends MODE and SQLINE */ +#if defined(IRC_HYBRID) +# define NICK(nick,name,modes) \ + do { \ + kill_user(NULL, (nick), "Nick used by Services"); \ + send_cmd(NULL, "NICK %s 1 %ld %s %s %s %s :%s", (nick), time(NULL), (modes), \ + ServiceUser, ServiceHost, ServerName, (name)); \ + } while (0) +#elif defined(IRC_ULTIMATE3) +# define NICK(nick,name,modes) \ + do { \ + send_cmd(NULL, "CLIENT %s 1 %ld %s + %s %s * %s 0 0 :%s", (nick), time(NULL), (modes), \ + ServiceUser, ServiceHost, ServerName, (name)); \ + send_cmd(NULL, "SQLINE %s :Reserved for services", (nick)); \ + } while (0) +#elif defined(IRC_BAHAMUT) +# define NICK(nick,name,modes) \ + do { \ + send_cmd(NULL, "NICK %s 1 %ld %s %s %s %s 0 0 :%s", (nick), time(NULL), (modes), \ + ServiceUser, ServiceHost, ServerName, (name)); \ + send_cmd(NULL, "SQLINE %s :Reserved for services", (nick)); \ + } while (0) +#elif defined(IRC_UNREAL) +# define NICK(nick,name,modes) \ + do { \ + send_cmd(NULL, "NICK %s 1 %ld %s %s %s 0 %s * :%s", (nick), time(NULL), \ + ServiceUser, ServiceHost, ServerName, (modes), (name)); \ + send_cmd(NULL, "SQLINE %s :Reserved for services", (nick)); \ + } while (0) +#elif defined(IRC_DREAMFORGE) +# define NICK(nick,name,modes) \ + do { \ + send_cmd(NULL, "NICK %s 1 %ld %s %s %s 0 :%s", (nick), time(NULL), \ + ServiceUser, ServiceHost, ServerName, (name)); \ + if (strcmp(modes, "+")) send_cmd((nick), "MODE %s %s", (nick), (modes)); \ + send_cmd(NULL, "SQLINE %s :Reserved for services", (nick)); \ + } while (0) +#elif defined(IRC_PTLINK) +# define NICK(nick,name,modes) \ + do { \ + send_cmd(NULL, "NICK %s 1 %lu %s %s %s %s %s :%s", (nick), time(NULL), \ + (modes), ServiceUser, ServiceHost, ServiceHost, ServerName, (name)); \ + } while (0) +#endif + +void introduce_user(const char *user) +{ + /* Watch out for infinite loops... */ +#define LTSIZE 20 + static int lasttimes[LTSIZE]; + if (lasttimes[0] >= time(NULL) - 3) + fatal("introduce_user() loop detected"); + memmove(lasttimes, lasttimes + 1, sizeof(lasttimes) - sizeof(int)); + lasttimes[LTSIZE - 1] = time(NULL); +#undef LTSIZE + + if (!user || stricmp(user, s_NickServ) == 0) +#if defined(IRC_ULTIMATE) || defined(IRC_ULTIMATE3) + NICK(s_NickServ, desc_NickServ, "+S"); +#elif defined(IRC_UNREAL) || defined(IRC_VIAGRA) + NICK(s_NickServ, desc_NickServ, "+oS"); +#else + NICK(s_NickServ, desc_NickServ, "+o"); +#endif + if (!user || stricmp(user, s_ChanServ) == 0) +#if defined(IRC_ULTIMATE) || defined(IRC_ULTIMATE3) + NICK(s_ChanServ, desc_ChanServ, "+S"); +#elif defined(IRC_UNREAL) || defined(IRC_VIAGRA) + NICK(s_ChanServ, desc_ChanServ, "+oS"); +#else + NICK(s_ChanServ, desc_ChanServ, "+o"); +#endif + +#ifdef HAS_VHOST + if (s_HostServ && (!user || stricmp(user, s_HostServ) == 0)) +#if defined(IRC_ULTIMATE) || defined(IRC_UNREAL) || defined(IRC_VIAGRA) + NICK(s_HostServ, desc_HostServ, "+oS"); +#else + NICK(s_HostServ, desc_HostServ, "+o"); +#endif +#endif + + if (!user || stricmp(user, s_MemoServ) == 0) +#if defined(IRC_ULTIMATE) || defined(IRC_ULTIMATE3) + NICK(s_MemoServ, desc_MemoServ, "+S"); +#elif defined(IRC_UNREAL) || defined(IRC_VIAGRA) + NICK(s_MemoServ, desc_MemoServ, "+oS"); +#else + NICK(s_MemoServ, desc_MemoServ, "+o"); +#endif + if (s_BotServ && (!user || stricmp(user, s_BotServ) == 0)) +#if defined(IRC_ULTIMATE) || defined(IRC_ULTIMATE3) + NICK(s_BotServ, desc_BotServ, "+S"); +#elif defined(IRC_UNREAL) || defined(IRC_VIAGRA) + NICK(s_BotServ, desc_BotServ, "+oS"); +#else + NICK(s_BotServ, desc_BotServ, "+o"); +#endif + if (!user || stricmp(user, s_HelpServ) == 0) +#if defined(IRC_ULTIMATE) || defined(IRC_ULTIMATE3) + NICK(s_HelpServ, desc_HelpServ, "+Sh"); +#elif defined(IRC_UNREAL) || defined(IRC_VIAGRA) + NICK(s_HelpServ, desc_HelpServ, "+oS"); +#else + NICK(s_HelpServ, desc_HelpServ, "+h"); +#endif + if (!user || stricmp(user, s_OperServ) == 0) +#if defined(IRC_ULTIMATE) || defined(IRC_ULTIMATE3) + NICK(s_OperServ, desc_OperServ, "+iS"); +#elif defined(IRC_UNREAL) || defined(IRC_VIAGRA) + NICK(s_OperServ, desc_OperServ, "+ioS"); +#else + NICK(s_OperServ, desc_OperServ, "+io"); +#endif + if (s_DevNull && (!user || stricmp(user, s_DevNull) == 0)) +#if defined(IRC_ULTIMATE) || defined(IRC_UNREAL) || defined(IRC_ULTIMATE3) + NICK(s_DevNull, desc_DevNull, "+iS"); +#else + NICK(s_DevNull, desc_DevNull, "+i"); +#endif + if (!user || stricmp(user, s_GlobalNoticer) == 0) +#if defined(IRC_ULTIMATE) || defined(IRC_ULTIMATE3) + NICK(s_GlobalNoticer, desc_GlobalNoticer, "+iS"); +#elif defined(IRC_UNREAL) || defined(IRC_VIAGRA) + NICK(s_GlobalNoticer, desc_GlobalNoticer, "+ioS"); +#else + NICK(s_GlobalNoticer, desc_GlobalNoticer, "+io"); +#endif + +/* We make aliases go online */ + if (s_NickServAlias && (!user || stricmp(user, s_NickServAlias) == 0)) +#if defined(IRC_ULTIMATE) || defined(IRC_UNREAL) || defined(IRC_VIAGRA) + NICK(s_NickServAlias, desc_NickServAlias, "+oS"); +#else + NICK(s_NickServAlias, desc_NickServAlias, "+o"); +#endif + if (s_ChanServAlias && (!user || stricmp(user, s_ChanServAlias) == 0)) +#if defined(IRC_ULTIMATE) || defined(IRC_UNREAL) || defined(IRC_VIAGRA) + NICK(s_ChanServAlias, desc_ChanServAlias, "+oS"); +#else + NICK(s_ChanServAlias, desc_ChanServAlias, "+o"); +#endif + if (s_MemoServAlias && (!user || stricmp(user, s_MemoServAlias) == 0)) +#if defined(IRC_ULTIMATE) || defined(IRC_UNREAL) || defined(IRC_VIAGRA) + NICK(s_MemoServAlias, desc_MemoServAlias, "+oS"); +#else + NICK(s_MemoServAlias, desc_MemoServAlias, "+o"); +#endif + if (s_BotServAlias && (!user || stricmp(user, s_BotServAlias) == 0)) +#if defined(IRC_ULTIMATE) || defined(IRC_UNREAL) || defined(IRC_VIAGRA) + NICK(s_BotServAlias, desc_BotServAlias, "+oS"); +#else + NICK(s_BotServAlias, desc_BotServAlias, "+o"); +#endif + if (s_HelpServAlias && (!user || stricmp(user, s_HelpServAlias) == 0)) +#if defined(IRC_ULTIMATE) || defined(IRC_UNREAL) || defined(IRC_VIAGRA) + NICK(s_HelpServAlias, desc_HelpServAlias, "+oS"); +#else + NICK(s_HelpServAlias, desc_HelpServAlias, "+h"); +#endif + if (s_OperServAlias && (!user || stricmp(user, s_OperServAlias) == 0)) +#if defined(IRC_ULTIMATE) || defined(IRC_UNREAL) || defined(IRC_VIAGRA) + NICK(s_OperServAlias, desc_OperServAlias, "+ioS"); +#else + NICK(s_OperServAlias, desc_OperServAlias, "+io"); +#endif + if (s_DevNullAlias && (!user || stricmp(user, s_DevNullAlias) == 0)) +#if defined(IRC_ULTIMATE) || defined(IRC_UNREAL) || defined(IRC_VIAGRA) + NICK(s_DevNullAlias, desc_DevNullAlias, "+iS"); +#else + NICK(s_DevNullAlias, desc_DevNullAlias, "+i"); +#endif + if (s_HostServAlias && (!user || stricmp(user, s_HostServAlias) == 0)) +#if defined(IRC_ULTIMATE) || defined(IRC_UNREAL) || defined(IRC_VIAGRA) + NICK(s_HostServAlias, desc_HostServAlias, "+ioS"); +#else + NICK(s_HostServAlias, desc_HostServAlias, "+io"); +#endif + if (s_GlobalNoticerAlias + && (!user || stricmp(user, s_GlobalNoticerAlias) == 0)) +#if defined(IRC_ULTIMATE) || defined(IRC_UNREAL) + NICK(s_GlobalNoticerAlias, desc_GlobalNoticerAlias, "+ioS"); +#else + NICK(s_GlobalNoticerAlias, desc_GlobalNoticerAlias, "+io"); +#endif + + /* We make the bots go online */ + if (s_BotServ) { + BotInfo *bi; + int i; + + for (i = 0; i < 256; i++) + for (bi = botlists[i]; bi; bi = bi->next) + if (!user || !stricmp(user, bi->nick)) +#if defined(IRC_UNREAL) || defined(IRC_VIAGRA) + NEWNICK(bi->nick, bi->user, bi->host, bi->real, "+qS", + 1); +#elif defined(IRC_ULTIMATE) + NEWNICK(bi->nick, bi->user, bi->host, bi->real, "+pS", + 1); +#elif defined(IRC_ULTIMATE3) + NEWNICK(bi->nick, bi->user, bi->host, bi->real, "+S", + 1); +#else + NEWNICK(bi->nick, bi->user, bi->host, bi->real, "+", + 1); +#endif + } +} + +#undef NICK + +/*************************************************************************/ + +/* Set GID if necessary. Return 0 if successful (or if RUNGROUP not + * defined), else print an error message to logfile and return -1. + */ + +static int set_group(void) +{ +#if defined(RUNGROUP) && defined(HAVE_SETGRENT) + struct group *gr; + + setgrent(); + while ((gr = getgrent()) != NULL) { + if (strcmp(gr->gr_name, RUNGROUP) == 0) + break; + } + endgrent(); + if (gr) { + setgid(gr->gr_gid); + return 0; + } else { + alog("Unknown group `%s'\n", RUNGROUP); + return -1; + } +#else + return 0; +#endif +} + +/*************************************************************************/ + +/* Parse command-line options for the "-dir" option only. Return 0 if all + * went well or -1 for a syntax error. + */ + +/* XXX this could fail if we have "-some-option-taking-an-argument -dir" */ + +static int parse_dir_options(int ac, char **av) +{ + int i; + char *s; + + for (i = 1; i < ac; i++) { + s = av[i]; + if (*s == '-') { + s++; + if (strcmp(s, "dir") == 0) { + if (++i >= ac) { + fprintf(stderr, "-dir requires a parameter\n"); + return -1; + } + services_dir = av[i]; + } else if (strcmp(s, "log") == 0) { + if (++i >= ac) { + fprintf(stderr, "-log requires a parameter\n"); + return -1; + } + log_filename = av[i]; + } + } + } + return 0; +} + +/*************************************************************************/ + +/* Parse command-line options. Return 0 if all went well, -1 for an error + * with an option, or 1 for -help. + */ + +static int parse_options(int ac, char **av) +{ + int i; + char *s, *t; + + for (i = 1; i < ac; i++) { + s = av[i]; + if (*s == '-') { + s++; + if (strcmp(s, "remote") == 0) { + if (++i >= ac) { + fprintf(stderr, "-remote requires hostname[:port]\n"); + return -1; + } + s = av[i]; + t = strchr(s, ':'); + if (t) { + *t++ = 0; + if (atoi(t) > 0) + RemotePort = atoi(t); + else { + fprintf(stderr, + "-remote: port number must be a positive integer. Using default."); + return -1; + } + } + RemoteServer = s; + } else if (strcmp(s, "local") == 0) { + if (++i >= ac) { + fprintf(stderr, + "-local requires hostname or [hostname]:[port]\n"); + return -1; + } + s = av[i]; + t = strchr(s, ':'); + if (t) { + *t++ = 0; + if (atoi(t) >= 0) + LocalPort = atoi(t); + else { + fprintf(stderr, + "-local: port number must be a positive integer or 0. Using default."); + return -1; + } + } + LocalHost = s; + } else if (strcmp(s, "name") == 0) { + if (++i >= ac) { + fprintf(stderr, "-name requires a parameter\n"); + return -1; + } + ServerName = av[i]; + } else if (strcmp(s, "desc") == 0) { + if (++i >= ac) { + fprintf(stderr, "-desc requires a parameter\n"); + return -1; + } + ServerDesc = av[i]; + } else if (strcmp(s, "user") == 0) { + if (++i >= ac) { + fprintf(stderr, "-user requires a parameter\n"); + return -1; + } + ServiceUser = av[i]; + } else if (strcmp(s, "host") == 0) { + if (++i >= ac) { + fprintf(stderr, "-host requires a parameter\n"); + return -1; + } + ServiceHost = av[i]; + } else if (strcmp(s, "dir") == 0) { + /* Handled by parse_dir_options() */ + i++; /* Skip parameter */ + } else if (strcmp(s, "log") == 0) { + /* Handled by parse_dir_options(), too */ + i++; /* Skip parameter */ + } else if (strcmp(s, "update") == 0) { + if (++i >= ac) { + fprintf(stderr, "-update requires a parameter\n"); + return -1; + } + s = av[i]; + if (atoi(s) <= 0) { + fprintf(stderr, + "-update: number of seconds must be positive"); + return -1; + } else + UpdateTimeout = atol(s); + } else if (strcmp(s, "expire") == 0) { + if (++i >= ac) { + fprintf(stderr, "-expire requires a parameter\n"); + return -1; + } + s = av[i]; + if (atoi(s) <= 0) { + fprintf(stderr, + "-expire: number of seconds must be positive"); + return -1; + } else + ExpireTimeout = atol(s); + } else if (strcmp(s, "debug") == 0) { + debug++; + } else if (strcmp(s, "readonly") == 0) { + readonly = 1; + skeleton = 0; + } else if (strcmp(s, "skeleton") == 0) { + readonly = 0; + skeleton = 1; + } else if (strcmp(s, "nofork") == 0) { + nofork = 1; + } else if (strcmp(s, "logchan") == 0) { + logchan = 1; +#ifdef IRC_HYBRID + fprintf(stderr, + "LogChan will only work if your logchannel is not set to +n\n"); +#endif + } else if (strcmp(s, "forceload") == 0) { + forceload = 1; + } else if (!strcmp(s, "noexpire")) { + noexpire = 1; +#ifdef IS44_CONVERTER + } else if (!strcmp(s, "is44")) { + is44 = 1; +#endif + } else { + fprintf(stderr, "Unknown option -%s\n", s); + return -1; + } + } else { + fprintf(stderr, "Non-option arguments not allowed\n"); + return -1; + } + } + return 0; +} + +/*************************************************************************/ + +/* Remove our PID file. Done at exit. */ + +static void remove_pidfile(void) +{ + remove(PIDFilename); +} + +/*************************************************************************/ + +/* Create our PID file and write the PID to it. */ + +static void write_pidfile(void) +{ + FILE *pidfile; + + pidfile = fopen(PIDFilename, "w"); + if (pidfile) { + fprintf(pidfile, "%d\n", (int) getpid()); + fclose(pidfile); + atexit(remove_pidfile); + } else { + log_perror("Warning: cannot write to PID file %s", PIDFilename); + } +} + +/*************************************************************************/ + +/* Overall initialization routine. Returns 0 on success, -1 on failure. */ + +int init(int ac, char **av) +{ + int i; + int openlog_failed = 0, openlog_errno = 0; + int started_from_term = isatty(0) && isatty(1) && isatty(2); + + /* Imported from main.c */ + extern void sighandler(int signum); + + + /* Set file creation mask and group ID. */ +#if defined(DEFUMASK) && HAVE_UMASK + umask(DEFUMASK); +#endif + if (set_group() < 0) + return -1; + + /* Parse command line for -dir option. */ + parse_dir_options(ac, av); + + /* Chdir to Services data directory. */ + if (chdir(services_dir) < 0) { + fprintf(stderr, "chdir(%s): %s\n", services_dir, strerror(errno)); + return -1; + } + + /* Open logfile, and complain if we didn't. */ + if (open_log() < 0) { + openlog_errno = errno; + if (started_from_term) { + fprintf(stderr, "Warning: unable to open log file %s: %s\n", + log_filename, strerror(errno)); + } else { + openlog_failed = 1; + } + } + + /* Read configuration file; exit if there are problems. */ + if (!read_config(0)) + return -1; + + /* Add Core MSG handles */ + moduleAddMsgs(); + + /* Parse all remaining command-line options. */ + parse_options(ac, av); + + /* Detach ourselves if requested. */ + if (!nofork) { + if ((i = fork()) < 0) { + perror("fork()"); + return -1; + } else if (i != 0) { + exit(0); + } + if (started_from_term) { + close(0); + close(1); + close(2); + } + if (setpgid(0, 0) < 0) { + perror("setpgid()"); + return -1; + } + } + + /* Write our PID to the PID file. */ + write_pidfile(); + + /* Announce ourselves to the logfile. */ + if (debug || readonly || skeleton) { + alog("Anope %s (compiled for %s) starting up (options:%s%s%s)", + version_number, version_protocol, + debug ? " debug" : "", readonly ? " readonly" : "", + skeleton ? " skeleton" : ""); + } else { + alog("Anope %s (compiled for %s) starting up", + version_number, version_protocol); + } + start_time = time(NULL); + + /* If in read-only mode, close the logfile again. */ + if (readonly) + close_log(); + + /* Set signal handlers. Catch certain signals to let us do things or + * panic as necessary, and ignore all others. + */ + +#if defined(NSIG) && !defined(LINUX20) && !defined(LINUX22) + for (i = 1; i <= NSIG - 1; i++) { +#else + for (i = 1; i <= 31; i++) { +#endif +#if defined(USE_THREADS) && defined(LINUX20) + if (i != SIGUSR1 && i != SIGUSR2) +#endif + signal(i, SIG_IGN); + } + +#ifndef USE_THREADS + signal(SIGINT, sighandler); +#else + signal(SIGINT, SIG_DFL); +#endif + signal(SIGTERM, sighandler); + signal(SIGQUIT, sighandler); + if (!DumpCore) { + signal(SIGSEGV, sighandler); + signal(SIGBUS, sighandler); + signal(SIGILL, sighandler); + signal(SIGTRAP, sighandler); + } else { + signal(SIGSEGV, SIG_DFL); + signal(SIGBUS, SIG_DFL); + signal(SIGILL, SIG_DFL); + signal(SIGTRAP, SIG_DFL); + } + signal(SIGQUIT, sighandler); + signal(SIGHUP, sighandler); + +#ifdef SIGIOT + signal(SIGIOT, sighandler); +#endif + signal(SIGFPE, sighandler); + +#if !defined(USE_THREADS) || !defined(LINUX20) + signal(SIGUSR1, sighandler); /* This is our "out-of-memory" panic switch */ +#endif + + /* Initialize multi-language support */ + lang_init(); + if (debug) + alog("debug: Loaded languages"); + + /* Initialize subservices */ + ns_init(); + cs_init(); + ms_init(); + bs_init(); + os_init(); + hostserv_init(); + helpserv_init(); + +#ifdef USE_RDB + db_mysql_init(); +#endif + + /* Initialize proxy detection */ +#ifdef USE_THREADS + if (ProxyDetect && !proxy_init()) { + perror("proxy_init()"); + return -1; + } +#endif + + /* load any custom modules */ + modules_init(); + +#ifdef USE_CONVERTER + /* Convert the databases NOW! */ +# ifdef IS44_CONVERTER + if (is44) { + convert_ircservices_44(); + alog("debug: Databases converted"); + } +# endif +#endif + + /* Load up databases */ + if (!skeleton) { + load_ns_dbase(); + if (debug) + alog("debug: Loaded %s database (1/9)", s_NickServ); + if (s_HostServ) { + load_hs_dbase(); + if (debug) + alog("debug: Loaded %s database (2/9)", s_HostServ); + } + if (s_BotServ) { + load_bs_dbase(); + if (debug) + alog("debug: Loaded %s database (3/9)", s_BotServ); + } else if (debug) + alog("debug: BotServ database (4/9) not loaded because BotServ is disabled"); + load_cs_dbase(); + if (debug) + alog("debug: Loaded %s database (5/9)", s_ChanServ); + } + load_os_dbase(); + if (debug) + alog("debug: Loaded %s database (6/9)", s_OperServ); + load_news(); + if (debug) + alog("debug: Loaded news database (7/9)"); + load_exceptions(); + if (debug) + alog("debug: Loaded exception database (8/9)"); + if (PreNickDBName) { + load_ns_req_db(); + if (debug) + alog("debug: Loaded PreNick database (9/9)"); + } + + alog("Databases loaded"); + + /* Save the databases back to file/mysql to reflect any changes */ + save_databases(); + + /* Connect to the remote server */ + servsock = conn(RemoteServer, RemotePort, LocalHost, LocalPort); + if (servsock < 0 && RemoteServer2) { + servsock = conn(RemoteServer2, RemotePort2, LocalHost, LocalPort); + if (servsock < 0 && RemoteServer3) { + servsock = + conn(RemoteServer3, RemotePort3, LocalHost, LocalPort); + if (servsock < 0) { + fatal_perror("Can't connect to server"); + } else { + servernum = 3; + alog("Connected to Server %d (%s:%d)", servernum, + RemoteServer3, RemotePort3); + } + } else { + if (servsock < 0) { + fatal_perror("Can't connect to server"); + } + servernum = 2; + alog("Connected to Server %d (%s:%d)", servernum, + RemoteServer2, RemotePort2); + } + } else { + if (servsock < 0) { + fatal_perror("Can't connect to server"); + } + servernum = 1; + alog("Connected to Server %d (%s:%d)", servernum, RemoteServer, + RemotePort); + } + +#ifdef IRC_UNREAL + send_cmd(NULL, "PROTOCTL NICKv2 VHP"); +#endif +#if defined(IRC_ULTIMATE3) + if (servernum == 1) + send_cmd(NULL, "PASS %s :TS", RemotePassword); + else if (servernum == 2) + send_cmd(NULL, "PASS %s :TS", RemotePassword2); + else if (servernum == 3) + send_cmd(NULL, "PASS %s :TS", RemotePassword3); + send_cmd(NULL, "CAPAB NICKIP SSJ5 TS5 CLIENT"); + +#elif defined(IRC_BAHAMUT) + if (servernum == 1) + send_cmd(NULL, "PASS %s :TS", RemotePassword); + else if (servernum == 2) + send_cmd(NULL, "PASS %s :TS", RemotePassword2); + else if (servernum == 3) + send_cmd(NULL, "PASS %s :TS", RemotePassword3); + send_cmd(NULL, "CAPAB NICKIP SSJOIN TS3"); +#elif defined(IRC_HYBRID) + if (servernum == 1) + send_cmd(NULL, "PASS %s :TS", RemotePassword); + else if (servernum == 2) + send_cmd(NULL, "PASS %s :TS", RemotePassword2); + else if (servernum == 3) + send_cmd(NULL, "PASS %s :TS", RemotePassword3); + send_cmd(NULL, "CAPAB TS5 EX IE HOPS HUB AOPS"); +#elif defined(IRC_PTLINK) + if (servernum == 1) + send_cmd(NULL, "PASS %s :TS", RemotePassword); + else if (servernum == 2) + send_cmd(NULL, "PASS %s :TS", RemotePassword2); + else if (servernum == 3) + send_cmd(NULL, "PASS %s :TS", RemotePassword3); +#else + if (servernum == 1) + send_cmd(NULL, "PASS :%s", RemotePassword); + if (servernum == 2) + send_cmd(NULL, "PASS :%s", RemotePassword2); + if (servernum == 3) + send_cmd(NULL, "PASS :%s", RemotePassword3); +#endif +#ifdef IRC_PTLINK + send_cmd(NULL, "SERVER %s 1 Anope.Services%s :%s", + ServerName, version_number, ServerDesc); +#else + send_cmd(NULL, "SERVER %s 1 :%s", ServerName, ServerDesc); +#endif +#ifdef IRC_BAHAMUT + send_cmd(NULL, "SVINFO 3 1 0 :%ld", time(NULL)); +#endif +#ifdef IRC_HYBRID + send_cmd(NULL, "SVSINFO 5 5 0 :%ld", time(NULL)); +#endif +#ifdef IRC_PTLINK + send_cmd(NULL, "SVINFO 3 6 %lu", time(NULL)); + send_cmd(NULL, "SVSINFO %lu %d", time(NULL), maxusercnt); +#endif + sgets2(inbuf, sizeof(inbuf), servsock); + if (strnicmp(inbuf, "ERROR", 5) == 0) { + /* Close server socket first to stop wallops, since the other + * server doesn't want to listen to us anyway */ + disconn(servsock); + servsock = -1; + fatal("Remote server returned: %s", inbuf); + } + + /* Announce a logfile error if there was one */ + if (openlog_failed) { + wallops(NULL, "Warning: couldn't open logfile: %s", + strerror(openlog_errno)); + } + + /* Bring in our pseudo-clients */ + introduce_user(NULL); + + /** + * Load our delayed modeles - modules that are planing on making clients need to wait till now + * where as modules wanting to modify our ircd connection messages need to load eariler :| + **/ + modules_delayed_init(); + + /* Write the StartGlobal */ + if (GlobalOnCycle) { + if (GlobalOnCycleUP) + oper_global(NULL, GlobalOnCycleUP); + } + + /* Success! */ + return 0; +} + +/*************************************************************************/ |