ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/main.c
Revision: 7005
Committed: Fri Jan 1 00:06:56 2016 UTC (9 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 6002 byte(s)
Log Message:
- Update copyright years

File Contents

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

Properties

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