ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/main.c
Revision: 5351
Committed: Sun Jan 11 13:24:19 2015 UTC (9 years, 2 months ago) by michael
Content type: text/x-csrc
File size: 6082 byte(s)
Log Message:
- Update license headers

File Contents

# Content
1 /*
2 * Copyright (c) 2002-2003 Erik Fears
3 * Copyright (c) 2014-2015 ircd-hybrid development team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
18 * USA
19 */
20
21 #include "setup.h"
22
23 #include <stdio.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <sys/socket.h>
27 #include <netinet/in.h>
28 #include <arpa/inet.h>
29 #include <signal.h>
30 #include <unistd.h>
31 #include <errno.h>
32 #include <sys/resource.h> /* getrlimit */
33 #include <fcntl.h>
34 #include <stdlib.h>
35 #include <string.h>
36
37 #include "compat.h"
38 #include "config.h"
39 #include "irc.h"
40 #include "log.h"
41 #include "opercmd.h"
42 #include "scan.h"
43 #include "stats.h"
44 #include "negcache.h"
45 #include "options.h"
46 #include "memory.h"
47 #include "firedns.h"
48 #include "main.h"
49
50
51 static int RESTART = 0; /* Flagged to restart on next cycle */
52 static int ALARMED = 0; /* Flagged to call timer functions on next cycle */
53 static int REOPEN = 0; /* Flagged to reopen log files on next cycle */
54
55 static struct sigaction ALARMACTION;
56 static struct sigaction INTACTION;
57 static struct sigaction USR1ACTION;
58
59 static char *CONFNAME = DEFAULTNAME;
60 static const char *CONFDIR = HOPM_ETCDIR;
61 static const char *LOGDIR = HOPM_LOGDIR;
62 static char *CONFFILE, *LOGFILE;
63
64 unsigned int OPT_DEBUG = 0; /* Debug level */
65
66
67 static void
68 do_signal(int signum)
69 {
70 switch (signum)
71 {
72 case SIGALRM:
73 ALARMED = 1;
74 alarm(1);
75 break;
76 case SIGINT:
77 log_printf("MAIN -> Caught SIGINT, bye!");
78 exit(0);
79 break;
80 case SIGUSR1:
81 REOPEN = 1;
82 break;
83 }
84 }
85
86 int
87 main(int argc, char *argv[])
88 {
89 pid_t pid;
90 size_t lenc, lenl;
91 FILE *pidout;
92 struct rlimit rlim;
93
94 while (1)
95 {
96 int c = getopt(argc, argv, "dc:");
97
98 if (c == -1)
99 break;
100
101 switch (c)
102 {
103 case 'c':
104 CONFNAME = xstrdup(optarg);
105 break;
106 case 'd':
107 ++OPT_DEBUG;
108 break;
109 default: /* Unknown arg, guess we'll just do nothing for now. */
110 break;
111 }
112 }
113
114 lenc = strlen(CONFDIR) + strlen(CONFNAME) + strlen(CONFEXT) + 3;
115 lenl = strlen(LOGDIR) + strlen(CONFNAME) + strlen(LOGEXT) + 3;
116
117 CONFFILE = xcalloc(lenc * sizeof *CONFFILE);
118 LOGFILE = xcalloc(lenl * sizeof *LOGFILE);
119
120 snprintf(CONFFILE, lenc, "%s/%s.%s", CONFDIR, CONFNAME, CONFEXT);
121 snprintf(LOGFILE, lenl, "%s/%s.%s", LOGDIR, CONFNAME, LOGEXT);
122
123 /* Fork off. */
124 if (OPT_DEBUG == 0)
125 {
126 if ((pid = fork()) < 0)
127 {
128 perror("fork()");
129 exit(EXIT_FAILURE);
130 }
131 else if (pid != 0)
132 _exit(EXIT_SUCCESS);
133
134 /* Get us in our own process group. */
135 if (setpgid(0, 0) < 0)
136 {
137 perror("setpgid()");
138 exit(EXIT_FAILURE);
139 }
140
141 /* Reset file mode. */
142 /* shasta: o+w is BAD, mmkay? */
143 umask(002);
144
145 /* Close file descriptors. */
146 close(STDIN_FILENO);
147 close(STDOUT_FILENO);
148 close(STDERR_FILENO);
149
150 log_open(LOGFILE);
151 }
152 else
153 log_printf("MAIN -> Debug level %d", OPT_DEBUG);
154
155 log_printf("MAIN -> HOPM %s started.", VERSION);
156 log_printf("MAIN -> Reading configuration file...");
157
158 config_load(CONFFILE);
159
160 if (OptionsItem->scanlog)
161 scanlog_open(OptionsItem->scanlog);
162
163 pidout = fopen(OptionsItem->pidfile, "w");
164
165 if (pidout)
166 {
167 fprintf(pidout, "%u\n", (unsigned int)getpid());
168 fclose(pidout);
169 }
170 else
171 {
172 log_printf("MAIN -> Error opening %s: %s", OptionsItem->pidfile,
173 strerror(errno));
174 exit(EXIT_FAILURE);
175 }
176
177 /* Setup alarm & int handlers. */
178 ALARMACTION.sa_handler = &do_signal;
179 ALARMACTION.sa_flags = SA_RESTART;
180 INTACTION.sa_handler = &do_signal;
181 USR1ACTION.sa_handler = &do_signal;
182
183 sigaction(SIGALRM, &ALARMACTION, 0);
184 sigaction(SIGINT, &INTACTION, 0);
185 sigaction(SIGUSR1, &USR1ACTION, 0);
186
187 /* Ignore SIGPIPE. */
188 signal(SIGPIPE, SIG_IGN);
189
190 alarm(1);
191
192 while (1)
193 {
194 /* Main cycles */
195 irc_cycle();
196 scan_cycle();
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 (unsigned int 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 if (!OPT_DEBUG)
256 log_close();
257
258 /* If there's no scanlog open then this will do nothing anyway */
259 scanlog_close();
260 return 0;
261 }
262
263 void
264 main_restart(void)
265 {
266 RESTART = 1;
267 }

Properties

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