Code

utils/proto: Let all unmarshal functions accept strings instead of strbufs.
[sysdb.git] / src / utils / proto.c
index 26c4826a7f949a003d67932bd283cc59eff2befd..b5cfe04700c52793388f4d3d62bc40dec1674b83 100644 (file)
  * public API
  */
 
-int
-sdb_proto_select(int fd, int type)
-{
-       fd_set fds;
-       fd_set *readfds = NULL;
-       fd_set *writefds = NULL;
-       fd_set *exceptfds = NULL;
-
-       if (fd < 0) {
-               errno = EBADF;
-               return -1;
-       }
-
-       FD_ZERO(&fds);
-
-       switch (type) {
-               case SDB_PROTO_SELECTIN:
-                       readfds = &fds;
-                       break;
-               case SDB_PROTO_SELECTOUT:
-                       writefds = &fds;
-                       break;
-               case SDB_PROTO_SELECTERR:
-                       exceptfds = &fds;
-                       break;
-               default:
-                       errno = EINVAL;
-                       return -1;
-       }
-
-       FD_SET(fd, &fds);
-
-       while (42) {
-               int n;
-               errno = 0;
-               n = select(fd + 1, readfds, writefds, exceptfds, NULL);
-
-               if ((n < 0) && (errno != EINTR))
-                       return n;
-               if (n > 0)
-                       break;
-       }
-       return 0;
-} /* sdb_proto_select */
-
 ssize_t
-sdb_proto_send(int fd, size_t msg_len, const char *msg)
+sdb_proto_marshal(char *buf, size_t buf_len, uint32_t code,
+               uint32_t msg_len, const char *msg)
 {
-       const char *buf;
-       size_t len;
+       size_t len = 2 * sizeof(uint32_t) + msg_len;
+       uint32_t tmp;
 
-       if ((fd < 0) || (msg_len && (! msg)))
+       if (buf_len < 2 * sizeof(uint32_t))
                return -1;
-       if (! msg_len)
-               return 0;
-
-       buf = msg;
-       len = msg_len;
-       while (len > 0) {
-               ssize_t status;
-
-               if (sdb_proto_select(fd, SDB_PROTO_SELECTOUT))
-                       return -1;
+       if (buf_len < len) /* crop message */
+               msg_len -= (uint32_t)(len - buf_len);
 
-               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;
-       }
+       tmp = htonl(code);
+       memcpy(buf, &tmp, sizeof(tmp));
+       tmp = htonl(msg_len);
+       memcpy(buf + sizeof(tmp), &tmp, sizeof(tmp));
 
-       return (ssize_t)msg_len;
-} /* sdb_proto_send */
+       if (msg_len)
+               memcpy(buf + 2 * sizeof(tmp), msg, msg_len);
+       return len;
+} /* sdb_proto_marshal */
 
-ssize_t
-sdb_proto_send_msg(int fd, uint32_t code,
-               uint32_t msg_len, const char *msg)
+int
+sdb_proto_unmarshal_header(const char *buf, size_t buf_len,
+               uint32_t *code, uint32_t *msg_len)
 {
-       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 (buf_len < 2 * sizeof(uint32_t))
+               return -1;
 
+       tmp = sdb_proto_unmarshal_int(buf, buf_len);
+       if (code)
+               *code = tmp;
+       tmp = sdb_proto_unmarshal_int(buf + sizeof(uint32_t),
+                       buf_len - sizeof(uint32_t));
        if (msg_len)
-               memcpy(buffer + 2 * sizeof(tmp), msg, msg_len);
-
-       return sdb_proto_send(fd, len, buffer);
-} /* sdb_proto_send_msg */
+               *msg_len = tmp;
+       return 0;
+} /* sdb_proto_unmarshal_header */
 
 uint32_t
-sdb_proto_get_int(sdb_strbuf_t *buf, size_t offset)
+sdb_proto_unmarshal_int(const char *buf, size_t buf_len)
 {
-       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))
+       if (buf_len < sizeof(n))
                return UINT32_MAX;
 
-       data = sdb_strbuf_string(buf);
-       data += offset;
-       memcpy(&n, data, sizeof(n));
+       memcpy(&n, buf, sizeof(n));
        return ntohl(n);
-} /* sdb_proto_get_int */
+} /* sdb_proto_unmarshal_int */
 
 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */