ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/releases/1.0.0beta2/src/main.c
Revision: 5236
Committed: Wed Dec 31 15:43:14 2014 UTC (11 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 6062 byte(s)
Log Message:
RELEASE TAG 1.0.0beta2

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

Properties

Name Value
svn:eol-style native
svn:keywords Id