/* 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 420 2004-10-23 23:42:15Z trystan $ * */ #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), (long int) 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), (long int) 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), (long int) 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), (long int) 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), (long int) 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), (long int) time(NULL), \ (modes), ServiceUser, ServiceHost, ServiceHost, ServerName, (name)); \ send_cmd(NULL, "SQLINE %s :Reserved for services", (nick)); \ } 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; } 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/%d)", s_NickServ, (PreNickDBName ? 8 : 7)); if (s_HostServ) { load_hs_dbase(); if (debug) alog("debug: Loaded %s database (2/%d)", s_HostServ, (PreNickDBName ? 8 : 7)); } if (s_BotServ) { load_bs_dbase(); if (debug) alog("debug: Loaded %s database (3/%d)", s_BotServ, (PreNickDBName ? 8 : 7)); } else if (debug) alog("debug: BotServ database (3/%d) not loaded because BotServ is disabled", (PreNickDBName ? 8 : 7)); load_cs_dbase(); if (debug) alog("debug: Loaded %s database (4/%d)", s_ChanServ, (PreNickDBName ? 8 : 7)); } load_os_dbase(); if (debug) alog("debug: Loaded %s database (5/%d)", s_OperServ, (PreNickDBName ? 8 : 7)); load_news(); if (debug) alog("debug: Loaded news database (6/%d)", (PreNickDBName ? 8 : 7)); load_exceptions(); if (debug) alog("debug: Loaded exception database (7/%d)", (PreNickDBName ? 8 : 7)); if (PreNickDBName) { load_ns_req_db(); if (debug) alog("debug: Loaded PreNick database (8/8)"); } 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", (long int) time(NULL)); #endif #ifdef IRC_HYBRID send_cmd(NULL, "SVSINFO 5 5 0 :%ld", (long int) time(NULL)); #endif #ifdef IRC_PTLINK send_cmd(NULL, "SVINFO 3 6 %lu", (long int) time(NULL)); send_cmd(NULL, "SVSINFO %lu %d", (long int) 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); /* And hybrid needs Global joined in the logchan */ #ifdef IRC_HYBRID if (logchan) { send_cmd(NULL, "SJOIN %ld %s + :%s", (long int) time(NULL), LogChannel, s_GlobalNoticer); } #endif /** * 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, "%s", GlobalOnCycleUP); } /* Success! */ return 0; } /*************************************************************************/