From: Sebastian Harl Date: Sun, 15 Dec 2013 15:36:41 +0000 (+0100) Subject: Moved sysdb and sysdbd sources to src/tools/. X-Git-Tag: sysdb-0.1.0~300^2~2 X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=commitdiff_plain;h=52f0df58b96af940cf6f527b4dd052a051f299bd Moved sysdb and sysdbd sources to src/tools/. Also, moved all purely private headers to that directory as well. Renamed some files for greater consistency. --- diff --git a/src/Makefile.am b/src/Makefile.am index 3b1de0a..3f5a007 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -83,20 +83,20 @@ bin_PROGRAMS = sysdbd if BUILD_CLIENT bin_PROGRAMS += sysdb -sysdb_SOURCES = client/sysdb.c include/client/sysdb.h +sysdb_SOURCES = tools/sysdb/main.c include/client/sysdb.h sysdb_CFLAGS = -DBUILD_DATE="\"$$( date --utc '+%F %T' ) (UTC)\"" \ $(AM_CFLAGS) @READLINE_CFLAGS@ sysdb_LDADD = libsysdbclient.la @READLINE_LIBS@ endif -sysdbd_SOURCES = daemon/sysdbd.c include/sysdb.h \ - daemon/config.c include/daemon/config.h +sysdbd_SOURCES = tools/sysdbd/main.c include/sysdb.h \ + tools/sysdbd/configfile.c tools/sysdbd/configfile.h sysdbd_CFLAGS = $(AM_CFLAGS) -DBUILD_DATE="\"$$( date --utc '+%F %T' ) (UTC)\"" sysdbd_LDADD = libsysdb.la liboconfig/liboconfig.la sysdbd_DEPENDENCIES = liboconfig/liboconfig.la sdbconfdir = $(sysconfdir)/sysdb -dist_sdbconf_DATA = daemon/sysdbd.conf.sample +dist_sdbconf_DATA = tools/sysdbd/sysdbd.conf.sample pkgbackendlibdir = $(pkglibdir)/backend pkgbackendcollectdlibdir = $(pkgbackendlibdir)/collectd diff --git a/src/client/sysdb.c b/src/client/sysdb.c deleted file mode 100644 index ecadb4c..0000000 --- a/src/client/sysdb.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * SysDB - src/client/sysdb.c - * Copyright (C) 2013 Sebastian 'tokkee' Harl - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if HAVE_CONFIG_H -# include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include "client/sysdb.h" -#include "client/sock.h" -#include "utils/error.h" -#include "utils/strbuf.h" - -#include - -#if HAVE_LIBGEN_H -# include -#else /* HAVE_LIBGEN_H */ -# define basename(path) (path) -#endif /* ! HAVE_LIBGEN_H */ - -#include -#include - -#include -#include -#include - -#include - -#include - -#include - -#if HAVE_EDITLINE_READLINE_H -# include -# if HAVE_EDITLINE_HISTORY_H -# include -# endif -#elif HAVE_READLINE_READLINE_H -# include -# if HAVE_READLINE_HISTORY_H -# include -# endif -#elif HAVE_READLINE_H -# include -# if HAVE_HISTORY_H -# include -# endif -#endif /* READLINEs */ - -#ifndef DEFAULT_SOCKET -# define DEFAULT_SOCKET "unix:"LOCALSTATEDIR"/run/sysdbd.sock" -#endif - -static void -exit_usage(char *name, int status) -{ - printf( -"Usage: %s \n" - -"\nOptions:\n" -" -h display this help and exit\n" -" -V display the version number and copyright\n" - -"\nSysDB client "SDB_CLIENT_VERSION_STRING SDB_CLIENT_VERSION_EXTRA", " -PACKAGE_URL"\n", basename(name)); - exit(status); -} /* exit_usage */ - -static void -exit_version(void) -{ - printf("SysDB version "SDB_CLIENT_VERSION_STRING - SDB_CLIENT_VERSION_EXTRA", built "BUILD_DATE"\n" - "using libsysdbclient version %s%s\n" - "Copyright (C) 2012-2013 "PACKAGE_MAINTAINER"\n" - - "\nThis is free software under the terms of the BSD license, see " - "the source for\ncopying conditions. There is NO WARRANTY; not " - "even for MERCHANTABILITY or\nFITNESS FOR A PARTICULAR " - "PURPOSE.\n", sdb_client_version_string(), - sdb_client_version_extra()); - exit(0); -} /* exit_version */ - -static const char * -get_current_user(void) -{ - struct passwd pw_entry; - struct passwd *result = NULL; - - uid_t uid; - - /* needs to be static because we return a pointer into this buffer - * to the caller */ - static char buf[1024]; - - int status; - - uid = geteuid(); - - memset(&pw_entry, 0, sizeof(pw_entry)); - status = getpwuid_r(uid, &pw_entry, buf, sizeof(buf), &result); - - if (status || (! result)) { - char errbuf[1024]; - sdb_log(SDB_LOG_ERR, "Failed to determine current username: %s", - sdb_strerror(errno, errbuf, sizeof(errbuf))); - return NULL; - } - return result->pw_name; -} /* get_current_user */ - -static const char * -get_homedir(const char *username) -{ - struct passwd pw_entry; - struct passwd *result = NULL; - - /* needs to be static because we return a pointer into this buffer - * to the caller */ - static char buf[1024]; - - int status; - - memset(&pw_entry, 0, sizeof(pw_entry)); - status = getpwnam_r(username, &pw_entry, buf, sizeof(buf), &result); - - if (status || (! result)) { - char errbuf[1024]; - sdb_log(SDB_LOG_WARNING, "Failed to determine home directory " - "for user %s: %s", username, - sdb_strerror(errno, errbuf, sizeof(errbuf))); - return NULL; - } - return result->pw_dir; -} /* get_homedir */ - -int -main(int argc, char **argv) -{ - sdb_client_t *client; - - const char *host = NULL; - const char *user = NULL; - - const char *homedir; - char hist_file[1024] = ""; - - sdb_strbuf_t *buf; - - while (42) { - int opt = getopt(argc, argv, "H:U:hV"); - - if (-1 == opt) - break; - - switch (opt) { - case 'H': - host = optarg; - break; - case 'U': - user = optarg; - break; - - case 'h': - exit_usage(argv[0], 0); - break; - case 'V': - exit_version(); - break; - default: - exit_usage(argv[0], 1); - } - } - - if (optind < argc) - exit_usage(argv[0], 1); - - if (! host) - host = DEFAULT_SOCKET; - if (! user) { - user = get_current_user(); - if (! user) - exit(1); - } - - client = sdb_client_create(host); - if (! client) { - sdb_log(SDB_LOG_ERR, "Failed to create client object"); - exit(1); - } - if (sdb_client_connect(client, user)) { - sdb_log(SDB_LOG_ERR, "Failed to connect to SysDBd"); - sdb_client_destroy(client); - exit(1); - } - - sdb_log(SDB_LOG_INFO, "SysDB client "SDB_CLIENT_VERSION_STRING - SDB_CLIENT_VERSION_EXTRA"\n"); - - using_history(); - - if ((homedir = get_homedir(user))) { - snprintf(hist_file, sizeof(hist_file) - 1, - "%s/.sysdb_history", homedir); - hist_file[sizeof(hist_file) - 1] = '\0'; - - errno = 0; - if (read_history(hist_file) && (errno != ENOENT)) { - char errbuf[1024]; - sdb_log(SDB_LOG_WARNING, "Failed to load history (%s): %s", - hist_file, sdb_strerror(errno, errbuf, sizeof(errbuf))); - } - } - - buf = sdb_strbuf_create(1024); - - while (42) { - const char *prompt = "sysdb=> "; - const char *query; - char *input; - - if (sdb_strbuf_len(buf)) - prompt = "sysdb-> "; - - input = readline(prompt); - - if (! input) - break; - - sdb_strbuf_append(buf, input); - free(input); - - query = sdb_strbuf_string(buf); - if (! strchr(query, (int)';')) - continue; - - /* XXX */ - sdb_strbuf_clear(buf); - } - - if (hist_file[0] != '\0') { - errno = 0; - if (write_history(hist_file)) { - char errbuf[1024]; - sdb_log(SDB_LOG_WARNING, "Failed to store history (%s): %s", - hist_file, sdb_strerror(errno, errbuf, sizeof(errbuf))); - } - } - - sdb_client_destroy(client); - return 0; -} /* main */ - -/* vim: set tw=78 sw=4 ts=4 noexpandtab : */ - diff --git a/src/daemon/config.c b/src/daemon/config.c deleted file mode 100644 index 906f4c5..0000000 --- a/src/daemon/config.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * SysDB - src/daemon/config.c - * Copyright (C) 2012 Sebastian 'tokkee' Harl - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "sysdb.h" -#include "core/plugin.h" -#include "core/time.h" -#include "utils/error.h" - -#include "daemon/config.h" - -#include "liboconfig/oconfig.h" -#include "liboconfig/utils.h" - -#include -#include - -#include -#include -#include - -/* - * Parser error values: - * - Values less than zero indicate an error in the daemon or libsysdb. - * - Zero indicates success. - * - Any other values indicate parsing errors. - */ - -enum { - ERR_UNKNOWN_OPTION = 1, - ERR_UNKNOWN_ARG = 2, - ERR_INVALID_ARG = 3, - ERR_PARSE_FAILED = 4, -}; - -/* - * private variables - */ - -static sdb_time_t default_interval = 0; - -/* - * private helper functions - */ - -static int -config_get_interval(oconfig_item_t *ci, sdb_time_t *interval) -{ - double interval_dbl = 0.0; - - assert(ci && interval); - - if (oconfig_get_number(ci, &interval_dbl)) { - sdb_log(SDB_LOG_ERR, "config: Interval requires " - "a single numeric argument\n" - "\tUsage: Interval SECONDS"); - return ERR_INVALID_ARG; - } - - if (interval_dbl <= 0.0) { - sdb_log(SDB_LOG_ERR, "config: Invalid interval: %f\n" - "\tInterval may not be less than or equal to zero.", - interval_dbl); - return ERR_INVALID_ARG; - } - - *interval = DOUBLE_TO_SDB_TIME(interval_dbl); - return 0; -} /* config_get_interval */ - -/* - * public parse results - */ - -char **listen_addresses = NULL; -size_t listen_addresses_num = 0; - -/* - * token parser - */ - -typedef struct { - char *name; - int (*dispatcher)(oconfig_item_t *); -} token_parser_t; - -static int -daemon_add_listener(oconfig_item_t *ci) -{ - char **tmp; - char *address; - - if (oconfig_get_string(ci, &address)) { - sdb_log(SDB_LOG_ERR, "config: Listen requires a single " - "string argument\n" - "\tUsage: Listen ADDRESS"); - return ERR_INVALID_ARG; - } - - tmp = realloc(listen_addresses, - (listen_addresses_num + 1) * sizeof(*listen_addresses)); - if (! tmp) { - char buf[1024]; - sdb_log(SDB_LOG_ERR, "config: Failed to allocate memory: %s", - sdb_strerror(errno, buf, sizeof(buf))); - return -1; - } - - tmp[listen_addresses_num] = strdup(address); - if (! tmp[listen_addresses_num]) { - char buf[1024]; - sdb_log(SDB_LOG_ERR, "config: Failed to allocate memory: %s", - sdb_strerror(errno, buf, sizeof(buf))); - return -1; - } - - listen_addresses = tmp; - ++listen_addresses_num; - return 0; -} /* daemon_add_listener */ - -static int -daemon_set_interval(oconfig_item_t *ci) -{ - return config_get_interval(ci, &default_interval); -} /* daemon_set_interval */ - -static int -daemon_load_plugin(oconfig_item_t *ci) -{ - char *name; - int i; - - if (oconfig_get_string(ci, &name)) { - sdb_log(SDB_LOG_ERR, "config: LoadPlugin requires a single " - "string argument\n" - "\tUsage: LoadPlugin PLUGIN"); - return ERR_INVALID_ARG; - } - - for (i = 0; i < ci->children_num; ++i) { - oconfig_item_t *child = ci->children + i; - - /* we don't currently support any options */ - sdb_log(SDB_LOG_WARNING, "config: Unknown option '%s' " - "inside 'LoadPlugin' -- see the documentation for " - "details.", child->key); - continue; - } - - /* returns a negative value on error */ - return sdb_plugin_load(name, NULL); -} /* daemon_load_plugin */ - -static int -daemon_load_backend(oconfig_item_t *ci) -{ - sdb_plugin_ctx_t ctx = SDB_PLUGIN_CTX_INIT; - - char plugin_name[1024]; - char *name; - - int i; - - ctx.interval = default_interval; - - if (oconfig_get_string(ci, &name)) { - sdb_log(SDB_LOG_ERR, "config: LoadBackend requires a single " - "string argument\n" - "\tUsage: LoadBackend BACKEND"); - return ERR_INVALID_ARG; - } - - snprintf(plugin_name, sizeof(plugin_name), "backend::%s", name); - - for (i = 0; i < ci->children_num; ++i) { - oconfig_item_t *child = ci->children + i; - - if (! strcasecmp(child->key, "Interval")) { - if (config_get_interval(child, &ctx.interval)) - return ERR_INVALID_ARG; - } - else { - sdb_log(SDB_LOG_WARNING, "config: Unknown option '%s' " - "inside 'LoadBackend' -- see the documentation for " - "details.", child->key); - continue; - } - } - - return sdb_plugin_load(plugin_name, &ctx); -} /* daemon_load_backend */ - -static int -daemon_configure_plugin(oconfig_item_t *ci) -{ - char *name; - - assert(ci); - - if (oconfig_get_string(ci, &name)) { - sdb_log(SDB_LOG_ERR, "config: %s requires a single " - "string argument\n" - "\tUsage: LoadBackend BACKEND", - ci->key); - return ERR_INVALID_ARG; - } - - return sdb_plugin_configure(name, ci); -} /* daemon_configure_backend */ - -static token_parser_t token_parser_list[] = { - { "Listen", daemon_add_listener }, - { "Interval", daemon_set_interval }, - { "LoadPlugin", daemon_load_plugin }, - { "LoadBackend", daemon_load_backend }, - { "Backend", daemon_configure_plugin }, - { "Plugin", daemon_configure_plugin }, - { NULL, NULL }, -}; - -/* - * public API - */ - -int -daemon_parse_config(const char *filename) -{ - oconfig_item_t *ci; - int retval = 0, i; - - ci = oconfig_parse_file(filename); - if (! ci) - return ERR_PARSE_FAILED; - - for (i = 0; i < ci->children_num; ++i) { - oconfig_item_t *child = ci->children + i; - int status = ERR_UNKNOWN_OPTION, j; - - for (j = 0; token_parser_list[j].name; ++j) { - if (! strcasecmp(token_parser_list[j].name, child->key)) - status = token_parser_list[j].dispatcher(child); - } - - if (status) { - sdb_error_set("config: Failed to parse option '%s'\n", - child->key); - if (status == ERR_UNKNOWN_OPTION) - sdb_error_append("\tUnknown option '%s' -- " - "see the documentation for details\n", - child->key); - sdb_error_chomp(); - sdb_error_log(SDB_LOG_ERR); - retval = status; - } - } - return retval; -} /* daemon_parse_config */ - -/* vim: set tw=78 sw=4 ts=4 noexpandtab : */ - diff --git a/src/daemon/sysdbd.c b/src/daemon/sysdbd.c deleted file mode 100644 index 21350f3..0000000 --- a/src/daemon/sysdbd.c +++ /dev/null @@ -1,298 +0,0 @@ -/* - * SysDB - src/sysdbd.c - * Copyright (C) 2012 Sebastian 'tokkee' Harl - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if HAVE_CONFIG_H -# include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include "sysdb.h" -#include "core/plugin.h" -#include "core/store.h" -#include "utils/error.h" - -#include "frontend/sock.h" - -#include "daemon/config.h" - -#if HAVE_LIBGEN_H -# include -#else /* HAVE_LIBGEN_H */ -# define basename(path) (path) -#endif /* ! HAVE_LIBGEN_H */ - -#include - -#include -#include - -#include - -#include -#include -#include - -#include - -#include - -#ifndef CONFIGFILE -# define CONFIGFILE SYSCONFDIR"/sysdb/sysdbd.conf" -#endif - -#ifndef DEFAULT_SOCKET -# define DEFAULT_SOCKET "unix:"LOCALSTATEDIR"/run/sysdbd.sock" -#endif - -static sdb_plugin_loop_t plugin_main_loop = SDB_PLUGIN_LOOP_INIT; -static sdb_fe_loop_t frontend_main_loop = SDB_FE_LOOP_INIT; - -static char *default_listen_addresses[] = { - DEFAULT_SOCKET, -}; - -static void -sigintterm_handler(int __attribute__((unused)) signo) -{ - frontend_main_loop.do_loop = 0; -} /* sigintterm_handler */ - -static void -exit_usage(char *name, int status) -{ - printf( -"Usage: %s \n" - -"\nOptions:\n" -" -C FILE the main configuration file\n" -" default: "CONFIGFILE"\n" -" -D do not run in background (daemonize)\n" -"\n" -" -h display this help and exit\n" -" -V display the version number and copyright\n" - -"\nSysDB daemon "SDB_VERSION_STRING SDB_VERSION_EXTRA", "PACKAGE_URL"\n", -basename(name)); - exit(status); -} /* exit_usage */ - -static void -exit_version(void) -{ - printf("SysDBd version "SDB_VERSION_STRING SDB_VERSION_EXTRA", " - "built "BUILD_DATE"\n" - "using libsysdb version %s%s\n" - "Copyright (C) 2012-2013 "PACKAGE_MAINTAINER"\n" - - "\nThis is free software under the terms of the BSD license, see " - "the source for\ncopying conditions. There is NO WARRANTY; not " - "even for MERCHANTABILITY or\nFITNESS FOR A PARTICULAR " - "PURPOSE.\n", sdb_version_string(), sdb_version_extra()); - exit(0); -} /* exit_version */ - -static int -daemonize(void) -{ - pid_t pid; - - if ((pid = fork()) < 0) { - char errbuf[1024]; - sdb_log(SDB_LOG_ERR, "Failed to fork to background: %s", - sdb_strerror(errno, errbuf, sizeof(errbuf))); - return errno; - } - else if (pid != 0) { - /* parent */ - exit(0); - } - - if (chdir("/")) { - char errbuf[1024]; - sdb_log(SDB_LOG_ERR, "Failed to change working directory to " - "the root directory: %s", - sdb_strerror(errno, errbuf, sizeof(errbuf))); - return errno; - } - - /* detach from session */ - setsid(); - - close(0); - if (open("/dev/null", O_RDWR)) { - char errbuf[1024]; - sdb_log(SDB_LOG_ERR, "Failed to connect stdin to '/dev/null': %s", - sdb_strerror(errno, errbuf, sizeof(errbuf))); - return errno; - } - - close(1); - if (dup(0) != 1) { - char errbuf[1024]; - sdb_log(SDB_LOG_ERR, "Could not connect stdout to '/dev/null': %s", - sdb_strerror(errno, errbuf, sizeof(errbuf))); - return errno; - } - - close(2); - if (dup(0) != 2) { - char errbuf[1024]; - sdb_log(SDB_LOG_ERR, "Could not connect stderr to '/dev/null': %s", - sdb_strerror(errno, errbuf, sizeof(errbuf))); - return errno; - } - return 0; -} /* daemonize */ - -static void * -backend_handler(void __attribute__((unused)) *data) -{ - sdb_plugin_collector_loop(&plugin_main_loop); - sdb_log(SDB_LOG_INFO, "Shutting down backend thread"); - return NULL; -} /* backend_handler */ - -int -main(int argc, char **argv) -{ - char *config_filename = NULL; - _Bool do_daemonize = 1; - - pthread_t backend_thread; - - struct sigaction sa_intterm; - int status; - - sdb_error_set_logger(sdb_plugin_log); - - while (42) { - int opt = getopt(argc, argv, "C:DhV"); - - if (-1 == opt) - break; - - switch (opt) { - case 'C': - config_filename = optarg; - break; - case 'D': - do_daemonize = 0; - break; - - case 'h': - exit_usage(argv[0], 0); - break; - case 'V': - exit_version(); - break; - default: - exit_usage(argv[0], 1); - } - } - - if (optind < argc) - exit_usage(argv[0], 1); - - if (! config_filename) - config_filename = CONFIGFILE; - - if ((status = daemon_parse_config(config_filename))) { - if (status > 0) - sdb_log(SDB_LOG_ERR, "Failed to parse configuration file."); - else - sdb_log(SDB_LOG_ERR, "Failed to load configuration file.\n" - "\tCheck other error messages for details."); - exit(1); - } - - if (! listen_addresses) { - listen_addresses = default_listen_addresses; - listen_addresses_num = SDB_STATIC_ARRAY_LEN(default_listen_addresses); - } - - memset(&sa_intterm, 0, sizeof(sa_intterm)); - sa_intterm.sa_handler = sigintterm_handler; - sa_intterm.sa_flags = 0; - - if (sigaction(SIGINT, &sa_intterm, /* old action */ NULL)) { - char errbuf[1024]; - sdb_log(SDB_LOG_ERR, "Failed to install signal handler for " - "SIGINT: %s", sdb_strerror(errno, errbuf, sizeof(errbuf))); - exit(1); - } - if (sigaction(SIGTERM, &sa_intterm, /* old action */ NULL)) { - char errbuf[1024]; - sdb_log(SDB_LOG_ERR, "Failed to install signal handler for " - "SIGTERM: %s", sdb_strerror(errno, errbuf, sizeof(errbuf))); - exit(1); - } - - if (do_daemonize) - if (daemonize()) - exit(1); - - sdb_log(SDB_LOG_INFO, "SysDB daemon "SDB_VERSION_STRING - SDB_VERSION_EXTRA " (pid %i) initialized successfully", - (int)getpid()); - - sdb_plugin_init_all(); - plugin_main_loop.default_interval = SECS_TO_SDB_TIME(60); - - memset(&backend_thread, 0, sizeof(backend_thread)); - if (pthread_create(&backend_thread, /* attr = */ NULL, - backend_handler, /* arg = */ NULL)) { - char buf[1024]; - sdb_log(SDB_LOG_ERR, "Failed to create backend handler thread: %s", - sdb_strerror(errno, buf, sizeof(buf))); - - plugin_main_loop.do_loop = 0; - } - else { - size_t i; - - sdb_fe_socket_t *sock = sdb_fe_sock_create(); - for (i = 0; i < listen_addresses_num; ++i) - if (sdb_fe_sock_add_listener(sock, listen_addresses[i])) - break; - - /* break on error */ - if (i >= listen_addresses_num) - sdb_fe_sock_listen_and_serve(sock, &frontend_main_loop); - - sdb_log(SDB_LOG_INFO, "Waiting for backend thread to terminate"); - plugin_main_loop.do_loop = 0; - pthread_kill(backend_thread, SIGINT); - pthread_join(backend_thread, NULL); - sdb_fe_sock_destroy(sock); - } - - sdb_log(SDB_LOG_INFO, "Shutting down SysDB daemon "SDB_VERSION_STRING - SDB_VERSION_EXTRA" (pid %i)", (int)getpid()); - return 0; -} /* main */ - -/* vim: set tw=78 sw=4 ts=4 noexpandtab : */ - diff --git a/src/daemon/sysdbd.conf.sample b/src/daemon/sysdbd.conf.sample deleted file mode 100644 index 0976e80..0000000 --- a/src/daemon/sysdbd.conf.sample +++ /dev/null @@ -1,73 +0,0 @@ -# -# Sample configuration file for the System DataBase daemon (SysDBd). -# - -#============================================================================# -# Global options: # -# This section defines global settings and default values for the daemon. # -#============================================================================# - -# default interval used for actively polling plugins -Interval 300 - -#============================================================================# -# Logging settings: # -# These plugins should be loaded first. Else, any log messages will be # -# written to the standard error channel which is closed after the daemon has # -# started. # -#============================================================================# -LoadPlugin "syslog" - -#============================================================================# -# Plugins: # -# Plugins are the working horses of SysDB. Load any of the following plugins # -# to active the respective feature. # -#============================================================================# - -#----------------------------------------------------------------------------# -# "cname" plugins canonicalize hostnames before actually storing them. All # -# cname callbacks are applied to an hostname in the order in which they have # -# been loaded, each receiving the result of the previous call. # -#----------------------------------------------------------------------------# -LoadPlugin "cname::dns" - -#----------------------------------------------------------------------------# -# "Backends" are plugins which collect information to be stored in SysDB. # -# Each backend may use its own custom query interval by specifying the # -# 'Interval' option: # -# # -# Interval 60 # -# # -#----------------------------------------------------------------------------# -LoadBackend "collectd::unixsock" -LoadBackend "mk-livestatus" -LoadBackend "puppet::store-configs" - -#----------------------------------------------------------------------------# -# Plugin configuration: # -#----------------------------------------------------------------------------# - - - - Socket "/var/run/collectd-unixsock" - - - - - - Socket "/var/lib/nagios4/rw/live" - - - - - - DBAdapter "pgsql" - DBName "puppet" - DBServer "puppet.domain.tld" - DBPort "5432" - DBUser "puppet" - DBPassword "secret1" - DBIOption "name" "value" - - - diff --git a/src/include/daemon/config.h b/src/include/daemon/config.h deleted file mode 100644 index 0fe278d..0000000 --- a/src/include/daemon/config.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SysDB - src/daemon/config.h - * Copyright (C) 2012 Sebastian 'tokkee' Harl - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef DAEMON_CONFIG_H -#define DAEMON_CONFIG_H 1 - -/* - * parse result values - */ - -extern char **listen_addresses; -extern size_t listen_addresses_num; - -/* - * daemon_parse_config: - * Parse the specified configuration file. - * - * Returns: - * - 0 on success - * - a negative value when loading the configuration failed because of errors - * in the daemon or libsysdb - * - a positive value on parser errors - */ -int -daemon_parse_config(const char *filename); - -#endif /* ! DAEMON_CONFIG_H */ - -/* vim: set tw=78 sw=4 ts=4 noexpandtab : */ - diff --git a/src/tools/sysdb/main.c b/src/tools/sysdb/main.c new file mode 100644 index 0000000..0639e5f --- /dev/null +++ b/src/tools/sysdb/main.c @@ -0,0 +1,281 @@ +/* + * SysDB - src/tools/sysdb/main.c + * Copyright (C) 2013 Sebastian 'tokkee' Harl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include "client/sysdb.h" +#include "client/sock.h" +#include "utils/error.h" +#include "utils/strbuf.h" + +#include + +#if HAVE_LIBGEN_H +# include +#else /* HAVE_LIBGEN_H */ +# define basename(path) (path) +#endif /* ! HAVE_LIBGEN_H */ + +#include +#include + +#include +#include +#include + +#include + +#include + +#include + +#if HAVE_EDITLINE_READLINE_H +# include +# if HAVE_EDITLINE_HISTORY_H +# include +# endif +#elif HAVE_READLINE_READLINE_H +# include +# if HAVE_READLINE_HISTORY_H +# include +# endif +#elif HAVE_READLINE_H +# include +# if HAVE_HISTORY_H +# include +# endif +#endif /* READLINEs */ + +#ifndef DEFAULT_SOCKET +# define DEFAULT_SOCKET "unix:"LOCALSTATEDIR"/run/sysdbd.sock" +#endif + +static void +exit_usage(char *name, int status) +{ + printf( +"Usage: %s \n" + +"\nOptions:\n" +" -h display this help and exit\n" +" -V display the version number and copyright\n" + +"\nSysDB client "SDB_CLIENT_VERSION_STRING SDB_CLIENT_VERSION_EXTRA", " +PACKAGE_URL"\n", basename(name)); + exit(status); +} /* exit_usage */ + +static void +exit_version(void) +{ + printf("SysDB version "SDB_CLIENT_VERSION_STRING + SDB_CLIENT_VERSION_EXTRA", built "BUILD_DATE"\n" + "using libsysdbclient version %s%s\n" + "Copyright (C) 2012-2013 "PACKAGE_MAINTAINER"\n" + + "\nThis is free software under the terms of the BSD license, see " + "the source for\ncopying conditions. There is NO WARRANTY; not " + "even for MERCHANTABILITY or\nFITNESS FOR A PARTICULAR " + "PURPOSE.\n", sdb_client_version_string(), + sdb_client_version_extra()); + exit(0); +} /* exit_version */ + +static const char * +get_current_user(void) +{ + struct passwd pw_entry; + struct passwd *result = NULL; + + uid_t uid; + + /* needs to be static because we return a pointer into this buffer + * to the caller */ + static char buf[1024]; + + int status; + + uid = geteuid(); + + memset(&pw_entry, 0, sizeof(pw_entry)); + status = getpwuid_r(uid, &pw_entry, buf, sizeof(buf), &result); + + if (status || (! result)) { + char errbuf[1024]; + sdb_log(SDB_LOG_ERR, "Failed to determine current username: %s", + sdb_strerror(errno, errbuf, sizeof(errbuf))); + return NULL; + } + return result->pw_name; +} /* get_current_user */ + +static const char * +get_homedir(const char *username) +{ + struct passwd pw_entry; + struct passwd *result = NULL; + + /* needs to be static because we return a pointer into this buffer + * to the caller */ + static char buf[1024]; + + int status; + + memset(&pw_entry, 0, sizeof(pw_entry)); + status = getpwnam_r(username, &pw_entry, buf, sizeof(buf), &result); + + if (status || (! result)) { + char errbuf[1024]; + sdb_log(SDB_LOG_WARNING, "Failed to determine home directory " + "for user %s: %s", username, + sdb_strerror(errno, errbuf, sizeof(errbuf))); + return NULL; + } + return result->pw_dir; +} /* get_homedir */ + +int +main(int argc, char **argv) +{ + sdb_client_t *client; + + const char *host = NULL; + const char *user = NULL; + + const char *homedir; + char hist_file[1024] = ""; + + sdb_strbuf_t *buf; + + while (42) { + int opt = getopt(argc, argv, "H:U:hV"); + + if (-1 == opt) + break; + + switch (opt) { + case 'H': + host = optarg; + break; + case 'U': + user = optarg; + break; + + case 'h': + exit_usage(argv[0], 0); + break; + case 'V': + exit_version(); + break; + default: + exit_usage(argv[0], 1); + } + } + + if (optind < argc) + exit_usage(argv[0], 1); + + if (! host) + host = DEFAULT_SOCKET; + if (! user) { + user = get_current_user(); + if (! user) + exit(1); + } + + client = sdb_client_create(host); + if (! client) { + sdb_log(SDB_LOG_ERR, "Failed to create client object"); + exit(1); + } + if (sdb_client_connect(client, user)) { + sdb_log(SDB_LOG_ERR, "Failed to connect to SysDBd"); + sdb_client_destroy(client); + exit(1); + } + + sdb_log(SDB_LOG_INFO, "SysDB client "SDB_CLIENT_VERSION_STRING + SDB_CLIENT_VERSION_EXTRA"\n"); + + using_history(); + + if ((homedir = get_homedir(user))) { + snprintf(hist_file, sizeof(hist_file) - 1, + "%s/.sysdb_history", homedir); + hist_file[sizeof(hist_file) - 1] = '\0'; + + errno = 0; + if (read_history(hist_file) && (errno != ENOENT)) { + char errbuf[1024]; + sdb_log(SDB_LOG_WARNING, "Failed to load history (%s): %s", + hist_file, sdb_strerror(errno, errbuf, sizeof(errbuf))); + } + } + + buf = sdb_strbuf_create(1024); + + while (42) { + const char *prompt = "sysdb=> "; + const char *query; + char *input; + + if (sdb_strbuf_len(buf)) + prompt = "sysdb-> "; + + input = readline(prompt); + + if (! input) + break; + + sdb_strbuf_append(buf, input); + free(input); + + query = sdb_strbuf_string(buf); + if (! strchr(query, (int)';')) + continue; + + /* XXX */ + sdb_strbuf_clear(buf); + } + + if (hist_file[0] != '\0') { + errno = 0; + if (write_history(hist_file)) { + char errbuf[1024]; + sdb_log(SDB_LOG_WARNING, "Failed to store history (%s): %s", + hist_file, sdb_strerror(errno, errbuf, sizeof(errbuf))); + } + } + + sdb_client_destroy(client); + return 0; +} /* main */ + +/* vim: set tw=78 sw=4 ts=4 noexpandtab : */ + diff --git a/src/tools/sysdbd/configfile.c b/src/tools/sysdbd/configfile.c new file mode 100644 index 0000000..9527626 --- /dev/null +++ b/src/tools/sysdbd/configfile.c @@ -0,0 +1,284 @@ +/* + * SysDB - src/tools/sysdbd/configfile.c + * Copyright (C) 2012 Sebastian 'tokkee' Harl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "tools/sysdbd/configfile.h" + +#include "sysdb.h" +#include "core/plugin.h" +#include "core/time.h" +#include "utils/error.h" + +#include "liboconfig/oconfig.h" +#include "liboconfig/utils.h" + +#include +#include + +#include +#include +#include + +/* + * Parser error values: + * - Values less than zero indicate an error in the daemon or libsysdb. + * - Zero indicates success. + * - Any other values indicate parsing errors. + */ + +enum { + ERR_UNKNOWN_OPTION = 1, + ERR_UNKNOWN_ARG = 2, + ERR_INVALID_ARG = 3, + ERR_PARSE_FAILED = 4, +}; + +/* + * private variables + */ + +static sdb_time_t default_interval = 0; + +/* + * private helper functions + */ + +static int +config_get_interval(oconfig_item_t *ci, sdb_time_t *interval) +{ + double interval_dbl = 0.0; + + assert(ci && interval); + + if (oconfig_get_number(ci, &interval_dbl)) { + sdb_log(SDB_LOG_ERR, "config: Interval requires " + "a single numeric argument\n" + "\tUsage: Interval SECONDS"); + return ERR_INVALID_ARG; + } + + if (interval_dbl <= 0.0) { + sdb_log(SDB_LOG_ERR, "config: Invalid interval: %f\n" + "\tInterval may not be less than or equal to zero.", + interval_dbl); + return ERR_INVALID_ARG; + } + + *interval = DOUBLE_TO_SDB_TIME(interval_dbl); + return 0; +} /* config_get_interval */ + +/* + * public parse results + */ + +char **listen_addresses = NULL; +size_t listen_addresses_num = 0; + +/* + * token parser + */ + +typedef struct { + char *name; + int (*dispatcher)(oconfig_item_t *); +} token_parser_t; + +static int +daemon_add_listener(oconfig_item_t *ci) +{ + char **tmp; + char *address; + + if (oconfig_get_string(ci, &address)) { + sdb_log(SDB_LOG_ERR, "config: Listen requires a single " + "string argument\n" + "\tUsage: Listen ADDRESS"); + return ERR_INVALID_ARG; + } + + tmp = realloc(listen_addresses, + (listen_addresses_num + 1) * sizeof(*listen_addresses)); + if (! tmp) { + char buf[1024]; + sdb_log(SDB_LOG_ERR, "config: Failed to allocate memory: %s", + sdb_strerror(errno, buf, sizeof(buf))); + return -1; + } + + tmp[listen_addresses_num] = strdup(address); + if (! tmp[listen_addresses_num]) { + char buf[1024]; + sdb_log(SDB_LOG_ERR, "config: Failed to allocate memory: %s", + sdb_strerror(errno, buf, sizeof(buf))); + return -1; + } + + listen_addresses = tmp; + ++listen_addresses_num; + return 0; +} /* daemon_add_listener */ + +static int +daemon_set_interval(oconfig_item_t *ci) +{ + return config_get_interval(ci, &default_interval); +} /* daemon_set_interval */ + +static int +daemon_load_plugin(oconfig_item_t *ci) +{ + char *name; + int i; + + if (oconfig_get_string(ci, &name)) { + sdb_log(SDB_LOG_ERR, "config: LoadPlugin requires a single " + "string argument\n" + "\tUsage: LoadPlugin PLUGIN"); + return ERR_INVALID_ARG; + } + + for (i = 0; i < ci->children_num; ++i) { + oconfig_item_t *child = ci->children + i; + + /* we don't currently support any options */ + sdb_log(SDB_LOG_WARNING, "config: Unknown option '%s' " + "inside 'LoadPlugin' -- see the documentation for " + "details.", child->key); + continue; + } + + /* returns a negative value on error */ + return sdb_plugin_load(name, NULL); +} /* daemon_load_plugin */ + +static int +daemon_load_backend(oconfig_item_t *ci) +{ + sdb_plugin_ctx_t ctx = SDB_PLUGIN_CTX_INIT; + + char plugin_name[1024]; + char *name; + + int i; + + ctx.interval = default_interval; + + if (oconfig_get_string(ci, &name)) { + sdb_log(SDB_LOG_ERR, "config: LoadBackend requires a single " + "string argument\n" + "\tUsage: LoadBackend BACKEND"); + return ERR_INVALID_ARG; + } + + snprintf(plugin_name, sizeof(plugin_name), "backend::%s", name); + + for (i = 0; i < ci->children_num; ++i) { + oconfig_item_t *child = ci->children + i; + + if (! strcasecmp(child->key, "Interval")) { + if (config_get_interval(child, &ctx.interval)) + return ERR_INVALID_ARG; + } + else { + sdb_log(SDB_LOG_WARNING, "config: Unknown option '%s' " + "inside 'LoadBackend' -- see the documentation for " + "details.", child->key); + continue; + } + } + + return sdb_plugin_load(plugin_name, &ctx); +} /* daemon_load_backend */ + +static int +daemon_configure_plugin(oconfig_item_t *ci) +{ + char *name; + + assert(ci); + + if (oconfig_get_string(ci, &name)) { + sdb_log(SDB_LOG_ERR, "config: %s requires a single " + "string argument\n" + "\tUsage: LoadBackend BACKEND", + ci->key); + return ERR_INVALID_ARG; + } + + return sdb_plugin_configure(name, ci); +} /* daemon_configure_backend */ + +static token_parser_t token_parser_list[] = { + { "Listen", daemon_add_listener }, + { "Interval", daemon_set_interval }, + { "LoadPlugin", daemon_load_plugin }, + { "LoadBackend", daemon_load_backend }, + { "Backend", daemon_configure_plugin }, + { "Plugin", daemon_configure_plugin }, + { NULL, NULL }, +}; + +/* + * public API + */ + +int +daemon_parse_config(const char *filename) +{ + oconfig_item_t *ci; + int retval = 0, i; + + ci = oconfig_parse_file(filename); + if (! ci) + return ERR_PARSE_FAILED; + + for (i = 0; i < ci->children_num; ++i) { + oconfig_item_t *child = ci->children + i; + int status = ERR_UNKNOWN_OPTION, j; + + for (j = 0; token_parser_list[j].name; ++j) { + if (! strcasecmp(token_parser_list[j].name, child->key)) + status = token_parser_list[j].dispatcher(child); + } + + if (status) { + sdb_error_set("config: Failed to parse option '%s'\n", + child->key); + if (status == ERR_UNKNOWN_OPTION) + sdb_error_append("\tUnknown option '%s' -- " + "see the documentation for details\n", + child->key); + sdb_error_chomp(); + sdb_error_log(SDB_LOG_ERR); + retval = status; + } + } + return retval; +} /* daemon_parse_config */ + +/* vim: set tw=78 sw=4 ts=4 noexpandtab : */ + diff --git a/src/tools/sysdbd/configfile.h b/src/tools/sysdbd/configfile.h new file mode 100644 index 0000000..19abe9a --- /dev/null +++ b/src/tools/sysdbd/configfile.h @@ -0,0 +1,56 @@ +/* + * SysDB - src/tools/sysdbd/configfile.h + * Copyright (C) 2012 Sebastian 'tokkee' Harl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#ifndef DAEMON_CONFIG_H +#define DAEMON_CONFIG_H 1 + +/* + * parse result values + */ + +extern char **listen_addresses; +extern size_t listen_addresses_num; + +/* + * daemon_parse_config: + * Parse the specified configuration file. + * + * Returns: + * - 0 on success + * - a negative value when loading the configuration failed because of errors + * in the daemon or libsysdb + * - a positive value on parser errors + */ +int +daemon_parse_config(const char *filename); + +#endif /* ! DAEMON_CONFIG_H */ + +/* vim: set tw=78 sw=4 ts=4 noexpandtab : */ + diff --git a/src/tools/sysdbd/main.c b/src/tools/sysdbd/main.c new file mode 100644 index 0000000..195d494 --- /dev/null +++ b/src/tools/sysdbd/main.c @@ -0,0 +1,298 @@ +/* + * SysDB - src/tools/sysdbd/main.c + * Copyright (C) 2012 Sebastian 'tokkee' Harl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include "sysdb.h" +#include "core/plugin.h" +#include "core/store.h" +#include "utils/error.h" + +#include "frontend/sock.h" + +#include "tools/sysdbd/configfile.h" + +#if HAVE_LIBGEN_H +# include +#else /* HAVE_LIBGEN_H */ +# define basename(path) (path) +#endif /* ! HAVE_LIBGEN_H */ + +#include + +#include +#include + +#include + +#include +#include +#include + +#include + +#include + +#ifndef CONFIGFILE +# define CONFIGFILE SYSCONFDIR"/sysdb/sysdbd.conf" +#endif + +#ifndef DEFAULT_SOCKET +# define DEFAULT_SOCKET "unix:"LOCALSTATEDIR"/run/sysdbd.sock" +#endif + +static sdb_plugin_loop_t plugin_main_loop = SDB_PLUGIN_LOOP_INIT; +static sdb_fe_loop_t frontend_main_loop = SDB_FE_LOOP_INIT; + +static char *default_listen_addresses[] = { + DEFAULT_SOCKET, +}; + +static void +sigintterm_handler(int __attribute__((unused)) signo) +{ + frontend_main_loop.do_loop = 0; +} /* sigintterm_handler */ + +static void +exit_usage(char *name, int status) +{ + printf( +"Usage: %s \n" + +"\nOptions:\n" +" -C FILE the main configuration file\n" +" default: "CONFIGFILE"\n" +" -D do not run in background (daemonize)\n" +"\n" +" -h display this help and exit\n" +" -V display the version number and copyright\n" + +"\nSysDB daemon "SDB_VERSION_STRING SDB_VERSION_EXTRA", "PACKAGE_URL"\n", +basename(name)); + exit(status); +} /* exit_usage */ + +static void +exit_version(void) +{ + printf("SysDBd version "SDB_VERSION_STRING SDB_VERSION_EXTRA", " + "built "BUILD_DATE"\n" + "using libsysdb version %s%s\n" + "Copyright (C) 2012-2013 "PACKAGE_MAINTAINER"\n" + + "\nThis is free software under the terms of the BSD license, see " + "the source for\ncopying conditions. There is NO WARRANTY; not " + "even for MERCHANTABILITY or\nFITNESS FOR A PARTICULAR " + "PURPOSE.\n", sdb_version_string(), sdb_version_extra()); + exit(0); +} /* exit_version */ + +static int +daemonize(void) +{ + pid_t pid; + + if ((pid = fork()) < 0) { + char errbuf[1024]; + sdb_log(SDB_LOG_ERR, "Failed to fork to background: %s", + sdb_strerror(errno, errbuf, sizeof(errbuf))); + return errno; + } + else if (pid != 0) { + /* parent */ + exit(0); + } + + if (chdir("/")) { + char errbuf[1024]; + sdb_log(SDB_LOG_ERR, "Failed to change working directory to " + "the root directory: %s", + sdb_strerror(errno, errbuf, sizeof(errbuf))); + return errno; + } + + /* detach from session */ + setsid(); + + close(0); + if (open("/dev/null", O_RDWR)) { + char errbuf[1024]; + sdb_log(SDB_LOG_ERR, "Failed to connect stdin to '/dev/null': %s", + sdb_strerror(errno, errbuf, sizeof(errbuf))); + return errno; + } + + close(1); + if (dup(0) != 1) { + char errbuf[1024]; + sdb_log(SDB_LOG_ERR, "Could not connect stdout to '/dev/null': %s", + sdb_strerror(errno, errbuf, sizeof(errbuf))); + return errno; + } + + close(2); + if (dup(0) != 2) { + char errbuf[1024]; + sdb_log(SDB_LOG_ERR, "Could not connect stderr to '/dev/null': %s", + sdb_strerror(errno, errbuf, sizeof(errbuf))); + return errno; + } + return 0; +} /* daemonize */ + +static void * +backend_handler(void __attribute__((unused)) *data) +{ + sdb_plugin_collector_loop(&plugin_main_loop); + sdb_log(SDB_LOG_INFO, "Shutting down backend thread"); + return NULL; +} /* backend_handler */ + +int +main(int argc, char **argv) +{ + char *config_filename = NULL; + _Bool do_daemonize = 1; + + pthread_t backend_thread; + + struct sigaction sa_intterm; + int status; + + sdb_error_set_logger(sdb_plugin_log); + + while (42) { + int opt = getopt(argc, argv, "C:DhV"); + + if (-1 == opt) + break; + + switch (opt) { + case 'C': + config_filename = optarg; + break; + case 'D': + do_daemonize = 0; + break; + + case 'h': + exit_usage(argv[0], 0); + break; + case 'V': + exit_version(); + break; + default: + exit_usage(argv[0], 1); + } + } + + if (optind < argc) + exit_usage(argv[0], 1); + + if (! config_filename) + config_filename = CONFIGFILE; + + if ((status = daemon_parse_config(config_filename))) { + if (status > 0) + sdb_log(SDB_LOG_ERR, "Failed to parse configuration file."); + else + sdb_log(SDB_LOG_ERR, "Failed to load configuration file.\n" + "\tCheck other error messages for details."); + exit(1); + } + + if (! listen_addresses) { + listen_addresses = default_listen_addresses; + listen_addresses_num = SDB_STATIC_ARRAY_LEN(default_listen_addresses); + } + + memset(&sa_intterm, 0, sizeof(sa_intterm)); + sa_intterm.sa_handler = sigintterm_handler; + sa_intterm.sa_flags = 0; + + if (sigaction(SIGINT, &sa_intterm, /* old action */ NULL)) { + char errbuf[1024]; + sdb_log(SDB_LOG_ERR, "Failed to install signal handler for " + "SIGINT: %s", sdb_strerror(errno, errbuf, sizeof(errbuf))); + exit(1); + } + if (sigaction(SIGTERM, &sa_intterm, /* old action */ NULL)) { + char errbuf[1024]; + sdb_log(SDB_LOG_ERR, "Failed to install signal handler for " + "SIGTERM: %s", sdb_strerror(errno, errbuf, sizeof(errbuf))); + exit(1); + } + + if (do_daemonize) + if (daemonize()) + exit(1); + + sdb_log(SDB_LOG_INFO, "SysDB daemon "SDB_VERSION_STRING + SDB_VERSION_EXTRA " (pid %i) initialized successfully", + (int)getpid()); + + sdb_plugin_init_all(); + plugin_main_loop.default_interval = SECS_TO_SDB_TIME(60); + + memset(&backend_thread, 0, sizeof(backend_thread)); + if (pthread_create(&backend_thread, /* attr = */ NULL, + backend_handler, /* arg = */ NULL)) { + char buf[1024]; + sdb_log(SDB_LOG_ERR, "Failed to create backend handler thread: %s", + sdb_strerror(errno, buf, sizeof(buf))); + + plugin_main_loop.do_loop = 0; + } + else { + size_t i; + + sdb_fe_socket_t *sock = sdb_fe_sock_create(); + for (i = 0; i < listen_addresses_num; ++i) + if (sdb_fe_sock_add_listener(sock, listen_addresses[i])) + break; + + /* break on error */ + if (i >= listen_addresses_num) + sdb_fe_sock_listen_and_serve(sock, &frontend_main_loop); + + sdb_log(SDB_LOG_INFO, "Waiting for backend thread to terminate"); + plugin_main_loop.do_loop = 0; + pthread_kill(backend_thread, SIGINT); + pthread_join(backend_thread, NULL); + sdb_fe_sock_destroy(sock); + } + + sdb_log(SDB_LOG_INFO, "Shutting down SysDB daemon "SDB_VERSION_STRING + SDB_VERSION_EXTRA" (pid %i)", (int)getpid()); + return 0; +} /* main */ + +/* vim: set tw=78 sw=4 ts=4 noexpandtab : */ + diff --git a/src/tools/sysdbd/sysdbd.conf.sample b/src/tools/sysdbd/sysdbd.conf.sample new file mode 100644 index 0000000..0976e80 --- /dev/null +++ b/src/tools/sysdbd/sysdbd.conf.sample @@ -0,0 +1,73 @@ +# +# Sample configuration file for the System DataBase daemon (SysDBd). +# + +#============================================================================# +# Global options: # +# This section defines global settings and default values for the daemon. # +#============================================================================# + +# default interval used for actively polling plugins +Interval 300 + +#============================================================================# +# Logging settings: # +# These plugins should be loaded first. Else, any log messages will be # +# written to the standard error channel which is closed after the daemon has # +# started. # +#============================================================================# +LoadPlugin "syslog" + +#============================================================================# +# Plugins: # +# Plugins are the working horses of SysDB. Load any of the following plugins # +# to active the respective feature. # +#============================================================================# + +#----------------------------------------------------------------------------# +# "cname" plugins canonicalize hostnames before actually storing them. All # +# cname callbacks are applied to an hostname in the order in which they have # +# been loaded, each receiving the result of the previous call. # +#----------------------------------------------------------------------------# +LoadPlugin "cname::dns" + +#----------------------------------------------------------------------------# +# "Backends" are plugins which collect information to be stored in SysDB. # +# Each backend may use its own custom query interval by specifying the # +# 'Interval' option: # +# # +# Interval 60 # +# # +#----------------------------------------------------------------------------# +LoadBackend "collectd::unixsock" +LoadBackend "mk-livestatus" +LoadBackend "puppet::store-configs" + +#----------------------------------------------------------------------------# +# Plugin configuration: # +#----------------------------------------------------------------------------# + + + + Socket "/var/run/collectd-unixsock" + + + + + + Socket "/var/lib/nagios4/rw/live" + + + + + + DBAdapter "pgsql" + DBName "puppet" + DBServer "puppet.domain.tld" + DBPort "5432" + DBUser "puppet" + DBPassword "secret1" + DBIOption "name" "value" + + +