+ rc = 0;
+out:
+ return rc;
+}
+
+static int pb_protocol_deserialise_config_interface(const char **buf,
+ unsigned int *len, struct interface_config *iface)
+{
+ unsigned int tmp;
+
+ if (*len < sizeof(iface->hwaddr))
+ return -1;
+
+ memcpy(iface->hwaddr, *buf, sizeof(iface->hwaddr));
+ *buf += sizeof(iface->hwaddr);
+ *len -= sizeof(iface->hwaddr);
+
+ if (read_u32(buf, len, &tmp))
+ return -1;
+ iface->ignore = !!tmp;
+
+ if (iface->ignore)
+ return 0;
+
+ if (read_u32(buf, len, &iface->method))
+ return -1;
+
+ if (iface->method == CONFIG_METHOD_STATIC) {
+ if (read_string(iface, buf, len, &iface->static_config.address))
+ return -1;
+
+ if (read_string(iface, buf, len, &iface->static_config.gateway))
+ return -1;
+
+ if (read_string(iface, buf, len, &iface->static_config.url))
+ return -1;
+ }
+
+ if (read_u32(buf, len, &tmp))
+ return -1;
+ iface->override = !!tmp;
+
+ return 0;
+}
+
+int pb_protocol_deserialise_config(struct config *config,
+ const struct pb_protocol_message *message)
+{
+ unsigned int len, i, tmp;
+ const char *pos;
+ int rc = -1;
+ char *str;
+
+ len = message->payload_len;
+ pos = message->payload;
+
+ if (read_u32(&pos, &len, &tmp))
+ goto out;
+ config->autoboot_enabled = !!tmp;
+
+ if (read_u32(&pos, &len, &config->autoboot_timeout_sec))
+ goto out;
+
+ if (read_u32(&pos, &len, &tmp))
+ goto out;
+ config->safe_mode = !!tmp;
+
+ if (read_u32(&pos, &len, &config->network.n_interfaces))
+ goto out;
+
+ config->network.interfaces = talloc_array(config,
+ struct interface_config *, config->network.n_interfaces);
+
+ for (i = 0; i < config->network.n_interfaces; i++) {
+ struct interface_config *iface = talloc_zero(
+ config->network.interfaces,
+ struct interface_config);
+ if (pb_protocol_deserialise_config_interface(&pos, &len, iface))
+ goto out;
+ config->network.interfaces[i] = iface;
+ }
+
+ if (read_u32(&pos, &len, &config->network.n_dns_servers))
+ goto out;
+ config->network.dns_servers = talloc_array(config, const char *,
+ config->network.n_dns_servers);
+
+ for (i = 0; i < config->network.n_dns_servers; i++) {
+ if (read_string(config->network.dns_servers, &pos, &len, &str))
+ goto out;
+ config->network.dns_servers[i] = str;
+ }
+
+ if (read_string(config, &pos, &len, &str))
+ goto out;
+ config->http_proxy = str;
+ if (read_string(config, &pos, &len, &str))
+ goto out;
+ config->https_proxy = str;
+
+ if (read_u32(&pos, &len, &config->n_autoboot_opts))
+ goto out;
+ config->autoboot_opts = talloc_array(config, struct autoboot_option,
+ config->n_autoboot_opts);
+
+ for (i = 0; i < config->n_autoboot_opts; i++) {
+ if (read_u32(&pos, &len, &tmp))
+ goto out;
+ config->autoboot_opts[i].boot_type = (int)tmp;
+ if (config->autoboot_opts[i].boot_type == BOOT_DEVICE_TYPE) {
+ if (read_u32(&pos, &len, &tmp))
+ goto out;
+ config->autoboot_opts[i].type = tmp;
+ } else {
+ if (read_string(config, &pos, &len, &str))
+ goto out;
+ config->autoboot_opts[i].uuid = str;
+ }
+ }
+
+ if (read_u32(&pos, &len, &config->ipmi_bootdev))
+ goto out;
+ if (read_u32(&pos, &len, &tmp))
+ goto out;
+ config->ipmi_bootdev_persistent = !!tmp;
+
+ if (read_u32(&pos, &len, &tmp))
+ goto out;
+ config->allow_writes = !!tmp;
+
+ if (read_u32(&pos, &len, &config->n_consoles))
+ goto out;
+
+ config->consoles = talloc_array(config, char *, config->n_consoles);
+ for (i = 0; i < config->n_consoles; i++) {
+ if (read_string(config->consoles, &pos, &len, &str))
+ goto out;
+ config->consoles[i] = str;
+ }
+
+ if (read_string(config, &pos, &len, &str))
+ goto out;
+
+ config->boot_console = str;
+
+ if (read_u32(&pos, &len, &tmp))
+ goto out;
+ config->manual_console = !!tmp;
+
+ if (read_string(config, &pos, &len, &str))
+ goto out;
+
+ config->lang = str;
+
+ rc = 0;
+
+out:
+ return rc;
+}
+
+int pb_protocol_deserialise_plugin_option(struct plugin_option *opt,
+ const struct pb_protocol_message *message)
+{
+ unsigned int len, i, tmp;
+ const char *pos;
+ int rc = -1;
+ char *str;
+
+ len = message->payload_len;
+ pos = message->payload;
+
+ if (read_string(opt, &pos, &len, &str))
+ goto out;
+ opt->id = str;
+
+ if (read_string(opt, &pos, &len, &str))
+ goto out;
+ opt->name = str;
+
+ if (read_string(opt, &pos, &len, &str))
+ goto out;
+ opt->vendor = str;
+
+ if (read_string(opt, &pos, &len, &str))
+ goto out;
+ opt->vendor_id = str;
+
+ if (read_string(opt, &pos, &len, &str))
+ goto out;
+ opt->version = str;
+
+ if (read_string(opt, &pos, &len, &str))
+ goto out;
+ opt->date = str;
+
+ if (read_string(opt, &pos, &len, &str))
+ goto out;
+ opt->plugin_file = str;
+
+ if (read_u32(&pos, &len, &tmp))
+ goto out;
+ opt->n_executables = tmp;
+
+ opt->executables = talloc_zero_array(opt, char *, opt->n_executables);
+ if (!opt->executables)
+ goto out;
+
+ for (i = 0; i < opt->n_executables; i++) {
+ if (read_string(opt, &pos, &len, &str))
+ goto out;
+ opt->executables[i] = talloc_strdup(opt, str);
+ }
+
+ rc = 0;
+out:
+ return rc;
+}
+
+int pb_protocol_deserialise_temp_autoboot(struct autoboot_option *opt,
+ const struct pb_protocol_message *message)
+{
+ unsigned int len, tmp;
+ const char *pos;
+ int rc = -1;
+ char *str;
+
+ len = message->payload_len;
+ pos = message->payload;
+
+ if (read_u32(&pos, &len, &tmp))
+ goto out;
+
+ opt->boot_type = tmp;
+ if (opt->boot_type == BOOT_DEVICE_TYPE) {
+ if (read_u32(&pos, &len, &tmp))
+ goto out;
+ opt->type = tmp;
+
+ } else if (opt->boot_type == BOOT_DEVICE_UUID) {
+ if (read_string(opt, &pos, &len, &str))
+ goto out;
+ opt->uuid = str;
+
+ } else {
+ return -1;
+ }
+
+ rc = 0;
+
+out:
+ return rc;
+}
+
+int pb_protocol_deserialise_authenticate(struct auth_message *msg,
+ const struct pb_protocol_message *message)
+{
+ unsigned int len;
+ const char *pos;
+
+ len = message->payload_len;
+ pos = message->payload;
+
+ msg->op = *(enum auth_msg_type *)pos;
+ pos += sizeof(enum auth_msg_type);
+
+ switch (msg->op) {
+ case AUTH_MSG_REQUEST:
+ if (read_string(msg, &pos, &len, &msg->password))
+ return -1;
+ break;
+ case AUTH_MSG_RESPONSE:
+ msg->authenticated = *(bool *)pos;
+ pos += sizeof(bool);
+ break;
+ case AUTH_MSG_SET:
+ if (read_string(msg, &pos, &len, &msg->set_password.password))
+ return -1;
+ if (read_string(msg, &pos, &len,
+ &msg->set_password.new_password))
+ return -1;
+ break;
+ default:
+ pb_log("%s: unable to parse\n", __func__);
+ return -1;
+ }
+
+ return 0;