diff --git a/src/utils/proto.c b/src/utils/proto.c
index d049144ca2716c7a493cab1be92f9fb698bde274..16007f2e5bd48d1ebe9a6d2958cdf8624c52f4fb 100644 (file)
--- a/src/utils/proto.c
+++ b/src/utils/proto.c
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "utils/error.h"
#include "utils/proto.h"
-#include "core/error.h"
#include <arpa/inet.h>
#include <errno.h>
+#include <limits.h>
+
#include <string.h>
#include <unistd.h>
+#include <sys/select.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,
+sdb_proto_marshal(char *buf, size_t buf_len, 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;
+ if (buf_len < 2 * sizeof(uint32_t))
+ return -1;
+ if (buf_len < len) /* crop message */
+ msg_len -= (uint32_t)(len - buf_len);
+
tmp = htonl(code);
- memcpy(buffer, &tmp, sizeof(tmp));
+ memcpy(buf, &tmp, sizeof(tmp));
tmp = htonl(msg_len);
- memcpy(buffer + sizeof(tmp), &tmp, sizeof(tmp));
+ memcpy(buf + sizeof(tmp), &tmp, sizeof(tmp));
if (msg_len)
- memcpy(buffer + 2 * sizeof(tmp), msg, msg_len);
+ memcpy(buf + 2 * sizeof(tmp), msg, msg_len);
+ return len;
+} /* sdb_proto_marshal */
+
+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;
- return sdb_proto_send(fd, len, buffer);
-} /* sdb_proto_send_msg */
+ 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 : */