author | Sebastian Harl <sh@tokkee.org> | |
Sat, 7 Dec 2013 15:23:44 +0000 (16:23 +0100) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Sat, 7 Dec 2013 15:23:44 +0000 (16:23 +0100) |
16 files changed:
.gitignore | patch | blob | history | |
doc/sysdbd.1.txt | patch | blob | history | |
doc/sysdbd.conf.5.txt | patch | blob | history | |
src/Makefile.am | patch | blob | history | |
src/client/client.c | [new file with mode: 0644] | patch | blob |
src/client/sock.c | [new file with mode: 0644] | patch | blob |
src/client/sysdb.c | [new file with mode: 0644] | patch | blob |
src/daemon/sysdbd.c | patch | blob | history | |
src/frontend/connection.c | patch | blob | history | |
src/include/client/sock.h | [new file with mode: 0644] | patch | blob |
src/include/client/sysdb.h.in | [new file with mode: 0644] | patch | blob |
src/include/utils/proto.h | [new file with mode: 0644] | patch | blob |
src/include/utils/strbuf.h | patch | blob | history | |
src/utils/proto.c | [new file with mode: 0644] | patch | blob |
src/utils/strbuf.c | patch | blob | history | |
t/utils/strbuf_test.c | patch | blob | history |
diff --git a/.gitignore b/.gitignore
index 0318b30ed8338665792dceea67fe99b7a00bb20a..63813b029f164e7c60eea3d0bc000b4a20644e55 100644 (file)
--- a/.gitignore
+++ b/.gitignore
*.la
*.lo
*.o
+sysdb
sysdbd
sysdbd.1
sysdbd.conf.5
diff --git a/doc/sysdbd.1.txt b/doc/sysdbd.1.txt
index 019ad9792192a525716f2647cd6cdc18f84a53cf..662241b278750ad41f280a765cfb4c809a6d0da2 100644 (file)
--- a/doc/sysdbd.1.txt
+++ b/doc/sysdbd.1.txt
The main configuration file. This file defines the behavior of *sysdbd* by
specifying default settings and the plugins to be loaded.
-*-d*::
- Daemonize on startup: Start *sysdbd* as a background process detached from
- the current terminal and session.
+*-D*::
+ Do not daemonize on startup: Rather than starting *sysdbd* as a background
+ process detached from the current terminal and session (the default), run
+ the process in the foreground. This allows easy monitoring of *sysdbd*.
*-h*::
Display a usage and help summary and exit.
COPYRIGHT
---------
-Copyright (C) 2012 Sebastian "tokkee" Harl <sh@tokkee.org>
+Copyright (C) 2012-2013 Sebastian "tokkee" Harl <sh@tokkee.org>
This is free software under the terms of the BSD license, see the source for
copying conditions. There is NO WARRANTY; not even for MERCHANTABILITY or
diff --git a/doc/sysdbd.conf.5.txt b/doc/sysdbd.conf.5.txt
index dd947310070d00b4b1bd2836d0777ae0b6769331..131c75548d05a2e846a6c83f1c92979717652857 100644 (file)
--- a/doc/sysdbd.conf.5.txt
+++ b/doc/sysdbd.conf.5.txt
COPYRIGHT
---------
-Copyright (C) 2012 Sebastian "tokkee" Harl <sh@tokkee.org>
+Copyright (C) 2012-2013 Sebastian "tokkee" Harl <sh@tokkee.org>
This is free software under the terms of the BSD license, see the source for
copying conditions. There is NO WARRANTY; not even for MERCHANTABILITY or
diff --git a/src/Makefile.am b/src/Makefile.am
index 5a15f9bdb2a35dea9382bebcadf3928549fb1f2d..724bfaae7a7e45c8fa15179d5a9c6cf5475f6c4a 100644 (file)
--- a/src/Makefile.am
+++ b/src/Makefile.am
AM_CPPFLAGS += -DLOCALSTATEDIR='"${localstatedir}"'
AM_CPPFLAGS += -DPKGLIBDIR='"${pkglibdir}"'
-BUILT_SOURCES = include/sysdb.h
+BUILT_SOURCES = include/client/sysdb.h include/sysdb.h
pkginclude_HEADERS = include/sysdb.h
pkgcoreincludedir = $(pkgincludedir)/core
include/utils/channel.h \
include/utils/dbi.h \
include/utils/llist.h \
+ include/utils/proto.h \
include/utils/strbuf.h \
include/utils/unixsock.h
-lib_LTLIBRARIES = libsysdb.la
+pkgclientincludedir = $(pkgincludedir)/client
+pkgclientinclude_HEADERS = \
+ include/client/sock.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/proto.c include/utils/proto.h \
+ utils/strbuf.c include/utils/strbuf.h
+libsysdbclient_la_CFLAGS = $(AM_CFLAGS)
+libsysdbclient_la_CPPFLAGS = $(AM_CPPFLAGS) $(LTDLINCL)
+libsysdbclient_la_LDFLAGS = -version-info 0:0:0 -pthread
+libsysdbclient_la_LIBADD = $(LIBLTDL)
libsysdb_la_SOURCES = \
sysdb.c include/sysdb.h \
frontend/query.c \
utils/channel.c include/utils/channel.h \
utils/llist.c include/utils/llist.h \
+ utils/proto.c include/utils/proto.h \
utils/strbuf.c include/utils/strbuf.h \
core/time.c include/core/time.h \
utils/unixsock.c include/utils/unixsock.h
libsysdb_la_LIBADD += -ldbi
endif
-bin_PROGRAMS = sysdbd
+bin_PROGRAMS = sysdb sysdbd
+
+sysdb_SOURCES = client/sysdb.c include/client/sysdb.h
+sysdb_CFLAGS = $(AM_CFLAGS) -DBUILD_DATE="\"$$( date --utc '+%F %T' ) (UTC)\""
+sysdb_LDADD = libsysdbclient.la
sysdbd_SOURCES = daemon/sysdbd.c include/sysdb.h \
daemon/config.c include/daemon/config.h
libsysdb_la_DEPENDENCIES += plugins/cname/dns.la
endif
+include/client/sysdb.h: include/client/sysdb.h.in ../version
+ source ../version; sed \
+ -e "s/@SDB_VERSION_MAJOR@/$$VERSION_MAJOR/g" \
+ -e "s/@SDB_VERSION_MINOR@/$$VERSION_MINOR/g" \
+ -e "s/@SDB_VERSION_PATCH@/$$VERSION_PATCH/g" \
+ -e "s/@SDB_VERSION_EXTRA@/$$VERSION_EXTRA/g" \
+ -e "s/@SDB_VERSION_STRING@/$$VERSION_STRING/g" \
+ include/client/sysdb.h.in > include/client/sysdb.h
+
include/sysdb.h: include/sysdb.h.in ../version
source ../version; sed \
-e "s/@SDB_VERSION_MAJOR@/$$VERSION_MAJOR/g" \
diff --git a/src/client/client.c b/src/client/client.c
--- /dev/null
+++ b/src/client/client.c
@@ -0,0 +1,53 @@
+/*
+ * SysDB - src/client/client.c
+ * Copyright (C) 2013 Sebastian 'tokkee' Harl <sh@tokkee.org>
+ * 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 "client/sysdb.h"
+
+/*
+ * public API
+ */
+
+unsigned int
+sdb_client_version(void)
+{
+ return SDB_CLIENT_VERSION;
+} /* sdb_client_version */
+
+const char *
+sdb_client_version_string(void)
+{
+ return SDB_CLIENT_VERSION_STRING;
+} /* sdb_client_version_string */
+
+const char *
+sdb_client_version_extra(void)
+{
+ return SDB_CLIENT_VERSION_EXTRA;
+} /* sdb_client_version_extra */
+
+/* vim: set tw=78 sw=4 ts=4 noexpandtab : */
+
diff --git a/src/client/sock.c b/src/client/sock.c
--- /dev/null
+++ b/src/client/sock.c
@@ -0,0 +1,235 @@
+/*
+ * SysDB - src/client/sock.c
+ * Copyright (C) 2013 Sebastian 'tokkee' Harl <sh@tokkee.org>
+ * 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 "client/sock.h"
+#include "utils/strbuf.h"
+#include "utils/proto.h"
+
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <limits.h>
+
+#include <stdlib.h>
+
+#include <string.h>
+#include <strings.h>
+
+#include <unistd.h>
+
+#include <sys/socket.h>
+#include <sys/un.h>
+
+/*
+ * private data types
+ */
+
+struct sdb_client {
+ char *address;
+ int fd;
+};
+
+/*
+ * private helper functions
+ */
+
+static int
+connect_unixsock(sdb_client_t *client, const char *address)
+{
+ struct sockaddr_un sa;
+
+ client->fd = socket(AF_UNIX, SOCK_STREAM, /* protocol = */ 0);
+ if (client->fd < 0)
+ return -1;
+
+ sa.sun_family = AF_UNIX;
+ strncpy(sa.sun_path, address, sizeof(sa.sun_path));
+ sa.sun_path[sizeof(sa.sun_path) - 1] = '\0';
+
+ if (connect(client->fd, (struct sockaddr *)&sa, sizeof(sa))) {
+ sdb_client_close(client);
+ return -1;
+ }
+ return client->fd;
+} /* connect_unixsock */
+
+/*
+ * public API
+ */
+
+sdb_client_t *
+sdb_client_create(const char *address)
+{
+ sdb_client_t *client;
+
+ if (! address)
+ return NULL;
+
+ client = malloc(sizeof(*client));
+ if (! client)
+ return NULL;
+ memset(client, 0, sizeof(*client));
+ client->fd = -1;
+
+ client->address = strdup(address);
+ if (! client->address) {
+ sdb_client_destroy(client);
+ return NULL;
+ }
+
+ return client;
+} /* sdb_client_create */
+
+void
+sdb_client_destroy(sdb_client_t *client)
+{
+ if (! client)
+ return;
+
+ sdb_client_close(client);
+
+ if (client->address)
+ free(client->address);
+ client->address = NULL;
+
+ free(client);
+} /* sdb_client_destroy */
+
+int
+sdb_client_connect(sdb_client_t *client)
+{
+ if ((! client) || (! client->address))
+ return -1;
+
+ if (client->fd >= 0)
+ return -1;
+
+ if (!strncasecmp(client->address, "unix:", strlen("unix:")))
+ connect_unixsock(client, client->address + strlen("unix:"));
+ else if (*client->address == '/')
+ connect_unixsock(client, client->address);
+ else
+ return -1;
+
+ if (client->fd < 0)
+ return -1;
+ return 0;
+} /* sdb_client_connect */
+
+void
+sdb_client_close(sdb_client_t *client)
+{
+ if (! client)
+ return;
+
+ close(client->fd);
+ client->fd = -1;
+} /* sdb_client_close */
+
+ssize_t
+sdb_client_send(sdb_client_t *client,
+ uint32_t cmd, uint32_t msg_len, const char *msg)
+{
+ if ((! client) || (! client->fd))
+ return -1;
+
+ return sdb_proto_send_msg(client->fd, cmd, msg_len, msg);
+} /* sdb_client_send */
+
+ssize_t
+sdb_client_recv(sdb_client_t *client,
+ uint32_t *code, sdb_strbuf_t *buf)
+{
+ uint32_t rstatus = UINT32_MAX;
+ uint32_t rlen = UINT32_MAX;
+
+ size_t total = 0;
+ size_t req = 2 * sizeof(uint32_t);
+
+ size_t data_offset = sdb_strbuf_len(buf);
+
+ if ((! client) || (! client->fd) || (! buf)) {
+ errno = EBADF;
+ return -1;
+ }
+
+ if (code)
+ *code = UINT32_MAX;
+
+ while (42) {
+ ssize_t status;
+
+ /* XXX: use select */
+
+ errno = 0;
+ status = sdb_strbuf_read(buf, client->fd, req);
+ if (status < 0) {
+ if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
+ continue;
+ return status;
+ }
+ else if (! status) /* EOF */
+ break;
+
+ total += (size_t)status;
+
+ if (total != req)
+ continue;
+
+ if (rstatus == UINT32_MAX) {
+ /* retrieve status and data len */
+ rstatus = sdb_proto_get_int(buf, data_offset);
+ rlen = sdb_proto_get_int(buf, data_offset + sizeof(rstatus));
+
+ if (! rlen)
+ break;
+
+ req = (size_t)rlen;
+ total = 0;
+ }
+ else /* finished reading data */
+ break;
+ }
+
+ if (total != req) {
+ /* unexpected EOF; clear partially read data */
+ sdb_strbuf_skip(buf, data_offset, sdb_strbuf_len(buf));
+ return 0;
+ }
+
+ if (rstatus != UINT32_MAX)
+ /* remove status,len */
+ sdb_strbuf_skip(buf, data_offset, 2 * sizeof(rstatus));
+
+ if (code)
+ *code = rstatus;
+
+ return (ssize_t)total;
+} /* sdb_client_recv */
+
+/* vim: set tw=78 sw=4 ts=4 noexpandtab : */
+
diff --git a/src/client/sysdb.c b/src/client/sysdb.c
--- /dev/null
+++ b/src/client/sysdb.c
@@ -0,0 +1,115 @@
+/*
+ * SysDB - src/client/sysdb.c
+ * Copyright (C) 2013 Sebastian 'tokkee' Harl <sh@tokkee.org>
+ * 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"
+
+#if HAVE_LIBGEN_H
+# include <libgen.h>
+#else /* HAVE_LIBGEN_H */
+# define basename(path) (path)
+#endif /* ! HAVE_LIBGEN_H */
+
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <unistd.h>
+
+#ifndef DEFAULT_SOCKET
+# define DEFAULT_SOCKET "unix:"LOCALSTATEDIR"/run/sysdbd.sock"
+#endif
+
+static void
+exit_usage(char *name, int status)
+{
+ printf(
+"Usage: %s <options>\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 */
+
+int
+main(int argc, char **argv)
+{
+ while (42) {
+ int opt = getopt(argc, argv, "hV");
+
+ if (-1 == opt)
+ break;
+
+ switch (opt) {
+ 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);
+
+ printf("SysDB client "SDB_CLIENT_VERSION_STRING
+ SDB_CLIENT_VERSION_EXTRA"\n");
+ return 0;
+} /* main */
+
+/* vim: set tw=78 sw=4 ts=4 noexpandtab : */
+
diff --git a/src/daemon/sysdbd.c b/src/daemon/sysdbd.c
index 123314d3dfc0aa0e2fa73434ae3f3fc5bcd9bfb7..4fbf48f449b1eca24b4dc4bcdd7db346fe807da8 100644 (file)
--- a/src/daemon/sysdbd.c
+++ b/src/daemon/sysdbd.c
"\nOptions:\n"
" -C FILE the main configuration file\n"
" default: "CONFIGFILE"\n"
-" -d run in background (daemonize)\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"
{
printf("SysDBd version "SDB_VERSION_STRING SDB_VERSION_EXTRA", "
"built "BUILD_DATE"\n"
- "using libsysdb verion %s%s\n"
- "Copyright (C) 2012 "PACKAGE_MAINTAINER"\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 "
main(int argc, char **argv)
{
char *config_filename = NULL;
- _Bool do_daemonize = 0;
+ _Bool do_daemonize = 1;
pthread_t backend_thread;
int status;
while (42) {
- int opt = getopt(argc, argv, "C:dhV");
+ int opt = getopt(argc, argv, "C:DhV");
if (-1 == opt)
break;
case 'C':
config_filename = optarg;
break;
- case 'd':
- do_daemonize = 1;
+ case 'D':
+ do_daemonize = 0;
break;
case 'h':
index 962cd9cf8d9a14f9a3bc2f2a864e993958eb467d..096a7590444c3ef467372f606ee70dda9cdbbe72 100644 (file)
#include "core/object.h"
#include "frontend/connection-private.h"
#include "utils/strbuf.h"
+#include "utils/proto.h"
#include <assert.h>
#include <errno.h>
/* remove the command from the buffer */
if (conn->cmd_len)
- sdb_strbuf_skip(conn->buf, conn->cmd_len);
+ sdb_strbuf_skip(conn->buf, 0, conn->cmd_len);
conn->cmd = CONNECTION_IDLE;
conn->cmd_len = 0;
return status;
len = 2 * sizeof(uint32_t);
if (conn->cmd == CONNECTION_IDLE)
len += conn->cmd_len;
- sdb_strbuf_skip(conn->buf, len);
+ sdb_strbuf_skip(conn->buf, 0, len);
return 0;
} /* command_init */
sdb_connection_send(sdb_conn_t *conn, uint32_t code,
uint32_t msg_len, const char *msg)
{
- size_t len = 2 * sizeof(uint32_t) + msg_len;
- char buffer[len];
- char *buf;
-
- uint32_t tmp;
+ ssize_t status;
if ((! conn) || (conn->fd < 0))
return -1;
- tmp = htonl(code);
- memcpy(buffer, &tmp, sizeof(uint32_t));
-
- tmp = htonl(msg_len);
- memcpy(buffer + sizeof(uint32_t), &tmp, sizeof(uint32_t));
+ status = sdb_proto_send_msg(conn->fd, code, msg_len, msg);
+ if (status < 0) {
+ char errbuf[1024];
- if (msg_len)
- memcpy(buffer + 2 * sizeof(uint32_t), msg, msg_len);
-
- buf = buffer;
- while (len > 0) {
- ssize_t status;
-
- /* XXX: use select() */
-
- errno = 0;
- status = write(conn->fd, buf, len);
- if (status < 0) {
- char errbuf[1024];
-
- if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
- continue;
- if (errno == EINTR)
- continue;
-
- sdb_log(SDB_LOG_ERR, "frontend: Failed to send msg "
- "(code: %u, len: %u) to client: %s", code, msg_len,
- sdb_strerror(errno, errbuf, sizeof(errbuf)));
- return status;
- }
-
- len -= (size_t)status;
- buf += status;
+ sdb_log(SDB_LOG_ERR, "frontend: Failed to send msg "
+ "(code: %u, len: %u) to client: %s", code, msg_len,
+ sdb_strerror(errno, errbuf, sizeof(errbuf)));
}
- return (ssize_t)len;
+ return status;
} /* sdb_connection_send */
int
diff --git a/src/include/client/sock.h b/src/include/client/sock.h
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * SysDB - src/include/client/sock.h
+ * Copyright (C) 2013 Sebastian 'tokkee' Harl <sh@tokkee.org>
+ * 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_CLIENT_SOCK_H
+#define SDB_CLIENT_SOCK_H 1
+
+#include "core/object.h"
+#include "core/data.h"
+
+#include "utils/strbuf.h"
+
+#include <sys/socket.h>
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct sdb_client;
+typedef struct sdb_client sdb_client_t;
+
+/*
+ * sdb_client_create:
+ * Allocates and initializes a client object to connect to the specified
+ * address.
+ *
+ * Returns:
+ * - a new client object on success
+ * - NULL in case of an error
+ */
+sdb_client_t *
+sdb_client_create(const char *address);
+
+/*
+ * sdb_client_destroy:
+ * Destroyes the client connection and deallocates the client object.
+ */
+void
+sdb_client_destroy(sdb_client_t *client);
+
+/*
+ * sdb_client_connect:
+ * Connect to the client's address.
+ *
+ * Returns:
+ * - 0 on success
+ * - a negative value else
+ */
+int
+sdb_client_connect(sdb_client_t *client);
+
+/*
+ * sdb_client_close:
+ * Close the client connection.
+ */
+void
+sdb_client_close(sdb_client_t *client);
+
+/*
+ * sdb_client_send:
+ * Send the specified command and accompanying data to through the client
+ * connection.
+ *
+ * Returns:
+ * - 0 on success
+ * - a negative value else.
+ */
+ssize_t
+sdb_client_send(sdb_client_t *client,
+ uint32_t cmd, uint32_t data_len, const char *data);
+
+/*
+ * sdb_client_recv:
+ * Receive data from the connection. All data is written to the specified
+ * buffer. If specified, the returned status code is written to the memory
+ * location pointed to by 'code'. In case of an error or an incomplete
+ * command, the status code is set to UINT32_MAX. The returned data does not
+ * include the status code and message len as received from the remote side
+ * but only the data associated with the message.
+ *
+ * Returns:
+ * - the number of bytes read
+ * (may be zero if the message did not include any data)
+ * - a negative value on error
+ */
+ssize_t
+sdb_client_recv(sdb_client_t *client,
+ uint32_t *code, sdb_strbuf_t *buf);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* ! SDB_CLIENT_SOCK_H */
+
+/* vim: set tw=78 sw=4 ts=4 noexpandtab : */
+
diff --git a/src/include/client/sysdb.h.in b/src/include/client/sysdb.h.in
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * SysDB - src/include/client/sysdb.h
+ * Copyright (C) 2013 Sebastian 'tokkee' Harl <sh@tokkee.org>
+ * 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 CLIENT_SYSDB_H
+#define CLIENT_SYSDB_H 1
+
+#define SDB_CLIENT_VERSION_MAJOR @SDB_VERSION_MAJOR@
+#define SDB_CLIENT_VERSION_MINOR @SDB_VERSION_MINOR@
+#define SDB_CLIENT_VERSION_PATCH @SDB_VERSION_PATCH@
+
+#define SDB_CLIENT_VERSION_EXTRA "@SDB_VERSION_EXTRA@"
+
+#define SDB_CLIENT_VERSION_STRING "@SDB_VERSION_STRING@"
+
+#define SDB_CLIENT_VERSION_ENCODE(major, minor, patch) \
+ ((major) * 10000 + (minor) * 100 + (patch))
+#define SDB_CLIENT_VERSION_DECODE(version) \
+ (int)((version) / 10000), \
+ (int)((version) / 100) - (int)((version) / 10000) * 100, \
+ (int)(version) - (int)((version) / 100) * 100
+
+#define SDB_CLIENT_VERSION \
+ SDB_CLIENT_VERSION_ENCODE(SDB_CLIENT_VERSION_MAJOR, \
+ SDB_CLIENT_VERSION_MINOR, SDB_CLIENT_VERSION_PATCH)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+unsigned int
+sdb_client_version(void);
+
+const char *
+sdb_client_version_string(void);
+
+const char *
+sdb_client_version_extra(void);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* ! CLIENT_SYSDB_H */
+
+/* vim: set tw=78 sw=4 ts=4 noexpandtab : */
+
diff --git a/src/include/utils/proto.h b/src/include/utils/proto.h
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * SysDB - src/include/utils/proto.h
+ * Copyright (C) 2013 Sebastian 'tokkee' Harl <sh@tokkee.org>
+ * 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_UTILS_PROTO_H
+#define SDB_UTILS_PROTO_H 1
+
+#include "utils/strbuf.h"
+
+#include <stdint.h>
+#include <unistd.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ssize_t
+sdb_proto_send(int fd, size_t msg_len, const char *msg);
+
+ssize_t
+sdb_proto_send_msg(int fd, uint32_t code,
+ uint32_t msg_len, const char *msg);
+
+uint32_t
+sdb_proto_get_int(sdb_strbuf_t *buf, size_t offset);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* ! SDB_UTILS_PROTO_H */
+
+/* vim: set tw=78 sw=4 ts=4 noexpandtab : */
+
index 9577a64f2956ce0a600ea9498adc485cf892f2c8..900a4530511020ae9c5d8374b065c943922c23ad 100644 (file)
/*
* sdb_strbuf_skip:
- * Removes the first 'n' bytes from the buffer.
+ * Removes 'n' bytes from the buffer starting at offset 'offset'.
*/
void
-sdb_strbuf_skip(sdb_strbuf_t *strbuf, size_t n);
+sdb_strbuf_skip(sdb_strbuf_t *strbuf, size_t offset, size_t n);
/*
* sdb_strbuf_string:
diff --git a/src/utils/proto.c b/src/utils/proto.c
--- /dev/null
+++ b/src/utils/proto.c
@@ -0,0 +1,119 @@
+/*
+ * SysDB - src/utils/proto.c
+ * Copyright (C) 2013 Sebastian 'tokkee' Harl <sh@tokkee.org>
+ * 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/proto.h"
+#include "core/error.h"
+
+#include <arpa/inet.h>
+#include <errno.h>
+
+#include <limits.h>
+
+#include <string.h>
+#include <unistd.h>
+
+/*
+ * public API
+ */
+
+ssize_t
+sdb_proto_send(int fd, size_t msg_len, const char *msg)
+{
+ const char *buf;
+ size_t len;
+
+ if ((fd < 0) || (msg_len && (! msg)))
+ return -1;
+ if (! msg_len)
+ return 0;
+
+ buf = msg;
+ len = msg_len;
+ while (len > 0) {
+ ssize_t status;
+
+ /* XXX: use select() */
+
+ errno = 0;
+ status = write(fd, buf, len);
+ if (status < 0) {
+ if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
+ continue;
+ if (errno == EINTR)
+ continue;
+
+ return status;
+ }
+
+ len -= (size_t)status;
+ buf += status;
+ }
+
+ return (ssize_t)msg_len;
+} /* sdb_proto_send */
+
+ssize_t
+sdb_proto_send_msg(int fd, uint32_t code,
+ uint32_t msg_len, const char *msg)
+{
+ size_t len = 2 * sizeof(uint32_t) + msg_len;
+ char buffer[len];
+
+ uint32_t tmp;
+
+ tmp = htonl(code);
+ memcpy(buffer, &tmp, sizeof(tmp));
+ tmp = htonl(msg_len);
+ memcpy(buffer + sizeof(tmp), &tmp, sizeof(tmp));
+
+ if (msg_len)
+ memcpy(buffer + 2 * sizeof(tmp), msg, msg_len);
+
+ return sdb_proto_send(fd, len, buffer);
+} /* sdb_proto_send_msg */
+
+uint32_t
+sdb_proto_get_int(sdb_strbuf_t *buf, size_t offset)
+{
+ const char *data;
+ uint32_t n;
+
+ if (! buf)
+ return UINT32_MAX;
+
+ /* not enough data to read */
+ if (offset + sizeof(uint32_t) < sdb_strbuf_len(buf))
+ return UINT32_MAX;
+
+ data = sdb_strbuf_string(buf);
+ data += offset;
+ memcpy(&n, data, sizeof(n));
+ return ntohl(n);
+} /* sdb_proto_get_int */
+
+/* vim: set tw=78 sw=4 ts=4 noexpandtab : */
+
diff --git a/src/utils/strbuf.c b/src/utils/strbuf.c
index 77d19f044d71a1fec89ec629877d0deda5b3585d..6190e3a8a045a650c26067a0d637003bf321ded9 100644 (file)
--- a/src/utils/strbuf.c
+++ b/src/utils/strbuf.c
} /* sdb_strbuf_chomp */
void
-sdb_strbuf_skip(sdb_strbuf_t *strbuf, size_t n)
+sdb_strbuf_skip(sdb_strbuf_t *strbuf, size_t offset, size_t n)
{
+ char *start;
+ size_t len;
+
if ((! strbuf) || (! n))
return;
- if (n >= strbuf->pos) {
- strbuf->string[0] = '\0';
- strbuf->pos = 0;
+ if (offset >= strbuf->pos)
+ return;
+
+ len = strbuf->pos - offset;
+
+ if (n >= len) {
+ strbuf->string[offset] = '\0';
+ strbuf->pos = offset;
return;
}
- assert(n < strbuf->pos);
- memmove(strbuf->string, strbuf->string + n, strbuf->pos - n);
+ assert(offset + n < strbuf->pos);
+ assert(offset < strbuf->pos);
+
+ start = strbuf->string + offset;
+ memmove(start, start + n, strbuf->pos - n);
strbuf->pos -= n;
strbuf->string[strbuf->pos] = '\0';
} /* sdb_strbuf_skip */
diff --git a/t/utils/strbuf_test.c b/t/utils/strbuf_test.c
index d76c0f20adcdb9556ae8fa6910ea310cdf661ffa..c68a23efcf22df1157d2ac4adb02ceaf5f3b7f38 100644 (file)
--- a/t/utils/strbuf_test.c
+++ b/t/utils/strbuf_test.c
/* check that methods don't crash */
sdb_strbuf_destroy(b);
- sdb_strbuf_skip(b, 0);
- sdb_strbuf_skip(b, 10);
+ sdb_strbuf_skip(b, 0, 0);
+ sdb_strbuf_skip(b, 0, 10);
+ sdb_strbuf_skip(b, 10, 10);
/* check that methods return an error */
fail_unless(sdb_strbuf_vappend(b, "test", ap) < 0,
/* input is "1234567890" */
static struct {
+ size_t offset;
size_t n;
const char *expected;
size_t expected_len;
} skip_golden_data[] = {
- { 0, "1234567890", 10 },
- { 1, "234567890", 9 },
- { 2, "34567890", 8 },
- { 9, "0", 1 },
- { 10, "", 0 },
- { 11, "", 0 },
- { 100, "", 0 },
+ { 0, 0, "1234567890", 10 },
+ { 0, 1, "234567890", 9 },
+ { 0, 2, "34567890", 8 },
+ { 0, 9, "0", 1 },
+ { 0, 10, "", 0 },
+ { 0, 11, "", 0 },
+ { 0, 100, "", 0 },
+ { 1, 0, "1234567890", 10 },
+ { 1, 1, "134567890", 9 },
+ { 1, 2, "14567890", 8 },
+ { 8, 1, "123456780", 9 },
+ { 8, 2, "12345678", 8 },
+ { 8, 3, "12345678", 8 },
+ { 9, 1, "123456789", 9 },
+ { 9, 2, "123456789", 9 },
+ { 10, 1, "1234567890", 10 },
+ { 10, 2, "1234567890", 10 },
};
START_TEST(test_sdb_strbuf_skip)
size_t n;
sdb_strbuf_sprintf(buf, input);
- sdb_strbuf_skip(buf, skip_golden_data[i].n);
+ sdb_strbuf_skip(buf, skip_golden_data[i].offset,
+ skip_golden_data[i].n);
n = sdb_strbuf_len(buf);
fail_unless(n == skip_golden_data[i].expected_len,