]>
git.ipfire.org Git - thirdparty/bird.git/blob - sysdep/unix/main.c
2 * BIRD Internet Routing Daemon -- Unix Entry Point
4 * (c) 1998--2000 Martin Mares <mj@ucw.cz>
6 * Can be freely distributed and used under the terms of the GNU GPL.
22 #include "nest/bird.h"
23 #include "lib/lists.h"
24 #include "lib/resource.h"
25 #include "lib/socket.h"
26 #include "lib/event.h"
27 #include "lib/string.h"
28 #include "nest/route.h"
29 #include "nest/protocol.h"
30 #include "nest/iface.h"
32 #include "nest/locks.h"
33 #include "conf/conf.h"
34 #include "filter/filter.h"
44 static int debug_flag
= 1;
46 static int debug_flag
= 0;
52 debug("INTERNAL STATE DUMP\n\n");
70 #ifdef CONFIG_RESTRICTED_PRIVILEGES
71 #include "lib/syspriv.h"
77 die("Cannot change user on this platform");
90 * Reading the Configuration
93 #ifdef PATH_IPROUTE_DIR
96 add_num_const(char *name
, int val
)
98 struct symbol
*s
= cf_find_symbol(name
);
99 s
->class = SYM_NUMBER
;
104 /* the code of read_iproute_table() is based on
105 rtnl_tab_initialize() from iproute2 package */
107 read_iproute_table(char *file
, char *prefix
, int max
)
109 char buf
[512], namebuf
[512];
114 strcpy(namebuf
, prefix
);
115 name
= namebuf
+ strlen(prefix
);
117 fp
= fopen(file
, "r");
121 while (fgets(buf
, sizeof(buf
), fp
))
125 while (*p
== ' ' || *p
== '\t')
128 if (*p
== '#' || *p
== '\n' || *p
== 0)
131 if (sscanf(p
, "0x%x %s\n", &val
, name
) != 2 &&
132 sscanf(p
, "0x%x %s #", &val
, name
) != 2 &&
133 sscanf(p
, "%d %s\n", &val
, name
) != 2 &&
134 sscanf(p
, "%d %s #", &val
, name
) != 2)
137 if (val
< 0 || val
> max
)
140 for(p
= name
; *p
; p
++)
141 if ((*p
< 'a' || *p
> 'z') && (*p
< '0' || *p
> '9') && (*p
!= '_'))
144 add_num_const(namebuf
, val
);
150 #endif // PATH_IPROUTE_DIR
154 static char *config_name
= PATH_CONFIG
;
157 cf_read(byte
*dest
, unsigned int len
)
159 int l
= read(conf_fd
, dest
, len
);
161 cf_error("Read error");
166 sysdep_preconfig(struct config
*c
)
168 init_list(&c
->logfiles
);
170 #ifdef PATH_IPROUTE_DIR
171 // read_iproute_table(PATH_IPROUTE_DIR "/rt_protos", "ipp_", 256);
172 read_iproute_table(PATH_IPROUTE_DIR
"/rt_realms", "ipr_", 256);
173 read_iproute_table(PATH_IPROUTE_DIR
"/rt_scopes", "ips_", 256);
174 read_iproute_table(PATH_IPROUTE_DIR
"/rt_tables", "ipt_", 256);
179 sysdep_commit(struct config
*new, struct config
*old UNUSED
)
181 log_switch(debug_flag
, &new->logfiles
, new->syslog_name
);
186 unix_read_config(struct config
**cp
, char *name
)
188 struct config
*conf
= config_alloc(name
);
192 conf_fd
= open(name
, O_RDONLY
);
195 cf_read_hook
= cf_read
;
196 ret
= config_parse(conf
);
206 if (!unix_read_config(&conf
, config_name
))
209 die("%s, line %d: %s", config_name
, conf
->err_lino
, conf
->err_msg
);
211 die("Unable to open configuration file %s: %m", config_name
);
213 config_commit(conf
, RECONFIG_HARD
);
221 log(L_INFO
"Reconfiguration requested by SIGHUP");
222 if (!unix_read_config(&conf
, config_name
))
225 log(L_ERR
"%s, line %d: %s", config_name
, conf
->err_lino
, conf
->err_msg
);
227 log(L_ERR
"Unable to open configuration file %s: %m", config_name
);
231 config_commit(conf
, RECONFIG_HARD
);
235 cmd_reconfig(char *name
, int type
)
239 if (cli_access_restricted())
244 cli_msg(-2, "Reading configuration from %s", name
);
245 if (!unix_read_config(&conf
, name
))
248 cli_msg(8002, "%s, line %d: %s", name
, conf
->err_lino
, conf
->err_msg
);
250 cli_msg(8002, "%s: %m", name
);
255 switch (config_commit(conf
, type
))
258 cli_msg(3, "Reconfigured.");
261 cli_msg(4, "Reconfiguration in progress.");
264 cli_msg(6, "Reconfiguration ignored, shutting down.");
267 cli_msg(5, "Reconfiguration already in progress, queueing new config");
273 * Command-Line Interface
277 static char *path_control_socket
= PATH_CONTROL_SOCKET
;
287 struct cli_out
*o
= c
->tx_pos
;
289 int len
= o
->wpos
- o
->outpos
;
293 if (sk_send(s
, len
) <= 0)
299 /* Everything is written */
305 cli_write_trigger(cli
*c
)
320 cli_get_command(cli
*c
)
323 byte
*t
= c
->rx_aux
? : s
->rbuf
;
324 byte
*tend
= s
->rpos
;
326 byte
*dend
= c
->rx_buf
+ CLI_RX_BUF_SIZE
- 2;
335 c
->rx_pos
= c
->rx_buf
;
338 return (d
< dend
) ? 1 : -1;
343 c
->rx_aux
= s
->rpos
= s
->rbuf
;
349 cli_rx(sock
*s
, int size UNUSED
)
356 cli_err(sock
*s
, int err
)
358 if (config
->cli_debug
)
361 log(L_INFO
"CLI connection dropped: %s", strerror(err
));
363 log(L_INFO
"CLI connection closed");
369 cli_connect(sock
*s
, int size UNUSED
)
373 if (config
->cli_debug
)
374 log(L_INFO
"CLI connect");
377 s
->err_hook
= cli_err
;
378 s
->data
= c
= cli_new(s
);
379 s
->pool
= c
->pool
; /* We need to have all the socket buffers allocated in the cli pool */
380 c
->rx_pos
= c
->rx_buf
;
387 cli_init_unix(uid_t use_uid
, gid_t use_gid
)
392 s
= cli_sk
= sk_new(cli_pool
);
393 s
->type
= SK_UNIX_PASSIVE
;
394 s
->rx_hook
= cli_connect
;
396 sk_open_unix(s
, path_control_socket
);
398 if (use_uid
|| use_gid
)
399 if (chown(path_control_socket
, use_uid
, use_gid
) < 0)
402 if (chmod(path_control_socket
, 0660) < 0)
413 if (cli_access_restricted())
416 cli_msg(7, "Shutdown requested");
423 DBG("Shutting down...\n");
428 sysdep_shutdown_done(void)
430 unlink(path_control_socket
);
431 log_msg(L_FATAL
"Shutdown completed");
440 handle_sighup(int sig UNUSED
)
442 DBG("Caught SIGHUP...\n");
443 async_config_flag
= 1;
447 handle_sigusr(int sig UNUSED
)
449 DBG("Caught SIGUSR...\n");
454 handle_sigterm(int sig UNUSED
)
456 DBG("Caught SIGTERM...\n");
457 async_shutdown_flag
= 1;
465 bzero(&sa
, sizeof(sa
));
466 sa
.sa_handler
= handle_sigusr
;
467 sa
.sa_flags
= SA_RESTART
;
468 sigaction(SIGUSR1
, &sa
, NULL
);
469 sa
.sa_handler
= handle_sighup
;
470 sa
.sa_flags
= SA_RESTART
;
471 sigaction(SIGHUP
, &sa
, NULL
);
472 sa
.sa_handler
= handle_sigterm
;
473 sa
.sa_flags
= SA_RESTART
;
474 sigaction(SIGTERM
, &sa
, NULL
);
475 signal(SIGPIPE
, SIG_IGN
);
479 * Parsing of command-line arguments
482 static char *opt_list
= "c:dD:ps:u:g:";
483 static int parse_and_exit
;
485 static char *use_user
;
486 static char *use_group
;
491 fprintf(stderr
, "Usage: %s [-c <config-file>] [-d] [-D <debug-file>] [-p] [-s <control-socket>] [-u <user>] [-g <group>]\n", bird_name
);
496 get_bird_name(char *s
, char *def
)
510 get_uid(const char *s
)
520 rv
= strtol(s
, &endptr
, 10);
522 if (!errno
&& !*endptr
)
527 die("Cannot find user '%s'", s
);
533 get_gid(const char *s
)
543 rv
= strtol(s
, &endptr
, 10);
545 if (!errno
&& !*endptr
)
550 die("Cannot find group '%s'", s
);
556 parse_args(int argc
, char **argv
)
560 bird_name
= get_bird_name(argv
[0], "bird");
563 if (!strcmp(argv
[1], "--version"))
565 fprintf(stderr
, "BIRD version " BIRD_VERSION
"\n");
568 if (!strcmp(argv
[1], "--help"))
571 while ((c
= getopt(argc
, argv
, opt_list
)) >= 0)
575 config_name
= optarg
;
581 log_init_debug(optarg
);
588 path_control_socket
= optarg
;
608 main(int argc
, char **argv
)
610 #ifdef HAVE_LIBDMALLOC
611 if (!getenv("DMALLOC_OPTIONS"))
612 dmalloc_debug(0x2f03d00);
615 parse_args(argc
, argv
);
618 log_switch(debug_flag
, NULL
, NULL
);
626 uid_t use_uid
= get_uid(use_user
);
627 gid_t use_gid
= get_gid(use_group
);
631 test_old_bird(path_control_socket
);
632 cli_init_unix(use_uid
, use_gid
);
642 proto_build(&proto_unix_kernel
);
643 proto_build(&proto_unix_iface
);
659 if (open("/dev/null", O_RDWR
) < 0)
660 die("Cannot open /dev/null: %m");
671 log(L_INFO
"Started");
672 DBG("Entering I/O loop.\n");
675 bug("I/O loop died");