src/EventLogger.c \
src/IRCEvents.c \
src/main.c \
+ src/signal.c \
src/ChanNode.c \
src/IRCParser.c \
src/ClientSocket.c \
*/
#include "main.h"
+#include "signal.h"
#include "ClientSocket.h"
#include "UserNode.h"
#include "ChanNode.h"
int statistics_enabled;
TIMEQ_CALLBACK(main_statistics);
TIMEQ_CALLBACK(main_checkauths);
+static int process_argc;
+static char **process_argv;
#ifdef HAVE_THREADS
int running_threads;
pthread_mutex_t cache_sync;
int main(int argc, char *argv[]) {
main:
+ process_argv = argv;
+ process_argc = argc;
+
+ signal(SIGABRT, sighandler);
+ signal(SIGFPE, sighandler);
+ signal(SIGILL, sighandler);
+ signal(SIGINT, sighandler);
+ signal(SIGSEGV, sighandler);
+ signal(SIGTERM, sighandler);
start_time = time(0);
#endif
cleanup();
if(hard_restart) {
- /* Append a NULL to the end of argv[]. */
- char **restart_argv = (char **)alloca((argc + 1) * sizeof(char *));
- memcpy(restart_argv, argv, argc * sizeof(char *));
- restart_argv[argc] = NULL;
-
- #ifdef WIN32
- execv(argv[0], (const char * const*)restart_argv);
- #else
- execv(argv[0], restart_argv);
- #endif
+ restart_process();
}
goto main;
}
+void restart_process() {
+ /* Append a NULL to the end of argv[]. */
+ char **restart_argv = (char **)alloca((process_argc + 1) * sizeof(char *));
+ memcpy(restart_argv, process_argv, process_argc * sizeof(char *));
+ restart_argv[process_argc] = NULL;
+ #ifdef WIN32
+ execv(process_argv[0], (const char * const*)restart_argv);
+ #else
+ execv(process_argv[0], restart_argv);
+ #endif
+}
+
int stricmp (const char *s1, const char *s2)
{
if (s1 == NULL) return s2 == NULL ? 0 : -(*s2);
int stricmp (const char *s1, const char *s2);
int stricmplen (const char *s1, const char *s2, int len);
+void restart_process();
+void cleanup();
void restart_bot(int do_hard_restart);
void stop_bot();
void reload_config();
--- /dev/null
+/* signal.c - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "signal.h"
+#include "bots.h"
+#include "ChanNode.h"
+#include "ClientSocket.h"
+#include "ConfigParser.h"
+
+static void sigcrash();
+static void sigexit();
+
+void sighandler(int signum) {
+ signal(signum, SIG_DFL);
+ switch(signum) {
+ case SIGABRT:
+ case SIGTERM:
+ case SIGINT:
+ //normal shutdown
+ sigexit(signum);
+ break;
+ case SIGSEGV:
+ case SIGFPE:
+ case SIGILL:
+ //crash
+ sigcrash(signum);
+ break;
+ }
+ kill(getpid(), signum);
+}
+
+static void sigcrash(int signum) {
+ char *coregen = "";
+ #ifndef WIN32
+ char gcore[50];
+ sprintf(gcore, "gcore %u", getpid());
+ system(gcore); //generate core file
+ coregen = "core file generated.";
+ #endif
+ char *signame;
+ switch(signum) {
+ case SIGSEGV:
+ signame = "SIGSEGV";
+ break;
+ case SIGFPE:
+ signame = "SIGFPE";
+ break;
+ case SIGILL:
+ signame = "SIGILL";
+ break;
+ default:
+ signame = "SIGUNKNOWN";
+ break;
+ }
+ char *alertchan = get_string_field("General.alertchan");
+ if(alertchan) {
+ struct ChanNode *channel = getChanByName(alertchan);
+ struct ClientSocket *client;
+ if(channel && (client = getChannelBot(channel, 0))) {
+ putsock(client, "PRIVMSG %s :\00304NeonServ received signal %d (%s). %s", alertchan, signum, signame, coregen);
+ }
+ }
+ //close all bots
+ struct ClientSocket *bot;
+ for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
+ if((bot->flags & SOCKET_FLAG_CONNECTED)) {
+ close(bot->sock);
+ bot->flags &= SOCKET_FLAG_CONNECTED;
+ }
+ }
+ sleep(1);
+ //hard restart
+ restart_process();
+}
+
+static void sigexit(int signum) {
+ cleanup();
+}
--- /dev/null
+/* signal.h - NeonServ v5.3
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _signal_h
+#define _signal_h
+
+#include "main.h"
+
+void sighandler(int signum);
+
+#endif
\ No newline at end of file