ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/releases/1.0.2/src/main.c
Revision: 5218
Committed: Tue Dec 30 17:18:47 2014 UTC (11 years, 7 months ago) by michael
Content type: text/x-csrc
Original Path: hopm/branches/1.0.x/src/main.c
File size: 6062 byte(s)
Log Message:
- main.c: style corrections

File Contents

# User Rev Content
1 michael 5052 /*
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 michael 5218 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 michael 5052
57 michael 5218 static struct sigaction ALARMACTION;
58     static struct sigaction INTACTION;
59     static struct sigaction USR1ACTION;
60 michael 5052
61 michael 5218 static char *CONFNAME = DEFAULTNAME;
62 michael 5072 static const char *CONFDIR = HOPM_ETCDIR;
63     static const char *LOGDIR = HOPM_LOGDIR;
64 michael 5218 static char *CONFFILE, *LOGFILE;
65 michael 5052
66 michael 5218 unsigned int OPT_DEBUG = 0; /* Debug level */
67 michael 5052
68 michael 5218
69     static void
70     do_signal(int signum)
71 michael 5052 {
72 michael 5218 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 michael 5052
88 michael 5218 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 michael 5052
96 michael 5218 while (1)
97     {
98     int c = getopt(argc, argv, "dc:");
99 michael 5052
100 michael 5218 if (c == -1)
101     break;
102 michael 5052
103 michael 5218 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 michael 5052
116 michael 5218 lenc = strlen(CONFDIR) + strlen(CONFNAME) + strlen(CONFEXT) + 3;
117     lenl = strlen(LOGDIR) + strlen(CONFNAME) + strlen(LOGEXT) + 3;
118 michael 5052
119 michael 5218 CONFFILE = MyMalloc(lenc * sizeof *CONFFILE);
120     LOGFILE = MyMalloc(lenl * sizeof *LOGFILE);
121 michael 5052
122 michael 5218 snprintf(CONFFILE, lenc, "%s/%s.%s", CONFDIR, CONFNAME, CONFEXT);
123     snprintf(LOGFILE, lenl, "%s/%s.%s", LOGDIR, CONFNAME, LOGEXT);
124 michael 5052
125 michael 5218 /* 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 michael 5052
136 michael 5218 /* Get us in our own process group. */
137     if (setpgid(0, 0) < 0)
138     {
139     perror("setpgid()");
140     exit(EXIT_FAILURE);
141     }
142 michael 5052
143 michael 5218 /* Reset file mode. */
144     /* shasta: o+w is BAD, mmkay? */
145     umask(002);
146 michael 5052
147 michael 5218 /* Close file descriptors. */
148     close(STDIN_FILENO);
149     close(STDOUT_FILENO);
150     close(STDERR_FILENO);
151 michael 5052
152 michael 5218 log_open(LOGFILE);
153     }
154     else
155     log_printf("MAIN -> Debug level %d", OPT_DEBUG);
156 michael 5052
157 michael 5218 log_printf("MAIN -> HOPM %s started.", VERSION);
158     log_printf("MAIN -> Reading configuration file...");
159 michael 5052
160 michael 5218 config_load(CONFFILE);
161 michael 5052
162 michael 5218 if (OptionsItem->scanlog)
163     scanlog_open(OptionsItem->scanlog);
164 michael 5052
165 michael 5218 pidout = fopen(OptionsItem->pidfile, "w");
166 michael 5052
167 michael 5218 if (pidout)
168     {
169     char spid[16];
170 michael 5052
171 michael 5218 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 michael 5052
182 michael 5218 /* 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 michael 5052
188 michael 5218 sigaction(SIGALRM, &ALARMACTION, 0);
189     sigaction(SIGINT, &INTACTION, 0);
190     sigaction(SIGUSR1, &USR1ACTION, 0);
191 michael 5052
192 michael 5218 /* Ignore SIGPIPE. */
193     signal(SIGPIPE, SIG_IGN);
194 michael 5052
195 michael 5218 alarm(1);
196 michael 5052
197 michael 5218 while (1)
198     {
199     /* Main cycles */
200     irc_cycle();
201     scan_cycle();
202 michael 5052
203 michael 5218 /* 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 michael 5052
210 michael 5218 log_printf("MAIN -> Restarting process");
211 michael 5052
212 michael 5218 /* Get upper file descriptor limit */
213     if (getrlimit(RLIMIT_NOFILE, &rlim) == -1)
214 michael 5052 {
215 michael 5218 log_printf("MAIN RESTART -> getrlimit() error retrieving RLIMIT_NOFILE (%s)", strerror(errno));
216     return 1;
217 michael 5052 }
218    
219 michael 5218 /* 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 michael 5052
223 michael 5218 /* 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 michael 5052
227 michael 5218 /* Should only get here if execve failed */
228     RESTART = 0;
229     }
230 michael 5052
231 michael 5218 /* Check for log reopen */
232     if (REOPEN)
233     {
234     log_printf("MAIN -> Caught SIGUSR1, reopening logfiles");
235     log_close();
236     log_open(LOGFILE);
237 michael 5052
238 michael 5218 if (OptionsItem->scanlog)
239 michael 5052 {
240 michael 5218 scanlog_close();
241     scanlog_open(OptionsItem->scanlog);
242 michael 5052 }
243    
244 michael 5218 log_printf("MAIN -> reopened logfiles");
245 michael 5052
246 michael 5218 REOPEN = 0;
247     }
248 michael 5052
249 michael 5218 /* Call 1 second timers */
250     if (ALARMED)
251     {
252     irc_timer();
253     scan_timer();
254     command_timer();
255 michael 5052
256 michael 5218 ALARMED = 0;
257     }
258     }
259 michael 5052
260 michael 5218 if (!OPT_DEBUG)
261     log_close();
262 michael 5052
263 michael 5218 /* If there's no scanlog open then this will do nothing anyway */
264     scanlog_close();
265     return 0;
266 michael 5052 }
267    
268 michael 5218 void
269     main_restart(void)
270 michael 5052 {
271 michael 5218 RESTART = 1;
272 michael 5052 }

Properties

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