#include "hash.h"
#include "irc_string.h"
#include "ircd_signal.h"
-#include "sprintf_irc.h"
-#include "s_gline.h"
#include "msg.h" /* msgtab */
#include "hostmask.h"
#include "numeric.h"
#include "serno.h"
#include "sslproc.h"
-/*
- * Try and find the correct name to use with getrlimit() for setting the max.
- * number of files allowed to be open by this process.
- */
-int _charybdis_data_version = CHARYBDIS_DV;
-
-extern int ServerRunning;
-extern struct LocalUser meLocalUser;
-extern char **myargv;
+/* /quote set variables */
+struct SetOptions GlobalSetOptions;
-int maxconnections;
+/* configuration set from ircd.conf */
+struct config_file_entry ConfigFileEntry;
+/* server info set from ircd.conf */
+struct server_info ServerInfo;
+/* admin info set from ircd.conf */
+struct admin_info AdminInfo;
-/* /quote set variables */\r
-struct SetOptions GlobalSetOptions;
-\r
-/* configuration set from ircd.conf */\r
-struct config_file_entry ConfigFileEntry;\r
-/* server info set from ircd.conf */\r
-struct server_info ServerInfo;\r
-/* admin info set from ircd.conf */\r
-struct admin_info AdminInfo;\r
-\r
-struct Counter Count;\r
+struct Counter Count;
struct ServerStatistics ServerStats;
-int ssl_ok = 0;\r
+int maxconnections;
+struct timeval SystemTime;
+struct Client me; /* That's me */
+struct LocalUser meLocalUser; /* That's also part of me */
+
+rb_dlink_list lclient_list = { NULL, NULL, 0 };
+rb_dlink_list global_client_list = { NULL, NULL, 0 };
+rb_dlink_list global_channel_list = { NULL, NULL, 0 };
+
+rb_dlink_list unknown_list; /* unknown clients ON this server only */
+rb_dlink_list serv_list; /* local servers to this server ONLY */
+rb_dlink_list global_serv_list; /* global servers on the network */
+rb_dlink_list local_oper_list; /* our opers, duplicated in lclient_list */
+rb_dlink_list oper_list; /* network opers */
+
+time_t startup_time;
+
+int default_server_capabs = CAP_MASK;
+
+int splitmode;
+int splitchecking;
+int split_users;
+int split_servers;
+int eob_count;
+
+unsigned long initialVMTop = 0; /* top of virtual memory at init */
+const char *logFileName = LPATH;
+const char *pidFileName = PPATH;
+
+char **myargv;
+int dorehash = 0;
+int dorehashbans = 0;
+int doremotd = 0;
+int kline_queued = 0;
+int server_state_foreground = 0;
+int opers_see_all_users = 0;
+int ssl_ok = 0;
int zlib_ok = 1;
+int testing_conf = 0;
+
+struct config_channel_entry ConfigChannel;
+rb_bh *channel_heap;
+rb_bh *ban_heap;
+rb_bh *topic_heap;
+rb_bh *member_heap;
+
+rb_bh *client_heap = NULL;
+rb_bh *lclient_heap = NULL;
+rb_bh *pclient_heap = NULL;
+
+char current_uid[IDLEN];
+
+/* patricia */
+rb_bh *prefix_heap;
+rb_bh *node_heap;
+rb_bh *patricia_heap;
+
+rb_bh *linebuf_heap;
+
+rb_bh *dnode_heap;
+
+void
+ircd_shutdown(const char *reason)
+{
+ struct Client *target_p;
+ rb_dlink_node *ptr;
+
+ RB_DLINK_FOREACH(ptr, lclient_list.head)
+ {
+ target_p = ptr->data;
+
+ sendto_one(target_p, ":%s NOTICE %s :Server Terminating. %s",
+ me.name, target_p->name, reason);
+ }
+
+ RB_DLINK_FOREACH(ptr, serv_list.head)
+ {
+ target_p = ptr->data;
+
+ sendto_one(target_p, ":%s ERROR :Terminated by %s",
+ me.name, reason);
+ }
+
+ ilog(L_MAIN, "Server Terminating. %s", reason);
+ close_logfiles();
+
+ unlink(pidFileName);
+ exit(0);
+}
+
/*
* print_startup - print startup information
*/
static void
ircd_die_cb(const char *str)
{
- /* Try to get the message out to currently logged in operators. */
- sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Server panic! %s", str);
- inotice("server panic: %s", str);
+ if(str != NULL)
+ {
+ /* Try to get the message out to currently logged in operators. */
+ sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Server panic! %s", str);
+ inotice("server panic: %s", str);
+ }
unlink(pidFileName);
exit(EXIT_FAILURE);
static void
init_sys(void)
{
-#if defined(RLIMIT_NOFILE) && defined(HAVE_SYS_RESOURCE_H)\r
- struct rlimit limit;\r
-\r
- if(!getrlimit(RLIMIT_NOFILE, &limit))\r
- {\r
- maxconnections = limit.rlim_cur;\r
- if(maxconnections <= MAX_BUFFER)\r
- {\r
- fprintf(stderr, "ERROR: Shell FD limits are too low.\n");\r
- fprintf(stderr, "ERROR: ircd-ratbox reserves %d FDs, shell limits must be above this\n", MAX_BUFFER);\r
- exit(EXIT_FAILURE);\r
- }\r
- return;\r
- }\r
-#endif /* RLIMIT_FD_MAX */\r
+#if defined(RLIMIT_NOFILE) && defined(HAVE_SYS_RESOURCE_H)
+ struct rlimit limit;
+
+ if(!getrlimit(RLIMIT_NOFILE, &limit))
+ {
+ maxconnections = limit.rlim_cur;
+ if(maxconnections <= MAX_BUFFER)
+ {
+ fprintf(stderr, "ERROR: Shell FD limits are too low.\n");
+ fprintf(stderr, "ERROR: ircd-ratbox reserves %d FDs, shell limits must be above this\n", MAX_BUFFER);
+ exit(EXIT_FAILURE);
+ }
+ return;
+ }
+#endif /* RLIMIT_FD_MAX */
maxconnections = MAXCONNECTIONS;
}
{
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Got signal SIGUSR1, reloading ircd motd file");
- free_cachefile(user_motd);
- user_motd = cache_file(MPATH, "ircd.motd", 0);
+ cache_user_motd();
doremotd = 0;
}
}
memset(&GlobalSetOptions, 0, sizeof(GlobalSetOptions));
/* memset( &ConfigFileEntry, 0, sizeof(ConfigFileEntry)); */
- GlobalSetOptions.maxclients = ServerInfo.default_max_clients;\r
-\r
- if(GlobalSetOptions.maxclients > (maxconnections - MAX_BUFFER))\r
+ GlobalSetOptions.maxclients = ServerInfo.default_max_clients;
+
+ if(GlobalSetOptions.maxclients > (maxconnections - MAX_BUFFER) || (GlobalSetOptions.maxclients <= 0))
GlobalSetOptions.maxclients = maxconnections - MAX_BUFFER;
GlobalSetOptions.autoconn = 1;
GlobalSetOptions.ident_timeout = IDENT_TIMEOUT;
- strlcpy(GlobalSetOptions.operstring,
+ rb_strlcpy(GlobalSetOptions.operstring,
ConfigFileEntry.default_operstring,
sizeof(GlobalSetOptions.operstring));
- strlcpy(GlobalSetOptions.adminstring,
+ rb_strlcpy(GlobalSetOptions.adminstring,
ConfigFileEntry.default_adminstring,
sizeof(GlobalSetOptions.adminstring));
struct ev_entry *check_splitmode_ev = NULL;
+static int
+seed_with_urandom(void)
+{
+ unsigned int seed;
+ int fd;
+
+ fd = open("/dev/urandom", O_RDONLY);
+ if(fd >= 0)
+ {
+ if(read(fd, &seed, sizeof(seed)) == sizeof(seed))
+ {
+ close(fd);
+ srand(seed);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static void
+seed_with_clock(void)
+{
+ const struct timeval *tv;
+ rb_set_time();
+ tv = rb_current_time_tv();
+ srand(tv->tv_sec ^ (tv->tv_usec | (getpid() << 20)));
+}
+
+static void
+seed_random(void *unused)
+{
+ unsigned int seed;
+ if(rb_get_random(&seed, sizeof(seed)) == -1)
+ {
+ if(!seed_with_urandom())
+ seed_with_clock();
+ return;
+ }
+ srand(seed);
+}
+
/*
* main
*
*/
setup_corefile();
- 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));
ierror("no server name specified in serverinfo block.");
return -1;
}
- strlcpy(me.name, ServerInfo.name, sizeof(me.name));
+ rb_strlcpy(me.name, ServerInfo.name, sizeof(me.name));
if(ServerInfo.sid[0] == '\0')
{
ierror("no server description specified in serverinfo block.");
return -3;
}
- strlcpy(me.info, ServerInfo.description, sizeof(me.info));
-
- if(ServerInfo.ssl_cert != NULL && ServerInfo.ssl_private_key != NULL)\r
- {\r
- /* just do the rb_setup_ssl_server to validate the config */\r
- if(!rb_setup_ssl_server(ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params))\r
- {\r
- ilog(L_MAIN, "WARNING: Unable to setup SSL.");\r
- ssl_ok = 0;\r
- }\r
- else\r
- ssl_ok = 1;\r
+ rb_strlcpy(me.info, ServerInfo.description, sizeof(me.info));
+
+ if(ServerInfo.ssl_cert != NULL && ServerInfo.ssl_private_key != NULL)
+ {
+ /* just do the rb_setup_ssl_server to validate the config */
+ if(!rb_setup_ssl_server(ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params))
+ {
+ ilog(L_MAIN, "WARNING: Unable to setup SSL.");
+ ssl_ok = 0;
+ }
+ else
+ ssl_ok = 1;
}
if (testing_conf)
ilog(L_MAIN, "Server Ready");
- rb_event_addish("cleanup_glines", cleanup_glines, NULL, CLEANUP_GLINES_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 */
/* um. by waiting even longer, that just means we have even *more*
*/
rb_event_addish("try_connections", try_connections, NULL, STARTUP_CONNECTIONS_TIME);
rb_event_addonce("try_connections_startup", try_connections, NULL, 0);
-
- /* Setup the timeout check. I'll shift it later :) -- adrian */
- rb_event_addish("rb_checktimeouts", rb_checktimeouts, NULL, 1);
-
rb_event_add("check_rehash", check_rehash, NULL, 1);
+ rb_event_addish("reseed_srand", seed_random, NULL, 300); /* reseed every 10 minutes */
if(splitmode)
check_splitmode_ev = rb_event_add("check_splitmode", check_splitmode, NULL, 2);
- ServerRunning = 1;
-
print_startup(getpid());
- rb_lib_loop(250);
+ rb_lib_loop(0);
return 0;
}