root/trunk/wifidog/src/gateway.c @ 85

Revision 85, 5.0 KB (checked in by alexcv, 9 years ago)

Fixed sigterm handler running twice on Linux

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/********************************************************************\
2 * This program is free software; you can redistribute it and/or    *
3 * modify it under the terms of the GNU General Public License as   *
4 * published by the Free:Software Foundation; either version 2 of   *
5 * the License, or (at your option) any later version.              *
6 *                                                                  *
7 * This program is distributed in the hope that it will be useful,  *
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
10 * GNU General Public License for more details.                     *
11 *                                                                  *
12 * You should have received a copy of the GNU General Public License*
13 * along with this program; if not, contact:                        *
14 *                                                                  *
15 * Free Software Foundation           Voice:  +1-617-542-5942       *
16 * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
17 * Boston, MA  02111-1307,  USA       gnu@gnu.org                   *
18 *                                                                  *
19 \********************************************************************/
20
21/* $Header$ */
22/** @internal
23  @file gateway.c
24  @brief Main loop
25  @author Copyright (C) 2004 Philippe April <papril777@yahoo.com>
26 */
27
28#include "common.h"
29
30extern s_config config;
31
32pthread_mutex_t sigterm_mutex = PTHREAD_MUTEX_INITIALIZER;
33
34void
35main_loop(void)
36{
37        struct timeval tv;
38        time_t last_checked;
39        httpd * webserver;
40        int result;
41        pthread_t       tid;
42
43        /* Initialize the linked list */
44        node_init();
45
46        // Initialize the web server
47        debug(D_LOG_DEBUG, "Creating web server on %s:%d", 
48                        config.gw_address, config.gw_port);
49        webserver = httpdCreate(config.gw_address, config.gw_port);
50        if (webserver == NULL) {
51                debug(D_LOG_ERR, "Could not create web server");
52                exit(1);
53        }
54        debug(D_LOG_DEBUG, "Assigning callbacks to web server");
55        httpdAddCContent(webserver, "/wifidog", "about", 0, NULL,
56                        http_callback_about);
57        httpdAddCContent(webserver, "/wifidog", "auth", 0, NULL,
58                        http_callback_auth);
59        httpdAddC404Content(webserver, http_callback_404);
60
61        // Init the signals to catch chld/quit/etc
62        init_signals();
63
64        // Reset the firewall
65        fw_init();
66
67        /* start clean up thread */
68        pthread_create(&tid, NULL, (void *)cleanup_thread, NULL);
69        pthread_detach(tid);
70       
71        debug(D_LOG_DEBUG, "Waiting for connections");
72        while(1) {
73                tv.tv_sec = config.checkinterval;
74                tv.tv_usec = 0;
75                result = httpdGetConnection(webserver, &tv);
76                if (result == -1) {
77                        /* Interrupted system call */
78                        continue; /* restart loop */
79                } else if (result < -1) {
80                        /*
81                         * FIXME
82                         * An error occurred - should we abort?
83                         * reboot the device ?
84                         */
85                        debug(D_LOG_ERR, "httpdGetConnection returned %d",
86                                result);
87                        fw_destroy();
88                        exit(1);
89                } else if (result > 0) {
90                        /*
91                         * We got a connection
92                         */
93                        debug(D_LOG_DEBUG, "Received connection from %s",
94                                webserver->clientAddr);
95                        if (httpdReadRequest(webserver) >=0) {
96                                /*
97                                 * We read the request fine
98                                 */
99                                debug(D_LOG_DEBUG, "Processing request from "
100                                        "%s", webserver->clientAddr);
101                                httpdProcessRequest(webserver);
102                        }
103                        else {
104                                debug(D_LOG_ERR, "No valid request received "
105                                        "from %s", webserver->clientAddr);
106                        }
107                        debug(D_LOG_DEBUG, "Closing connection with %s",
108                                webserver->clientAddr);
109                        httpdEndRequest(webserver);
110                }
111        }
112
113        fw_destroy();
114}
115
116int
117main(int argc, char **argv)
118{
119        config_init();
120
121        parse_commandline(argc, argv);
122
123        config_read(config.configfile);
124        config_validate();
125
126        init_userclasses(0);
127       
128        if (config.daemon) {
129                int childPid;
130
131                debug(D_LOG_INFO, "Forking into background");
132
133                switch((childPid = fork())) {
134                case -1: /* error */
135                        debug(D_LOG_ERR, "fork(): %s", strerror(errno));
136                        exit(1);
137                        break;
138
139                case 0: /* parent */
140                        main_loop();
141                        break;
142
143                default: /* child */
144                        exit(0);
145                        break;
146                }
147        } else {
148                main_loop();
149        }
150
151        return(0);
152}
153
154void
155sigchld_handler(int s)
156{
157        int     status;
158       
159        wait(&status);
160}
161
162void
163termination_handler(int s)
164{
165        /* Makes sure we only call fw_destroy() once. */
166        if (pthread_mutex_trylock(&sigterm_mutex))
167                return;
168       
169        fw_destroy();
170
171        debug(D_LOG_INFO, "Exiting...");
172        exit(0);
173}
174
175void
176init_signals(void)
177{
178        struct sigaction sa;
179
180        debug(D_LOG_DEBUG, "Initializing signal handlers");
181       
182        sa.sa_handler = sigchld_handler;
183        sigemptyset(&sa.sa_mask);
184        sa.sa_flags = SA_RESTART;
185        if (sigaction(SIGCHLD, &sa, NULL) == -1) {
186                debug(D_LOG_ERR, "sigaction(): %s", strerror(errno));
187                exit(1);
188        }
189
190        sa.sa_handler = termination_handler;
191        sigemptyset(&sa.sa_mask);
192        sa.sa_flags = SA_RESTART;
193
194        /* Trap SIGTERM */
195        if (sigaction(SIGTERM, &sa, NULL) == -1) {
196                debug(D_LOG_ERR, "sigaction(): %s", strerror(errno));
197                exit(1);
198        }
199
200        /* Trap SIGQUIT */
201        if (sigaction(SIGQUIT, &sa, NULL) == -1) {
202                debug(D_LOG_ERR, "sigaction(): %s", strerror(errno));
203                exit(1);
204        }
205
206        /* Trap SIGINT */
207        if (sigaction(SIGINT, &sa, NULL) == -1) {
208                debug(D_LOG_ERR, "sigaction(): %s", strerror(errno));
209                exit(1);
210        }
211}
212
Note: See TracBrowser for help on using the browser.