/** * Appends `n_bytes' to the pmsg_t buffer. If the last pmsg_t is writable * it is filled with as much data as space is still available. Otherwise * or if this space is not sufficient another pmsg_t is created and * appendded to the list. */ void pmsg_slist_append(slist_t *slist, const void *data, size_t n_bytes) { pmsg_t *mb; g_assert(slist); if (0 == n_bytes) return; g_assert(NULL != data); mb = slist_tail(slist); if (mb && pmsg_is_writable(mb)) { size_t n; n = pmsg_write(mb, data, n_bytes); data = (const char *) data + n; n_bytes -= n; } if (n_bytes > 0) { mb = pmsg_new(PMSG_P_DATA, NULL, MAX(n_bytes, PMSG_SLIST_GROW_MIN)); pmsg_write(mb, data, n_bytes); slist_append(slist, mb); } }
/** * Write data to stream. * * @param os the output stream * @param data start of data to write * @param len length of data to write * * @return size of data written, -1 on error. */ ssize_t ostream_write(ostream_t *os, const void *data, size_t len) { ssize_t w = (ssize_t) -1; ostream_check(os); len = MIN(len, MAX_INT_VAL(ssize_t)); switch (os->type) { case OSTREAM_T_FILE: { size_t n = fwrite(data, len, 1, os->u.f); w = (0 == n) ? -1 : (ssize_t) len; } break; case OSTREAM_T_FD: w = write(os->u.fd, data, len); break; case OSTREAM_T_MEM: pmsg_slist_append(os->u.sl, data, len); w = len; break; case OSTREAM_T_PMSG: w = pmsg_write(os->u.mb, data, len); w = (len == UNSIGNED(w)) ? w : -1; break; case OSTREAM_T_MAX: g_assert_not_reached(); } if (-1 == w) os->ioerr = TRUE; return w; }
/** * Serialization routine for keydata. */ static void serialize_keydata(pmsg_t *mb, const void *data) { const struct keydata *kd = data; int i; g_assert(kd->values <= MAX_VALUES); pmsg_write_u8(mb, KEYS_KEYDATA_VERSION); pmsg_write_u8(mb, kd->values); for (i = 0; i < kd->values; i++) { pmsg_write(mb, &kd->creators[i], sizeof(kd->creators[i])); pmsg_write(mb, &kd->dbkeys[i], sizeof(kd->dbkeys[i])); pmsg_write_time(mb, kd->expire[i]); } }
/** * Serialization routine for tokdata. */ static void serialize_tokdata(pmsg_t *mb, const void *data) { const struct tokdata *td = data; pmsg_write_time(mb, td->last_update); pmsg_write_u8(mb, td->length); pmsg_write(mb, td->token, td->length); }
/** * Write NUL-terminated string. * * If (size_t) -1 is given as length, then it is computed via strlen(), in * which case the string buffer must be NUL-terminated. Otherwise, the value * is taken to be the pre-computed string length. * * The string is written as: <ule64(length)><bytes>, no trailing NUL. */ void pmsg_write_string(pmsg_t *mb, const char *str, size_t length) { size_t len; g_assert(pmsg_is_writable(mb)); /* Not shared, or would corrupt data */ len = (size_t) -1 == length ? strlen(str) : length; g_assert(UNSIGNED(pmsg_available(mb)) >= len + 10); /* Need ule64 length */ pmsg_write_ule64(mb, (uint64) len); if (len != 0) { pmsg_write(mb, str, len); } }
/** * Write NUL-terminated string, up to `n' characters or the first seen NUL * in the buffer, whichever comes first. * * The string is written as: <ule64(length)><bytes>, no trailing NUL. */ void pmsg_write_fixed_string(pmsg_t *mb, const char *str, size_t n) { size_t len; g_assert(pmsg_is_writable(mb)); /* Not shared, or would corrupt data */ g_assert(UNSIGNED(pmsg_available(mb)) >= n + 10); /* Need ule64 length */ len = strlen(str); len = MIN(n, len); pmsg_write_ule64(mb, (uint64) len); if (len != 0) { pmsg_write(mb, str, len); } }
/** * Write NUL-terminated string, up to `n' characters or the first seen NUL * in the buffer, whichever comes first. * * The string is written as: <ule64(length)><bytes>, no trailing NUL. */ void pmsg_write_fixed_string(pmsg_t *mb, const char *str, size_t n) { size_t len; g_assert(pmsg_is_writable(mb)); /* Not shared, or would corrupt data */ g_assert(UNSIGNED(pmsg_available(mb)) >= n + 10); /* Need ule64 length */ g_assert_log(size_is_non_negative(n), "%s(): n=%zd", G_STRFUNC, n); len = vstrlen(str); len = MIN(n, len); pmsg_write_ule64(mb, (uint64) len); if (len != 0) { pmsg_write(mb, str, len); } }
/** * Write NUL-terminated string. * * If (size_t) -1 is given as length, then it is computed via strlen(), in * which case the string buffer must be NUL-terminated. Otherwise, the value * is taken to be the pre-computed string length. * * The string is written as: <ule64(length)><bytes>, no trailing NUL. */ void pmsg_write_string(pmsg_t *mb, const char *str, size_t length) { size_t len; g_assert(pmsg_is_writable(mb)); /* Not shared, or would corrupt data */ g_assert_log(size_is_non_negative(length) || (size_t) -1 == length, "%s(): length=%zd", G_STRFUNC, length); len = (size_t) -1 == length ? strlen(str) : length; g_assert(UNSIGNED(pmsg_available(mb)) >= len + 10); /* Need ule64 length */ pmsg_write_ule64(mb, (uint64) len); if (len != 0) { pmsg_write(mb, str, len); } }
/** * Write an IPv4 or IPv6 address. */ void pmsg_write_ipv4_or_ipv6_addr(pmsg_t *mb, host_addr_t addr) { g_assert(pmsg_is_writable(mb)); /* Not shared, or would corrupt data */ g_assert(pmsg_available(mb) >= 17); switch (host_addr_net(addr)) { case NET_TYPE_IPV4: pmsg_write_u8(mb, 4); pmsg_write_be32(mb, host_addr_ipv4(addr)); break; case NET_TYPE_IPV6: pmsg_write_u8(mb, 16); pmsg_write(mb, host_addr_ipv6(&addr), 16); break; case NET_TYPE_LOCAL: case NET_TYPE_NONE: g_error("unexpected address in pmsg_write_ipv4_or_ipv6_addr(): %s", host_addr_to_string(addr)); } }