ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/main.c
Revision: 5207
Committed: Mon Dec 29 19:38:22 2014 UTC (11 years, 6 months ago) by michael
Content type: text/x-csrc
File size: 6483 byte(s)
Log Message:
- Removed AC_HEADER_STDC configure test

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

Properties

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