From: Sebastian Harl Date: Tue, 10 Dec 2013 19:29:28 +0000 (+0100) Subject: Merged branch 'master' of git://git.tokkee.org/sysdb. X-Git-Tag: sysdb-0.1.0~314 X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=commitdiff_plain;h=ddb7ffc175e49abfa69c82777b88d73e1f1103fb;hp=e9881fcf521265f8e88004694e5678df0dd6b3d4 Merged branch 'master' of git://git.tokkee.org/sysdb. --- diff --git a/src/Makefile.am b/src/Makefile.am index 724bfaa..e547fa4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -12,7 +12,6 @@ pkginclude_HEADERS = include/sysdb.h pkgcoreincludedir = $(pkgincludedir)/core pkgcoreinclude_HEADERS = \ include/core/data.h \ - include/core/error.h \ include/core/object.h \ include/core/plugin.h \ include/core/store.h \ @@ -20,11 +19,13 @@ pkgcoreinclude_HEADERS = \ pkgfeincludedir = $(pkgincludedir)/frontend pkgfeinclude_HEADERS = \ include/frontend/connection.h \ + include/frontend/proto.h \ include/frontend/sock.h pkgutilsincludedir = $(pkgincludedir)/utils pkgutilsinclude_HEADERS = \ include/utils/channel.h \ include/utils/dbi.h \ + include/utils/error.h \ include/utils/llist.h \ include/utils/proto.h \ include/utils/strbuf.h \ @@ -32,13 +33,15 @@ pkgutilsinclude_HEADERS = \ pkgclientincludedir = $(pkgincludedir)/client pkgclientinclude_HEADERS = \ - include/client/sock.h + include/client/sock.h \ + include/client/sysdb.h lib_LTLIBRARIES = libsysdbclient.la libsysdb.la libsysdbclient_la_SOURCES = \ client/client.c include/client/sysdb.h \ client/sock.c include/client/sock.h \ + utils/error.c include/utils/error.h \ utils/proto.c include/utils/proto.h \ utils/strbuf.c include/utils/strbuf.h libsysdbclient_la_CFLAGS = $(AM_CFLAGS) @@ -52,13 +55,13 @@ libsysdb_la_SOURCES = \ core/plugin.c include/core/plugin.h \ core/store.c include/core/store.h \ include/core/data.h \ - core/error.c include/core/error.h \ frontend/connection.c include/frontend/connection.h \ include/frontend/connection-private.h \ frontend/sock.c include/frontend/sock.h \ frontend/session.c \ frontend/query.c \ utils/channel.c include/utils/channel.h \ + utils/error.c include/utils/error.h \ utils/llist.c include/utils/llist.h \ utils/proto.c include/utils/proto.h \ utils/strbuf.c include/utils/strbuf.h \ diff --git a/src/backend/collectd/unixsock.c b/src/backend/collectd/unixsock.c index c01b0f3..766bbce 100644 --- a/src/backend/collectd/unixsock.c +++ b/src/backend/collectd/unixsock.c @@ -28,7 +28,7 @@ #include "sysdb.h" #include "core/plugin.h" #include "core/store.h" -#include "core/error.h" +#include "utils/error.h" #include "utils/unixsock.h" #include "liboconfig/utils.h" diff --git a/src/backend/mk-livestatus.c b/src/backend/mk-livestatus.c index d672b36..bf45da6 100644 --- a/src/backend/mk-livestatus.c +++ b/src/backend/mk-livestatus.c @@ -28,7 +28,7 @@ #include "sysdb.h" #include "core/plugin.h" #include "core/store.h" -#include "core/error.h" +#include "utils/error.h" #include "utils/unixsock.h" #include "liboconfig/utils.h" diff --git a/src/backend/puppet/store-configs.c b/src/backend/puppet/store-configs.c index 4343920..a9a0ff7 100644 --- a/src/backend/puppet/store-configs.c +++ b/src/backend/puppet/store-configs.c @@ -28,8 +28,8 @@ #include "sysdb.h" #include "core/plugin.h" #include "core/store.h" -#include "core/error.h" #include "utils/dbi.h" +#include "utils/error.h" #include "liboconfig/utils.h" diff --git a/src/client/sock.c b/src/client/sock.c index b3be615..18ab6a5 100644 --- a/src/client/sock.c +++ b/src/client/sock.c @@ -120,8 +120,12 @@ sdb_client_destroy(sdb_client_t *client) } /* sdb_client_destroy */ int -sdb_client_connect(sdb_client_t *client) +sdb_client_connect(sdb_client_t *client, const char *username) { + sdb_strbuf_t *buf; + ssize_t status; + uint32_t rstatus; + if ((! client) || (! client->address)) return -1; @@ -137,6 +141,32 @@ sdb_client_connect(sdb_client_t *client) if (client->fd < 0) return -1; + + /* XXX */ + if (! username) + username = ""; + + status = sdb_client_send(client, CONNECTION_STARTUP, + (uint32_t)strlen(username), username); + if (status < 0) { + sdb_client_close(client); + return (int)status; + } + + buf = sdb_strbuf_create(64); + rstatus = 0; + status = sdb_client_recv(client, &rstatus, buf); + if (status < 0) { + sdb_client_close(client); + sdb_strbuf_destroy(buf); + return (int)status; + } + + if (rstatus != CONNECTION_OK) { + sdb_client_close(client); + sdb_strbuf_destroy(buf); + return -((int)rstatus); + } return 0; } /* sdb_client_connect */ diff --git a/src/client/sysdb.c b/src/client/sysdb.c index 073e40e..fa71eed 100644 --- a/src/client/sysdb.c +++ b/src/client/sysdb.c @@ -31,6 +31,9 @@ #include "client/sysdb.h" #include "client/sock.h" +#include "utils/error.h" + +#include #if HAVE_LIBGEN_H # include @@ -47,6 +50,10 @@ #include +#include + +#include + #ifndef DEFAULT_SOCKET # define DEFAULT_SOCKET "unix:"LOCALSTATEDIR"/run/sysdbd.sock" #endif @@ -82,16 +89,56 @@ exit_version(void) 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 */ + int main(int argc, char **argv) { + sdb_client_t *client; + + const char *host = NULL; + const char *user = NULL; + while (42) { - int opt = getopt(argc, argv, "hV"); + 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; @@ -106,8 +153,26 @@ main(int argc, char **argv) if (optind < argc) exit_usage(argv[0], 1); - printf("SysDB client "SDB_CLIENT_VERSION_STRING + if (! host) + host = DEFAULT_SOCKET; + if (! user) + user = get_current_user(); + + 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"); + + sdb_client_destroy(client); return 0; } /* main */ diff --git a/src/core/error.c b/src/core/error.c deleted file mode 100644 index 7d14a25..0000000 --- a/src/core/error.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * SysDB - src/core/error.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. - */ - -#include "core/error.h" -#include "core/plugin.h" -#include "utils/strbuf.h" - -#include - -#include -#include -#include - -#include - -/* - * private data types - */ - -typedef struct { - int prio; - sdb_strbuf_t *msg; - _Bool logged; -} sdb_error_ctx_t; -#define SDB_ERROR_INIT { -1, NULL, 1 } - -/* - * private variables - */ - -static sdb_error_ctx_t default_error_ctx = SDB_ERROR_INIT; - -static pthread_key_t error_ctx_key; -static _Bool error_ctx_key_initialized = 0; - -/* - * private helper functions - */ - -static void -sdb_error_ctx_destructor(void *p) -{ - sdb_error_ctx_t *ctx = p; - - if (! ctx) - return; - - sdb_strbuf_destroy(ctx->msg); - free(ctx); -} /* sdb_error_ctx_destructor */ - -static void -sdb_error_ctx_init(void) -{ - if (error_ctx_key_initialized) - return; - - pthread_key_create(&error_ctx_key, sdb_error_ctx_destructor); - error_ctx_key_initialized = 1; -} /* sdb_error_init */ - -static sdb_error_ctx_t * -sdb_error_ctx_create(void) -{ - sdb_error_ctx_t *ctx; - - ctx = malloc(sizeof(*ctx)); - if (! ctx) - return NULL; - - *ctx = default_error_ctx; - ctx->msg = sdb_strbuf_create(64); - if (! ctx->msg) { - free(ctx); - return NULL; - } - - if (! error_ctx_key_initialized) - sdb_error_ctx_init(); - pthread_setspecific(error_ctx_key, ctx); - return ctx; -} /* sdb_error_ctx_create */ - -static sdb_error_ctx_t * -sdb_error_get_ctx(void) -{ - sdb_error_ctx_t *ctx; - - if (! error_ctx_key_initialized) - sdb_error_ctx_init(); - ctx = pthread_getspecific(error_ctx_key); - - if (! ctx) - ctx = sdb_error_ctx_create(); - if (! ctx) - return NULL; - return ctx; -} /* sdb_error_get_ctx */ - -static int -sdb_error_vprintf(const char *fmt, va_list ap) -{ - sdb_error_ctx_t *ctx; - - ctx = sdb_error_get_ctx(); - if (! ctx) - return -1; - - ctx->logged = 0; - return (int)sdb_strbuf_vsprintf(ctx->msg, fmt, ap); -} /* sdb_error_vprintf */ - -static int -sdb_error_vappend(const char *fmt, va_list ap) -{ - sdb_error_ctx_t *ctx; - - ctx = sdb_error_get_ctx(); - if (! ctx) - return -1; - - ctx->logged = 0; - return (int)sdb_strbuf_vappend(ctx->msg, fmt, ap); -} /* sdb_error_vappend */ - -static int -sdb_do_log(int prio) -{ - sdb_error_ctx_t *ctx; - int ret; - - ctx = sdb_error_get_ctx(); - if (! ctx) - return -1; - - if (prio >= 0) - ctx->prio = prio; - - if (ctx->logged) - return 0; - - ret = sdb_plugin_log(prio, sdb_strbuf_string(ctx->msg)); - ctx->logged = 1; - return ret; -} /* sdb_do_log */ - -/* - * public API - */ - -int -sdb_log(int prio, const char *fmt, ...) -{ - va_list ap; - int ret; - - va_start(ap, fmt); - ret = sdb_error_vprintf(fmt, ap); - va_end(ap); - - if (ret > 0) - sdb_do_log(prio); - return ret; -} /* sdb_log */ - -int -sdb_error_set(const char *fmt, ...) -{ - va_list ap; - int ret; - - va_start(ap, fmt); - ret = sdb_error_vprintf(fmt, ap); - va_end(ap); - - return ret; -} /* sdb_error_set */ - -int -sdb_error_append(const char *fmt, ...) -{ - va_list ap; - int ret; - - va_start(ap, fmt); - ret = sdb_error_vappend(fmt, ap); - va_end(ap); - - return ret; -} /* sdb_error_append */ - -int -sdb_error_chomp(void) -{ - sdb_error_ctx_t *ctx; - - ctx = sdb_error_get_ctx(); - if (! ctx) - return -1; - - sdb_strbuf_chomp(ctx->msg); - return 0; -} /* sdb_error_chomp */ - -int -sdb_error_log(int prio) -{ - return sdb_do_log(prio); -} /* sdb_error_log */ - -const char * -sdb_error_get(void) -{ - sdb_error_ctx_t *ctx; - - ctx = sdb_error_get_ctx(); - if (! ctx) - return "success"; - return sdb_strbuf_string(ctx->msg); -} /* sdb_error_get */ - -int -sdb_error_get_prio(void) -{ - sdb_error_ctx_t *ctx; - - ctx = sdb_error_get_ctx(); - if (! ctx) - return -1; - return ctx->prio; -} /* sdb_error_get_prio */ - -char * -sdb_strerror(int errnum, char *strerrbuf, size_t buflen) -{ -#if STRERROR_R_CHAR_P - { - char *tmp = strerror_r(errnum, strerrbuf, buflen); - if (*strerrbuf = '\0') { - if (tmp && (tmp != strerrbuf) && (*tmp != '\0')) - strncpy(strerrbuf, tmp, buflen); - else - snprintf(strerrbuf, buflen, "unknown error #%i " - "(strerror_r(3) did not return an error message)", - errnum); - } - } -#else - if (strerror_r(errnum, strerrbuf, buflen)) - snprintf(strerrbuf, buflen, "unknown error #%i " - "(strerror_r(3) failed)", errnum); -#endif - - strerrbuf[buflen - 1] = '\0'; - return strerrbuf; -} /* sdb_strerror */ - -/* vim: set tw=78 sw=4 ts=4 noexpandtab : */ - diff --git a/src/core/plugin.c b/src/core/plugin.c index 09d5cce..8200338 100644 --- a/src/core/plugin.c +++ b/src/core/plugin.c @@ -27,8 +27,8 @@ #include "sysdb.h" #include "core/plugin.h" -#include "core/error.h" #include "core/time.h" +#include "utils/error.h" #include "utils/llist.h" #include "utils/strbuf.h" diff --git a/src/core/store.c b/src/core/store.c index cf4d4a4..e9e0979 100644 --- a/src/core/store.c +++ b/src/core/store.c @@ -27,8 +27,8 @@ #include "sysdb.h" #include "core/store.h" -#include "core/error.h" #include "core/plugin.h" +#include "utils/error.h" #include "utils/llist.h" #include diff --git a/src/daemon/config.c b/src/daemon/config.c index beb0217..906f4c5 100644 --- a/src/daemon/config.c +++ b/src/daemon/config.c @@ -27,8 +27,8 @@ #include "sysdb.h" #include "core/plugin.h" -#include "core/error.h" #include "core/time.h" +#include "utils/error.h" #include "daemon/config.h" diff --git a/src/daemon/sysdbd.c b/src/daemon/sysdbd.c index 4fbf48f..21350f3 100644 --- a/src/daemon/sysdbd.c +++ b/src/daemon/sysdbd.c @@ -32,7 +32,7 @@ #include "sysdb.h" #include "core/plugin.h" #include "core/store.h" -#include "core/error.h" +#include "utils/error.h" #include "frontend/sock.h" @@ -171,6 +171,7 @@ 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 */ @@ -185,6 +186,8 @@ main(int argc, char **argv) struct sigaction sa_intterm; int status; + sdb_error_set_logger(sdb_plugin_log); + while (42) { int opt = getopt(argc, argv, "C:DhV"); @@ -281,6 +284,7 @@ main(int argc, char **argv) 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); } diff --git a/src/frontend/connection.c b/src/frontend/connection.c index 096a759..636396a 100644 --- a/src/frontend/connection.c +++ b/src/frontend/connection.c @@ -26,9 +26,9 @@ */ #include "sysdb.h" -#include "core/error.h" #include "core/object.h" #include "frontend/connection-private.h" +#include "utils/error.h" #include "utils/strbuf.h" #include "utils/proto.h" diff --git a/src/frontend/query.c b/src/frontend/query.c index fa493a6..b3bf05e 100644 --- a/src/frontend/query.c +++ b/src/frontend/query.c @@ -27,9 +27,9 @@ #include "sysdb.h" -#include "core/error.h" #include "core/store.h" #include "frontend/connection-private.h" +#include "utils/error.h" #include "utils/strbuf.h" #include diff --git a/src/frontend/sock.c b/src/frontend/sock.c index cac49e1..4cf1d79 100644 --- a/src/frontend/sock.c +++ b/src/frontend/sock.c @@ -26,12 +26,12 @@ */ #include "sysdb.h" -#include "core/error.h" #include "core/object.h" #include "frontend/connection-private.h" #include "frontend/sock.h" #include "utils/channel.h" +#include "utils/error.h" #include "utils/llist.h" #include "utils/strbuf.h" diff --git a/src/include/client/sock.h b/src/include/client/sock.h index e33f4d7..c88fc9a 100644 --- a/src/include/client/sock.h +++ b/src/include/client/sock.h @@ -31,6 +31,8 @@ #include "core/object.h" #include "core/data.h" +#include "frontend/proto.h" + #include "utils/strbuf.h" #include @@ -65,14 +67,14 @@ sdb_client_destroy(sdb_client_t *client); /* * sdb_client_connect: - * Connect to the client's address. + * Connect to the client's address using the specified username. * * Returns: * - 0 on success * - a negative value else */ int -sdb_client_connect(sdb_client_t *client); +sdb_client_connect(sdb_client_t *client, const char *username); /* * sdb_client_close: diff --git a/src/include/core/error.h b/src/include/core/error.h deleted file mode 100644 index 1a55c3b..0000000 --- a/src/include/core/error.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * SysDB - src/include/core/error.h - * 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. - */ - -/* - * SysDB error handling: - * Error handling in SysDB is done on a by-thread basis, that is, each thread - * will use its own memory region to store information about the last reported - * error. - * Once the error message has been passed to SysDB, it will log the entire - * message at once. The message will be sent to all registered log functions. - */ - -#ifndef SDB_CORE_ERROR_H -#define SDB_CORE_ERROR_H 1 - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* max length of any error message */ -#ifndef SDB_MAX_ERROR -# define SDB_MAX_ERROR 4096 -#endif /* ! SDB_MAX_ERROR */ - -/* On Linux systems and possibly others, this should be the same as the LOG_ - * constants defined by syslog. */ -enum { - SDB_LOG_EMERG = 0, - SDB_LOG_ERR = 3, - SDB_LOG_WARNING = 4, - SDB_LOG_NOTICE = 5, - SDB_LOG_INFO = 6, - SDB_LOG_DEBUG = 7, -}; -#define SDB_LOG_PRIO_TO_STRING(prio) \ - (((prio) == SDB_LOG_EMERG) ? "EMERG" \ - : ((prio) == SDB_LOG_ERR) ? "ERROR" \ - : ((prio) == SDB_LOG_WARNING) ? "WARNING" \ - : ((prio) == SDB_LOG_NOTICE) ? "NOTICE" \ - : ((prio) == SDB_LOG_INFO) ? "INFO" \ - : ((prio) == SDB_LOG_DEBUG) ? "DEBUG" : "UNKNOWN") - -/* - * sdb_log: - * Log the specified message. The string will be formatted in printf-style - * using the specified format and arguments and logged with the specified - * priority. In addition, the error message will be stored as the current - * error message. This function is basically the same as calling sdb_error_set - * and sdb_error_log. XXX: SDB_LOG_EMERG might, at some point and/or depending - * on configuration, try a clean shut-down of the process. - */ -int -sdb_log(int prio, const char *fmt, ...); - -/* - * sdb_error_set, sdb_error_append: - * Compose the current error message. The string will be formatted in printf- - * style using the specified format and arguments. No automatic logging will - * be done. - */ -int -sdb_error_set(const char *fmt, ...); -int -sdb_error_append(const char *fmt, ...); - -/* - * sdb_error_chomp: - * Remove all consecutive newline characters at the end of the error message. - */ -int -sdb_error_chomp(void); - -/* - * sdb_error_log: - * Log the current error message with the specified priority. See sdb_log for - * more information. - */ -int -sdb_error_log(int prio); - -/* - * sdb_error_get: - * Get the current error message. The string returned by this function is - * owned by SysDB and might point to static memory -- do not modify or free - * it. - */ -const char * -sdb_error_get(void); - -/* - * sdb_error_get_prio: - * Get the priority of the last logged error message -- see the SDB_LOG_ - * constants for details. - */ -int -sdb_error_get_prio(void); - -/* - * sdb_strerror: - * This is a wrapper around the system's strerror function which ensures that - * a pointer to the formatted error message is returned. - */ -char * -sdb_strerror(int errnum, char *strerrbuf, size_t buflen); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* ! SDB_CORE_ERROR_H */ - -/* vim: set tw=78 sw=4 ts=4 noexpandtab : */ - diff --git a/src/include/frontend/connection.h b/src/include/frontend/connection.h index 955180f..a2163bc 100644 --- a/src/include/frontend/connection.h +++ b/src/include/frontend/connection.h @@ -28,6 +28,7 @@ #ifndef SDB_FRONTEND_CONNECTION_H #define SDB_FRONTEND_CONNECTION_H 1 +#include "frontend/proto.h" #include "utils/strbuf.h" #include @@ -36,23 +37,6 @@ extern "C" { #endif -/* status codes returned to a client */ -typedef enum { - CONNECTION_OK = 0, - CONNECTION_ERROR -} sdb_conn_status_t; - -/* accepted commands / state of the connection */ -typedef enum { - /* connection handling */ - CONNECTION_IDLE = 0, - CONNECTION_PING, - CONNECTION_STARTUP, - - /* querying */ - CONNECTION_LIST, -} sdb_conn_state_t; - typedef struct sdb_conn sdb_conn_t; /* diff --git a/src/include/frontend/proto.h b/src/include/frontend/proto.h new file mode 100644 index 0000000..1d02151 --- /dev/null +++ b/src/include/frontend/proto.h @@ -0,0 +1,59 @@ +/* + * SysDB - src/include/frontend/proto.h + * 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. + */ + +#ifndef SDB_FRONTEND_PROTO_H +#define SDB_FRONTEND_PROTO_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* status codes returned to a client */ +typedef enum { + CONNECTION_OK = 0, + CONNECTION_ERROR +} sdb_conn_status_t; + +/* accepted commands / state of the connection */ +typedef enum { + /* connection handling */ + CONNECTION_IDLE = 0, + CONNECTION_PING, + CONNECTION_STARTUP, + + /* querying */ + CONNECTION_LIST, +} sdb_conn_state_t; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* ! SDB_FRONTEND_PROTO_H */ + +/* vim: set tw=78 sw=4 ts=4 noexpandtab : */ + diff --git a/src/include/utils/error.h b/src/include/utils/error.h new file mode 100644 index 0000000..e170a7d --- /dev/null +++ b/src/include/utils/error.h @@ -0,0 +1,148 @@ +/* + * SysDB - src/include/utils/error.h + * 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. + */ + +/* + * SysDB error handling: + * Error handling in SysDB is done on a by-thread basis, that is, each thread + * will use its own memory region to store information about the last reported + * error. + * Once the error message has been passed to SysDB, it will log the entire + * message at once. The message will be sent to all registered log functions. + */ + +#ifndef SDB_UTILS_ERROR_H +#define SDB_UTILS_ERROR_H 1 + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* max length of any error message */ +#ifndef SDB_MAX_ERROR +# define SDB_MAX_ERROR 4096 +#endif /* ! SDB_MAX_ERROR */ + +/* On Linux systems and possibly others, this should be the same as the LOG_ + * constants defined by syslog. */ +enum { + SDB_LOG_EMERG = 0, + SDB_LOG_ERR = 3, + SDB_LOG_WARNING = 4, + SDB_LOG_NOTICE = 5, + SDB_LOG_INFO = 6, + SDB_LOG_DEBUG = 7, +}; +#define SDB_LOG_PRIO_TO_STRING(prio) \ + (((prio) == SDB_LOG_EMERG) ? "EMERG" \ + : ((prio) == SDB_LOG_ERR) ? "ERROR" \ + : ((prio) == SDB_LOG_WARNING) ? "WARNING" \ + : ((prio) == SDB_LOG_NOTICE) ? "NOTICE" \ + : ((prio) == SDB_LOG_INFO) ? "INFO" \ + : ((prio) == SDB_LOG_DEBUG) ? "DEBUG" : "UNKNOWN") + +/* + * sdb_error_set_logger: + * Set the logging callback to be used for logging messages. By default (or + * when explicitely setting the logger to NULL), logs will be written to the + * stderr channel. + */ +void +sdb_error_set_logger(int (*f)(int, const char *)); + +/* + * sdb_log: + * Log the specified message. The string will be formatted in printf-style + * using the specified format and arguments and logged with the specified + * priority. In addition, the error message will be stored as the current + * error message. This function is basically the same as calling sdb_error_set + * and sdb_error_log. XXX: SDB_LOG_EMERG might, at some point and/or depending + * on configuration, try a clean shut-down of the process. + */ +int +sdb_log(int prio, const char *fmt, ...); + +/* + * sdb_error_set, sdb_error_append: + * Compose the current error message. The string will be formatted in printf- + * style using the specified format and arguments. No automatic logging will + * be done. + */ +int +sdb_error_set(const char *fmt, ...); +int +sdb_error_append(const char *fmt, ...); + +/* + * sdb_error_chomp: + * Remove all consecutive newline characters at the end of the error message. + */ +int +sdb_error_chomp(void); + +/* + * sdb_error_log: + * Log the current error message with the specified priority. See sdb_log for + * more information. + */ +int +sdb_error_log(int prio); + +/* + * sdb_error_get: + * Get the current error message. The string returned by this function is + * owned by SysDB and might point to static memory -- do not modify or free + * it. + */ +const char * +sdb_error_get(void); + +/* + * sdb_error_get_prio: + * Get the priority of the last logged error message -- see the SDB_LOG_ + * constants for details. + */ +int +sdb_error_get_prio(void); + +/* + * sdb_strerror: + * This is a wrapper around the system's strerror function which ensures that + * a pointer to the formatted error message is returned. + */ +char * +sdb_strerror(int errnum, char *strerrbuf, size_t buflen); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* ! SDB_UTILS_ERROR_H */ + +/* vim: set tw=78 sw=4 ts=4 noexpandtab : */ + diff --git a/src/plugins/cname/dns.c b/src/plugins/cname/dns.c index d989e52..6f5d518 100644 --- a/src/plugins/cname/dns.c +++ b/src/plugins/cname/dns.c @@ -27,7 +27,7 @@ #include "sysdb.h" #include "core/plugin.h" -#include "core/error.h" +#include "utils/error.h" #include #include diff --git a/src/plugins/syslog.c b/src/plugins/syslog.c index b548988..a487521 100644 --- a/src/plugins/syslog.c +++ b/src/plugins/syslog.c @@ -27,7 +27,7 @@ #include "sysdb.h" #include "core/plugin.h" -#include "core/error.h" +#include "utils/error.h" #include #include diff --git a/src/utils/dbi.c b/src/utils/dbi.c index db93857..2692618 100644 --- a/src/utils/dbi.c +++ b/src/utils/dbi.c @@ -25,8 +25,8 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "core/error.h" #include "utils/dbi.h" +#include "utils/error.h" #include diff --git a/src/utils/error.c b/src/utils/error.c new file mode 100644 index 0000000..6bf64c2 --- /dev/null +++ b/src/utils/error.c @@ -0,0 +1,295 @@ +/* + * SysDB - src/utils/error.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. + */ + +#include "utils/error.h" +#include "utils/strbuf.h" + +#include + +#include +#include +#include + +#include + +/* + * private data types + */ + +typedef struct { + int prio; + sdb_strbuf_t *msg; + _Bool logged; +} sdb_error_ctx_t; +#define SDB_ERROR_INIT { -1, NULL, 1 } + +/* + * private variables + */ + +static sdb_error_ctx_t default_error_ctx = SDB_ERROR_INIT; + +static pthread_key_t error_ctx_key; +static _Bool error_ctx_key_initialized = 0; + +static int (*logger)(int prio, const char *msg) = NULL; + +/* + * private helper functions + */ + +static void +sdb_error_ctx_destructor(void *p) +{ + sdb_error_ctx_t *ctx = p; + + if (! ctx) + return; + + sdb_strbuf_destroy(ctx->msg); + free(ctx); +} /* sdb_error_ctx_destructor */ + +static void +sdb_error_ctx_init(void) +{ + if (error_ctx_key_initialized) + return; + + pthread_key_create(&error_ctx_key, sdb_error_ctx_destructor); + error_ctx_key_initialized = 1; +} /* sdb_error_init */ + +static sdb_error_ctx_t * +sdb_error_ctx_create(void) +{ + sdb_error_ctx_t *ctx; + + ctx = malloc(sizeof(*ctx)); + if (! ctx) + return NULL; + + *ctx = default_error_ctx; + ctx->msg = sdb_strbuf_create(64); + if (! ctx->msg) { + free(ctx); + return NULL; + } + + if (! error_ctx_key_initialized) + sdb_error_ctx_init(); + pthread_setspecific(error_ctx_key, ctx); + return ctx; +} /* sdb_error_ctx_create */ + +static sdb_error_ctx_t * +sdb_error_get_ctx(void) +{ + sdb_error_ctx_t *ctx; + + if (! error_ctx_key_initialized) + sdb_error_ctx_init(); + ctx = pthread_getspecific(error_ctx_key); + + if (! ctx) + ctx = sdb_error_ctx_create(); + if (! ctx) + return NULL; + return ctx; +} /* sdb_error_get_ctx */ + +static int +sdb_error_vprintf(const char *fmt, va_list ap) +{ + sdb_error_ctx_t *ctx; + + ctx = sdb_error_get_ctx(); + if (! ctx) + return -1; + + ctx->logged = 0; + return (int)sdb_strbuf_vsprintf(ctx->msg, fmt, ap); +} /* sdb_error_vprintf */ + +static int +sdb_error_vappend(const char *fmt, va_list ap) +{ + sdb_error_ctx_t *ctx; + + ctx = sdb_error_get_ctx(); + if (! ctx) + return -1; + + ctx->logged = 0; + return (int)sdb_strbuf_vappend(ctx->msg, fmt, ap); +} /* sdb_error_vappend */ + +static int +sdb_do_log(int prio) +{ + sdb_error_ctx_t *ctx; + int ret; + + ctx = sdb_error_get_ctx(); + if (! ctx) + return -1; + + if (prio >= 0) + ctx->prio = prio; + + if (ctx->logged) + return 0; + + if (logger) + ret = logger(prio, sdb_strbuf_string(ctx->msg)); + else + ret = fprintf(stderr, "[%s] %s\n", SDB_LOG_PRIO_TO_STRING(prio), + sdb_strbuf_string(ctx->msg)); + + ctx->logged = 1; + return ret; +} /* sdb_do_log */ + +/* + * public API + */ + +void +sdb_error_set_logger(int (*f)(int, const char *)) +{ + logger = f; +} /* sdb_error_set_logger */ + +int +sdb_log(int prio, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = sdb_error_vprintf(fmt, ap); + va_end(ap); + + if (ret > 0) + sdb_do_log(prio); + return ret; +} /* sdb_log */ + +int +sdb_error_set(const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = sdb_error_vprintf(fmt, ap); + va_end(ap); + + return ret; +} /* sdb_error_set */ + +int +sdb_error_append(const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = sdb_error_vappend(fmt, ap); + va_end(ap); + + return ret; +} /* sdb_error_append */ + +int +sdb_error_chomp(void) +{ + sdb_error_ctx_t *ctx; + + ctx = sdb_error_get_ctx(); + if (! ctx) + return -1; + + sdb_strbuf_chomp(ctx->msg); + return 0; +} /* sdb_error_chomp */ + +int +sdb_error_log(int prio) +{ + return sdb_do_log(prio); +} /* sdb_error_log */ + +const char * +sdb_error_get(void) +{ + sdb_error_ctx_t *ctx; + + ctx = sdb_error_get_ctx(); + if (! ctx) + return "success"; + return sdb_strbuf_string(ctx->msg); +} /* sdb_error_get */ + +int +sdb_error_get_prio(void) +{ + sdb_error_ctx_t *ctx; + + ctx = sdb_error_get_ctx(); + if (! ctx) + return -1; + return ctx->prio; +} /* sdb_error_get_prio */ + +char * +sdb_strerror(int errnum, char *strerrbuf, size_t buflen) +{ +#if STRERROR_R_CHAR_P + { + char *tmp = strerror_r(errnum, strerrbuf, buflen); + if (*strerrbuf = '\0') { + if (tmp && (tmp != strerrbuf) && (*tmp != '\0')) + strncpy(strerrbuf, tmp, buflen); + else + snprintf(strerrbuf, buflen, "unknown error #%i " + "(strerror_r(3) did not return an error message)", + errnum); + } + } +#else + if (strerror_r(errnum, strerrbuf, buflen)) + snprintf(strerrbuf, buflen, "unknown error #%i " + "(strerror_r(3) failed)", errnum); +#endif + + strerrbuf[buflen - 1] = '\0'; + return strerrbuf; +} /* sdb_strerror */ + +/* vim: set tw=78 sw=4 ts=4 noexpandtab : */ + diff --git a/src/utils/proto.c b/src/utils/proto.c index e9e3e6c..29783ef 100644 --- a/src/utils/proto.c +++ b/src/utils/proto.c @@ -25,8 +25,8 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "utils/error.h" #include "utils/proto.h" -#include "core/error.h" #include #include @@ -106,7 +106,7 @@ sdb_proto_get_int(sdb_strbuf_t *buf, size_t offset) return UINT32_MAX; /* not enough data to read */ - if (offset + sizeof(uint32_t) < sdb_strbuf_len(buf)) + if (offset + sizeof(uint32_t) > sdb_strbuf_len(buf)) return UINT32_MAX; data = sdb_strbuf_string(buf); diff --git a/src/utils/unixsock.c b/src/utils/unixsock.c index 256cf9f..59bf563 100644 --- a/src/utils/unixsock.c +++ b/src/utils/unixsock.c @@ -25,8 +25,8 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "utils/error.h" #include "utils/unixsock.h" -#include "core/error.h" #include #include