From 2df0d2d5c79582e1dce5cdedede9ac564a6f126b Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Wed, 4 Dec 2013 11:06:39 +0100 Subject: [PATCH] utils proto: Added utility functions for protocol handling. So far, added functions to send data to an open file descriptor and use that in the frontend code. --- src/Makefile.am | 2 + src/frontend/connection.c | 47 ++++--------------- src/include/utils/proto.h | 52 +++++++++++++++++++++ src/utils/proto.c | 98 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 161 insertions(+), 38 deletions(-) create mode 100644 src/include/utils/proto.h create mode 100644 src/utils/proto.c diff --git a/src/Makefile.am b/src/Makefile.am index 5a15f9b..e4695cd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -26,6 +26,7 @@ pkgutilsinclude_HEADERS = \ include/utils/channel.h \ include/utils/dbi.h \ include/utils/llist.h \ + include/utils/proto.h \ include/utils/strbuf.h \ include/utils/unixsock.h @@ -45,6 +46,7 @@ libsysdb_la_SOURCES = \ 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 diff --git a/src/frontend/connection.c b/src/frontend/connection.c index 962cd9c..dbc0f4e 100644 --- a/src/frontend/connection.c +++ b/src/frontend/connection.c @@ -30,6 +30,7 @@ #include "core/object.h" #include "frontend/connection-private.h" #include "utils/strbuf.h" +#include "utils/proto.h" #include #include @@ -301,50 +302,20 @@ ssize_t 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/utils/proto.h b/src/include/utils/proto.h new file mode 100644 index 0000000..8ab2e1e --- /dev/null +++ b/src/include/utils/proto.h @@ -0,0 +1,52 @@ +/* + * SysDB - src/include/utils/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_UTILS_PROTO_H +#define SDB_UTILS_PROTO_H 1 + +#include +#include + +#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); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* ! SDB_UTILS_PROTO_H */ + +/* vim: set tw=78 sw=4 ts=4 noexpandtab : */ + diff --git a/src/utils/proto.c b/src/utils/proto.c new file mode 100644 index 0000000..d049144 --- /dev/null +++ b/src/utils/proto.c @@ -0,0 +1,98 @@ +/* + * SysDB - src/utils/proto.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/proto.h" +#include "core/error.h" + +#include +#include + +#include +#include + +/* + * 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 */ + +/* vim: set tw=78 sw=4 ts=4 noexpandtab : */ + -- 2.30.2