ctdb-protocol: Fix marshalling for ctdb_uptime
[vlendec/samba-autobuild/.git] / ctdb / tests / src / protocol_types_compat_test.c
index e2e6d39fb0605b8b16f000aa80ffad517b470af9..ad908d0b515ee3a077666776ff82403dad25892e 100644 (file)
@@ -825,6 +825,347 @@ static int ctdb_node_flag_change_pull_old(uint8_t *buf, size_t buflen,
        return 0;
 }
 
+struct ctdb_var_list_wire {
+       uint32_t length;
+       char list_str[1];
+};
+
+static size_t ctdb_var_list_len_old(struct ctdb_var_list *in)
+{
+       int i;
+       size_t len = sizeof(uint32_t);
+
+       for (i=0; i<in->count; i++) {
+               len += strlen(in->var[i]) + 1;
+       }
+       return len;
+}
+
+static void ctdb_var_list_push_old(struct ctdb_var_list *in, uint8_t *buf)
+{
+       struct ctdb_var_list_wire *wire = (struct ctdb_var_list_wire *)buf;
+       int i, n;
+       size_t offset = 0;
+
+       if (in->count > 0) {
+               n = sprintf(wire->list_str, "%s", in->var[0]);
+               offset += n;
+       }
+       for (i=1; i<in->count; i++) {
+               n = sprintf(&wire->list_str[offset], ":%s", in->var[i]);
+               offset += n;
+       }
+       wire->length = offset + 1;
+}
+
+static int ctdb_var_list_pull_old(uint8_t *buf, size_t buflen,
+                                 TALLOC_CTX *mem_ctx,
+                                 struct ctdb_var_list **out)
+{
+       struct ctdb_var_list *val = NULL;
+       struct ctdb_var_list_wire *wire = (struct ctdb_var_list_wire *)buf;
+       char *str, *s, *tok, *ptr;
+       const char **list;
+
+       if (buflen < sizeof(uint32_t)) {
+               return EMSGSIZE;
+       }
+       if (wire->length > buflen) {
+               return EMSGSIZE;
+       }
+       if (sizeof(uint32_t) + wire->length < sizeof(uint32_t)) {
+               return EMSGSIZE;
+       }
+       if (buflen < sizeof(uint32_t) + wire->length) {
+               return EMSGSIZE;
+       }
+
+       str = talloc_strndup(mem_ctx, (char *)wire->list_str, wire->length);
+       if (str == NULL) {
+               return ENOMEM;
+       }
+
+       val = talloc_zero(mem_ctx, struct ctdb_var_list);
+       if (val == NULL) {
+               goto fail;
+       }
+
+       s = str;
+       while ((tok = strtok_r(s, ":", &ptr)) != NULL) {
+               s = NULL;
+               list = talloc_realloc(val, val->var, const char *,
+                                     val->count+1);
+               if (list == NULL) {
+                       goto fail;
+               }
+
+               val->var = list;
+               val->var[val->count] = talloc_strdup(val, tok);
+               if (val->var[val->count] == NULL) {
+                       goto fail;
+               }
+               val->count++;
+       }
+
+       talloc_free(str);
+       *out = val;
+       return 0;
+
+fail:
+       talloc_free(str);
+       talloc_free(val);
+       return ENOMEM;
+}
+
+static size_t ctdb_tunable_list_len_old(struct ctdb_tunable_list *in)
+{
+       return sizeof(struct ctdb_tunable_list);
+}
+
+static void ctdb_tunable_list_push_old(struct ctdb_tunable_list *in,
+                                      uint8_t *buf)
+{
+       memcpy(buf, in, sizeof(struct ctdb_tunable_list));
+}
+
+static int ctdb_tunable_list_pull_old(uint8_t *buf, size_t buflen,
+                                     TALLOC_CTX *mem_ctx,
+                                     struct ctdb_tunable_list **out)
+{
+       struct ctdb_tunable_list *val;
+
+       if (buflen < sizeof(struct ctdb_tunable_list)) {
+               return EMSGSIZE;
+       }
+
+       val = talloc_memdup(mem_ctx, buf, sizeof(struct ctdb_tunable_list));
+       if (val == NULL) {
+               return ENOMEM;
+       }
+
+       *out = val;
+       return 0;
+}
+
+struct ctdb_tickle_list_wire {
+       ctdb_sock_addr addr;
+       uint32_t num;
+       struct ctdb_connection conn[1];
+};
+
+static size_t ctdb_tickle_list_len_old(struct ctdb_tickle_list *in)
+{
+       return offsetof(struct ctdb_tickle_list, conn) +
+              in->num * sizeof(struct ctdb_connection);
+}
+
+static void ctdb_tickle_list_push_old(struct ctdb_tickle_list *in,
+                                     uint8_t *buf)
+{
+       struct ctdb_tickle_list_wire *wire =
+               (struct ctdb_tickle_list_wire *)buf;
+       size_t offset;
+       int i;
+
+       memcpy(&wire->addr, &in->addr, sizeof(ctdb_sock_addr));
+       wire->num = in->num;
+
+       offset = offsetof(struct ctdb_tickle_list_wire, conn);
+       for (i=0; i<in->num; i++) {
+               ctdb_connection_push_old(&in->conn[i], &buf[offset]);
+               offset += ctdb_connection_len_old(&in->conn[i]);
+       }
+}
+
+static int ctdb_tickle_list_pull_old(uint8_t *buf, size_t buflen,
+                                    TALLOC_CTX *mem_ctx,
+                                    struct ctdb_tickle_list **out)
+{
+       struct ctdb_tickle_list *val;
+       struct ctdb_tickle_list_wire *wire =
+               (struct ctdb_tickle_list_wire *)buf;
+       size_t offset;
+       int i, ret;
+
+       if (buflen < offsetof(struct ctdb_tickle_list_wire, conn)) {
+               return EMSGSIZE;
+       }
+       if (wire->num > buflen / sizeof(struct ctdb_connection)) {
+               return EMSGSIZE;
+       }
+       if (offsetof(struct ctdb_tickle_list_wire, conn) +
+           wire->num * sizeof(struct ctdb_connection) <
+           offsetof(struct ctdb_tickle_list_wire, conn)) {
+               return EMSGSIZE;
+       }
+       if (buflen < offsetof(struct ctdb_tickle_list_wire, conn) +
+                    wire->num * sizeof(struct ctdb_connection)) {
+               return EMSGSIZE;
+       }
+
+       val = talloc(mem_ctx, struct ctdb_tickle_list);
+       if (val == NULL) {
+               return ENOMEM;
+       }
+
+       offset = offsetof(struct ctdb_tickle_list, conn);
+       memcpy(val, wire, offset);
+
+       val->conn = talloc_array(val, struct ctdb_connection, wire->num);
+       if (val->conn == NULL) {
+               talloc_free(val);
+               return ENOMEM;
+       }
+
+       for (i=0; i<wire->num; i++) {
+               ret = ctdb_connection_pull_elems_old(&buf[offset],
+                                                    buflen-offset,
+                                                    val->conn,
+                                                    &val->conn[i]);
+               if (ret != 0) {
+                       talloc_free(val);
+                       return ret;
+               }
+               offset += ctdb_connection_len_old(&val->conn[i]);
+       }
+
+       *out = val;
+       return 0;
+}
+
+struct ctdb_addr_info_wire {
+       ctdb_sock_addr addr;
+       uint32_t mask;
+       uint32_t len;
+       char iface[1];
+};
+
+static size_t ctdb_addr_info_len_old(struct ctdb_addr_info *in)
+{
+       uint32_t len;
+
+       len = offsetof(struct ctdb_addr_info_wire, iface);
+       if (in->iface != NULL) {
+              len += strlen(in->iface)+1;
+       }
+
+       return len;
+}
+
+static void ctdb_addr_info_push_old(struct ctdb_addr_info *in, uint8_t *buf)
+{
+       struct ctdb_addr_info_wire *wire = (struct ctdb_addr_info_wire *)buf;
+
+       wire->addr = in->addr;
+       wire->mask = in->mask;
+       if (in->iface == NULL) {
+               wire->len = 0;
+       } else {
+               wire->len = strlen(in->iface)+1;
+               memcpy(wire->iface, in->iface, wire->len);
+       }
+}
+
+static int ctdb_addr_info_pull_old(uint8_t *buf, size_t buflen,
+                                  TALLOC_CTX *mem_ctx,
+                                  struct ctdb_addr_info **out)
+{
+       struct ctdb_addr_info *val;
+       struct ctdb_addr_info_wire *wire = (struct ctdb_addr_info_wire *)buf;
+
+       if (buflen < offsetof(struct ctdb_addr_info_wire, iface)) {
+               return EMSGSIZE;
+       }
+       if (wire->len > buflen) {
+               return EMSGSIZE;
+       }
+       if (offsetof(struct ctdb_addr_info_wire, iface) + wire->len <
+           offsetof(struct ctdb_addr_info_wire, iface)) {
+               return EMSGSIZE;
+       }
+       if (buflen < offsetof(struct ctdb_addr_info_wire, iface) + wire->len) {
+               return EMSGSIZE;
+       }
+
+       val = talloc(mem_ctx, struct ctdb_addr_info);
+       if (val == NULL) {
+               return ENOMEM;
+       }
+
+       val->addr = wire->addr;
+       val->mask = wire->mask;
+
+       if (wire->len == 0) {
+               val->iface = NULL;
+       } else {
+               val->iface = talloc_strndup(val, wire->iface, wire->len);
+               if (val->iface == NULL) {
+                       talloc_free(val);
+                       return ENOMEM;
+               }
+       }
+
+       *out = val;
+       return 0;
+}
+
+static size_t ctdb_transdb_len_old(struct ctdb_transdb *in)
+{
+       return sizeof(struct ctdb_transdb);
+}
+
+static void ctdb_transdb_push_old(struct ctdb_transdb *in, uint8_t *buf)
+{
+       memcpy(buf, in, sizeof(struct ctdb_transdb));
+}
+
+static int ctdb_transdb_pull_old(uint8_t *buf, size_t buflen,
+                                TALLOC_CTX *mem_ctx,
+                                struct ctdb_transdb **out)
+{
+       struct ctdb_transdb *val;
+
+       if (buflen < sizeof(struct ctdb_transdb)) {
+               return EMSGSIZE;
+       }
+
+       val = talloc_memdup(mem_ctx, buf, sizeof(struct ctdb_transdb));
+       if (val == NULL) {
+               return ENOMEM;
+       }
+
+       *out = val;
+       return 0;
+}
+
+static size_t ctdb_uptime_len_old(struct ctdb_uptime *in)
+{
+       return sizeof(struct ctdb_uptime);
+}
+
+static void ctdb_uptime_push_old(struct ctdb_uptime *in, uint8_t *buf)
+{
+       memcpy(buf, in, sizeof(struct ctdb_uptime));
+}
+
+static int ctdb_uptime_pull_old(uint8_t *buf, size_t buflen,
+                               TALLOC_CTX *mem_ctx, struct ctdb_uptime **out)
+{
+       struct ctdb_uptime *val;
+
+       if (buflen < sizeof(struct ctdb_uptime)) {
+               return EMSGSIZE;
+       }
+
+       val = talloc_memdup(mem_ctx, buf, sizeof(struct ctdb_uptime));
+       if (val == NULL) {
+               return ENOMEM;
+       }
+
+       *out = val;
+       return 0;
+}
+
 
 COMPAT_TYPE3_TEST(struct ctdb_statistics, ctdb_statistics);
 COMPAT_TYPE3_TEST(struct ctdb_vnn_map, ctdb_vnn_map);
@@ -844,6 +1185,12 @@ COMPAT_TYPE3_TEST(ctdb_sock_addr, ctdb_sock_addr);
 COMPAT_TYPE3_TEST(struct ctdb_connection, ctdb_connection);
 COMPAT_TYPE3_TEST(struct ctdb_tunable, ctdb_tunable);
 COMPAT_TYPE3_TEST(struct ctdb_node_flag_change, ctdb_node_flag_change);
+COMPAT_TYPE3_TEST(struct ctdb_var_list, ctdb_var_list);
+COMPAT_TYPE3_TEST(struct ctdb_tunable_list, ctdb_tunable_list);
+COMPAT_TYPE3_TEST(struct ctdb_tickle_list, ctdb_tickle_list);
+COMPAT_TYPE3_TEST(struct ctdb_addr_info, ctdb_addr_info);
+COMPAT_TYPE3_TEST(struct ctdb_transdb, ctdb_transdb);
+COMPAT_TYPE3_TEST(struct ctdb_uptime, ctdb_uptime);
 
 int main(int argc, char *argv[])
 {
@@ -868,6 +1215,12 @@ int main(int argc, char *argv[])
        COMPAT_TEST_FUNC(ctdb_connection)();
        COMPAT_TEST_FUNC(ctdb_tunable)();
        COMPAT_TEST_FUNC(ctdb_node_flag_change)();
+       COMPAT_TEST_FUNC(ctdb_var_list)();
+       COMPAT_TEST_FUNC(ctdb_tunable_list)();
+       COMPAT_TEST_FUNC(ctdb_tickle_list)();
+       COMPAT_TEST_FUNC(ctdb_addr_info)();
+       COMPAT_TEST_FUNC(ctdb_transdb)();
+       COMPAT_TEST_FUNC(ctdb_uptime)();
 
        return 0;
 }