ctdb-protocol: Fix marshalling for ctdb_script_list
[vlendec/samba-autobuild/.git] / ctdb / tests / src / protocol_types_compat_test.c
index 7a66cdefced44eac12d4c55e46e2bb8b2560e7c9..9b3fc9e1512cf5a42e3a17fae91e6e6553700271 100644 (file)
@@ -736,6 +736,847 @@ static int ctdb_connection_pull_old(uint8_t *buf, size_t buflen,
        return ret;
 }
 
+struct ctdb_tunable_wire {
+       uint32_t value;
+       uint32_t length;
+       uint8_t name[1];
+};
+
+static size_t ctdb_tunable_len_old(struct ctdb_tunable *in)
+{
+       return offsetof(struct ctdb_tunable_wire, name) +
+              strlen(in->name) + 1;
+}
+
+static void ctdb_tunable_push_old(struct ctdb_tunable *in, uint8_t *buf)
+{
+       struct ctdb_tunable_wire *wire = (struct ctdb_tunable_wire *)buf;
+
+       wire->value = in->value;
+       wire->length = strlen(in->name) + 1;
+       memcpy(wire->name, in->name, wire->length);
+}
+
+static int ctdb_tunable_pull_old(uint8_t *buf, size_t buflen,
+                                TALLOC_CTX *mem_ctx,
+                                struct ctdb_tunable **out)
+{
+       struct ctdb_tunable *val;
+       struct ctdb_tunable_wire *wire = (struct ctdb_tunable_wire *)buf;
+
+       if (buflen < offsetof(struct ctdb_tunable_wire, name)) {
+               return EMSGSIZE;
+       }
+       if (wire->length > buflen) {
+               return EMSGSIZE;
+       }
+       if (offsetof(struct ctdb_tunable_wire, name) + wire->length <
+           offsetof(struct ctdb_tunable_wire, name)) {
+               return EMSGSIZE;
+       }
+       if (buflen < offsetof(struct ctdb_tunable_wire, name) + wire->length) {
+               return EMSGSIZE;
+       }
+
+       val = talloc(mem_ctx, struct ctdb_tunable);
+       if (val == NULL) {
+               return ENOMEM;
+       }
+
+       val->value = wire->value;
+       val->name = talloc_memdup(val, wire->name, wire->length);
+       if (val->name == NULL) {
+               talloc_free(val);
+               return ENOMEM;
+       }
+
+       *out = val;
+       return 0;
+}
+
+static size_t ctdb_node_flag_change_len_old(struct ctdb_node_flag_change *in)
+{
+       return sizeof(struct ctdb_node_flag_change);
+}
+
+static void ctdb_node_flag_change_push_old(struct ctdb_node_flag_change *in,
+                                          uint8_t *buf)
+{
+       memcpy(buf, in, sizeof(struct ctdb_node_flag_change));
+}
+
+static int ctdb_node_flag_change_pull_old(uint8_t *buf, size_t buflen,
+                                         TALLOC_CTX *mem_ctx,
+                                         struct ctdb_node_flag_change **out)
+{
+       struct ctdb_node_flag_change *val;
+
+       if (buflen < sizeof(struct ctdb_node_flag_change)) {
+               return EMSGSIZE;
+       }
+
+       val = talloc_memdup(mem_ctx, buf,
+                           sizeof(struct ctdb_node_flag_change));
+       if (val == NULL) {
+               return ENOMEM;
+       }
+
+       *out = val;
+       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;
+}
+
+static size_t ctdb_public_ip_len_old(struct ctdb_public_ip *in)
+{
+       return sizeof(struct ctdb_public_ip);
+}
+
+static void ctdb_public_ip_push_old(struct ctdb_public_ip *in, uint8_t *buf)
+{
+       memcpy(buf, in, sizeof(struct ctdb_public_ip));
+}
+
+static int ctdb_public_ip_pull_elems_old(uint8_t *buf, size_t buflen,
+                                        TALLOC_CTX *mem_ctx,
+                                        struct ctdb_public_ip *out)
+{
+       if (buflen < sizeof(struct ctdb_public_ip)) {
+               return EMSGSIZE;
+       }
+
+       memcpy(out, buf, sizeof(struct ctdb_public_ip));
+
+       return 0;
+}
+
+static int ctdb_public_ip_pull_old(uint8_t *buf, size_t buflen,
+                                  TALLOC_CTX *mem_ctx,
+                                  struct ctdb_public_ip **out)
+{
+       struct ctdb_public_ip *val;
+       int ret;
+
+       val = talloc(mem_ctx, struct ctdb_public_ip);
+       if (val == NULL) {
+               return ENOMEM;
+       }
+
+       ret = ctdb_public_ip_pull_elems_old(buf, buflen, val, val);
+       if (ret != 0) {
+               TALLOC_FREE(val);
+               return ret;
+       }
+
+       *out = val;
+       return ret;
+}
+
+struct ctdb_public_ip_list_wire {
+       uint32_t num;
+       struct ctdb_public_ip ip[1];
+};
+
+static size_t ctdb_public_ip_list_len_old(struct ctdb_public_ip_list *in)
+{
+       int i;
+       size_t len;
+
+       len = sizeof(uint32_t);
+       for (i=0; i<in->num; i++) {
+               len += ctdb_public_ip_len_old(&in->ip[i]);
+       }
+       return len;
+}
+
+static void ctdb_public_ip_list_push_old(struct ctdb_public_ip_list *in,
+                                        uint8_t *buf)
+{
+       struct ctdb_public_ip_list_wire *wire =
+               (struct ctdb_public_ip_list_wire *)buf;
+       size_t offset;
+       int i;
+
+       wire->num = in->num;
+
+       offset = offsetof(struct ctdb_public_ip_list_wire, ip);
+       for (i=0; i<in->num; i++) {
+               ctdb_public_ip_push_old(&in->ip[i], &buf[offset]);
+               offset += ctdb_public_ip_len_old(&in->ip[i]);
+       }
+}
+
+static int ctdb_public_ip_list_pull_old(uint8_t *buf, size_t buflen,
+                                       TALLOC_CTX *mem_ctx,
+                                       struct ctdb_public_ip_list **out)
+{
+       struct ctdb_public_ip_list *val;
+       struct ctdb_public_ip_list_wire *wire =
+               (struct ctdb_public_ip_list_wire *)buf;
+       size_t offset;
+       int i;
+       bool ret;
+
+       if (buflen < sizeof(uint32_t)) {
+               return EMSGSIZE;
+       }
+       if (wire->num > buflen / sizeof(struct ctdb_public_ip)) {
+               return EMSGSIZE;
+       }
+       if (sizeof(uint32_t) + wire->num * sizeof(struct ctdb_public_ip) <
+           sizeof(uint32_t)) {
+               return EMSGSIZE;
+       }
+       if (buflen < sizeof(uint32_t) +
+                    wire->num * sizeof(struct ctdb_public_ip)) {
+               return EMSGSIZE;
+       }
+
+       val = talloc(mem_ctx, struct ctdb_public_ip_list);
+       if (val == NULL) {
+               return ENOMEM;
+       }
+
+       val->num = wire->num;
+       if (wire->num == 0) {
+               val->ip = NULL;
+               *out = val;
+               return 0;
+       }
+       val->ip = talloc_array(val, struct ctdb_public_ip, wire->num);
+       if (val->ip == NULL) {
+               talloc_free(val);
+               return ENOMEM;
+       }
+
+       offset = offsetof(struct ctdb_public_ip_list_wire, ip);
+       for (i=0; i<wire->num; i++) {
+               ret = ctdb_public_ip_pull_elems_old(&buf[offset],
+                                                   buflen-offset,
+                                                   val->ip,
+                                                   &val->ip[i]);
+               if (ret != 0) {
+                       talloc_free(val);
+                       return ret;
+               }
+               offset += ctdb_public_ip_len_old(&val->ip[i]);
+       }
+
+       *out = val;
+       return 0;
+}
+
+static size_t ctdb_node_and_flags_len_old(struct ctdb_node_and_flags *in)
+{
+       return sizeof(struct ctdb_node_and_flags);
+}
+
+static void ctdb_node_and_flags_push_old(struct ctdb_node_and_flags *in,
+                                        uint8_t *buf)
+{
+       memcpy(buf, in, sizeof(struct ctdb_node_and_flags));
+}
+
+static int ctdb_node_and_flags_pull_elems_old(TALLOC_CTX *mem_ctx,
+                                             uint8_t *buf, size_t buflen,
+                                             struct ctdb_node_and_flags *out)
+{
+       if (buflen < sizeof(struct ctdb_node_and_flags)) {
+               return EMSGSIZE;
+       }
+
+       memcpy(out, buf, sizeof(struct ctdb_node_and_flags));
+
+       return 0;
+}
+
+static int ctdb_node_and_flags_pull_old(uint8_t *buf, size_t buflen,
+                                       TALLOC_CTX *mem_ctx,
+                                       struct ctdb_node_and_flags **out)
+{
+       struct ctdb_node_and_flags *val;
+       int ret;
+
+       val = talloc(mem_ctx, struct ctdb_node_and_flags);
+       if (val == NULL) {
+               return ENOMEM;
+       }
+
+       ret = ctdb_node_and_flags_pull_elems_old(val, buf, buflen, val);
+       if (ret != 0) {
+               TALLOC_FREE(val);
+               return ret;
+       }
+
+       *out = val;
+       return ret;
+}
+
+struct ctdb_node_map_wire {
+       uint32_t num;
+       struct ctdb_node_and_flags node[1];
+};
+
+static size_t ctdb_node_map_len_old(struct ctdb_node_map *in)
+{
+       return sizeof(uint32_t) +
+              in->num * sizeof(struct ctdb_node_and_flags);
+}
+
+static void ctdb_node_map_push_old(struct ctdb_node_map *in, uint8_t *buf)
+{
+       struct ctdb_node_map_wire *wire = (struct ctdb_node_map_wire *)buf;
+       size_t offset;
+       int i;
+
+       wire->num = in->num;
+
+       offset = offsetof(struct ctdb_node_map_wire, node);
+       for (i=0; i<in->num; i++) {
+               ctdb_node_and_flags_push_old(&in->node[i], &buf[offset]);
+               offset += ctdb_node_and_flags_len_old(&in->node[i]);
+       }
+}
+
+static int ctdb_node_map_pull_old(uint8_t *buf, size_t buflen,
+                                 TALLOC_CTX *mem_ctx,
+                                 struct ctdb_node_map **out)
+{
+       struct ctdb_node_map *val;
+       struct ctdb_node_map_wire *wire = (struct ctdb_node_map_wire *)buf;
+       size_t offset;
+       int i;
+       bool ret;
+
+       if (buflen < sizeof(uint32_t)) {
+               return EMSGSIZE;
+       }
+       if (wire->num > buflen / sizeof(struct ctdb_node_and_flags)) {
+               return EMSGSIZE;
+       }
+       if (sizeof(uint32_t) + wire->num * sizeof(struct ctdb_node_and_flags) <
+           sizeof(uint32_t)) {
+               return EMSGSIZE;
+       }
+       if (buflen < sizeof(uint32_t) +
+                    wire->num * sizeof(struct ctdb_node_and_flags)) {
+               return EMSGSIZE;
+       }
+
+       val = talloc(mem_ctx, struct ctdb_node_map);
+       if (val == NULL) {
+               return ENOMEM;
+       }
+
+       val->num = wire->num;
+       val->node = talloc_array(val, struct ctdb_node_and_flags, wire->num);
+       if (val->node == NULL) {
+               talloc_free(val);
+               return ENOMEM;
+       }
+
+       offset = offsetof(struct ctdb_node_map_wire, node);
+       for (i=0; i<wire->num; i++) {
+               ret = ctdb_node_and_flags_pull_elems_old(val->node,
+                                                        &buf[offset],
+                                                        buflen-offset,
+                                                        &val->node[i]);
+               if (ret != 0) {
+                       talloc_free(val);
+                       return ret;
+               }
+               offset += ctdb_node_and_flags_len_old(&val->node[i]);
+       }
+
+       *out = val;
+       return 0;
+}
+
+static size_t ctdb_script_len_old(struct ctdb_script *in)
+{
+       return sizeof(struct ctdb_script);
+}
+
+static void ctdb_script_push_old(struct ctdb_script *in, uint8_t *buf)
+{
+       memcpy(buf, in, sizeof(struct ctdb_script));
+}
+
+static int ctdb_script_pull_elems_old(uint8_t *buf, size_t buflen,
+                                     TALLOC_CTX *mem_ctx,
+                                     struct ctdb_script *out)
+{
+       if (buflen < sizeof(struct ctdb_script)) {
+               return EMSGSIZE;
+       }
+
+       memcpy(out, buf, sizeof(struct ctdb_script));
+
+       return 0;
+}
+
+static int ctdb_script_pull_old(uint8_t *buf, size_t buflen,
+                               TALLOC_CTX *mem_ctx, struct ctdb_script **out)
+{
+       struct ctdb_script *val;
+       int ret;
+
+       val = talloc(mem_ctx, struct ctdb_script);
+       if (val == NULL) {
+               return ENOMEM;
+       }
+
+       ret = ctdb_script_pull_elems_old(buf, buflen, val, val);
+       if (ret != 0) {
+               TALLOC_FREE(val);
+               return ret;
+       }
+
+       *out = val;
+       return ret;
+}
+
+struct ctdb_script_list_wire {
+       uint32_t num_scripts;
+       struct ctdb_script script[1];
+};
+
+static size_t ctdb_script_list_len_old(struct ctdb_script_list *in)
+{
+       int i;
+       size_t len;
+
+       if (in == NULL) {
+               return 0;
+       }
+
+       len = offsetof(struct ctdb_script_list_wire, script);
+       for (i=0; i<in->num_scripts; i++) {
+               len += ctdb_script_len_old(&in->script[i]);
+       }
+       return len;
+}
+
+static void ctdb_script_list_push_old(struct ctdb_script_list *in,
+                                     uint8_t *buf)
+{
+       struct ctdb_script_list_wire *wire =
+               (struct ctdb_script_list_wire *)buf;
+       size_t offset;
+       int i;
+
+       if (in == NULL) {
+               return;
+       }
+
+       wire->num_scripts = in->num_scripts;
+
+       offset = offsetof(struct ctdb_script_list_wire, script);
+       for (i=0; i<in->num_scripts; i++) {
+               ctdb_script_push_old(&in->script[i], &buf[offset]);
+               offset += ctdb_script_len_old(&in->script[i]);
+       }
+}
+
+static int ctdb_script_list_pull_old(uint8_t *buf, size_t buflen,
+                                    TALLOC_CTX *mem_ctx,
+                                    struct ctdb_script_list **out)
+{
+       struct ctdb_script_list *val;
+       struct ctdb_script_list_wire *wire =
+               (struct ctdb_script_list_wire *)buf;
+       size_t offset;
+       int i;
+       bool ret;
+
+       /* If event scripts have never been run, the result will be NULL */
+       if (buflen == 0) {
+               *out = NULL;
+               return 0;
+       }
+
+       offset = offsetof(struct ctdb_script_list_wire, script);
+
+       if (buflen < offset) {
+               return EMSGSIZE;
+       }
+       if (wire->num_scripts > buflen / sizeof(struct ctdb_script)) {
+               return EMSGSIZE;
+       }
+       if (offset + wire->num_scripts * sizeof(struct ctdb_script) < offset) {
+               return EMSGSIZE;
+       }
+       if (buflen < offset + wire->num_scripts * sizeof(struct ctdb_script)) {
+               return EMSGSIZE;
+       }
+
+       val = talloc(mem_ctx, struct ctdb_script_list);
+       if (val == NULL) {
+               return ENOMEM;
+
+       }
+
+       val->num_scripts = wire->num_scripts;
+       val->script = talloc_array(val, struct ctdb_script, wire->num_scripts);
+       if (val->script == NULL) {
+               talloc_free(val);
+               return ENOMEM;
+       }
+
+       for (i=0; i<wire->num_scripts; i++) {
+               ret = ctdb_script_pull_elems_old(&buf[offset], buflen-offset,
+                                                val->script,
+                                                &val->script[i]);
+               if (ret != 0) {
+                       talloc_free(val);
+                       return ret;
+               }
+               offset += ctdb_script_len_old(&val->script[i]);
+       }
+
+       *out = val;
+       return 0;
+}
+
 
 COMPAT_TYPE3_TEST(struct ctdb_statistics, ctdb_statistics);
 COMPAT_TYPE3_TEST(struct ctdb_vnn_map, ctdb_vnn_map);
@@ -753,6 +1594,20 @@ COMPAT_TYPE3_TEST(struct ctdb_traverse_start_ext, ctdb_traverse_start_ext);
 COMPAT_TYPE3_TEST(struct ctdb_traverse_all_ext, ctdb_traverse_all_ext);
 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);
+COMPAT_TYPE3_TEST(struct ctdb_public_ip, ctdb_public_ip);
+COMPAT_TYPE3_TEST(struct ctdb_public_ip_list, ctdb_public_ip_list);
+COMPAT_TYPE3_TEST(struct ctdb_node_and_flags, ctdb_node_and_flags);
+COMPAT_TYPE3_TEST(struct ctdb_node_map, ctdb_node_map);
+COMPAT_TYPE3_TEST(struct ctdb_script, ctdb_script);
+COMPAT_TYPE3_TEST(struct ctdb_script_list, ctdb_script_list);
 
 int main(int argc, char *argv[])
 {
@@ -775,6 +1630,20 @@ int main(int argc, char *argv[])
        COMPAT_TEST_FUNC(ctdb_traverse_all_ext)();
        COMPAT_TEST_FUNC(ctdb_sock_addr)();
        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)();
+       COMPAT_TEST_FUNC(ctdb_public_ip)();
+       COMPAT_TEST_FUNC(ctdb_public_ip_list)();
+       COMPAT_TEST_FUNC(ctdb_node_and_flags)();
+       COMPAT_TEST_FUNC(ctdb_node_map)();
+       COMPAT_TEST_FUNC(ctdb_script)();
+       COMPAT_TEST_FUNC(ctdb_script_list)();
 
        return 0;
 }