ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/main.c
Revision: 5122
Committed: Thu Dec 25 16:50:00 2014 UTC (9 years, 3 months ago) by michael
Content type: text/x-csrc
File size: 6531 byte(s)
Log Message:
- Modernizie build system some more

File Contents

# Content
1 /*
2 Copyright (C) 2002-2003 Erik Fears
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (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, write to the Free Software
16
17 Foundation, Inc.
18 59 Temple Place - Suite 330
19 Boston, MA 02111-1307, USA.
20
21 */
22
23 #include "setup.h"
24
25 #include <stdio.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <sys/socket.h>
29 #include <netinet/in.h>
30 #include <arpa/inet.h>
31 #include <signal.h>
32 #include <unistd.h>
33 #include <errno.h>
34 #include <sys/resource.h> /* getrlimit */
35 #include <fcntl.h>
36
37 #ifdef STDC_HEADERS
38 #include <stdlib.h>
39 #include <string.h>
40 #endif
41
42 #include "compat.h"
43 #include "config.h"
44 #include "extern.h"
45 #include "irc.h"
46 #include "log.h"
47 #include "opercmd.h"
48 #include "scan.h"
49 #include "stats.h"
50 #include "negcache.h"
51 #include "options.h"
52 #include "malloc.h"
53 #include "firedns.h"
54 #include "main.h"
55
56
57 static void do_signal(int signum);
58
59 int RESTART = 0; /* Flagged to restart on next cycle */
60 int ALARMED = 0; /* Flagged to call timer functions on next cycle */
61 int REOPEN = 0; /* Flagged to reopen log files on next cycle */
62 unsigned int OPT_DEBUG = 0; /* Debug level */
63
64 char *CONFNAME = DEFAULTNAME;
65 static const char *CONFDIR = HOPM_ETCDIR;
66 static const char *LOGDIR = HOPM_LOGDIR;
67 char *CONFFILE, *LOGFILE;
68
69 struct sigaction ALARMACTION;
70 struct sigaction INTACTION;
71 struct sigaction USR1ACTION;
72
73 int main(int argc, char *argv[])
74 {
75 pid_t pid;
76 int c;
77 size_t lenc, lenl;
78 unsigned int i;
79 FILE *pidout;
80 struct rlimit rlim;
81
82 while (1)
83 {
84 c = getopt(argc, argv, "dc:");
85
86 if (c == -1)
87 break;
88
89 switch (c)
90 {
91 case 'c':
92 CONFNAME = xstrdup(optarg);
93 break;
94 case 'd':
95 OPT_DEBUG++;
96 break;
97 case '?':
98 default:
99 /* Unknown arg, guess we'll just do nothing for now. */
100 break;
101 }
102 }
103
104 lenc = strlen(CONFDIR) + strlen(CONFNAME) + strlen(CONFEXT) + 3;
105 lenl = strlen(LOGDIR) + strlen(CONFNAME) + strlen(LOGEXT) + 3;
106
107 CONFFILE = MyMalloc(lenc * sizeof *CONFFILE);
108 LOGFILE = MyMalloc(lenl * sizeof *LOGFILE);
109
110 snprintf(CONFFILE, lenc, "%s/%s.%s", CONFDIR, CONFNAME, CONFEXT);
111 snprintf(LOGFILE, lenl, "%s/%s.%s", LOGDIR, CONFNAME, LOGEXT);
112
113 /* Fork off. */
114
115 if (OPT_DEBUG <= 0)
116 {
117 if ((pid = fork()) < 0)
118 {
119 perror("fork()");
120 exit(EXIT_FAILURE);
121 }
122 else if (pid != 0)
123 {
124 _exit(EXIT_SUCCESS);
125 }
126
127 /* Get us in our own process group. */
128 if (setpgid(0, 0) < 0)
129 {
130 perror("setpgid()");
131 exit(EXIT_FAILURE);
132 }
133
134 /* Reset file mode. */
135 /* shasta: o+w is BAD, mmkay? */
136 umask(002);
137
138 /* Close file descriptors. */
139 close(STDIN_FILENO);
140 close(STDOUT_FILENO);
141 close(STDERR_FILENO);
142
143 log_open(LOGFILE);
144 }
145 else
146 log_printf("MAIN -> Debug level %d", OPT_DEBUG);
147
148
149 log_printf("MAIN -> HOPM %s started.", VERSION);
150 log_printf("MAIN -> Reading configuration file...");
151
152 config_load(CONFFILE);
153
154 if (OptionsItem->scanlog)
155 scanlog_open(OptionsItem->scanlog);
156
157 pidout = fopen(OptionsItem->pidfile, "w");
158
159 if (pidout)
160 {
161 char spid[16];
162
163 snprintf(spid, sizeof(spid), "%u", getpid());
164 fwrite(spid, sizeof(char), strlen(spid), pidout);
165 fclose(pidout);
166 }
167 else
168 {
169 log_printf("MAIN -> Error opening %s: %s", OptionsItem->pidfile,
170 strerror(errno));
171 exit(EXIT_FAILURE);
172 }
173
174 /* Setup alarm & int handlers. */
175
176 ALARMACTION.sa_handler = &(do_signal);
177 ALARMACTION.sa_flags = SA_RESTART;
178 INTACTION.sa_handler = &(do_signal);
179 USR1ACTION.sa_handler = &(do_signal);
180
181 sigaction(SIGALRM, &ALARMACTION, 0);
182 sigaction(SIGINT, &INTACTION, 0);
183 sigaction(SIGUSR1, &USR1ACTION, 0);
184
185 /* Ignore SIGPIPE. */
186 signal(SIGPIPE, SIG_IGN);
187
188 alarm(1);
189
190 while (1)
191 {
192
193
194 /* Main cycles */
195 irc_cycle();
196 scan_cycle();
197
198
199 /* Restart bopm if main_restart() was called (usually happens by m_kill in irc.c) */
200 if(RESTART)
201 {
202 /* If restarted in debug mode, die */
203 if(OPT_DEBUG)
204 return(1);
205
206 log_printf("MAIN -> Restarting process");
207
208 /* Get upper file descriptor limit */
209 if(getrlimit(RLIMIT_NOFILE, &rlim) == -1)
210 {
211 log_printf("MAIN RESTART -> getrlimit() error retrieving RLIMIT_NOFILE (%s)", strerror(errno));
212 return(1);
213 }
214
215 /* Set file descriptors 0-rlim_cur close on exec */
216 for(i = 0; i < rlim.rlim_cur; i++)
217 fcntl(i, F_SETFD, FD_CLOEXEC);
218
219 /* execute new process */
220 if(execve(argv[0], argv, NULL) == -1)
221 log_printf("MAIN RESTART -> Execution of \"%s\" failed. ERROR: %s", argv[0], strerror(errno));
222
223 /* Should only get here if execve failed */
224 RESTART = 0;
225 }
226
227 /* Check for log reopen */
228 if(REOPEN)
229 {
230 log_printf("MAIN -> Caught SIGUSR1, reopening logfiles");
231 log_close();
232 log_open(LOGFILE);
233
234 if(OptionsItem->scanlog)
235 {
236 scanlog_close();
237 scanlog_open(OptionsItem->scanlog);
238 }
239
240 log_printf("MAIN -> reopened logfiles");
241
242 REOPEN = 0;
243 }
244
245 /* Call 1 second timers */
246 if(ALARMED)
247 {
248 irc_timer();
249 scan_timer();
250 command_timer();
251
252 ALARMED = 0;
253 }
254
255
256 }
257
258 if (!OPT_DEBUG)
259 log_close();
260
261 /* If there's no scanlog open then this will do nothing anyway */
262 scanlog_close();
263
264 return(0);
265 }
266
267 static void do_signal(int signum)
268 {
269 switch (signum)
270 {
271 case SIGALRM:
272 ALARMED = 1;
273 alarm(1);
274 break;
275 case SIGINT:
276 log_printf("MAIN -> Caught SIGINT, bye!");
277 exit(0);
278 break;
279 case SIGUSR1:
280 REOPEN = 1;
281 break;
282 }
283 }
284
285
286 void main_restart(void)
287 {
288 RESTART = 1;
289 }