root/fwknop/tags/fwknop-0.9.7/knopwatchd.c

Revision 436, 20.5 kB (checked in by mbr, 3 years ago)

updated to new fwknopd server path, replaced multiple strlcat() calls with single snprintf()

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*
2 *****************************************************************************
3 *
4 *  File: knopwatchd.c
5 *
6 *  Purpose: knopwatchd checks on an interval of every five seconds to make
7 *           sure that both knopmd and fwknop are running on the box.  If
8 *           either daemon has died, knopwatchd will restart it and notify
9 *           each email address in EMAIL_ADDRESSES that the daemon has been
10 *           restarted.
11 *
12 *  Author: Michael Rash (mbr@cipherdyne.org)
13 *
14 *  Credits:  (see the CREDITS file)
15 *
16 *  Version: 0.9.5
17 *
18 *  Copyright (C) 1999-2001 Michael Rash (mbr@cipherdyne.org)
19 *
20 *  License (GNU Public License):
21 *
22 *     This program is distributed in the hope that it will be useful,
23 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
24 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25 *     GNU General Public License for more details.
26 *
27 *     You should have received a copy of the GNU General Public License
28 *     along with this program; if not, write to the Free Software
29 *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
30 *     USA
31 *
32 *****************************************************************************
33 *
34 *  $Id$
35 */
36
37 /* includes */
38 #include "fwknop.h"
39
40 /* defines */
41 #define KNOPWATCHD_CONF "/etc/fwknop/knopwatchd.conf"
42 #define ALERT_CONF "/etc/fwknop/alert.conf"
43 #define FWKNOP_CONF "/etc/fwknop/fwknop.conf"
44
45 /* globals */
46 unsigned short int fwknopd_syscalls_ctr = 0;
47 unsigned short int knopmd_syscalls_ctr = 0;
48 unsigned short int no_email = 0;
49 unsigned short int check_knopmd = 1;
50 unsigned short int check_knoptm = 0;  /* PCAP-based rule timeouts */
51 const char mail_redr[] = " < /dev/null > /dev/null 2>&1";
52 char hostname[MAX_GEN_LEN];
53 char mail_addrs[MAX_GEN_LEN];
54 char shCmd[MAX_GEN_LEN];
55 char mailCmd[MAX_GEN_LEN];
56 static volatile sig_atomic_t received_sighup = 0;
57
58 /* prototypes */
59 static void parse_config(
60     char *config_file,
61     char *hostname,
62     char *fwknopd_binary,
63     char *fwknopd_pid_file,
64     char *fwknopd_cmdline_file,
65     char *knopmd_binary,
66     char *knoptm_binary,
67     char *knopmd_pid_file,
68     char *knoptm_pid_file,
69     char *shCmd,
70     char *mailCmd,
71     char *mail_addrs,
72     char *knopwatchd_pid_file,
73     unsigned int *knopwatchd_check_interval,
74     unsigned int *knopwatchd_max_retries
75 );
76 static void parse_alert_config(
77     char *alert_config_file,
78     char *alerting_methods
79 );
80 static void check_process(
81     const char *pid_name,
82     const char *pid_file,
83     const char *cmdline_file,
84     const char *binary_path,
85     unsigned int max_retries
86 );
87 static void check_auth_mode(void);
88 static void incr_syscall_ctr(const char *pid_name, unsigned int max_retries);
89 static void reset_syscall_ctr(const char *pid_name);
90 static void give_up(const char *pid_name);
91 static void exec_binary(const char *binary_path, const char *cmdline_file);
92 static void sighup_handler(int sig);
93
94 /* main */
95 int main(int argc, char *argv[]) {
96     char config_file[MAX_PATH_LEN] = "";
97     char alert_config_file[MAX_PATH_LEN] = "";
98     char alerting_methods[MAX_GEN_LEN] = "";
99     char fwknopdCmd[MAX_PATH_LEN] = "";
100     char fwknopd_pid_file[MAX_PATH_LEN] = "";
101     char fwknopd_cmdline_file[MAX_PATH_LEN] = "";
102     char knopmdCmd[MAX_PATH_LEN] = "";
103     char knoptmCmd[MAX_PATH_LEN] = "";
104     char knopmd_pid_file[MAX_PATH_LEN] = "";
105     char knoptm_pid_file[MAX_PATH_LEN] = "";
106     char knopwatchd_pid_file[MAX_PATH_LEN] = "";
107     unsigned int knopwatchd_check_interval = 5;  /* default to 5 seconds */
108     unsigned int knopwatchd_max_retries = 10; /* default to 10 tries */
109     int cmdlopt;
110
111 #ifdef DEBUG
112     fprintf(stderr, "[+] Entering DEBUG mode...\n");
113     sleep(1);
114 #endif
115
116     strlcpy(config_file, KNOPWATCHD_CONF, MAX_PATH_LEN);
117     strlcpy(alert_config_file, ALERT_CONF, MAX_PATH_LEN);
118
119     /* handle command line arguments */
120     while((cmdlopt = getopt(argc, argv, "c:k:")) != -1) {
121         switch(cmdlopt) {
122             case 'c':
123                 strlcpy(config_file, optarg, MAX_PATH_LEN);
124                 break;
125             case 'a':
126                 strlcpy(alert_config_file, optarg, MAX_PATH_LEN);
127                 break;
128             default:
129                 printf("[+] Usage: knopwatchd [-c <config file>] ");
130                 printf("[-a <alert config file>]\n");
131                 exit(EXIT_FAILURE);
132         }
133     }
134
135 #ifdef DEBUG
136     fprintf(stderr, "[+] parsing config_file: %s\n", config_file);
137 #endif
138
139     /* parse the config file */
140     parse_config(
141         config_file,
142         hostname,
143         fwknopdCmd,
144         fwknopd_pid_file,
145         fwknopd_cmdline_file,
146         knopmdCmd,
147         knoptmCmd,
148         knopmd_pid_file,
149         knoptm_pid_file,
150         shCmd,
151         mailCmd,
152         mail_addrs,
153         knopwatchd_pid_file,
154         &knopwatchd_check_interval,
155         &knopwatchd_max_retries
156     );
157
158     parse_alert_config(alert_config_file, alerting_methods);
159
160     /* see if we are suppose to disable all email alerts */
161     if (strncmp("noemail", alerting_methods, MAX_GEN_LEN) == 0) {
162         no_email = 1;
163     }
164
165     /* first make sure there isn't another knopwatchd already running */
166     check_unique_pid(knopwatchd_pid_file, "knopwatchd");
167
168 #ifndef DEBUG
169     /* become a daemon */
170     daemonize_process(knopwatchd_pid_file);
171 #endif
172
173     /* install signal handler for HUP signals */
174     signal(SIGHUP, sighup_handler);
175
176     /* start doing the real work now that the daemon is running and
177      * the config file has been processed */
178
179     /* MAIN LOOP */
180     for (;;) {
181         /* restart processes as necessary */
182         check_process("fwknopd", fwknopd_pid_file, fwknopd_cmdline_file,
183             fwknopdCmd, knopwatchd_max_retries);
184
185         if (check_knopmd)
186             check_process("knopmd", knopmd_pid_file, NULL,
187                 knopmdCmd, knopwatchd_max_retries);
188
189         if (check_knoptm)
190             check_process("knoptm", knoptm_pid_file, NULL,
191                 knoptmCmd, knopwatchd_max_retries);
192
193         /* sleep and then check to see if we received any signals */
194         sleep(knopwatchd_check_interval);
195
196         /* check for sighup */
197         if (received_sighup) {
198             received_sighup = 0;
199 #ifdef DEBUG
200     fprintf(stderr, "[+] re-parsing config file: %s\n", config_file);
201 #endif
202             /* reparse the config file since we received a
203              * HUP signal */
204             parse_config(
205                 config_file,
206                 hostname,
207                 fwknopdCmd,
208                 fwknopd_pid_file,
209                 fwknopd_cmdline_file,
210                 knopmdCmd,
211                 knoptmCmd,
212                 knopmd_pid_file,
213                 knoptm_pid_file,
214                 shCmd,
215                 mailCmd,
216                 mail_addrs,
217                 knopwatchd_pid_file,
218                 &knopwatchd_check_interval,
219                 &knopwatchd_max_retries
220             );
221             slogr("fwknopd(knopwatchd)",
222                     "received HUP signal, re-imported knopwatchd.conf");
223         }
224     }
225
226     /* this statement doesn't get executed, but for completeness... */
227     exit(EXIT_SUCCESS);
228 }
229 /******************** end main ********************/
230
231 static void check_process(
232     const char *pid_name,
233     const char *pid_file,
234     const char *cmdline_file,
235     const char *binary_path,
236     unsigned int max_retries)
237 {
238     FILE *pidfile_ptr;
239     pid_t pid;
240     unsigned short int restart = 0;
241     char mail_str[MAX_MSG_LEN] = "";
242     char pid_line[MAX_PID_SIZE];
243
244     if ((pidfile_ptr = fopen(pid_file, "r")) == NULL) {
245 #ifdef DEBUG
246     fprintf(stderr, "[+] Could not open pid_file: %s\n", pid_file);
247 #endif
248         /* the pid file must not exist (or we can't read it), so
249          * setup to start the appropriate process */
250         restart = 1;
251     }
252
253     /* read the first line of the pid_file, which will contain the
254      * process id of any running pid_name process. */
255     if (! restart) {
256         if (fgets(pid_line, MAX_PID_SIZE, pidfile_ptr) == NULL) {
257 #ifdef DEBUG
258             fprintf(stderr, "[+] Could not read the pid_file: %s\n", pid_file);
259 #endif
260             /* see if we need to give up */
261             incr_syscall_ctr(pid_name, max_retries);
262             fclose(pidfile_ptr);
263             return;
264         }
265
266         /* convert the pid_line into an integer */
267         pid = atoi(pid_line);
268
269         /* close the pid_file now that we have read it */
270         fclose(pidfile_ptr);
271
272         if (kill(pid, 0) != 0) {
273             /* the process is not running so start it */
274             restart = 1;
275         }
276     }
277
278     if (restart) {
279 #ifdef DEBUG
280         fprintf(stderr, "[+] executing exec_binary(%s)\n", binary_path);
281 #endif
282         snprintf(mail_str, MAX_MSG_LEN,
283                 " -s \"[*] knopwatchd: Restarting %s on %s\" %s%s",
284                 pid_name, hostname, mail_addrs, mail_redr);
285         mail_str[MAX_MSG_LEN-1] = '\0';
286
287 #ifdef DEBUG
288         fprintf(stderr, "[+] sending mail: %s\n", mail_str);
289 #endif
290         if (! no_email) {
291             /* send the email */
292             send_alert_email(shCmd, mailCmd, mail_str);
293         }
294
295         /* execute the binary_path fwknopd daemon */
296         exec_binary(binary_path, cmdline_file);
297
298         /* increment the number of times we have tried to restart the binary */
299         incr_syscall_ctr(pid_name, max_retries);
300     } else {
301 #ifdef DEBUG
302         fprintf(stderr, "[+] %s is running.\n", pid_name);
303 #endif
304         /* reset the syscall counter since the process is successfully
305          * running. */
306         reset_syscall_ctr(pid_name);
307     }
308     return;
309 }
310
311 static void incr_syscall_ctr(const char *pid_name, unsigned int max_retries)
312 {
313     if (strcmp("fwknopd", pid_name) == 0) {
314         fwknopd_syscalls_ctr++;
315 #ifdef DEBUG
316         fprintf(stderr,
317             "[+] %s not running.  Trying to restart (%d tries so far).\n",
318             pid_name, fwknopd_syscalls_ctr);
319 #endif
320         if (fwknopd_syscalls_ctr >= max_retries)
321             give_up(pid_name);
322     } else if (strcmp("knopmd", pid_name) == 0) {
323         knopmd_syscalls_ctr++;
324 #ifdef DEBUG
325         fprintf(stderr,
326             "[+] %s not running.  Trying to restart (%d tries so far).\n",
327             pid_name, knopmd_syscalls_ctr);
328 #endif
329         if (knopmd_syscalls_ctr >= max_retries)
330             give_up(pid_name);
331     }
332     return;
333 }
334
335 static void reset_syscall_ctr(const char *pid_name)
336 {
337     if (strcmp("fwknopd", pid_name) == 0) {
338         fwknopd_syscalls_ctr = 0;
339     } else if (strcmp("knopmd", pid_name) == 0) {
340         knopmd_syscalls_ctr = 0;
341     }
342     return;
343 }
344
345 static void give_up(const char *pid_name)
346 {
347     char mail_str[MAX_MSG_LEN] = "";
348 #ifdef DEBUG
349     fprintf(stderr, "[*] Could not restart %s process.  Exiting.\n", pid_name);
350 #endif
351     snprintf(mail_str, MAX_MSG_LEN,
352             " -s \"[*] knopwatchd: Could not restart %s on %s. Exiting.\" %s%s",
353             pid_name, hostname, mail_addrs, mail_redr);
354     mail_str[MAX_MSG_LEN-1] = '\0';
355
356     if (! no_email) {
357         /* Send the email */
358         send_alert_email(shCmd, mailCmd, mail_str);
359     }
360     exit(EXIT_FAILURE);
361 }
362
363 static void exec_binary(const char *binary, const char *cmdlinefile)
364 {
365     FILE *cmdline_ptr;
366     char *prog_argv[MAX_ARG_LEN];
367     char cmdline_buf[MAX_LINE_BUF];
368     char *index;
369     pid_t child_pid;
370     int arg_num=0, non_ws, i;
371
372     prog_argv[arg_num] = (char *) malloc(strlen(binary));
373     if (prog_argv[arg_num] == NULL) {
374         exit(EXIT_FAILURE);
375     }
376     strlcpy(prog_argv[arg_num], binary, MAX_ARG_LEN);
377     arg_num++;
378
379     if (cmdlinefile != NULL) {
380         /* restart binary with its command line arguments intact */
381         if ((cmdline_ptr = fopen(cmdlinefile, "r")) == NULL) {
382             exit(EXIT_FAILURE);
383         }
384         if ((fgets(cmdline_buf, MAX_LINE_BUF, cmdline_ptr)) == NULL) {
385             exit(EXIT_FAILURE);
386         }
387         fclose(cmdline_ptr);
388
389         /* initialize index to the beginning of the line */
390         index = cmdline_buf;
391
392         /* advance the index pointer through any whitespace
393          * at the beginning of the line */
394         while (*index == ' ' || *index == '\t') index++;
395
396         while (*index != '\n' && *index != '\0') {
397             non_ws = 0;
398             while (*index != ' ' && *index != '\t'
399                     && index != '\0' && *index != '\n') {
400                 index++;
401                 non_ws++;
402             }
403             prog_argv[arg_num] = (char *) malloc(non_ws+1);
404             if (prog_argv[arg_num] == NULL) {
405                 exit(EXIT_FAILURE);
406             }
407             for (i=0; i<non_ws; i++)
408                 prog_argv[arg_num][i] = *(index - (non_ws - i));
409             prog_argv[arg_num][i] = '\0';
410
411             arg_num++;
412
413             /* get past any whitespace */
414             while (*index == ' ' || *index == '\t') index++;
415         }
416     }
417     /* is it necessary to malloc for the ending NULL? */
418     prog_argv[arg_num] = (char *) malloc(1);
419     if (prog_argv[arg_num] == NULL) {
420         exit(EXIT_FAILURE);
421     }
422     prog_argv[arg_num] = NULL;
423
424     if ((child_pid = fork()) < 0)
425         /* could not fork */
426         exit(EXIT_FAILURE);
427     else if (child_pid > 0) {
428         wait(NULL);
429         for (i=0; i<=arg_num; i++) {
430             free(prog_argv[i]);
431         }
432     } else {
433 #ifdef DEBUG
434         fprintf(stderr, "[+] restarting %s\n", binary);
435 #endif
436         execve(binary, prog_argv, NULL);  /* don't use environment */
437     }
438     return;
439 }
440
441 static void parse_config(
442     char *config_file,
443     char *hostname,
444     char *fwknopdCmd,
445     char *fwknopd_pid_file,
446     char *fwknopd_cmdline_file,
447     char *knopmdCmd,
448     char *knoptmCmd,
449     char *knopmd_pid_file,
450     char *knoptm_pid_file,
451     char *shCmd,
452     char *mailCmd,
453     char *mail_addrs,
454     char *knopwatchd_pid_file,
455     unsigned int *knopwatchd_check_interval,
456     unsigned int *knopwatchd_max_retries)
457 {
458     FILE *config_ptr;         /* FILE pointer to the config file */
459     int linectr = 0;
460     char config_buf[MAX_LINE_BUF];
461     char char_knopwatchd_check_interval[MAX_NUM_LEN];
462     char char_knopwatchd_max_retries[MAX_NUM_LEN];
463     char *index;
464
465     /* first check to see if knopmd and knoptm should not be running (i.e.
466      * AUTH_MODE in the fwknop.conf file is set to a pcap-based method).
467      * This will set check_knopmd and check_knoptm appropriately */
468     check_auth_mode();
469
470     if ((config_ptr = fopen(config_file, "r")) == NULL) {
471         perror("[*] Could not open config file");
472         exit(EXIT_FAILURE);
473     }
474
475     /* increment through each line of the config file */
476     while ((fgets(config_buf, MAX_LINE_BUF, config_ptr)) != NULL) {
477         linectr++;
478         index = config_buf;  /* set the index pointer to the
479                                 beginning of the line */
480
481         /* advance the index pointer through any whitespace
482          * at the beginning of the line */
483         while (*index == ' ' || *index == '\t') index++;
484
485         /* skip comments and blank lines, etc. */
486         if ((*index != '#') && (*index != '\n') &&
487                 (*index != ';') && (index != NULL)) {
488
489             find_char_var("fwknopdCmd ", fwknopdCmd, index);
490             find_char_var("HOSTNAME ", hostname, index);
491             find_char_var("FWKNOPD_PID_FILE ", fwknopd_pid_file, index);
492             find_char_var("FWKNOPD_CMDLINE_FILE ", fwknopd_cmdline_file, index);
493             find_char_var("knopmdCmd ", knopmdCmd, index);
494             find_char_var("knoptmCmd ", knoptmCmd, index);
495             find_char_var("KNOPMD_PID_FILE ", knopmd_pid_file, index);
496             find_char_var("KNOPTM_PID_FILE ", knoptm_pid_file, index);
497             find_char_var("shCmd ", shCmd, index);
498             find_char_var("mailCmd ", mailCmd, index);
499             find_char_var("EMAIL_ADDRESSES ", mail_addrs, index);
500             find_char_var("CHECK_INTERVAL ",
501                 char_knopwatchd_check_interval, index);
502             find_char_var("MAX_RETRIES ",
503                 char_knopwatchd_max_retries, index);
504             find_char_var("KNOPWATCHD_PID_FILE ", knopwatchd_pid_file, index);
505         }
506     }
507     fclose(config_ptr);
508
509     if (fwknopdCmd[0] == '\0') {
510         fprintf(stderr, "[*] Could not get fwknopdCmd from %s\n",
511                 config_file);
512         exit(EXIT_FAILURE);
513     }
514     if (hostname[0] == '\0') {
515         fprintf(stderr, "[*] Could not get HOSTNAME from %s\n",
516                 config_file);
517         exit(EXIT_FAILURE);
518     }
519     if (fwknopd_pid_file[0] == '\0') {
520         fprintf(stderr, "[*] Could not get FWKNOPD_PID_FILE from %s\n",
521                 config_file);
522         exit(EXIT_FAILURE);
523     }
524     if (fwknopd_cmdline_file[0] == '\0') {
525         fprintf(stderr, "[*] Could not get FWKNOPD_CMDLINE_FILE from %s\n",
526                 config_file);
527         exit(EXIT_FAILURE);
528     }
529     if (knopmdCmd[0] == '\0') {
530         fprintf(stderr, "[*] Could not get knopmdCmd from %s\n",
531                 config_file);
532         exit(EXIT_FAILURE);
533     }
534     if (knoptmCmd[0] == '\0') {
535         fprintf(stderr, "[*] Could not get knoptmCmd from %s\n",
536                 config_file);
537         exit(EXIT_FAILURE);
538     }
539     if (knopmd_pid_file[0] == '\0') {
540         fprintf(stderr, "[*] Could not get KNOPMD_PID_FILE from %s\n",
541                 config_file);
542         exit(EXIT_FAILURE);
543     }
544     if (knoptm_pid_file[0] == '\0') {
545         fprintf(stderr, "[*] Could not get KNOPTM_PID_FILE from %s\n",
546                 config_file);
547         exit(EXIT_FAILURE);
548     }
549     if (shCmd[0] == '\0') {
550         fprintf(stderr, "[*] Could not get shCmd from %s\n",
551                 config_file);
552         exit(EXIT_FAILURE);
553     }
554     if (mailCmd[0] == '\0') {
555         fprintf(stderr, "[*] Could not get mailCmd from %s\n",
556                 config_file);
557         exit(EXIT_FAILURE);
558     }
559     if (mail_addrs[0] == '\0') {
560         fprintf(stderr, "[*] Could not get EMAIL_ADDRESSES from %s\n",
561                 config_file);
562         exit(EXIT_FAILURE);
563     }
564     if (char_knopwatchd_check_interval[0] == '\0') {
565         fprintf(stderr, "[*] Could not get CHECK_INTERVAL from %s\n",
566                 config_file);
567         exit(EXIT_FAILURE);
568     }
569     if (char_knopwatchd_max_retries[0] == '\0') {
570         fprintf(stderr, "[*] Could not get MAX_RETRIES from %s\n",
571                 config_file);
572         exit(EXIT_FAILURE);
573     }
574     if (knopwatchd_pid_file[0] == '\0') {
575         fprintf(stderr, "[*] Could not get KNOPWATCHD_PID_FILE from %s\n",
576                 config_file);
577         exit(EXIT_FAILURE);
578     }
579
580     *knopwatchd_check_interval = atoi(char_knopwatchd_check_interval);
581     *knopwatchd_max_retries    = atoi(char_knopwatchd_max_retries);
582
583     return;
584 }
585
586 static void check_auth_mode(void)
587 {
588     FILE *config_ptr;   /* FILE pointer to the config file */
589     char config_buf[MAX_LINE_BUF];
590     char auth_mode[MAX_GEN_LEN];
591     char *index;
592
593     if ((config_ptr = fopen(FWKNOP_CONF, "r")) == NULL) {
594         fprintf(stderr, "[-] Could not open %s for reading.\n",
595             FWKNOP_CONF);
596         exit(EXIT_FAILURE);
597     }
598
599     auth_mode[0] = '\0';
600
601     /* increment through each line of the config file */
602     while ((fgets(config_buf, MAX_LINE_BUF, config_ptr)) != NULL) {
603         /* set the index pointer to the beginning of the line */
604         index = config_buf;
605
606         /* advance the index pointer through any whitespace
607          * at the beginning of the line */
608         while (*index == ' ' || *index == '\t') index++;
609
610         /* skip comments and blank lines, etc. */
611         if ((*index != '#') && (*index != '\n') &&
612                 (*index != ';') && (index != NULL)) {
613
614             find_char_var("AUTH_MODE ", auth_mode, index);
615         }
616     }
617     fclose(config_ptr);
618
619     /* see if we are using the ULOG_PCAP mode */
620     if (strncmp(auth_mode, "ULOG_PCAP", MAX_GEN_LEN) == 0)
621         check_knopmd = 0;
622
623     /* see if we are using the PCAP mode */
624     if (strncmp(auth_mode, "PCAP", MAX_GEN_LEN) == 0) {
625         check_knopmd = 0;
626         check_knoptm = 1;
627     }
628
629     return;
630 }
631
632 static void parse_alert_config(
633     char *alert_config_file,
634     char *alerting_methods)
635 {
636     FILE *config_ptr;         /* FILE pointer to the config file */
637     int linectr = 0;
638     char config_buf[MAX_LINE_BUF];
639     char *index;
640
641     if ((config_ptr = fopen(alert_config_file, "r")) == NULL) {
642         perror("[*] Could not open config file");
643         exit(EXIT_FAILURE);
644     }
645
646     /* increment through each line of the config file */
647     while ((fgets(config_buf, MAX_LINE_BUF, config_ptr)) != NULL) {
648         linectr++;
649         index = config_buf;  /* set the index pointer to the
650                                 beginning of the line */
651
652         /* advance the index pointer through any whitespace
653          * at the beginning of the line */
654         while (*index == ' ' || *index == '\t') index++;
655
656         /* skip comments and blank lines, etc. */
657         if ((*index != '#') && (*index != '\n') &&
658                 (*index != ';') && (index != NULL)) {
659
660             find_char_var("ALERTING_METHODS ", alerting_methods, index);
661         }
662     }
663     fclose(config_ptr);
664     return;
665 }
666
667 static void sighup_handler(int sig)
668 {
669     received_sighup = 1;
670 }
Note: See TracBrowser for help on using the browser.