From d25f3c59b5cf5387acd4e6d1467ce9efffa40f9a Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Mon, 29 Dec 2014 16:53:44 +0100 Subject: [PATCH] proto: Let unmarshal functions return the number of bytes processed. That's a more flexible and straight-forward interface allowing callers to not care about the size of the expected data. --- src/client/sock.c | 7 ++++--- src/frontend/connection.c | 2 +- src/frontend/query.c | 20 ++++++++++---------- src/include/utils/proto.h | 12 ++++++++---- src/tools/sysdb/command.c | 4 ++-- src/utils/proto.c | 21 ++++++++++++--------- 6 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/client/sock.c b/src/client/sock.c index bed6fc0..0d734f3 100644 --- a/src/client/sock.c +++ b/src/client/sock.c @@ -306,12 +306,13 @@ sdb_client_recv(sdb_client_t *client, if (rstatus == UINT32_MAX) { const char *str = sdb_strbuf_string(buf) + data_offset; size_t len = sdb_strbuf_len(buf) - data_offset; + ssize_t n; /* retrieve status and data len */ assert(len >= 2 * sizeof(uint32_t)); - rstatus = sdb_proto_unmarshal_int32(str, len); - rlen = sdb_proto_unmarshal_int32(str + sizeof(rstatus), - len - sizeof(rstatus)); + n = sdb_proto_unmarshal_int32(str, len, &rstatus); + str += n; len -= (size_t)n; + sdb_proto_unmarshal_int32(str, len, &rlen); if (! rlen) break; diff --git a/src/frontend/connection.c b/src/frontend/connection.c index 14e5336..91a9710 100644 --- a/src/frontend/connection.c +++ b/src/frontend/connection.c @@ -357,7 +357,7 @@ command_init(sdb_conn_t *conn) sdb_strbuf_clear(conn->errbuf); if (sdb_proto_unmarshal_header(SDB_STRBUF_STR(conn->buf), - &conn->cmd, &conn->cmd_len)) + &conn->cmd, &conn->cmd_len) < 0) return -1; sdb_strbuf_skip(conn->buf, 0, 2 * sizeof(uint32_t)); diff --git a/src/frontend/query.c b/src/frontend/query.c index 933ca04..63ec226 100644 --- a/src/frontend/query.c +++ b/src/frontend/query.c @@ -119,7 +119,7 @@ int sdb_fe_fetch(sdb_conn_t *conn) { char name[conn->cmd_len + 1]; - int type; + uint32_t type; if ((! conn) || (conn->cmd != SDB_CONNECTION_FETCH)) return -1; @@ -132,24 +132,24 @@ sdb_fe_fetch(sdb_conn_t *conn) return -1; } - type = sdb_proto_unmarshal_int32(SDB_STRBUF_STR(conn->buf)); + sdb_proto_unmarshal_int32(SDB_STRBUF_STR(conn->buf), &type); strncpy(name, sdb_strbuf_string(conn->buf) + sizeof(uint32_t), conn->cmd_len - sizeof(uint32_t)); name[sizeof(name) - 1] = '\0'; /* TODO: support other types besides hosts */ - return sdb_fe_exec_fetch(conn, type, name, NULL, /* filter = */ NULL); + return sdb_fe_exec_fetch(conn, (int)type, name, NULL, /* filter = */ NULL); } /* sdb_fe_fetch */ int sdb_fe_list(sdb_conn_t *conn) { - int type = SDB_HOST; + uint32_t type = SDB_HOST; if ((! conn) || (conn->cmd != SDB_CONNECTION_LIST)) return -1; if (conn->cmd_len == sizeof(uint32_t)) - type = sdb_proto_unmarshal_int32(SDB_STRBUF_STR(conn->buf)); + sdb_proto_unmarshal_int32(SDB_STRBUF_STR(conn->buf), &type); else if (conn->cmd_len) { sdb_log(SDB_LOG_ERR, "frontend: Invalid command length %d for " "LIST command", conn->cmd_len); @@ -157,7 +157,7 @@ sdb_fe_list(sdb_conn_t *conn) conn->cmd_len); return -1; } - return sdb_fe_exec_list(conn, type, /* filter = */ NULL); + return sdb_fe_exec_list(conn, (int)type, /* filter = */ NULL); } /* sdb_fe_list */ int @@ -167,7 +167,7 @@ sdb_fe_lookup(sdb_conn_t *conn) const char *matcher; size_t matcher_len; - int type; + uint32_t type; int status; conn_matcher_t m_node = { @@ -188,7 +188,7 @@ sdb_fe_lookup(sdb_conn_t *conn) conn->cmd_len); return -1; } - type = sdb_proto_unmarshal_int32(SDB_STRBUF_STR(conn->buf)); + sdb_proto_unmarshal_int32(SDB_STRBUF_STR(conn->buf), &type); matcher = sdb_strbuf_string(conn->buf) + sizeof(uint32_t); matcher_len = conn->cmd_len - sizeof(uint32_t); @@ -203,7 +203,7 @@ sdb_fe_lookup(sdb_conn_t *conn) return -1; } - node.type = type; + node.type = (int)type; m_node.matcher = m; /* run analyzer separately; parse_matcher is missing @@ -220,7 +220,7 @@ sdb_fe_lookup(sdb_conn_t *conn) status = -1; } else - status = sdb_fe_exec_lookup(conn, type, m, /* filter = */ NULL); + status = sdb_fe_exec_lookup(conn, (int)type, m, /* filter = */ NULL); sdb_object_deref(SDB_OBJ(m)); return status; } /* sdb_fe_lookup */ diff --git a/src/include/utils/proto.h b/src/include/utils/proto.h index fd842c1..a872dd5 100644 --- a/src/include/utils/proto.h +++ b/src/include/utils/proto.h @@ -133,19 +133,23 @@ sdb_proto_marshal_attribute(char *buf, size_t buf_len, * Read and decode a message header from the specified string. * * Returns: - * - 0 on success + * - the number of bytes read on success * - a negative value else */ -int +ssize_t sdb_proto_unmarshal_header(const char *buf, size_t buf_len, uint32_t *code, uint32_t *msg_len); /* * sdb_proto_unmarshal_int32: * Read and decode a 32-bit integer from the specified string. + * + * Returns: + * - the number of bytes read on success + * - a negative value else */ -uint32_t -sdb_proto_unmarshal_int32(const char *buf, size_t buf_len); +ssize_t +sdb_proto_unmarshal_int32(const char *buf, size_t buf_len, uint32_t *v); #ifdef __cplusplus } /* extern "C" */ diff --git a/src/tools/sysdb/command.c b/src/tools/sysdb/command.c index 2706dd2..c809c1f 100644 --- a/src/tools/sysdb/command.c +++ b/src/tools/sysdb/command.c @@ -49,9 +49,9 @@ static void log_printer(sdb_strbuf_t *buf) { - uint32_t prio = sdb_proto_unmarshal_int32(SDB_STRBUF_STR(buf)); + uint32_t prio = 0; - if (prio == UINT32_MAX) { + if (sdb_proto_unmarshal_int32(SDB_STRBUF_STR(buf), &prio) < 0) { sdb_log(SDB_LOG_WARNING, "Received a LOG message with invalid " "or missing priority"); prio = (uint32_t)SDB_LOG_ERR; diff --git a/src/utils/proto.c b/src/utils/proto.c index cd4e050..9cdc216 100644 --- a/src/utils/proto.c +++ b/src/utils/proto.c @@ -379,36 +379,39 @@ sdb_proto_marshal_attribute(char *buf, size_t buf_len, return len; } /* sdb_proto_marshal_attribute */ -int +ssize_t sdb_proto_unmarshal_header(const char *buf, size_t buf_len, uint32_t *code, uint32_t *msg_len) { uint32_t tmp; + ssize_t n; if (buf_len < 2 * sizeof(uint32_t)) return -1; - tmp = sdb_proto_unmarshal_int32(buf, buf_len); + n = sdb_proto_unmarshal_int32(buf, buf_len, &tmp); if (code) *code = tmp; - tmp = sdb_proto_unmarshal_int32(buf + sizeof(uint32_t), - buf_len - sizeof(uint32_t)); + buf += n; buf_len -= n; + sdb_proto_unmarshal_int32(buf, buf_len, &tmp); if (msg_len) *msg_len = tmp; - return 0; + return 2 * sizeof(uint32_t); } /* sdb_proto_unmarshal_header */ -uint32_t -sdb_proto_unmarshal_int32(const char *buf, size_t buf_len) +ssize_t +sdb_proto_unmarshal_int32(const char *buf, size_t buf_len, uint32_t *v) { uint32_t n; /* not enough data to read */ if (buf_len < sizeof(n)) - return UINT32_MAX; + return -1; memcpy(&n, buf, sizeof(n)); - return ntohl(n); + if (v) + *v = ntohl(n); + return sizeof(n); } /* sdb_proto_unmarshal_int32 */ /* vim: set tw=78 sw=4 ts=4 noexpandtab : */ -- 2.30.2