added signal handler
[NeonServV5.git] / src / signal.c
1 /* signal.c - NeonServ v5.3
2  * Copyright (C) 2011-2012  Philipp Kreil (pk910)
3  * 
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  * 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * 
14  * You should have received a copy of the GNU General Public License 
15  * along with this program. If not, see <http://www.gnu.org/licenses/>. 
16  */
17 #include "signal.h"
18 #include "bots.h"
19 #include "ChanNode.h"
20 #include "ClientSocket.h"
21 #include "ConfigParser.h"
22
23 static void sigcrash();
24 static void sigexit();
25
26 void sighandler(int signum) {
27     signal(signum, SIG_DFL);
28     switch(signum) {
29         case SIGABRT:
30         case SIGTERM:
31         case SIGINT:
32             //normal shutdown
33             sigexit(signum);
34             break;
35         case SIGSEGV:
36         case SIGFPE:
37         case SIGILL:
38             //crash
39             sigcrash(signum);
40             break;
41     }
42     kill(getpid(), signum);
43 }
44
45 static void sigcrash(int signum) {
46     char *coregen = "";
47     #ifndef WIN32
48     char gcore[50];
49     sprintf(gcore, "gcore %u", getpid());
50     system(gcore); //generate core file
51     coregen = "core file generated.";
52     #endif
53     char *signame;
54     switch(signum) {
55         case SIGSEGV:
56             signame = "SIGSEGV";
57             break;
58         case SIGFPE:
59             signame = "SIGFPE";
60             break;
61         case SIGILL:
62             signame = "SIGILL";
63             break;
64         default:
65             signame = "SIGUNKNOWN";
66             break;
67     }
68     char *alertchan = get_string_field("General.alertchan");
69     if(alertchan) {
70         struct ChanNode *channel = getChanByName(alertchan);
71         struct ClientSocket *client;
72         if(channel && (client = getChannelBot(channel, 0))) {
73             putsock(client, "PRIVMSG %s :\00304NeonServ received signal %d (%s). %s", alertchan, signum, signame, coregen);
74         }
75     }
76     //close all bots
77     struct ClientSocket *bot;
78     for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
79         if((bot->flags & SOCKET_FLAG_CONNECTED)) {
80             close(bot->sock);
81             bot->flags &= SOCKET_FLAG_CONNECTED;
82         }
83     }
84     sleep(1);
85     //hard restart
86     restart_process();
87 }
88
89 static void sigexit(int signum) {
90     cleanup();
91 }