diff options
Diffstat (limited to 'libsbus.c')
-rw-r--r-- | libsbus.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/libsbus.c b/libsbus.c new file mode 100644 index 0000000..bbd0b4f --- /dev/null +++ b/libsbus.c @@ -0,0 +1,86 @@ +/* See LICENSE file for copyright and license details. */ +#include "libsbus.h" +#include <sys/socket.h> +#include <errno.h> +#include <string.h> + +int +libsbus_subscribe(int fd, const char *pattern, char *buf) +{ + size_t n = strlen(pattern); + if (n + 4 > LIBSBUS_BUFFER_SIZE) { + errno = EMSGSIZE; + return -1; + } + buf[0] = 'S', buf[1] = 'U', buf[2] = 'B', buf[3] = ' '; + memcpy(&buf[4], pattern, n); + return -(send(fd, buf, n + 4, 0) < 0); +} + +int +libsbus_unsubscribe(int fd, const char *pattern, char *buf) +{ + size_t n = strlen(pattern); + if (n + 6 > LIBSBUS_BUFFER_SIZE) { + errno = EMSGSIZE; + return -1; + } + buf[0] = 'U', buf[1] = 'N', buf[2] = 'S', buf[3] = 'U', buf[4] = 'B', buf[5] = ' '; + memcpy(&buf[6], pattern, n); + return -(send(fd, buf, n + 6, 0) < 0); +} + +int +libsbus_publish(int fd, const char *key, const char *msg, size_t n, char *buf) +{ + size_t len = strlen(key) + 1; + if (len + n > LIBSBUS_BUFFER_SIZE - 4) { + errno = EMSGSIZE; + return -1; + } + buf[0] = 'M', buf[1] = 'S', buf[2] = 'G', buf[3] = ' '; + memcpy(&buf[4], key, len); + memcpy(&buf[4 + len], msg, n); + return -(send(fd, buf, len + n + 4, 0) < 0); +} + +ssize_t +libsbuf_prepare_message(const char *key, char *buf, size_t *remaining) +{ + size_t len = strlen(key) + 1; + if (len > LIBSBUS_BUFFER_SIZE - 4) { + errno = EMSGSIZE; + return -1; + } + buf[0] = 'M', buf[1] = 'S', buf[2] = 'G', buf[3] = ' '; + memcpy(&buf[4], key, len); + len += 4; + *remaining = LIBSBUS_BUFFER_SIZE - len; + return (ssize_t)len; +} + +int +libsbus_receive(int fd, char *buf, union libsbus_packet *packet) +{ + ssize_t r; + char *p; + + r = recv(fd, buf, LIBSBUS_BUFFER_SIZE, 0); + if (r < 0) + return -1; + + if (!strncmp(buf, "MSG ", 4)) { + p = memchr(buf, '\0', r); + if (!*p++) + goto unknown; + packet->type = LIBSBUS_MESSAGE; + packet->message.key = &buf[4]; + packet->message.msg = p; + packet->message.n = (size_t)(r - (p - buf)); + } else { + unknown: + packet->type = LIBSBUS_UNKNOWN; + packet->unknown.n = (size_t)r; + } + return 0; +} |