-/* main.c - NeonServ v5.3
+/* main.c - NeonServ v5.4
* Copyright (C) 2011-2012 Philipp Kreil (pk910)
*
* This program is free software: you can redistribute it and/or modify
#include "ModeNode.h"
#include "IRCQueue.h"
#include "DBHelper.h"
-#include "commands.h"
#include "ConfigParser.h"
#include "ssl.h"
#include "QServer.h"
#include "version.h"
+#include "modules.h"
+#include "module_commands.h"
+#include "ModuleFunctions.h"
time_t start_time;
static int running, hard_restart;
static void check_firstrun();
void cleanup() {
+ stop_modules();
free_sockets();
qserver_free();
free_parser();
free_bind();
free_modcmd();
free_whoqueue();
- free_bots();
free_mysql();
free_handleinfohandler();
free_lang();
socket_wait = time(0) + SOCKET_SELECT_TIME;
do {
if(!socket_loop(SOCKET_SELECT_TIME)) {
- putlog(LOGLEVEL_ERROR, "No more active Bots... shutting down.");
+ if(!running) break;
+ putlog(LOGLEVEL_ERROR, "No more active Bots... shutting down.\n");
cleanup();
exit(0);
}
} while(time(0) < socket_wait);
+ if(!running) break;
clearTempUsers();
destroyEvents();
mysql_free();
#endif
void exit_daemon() {
+ running = 0;
if(daemonized) {
remove(PID_FILE);
}
break;
}
}
+ #ifndef WIN32
if(geteuid() == 0 || getuid() == 0) {
fprintf(stderr, "NeonServ may not be run with super user privileges.\n");
exit(0);
}
+ #endif
+ #ifdef ENABLE_MEMORY_DEBUG
+ initMemoryDebug();
+ #endif
if(!loadConfig(CONF_FILE)) {
fprintf(stderr, "Unable to load " CONF_FILE "\n");
exit(0);
exit(0);
}
check_firstrun();
+ char **modulelist = get_all_fieldnames("modules");
+ if(!modulelist || !modulelist[0]) {
+ fprintf(stderr, "no modules loaded... Please update your configuration!\n");
+ exit(0);
+ }
+ free(modulelist);
if (run_as_daemon) {
#ifndef WIN32
/* Attempt to fork into the background if daemon mode is on. */
atexit(exit_daemon);
FILE *pidfile = fopen(PID_FILE, "w");
if (pidfile == NULL) {
- fprintf(stderr, "Unable to create PID file: %s", strerror(errno));
- putlog(LOGLEVEL_ERROR, "Unable to create PID file: %s", strerror(errno));
+ fprintf(stderr, "Unable to create PID file: %s\n", strerror(errno));
+ putlog(LOGLEVEL_ERROR, "Unable to create PID file: %s\n", strerror(errno));
} else {
fprintf(pidfile, "%i\n", (int)getpid());
fclose(pidfile);
}
- fclose(stdin); fopen("/dev/null", "r");
- fclose(stdout); fopen("/dev/null", "w");
- fclose(stderr); fopen("/dev/null", "w");
+ FILE *retn;
+ fclose(stdin); retn = fopen("/dev/null", "r");
+ fclose(stdout); retn = fopen("/dev/null", "w");
+ fclose(stderr); retn = fopen("/dev/null", "w");
#endif
}
signal(SIGSEGV, sighandler);
signal(SIGTERM, sighandler);
- #ifdef ENABLE_MEMORY_DEBUG
- initMemoryDebug();
- #endif
-
start_time = time(0);
#ifdef WIN32
init_ModeNode();
init_bind();
init_modcmd();
+ register_module_commands();
init_handleinfohandler();
init_tools();
- register_commands();
+ init_modulefunctions();
+ loadModules();
init_bots();
init_DBHelper();
qserver_init();
load_languages();
int update_minutes = get_int_field("statistics.frequency");
if(!update_minutes) update_minutes = 2;
- timeq_add(update_minutes * 60 + 10, main_statistics, NULL);
+ timeq_add(update_minutes * 60 + 10, 0, main_statistics, NULL);
- timeq_add(90, main_checkauths, NULL);
+ timeq_add(90, 0, main_checkauths, NULL);
int worker_threads = get_int_field("General.worker_threads");
if(!worker_threads) worker_threads = 1;
int usleep_delay = 1000000 / TICKS_PER_SECOND;
while(running) {
timeq_tick();
- loop_bots();
+ loop_modules();
qserver_loop();
queue_loop();
mysql_free();
socket_wait = time(0) + SOCKET_SELECT_TIME;
do {
if(!socket_loop(SOCKET_SELECT_TIME)) {
- putlog(LOGLEVEL_ERROR, "No more active Bots... shutting down.");
+ putlog(LOGLEVEL_ERROR, "No more active Bots... shutting down.\n");
cleanup();
exit(0);
}
} while(time(0) < socket_wait);
timeq_tick();
- loop_bots();
+ loop_modules();
clearTempUsers();
destroyEvents();
qserver_loop();
printf_mysql_query("SELECT `user_id`, `user_registered` FROM `users` WHERE `user_user` = '%s'", escape_string(auth));
res = mysql_use();
if ((row = mysql_fetch_row(res)) != NULL) {
- if(!exists || (strcmp(row[1], "0") && registered != atoi(row[1]))) {
+ int diff = registered - atoi(row[1]);
+ if(diff < 0)
+ diff *= -1;
+ if(!exists || (strcmp(row[1], "0") && diff > 86400)) {
//User is no longer valid! Delete it...
deleteUser(atoi(row[0]));
char *alertchan = get_string_field("General.CheckAuths.alertchan");
if(alertchan) {
+ char reason[MAXLEN];
+ if(!exists) {
+ strcpy(reason, "USER_NOT_EXISTS");
+ } else {
+ sprintf(reason, "USER_REGISTERED_MISSMATCH: %lu, expected %d (diff: %d)", (unsigned long) registered, atoi(row[1]), diff);
+ }
struct ChanNode *alertchan_chan = getChanByName(alertchan);
struct ClientSocket *alertclient;
if(alertchan_chan && (alertclient = getChannelBot(alertchan_chan, 0)) != NULL) {
- putsock(alertclient, "PRIVMSG %s :Deleted User %s", alertchan_chan->name, auth);
+ putsock(alertclient, "PRIVMSG %s :Deleted User %s (%s)", alertchan_chan->name, auth, reason);
}
}
} else if(exists && !strcmp(row[1], "0")) {
if ((row = mysql_fetch_row(res)) != NULL) {
lastcheck = atoi(row[1]);
if(!lastcheck || unixtime - lastcheck >= min_unckecked) {
- lookup_authname(row[0], main_checkauths_callback, NULL);
+ lookup_authname(row[0], 0, main_checkauths_callback, NULL);
} else
next_call = 300;
}
}
}
- timeq_add(next_call, main_checkauths, NULL);
+ timeq_add(next_call, 0, main_checkauths, NULL);
}
TIMEQ_CALLBACK(main_statistics) {
int update_minutes = get_int_field("statistics.frequency");
if(!update_minutes) update_minutes = 2;
- timeq_add(update_minutes * 60, main_statistics, NULL);
+ timeq_add(update_minutes * 60, 0, main_statistics, NULL);
if(get_int_field("statistics.enable")) {
statistics_enabled = 1;
statistics_requested_lusers = 1;
statistics_enabled = 0;
}
-void statistics_update() {
+int statistics_update() {
if(get_int_field("statistics.enable") && statistics_requested_lusers && get_string_field("statistics.execute")) {
statistics_requested_lusers = 0;
char command[MAXLEN];
sprintf(command, "%s %d %d %d %d %d %d %d", get_string_field("statistics.execute"), getUserCount(), getChanUserCount(), getChannelCount(), statistics_privmsg, statistics_commands, statistics_network_users, statistics_network_channels);
statistics_privmsg = 0;
statistics_commands = 0;
- system(command);
+ return system(command);
}
+ return -1;
+}
+
+time_t getStartTime() {
+ return start_time;
+}
+
+int getRunningThreads() {
+ #ifdef HAVE_THREADS
+ return running_threads;
+ #else
+ return 1;
+ #endif
}
void write_log(int loglevel, const char *line, int len) {
printf("AuthServ account name of admin user: ");
char *ptr;
char adminuser[31];
- fgets(adminuser, 30, stdin);
+ ptr = fgets(adminuser, 30, stdin);
for(ptr = adminuser; *ptr; ptr++) { if(*ptr == '\n' || *ptr == '\r') *ptr = '\0'; }
if(strlen(adminuser) < 2) goto check_firstrun_admin;
printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(adminuser));
char bot_nick[31];
check_firstrun_bot_nick:
printf("Nick: ");
- fgets(bot_nick, 30, stdin);
+ ptr = fgets(bot_nick, 30, stdin);
for(ptr = bot_nick; *ptr; ptr++) { if(*ptr == '\n' || *ptr == '\r') *ptr = '\0'; }
if(strlen(bot_nick) < 2) goto check_firstrun_bot_nick;
char bot_ident[16];
check_firstrun_bot_ident:
printf("Ident: ");
- fgets(bot_ident, 15, stdin);
+ ptr = fgets(bot_ident, 15, stdin);
for(ptr = bot_ident; *ptr; ptr++) { if(*ptr == '\n' || *ptr == '\r') *ptr = '\0'; }
if(strlen(bot_ident) < 2) goto check_firstrun_bot_ident;
char bot_realname[101];
check_firstrun_bot_realname:
printf("Realname: ");
- fgets(bot_realname, 100, stdin);
+ ptr = fgets(bot_realname, 100, stdin);
for(ptr = bot_realname; *ptr; ptr++) { if(*ptr == '\n' || *ptr == '\r') *ptr = '\0'; }
if(strlen(bot_realname) < 2) goto check_firstrun_bot_realname;
char bot_server[101];
check_firstrun_bot_server:
printf("Server: [irc.onlinegamesnet.net] ");
- fgets(bot_server, 100, stdin);
+ ptr = fgets(bot_server, 100, stdin);
for(ptr = bot_server; *ptr; ptr++) { if(*ptr == '\n' || *ptr == '\r') *ptr = '\0'; }
if(*bot_server && strlen(bot_nick) < 5) goto check_firstrun_bot_server;
if(!*bot_server)
int bot_port;
char bot_port_buf[7];
printf("Port: [6667] ");
- fgets(bot_port_buf, 6, stdin);
+ ptr = fgets(bot_port_buf, 6, stdin);
for(ptr = bot_port_buf; *ptr; ptr++) { if(*ptr == '\n' || *ptr == '\r') *ptr = '\0'; }
if(!*bot_port_buf)
bot_port = 6667;
char bot_ssl_buf[5];
check_firstrun_bot_ssl:
printf("SSL: [y/N] ");
- fgets(bot_ssl_buf, 4, stdin);
+ ptr = fgets(bot_ssl_buf, 4, stdin);
for(ptr = bot_ssl_buf; *ptr; ptr++) { if(*ptr == '\n' || *ptr == '\r') *ptr = '\0'; }
if(!*bot_ssl_buf || tolower(*bot_ssl_buf) == 'n')
bot_ssl = 0;
goto check_firstrun_bot_ssl;
char bot_pass[101];
printf("Server Password: [] ");
- fgets(bot_pass, 100, stdin);
+ ptr = fgets(bot_pass, 100, stdin);
for(ptr = bot_pass; *ptr; ptr++) { if(*ptr == '\n' || *ptr == '\r') *ptr = '\0'; }
int bot_maxchan;
char bot_maxchan_buf[5];
printf("MaxChannel: [20] ");
- fgets(bot_maxchan_buf, 5, stdin);
+ ptr = fgets(bot_maxchan_buf, 5, stdin);
for(ptr = bot_maxchan_buf; *ptr; ptr++) { if(*ptr == '\n' || *ptr == '\r') *ptr = '\0'; }
if(*bot_maxchan_buf)
bot_maxchan = atoi(bot_maxchan_buf);
char bot_queue_buf[5];
check_firstrun_bot_queue:
printf("Queue (prevents excess floods): [Y/n] ");
- fgets(bot_queue_buf, 4, stdin);
+ ptr = fgets(bot_queue_buf, 4, stdin);
for(ptr = bot_queue_buf; *ptr; ptr++) { if(*ptr == '\n' || *ptr == '\r') *ptr = '\0'; }
if(!*bot_queue_buf || tolower(*bot_queue_buf) == 'y')
bot_queue = 1;