/[svn]/hopm/branches/1.0.x/src/main.c
ViewVC logotype

Contents of /hopm/branches/1.0.x/src/main.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5201 - (show annotations)
Mon Dec 29 17:49:44 2014 UTC (4 years, 11 months ago) by michael
File MIME type: text/x-chdr
File size: 6511 byte(s)
- Moved OPT_DEBUG prototype to main.h (where it belongs to) and removed extern.h

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

Properties

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

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.26