/*! * * \param source_p Pointer to allocated Client struct from which the message * originally comes from. This can be a local or remote client. * \param parc Integer holding the number of supplied arguments. * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL * pointers. * \note Valid arguments for this command are: * * - parv[0] = command * - parv[1] = nickname * - parv[2] = timestamp */ static void change_remote_nick(struct Client *source_p, char *parv[]) { int samenick = !irccmp(source_p->name, parv[1]); assert(!EmptyString(parv[1])); assert(IsClient(source_p)); assert(source_p->name[0]); /* Client changing their nick */ if (!samenick) { DelUMode(source_p, UMODE_REGISTERED); watch_check_hash(source_p, RPL_LOGOFF); source_p->tsinfo = atol(parv[2]); assert(source_p->tsinfo > 0); } sendto_common_channels_local(source_p, 1, 0, ":%s!%s@%s NICK :%s", source_p->name, source_p->username, source_p->host, parv[1]); whowas_add_history(source_p, 1); sendto_server(source_p, 0, 0, ":%s NICK %s :%lu", source_p->id, parv[1], (unsigned long)source_p->tsinfo); /* Set the new nick name */ hash_del_client(source_p); strlcpy(source_p->name, parv[1], sizeof(source_p->name)); hash_add_client(source_p); if (!samenick) watch_check_hash(source_p, RPL_LOGON); }
/* set_initial_nick() * * inputs * output * side effects - * * This function is only called to set up an initially registering * client. */ static void set_initial_nick(struct Client *source_p, const char *nick) { /* Client setting NICK the first time */ /* This had to be copied here to avoid problems.. */ source_p->tsinfo = CurrentTime; source_p->localClient->registration &= ~REG_NEED_NICK; if (source_p->name[0]) hash_del_client(source_p); strlcpy(source_p->name, nick, sizeof(source_p->name)); hash_add_client(source_p); /* fd_desc is long enough */ fd_note(&source_p->localClient->fd, "Nick: %s", nick); if (!source_p->localClient->registration) register_local_user(source_p); }
/* * client_from_server() */ static void uid_from_server(struct Client *client_p, struct Client *source_p, int parc, char *parv[], time_t newts, const char *svsid, char *nick, char *ugecos) { const char *m = NULL; const char *servername = source_p->name; source_p = make_client(client_p); dlinkAdd(source_p, &source_p->node, &global_client_list); source_p->hopcount = atoi(parv[2]); source_p->tsinfo = newts; strlcpy(source_p->svid, svsid, sizeof(source_p->svid)); /* copy the nick in place */ strlcpy(source_p->name, nick, sizeof(source_p->name)); strlcpy(source_p->id, parv[8], sizeof(source_p->id)); strlcpy(source_p->sockhost, parv[7], sizeof(source_p->sockhost)); strlcpy(source_p->info, ugecos, sizeof(source_p->info)); hash_add_client(source_p); hash_add_id(source_p); /* parse usermodes */ for (m = &parv[4][1]; *m; ++m) { unsigned int flag = user_modes[(unsigned char)*m]; if ((flag & UMODE_INVISIBLE) && !HasUMode(source_p, UMODE_INVISIBLE)) ++Count.invisi; if ((flag & UMODE_OPER) && !HasUMode(source_p, UMODE_OPER)) ++Count.oper; source_p->umodes |= flag & SEND_UMODES; } register_remote_user(source_p, parv[5], parv[6], servername, ugecos); }
/* set_initial_nick() * * inputs * output * side effects - * * This function is only called to set up an initially registering * client. */ static void set_initial_nick(struct Client *source_p, const char *nick) { const int samenick = !irccmp(source_p->name, nick); if (!samenick) source_p->tsinfo = CurrentTime; source_p->connection->registration &= ~REG_NEED_NICK; if (source_p->name[0]) hash_del_client(source_p); strlcpy(source_p->name, nick, sizeof(source_p->name)); hash_add_client(source_p); /* fd_desc is long enough */ fd_note(&source_p->connection->fd, "Nick: %s", source_p->name); if (!source_p->connection->registration) register_local_user(source_p); }
/*! * * \param source_p Pointer to allocated Client struct from which the message * originally comes from. This can be a local or remote client. * \param parc Integer holding the number of supplied arguments. * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL * pointers. * \note Valid arguments for this command are: * * server introducing new nick/UID (without services support) * - parv[0] = command * - parv[1] = nickname * - parv[2] = hop count * - parv[3] = TS * - parv[4] = umode * - parv[5] = username * - parv[6] = hostname * - parv[7] = ip * - parv[8] = uid * - parv[9] = ircname (gecos) * * server introducing new nick/UID (with services support) * - parv[ 0] = command * - parv[ 1] = nickname * - parv[ 2] = hop count * - parv[ 3] = TS * - parv[ 4] = umode * - parv[ 5] = username * - parv[ 6] = hostname * - parv[ 7] = ip * - parv[ 8] = uid * - parv[ 9] = services account * - parv[10] = ircname (gecos) */ static void uid_from_server(struct Client *source_p, int parc, char *parv[]) { struct Client *client_p = NULL; client_p = make_client(source_p->from); client_p->servptr = source_p; client_p->hopcount = atoi(parv[2]); client_p->tsinfo = atol(parv[3]); strlcpy(client_p->account, (parc == 11 ? parv[9] : "*"), sizeof(client_p->account)); strlcpy(client_p->name, parv[1], sizeof(client_p->name)); strlcpy(client_p->id, parv[8], sizeof(client_p->id)); strlcpy(client_p->sockhost, parv[7], sizeof(client_p->sockhost)); strlcpy(client_p->info, parv[parc - 1], sizeof(client_p->info)); strlcpy(client_p->host, parv[6], sizeof(client_p->host)); strlcpy(client_p->username, parv[5], sizeof(client_p->username)); hash_add_client(client_p); hash_add_id(client_p); /* Parse user modes */ for (const char *m = &parv[4][1]; *m; ++m) { const struct user_modes *tab = umode_map[(unsigned char)*m]; if (!tab) continue; if ((tab->flag & UMODE_INVISIBLE) && !HasUMode(client_p, UMODE_INVISIBLE)) ++Count.invisi; if ((tab->flag & UMODE_OPER) && !HasUMode(client_p, UMODE_OPER)) ++Count.oper; AddUMode(client_p, tab->flag); } register_remote_user(client_p); }
/* * nick_from_server() */ static void nick_from_server(struct Client *client_p, struct Client *source_p, int parc, char *parv[], time_t newts, const char *svsid, char *nick, char *ngecos) { int samenick = 0; if (IsServer(source_p)) { /* A server introducing a new client, change source */ source_p = make_client(client_p); dlinkAdd(source_p, &source_p->node, &global_client_list); if (parc > 2) source_p->hopcount = atoi(parv[2]); if (newts) source_p->tsinfo = newts; else { newts = source_p->tsinfo = CurrentTime; ts_warn("Remote nick %s (%s) introduced without a TS", nick, parv[0]); } strlcpy(source_p->svid, svsid, sizeof(source_p->svid)); strlcpy(source_p->info, ngecos, sizeof(source_p->info)); /* copy the nick in place */ strlcpy(source_p->name, nick, sizeof(source_p->name)); hash_add_client(source_p); if (parc > 8) { const char *m; /* parse usermodes */ for (m = &parv[4][1]; *m; ++m) { unsigned int flag = user_modes[(unsigned char)*m]; if ((flag & UMODE_INVISIBLE) && !HasUMode(source_p, UMODE_INVISIBLE)) ++Count.invisi; if ((flag & UMODE_OPER) && !HasUMode(source_p, UMODE_OPER)) ++Count.oper; source_p->umodes |= flag & SEND_UMODES; } register_remote_user(source_p, parv[5], parv[6], parv[7], ngecos); return; } } else if (source_p->name[0]) { samenick = !irccmp(source_p->name, nick); /* Client changing their nick */ if (!samenick) { DelUMode(source_p, UMODE_REGISTERED); watch_check_hash(source_p, RPL_LOGOFF); source_p->tsinfo = newts ? newts : CurrentTime; } sendto_common_channels_local(source_p, 1, 0, ":%s!%s@%s NICK :%s", source_p->name,source_p->username, source_p->host, nick); add_history(source_p, 1); sendto_server(client_p, CAP_TS6, NOCAPS, ":%s NICK %s :%lu", ID(source_p), nick, (unsigned long)source_p->tsinfo); sendto_server(client_p, NOCAPS, CAP_TS6, ":%s NICK %s :%lu", source_p->name, nick, (unsigned long)source_p->tsinfo); } /* set the new nick name */ if (source_p->name[0]) hash_del_client(source_p); strlcpy(source_p->name, nick, sizeof(source_p->name)); hash_add_client(source_p); if (!samenick) watch_check_hash(source_p, RPL_LOGON); }
/* change_local_nick() * * inputs - pointer to server * - pointer to client * - nick * output - * side effects - changes nick of a LOCAL user */ static void change_local_nick(struct Client *source_p, const char *nick) { assert(source_p->name[0] && !EmptyString(nick)); assert(MyConnect(source_p)); /* * Client just changing his/her nick. If he/she is * on a channel, send note of change to all clients * on that channel. Propagate notice to other servers. */ if ((source_p->localClient->last_nick_change + ConfigFileEntry.max_nick_time) < CurrentTime) source_p->localClient->number_of_nick_changes = 0; source_p->localClient->last_nick_change = CurrentTime; source_p->localClient->number_of_nick_changes++; if ((ConfigFileEntry.anti_nick_flood && (source_p->localClient->number_of_nick_changes <= ConfigFileEntry.max_nick_changes)) || !ConfigFileEntry.anti_nick_flood || (HasUMode(source_p, UMODE_OPER) && ConfigFileEntry.no_oper_flood)) { int samenick = !irccmp(source_p->name, nick); if (!samenick) { source_p->tsinfo = CurrentTime; clear_ban_cache_client(source_p); watch_check_hash(source_p, RPL_LOGOFF); if (HasUMode(source_p, UMODE_REGISTERED)) { unsigned int oldmodes = source_p->umodes; char modebuf[IRCD_BUFSIZE] = { '\0' }; DelUMode(source_p, UMODE_REGISTERED); send_umode(source_p, source_p, oldmodes, 0xffffffff, modebuf); } } sendto_realops_flags(UMODE_NCHANGE, L_ALL, SEND_NOTICE, "Nick change: From %s to %s [%s@%s]", source_p->name, nick, source_p->username, source_p->host); sendto_common_channels_local(source_p, 1, 0, ":%s!%s@%s NICK :%s", source_p->name, source_p->username, source_p->host, nick); add_history(source_p, 1); sendto_server(source_p, CAP_TS6, NOCAPS, ":%s NICK %s :%lu", ID(source_p), nick, (unsigned long)source_p->tsinfo); sendto_server(source_p, NOCAPS, CAP_TS6, ":%s NICK %s :%lu", source_p->name, nick, (unsigned long)source_p->tsinfo); hash_del_client(source_p); strlcpy(source_p->name, nick, sizeof(source_p->name)); hash_add_client(source_p); if (!samenick) watch_check_hash(source_p, RPL_LOGON); /* fd_desc is long enough */ fd_note(&source_p->localClient->fd, "Nick: %s", nick); } else sendto_one(source_p, form_str(ERR_NICKTOOFAST), me.name, source_p->name, source_p->name, nick, ConfigFileEntry.max_nick_time); }
/* change_local_nick() * * inputs - pointer to server * - pointer to client * - nick * output - * side effects - changes nick of a LOCAL user */ static void change_local_nick(struct Client *source_p, const char *nick) { int samenick = 0; assert(source_p->name[0] && !EmptyString(nick)); assert(MyClient(source_p)); /* * Client just changing his/her nick. If he/she is * on a channel, send note of change to all clients * on that channel. Propagate notice to other servers. */ if ((source_p->connection->nick.last_attempt + ConfigGeneral.max_nick_time) < CurrentTime) source_p->connection->nick.count = 0; if (ConfigGeneral.anti_nick_flood && !HasUMode(source_p, UMODE_OPER) && source_p->connection->nick.count > ConfigGeneral.max_nick_changes) { sendto_one_numeric(source_p, &me, ERR_NICKTOOFAST, nick, ConfigGeneral.max_nick_time); return; } source_p->connection->nick.last_attempt = CurrentTime; source_p->connection->nick.count++; samenick = !irccmp(source_p->name, nick); if (!samenick) { source_p->tsinfo = CurrentTime; clear_ban_cache_client(source_p); watch_check_hash(source_p, RPL_LOGOFF); if (HasUMode(source_p, UMODE_REGISTERED)) { unsigned int oldmodes = source_p->umodes; char modebuf[IRCD_BUFSIZE] = ""; DelUMode(source_p, UMODE_REGISTERED); send_umode(source_p, source_p, oldmodes, modebuf); } } sendto_realops_flags(UMODE_NCHANGE, L_ALL, SEND_NOTICE, "Nick change: From %s to %s [%s@%s]", source_p->name, nick, source_p->username, source_p->host); sendto_common_channels_local(source_p, 1, 0, ":%s!%s@%s NICK :%s", source_p->name, source_p->username, source_p->host, nick); whowas_add_history(source_p, 1); sendto_server(source_p, 0, 0, ":%s NICK %s :%lu", source_p->id, nick, (unsigned long)source_p->tsinfo); hash_del_client(source_p); strlcpy(source_p->name, nick, sizeof(source_p->name)); hash_add_client(source_p); if (!samenick) watch_check_hash(source_p, RPL_LOGON); /* fd_desc is long enough */ fd_note(&source_p->connection->fd, "Nick: %s", source_p->name); }
int main(int argc, char *argv[]) { /* Check to see if the user is running us as root, which is a nono */ if (!geteuid()) { fprintf(stderr, "ERROR: This server won't run as root/superuser\n"); return -1; } /* Setup corefile size immediately after boot -kre */ setup_corefile(); /* Save server boot time right away, so getrusage works correctly */ set_time(); /* It's not random, but it ought to be a little harder to guess */ init_genrand(SystemTime.tv_sec ^ (SystemTime.tv_usec | (getpid() << 20))); dlinkAdd(&me, &me.node, &global_client_list); ConfigGeneral.dpath = DPATH; ConfigGeneral.spath = SPATH; ConfigGeneral.mpath = MPATH; ConfigGeneral.configfile = CPATH; /* Server configuration file */ ConfigGeneral.klinefile = KPATH; /* Server kline file */ ConfigGeneral.glinefile = GPATH; /* Server gline file */ ConfigGeneral.xlinefile = XPATH; /* Server xline file */ ConfigGeneral.dlinefile = DLPATH; /* dline file */ ConfigGeneral.resvfile = RESVPATH; /* resv file */ myargv = argv; umask(077); /* umask 077: u=rwx,g=,o= */ parseargs(&argc, &argv, myopts); if (printVersion) { printf("ircd: version %s(%s)\n", ircd_version, serno); exit(EXIT_SUCCESS); } if (chdir(ConfigGeneral.dpath)) { perror("chdir"); exit(EXIT_FAILURE); } ssl_init(); if (!server_state.foreground) { make_daemon(); close_standard_fds(); /* this needs to be before init_netio()! */ } else print_startup(getpid()); setup_signals(); /* We need this to initialise the fd array before anything else */ fdlist_init(); log_set_file(LOG_TYPE_IRCD, 0, logFileName); init_netio(); /* This needs to be setup early ! -- adrian */ /* Check if there is pidfile and daemon already running */ check_pidfile(pidFileName); mp_pool_init(); init_dlink_nodes(); init_isupport(); dbuf_init(); hash_init(); ipcache_init(); client_init(); class_init(); whowas_init(); watch_init(); auth_init(); /* Initialise the auth code */ init_resolver(); /* Needs to be setup before the io loop */ modules_init(); read_conf_files(1); /* cold start init conf files */ init_uid(); initialize_server_capabs(); /* Set up default_server_capabs */ initialize_global_set_options(); /* Has to be called after read_conf_files() */ channel_init(); read_links_file(); motd_init(); user_usermodes_init(); #ifdef HAVE_LIBGEOIP geoip_ctx = GeoIP_new(GEOIP_MEMORY_CACHE); #endif if (EmptyString(ConfigServerInfo.sid)) { ilog(LOG_TYPE_IRCD, "ERROR: No server id specified in serverinfo block."); exit(EXIT_FAILURE); } strlcpy(me.id, ConfigServerInfo.sid, sizeof(me.id)); if (EmptyString(ConfigServerInfo.name)) { ilog(LOG_TYPE_IRCD, "ERROR: No server name specified in serverinfo block."); exit(EXIT_FAILURE); } strlcpy(me.name, ConfigServerInfo.name, sizeof(me.name)); /* serverinfo{} description must exist. If not, error out.*/ if (EmptyString(ConfigServerInfo.description)) { ilog(LOG_TYPE_IRCD, "ERROR: No server description specified in serverinfo block."); exit(EXIT_FAILURE); } strlcpy(me.info, ConfigServerInfo.description, sizeof(me.info)); me.from = &me; me.servptr = &me; me.connection->lasttime = CurrentTime; me.connection->since = CurrentTime; me.connection->firsttime = CurrentTime; SetMe(&me); make_server(&me); hash_add_id(&me); hash_add_client(&me); dlinkAdd(&me, make_dlink_node(), &global_server_list); load_kline_database(); load_dline_database(); load_gline_database(); load_xline_database(); load_resv_database(); load_all_modules(1); load_conf_modules(); load_core_modules(1); write_pidfile(pidFileName); ilog(LOG_TYPE_IRCD, "Server Ready"); event_addish(&event_cleanup_glines, NULL); event_addish(&event_cleanup_tklines, NULL); /* We want try_connections to be called as soon as possible now! -- adrian */ /* No, 'cause after a restart it would cause all sorts of nick collides */ event_addish(&event_try_connections, NULL); /* Setup the timeout check. I'll shift it later :) -- adrian */ event_add(&event_comm_checktimeouts, NULL); event_addish(&event_save_all_databases, NULL); if (ConfigServerHide.links_delay > 0) { event_write_links_file.when = ConfigServerHide.links_delay; event_addish(&event_write_links_file, NULL); } else ConfigServerHide.links_disabled = 1; if (splitmode) event_addish(&splitmode_event, NULL); io_loop(); return 0; }
/*! \brief SVSNICK command handler * * \param source_p Pointer to allocated Client struct from which the message * originally comes from. This can be a local or remote client. * \param parc Integer holding the number of supplied arguments. * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL * pointers. * \note Valid arguments for this command are: * - parv[0] = command * - parv[1] = old nickname * - parv[2] = new nickname * - parv[3] = timestamp */ static int ms_svsnick(struct Client *source_p, int parc, char *parv[]) { struct Client *target_p = NULL, *exists_p = NULL; if (!HasFlag(source_p, FLAGS_SERVICE) || !valid_nickname(parv[2], 1)) return 0; if ((target_p = find_person(source_p, parv[1])) == NULL) return 0; if (!MyConnect(target_p)) { if (target_p->from == source_p->from) { sendto_realops_flags(UMODE_DEBUG, L_ALL, SEND_NOTICE, "Received wrong-direction SVSNICK " "for %s (behind %s) from %s", target_p->name, source_p->from->name, get_client_name(source_p, HIDE_IP)); return 0; } sendto_one(target_p, ":%s SVSNICK %s %s %s", source_p->id, target_p->id, parv[2], parv[3]); return 0; } if ((exists_p = hash_find_client(parv[2]))) { if (target_p == exists_p) { if (!strcmp(target_p->name, parv[2])) return 0; } else if (IsUnknown(exists_p)) exit_client(exists_p, "SVSNICK Override"); else { exit_client(target_p, "SVSNICK Collide"); return 0; } } target_p->tsinfo = strtoimax(parv[3], NULL, 10); clear_ban_cache_client(target_p); watch_check_hash(target_p, RPL_LOGOFF); if (HasUMode(target_p, UMODE_REGISTERED)) { const unsigned int oldmodes = target_p->umodes; char modebuf[IRCD_BUFSIZE] = ""; DelUMode(target_p, UMODE_REGISTERED); send_umode(target_p, target_p, oldmodes, modebuf); } sendto_common_channels_local(target_p, 1, 0, 0, ":%s!%s@%s NICK :%s", target_p->name, target_p->username, target_p->host, parv[2]); whowas_add_history(target_p, 1); sendto_server(NULL, 0, 0, ":%s NICK %s :%ju", target_p->id, parv[2], target_p->tsinfo); hash_del_client(target_p); strlcpy(target_p->name, parv[2], sizeof(target_p->name)); hash_add_client(target_p); watch_check_hash(target_p, RPL_LOGON); fd_note(&target_p->connection->fd, "Nick: %s", target_p->name); return 0; }
int main (int argc, char *argv[]) { /* Check to see if the user is running * us as root, which is a nono */ if (geteuid () == 0) { fprintf (stderr, "Don't run ircd as root!!!\n"); return (-1); } /* save server boot time right away, so getrusage works correctly */ set_time (); /* Setup corefile size immediately after boot -kre */ setup_corefile (); /* set initialVMTop before we allocate any memory */ initialVMTop = get_vm_top (); ServerRunning = 0; /* It ain't random, but it ought to be a little harder to guess */ srand (SystemTime.tv_sec ^ (SystemTime.tv_usec | (getpid () << 20))); memset (&me, 0, sizeof (me)); memset (&meLocalUser, 0, sizeof (meLocalUser)); me.localClient = &meLocalUser; dlinkAdd (&me, &me.node, &global_client_list); /* Pointer to beginning of Client list */ memset (&ServerInfo, 0, sizeof (ServerInfo)); /* Initialise the channel capability usage counts... */ init_chcap_usage_counts (); ConfigFileEntry.dpath = DPATH; ConfigFileEntry.configfile = CPATH; /* Server configuration file */ ConfigFileEntry.klinefile = KPATH; /* Server kline file */ ConfigFileEntry.xlinefile = XPATH; /* Server xline file */ ConfigFileEntry.dlinefile = DLPATH; /* dline file */ ConfigFileEntry.cresvfile = CRESVPATH; /* channel resv file */ ConfigFileEntry.nresvfile = NRESVPATH; /* nick resv file */ myargv = argv; umask (077); /* better safe than sorry --SRB */ parseargs (&argc, &argv, myopts); build_version (); if (printVersion) { printf ("ircd: version %s\n", ircd_version); exit (EXIT_SUCCESS); } if (chdir (ConfigFileEntry.dpath)) { perror ("chdir"); exit (EXIT_FAILURE); } if (!server_state.foreground) make_daemon (); else print_startup (getpid ()); #ifdef HAVE_LIBCRYPTO dh_init(); fprintf(stderr, "SSL: Initialize\n"); SSL_load_error_strings(); SSLeay_add_ssl_algorithms(); ServerInfo.ctx = SSL_CTX_new(SSLv23_server_method()); if (!ServerInfo.ctx) { ERR_print_errors_fp(stderr); return 0; } fprintf(stderr, "SSL: Client based SSL connections are enabled.\n"); #endif setup_signals (); /* We need this to initialise the fd array before anything else */ fdlist_init (); if (!server_state.foreground) close_all_connections (); /* this needs to be before init_netio()! */ else check_can_use_v6 (); /* Done in close_all_connections normally */ init_log (logFileName); init_netio (); /* This needs to be setup early ! -- adrian */ /* Check if there is pidfile and daemon already running */ check_pidfile (pidFileName); /* Init the event subsystem */ eventInit (); init_sys (); #ifndef NOBALLOC initBlockHeap (); #endif init_dlink_nodes (); init_slink_nodes (); initialize_message_files (); dbuf_init (); init_hash (); init_ip_hash_table (); /* client host ip hash table */ init_host_hash (); /* Host-hashtable. */ clear_hash_parse (); init_client (); init_user (); init_channels (); init_class (); init_whowas (); init_stats (); init_hooks (); read_conf_files (1); /* cold start init conf files */ initServerMask (); init_uid (); init_auth (); /* Initialise the auth code */ init_resolver (); /* Needs to be setup before the io loop */ init_reject (); /* Set up the reject code. */ init_umodes (); /* Set up the usermode system. */ initialize_foundation_signals(); /* register things that modules need */ #ifdef HAVE_LIBCRYPTO bio_spare_fd = save_spare_fd ("SSL private key validation"); #endif /* HAVE_LIBCRYPTO */ initialize_server_capabs (); /* Set up default_server_capabs */ initialize_global_set_options (); if (ServerInfo.name == NULL) { fprintf (stderr, "ERROR: No server name specified in serverinfo block.\n"); ilog (L_CRIT, "No server name specified in serverinfo block."); exit (EXIT_FAILURE); } strlcpy (me.name, ServerInfo.name, sizeof (me.name)); /* serverinfo{} description must exist. If not, error out. */ if (ServerInfo.description == NULL) { fprintf (stderr, "ERROR: No server description specified in serverinfo block.\n"); ilog (L_CRIT, "ERROR: No server description specified in serverinfo block."); exit (EXIT_FAILURE); } strlcpy (me.info, ServerInfo.description, sizeof (me.info)); me.from = &me; me.servptr = &me; SetMe (&me); make_server (&me); strlcpy (me.serv->up, me.name, sizeof (me.serv->up)); me.lasttime = me.since = me.firsttime = CurrentTime; hash_add_client (&me); /* add ourselves to global_serv_list */ dlinkAdd (&me, make_dlink_node (), &global_serv_list); check_class (); #ifndef STATIC_MODULES if (chdir (MODPATH)) { ilog (L_CRIT, "Could not load core modules. Terminating!"); exit (EXIT_FAILURE); } mod_set_base (); load_all_modules (1); load_core_modules (1); /* Go back to DPATH after checking to see if we can chdir to MODPATH */ chdir (ConfigFileEntry.dpath); #else load_all_modules (1); #endif write_pidfile (pidFileName); ilog (L_NOTICE, "Server Ready"); eventAddIsh ("cleanup_tklines", cleanup_tklines, NULL, CLEANUP_TKLINES_TIME); /* We want try_connections to be called as soon as possible now! -- adrian */ /* No, 'cause after a restart it would cause all sorts of nick collides */ eventAddIsh ("try_connections", try_connections, NULL, STARTUP_CONNECTIONS_TIME); eventAddIsh ("collect_zipstats", collect_zipstats, NULL, ZIPSTATS_TIME); /* Setup the timeout check. I'll shift it later :) -- adrian */ eventAddIsh ("comm_checktimeouts", comm_checktimeouts, NULL, 1); if (splitmode) eventAddIsh ("check_splitmode", check_splitmode, NULL, 60); ServerRunning = 1; io_loop (); return (0); }