diff options
-rw-r--r-- | conf/conf.h | 2 | ||||
-rw-r--r-- | nest/cli.h | 14 | ||||
-rw-r--r-- | sysdep/unix/config.Y | 3 | ||||
-rw-r--r-- | sysdep/unix/io.c | 2 | ||||
-rw-r--r-- | sysdep/unix/main.c | 67 | ||||
-rw-r--r-- | sysdep/unix/unix.h | 2 |
6 files changed, 70 insertions, 20 deletions
diff --git a/conf/conf.h b/conf/conf.h index c0a897fc..dd296652 100644 --- a/conf/conf.h +++ b/conf/conf.h @@ -14,6 +14,7 @@ #include "lib/hash.h" #include "lib/resource.h" #include "lib/timer.h" +#include "lib/tlists.h" /* Configuration structure */ struct config { @@ -25,6 +26,7 @@ struct config { list logfiles; /* Configured log files (sysdep) */ list tests; /* Configured unit tests (f_bt_test_suite) */ list symbols; /* Configured symbols in config order */ + TLIST_STRUCT_DEF(cli_config, struct cli_config) cli; /* Configured CLI sockets */ int mrtdump_file; /* Configured MRTDump file (sysdep, fd in unix) */ const char *syslog_name; /* Name used for syslog (NULL -> no syslog) */ @@ -11,6 +11,8 @@ #include "lib/resource.h" #include "lib/event.h" +#include "lib/tlists.h" +#include "conf/conf.h" #define CLI_RX_BUF_SIZE 4096 #define CLI_TX_BUF_SIZE 4096 @@ -47,6 +49,18 @@ typedef struct cli { uint async_msg_size; /* Total size of async messages queued in tx_buf */ } cli; +struct cli_config { +#define TLIST_PREFIX cli_config +#define TLIST_TYPE struct cli_config +#define TLIST_ITEM n +#define TLIST_DEFINED_BEFORE +#define TLIST_WANT_ADD_TAIL + TLIST_DEFAULT_NODE; + const char *name; + uint uid, gid, mode; +}; +#include "lib/tlists.h" + extern pool *cli_pool; extern struct cli *this_cli; /* Used during parsing */ diff --git a/sysdep/unix/config.Y b/sysdep/unix/config.Y index 8de79600..24d1ae5d 100644 --- a/sysdep/unix/config.Y +++ b/sysdep/unix/config.Y @@ -17,7 +17,7 @@ static struct log_config *this_log; CF_DECLS -CF_KEYWORDS(LOG, SYSLOG, NAME, STDERR, UDP, PORT) +CF_KEYWORDS(LOG, SYSLOG, NAME, STDERR, UDP, PORT, CLI) CF_KEYWORDS(ALL, DEBUG, TRACE, INFO, REMOTE, WARNING, ERROR, AUTH, FATAL, BUG) CF_KEYWORDS(DEBUG, LATENCY, LIMIT, WATCHDOG, WARNING, TIMEOUT, THREADS) @@ -123,7 +123,6 @@ mrtdump_base: } ; - conf: debug_unix ; debug_unix: diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c index da2c5492..5a0dde8e 100644 --- a/sysdep/unix/io.c +++ b/sysdep/unix/io.c @@ -1531,7 +1531,7 @@ err: } int -sk_open_unix(sock *s, char *name) +sk_open_unix(sock *s, const char *name) { struct sockaddr_un sa; int fd; diff --git a/sysdep/unix/main.c b/sysdep/unix/main.c index 0d7788bb..c712aee4 100644 --- a/sysdep/unix/main.c +++ b/sysdep/unix/main.c @@ -395,9 +395,12 @@ cmd_reconfig_status(void) * Command-Line Interface */ -static sock *cli_sk; static char *path_control_socket = PATH_CONTROL_SOCKET; - +static struct cli_config *main_control_socket_config = NULL; +static struct cli_listener { + sock *s; + struct cli_config *config; +} *main_control_socket = NULL; static void cli_write(cli *c) @@ -519,33 +522,65 @@ cli_connect(sock *s, uint size UNUSED) return 1; } -static void -cli_init_unix(uid_t use_uid, gid_t use_gid) +static struct cli_listener * +cli_listener(struct cli_config *cf) { - sock *s; - - cli_init(); - s = cli_sk = sk_new(cli_pool); + struct cli_listener *l = mb_allocz(cli_pool, sizeof *l); + l->config = cf; + sock *s = l->s = sk_new(cli_pool); s->type = SK_UNIX_PASSIVE; s->rx_hook = cli_connect; s->err_hook = cli_connect_err; + s->data = cf; s->rbsize = 1024; s->fast_rx = 1; /* Return value intentionally ignored */ - unlink(path_control_socket); + unlink(cf->name); + + if (sk_open_unix(s, cf->name) < 0) + { + log(L_ERR "Cannot create control socket %s: %m", cf->name); + return NULL; + } + + if (cf->uid || cf->gid) + if (chown(cf->name, cf->uid, cf->gid) < 0) + { + log(L_ERR "Cannot chown control socket %s: %m", cf->name); + return NULL; + } - if (sk_open_unix(s, path_control_socket) < 0) - die("Cannot create control socket %s: %m", path_control_socket); + if (chmod(cf->name, cf->mode) < 0) + { + log(L_ERR "Cannot chmod control socket %s: %m", cf->name); + return NULL; + } - if (use_uid || use_gid) - if (chown(path_control_socket, use_uid, use_gid) < 0) - die("chown: %m"); + return l; +} - if (chmod(path_control_socket, 0660) < 0) - die("chmod: %m"); +static void +cli_init_unix(uid_t use_uid, gid_t use_gid) +{ + ASSERT_DIE(main_control_socket_config == NULL); + + main_control_socket_config = mb_alloc(&root_pool, sizeof *main_control_socket_config); + *main_control_socket_config = (struct cli_config) { + .name = path_control_socket, + .uid = use_uid, + .gid = use_gid, + .mode = 0660, + }; + + ASSERT_DIE(main_control_socket == NULL); + cli_init(); + main_control_socket = cli_listener(main_control_socket_config); + if (!main_control_socket) + die("Won't run without control socket"); } + /* * PID file */ diff --git a/sysdep/unix/unix.h b/sysdep/unix/unix.h index c1d966f9..7c15e30d 100644 --- a/sysdep/unix/unix.h +++ b/sysdep/unix/unix.h @@ -107,7 +107,7 @@ extern volatile sig_atomic_t async_shutdown_flag; void io_init(void); void io_loop(void); void io_log_dump(void); -int sk_open_unix(struct birdsock *s, char *name); +int sk_open_unix(struct birdsock *s, const char *name); struct rfile *rf_open(struct pool *, const char *name, const char *mode); struct rfile *rf_fdopen(pool *p, int fd, const char *mode); void *rf_file(struct rfile *f); |