ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/branches/1.1.x/src/main.c
Revision: 5333
Committed: Wed Jan 7 20:45:06 2015 UTC (10 years, 7 months ago) by michael
Content type: text/x-csrc
Original Path: hopm/trunk/src/main.c
File size: 5989 byte(s)
Log Message:
- Move malloc.c to memory.c

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 michael 5333 #include "memory.h"
49 michael 5052 #include "firedns.h"
50     #include "main.h"
51    
52    
53 michael 5217 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 5217 static struct sigaction ALARMACTION;
58     static struct sigaction INTACTION;
59     static struct sigaction USR1ACTION;
60 michael 5052
61 michael 5217 static char *CONFNAME = DEFAULTNAME;
62 michael 5072 static const char *CONFDIR = HOPM_ETCDIR;
63     static const char *LOGDIR = HOPM_LOGDIR;
64 michael 5217 static char *CONFFILE, *LOGFILE;
65 michael 5052
66 michael 5217 unsigned int OPT_DEBUG = 0; /* Debug level */
67 michael 5052
68 michael 5217
69     static void
70     do_signal(int signum)
71 michael 5052 {
72 michael 5217 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 5217 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 5217 while (1)
97     {
98     int c = getopt(argc, argv, "dc:");
99 michael 5052
100 michael 5217 if (c == -1)
101     break;
102 michael 5052
103 michael 5217 switch (c)
104     {
105     case 'c':
106     CONFNAME = xstrdup(optarg);
107     break;
108     case 'd':
109 michael 5219 ++OPT_DEBUG;
110 michael 5217 break;
111     default: /* Unknown arg, guess we'll just do nothing for now. */
112     break;
113     }
114     }
115 michael 5052
116 michael 5217 lenc = strlen(CONFDIR) + strlen(CONFNAME) + strlen(CONFEXT) + 3;
117     lenl = strlen(LOGDIR) + strlen(CONFNAME) + strlen(LOGEXT) + 3;
118 michael 5052
119 michael 5274 CONFFILE = xcalloc(lenc * sizeof *CONFFILE);
120     LOGFILE = xcalloc(lenl * sizeof *LOGFILE);
121 michael 5052
122 michael 5217 snprintf(CONFFILE, lenc, "%s/%s.%s", CONFDIR, CONFNAME, CONFEXT);
123     snprintf(LOGFILE, lenl, "%s/%s.%s", LOGDIR, CONFNAME, LOGEXT);
124 michael 5052
125 michael 5217 /* Fork off. */
126 michael 5219 if (OPT_DEBUG == 0)
127 michael 5217 {
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 5217 /* 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 5217 /* Reset file mode. */
144     /* shasta: o+w is BAD, mmkay? */
145     umask(002);
146 michael 5052
147 michael 5217 /* Close file descriptors. */
148     close(STDIN_FILENO);
149     close(STDOUT_FILENO);
150     close(STDERR_FILENO);
151 michael 5052
152 michael 5217 log_open(LOGFILE);
153     }
154     else
155     log_printf("MAIN -> Debug level %d", OPT_DEBUG);
156 michael 5052
157 michael 5217 log_printf("MAIN -> HOPM %s started.", VERSION);
158     log_printf("MAIN -> Reading configuration file...");
159 michael 5052
160 michael 5217 config_load(CONFFILE);
161 michael 5052
162 michael 5217 if (OptionsItem->scanlog)
163     scanlog_open(OptionsItem->scanlog);
164 michael 5052
165 michael 5217 pidout = fopen(OptionsItem->pidfile, "w");
166 michael 5052
167 michael 5217 if (pidout)
168     {
169 michael 5323 fprintf(pidout, "%u\n", (unsigned int)getpid());
170 michael 5217 fclose(pidout);
171     }
172     else
173     {
174     log_printf("MAIN -> Error opening %s: %s", OptionsItem->pidfile,
175     strerror(errno));
176     exit(EXIT_FAILURE);
177     }
178 michael 5052
179 michael 5217 /* Setup alarm & int handlers. */
180     ALARMACTION.sa_handler = &do_signal;
181     ALARMACTION.sa_flags = SA_RESTART;
182     INTACTION.sa_handler = &do_signal;
183     USR1ACTION.sa_handler = &do_signal;
184 michael 5052
185 michael 5217 sigaction(SIGALRM, &ALARMACTION, 0);
186     sigaction(SIGINT, &INTACTION, 0);
187     sigaction(SIGUSR1, &USR1ACTION, 0);
188 michael 5052
189 michael 5217 /* Ignore SIGPIPE. */
190     signal(SIGPIPE, SIG_IGN);
191 michael 5052
192 michael 5217 alarm(1);
193 michael 5052
194 michael 5217 while (1)
195     {
196     /* Main cycles */
197     irc_cycle();
198     scan_cycle();
199 michael 5052
200 michael 5217 /* Restart bopm if main_restart() was called (usually happens by m_kill in irc.c) */
201     if (RESTART)
202     {
203     /* If restarted in debug mode, die */
204     if (OPT_DEBUG)
205     return 1;
206 michael 5052
207 michael 5217 log_printf("MAIN -> Restarting process");
208 michael 5052
209 michael 5217 /* Get upper file descriptor limit */
210     if (getrlimit(RLIMIT_NOFILE, &rlim) == -1)
211 michael 5052 {
212 michael 5217 log_printf("MAIN RESTART -> getrlimit() error retrieving RLIMIT_NOFILE (%s)", strerror(errno));
213     return 1;
214 michael 5052 }
215    
216 michael 5217 /* Set file descriptors 0-rlim_cur close on exec */
217     for (unsigned int i = 0; i < rlim.rlim_cur; ++i)
218     fcntl(i, F_SETFD, FD_CLOEXEC);
219 michael 5052
220 michael 5217 /* execute new process */
221     if (execve(argv[0], argv, NULL) == -1)
222     log_printf("MAIN RESTART -> Execution of \"%s\" failed. ERROR: %s", argv[0], strerror(errno));
223 michael 5052
224 michael 5217 /* Should only get here if execve failed */
225     RESTART = 0;
226     }
227 michael 5052
228 michael 5217 /* Check for log reopen */
229     if (REOPEN)
230     {
231     log_printf("MAIN -> Caught SIGUSR1, reopening logfiles");
232     log_close();
233     log_open(LOGFILE);
234 michael 5052
235 michael 5217 if (OptionsItem->scanlog)
236 michael 5052 {
237 michael 5217 scanlog_close();
238     scanlog_open(OptionsItem->scanlog);
239 michael 5052 }
240    
241 michael 5217 log_printf("MAIN -> reopened logfiles");
242 michael 5052
243 michael 5217 REOPEN = 0;
244     }
245 michael 5052
246 michael 5217 /* Call 1 second timers */
247     if (ALARMED)
248     {
249     irc_timer();
250     scan_timer();
251     command_timer();
252 michael 5052
253 michael 5217 ALARMED = 0;
254     }
255     }
256 michael 5052
257 michael 5217 if (!OPT_DEBUG)
258     log_close();
259 michael 5052
260 michael 5217 /* If there's no scanlog open then this will do nothing anyway */
261     scanlog_close();
262     return 0;
263 michael 5052 }
264    
265 michael 5217 void
266     main_restart(void)
267 michael 5052 {
268 michael 5217 RESTART = 1;
269 michael 5052 }

Properties

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