/* * add_accept() * * input - pointer to clients accept list to add to * - pointer to client to add * output - none * side effects - target is added to clients list */ static void add_accept(struct Client *source_p, struct Client *target_p) { dlink_node *m; m = make_dlink_node(); dlinkAdd(target_p, m, &source_p->allow_list); m = make_dlink_node() dlinkAdd(source_p, m, &target_p->on_allow_list); }
/* * check for public repeating and keep/replace appropriate last phrase * -demond */ static int check_repeat(struct Client *source_p, struct Channel *chptr, char *text) { dlink_node *ptr; struct Repeat *repeatptr; for (ptr = source_p->user->repeat.head; ptr; ptr = ptr->next) { repeatptr = ptr->data; if (repeatptr->chptr == chptr) if (!strcmp(repeatptr->text, text)) { return 1; } else { MyFree(repeatptr->text); DupString(repeatptr->text, text); repeatptr->lastphrase = CurrentTime; return 0; } } repeatptr = (struct Repeat *)MyMalloc(sizeof(struct Repeat)); repeatptr->chptr = chptr; DupString(repeatptr->text, text); repeatptr->lastphrase = CurrentTime; ptr = make_dlink_node(); dlinkAdd(repeatptr, ptr, &source_p->user->repeat); return 0; }
/* * dead_link - Adds client to a list of clients that need an exit_client() * */ void dead_link(struct Client *client_p) { dlink_node *m; const char *notice; if(IsClosing(client_p)) return; linebuf_donebuf(&client_p->localClient->buf_recvq); linebuf_donebuf(&client_p->localClient->buf_sendq); if(client_p->flags & FLAGS_SENDQEX) notice = "Max SendQ exceeded"; else notice = "Dead link"; if (!IsPerson(client_p) && !IsUnknown(client_p) && !IsClosing(client_p)) { sendto_realops_flags(FLAGS_ALL, L_ADMIN, notice, get_client_name(client_p, HIDE_IP)); sendto_realops_flags(FLAGS_ALL, L_OPER, notice, get_client_name(client_p, MASK_IP)); } Debug((DEBUG_ERROR, notice, get_client_name(to, HIDE_IP))); assert(dlinkFind(&abort_list, client_p) == NULL); m = make_dlink_node(); dlinkAdd(client_p, m, &abort_list); SetDead(client_p); /* You are dead my friend */ }
/* * linebuf_new_line * * Create a new line, and link it to the given linebuf. * It will be initially empty. */ static buf_line_t * linebuf_new_line(buf_head_t * bufhead) { buf_line_t *bufline; dlink_node *node; bufline = linebuf_allocate(); if(bufline == NULL) return NULL; ++bufline_count; node = make_dlink_node(); bufline->len = 0; bufline->terminated = 0; bufline->flushing = 0; bufline->raw = 0; /* Stick it at the end of the buf list */ dlinkAddTail(bufline, node, &bufhead->list); bufline->refcount++; /* And finally, update the allocated size */ bufhead->alloclen++; bufhead->numlines++; return bufline; }
static struct dbuf_block * dbuf_alloc(struct dbuf_queue *qptr) { struct dbuf_block *block = BlockHeapAlloc(dbuf_heap); dlinkAddTail(block, make_dlink_node(), &qptr->blocks); return block; }
static struct dbuf_block * dbuf_alloc(struct dbuf_queue *qptr) { struct dbuf_block *block = mp_pool_get(dbuf_pool); memset(block, 0, sizeof(*block)); dlinkAddTail(block, make_dlink_node(), &qptr->blocks); return block; }
/* * make_client - create a new Client struct and set it to initial state. * * from == NULL, create local client (a client connected * to a socket). * * from, create remote client (behind a socket * associated with the client defined by * 'from'). ('from' is a local client!!). */ struct Client* make_client(struct Client* from) { struct Client* client_p = NULL; struct LocalUser *localClient; dlink_node *m; client_p = BlockHeapAlloc(client_heap); memset(client_p, 0, sizeof(struct Client)); if (from == NULL) { client_p->from = client_p; /* 'from' of local client is self! */ client_p->since = client_p->lasttime = client_p->firsttime = CurrentTime; localClient = (struct LocalUser *)BlockHeapAlloc(lclient_heap); memset(localClient, 0, sizeof(struct LocalUser)); client_p->localClient = localClient; client_p->localClient->fd = -1; client_p->localClient->ctrlfd = -1; #ifndef HAVE_SOCKETPAIR client_p->localClient->fd_r = -1; client_p->localClient->ctrlfd_r = -1; #endif /* as good a place as any... */ m = make_dlink_node(); dlinkAdd(client_p, m, &unknown_list); ++local_client_count; } else { /* from is not NULL */ client_p->localClient = NULL; client_p->from = from; /* 'from' of local client is self! */ ++remote_client_count; } client_p->status = STAT_UNKNOWN; strcpy(client_p->username, "unknown"); #if 0 client_p->name[0] = '\0'; client_p->flags = 0; client_p->next = NULL; client_p->prev = NULL; client_p->hnext = NULL; client_p->lnext = NULL; client_p->lprev = NULL; client_p->user = NULL; client_p->serv = NULL; client_p->servptr = NULL; client_p->whowas = NULL; client_p->allow_list.head = NULL; client_p->allow_list.tail = NULL; client_p->on_allow_list.head = NULL; client_p->on_allow_list.tail = NULL; #endif return client_p; }
/*! \brief Blindly opers up given source_p, using conf info. * All checks on passwords have already been done. * \param source_p Pointer to given client to oper * \param conf operator {} configuration record */ static void oper_up(struct Client *source_p, const struct MaskItem *conf) { const unsigned int old = source_p->umodes; ++Count.oper; SetOper(source_p); if (conf->modes) AddUMode(source_p, conf->modes); else if (ConfigGeneral.oper_umodes) AddUMode(source_p, ConfigGeneral.oper_umodes); if (!(old & UMODE_INVISIBLE) && HasUMode(source_p, UMODE_INVISIBLE)) ++Count.invisi; else if ((old & UMODE_INVISIBLE) && !HasUMode(source_p, UMODE_INVISIBLE)) --Count.invisi; assert(dlinkFind(&oper_list, source_p) == NULL); dlinkAdd(source_p, make_dlink_node(), &oper_list); AddOFlag(source_p, conf->port); if (HasOFlag(source_p, OPER_FLAG_ADMIN)) AddUMode(source_p, UMODE_ADMIN); if (!EmptyString(conf->whois)) { svstag_attach(&source_p->svstags, RPL_WHOISOPERATOR, "+", conf->whois); sendto_server(NULL, 0, 0, ":%s SVSTAG %s %ju %u + :%s", me.id, source_p->id, source_p->tsinfo, RPL_WHOISOPERATOR, conf->whois); } ilog(LOG_TYPE_OPER, "OPER %s by %s!%s@%s", conf->name, source_p->name, source_p->username, source_p->host); sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE, "%s is now an operator", get_oper_name(source_p)); sendto_server(NULL, 0, 0, ":%s GLOBOPS :%s is now an operator", me.id, get_oper_name(source_p)); send_umode_out(source_p, old); sendto_one_numeric(source_p, &me, RPL_YOUREOPER); }
static void do_list(struct Client *source_p, char *arg) { struct ListTask *lt = NULL; int no_masked_channels = 1; if (source_p->connection->list_task) { free_list_task(source_p); sendto_one_numeric(source_p, &me, RPL_LISTEND); return; } lt = MyCalloc(sizeof(struct ListTask)); lt->users_max = UINT_MAX; lt->created_max = UINT_MAX; lt->topicts_max = UINT_MAX; source_p->connection->list_task = lt; if (!EmptyString(arg)) { char *opt, *save = NULL; dlink_list *list = NULL; int i = 0, errors = 0; for (opt = strtoken(&save, arg, ","); opt; opt = strtoken(&save, NULL, ",")) { switch (*opt) { case '<': if ((i = atoi(opt + 1)) > 0) lt->users_max = (unsigned int)i - 1; else errors = 1; break; case '>': if ((i = atoi(opt + 1)) >= 0) lt->users_min = (unsigned int)i + 1; else errors = 1; break; case 'C': case 'c': switch (*++opt) { case '<': if ((i = atoi(opt + 1)) >= 0) lt->created_max = (unsigned int)(CurrentTime - 60 * i); else errors = 1; break; case '>': if ((i = atoi(opt + 1)) >= 0) lt->created_min = (unsigned int)(CurrentTime - 60 * i); else errors = 1; break; default: errors = 1; } break; case 'T': case 't': switch (*++opt) { case '<': if ((i = atoi(opt + 1)) >= 0) lt->topicts_min = (unsigned int)(CurrentTime - 60 * i); else errors = 1; break; case '>': if ((i = atoi(opt + 1)) >= 0) lt->topicts_max = (unsigned int)(CurrentTime - 60 * i); else errors = 1; break; case ':': if (strlcpy(lt->topic, opt + 1, sizeof(lt->topic)) == 0) errors = 1; break; default: errors = 1; } break; default: if (*opt == '!') { list = <->hide_mask; opt++; } else list = <->show_mask; if (has_wildcards(opt + !!IsChanPrefix(*opt))) { if (list == <->show_mask) no_masked_channels = 0; } else if (!IsChanPrefix(*opt)) errors = 1; if (!errors) dlinkAdd(xstrdup(opt), make_dlink_node(), list); } } if (errors) { free_list_task(source_p); sendto_one_numeric(source_p, &me, ERR_LISTSYNTAX); return; } } dlinkAdd(source_p, <->node, &listing_client_list); sendto_one_numeric(source_p, &me, RPL_LISTSTART); safe_list_channels(source_p, no_masked_channels && lt->show_mask.head != NULL); }
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; }
static void do_list(struct Client *source_p, int parc, char *parv[]) { struct ListTask *lt; int no_masked_channels; if (MyConnect(source_p)) { if (source_p->localClient->list_task != NULL) { free_list_task(source_p->localClient->list_task, source_p); sendto_one(source_p, form_str(RPL_LISTEND), me.name, source_p->name); return; } } lt = (struct ListTask *) MyMalloc(sizeof(struct ListTask)); lt->users_max = UINT_MAX; lt->created_max = UINT_MAX; lt->topicts_max = UINT_MAX; if (MyConnect(source_p)) source_p->localClient->list_task = lt; no_masked_channels = 1; if (parc > 1) { char *opt, *save; dlink_list *list; int i, errors = 0; for (opt = strtoken(&save, parv[1], ","); opt != NULL; opt = strtoken(&save, NULL, ",")) switch (*opt) { case '<': if ((i = atoi(opt + 1)) > 0) lt->users_max = (unsigned int) i - 1; else errors = 1; break; case '>': if ((i = atoi(opt + 1)) >= 0) lt->users_min = (unsigned int) i + 1; else errors = 1; break; case '-': break; case 'C': case 'c': switch (*++opt) { case '<': if ((i = atoi(opt + 1)) >= 0) lt->created_max = (unsigned int) (CurrentTime - 60 * i); else errors = 1; break; case '>': if ((i = atoi(opt + 1)) >= 0) lt->created_min = (unsigned int) (CurrentTime - 60 * i); else errors = 1; break; default: errors = 1; } break; case 'T': case 't': switch (*++opt) { case '<': if ((i = atoi(opt + 1)) >= 0) lt->topicts_min = (unsigned int) (CurrentTime - 60 * i); else errors = 1; break; case '>': if ((i = atoi(opt + 1)) >= 0) lt->topicts_max = (unsigned int) (CurrentTime - 60 * i); else errors = 1; break; default: errors = 1; } break; default: if (*opt == '!') { list = <->hide_mask; opt++; } else list = <->show_mask; if (has_wildcards(opt + !!IsChanPrefix(*opt))) { if (list == <->show_mask) no_masked_channels = 0; } else if (!IsChanPrefix(*opt)) errors = 1; if (!errors) { char *s; DupString(s, opt); dlinkAdd(s, make_dlink_node(), list); } } if (errors) { free_list_task(lt, source_p); sendto_one(source_p, form_str(ERR_LISTSYNTAX), MyConnect(source_p) ? me.name : ID(&me), MyConnect(source_p) ? source_p->name : ID(source_p)); return; } } if (MyConnect(source_p)) dlinkAdd(source_p, make_dlink_node(), &listing_client_list); sendto_one(source_p, form_str(RPL_LISTSTART), MyConnect(source_p) ? me.name : ID(&me), MyConnect(source_p) ? source_p->name : ID(source_p)); safe_list_channels(source_p, lt, no_masked_channels && lt->show_mask.head != NULL, !MyConnect(source_p)); }
/* ** Exit one client, local or remote. Assuming all dependents have ** been already removed, and socket closed for local client. */ static void exit_one_client(struct Client *client_p, struct Client *source_p, struct Client *from, const char *comment) { struct Client* target_p; dlink_node *lp; dlink_node *next_lp; if (IsServer(source_p)) { if (source_p->servptr && source_p->servptr->serv) del_client_from_llist(&(source_p->servptr->serv->servers), source_p); else ts_warn("server %s without servptr!", source_p->name); if(!IsMe(source_p)) remove_server_from_list(source_p); } else if (source_p->servptr && source_p->servptr->serv) { del_client_from_llist(&(source_p->servptr->serv->users), source_p); } /* there are clients w/o a servptr: unregistered ones */ /* ** For a server or user quitting, propogate the information to ** other servers (except to the one where is came from (client_p)) */ if (IsMe(source_p)) { sendto_realops_flags(FLAGS_ALL, L_ALL, "ERROR: tried to exit me! : %s", comment); return; /* ...must *never* exit self!! */ } else if (IsServer(source_p)) { /* ** Old sendto_serv_but_one() call removed because we now ** need to send different names to different servers ** (domain name matching) */ /* ** The bulk of this is done in remove_dependents now, all ** we have left to do is send the SQUIT upstream. -orabidoo */ if (source_p->localClient) { if(source_p->localClient->ctrlfd > -1) { fd_close(source_p->localClient->ctrlfd); source_p->localClient->ctrlfd = -1; #ifndef HAVE_SOCKETPAIR fd_close(source_p->localClient->ctrlfd_r); fd_close(source_p->localClient->fd_r); source_p->localClient->ctrlfd_r = -1; source_p->localClient->fd_r = -1; #endif } } target_p = source_p->from; if (target_p && IsServer(target_p) && target_p != client_p && !IsMe(target_p) && (source_p->flags & FLAGS_KILLED) == 0) sendto_one(target_p, ":%s SQUIT %s :%s", from->name, source_p->name, comment); } else if (source_p->name[0]) /* ...just clean all others with QUIT... */ { /* ** If this exit is generated from "m_kill", then there ** is no sense in sending the QUIT--KILL's have been ** sent instead. */ if ((source_p->flags & FLAGS_KILLED) == 0) { sendto_server(client_p, source_p, NULL, NOCAPS, NOCAPS, NOFLAGS, ":%s QUIT :%s", source_p->name, comment); } /* ** If a person is on a channel, send a QUIT notice ** to every client (person) on the same channel (so ** that the client can show the "**signoff" message). ** (Note: The notice is to the local clients *only*) */ if (source_p->user) { sendto_common_channels_local(source_p, ":%s!%s@%s QUIT :%s", source_p->name, source_p->username, source_p->host, comment); for (lp = source_p->user->channel.head; lp; lp = next_lp) { next_lp = lp->next; remove_user_from_channel(lp->data, source_p); } /* Should not be in any channels now */ assert(source_p->user->channel.head == NULL); /* Clean up invitefield */ for (lp = source_p->user->invited.head; lp; lp = next_lp) { next_lp = lp->next; del_invite(lp->data, source_p); } /* Clean up allow lists */ del_all_accepts(source_p); add_history(source_p, 0); off_history(source_p); if (HasID(source_p)) del_from_id_hash_table(source_p->user->id, source_p); /* again, this is all that is needed */ } } /* * Remove source_p from the client lists */ del_from_client_hash_table(source_p->name, source_p); /* remove from global client list */ remove_client_from_list(source_p); /* Check to see if the client isn't already on the dead list */ assert(dlinkFind(&dead_list, source_p) == NULL); /* add to dead client dlist */ lp = make_dlink_node(); SetDead(source_p); dlinkAdd(source_p, lp, &dead_list); }
* linebuf_attach * * attach the lines in a buf_head_t to another buf_head_t * without copying the data (using refcounts). */ void linebuf_attach(buf_head_t * bufhead, buf_head_t * new) { dlink_node *new_node; dlink_node *node; buf_line_t *line; DLINK_FOREACH(node, new->list.head) { line = (buf_line_t *) node->data; new_node = make_dlink_node(); dlinkAddTail(line, new_node, &bufhead->list); /* Update the allocated size */ bufhead->alloclen++; bufhead->len += line->len; bufhead->numlines++; line->refcount++; } } /* * linebuf_putmsg * * Similar to linebuf_put, but designed for use by send.c.
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); }