1/* 2 * RIPngd main routine. 3 * Copyright (C) 1998, 1999 Kunihiro Ishiguro 4 * 5 * This file is part of GNU Zebra. 6 * 7 * GNU Zebra is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the 9 * Free Software Foundation; either version 2, or (at your option) any 10 * later version. 11 * 12 * GNU Zebra is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with GNU Zebra; see the file COPYING. If not, write to the Free 19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 20 * 02111-1307, USA. 21 */ 22 23#include <zebra.h> 24 25#include "version.h" 26#include "getopt.h" 27#include "vector.h" 28#include "vty.h" 29#include "command.h" 30#include "thread.h" 31#include "log.h" 32#include "prefix.h" 33#include "if.h" 34 35#include "ripngd/ripngd.h" 36 37/* Configuration filename and directory. */ 38char config_current[] = RIPNG_DEFAULT_CONFIG; 39char config_default[] = SYSCONFDIR RIPNG_DEFAULT_CONFIG; 40 41/* RIPngd options. */ 42struct option longopts[] = 43{ 44 { "daemon", no_argument, NULL, 'd'}, 45 { "config_file", required_argument, NULL, 'f'}, 46 { "pid_file", required_argument, NULL, 'i'}, 47 { "log_mode", no_argument, NULL, 'l'}, 48 { "help", no_argument, NULL, 'h'}, 49 { "vty_addr", required_argument, NULL, 'A'}, 50 { "vty_port", required_argument, NULL, 'P'}, 51 { "retain", no_argument, NULL, 'r'}, 52 { "version", no_argument, NULL, 'v'}, 53 { 0 } 54}; 55 56/* RIPngd program name */ 57 58/* Route retain mode flag. */ 59int retain_mode = 0; 60 61/* Master of threads. */ 62struct thread_master *master; 63 64/* Process ID saved for use by init system */ 65char *pid_file = PATH_RIPNGD_PID; 66 67/* Help information display. */ 68static void 69usage (char *progname, int status) 70{ 71 if (status != 0) 72 fprintf (stderr, "Try `%s --help' for more information.\n", progname); 73 else 74 { 75 printf ("Usage : %s [OPTION...]\n\ 76Daemon which manages RIPng.\n\n\ 77-d, --daemon Runs in daemon mode\n\ 78-f, --config_file Set configuration file name\n\ 79-i, --pid_file Set process identifier file name\n\ 80-l. --log_mode Set verbose log mode flag\n\ 81-A, --vty_addr Set vty's bind address\n\ 82-P, --vty_port Set vty's port number\n\ 83-r, --retain When program terminates, retain added route by ripngd.\n\ 84-v, --version Print program version\n\ 85-h, --help Display this help and exit\n\ 86\n\ 87Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS); 88 } 89 exit (status); 90} 91 92/* SIGHUP handler. */ 93void 94sighup (int sig) 95{ 96 zlog (NULL, LOG_INFO, "SIGHUP received"); 97} 98 99/* SIGINT handler. */ 100void 101sigint (int sig) 102{ 103 zlog (NULL, LOG_INFO, "Terminating on signal"); 104 105 if (! retain_mode) 106 ripng_terminate (); 107 108 exit (0); 109} 110 111/* SIGUSR1 handler. */ 112void 113sigusr1 (int sig) 114{ 115 zlog_rotate (NULL); 116} 117 118/* Signale wrapper. */ 119RETSIGTYPE * 120signal_set (int signo, void (*func)(int)) 121{ 122 int ret; 123 struct sigaction sig; 124 struct sigaction osig; 125 126 sig.sa_handler = func; 127 sigemptyset (&sig.sa_mask); 128 sig.sa_flags = 0; 129#ifdef SA_RESTART 130 sig.sa_flags |= SA_RESTART; 131#endif /* SA_RESTART */ 132 133 ret = sigaction (signo, &sig, &osig); 134 135 if (ret < 0) 136 return (SIG_ERR); 137 else 138 return (osig.sa_handler); 139} 140 141/* Initialization of signal handles. */ 142void 143signal_init () 144{ 145 signal_set (SIGHUP, sighup); 146 signal_set (SIGINT, sigint); 147 signal_set (SIGTERM, sigint); 148 signal_set (SIGPIPE, SIG_IGN); 149 signal_set (SIGUSR1, sigusr1); 150} 151 152/* RIPngd main routine. */ 153int 154main (int argc, char **argv) 155{ 156 char *p; 157 char *vty_addr = NULL; 158 int vty_port = 0; 159 int daemon_mode = 0; 160 char *config_file = NULL; 161 char *progname; 162 struct thread thread; 163 164 /* Set umask before anything for security */ 165 umask (0027); 166 167 /* get program name */ 168 progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]); 169 170 zlog_default = openzlog(progname, ZLOG_NOLOG, ZLOG_RIPNG, 171 LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON); 172 173 while (1) 174 { 175 int opt; 176 177 opt = getopt_long (argc, argv, "dlf:hA:P:v", longopts, 0); 178 179 if (opt == EOF) 180 break; 181 182 switch (opt) 183 { 184 case 0: 185 break; 186 case 'd': 187 daemon_mode = 1; 188 break; 189 case 'l': 190 /* log_mode = 1; */ 191 break; 192 case 'f': 193 config_file = optarg; 194 break; 195 case 'A': 196 vty_addr = optarg; 197 break; 198 case 'i': 199 pid_file = optarg; 200 break; 201 case 'P': 202 vty_port = atoi (optarg); 203 break; 204 case 'r': 205 retain_mode = 1; 206 break; 207 case 'v': 208 print_version (progname); 209 exit (0); 210 break; 211 case 'h': 212 usage (progname, 0); 213 break; 214 default: 215 usage (progname, 1); 216 break; 217 } 218 } 219 220 master = thread_master_create (); 221 222 /* Library inits. */ 223 signal_init (); 224 cmd_init (1); 225 vty_init (); 226 227 /* RIPngd inits. */ 228 ripng_init (); 229 zebra_init (); 230 sort_node (); 231 232 /* Get configuration file. */ 233 vty_read_config (config_file, config_current, config_default); 234 235 /* Change to the daemon program. */ 236 if (daemon_mode) 237 daemon (0, 0); 238 239 /* Create VTY socket */ 240 vty_serv_sock (vty_addr, 241 vty_port ? vty_port : RIPNG_VTY_PORT, RIPNG_VTYSH_PATH); 242 243 /* Process id file create. */ 244 pid_output (pid_file); 245 246 /* Fetch next active thread. */ 247 while (thread_fetch (master, &thread)) 248 thread_call (&thread); 249 250 /* Not reached. */ 251 exit (0); 252} 253