ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/main.c
Revision: 5202
Committed: Mon Dec 29 17:50:43 2014 UTC (10 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 6511 byte(s)
Log Message:
- Moved OPT_DEBUG prototype to main.h (where it belongs to) and removed extern.h

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    
37     #ifdef STDC_HEADERS
38     #include <stdlib.h>
39     #include <string.h>
40     #endif
41    
42     #include "compat.h"
43     #include "config.h"
44     #include "irc.h"
45     #include "log.h"
46     #include "opercmd.h"
47     #include "scan.h"
48     #include "stats.h"
49     #include "negcache.h"
50     #include "options.h"
51     #include "malloc.h"
52     #include "firedns.h"
53     #include "main.h"
54    
55    
56 michael 5122 static void do_signal(int signum);
57 michael 5052
58     int RESTART = 0; /* Flagged to restart on next cycle */
59     int ALARMED = 0; /* Flagged to call timer functions on next cycle */
60     int REOPEN = 0; /* Flagged to reopen log files on next cycle */
61     unsigned int OPT_DEBUG = 0; /* Debug level */
62    
63     char *CONFNAME = DEFAULTNAME;
64 michael 5072 static const char *CONFDIR = HOPM_ETCDIR;
65     static const char *LOGDIR = HOPM_LOGDIR;
66 michael 5052 char *CONFFILE, *LOGFILE;
67    
68     struct sigaction ALARMACTION;
69     struct sigaction INTACTION;
70     struct sigaction USR1ACTION;
71    
72 michael 5082 int main(int argc, char *argv[])
73 michael 5052 {
74     pid_t pid;
75     int c;
76 michael 5072 size_t lenc, lenl;
77     unsigned int i;
78 michael 5052 FILE *pidout;
79     struct rlimit rlim;
80    
81     while (1)
82     {
83     c = getopt(argc, argv, "dc:");
84    
85     if (c == -1)
86     break;
87    
88     switch (c)
89     {
90     case 'c':
91 michael 5093 CONFNAME = xstrdup(optarg);
92 michael 5052 break;
93     case 'd':
94     OPT_DEBUG++;
95     break;
96     case '?':
97     default:
98     /* Unknown arg, guess we'll just do nothing for now. */
99     break;
100     }
101     }
102    
103     lenc = strlen(CONFDIR) + strlen(CONFNAME) + strlen(CONFEXT) + 3;
104     lenl = strlen(LOGDIR) + strlen(CONFNAME) + strlen(LOGEXT) + 3;
105    
106     CONFFILE = MyMalloc(lenc * sizeof *CONFFILE);
107     LOGFILE = MyMalloc(lenl * sizeof *LOGFILE);
108    
109     snprintf(CONFFILE, lenc, "%s/%s.%s", CONFDIR, CONFNAME, CONFEXT);
110     snprintf(LOGFILE, lenl, "%s/%s.%s", LOGDIR, CONFNAME, LOGEXT);
111    
112     /* Fork off. */
113    
114     if (OPT_DEBUG <= 0)
115     {
116     if ((pid = fork()) < 0)
117     {
118     perror("fork()");
119     exit(EXIT_FAILURE);
120     }
121     else if (pid != 0)
122     {
123     _exit(EXIT_SUCCESS);
124     }
125    
126     /* Get us in our own process group. */
127     if (setpgid(0, 0) < 0)
128     {
129     perror("setpgid()");
130     exit(EXIT_FAILURE);
131     }
132    
133     /* Reset file mode. */
134     /* shasta: o+w is BAD, mmkay? */
135     umask(002);
136    
137     /* Close file descriptors. */
138     close(STDIN_FILENO);
139     close(STDOUT_FILENO);
140     close(STDERR_FILENO);
141    
142     log_open(LOGFILE);
143     }
144     else
145     log_printf("MAIN -> Debug level %d", OPT_DEBUG);
146    
147    
148 michael 5069 log_printf("MAIN -> HOPM %s started.", VERSION);
149 michael 5052 log_printf("MAIN -> Reading configuration file...");
150    
151     config_load(CONFFILE);
152    
153     if (OptionsItem->scanlog)
154     scanlog_open(OptionsItem->scanlog);
155    
156 michael 5082 pidout = fopen(OptionsItem->pidfile, "w");
157 michael 5052
158 michael 5082 if (pidout)
159     {
160     char spid[16];
161 michael 5052
162 michael 5082 snprintf(spid, sizeof(spid), "%u", getpid());
163 michael 5052 fwrite(spid, sizeof(char), strlen(spid), pidout);
164     fclose(pidout);
165 michael 5082 }
166     else
167     {
168     log_printf("MAIN -> Error opening %s: %s", OptionsItem->pidfile,
169     strerror(errno));
170     exit(EXIT_FAILURE);
171     }
172 michael 5052
173     /* Setup alarm & int handlers. */
174    
175     ALARMACTION.sa_handler = &(do_signal);
176     ALARMACTION.sa_flags = SA_RESTART;
177     INTACTION.sa_handler = &(do_signal);
178     USR1ACTION.sa_handler = &(do_signal);
179    
180     sigaction(SIGALRM, &ALARMACTION, 0);
181     sigaction(SIGINT, &INTACTION, 0);
182     sigaction(SIGUSR1, &USR1ACTION, 0);
183    
184     /* Ignore SIGPIPE. */
185     signal(SIGPIPE, SIG_IGN);
186    
187     alarm(1);
188    
189     while (1)
190     {
191    
192    
193     /* Main cycles */
194     irc_cycle();
195     scan_cycle();
196    
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(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     }
256    
257     if (!OPT_DEBUG)
258     log_close();
259    
260     /* If there's no scanlog open then this will do nothing anyway */
261     scanlog_close();
262    
263     return(0);
264     }
265    
266     static void do_signal(int signum)
267     {
268     switch (signum)
269     {
270     case SIGALRM:
271     ALARMED = 1;
272     alarm(1);
273     break;
274     case SIGINT:
275     log_printf("MAIN -> Caught SIGINT, bye!");
276     exit(0);
277     break;
278     case SIGUSR1:
279     REOPEN = 1;
280     break;
281     }
282     }
283    
284    
285     void main_restart(void)
286     {
287     RESTART = 1;
288     }

Properties

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