ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/main.c
Revision: 9865
Committed: Sat Jan 2 18:42:37 2021 UTC (3 years, 2 months ago) by michael
Content type: text/x-csrc
File size: 6566 byte(s)
Log Message:
- Bump copyright years

File Contents

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

Properties

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