diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2020-01-10 10:35:55 +0000 |
---|---|---|
committer | Laurent Bercot <ska-skaware@skarnet.org> | 2020-01-10 10:35:55 +0000 |
commit | 9dafc75bb51c0f350330277a2e96b04f5a1c73b3 (patch) | |
tree | d00d225400b981648d362e4c3bb56b46c0608b7c /src/libskabus | |
parent | 4a14a6b86a4a3c5ab8bc36e4c417a6783dfab463 (diff) | |
download | skabus-9dafc75bb51c0f350330277a2e96b04f5a1c73b3.tar.xz |
Add pub library and daemon
Diffstat (limited to 'src/libskabus')
23 files changed, 515 insertions, 1 deletions
diff --git a/src/libskabus/deps-lib/skabus b/src/libskabus/deps-lib/skabus index 21582c7..a7a8369 100644 --- a/src/libskabus/deps-lib/skabus +++ b/src/libskabus/deps-lib/skabus @@ -1,3 +1,24 @@ +skabus_pub_end.o +skabus_pub_list.o +skabus_pub_list_async.o +skabus_pub_message_get.o +skabus_pub_message_getnfds.o +skabus_pub_register.o +skabus_pub_register_async.o +skabus_pub_send.o +skabus_pub_send_async.o +skabus_pub_send_cb.o +skabus_pub_sendpm.o +skabus_pub_sendpm_async.o +skabus_pub_sendv.o +skabus_pub_sendv_async.o +skabus_pub_sendvpm.o +skabus_pub_sendvpm_async.o +skabus_pub_start.o +skabus_pub_start_async.o +skabus_pub_subunsub.o +skabus_pub_subunsub_async.o +skabus_pub_update.o skabus_rpc_cancel.o skabus_rpc_cancel_async.o skabus_rpc_end.o @@ -17,8 +38,8 @@ skabus_rpc_r_notimpl.o skabus_rpc_rcancel_ignore.o skabus_rpc_release.o skabus_rpc_reply.o -skabus_rpc_replyv.o skabus_rpc_reply_async.o +skabus_rpc_replyv.o skabus_rpc_replyv_async.o skabus_rpc_rinfo_pack.o skabus_rpc_rinfo_unpack.o diff --git a/src/libskabus/skabus-pub-internal.h b/src/libskabus/skabus-pub-internal.h new file mode 100644 index 0000000..efe8bb9 --- /dev/null +++ b/src/libskabus/skabus-pub-internal.h @@ -0,0 +1,12 @@ +/* ISC license. */ + +#ifndef SKABUS_PUB_INTERNAL_H +#define SKABUS_PUB_INTERNAL_H + +#include <skalibs/unixmessage.h> + +#define SKABUS_HEAD_MAX 64 + +extern unixmessage_handler_func_t skabus_pub_send_cb ; + +#endif diff --git a/src/libskabus/skabus_pub_end.c b/src/libskabus/skabus_pub_end.c new file mode 100644 index 0000000..579e83e --- /dev/null +++ b/src/libskabus/skabus_pub_end.c @@ -0,0 +1,25 @@ +/* ISC license. */ + +#include <skalibs/alloc.h> +#include <skalibs/djbunix.h> +#include <skalibs/genalloc.h> +#include <skalibs/skaclient.h> + +#include <skabus/pub.h> + +static void skabus_pub_cltinfo_free (skabus_pub_cltinfo_t *p) +{ + fd_close(p->fd) ; + if (p->nfds) + { + for (size_t i = 0 ; i < p->nfds ; i++) fd_close(p->fds[i]) ; + alloc_free(p->fds) ; + } +} + +void skabus_pub_end (skabus_pub_t *a) +{ + skaclient_end(&a->connection) ; + genalloc_deepfree(skabus_pub_cltinfo_t, &a->info, &skabus_pub_cltinfo_free) ; + a->head = 0 ; +} diff --git a/src/libskabus/skabus_pub_list.c b/src/libskabus/skabus_pub_list.c new file mode 100644 index 0000000..4b8ceeb --- /dev/null +++ b/src/libskabus/skabus_pub_list.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <errno.h> + +#include <skalibs/skaclient.h> + +#include <skabus/pub.h> + +int skabus_pub_list (skabus_pub_t *a, stralloc *sa, diuint32 *n, tain_t const *deadline, tain_t *stamp) +{ + skabus_pub_list_result_t r ; + if (!skabus_pub_list_async(a, sa, &r)) return 0 ; + if (!skaclient_syncify(&a->connection, deadline, stamp)) return 0 ; + if (r.err) return (errno = r.err, 0) ; + *n = r.n ; + return 1 ; +} diff --git a/src/libskabus/skabus_pub_list_async.c b/src/libskabus/skabus_pub_list_async.c new file mode 100644 index 0000000..48797b5 --- /dev/null +++ b/src/libskabus/skabus_pub_list_async.c @@ -0,0 +1,45 @@ +/* ISC license. */ + +#include <stdint.h> +#include <errno.h> + +#include <skalibs/posixishard.h> +#include <skalibs/uint32.h> +#include <skalibs/stralloc.h> +#include <skalibs/unixmessage.h> +#include <skalibs/skaclient.h> + +#include <skabus/pub.h> + +static int skabus_pub_list_cb (unixmessage_t const *m, void *p) +{ + skabus_pub_list_result_t *r = p ; + uint32_t n ; + size_t w = 9, len = m->len - 9 ; + if (m->len < 9 || m->nfds) goto errproto ; + r->err = m->s[0] ; + if (r->err) return 1 ; + uint32_unpack_big(m->s + 1, &n) ; + if (n > 0x7fffffffu || m->len < 9 + (n<<1)) goto errproto ; + if (!stralloc_readyplus(r->sa, m->len - 9 - n)) goto errproto ; + r->n.left = n ; + uint32_unpack_big(m->s + 5, &n) ; r->n.right = n ; + for (uint32_t i = 0 ; i < r->n.left ; i++) + { + size_t thislen ; + if (len < 2) goto errproto ; + thislen = m->s[w++] + 1 ; len-- ; + if ((thislen > len) || m->s[w + thislen]) goto errproto ; + stralloc_catb(r->sa, m->s + w, thislen) ; + w += thislen ; len -= thislen ; + } + return 1 ; + errproto: + return (errno = EPROTO, 0) ; +} + +int skabus_pub_list_async (skabus_pub_t *a, stralloc *sa, skabus_pub_list_result_t *result) +{ + result->sa = sa ; + return skaclient_put(&a->connection, "L", 1, &skabus_pub_list_cb, result) ; +} diff --git a/src/libskabus/skabus_pub_message_get.c b/src/libskabus/skabus_pub_message_get.c new file mode 100644 index 0000000..aabefaa --- /dev/null +++ b/src/libskabus/skabus_pub_message_get.c @@ -0,0 +1,32 @@ +/* ISC license. */ + +#include <string.h> + +#include <skalibs/alloc.h> +#include <skalibs/genalloc.h> + +#include <skabus/pub.h> +#include "skabus-pub-internal.h" + +size_t skabus_pub_message_get (skabus_pub_t *a, skabus_pub_msginfo_t *info, int *fd, int *fds) +{ + size_t n = genalloc_len(skabus_pub_cltinfo_t, &a->info) ; + skabus_pub_cltinfo_t *p = genalloc_s(skabus_pub_cltinfo_t, &a->info) + a->head ; + if (!n) return 0 ; + *info = p->msginfo ; + *fd = p->fd ; + if (p->nfds) + { + for (size_t i = 0 ; i < p->nfds ; i++) fds[i] = p->fds[i] ; + alloc_free(p->fds) ; + } + + if (++a->head == n || a->head > SKABUS_HEAD_MAX) + { + n -= a->head ; + memmove(a->info.s, a->info.s + a->head * sizeof(skabus_pub_cltinfo_t), n * sizeof(skabus_pub_cltinfo_t)) ; + genalloc_setlen(skabus_pub_cltinfo_t, &a->info, n) ; + a->head = 0 ; + } + return 1 + n - a->head ; +} diff --git a/src/libskabus/skabus_pub_message_getnfds.c b/src/libskabus/skabus_pub_message_getnfds.c new file mode 100644 index 0000000..828a42d --- /dev/null +++ b/src/libskabus/skabus_pub_message_getnfds.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/genalloc.h> + +#include <skabus/pub.h> + +int skabus_pub_message_getnfds (skabus_pub_t const *a) +{ + return genalloc_len(skabus_pub_cltinfo_t, &a->info) <= a->head ? -1 : + (int)genalloc_s(skabus_pub_cltinfo_t, &a->info)[a->head].nfds ; +} diff --git a/src/libskabus/skabus_pub_register.c b/src/libskabus/skabus_pub_register.c new file mode 100644 index 0000000..30a08a3 --- /dev/null +++ b/src/libskabus/skabus_pub_register.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <errno.h> + +#include <skalibs/skaclient.h> + +#include <skabus/pub.h> + +int skabus_pub_register (skabus_pub_t *a, char const *id, char const *sre, char const *wre, tain_t const *deadline, tain_t *stamp) +{ + unsigned char r ; + if (!skabus_pub_register_async(a, id, sre, wre, &r)) return 0 ; + if (!skaclient_syncify(&a->connection, deadline, stamp)) return 0 ; + return r ? (errno = r, 0) : 1 ; +} diff --git a/src/libskabus/skabus_pub_register_async.c b/src/libskabus/skabus_pub_register_async.c new file mode 100644 index 0000000..2736bcc --- /dev/null +++ b/src/libskabus/skabus_pub_register_async.c @@ -0,0 +1,30 @@ +/* ISC license. */ + +#include <string.h> +#include <errno.h> +#include <sys/uio.h> + +#include <skalibs/uint32.h> +#include <skalibs/skaclient.h> + +#include <skabus/pub.h> + +int skabus_pub_register_async (skabus_pub_t *a, char const *id, char const *sre, char const *wre, unsigned char *err) +{ + size_t idlen = strlen(id) ; + size_t srelen = strlen(sre) ; + size_t wrelen = strlen(wre) ; + char pack[10] = "R" ; + struct iovec v[4] = + { + { .iov_base = pack, .iov_len = 10 }, + { .iov_base = (char *)id, .iov_len = idlen+1 }, + { .iov_base = (char *)sre, .iov_len = srelen+1 }, + { .iov_base = (char *)wre, .iov_len = wrelen+1 } + } ; + if (idlen > SKABUS_PUB_IDSTR_SIZE) return (errno = ERANGE, 0) ; + pack[1] = (unsigned char)idlen ; + uint32_pack_big(pack+2, srelen) ; + uint32_pack_big(pack+6, wrelen) ; + return skaclient_putv(&a->connection, v, 4, &skaclient_default_cb, err) ; +} diff --git a/src/libskabus/skabus_pub_send.c b/src/libskabus/skabus_pub_send.c new file mode 100644 index 0000000..f41ede3 --- /dev/null +++ b/src/libskabus/skabus_pub_send.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <errno.h> + +#include <skalibs/skaclient.h> + +#include <skabus/pub.h> + +uint64_t skabus_pub_send_withfds (skabus_pub_t *a, char const *s, size_t len, int const *fds, unsigned int nfds, unsigned char const *bits, tain_t const *deadline, tain_t *stamp) +{ + skabus_pub_send_result_t r ; + if (!skabus_pub_send_withfds_async(a, s, len, fds, nfds, bits, &r)) return 0 ; + if (!skaclient_syncify(&a->connection, deadline, stamp)) return 0 ; + return r.err ? (errno = r.err, 0) : r.u ; +} diff --git a/src/libskabus/skabus_pub_send_async.c b/src/libskabus/skabus_pub_send_async.c new file mode 100644 index 0000000..1a2bb58 --- /dev/null +++ b/src/libskabus/skabus_pub_send_async.c @@ -0,0 +1,16 @@ +/* ISC license. */ + +#include <sys/uio.h> + +#include <skalibs/unixmessage.h> +#include <skalibs/skaclient.h> + +#include <skabus/pub.h> +#include "skabus-pub-internal.h" + +int skabus_pub_send_withfds_async (skabus_pub_t *a, char const *s, size_t len, int const *fds, unsigned int nfds, unsigned char const *bits, skabus_pub_send_result_t *result) +{ + struct iovec v[2] = { { .iov_base = "!", .iov_len = 1 }, { .iov_base = (char *)s, .iov_len = len } } ; + unixmessage_v_t m = { .v = v, .vlen = 2, .fds = (int *)fds, .nfds = nfds } ; + return skaclient_putmsgv_and_close(&a->connection, &m, bits, &skabus_pub_send_cb, result) ; +} diff --git a/src/libskabus/skabus_pub_send_cb.c b/src/libskabus/skabus_pub_send_cb.c new file mode 100644 index 0000000..e95ab6c --- /dev/null +++ b/src/libskabus/skabus_pub_send_cb.c @@ -0,0 +1,25 @@ +/* ISC license. */ + +#include <errno.h> + +#include <skalibs/posixishard.h> +#include <skalibs/uint64.h> +#include <skalibs/unixmessage.h> + +#include <skabus/pub.h> + +int skabus_pub_send_cb (unixmessage_t const *m, void *p) +{ + skabus_pub_send_result_t *r = p ; + if (!m->len || m->nfds) return (errno = EPROTO, 0) ; + if (m->s[0]) + { + r->u = 0 ; + r->err = m->s[0] ; + return 1 ; + } + if (m->len != 9) return (errno = EPROTO, 0) ; + uint64_unpack_big(m->s + 1, &r->u) ; + r->err = 0 ; + return 1 ; +} diff --git a/src/libskabus/skabus_pub_sendpm.c b/src/libskabus/skabus_pub_sendpm.c new file mode 100644 index 0000000..073633a --- /dev/null +++ b/src/libskabus/skabus_pub_sendpm.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <errno.h> + +#include <skalibs/skaclient.h> + +#include <skabus/pub.h> + +uint64_t skabus_pub_sendpm_withfds (skabus_pub_t *a, char const *id, char const *s, size_t len, int const *fds, unsigned int nfds, unsigned char const *bits, tain_t const *deadline, tain_t *stamp) +{ + skabus_pub_send_result_t r ; + if (!skabus_pub_sendpm_withfds_async(a, id, s, len, fds, nfds, bits, &r)) return 0 ; + if (!skaclient_syncify(&a->connection, deadline, stamp)) return 0 ; + return r.err ? (errno = r.err, 0) : r.u ; +} diff --git a/src/libskabus/skabus_pub_sendpm_async.c b/src/libskabus/skabus_pub_sendpm_async.c new file mode 100644 index 0000000..d43b01f --- /dev/null +++ b/src/libskabus/skabus_pub_sendpm_async.c @@ -0,0 +1,27 @@ +/* ISC license. */ + +#include <string.h> +#include <sys/uio.h> +#include <errno.h> + +#include <skalibs/unixmessage.h> +#include <skalibs/skaclient.h> + +#include <skabus/pub.h> +#include "skabus-pub-internal.h" + +int skabus_pub_sendpm_withfds_async (skabus_pub_t *a, char const *idstr, char const *s, size_t len, int const *fds, unsigned int nfds, unsigned char const *bits, skabus_pub_send_result_t *result) +{ + size_t idlen = strlen(idstr) ; + char tmp[2] = "+" ; + struct iovec v[3] = + { + { .iov_base = tmp, .iov_len = 2 }, + { .iov_base = (char *)idstr, .iov_len = idlen+1 }, + { .iov_base = (char *)s, .iov_len = len } + } ; + unixmessage_v_t m = { .v = v, .vlen = 3, .fds = (int *)fds, .nfds = nfds } ; + if (idlen > SKABUS_PUB_IDSTR_SIZE) return (errno = ERANGE, 0) ; + tmp[1] = (unsigned char)idlen ; + return skaclient_putmsgv_and_close(&a->connection, &m, bits, &skabus_pub_send_cb, result) ; +} diff --git a/src/libskabus/skabus_pub_sendv.c b/src/libskabus/skabus_pub_sendv.c new file mode 100644 index 0000000..ff1c743 --- /dev/null +++ b/src/libskabus/skabus_pub_sendv.c @@ -0,0 +1,16 @@ +/* ISC license. */ + +#include <errno.h> + +#include <skalibs/uint64.h> +#include <skalibs/skaclient.h> + +#include <skabus/pub.h> + +uint64_t skabus_pub_sendv_withfds (skabus_pub_t *a, struct iovec const *v, unsigned int vlen, int const *fds, unsigned int nfds, unsigned char const *bits, tain_t const *deadline, tain_t *stamp) +{ + skabus_pub_send_result_t r ; + if (!skabus_pub_sendv_withfds_async(a, v, vlen, fds, nfds, bits, &r)) return 0 ; + if (!skaclient_syncify(&a->connection, deadline, stamp)) return 0 ; + return r.err ? (errno = r.err, 0) : r.u ; +} diff --git a/src/libskabus/skabus_pub_sendv_async.c b/src/libskabus/skabus_pub_sendv_async.c new file mode 100644 index 0000000..54ce94e --- /dev/null +++ b/src/libskabus/skabus_pub_sendv_async.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <sys/uio.h> + +#include <skalibs/unixmessage.h> +#include <skalibs/skaclient.h> + +#include <skabus/pub.h> +#include "skabus-pub-internal.h" + +int skabus_pub_sendv_withfds_async (skabus_pub_t *a, struct iovec const *v, unsigned int vlen, int const *fds, unsigned int nfds, unsigned char const *bits, skabus_pub_send_result_t *result) +{ + struct iovec vv[vlen+1] ; + unixmessage_v_t m = { .v = vv, .vlen = vlen+1, .fds = (int *)fds, .nfds = nfds } ; + vv[0].iov_base = "!" ; vv[0].iov_len = 1 ; + for (unsigned int i = 0 ; i < vlen ; i++) vv[1+i] = v[i] ; + return skaclient_putmsgv_and_close(&a->connection, &m, bits, &skabus_pub_send_cb, result) ; +} diff --git a/src/libskabus/skabus_pub_sendvpm.c b/src/libskabus/skabus_pub_sendvpm.c new file mode 100644 index 0000000..a898bbc --- /dev/null +++ b/src/libskabus/skabus_pub_sendvpm.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <errno.h> + +#include <skalibs/skaclient.h> + +#include <skabus/pub.h> + +uint64_t skabus_pub_sendvpm_withfds (skabus_pub_t *a, char const *idstr, struct iovec const *v, unsigned int vlen, int const *fds, unsigned int nfds, unsigned char const *bits, tain_t const *deadline, tain_t *stamp) +{ + skabus_pub_send_result_t r ; + if (!skabus_pub_sendvpm_withfds_async(a, idstr, v, vlen, fds, nfds, bits, &r)) return 0 ; + if (!skaclient_syncify(&a->connection, deadline, stamp)) return 0 ; + return r.err ? (errno = r.err, 0) : r.u ; +} diff --git a/src/libskabus/skabus_pub_sendvpm_async.c b/src/libskabus/skabus_pub_sendvpm_async.c new file mode 100644 index 0000000..b1bab4d --- /dev/null +++ b/src/libskabus/skabus_pub_sendvpm_async.c @@ -0,0 +1,25 @@ +/* ISC license. */ + +#include <string.h> +#include <sys/uio.h> +#include <errno.h> + +#include <skalibs/unixmessage.h> +#include <skalibs/skaclient.h> + +#include <skabus/pub.h> +#include "skabus-pub-internal.h" + +int skabus_pub_sendvpm_withfds_async (skabus_pub_t *a, char const *idstr, struct iovec const *v, unsigned int vlen, int const *fds, unsigned int nfds, unsigned char const *bits, skabus_pub_send_result_t *result) +{ + size_t idlen = strlen(idstr) ; + char tmp[2] = "+" ; + struct iovec vv[vlen + 2] ; + unixmessage_v_t m = { .v = vv, .vlen = vlen + 2, .fds = (int *)fds, .nfds = nfds } ; + if (idlen > SKABUS_PUB_IDSTR_SIZE) return (errno = ERANGE, 0) ; + tmp[1] = (unsigned char)idlen ; + vv[0].iov_base = tmp ; vv[0].iov_len = 2 ; + vv[1].iov_base = (char *)idstr ; vv[1].iov_len = idlen+1 ; + for (unsigned int i = 0 ; i < vlen ; i++) vv[2+i] = v[i] ; + return skaclient_putmsgv_and_close(&a->connection, &m, bits, &skabus_pub_send_cb, result) ; +} diff --git a/src/libskabus/skabus_pub_start.c b/src/libskabus/skabus_pub_start.c new file mode 100644 index 0000000..d72b0f7 --- /dev/null +++ b/src/libskabus/skabus_pub_start.c @@ -0,0 +1,20 @@ +/* ISC license. */ + +#include <skalibs/skaclient.h> + +#include <skabus/pub.h> + +int skabus_pub_start (skabus_pub_t *a, char const *path, tain_t const *deadline, tain_t *stamp) +{ + return skaclient_start_b( + &a->connection, + &a->buffers, + path, + SKACLIENT_OPTION_ASYNC_ACCEPT_FDS, + SKABUS_PUB_BANNER1, + SKABUS_PUB_BANNER1_LEN, + SKABUS_PUB_BANNER2, + SKABUS_PUB_BANNER2_LEN, + deadline, + stamp) ; +} diff --git a/src/libskabus/skabus_pub_start_async.c b/src/libskabus/skabus_pub_start_async.c new file mode 100644 index 0000000..3a82f41 --- /dev/null +++ b/src/libskabus/skabus_pub_start_async.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +#include <skalibs/skaclient.h> + +#include <skabus/pub.h> + +int skabus_pub_start_async (skabus_pub_t *a, char const *path, skabus_pub_start_result_t *data) +{ + return skaclient_start_async_b( + &a->connection, + &a->buffers, + path, + SKACLIENT_OPTION_ASYNC_ACCEPT_FDS, + SKABUS_PUB_BANNER1, + SKABUS_PUB_BANNER1_LEN, + SKABUS_PUB_BANNER2, + SKABUS_PUB_BANNER2_LEN, + &data->skaclient_cbdata) ; +} diff --git a/src/libskabus/skabus_pub_subunsub.c b/src/libskabus/skabus_pub_subunsub.c new file mode 100644 index 0000000..29e61f1 --- /dev/null +++ b/src/libskabus/skabus_pub_subunsub.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <errno.h> + +#include <skalibs/skaclient.h> + +#include <skabus/pub.h> + +int skabus_pub_subunsub (skabus_pub_t *a, char what, char const *id, tain_t const *deadline, tain_t *stamp) +{ + unsigned char r ; + if (!skabus_pub_subunsub_async(a, what, id, &r)) return 0 ; + if (!skaclient_syncify(&a->connection, deadline, stamp)) return 0 ; + return r ? (errno = r, 0) : 1 ; +} diff --git a/src/libskabus/skabus_pub_subunsub_async.c b/src/libskabus/skabus_pub_subunsub_async.c new file mode 100644 index 0000000..d41ed98 --- /dev/null +++ b/src/libskabus/skabus_pub_subunsub_async.c @@ -0,0 +1,22 @@ +/* ISC license. */ + +#include <string.h> +#include <sys/uio.h> +#include <errno.h> + +#include <skalibs/skaclient.h> + +#include <skabus/pub.h> + +int skabus_pub_subunsub_async (skabus_pub_t *a, char what, char const *id, unsigned char *err) +{ + size_t idlen = strlen(id) ; + char pack[2] = { what, (unsigned char)idlen } ; + struct iovec v[2] = + { + { .iov_base = pack, .iov_len = 2 }, + { .iov_base = (char *)id, .iov_len = idlen+1 } + } ; + if (idlen > SKABUS_PUB_IDSTR_SIZE) return (errno = ERANGE, 0) ; + return skaclient_putv(&a->connection, v, 2, &skaclient_default_cb, err) ; +} diff --git a/src/libskabus/skabus_pub_update.c b/src/libskabus/skabus_pub_update.c new file mode 100644 index 0000000..46e699c --- /dev/null +++ b/src/libskabus/skabus_pub_update.c @@ -0,0 +1,58 @@ +/* ISC license. */ + +#include <string.h> +#include <stdint.h> +#include <errno.h> + +#include <skalibs/posixishard.h> +#include <skalibs/uint64.h> +#include <skalibs/tai.h> +#include <skalibs/alloc.h> +#include <skalibs/genalloc.h> +#include <skalibs/unixmessage.h> +#include <skalibs/skaclient.h> + +#include <skabus/pub.h> + +static int handler (unixmessage_t const *m, void *x) +{ + skabus_pub_t *a = (skabus_pub_t *)x ; + size_t n = genalloc_len(skabus_pub_cltinfo_t, &a->info) ; + char const *s = m->s ; + size_t len = m->len ; + skabus_pub_cltinfo_t *p ; + uint8_t idlen ; + if (len < 11 + TAIN_PACK || !m->nfds) goto errproto ; + if (!genalloc_readyplus(skabus_pub_cltinfo_t, &a->info, 1)) goto err ; + p = genalloc_s(skabus_pub_cltinfo_t, &a->info) + n ; + p->fd = m->fds[0] ; + p->nfds = m->nfds - 1 ; + if (p->nfds > 1) + { + p->fds = alloc(p->nfds * sizeof(int)) ; + if (!p->fds) goto err ; + for (size_t i = 0 ; i < p->nfds ; i++) p->fds[i] = m->fds[1 + i] ; + } + else p->fds = 0 ; + uint64_unpack_big(s, &p->msginfo.serial) ; s += 8 ; len -= 8 ; + tain_unpack(s, &p->msginfo.timestamp) ; s += TAIN_PACK ; len -= TAIN_PACK ; + p->msginfo.flags = *s++ ; len-- ; + idlen = *s++ ; len-- ; + if (len != (size_t)idlen + 1 || s[idlen] || idlen > SKABUS_PUB_IDSTR_SIZE) goto errprotof ; + memcpy(p->msginfo.sender, s, len) ; + genalloc_setlen(skabus_pub_cltinfo_t, &a->info, n+1) ; + return 1 ; + + errprotof: + alloc_free(p->fds) ; + errproto: + errno = EPROTO ; + err: + unixmessage_drop(m) ; + return 0 ; +} + +int skabus_pub_update (skabus_pub_t *a) +{ + return skaclient_update(&a->connection, &handler, a) ; +} |