aboutsummaryrefslogtreecommitdiffstats
path: root/libsbus.c
diff options
context:
space:
mode:
Diffstat (limited to 'libsbus.c')
-rw-r--r--libsbus.c86
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;
+}