X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Futils%2Fproto.c;h=b5cfe04700c52793388f4d3d62bc40dec1674b83;hb=ebeb14d9215ce017340525214728e4bc62bd1d67;hp=404d2a30ec5d2dabd270ab393bd9e262ec429017;hpb=0e9ae0a6da794b4c6f514c123d2a0ab9527ad592;p=sysdb.git diff --git a/src/utils/proto.c b/src/utils/proto.c index 404d2a3..b5cfe04 100644 --- a/src/utils/proto.c +++ b/src/utils/proto.c @@ -42,126 +42,59 @@ * 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 (ssize_t)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 : */