aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/ctld/uclparse.cc
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/ctld/uclparse.cc')
-rw-r--r--usr.sbin/ctld/uclparse.cc1279
1 files changed, 794 insertions, 485 deletions
diff --git a/usr.sbin/ctld/uclparse.cc b/usr.sbin/ctld/uclparse.cc
index 1eb9f7736e4b..8a62636ffec6 100644
--- a/usr.sbin/ctld/uclparse.cc
+++ b/usr.sbin/ctld/uclparse.cc
@@ -37,297 +37,392 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
-#include <ucl.h>
+#include <ucl++.h>
#include <netinet/in.h>
#include <netinet/ip.h>
+#include <libutil++.hh>
+#include <memory>
+
#include "conf.h"
-#include "ctld.h"
-
-static bool uclparse_toplevel(const ucl_object_t *);
-static bool uclparse_chap(const char *, const ucl_object_t *);
-static bool uclparse_chap_mutual(const char *, const ucl_object_t *);
-static bool uclparse_lun(const char *, const ucl_object_t *);
-static bool uclparse_lun_entries(const char *, const ucl_object_t *);
-static bool uclparse_auth_group(const char *, const ucl_object_t *);
-static bool uclparse_portal_group(const char *, const ucl_object_t *);
-static bool uclparse_target(const char *, const ucl_object_t *);
-static bool uclparse_target_portal_group(const char *, const ucl_object_t *);
-static bool uclparse_target_lun(const char *, const ucl_object_t *);
+#include "ctld.hh"
+
+struct scope_exit {
+ using callback = void();
+ scope_exit(callback *fn) : fn(fn) {}
+
+ ~scope_exit() { fn(); }
+
+private:
+ callback *fn;
+};
+
+static bool uclparse_toplevel(const ucl::Ucl &);
+static bool uclparse_chap(const char *, const ucl::Ucl &);
+static bool uclparse_chap_mutual(const char *, const ucl::Ucl &);
+static bool uclparse_lun(const char *, const ucl::Ucl &);
+static bool uclparse_lun_entries(const char *, const ucl::Ucl &);
+static bool uclparse_auth_group(const char *, const ucl::Ucl &);
+static bool uclparse_portal_group(const char *, const ucl::Ucl &);
+static bool uclparse_transport_group(const char *, const ucl::Ucl &);
+static bool uclparse_controller(const char *, const ucl::Ucl &);
+static bool uclparse_controller_transport_group(const char *, const ucl::Ucl &);
+static bool uclparse_controller_namespace(const char *, const ucl::Ucl &);
+static bool uclparse_target(const char *, const ucl::Ucl &);
+static bool uclparse_target_portal_group(const char *, const ucl::Ucl &);
+static bool uclparse_target_lun(const char *, const ucl::Ucl &);
static bool
-uclparse_chap(const char *ag_name, const ucl_object_t *obj)
+uclparse_chap(const char *ag_name, const ucl::Ucl &obj)
{
- const ucl_object_t *user, *secret;
-
- user = ucl_object_find_key(obj, "user");
- if (!user || user->type != UCL_STRING) {
+ auto user = obj["user"];
+ if (!user || user.type() != UCL_STRING) {
log_warnx("chap section in auth-group \"%s\" is missing "
"\"user\" string key", ag_name);
return (false);
}
- secret = ucl_object_find_key(obj, "secret");
- if (!secret || secret->type != UCL_STRING) {
+ auto secret = obj["secret"];
+ if (!secret || secret.type() != UCL_STRING) {
log_warnx("chap section in auth-group \"%s\" is missing "
"\"secret\" string key", ag_name);
return (false);
}
return (auth_group_add_chap(
- ucl_object_tostring(user),
- ucl_object_tostring(secret)));
+ user.string_value().c_str(),
+ secret.string_value().c_str()));
}
static bool
-uclparse_chap_mutual(const char *ag_name, const ucl_object_t *obj)
+uclparse_chap_mutual(const char *ag_name, const ucl::Ucl &obj)
{
- const ucl_object_t *user, *secret, *mutual_user;
- const ucl_object_t *mutual_secret;
-
- user = ucl_object_find_key(obj, "user");
- if (!user || user->type != UCL_STRING) {
+ auto user = obj["user"];
+ if (!user || user.type() != UCL_STRING) {
log_warnx("chap-mutual section in auth-group \"%s\" is missing "
"\"user\" string key", ag_name);
return (false);
}
- secret = ucl_object_find_key(obj, "secret");
- if (!secret || secret->type != UCL_STRING) {
+ auto secret = obj["secret"];
+ if (!secret || secret.type() != UCL_STRING) {
log_warnx("chap-mutual section in auth-group \"%s\" is missing "
"\"secret\" string key", ag_name);
return (false);
}
- mutual_user = ucl_object_find_key(obj, "mutual-user");
- if (!mutual_user || mutual_user->type != UCL_STRING) {
+ auto mutual_user = obj["mutual-user"];
+ if (!mutual_user || mutual_user.type() != UCL_STRING) {
log_warnx("chap-mutual section in auth-group \"%s\" is missing "
"\"mutual-user\" string key", ag_name);
return (false);
}
- mutual_secret = ucl_object_find_key(obj, "mutual-secret");
- if (!mutual_secret || mutual_secret->type != UCL_STRING) {
+ auto mutual_secret = obj["mutual-secret"];
+ if (!mutual_secret || mutual_secret.type() != UCL_STRING) {
log_warnx("chap-mutual section in auth-group \"%s\" is missing "
"\"mutual-secret\" string key", ag_name);
return (false);
}
return (auth_group_add_chap_mutual(
- ucl_object_tostring(user),
- ucl_object_tostring(secret),
- ucl_object_tostring(mutual_user),
- ucl_object_tostring(mutual_secret)));
+ user.string_value().c_str(),
+ secret.string_value().c_str(),
+ mutual_user.string_value().c_str(),
+ mutual_secret.string_value().c_str()));
}
static bool
-uclparse_target_chap(const char *t_name, const ucl_object_t *obj)
+uclparse_target_chap(const char *t_name, const ucl::Ucl &obj)
{
- const ucl_object_t *user, *secret;
-
- user = ucl_object_find_key(obj, "user");
- if (!user || user->type != UCL_STRING) {
+ auto user = obj["user"];
+ if (!user || user.type() != UCL_STRING) {
log_warnx("chap section in target \"%s\" is missing "
"\"user\" string key", t_name);
return (false);
}
- secret = ucl_object_find_key(obj, "secret");
- if (!secret || secret->type != UCL_STRING) {
+ auto secret = obj["secret"];
+ if (!secret || secret.type() != UCL_STRING) {
log_warnx("chap section in target \"%s\" is missing "
"\"secret\" string key", t_name);
return (false);
}
return (target_add_chap(
- ucl_object_tostring(user),
- ucl_object_tostring(secret)));
+ user.string_value().c_str(),
+ secret.string_value().c_str()));
}
static bool
-uclparse_target_chap_mutual(const char *t_name, const ucl_object_t *obj)
+uclparse_target_chap_mutual(const char *t_name, const ucl::Ucl &obj)
{
- const ucl_object_t *user, *secret, *mutual_user;
- const ucl_object_t *mutual_secret;
-
- user = ucl_object_find_key(obj, "user");
- if (!user || user->type != UCL_STRING) {
+ auto user = obj["user"];
+ if (!user || user.type() != UCL_STRING) {
log_warnx("chap-mutual section in target \"%s\" is missing "
"\"user\" string key", t_name);
return (false);
}
- secret = ucl_object_find_key(obj, "secret");
- if (!secret || secret->type != UCL_STRING) {
+ auto secret = obj["secret"];
+ if (!secret || secret.type() != UCL_STRING) {
log_warnx("chap-mutual section in target \"%s\" is missing "
"\"secret\" string key", t_name);
return (false);
}
- mutual_user = ucl_object_find_key(obj, "mutual-user");
- if (!mutual_user || mutual_user->type != UCL_STRING) {
+ auto mutual_user = obj["mutual-user"];
+ if (!mutual_user || mutual_user.type() != UCL_STRING) {
log_warnx("chap-mutual section in target \"%s\" is missing "
"\"mutual-user\" string key", t_name);
return (false);
}
- mutual_secret = ucl_object_find_key(obj, "mutual-secret");
- if (!mutual_secret || mutual_secret->type != UCL_STRING) {
+ auto mutual_secret = obj["mutual-secret"];
+ if (!mutual_secret || mutual_secret.type() != UCL_STRING) {
log_warnx("chap-mutual section in target \"%s\" is missing "
"\"mutual-secret\" string key", t_name);
return (false);
}
return (target_add_chap_mutual(
- ucl_object_tostring(user),
- ucl_object_tostring(secret),
- ucl_object_tostring(mutual_user),
- ucl_object_tostring(mutual_secret)));
+ user.string_value().c_str(),
+ secret.string_value().c_str(),
+ mutual_user.string_value().c_str(),
+ mutual_secret.string_value().c_str()));
}
static bool
-uclparse_target_portal_group(const char *t_name, const ucl_object_t *obj)
+uclparse_target_portal_group(const char *t_name, const ucl::Ucl &obj)
{
- const ucl_object_t *portal_group, *auth_group;
- const char *ag_name;
-
/*
* If the value is a single string, assume it is a
* portal-group name.
*/
- if (obj->type == UCL_STRING)
- return (target_add_portal_group(ucl_object_tostring(obj),
+ if (obj.type() == UCL_STRING)
+ return (target_add_portal_group(obj.string_value().c_str(),
NULL));
- if (obj->type != UCL_OBJECT) {
+ if (obj.type() != UCL_OBJECT) {
log_warnx("portal-group section in target \"%s\" must be "
"an object or string", t_name);
return (false);
}
- portal_group = ucl_object_find_key(obj, "name");
- if (!portal_group || portal_group->type != UCL_STRING) {
+ auto portal_group = obj["name"];
+ if (!portal_group || portal_group.type() != UCL_STRING) {
log_warnx("portal-group section in target \"%s\" is missing "
"\"name\" string key", t_name);
return (false);
}
- auth_group = ucl_object_find_key(obj, "auth-group-name");
- if (auth_group != NULL) {
- if (auth_group->type != UCL_STRING) {
+ auto auth_group = obj["auth-group-name"];
+ if (auth_group) {
+ if (auth_group.type() != UCL_STRING) {
log_warnx("\"auth-group-name\" property in "
"portal-group section for target \"%s\" is not "
"a string", t_name);
return (false);
}
- ag_name = ucl_object_tostring(auth_group);
- } else
- ag_name = NULL;
+ return (target_add_portal_group(
+ portal_group.string_value().c_str(),
+ auth_group.string_value().c_str()));
+ }
+
+ return (target_add_portal_group(portal_group.string_value().c_str(),
+ NULL));
+}
+
+static bool
+uclparse_controller_transport_group(const char *t_name, const ucl::Ucl &obj)
+{
+ /*
+ * If the value is a single string, assume it is a
+ * transport-group name.
+ */
+ if (obj.type() == UCL_STRING)
+ return target_add_portal_group(obj.string_value().c_str(),
+ nullptr);
+
+ if (obj.type() != UCL_OBJECT) {
+ log_warnx("transport-group section in controller \"%s\" must "
+ "be an object or string", t_name);
+ return false;
+ }
+
+ auto portal_group = obj["name"];
+ if (!portal_group || portal_group.type() != UCL_STRING) {
+ log_warnx("transport-group section in controller \"%s\" is "
+ "missing \"name\" string key", t_name);
+ return false;
+ }
+
+ auto auth_group = obj["auth-group-name"];
+ if (auth_group) {
+ if (auth_group.type() != UCL_STRING) {
+ log_warnx("\"auth-group-name\" property in "
+ "transport-group section for controller \"%s\" is "
+ "not a string", t_name);
+ return false;
+ }
+ return target_add_portal_group(
+ portal_group.string_value().c_str(),
+ auth_group.string_value().c_str());
+ }
- return (target_add_portal_group(ucl_object_tostring(portal_group),
- ag_name));
+ return target_add_portal_group(portal_group.string_value().c_str(),
+ nullptr);
}
static bool
-uclparse_target_lun(const char *t_name, const ucl_object_t *obj)
+uclparse_target_lun(const char *t_name, const ucl::Ucl &obj)
{
- const ucl_object_t *num;
- const ucl_object_t *name;
- const char *key;
- char *end, *lun_name;
+ char *end;
u_int id;
- bool ok;
- key = ucl_object_key(obj);
- if (key != NULL) {
- id = strtoul(key, &end, 0);
+ std::string key = obj.key();
+ if (!key.empty()) {
+ id = strtoul(key.c_str(), &end, 0);
if (*end != '\0') {
log_warnx("lun key \"%s\" in target \"%s\" is invalid",
- key, t_name);
+ key.c_str(), t_name);
return (false);
}
- if (obj->type == UCL_STRING)
- return (target_add_lun(id, ucl_object_tostring(obj)));
+ if (obj.type() == UCL_STRING)
+ return (target_add_lun(id, obj.string_value().c_str()));
}
- if (obj->type != UCL_OBJECT) {
+ if (obj.type() != UCL_OBJECT) {
log_warnx("lun section entries in target \"%s\" must be objects",
t_name);
return (false);
}
- if (key == NULL) {
- num = ucl_object_find_key(obj, "number");
- if (num == NULL || num->type != UCL_INT) {
+ if (key.empty()) {
+ auto num = obj["number"];
+ if (!num || num.type() != UCL_INT) {
log_warnx("lun section in target \"%s\" is missing "
"\"number\" integer property", t_name);
return (false);
}
- id = ucl_object_toint(num);
+ id = num.int_value();
}
- name = ucl_object_find_key(obj, "name");
- if (name == NULL) {
+ auto name = obj["name"];
+ if (!name) {
if (!target_start_lun(id))
return (false);
- asprintf(&lun_name, "lun %u for target \"%s\"", id, t_name);
- ok = uclparse_lun_entries(lun_name, obj);
- free(lun_name);
- return (ok);
+ scope_exit finisher(lun_finish);
+ std::string lun_name =
+ freebsd::stringf("lun %u for target \"%s\"", id, t_name);
+ return (uclparse_lun_entries(lun_name.c_str(), obj));
}
- if (name->type != UCL_STRING) {
+ if (name.type() != UCL_STRING) {
log_warnx("\"name\" property for lun %u for target "
"\"%s\" is not a string", id, t_name);
return (false);
}
- return (target_add_lun(id, ucl_object_tostring(name)));
+ return (target_add_lun(id, name.string_value().c_str()));
}
static bool
-uclparse_toplevel(const ucl_object_t *top)
+uclparse_controller_namespace(const char *t_name, const ucl::Ucl &obj)
{
- ucl_object_iter_t it = NULL, iter = NULL;
- const ucl_object_t *obj = NULL, *child = NULL;
+ char *end;
+ u_int id;
+
+ std::string key = obj.key();
+ if (!key.empty()) {
+ id = strtoul(key.c_str(), &end, 0);
+ if (*end != '\0') {
+ log_warnx("namespace key \"%s\" in controller \"%s\""
+ " is invalid", key.c_str(), t_name);
+ return false;
+ }
+
+ if (obj.type() == UCL_STRING)
+ return controller_add_namespace(id,
+ obj.string_value().c_str());
+ }
+
+ if (obj.type() != UCL_OBJECT) {
+ log_warnx("namespace section entries in controller \"%s\""
+ " must be objects", t_name);
+ return false;
+ }
+
+ if (key.empty()) {
+ auto num = obj["number"];
+ if (!num || num.type() != UCL_INT) {
+ log_warnx("namespace section in controller \"%s\" is "
+ "missing \"id\" integer property", t_name);
+ return (false);
+ }
+ id = num.int_value();
+ }
+
+ auto name = obj["name"];
+ if (!name) {
+ if (!controller_start_namespace(id))
+ return false;
+
+ std::string lun_name =
+ freebsd::stringf("namespace %u for controller \"%s\"", id,
+ t_name);
+ return uclparse_lun_entries(lun_name.c_str(), obj);
+ }
+
+ if (name.type() != UCL_STRING) {
+ log_warnx("\"name\" property for namespace %u for "
+ "controller \"%s\" is not a string", id, t_name);
+ return (false);
+ }
+ return controller_add_namespace(id, name.string_value().c_str());
+}
+
+static bool
+uclparse_toplevel(const ucl::Ucl &top)
+{
/* Pass 1 - everything except targets */
- while ((obj = ucl_iterate_object(top, &it, true))) {
- const char *key = ucl_object_key(obj);
+ for (const auto &obj : top) {
+ std::string key = obj.key();
- if (strcmp(key, "debug") == 0) {
- if (obj->type == UCL_INT)
- conf_set_debug(ucl_object_toint(obj));
+ if (key == "debug") {
+ if (obj.type() == UCL_INT)
+ conf_set_debug(obj.int_value());
else {
log_warnx("\"debug\" property value is not integer");
return (false);
}
}
- if (strcmp(key, "timeout") == 0) {
- if (obj->type == UCL_INT)
- conf_set_timeout(ucl_object_toint(obj));
+ if (key == "timeout") {
+ if (obj.type() == UCL_INT)
+ conf_set_timeout(obj.int_value());
else {
log_warnx("\"timeout\" property value is not integer");
return (false);
}
}
- if (strcmp(key, "maxproc") == 0) {
- if (obj->type == UCL_INT)
- conf_set_maxproc(ucl_object_toint(obj));
+ if (key == "maxproc") {
+ if (obj.type() == UCL_INT)
+ conf_set_maxproc(obj.int_value());
else {
log_warnx("\"maxproc\" property value is not integer");
return (false);
}
}
- if (strcmp(key, "pidfile") == 0) {
- if (obj->type == UCL_STRING) {
+ if (key == "pidfile") {
+ if (obj.type() == UCL_STRING) {
if (!conf_set_pidfile_path(
- ucl_object_tostring(obj)))
+ obj.string_value().c_str()))
return (false);
} else {
log_warnx("\"pidfile\" property value is not string");
@@ -335,16 +430,14 @@ uclparse_toplevel(const ucl_object_t *top)
}
}
- if (strcmp(key, "isns-server") == 0) {
- if (obj->type == UCL_ARRAY) {
- iter = NULL;
- while ((child = ucl_iterate_object(obj, &iter,
- true))) {
- if (child->type != UCL_STRING)
+ if (key == "isns-server") {
+ if (obj.type() == UCL_ARRAY) {
+ for (const auto &child : obj) {
+ if (child.type() != UCL_STRING)
return (false);
if (!isns_add_server(
- ucl_object_tostring(child)))
+ child.string_value().c_str()))
return (false);
}
} else {
@@ -354,30 +447,29 @@ uclparse_toplevel(const ucl_object_t *top)
}
}
- if (strcmp(key, "isns-period") == 0) {
- if (obj->type == UCL_INT)
- conf_set_isns_period(ucl_object_toint(obj));
+ if (key == "isns-period") {
+ if (obj.type() == UCL_INT)
+ conf_set_isns_period(obj.int_value());
else {
log_warnx("\"isns-period\" property value is not integer");
return (false);
}
}
- if (strcmp(key, "isns-timeout") == 0) {
- if (obj->type == UCL_INT)
- conf_set_isns_timeout(ucl_object_toint(obj));
+ if (key == "isns-timeout") {
+ if (obj.type() == UCL_INT)
+ conf_set_isns_timeout(obj.int_value());
else {
log_warnx("\"isns-timeout\" property value is not integer");
return (false);
}
}
- if (strcmp(key, "auth-group") == 0) {
- if (obj->type == UCL_OBJECT) {
- iter = NULL;
- while ((child = ucl_iterate_object(obj, &iter, true))) {
+ if (key == "auth-group") {
+ if (obj.type() == UCL_OBJECT) {
+ for (const auto &child : obj) {
if (!uclparse_auth_group(
- ucl_object_key(child), child))
+ child.key().c_str(), child))
return (false);
}
} else {
@@ -386,12 +478,11 @@ uclparse_toplevel(const ucl_object_t *top)
}
}
- if (strcmp(key, "portal-group") == 0) {
- if (obj->type == UCL_OBJECT) {
- iter = NULL;
- while ((child = ucl_iterate_object(obj, &iter, true))) {
+ if (key == "portal-group") {
+ if (obj.type() == UCL_OBJECT) {
+ for (const auto &child : obj) {
if (!uclparse_portal_group(
- ucl_object_key(child), child))
+ child.key().c_str(), child))
return (false);
}
} else {
@@ -400,11 +491,23 @@ uclparse_toplevel(const ucl_object_t *top)
}
}
- if (strcmp(key, "lun") == 0) {
- if (obj->type == UCL_OBJECT) {
- iter = NULL;
- while ((child = ucl_iterate_object(obj, &iter, true))) {
- if (!uclparse_lun(ucl_object_key(child),
+ if (key == "transport-group") {
+ if (obj.type() == UCL_OBJECT) {
+ for (const auto &child : obj) {
+ if (!uclparse_transport_group(
+ child.key().c_str(), child))
+ return false;
+ }
+ } else {
+ log_warnx("\"transport-group\" section is not an object");
+ return false;
+ }
+ }
+
+ if (key == "lun") {
+ if (obj.type() == UCL_OBJECT) {
+ for (const auto &child : obj) {
+ if (!uclparse_lun(child.key().c_str(),
child))
return (false);
}
@@ -416,17 +519,27 @@ uclparse_toplevel(const ucl_object_t *top)
}
/* Pass 2 - targets */
- it = NULL;
- while ((obj = ucl_iterate_object(top, &it, true))) {
- const char *key = ucl_object_key(obj);
-
- if (strcmp(key, "target") == 0) {
- if (obj->type == UCL_OBJECT) {
- iter = NULL;
- while ((child = ucl_iterate_object(obj, &iter,
- true))) {
+ for (const auto &obj : top) {
+ std::string key = obj.key();
+
+ if (key == "controller") {
+ if (obj.type() == UCL_OBJECT) {
+ for (const auto &child : obj) {
+ if (!uclparse_controller(
+ child.key().c_str(), child))
+ return false;
+ }
+ } else {
+ log_warnx("\"controller\" section is not an object");
+ return false;
+ }
+ }
+
+ if (key == "target") {
+ if (obj.type() == UCL_OBJECT) {
+ for (const auto &child : obj) {
if (!uclparse_target(
- ucl_object_key(child), child))
+ child.key().c_str(), child))
return (false);
}
} else {
@@ -440,179 +553,190 @@ uclparse_toplevel(const ucl_object_t *top)
}
static bool
-uclparse_auth_group(const char *name, const ucl_object_t *top)
+uclparse_auth_group(const char *name, const ucl::Ucl &top)
{
- ucl_object_iter_t it = NULL, it2 = NULL;
- const ucl_object_t *obj = NULL, *tmp = NULL;
- const char *key;
-
if (!auth_group_start(name))
return (false);
- while ((obj = ucl_iterate_object(top, &it, true))) {
- key = ucl_object_key(obj);
+ scope_exit finisher(auth_group_finish);
+ for (const auto &obj : top) {
+ std::string key = obj.key();
- if (strcmp(key, "auth-type") == 0) {
- const char *value = ucl_object_tostring(obj);
-
- if (!auth_group_set_type(value))
- goto fail;
+ if (key == "auth-type") {
+ if (!auth_group_set_type(obj.string_value().c_str()))
+ return false;
}
- if (strcmp(key, "chap") == 0) {
- if (obj->type == UCL_OBJECT) {
+ if (key == "chap") {
+ if (obj.type() == UCL_OBJECT) {
if (!uclparse_chap(name, obj))
- goto fail;
- } else if (obj->type == UCL_ARRAY) {
- it2 = NULL;
- while ((tmp = ucl_iterate_object(obj, &it2,
- true))) {
+ return false;
+ } else if (obj.type() == UCL_ARRAY) {
+ for (const auto &tmp : obj) {
if (!uclparse_chap(name, tmp))
- goto fail;
+ return false;
}
} else {
log_warnx("\"chap\" property of auth-group "
"\"%s\" is not an array or object",
name);
- goto fail;
+ return false;
}
}
- if (strcmp(key, "chap-mutual") == 0) {
- if (obj->type == UCL_OBJECT) {
+ if (key == "chap-mutual") {
+ if (obj.type() == UCL_OBJECT) {
if (!uclparse_chap_mutual(name, obj))
- goto fail;
- } else if (obj->type == UCL_ARRAY) {
- it2 = NULL;
- while ((tmp = ucl_iterate_object(obj, &it2,
- true))) {
+ return false;
+ } else if (obj.type() == UCL_ARRAY) {
+ for (const auto &tmp : obj) {
if (!uclparse_chap_mutual(name, tmp))
- goto fail;
+ return false;
}
} else {
log_warnx("\"chap-mutual\" property of "
"auth-group \"%s\" is not an array or object",
name);
- goto fail;
+ return false;
}
}
- if (strcmp(key, "initiator-name") == 0) {
- if (obj->type == UCL_STRING) {
- const char *value = ucl_object_tostring(obj);
+ if (key == "host-address") {
+ if (obj.type() == UCL_STRING) {
+ if (!auth_group_add_host_address(
+ obj.string_value().c_str()))
+ return false;
+ } else if (obj.type() == UCL_ARRAY) {
+ for (const auto &tmp : obj) {
+ if (!auth_group_add_host_address(
+ tmp.string_value().c_str()))
+ return false;
+ }
+ } else {
+ log_warnx("\"host-address\" property of "
+ "auth-group \"%s\" is not an array or string",
+ name);
+ return false;
+ }
+ }
- if (!auth_group_add_initiator_name(value))
- goto fail;
- } else if (obj->type == UCL_ARRAY) {
- it2 = NULL;
- while ((tmp = ucl_iterate_object(obj, &it2,
- true))) {
- const char *value =
- ucl_object_tostring(tmp);
+ if (key == "host-nqn") {
+ if (obj.type() == UCL_STRING) {
+ if (!auth_group_add_host_nqn(
+ obj.string_value().c_str()))
+ return false;
+ } else if (obj.type() == UCL_ARRAY) {
+ for (const auto &tmp : obj) {
+ if (!auth_group_add_host_nqn(
+ tmp.string_value().c_str()))
+ return false;
+ }
+ } else {
+ log_warnx("\"host-nqn\" property of "
+ "auth-group \"%s\" is not an array or string",
+ name);
+ return false;
+ }
+ }
+ if (key == "initiator-name") {
+ if (obj.type() == UCL_STRING) {
+ if (!auth_group_add_initiator_name(
+ obj.string_value().c_str()))
+ return false;
+ } else if (obj.type() == UCL_ARRAY) {
+ for (const auto &tmp : obj) {
if (!auth_group_add_initiator_name(
- value))
- goto fail;
+ tmp.string_value().c_str()))
+ return false;
}
} else {
log_warnx("\"initiator-name\" property of "
"auth-group \"%s\" is not an array or string",
name);
- goto fail;
+ return false;
}
}
- if (strcmp(key, "initiator-portal") == 0) {
- if (obj->type == UCL_STRING) {
- const char *value = ucl_object_tostring(obj);
-
- if (!auth_group_add_initiator_portal(value))
- goto fail;
- } else if (obj->type == UCL_ARRAY) {
- it2 = NULL;
- while ((tmp = ucl_iterate_object(obj, &it2,
- true))) {
- const char *value =
- ucl_object_tostring(tmp);
-
+ if (key == "initiator-portal") {
+ if (obj.type() == UCL_STRING) {
+ if (!auth_group_add_initiator_portal(
+ obj.string_value().c_str()))
+ return false;
+ } else if (obj.type() == UCL_ARRAY) {
+ for (const auto &tmp : obj) {
if (!auth_group_add_initiator_portal(
- value))
- goto fail;
+ tmp.string_value().c_str()))
+ return false;
}
} else {
log_warnx("\"initiator-portal\" property of "
"auth-group \"%s\" is not an array or string",
name);
- goto fail;
+ return false;
}
}
}
- auth_group_finish();
return (true);
-fail:
- auth_group_finish();
- return (false);
}
static bool
uclparse_dscp(const char *group_type, const char *pg_name,
- const ucl_object_t *obj)
+ const ucl::Ucl &obj)
{
- const char *key;
-
- if ((obj->type != UCL_STRING) && (obj->type != UCL_INT)) {
+ if ((obj.type() != UCL_STRING) && (obj.type() != UCL_INT)) {
log_warnx("\"dscp\" property of %s group \"%s\" is not a "
"string or integer", group_type, pg_name);
return (false);
}
- if (obj->type == UCL_INT)
- return (portal_group_set_dscp(ucl_object_toint(obj)));
+ if (obj.type() == UCL_INT)
+ return (portal_group_set_dscp(obj.int_value()));
- key = ucl_object_tostring(obj);
- if (strcmp(key, "be") == 0 || strcmp(key, "cs0") == 0)
+ std::string key = obj.key();
+ if (key == "be" || key == "cs0")
portal_group_set_dscp(IPTOS_DSCP_CS0 >> 2);
- else if (strcmp(key, "ef") == 0)
+ else if (key == "ef")
portal_group_set_dscp(IPTOS_DSCP_EF >> 2);
- else if (strcmp(key, "cs0") == 0)
+ else if (key == "cs0")
portal_group_set_dscp(IPTOS_DSCP_CS0 >> 2);
- else if (strcmp(key, "cs1") == 0)
+ else if (key == "cs1")
portal_group_set_dscp(IPTOS_DSCP_CS1 >> 2);
- else if (strcmp(key, "cs2") == 0)
+ else if (key == "cs2")
portal_group_set_dscp(IPTOS_DSCP_CS2 >> 2);
- else if (strcmp(key, "cs3") == 0)
+ else if (key == "cs3")
portal_group_set_dscp(IPTOS_DSCP_CS3 >> 2);
- else if (strcmp(key, "cs4") == 0)
+ else if (key == "cs4")
portal_group_set_dscp(IPTOS_DSCP_CS4 >> 2);
- else if (strcmp(key, "cs5") == 0)
+ else if (key == "cs5")
portal_group_set_dscp(IPTOS_DSCP_CS5 >> 2);
- else if (strcmp(key, "cs6") == 0)
+ else if (key == "cs6")
portal_group_set_dscp(IPTOS_DSCP_CS6 >> 2);
- else if (strcmp(key, "cs7") == 0)
+ else if (key == "cs7")
portal_group_set_dscp(IPTOS_DSCP_CS7 >> 2);
- else if (strcmp(key, "af11") == 0)
+ else if (key == "af11")
portal_group_set_dscp(IPTOS_DSCP_AF11 >> 2);
- else if (strcmp(key, "af12") == 0)
+ else if (key == "af12")
portal_group_set_dscp(IPTOS_DSCP_AF12 >> 2);
- else if (strcmp(key, "af13") == 0)
+ else if (key == "af13")
portal_group_set_dscp(IPTOS_DSCP_AF13 >> 2);
- else if (strcmp(key, "af21") == 0)
+ else if (key == "af21")
portal_group_set_dscp(IPTOS_DSCP_AF21 >> 2);
- else if (strcmp(key, "af22") == 0)
+ else if (key == "af22")
portal_group_set_dscp(IPTOS_DSCP_AF22 >> 2);
- else if (strcmp(key, "af23") == 0)
+ else if (key == "af23")
portal_group_set_dscp(IPTOS_DSCP_AF23 >> 2);
- else if (strcmp(key, "af31") == 0)
+ else if (key == "af31")
portal_group_set_dscp(IPTOS_DSCP_AF31 >> 2);
- else if (strcmp(key, "af32") == 0)
+ else if (key == "af32")
portal_group_set_dscp(IPTOS_DSCP_AF32 >> 2);
- else if (strcmp(key, "af33") == 0)
+ else if (key == "af33")
portal_group_set_dscp(IPTOS_DSCP_AF33 >> 2);
- else if (strcmp(key, "af41") == 0)
+ else if (key == "af41")
portal_group_set_dscp(IPTOS_DSCP_AF41 >> 2);
- else if (strcmp(key, "af42") == 0)
+ else if (key == "af42")
portal_group_set_dscp(IPTOS_DSCP_AF42 >> 2);
- else if (strcmp(key, "af43") == 0)
+ else if (key == "af43")
portal_group_set_dscp(IPTOS_DSCP_AF43 >> 2);
else {
log_warnx("\"dscp\" property value is not a supported textual value");
@@ -623,499 +747,684 @@ uclparse_dscp(const char *group_type, const char *pg_name,
static bool
uclparse_pcp(const char *group_type, const char *pg_name,
- const ucl_object_t *obj)
+ const ucl::Ucl &obj)
{
- if (obj->type != UCL_INT) {
+ if (obj.type() != UCL_INT) {
log_warnx("\"pcp\" property of %s group \"%s\" is not an "
"integer", group_type, pg_name);
return (false);
}
- return (portal_group_set_pcp(ucl_object_toint(obj)));
+ return (portal_group_set_pcp(obj.int_value()));
}
static bool
-uclparse_portal_group(const char *name, const ucl_object_t *top)
+uclparse_portal_group(const char *name, const ucl::Ucl &top)
{
- ucl_object_iter_t it = NULL, it2 = NULL;
- const ucl_object_t *obj = NULL, *tmp = NULL;
- const char *key;
-
if (!portal_group_start(name))
return (false);
- while ((obj = ucl_iterate_object(top, &it, true))) {
- key = ucl_object_key(obj);
+ scope_exit finisher(portal_group_finish);
+ for (const auto &obj : top) {
+ std::string key = obj.key();
- if (strcmp(key, "discovery-auth-group") == 0) {
- if (obj->type != UCL_STRING) {
+ if (key == "discovery-auth-group") {
+ if (obj.type() != UCL_STRING) {
log_warnx("\"discovery-auth-group\" property "
"of portal-group \"%s\" is not a string",
name);
- goto fail;
+ return false;
}
if (!portal_group_set_discovery_auth_group(
- ucl_object_tostring(obj)))
- goto fail;
+ obj.string_value().c_str()))
+ return false;
}
- if (strcmp(key, "discovery-filter") == 0) {
- if (obj->type != UCL_STRING) {
+ if (key == "discovery-filter") {
+ if (obj.type() != UCL_STRING) {
log_warnx("\"discovery-filter\" property of "
"portal-group \"%s\" is not a string",
name);
- goto fail;
+ return false;
}
- if (!portal_group_set_filter(ucl_object_tostring(obj)))
- goto fail;
+ if (!portal_group_set_filter(
+ obj.string_value().c_str()))
+ return false;
}
- if (strcmp(key, "foreign") == 0) {
+ if (key == "foreign") {
portal_group_set_foreign();
}
- if (strcmp(key, "listen") == 0) {
- if (obj->type == UCL_STRING) {
+ if (key == "listen") {
+ if (obj.type() == UCL_STRING) {
if (!portal_group_add_listen(
- ucl_object_tostring(obj), false))
- goto fail;
- } else if (obj->type == UCL_ARRAY) {
- while ((tmp = ucl_iterate_object(obj, &it2,
- true))) {
+ obj.string_value().c_str(), false))
+ return false;
+ } else if (obj.type() == UCL_ARRAY) {
+ for (const auto &tmp : obj) {
if (!portal_group_add_listen(
- ucl_object_tostring(tmp),
+ tmp.string_value().c_str(),
false))
- goto fail;
+ return false;
}
} else {
log_warnx("\"listen\" property of "
"portal-group \"%s\" is not a string",
name);
- goto fail;
+ return false;
}
}
- if (strcmp(key, "listen-iser") == 0) {
- if (obj->type == UCL_STRING) {
+ if (key == "listen-iser") {
+ if (obj.type() == UCL_STRING) {
if (!portal_group_add_listen(
- ucl_object_tostring(obj), true))
- goto fail;
- } else if (obj->type == UCL_ARRAY) {
- while ((tmp = ucl_iterate_object(obj, &it2,
- true))) {
+ obj.string_value().c_str(), true))
+ return false;
+ } else if (obj.type() == UCL_ARRAY) {
+ for (const auto &tmp : obj) {
if (!portal_group_add_listen(
- ucl_object_tostring(tmp),
+ tmp.string_value().c_str(),
true))
- goto fail;
+ return false;
}
} else {
log_warnx("\"listen\" property of "
"portal-group \"%s\" is not a string",
name);
- goto fail;
+ return false;
}
}
- if (strcmp(key, "offload") == 0) {
- if (obj->type != UCL_STRING) {
+ if (key == "offload") {
+ if (obj.type() != UCL_STRING) {
log_warnx("\"offload\" property of "
"portal-group \"%s\" is not a string",
name);
- goto fail;
+ return false;
}
- if (!portal_group_set_offload(ucl_object_tostring(obj)))
- goto fail;
+ if (!portal_group_set_offload(
+ obj.string_value().c_str()))
+ return false;
}
- if (strcmp(key, "redirect") == 0) {
- if (obj->type != UCL_STRING) {
+ if (key == "redirect") {
+ if (obj.type() != UCL_STRING) {
log_warnx("\"listen\" property of "
"portal-group \"%s\" is not a string",
name);
- goto fail;
+ return false;
}
if (!portal_group_set_redirection(
- ucl_object_tostring(obj)))
- goto fail;
+ obj.string_value().c_str()))
+ return false;
}
- if (strcmp(key, "options") == 0) {
- if (obj->type != UCL_OBJECT) {
+ if (key == "options") {
+ if (obj.type() != UCL_OBJECT) {
log_warnx("\"options\" property of portal group "
"\"%s\" is not an object", name);
- goto fail;
+ return false;
}
- while ((tmp = ucl_iterate_object(obj, &it2,
- true))) {
+ for (const auto &tmp : obj) {
if (!portal_group_add_option(
- ucl_object_key(tmp),
- ucl_object_tostring_forced(tmp)))
- goto fail;
+ tmp.key().c_str(),
+ tmp.forced_string_value().c_str()))
+ return false;
}
}
- if (strcmp(key, "tag") == 0) {
- if (obj->type != UCL_INT) {
+ if (key == "tag") {
+ if (obj.type() != UCL_INT) {
log_warnx("\"tag\" property of portal group "
"\"%s\" is not an integer",
name);
- goto fail;
+ return false;
}
- portal_group_set_tag(ucl_object_toint(obj));
+ portal_group_set_tag(obj.int_value());
}
- if (strcmp(key, "dscp") == 0) {
+ if (key == "dscp") {
if (!uclparse_dscp("portal", name, obj))
- goto fail;
+ return false;
}
- if (strcmp(key, "pcp") == 0) {
+ if (key == "pcp") {
if (!uclparse_pcp("portal", name, obj))
- goto fail;
+ return false;
}
}
- portal_group_finish();
return (true);
-fail:
- portal_group_finish();
- return (false);
}
static bool
-uclparse_target(const char *name, const ucl_object_t *top)
+uclparse_transport_listen_obj(const char *pg_name, const ucl::Ucl &top)
+{
+ for (const auto &obj : top) {
+ std::string key = obj.key();
+
+ if (key.empty()) {
+ log_warnx("missing protocol for \"listen\" "
+ "property of transport-group \"%s\"", pg_name);
+ return false;
+ }
+
+ if (key == "tcp") {
+ if (obj.type() == UCL_STRING) {
+ if (!transport_group_add_listen_tcp(
+ obj.string_value().c_str()))
+ return false;
+ } else if (obj.type() == UCL_ARRAY) {
+ for (const auto &tmp : obj) {
+ if (!transport_group_add_listen_tcp(
+ tmp.string_value().c_str()))
+ return false;
+ }
+ }
+ } else if (key == "discovery-tcp") {
+ if (obj.type() == UCL_STRING) {
+ if (!transport_group_add_listen_discovery_tcp(
+ obj.string_value().c_str()))
+ return false;
+ } else if (obj.type() == UCL_ARRAY) {
+ for (const auto &tmp : obj) {
+ if (!transport_group_add_listen_discovery_tcp(
+ tmp.string_value().c_str()))
+ return false;
+ }
+ }
+ } else {
+ log_warnx("invalid listen protocol \"%s\" for "
+ "transport-group \"%s\"", key.c_str(), pg_name);
+ return false;
+ }
+ }
+ return true;
+}
+
+static bool
+uclparse_transport_group(const char *name, const ucl::Ucl &top)
+{
+ if (!transport_group_start(name))
+ return false;
+
+ scope_exit finisher(portal_group_finish);
+ for (const auto &obj : top) {
+ std::string key = obj.key();
+
+ if (key == "discovery-auth-group") {
+ if (obj.type() != UCL_STRING) {
+ log_warnx("\"discovery-auth-group\" property "
+ "of transport-group \"%s\" is not a string",
+ name);
+ return false;
+ }
+
+ if (!portal_group_set_discovery_auth_group(
+ obj.string_value().c_str()))
+ return false;
+ }
+
+ if (key == "discovery-filter") {
+ if (obj.type() != UCL_STRING) {
+ log_warnx("\"discovery-filter\" property of "
+ "transport-group \"%s\" is not a string",
+ name);
+ return false;
+ }
+
+ if (!portal_group_set_filter(
+ obj.string_value().c_str()))
+ return false;
+ }
+
+ if (key == "listen") {
+ if (obj.type() != UCL_OBJECT) {
+ log_warnx("\"listen\" property of "
+ "transport-group \"%s\" is not an object",
+ name);
+ return false;
+ }
+ if (!uclparse_transport_listen_obj(name, obj))
+ return false;
+ }
+
+ if (key == "options") {
+ if (obj.type() != UCL_OBJECT) {
+ log_warnx("\"options\" property of transport group "
+ "\"%s\" is not an object", name);
+ return false;
+ }
+
+ for (const auto &tmp : obj) {
+ if (!portal_group_add_option(
+ tmp.key().c_str(),
+ tmp.forced_string_value().c_str()))
+ return false;
+ }
+ }
+
+ if (key == "dscp") {
+ if (!uclparse_dscp("transport", name, obj))
+ return false;
+ }
+
+ if (key == "pcp") {
+ if (!uclparse_pcp("transport", name, obj))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool
+uclparse_controller(const char *name, const ucl::Ucl &top)
{
- ucl_object_iter_t it = NULL, it2 = NULL;
- const ucl_object_t *obj = NULL, *tmp = NULL;
- const char *key;
+ if (!controller_start(name))
+ return false;
+
+ scope_exit finisher(target_finish);
+ for (const auto &obj : top) {
+ std::string key = obj.key();
+
+ if (key == "auth-group") {
+ if (obj.type() != UCL_STRING) {
+ log_warnx("\"auth-group\" property of "
+ "controller \"%s\" is not a string", name);
+ return false;
+ }
+
+ if (!target_set_auth_group(obj.string_value().c_str()))
+ return false;
+ }
+
+ if (key == "auth-type") {
+ if (obj.type() != UCL_STRING) {
+ log_warnx("\"auth-type\" property of "
+ "controller \"%s\" is not a string", name);
+ return false;
+ }
+
+ if (!target_set_auth_type(obj.string_value().c_str()))
+ return false;
+ }
+
+ if (key == "host-address") {
+ if (obj.type() == UCL_STRING) {
+ if (!controller_add_host_address(
+ obj.string_value().c_str()))
+ return false;
+ } else if (obj.type() == UCL_ARRAY) {
+ for (const auto &tmp : obj) {
+ if (!controller_add_host_address(
+ tmp.string_value().c_str()))
+ return false;
+ }
+ } else {
+ log_warnx("\"host-address\" property of "
+ "controller \"%s\" is not an array or "
+ "string", name);
+ return false;
+ }
+ }
+
+ if (key == "host-nqn") {
+ if (obj.type() == UCL_STRING) {
+ if (!controller_add_host_nqn(
+ obj.string_value().c_str()))
+ return false;
+ } else if (obj.type() == UCL_ARRAY) {
+ for (const auto &tmp : obj) {
+ if (!controller_add_host_nqn(
+ tmp.string_value().c_str()))
+ return false;
+ }
+ } else {
+ log_warnx("\"host-nqn\" property of "
+ "controller \"%s\" is not an array or "
+ "string", name);
+ return false;
+ }
+ }
+
+ if (key == "transport-group") {
+ if (obj.type() == UCL_ARRAY) {
+ for (const auto &tmp : obj) {
+ if (!uclparse_controller_transport_group(name,
+ tmp))
+ return false;
+ }
+ } else {
+ if (!uclparse_controller_transport_group(name,
+ obj))
+ return false;
+ }
+ }
+
+ if (key == "namespace") {
+ for (const auto &tmp : obj) {
+ if (!uclparse_controller_namespace(name, tmp))
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+static bool
+uclparse_target(const char *name, const ucl::Ucl &top)
+{
if (!target_start(name))
return (false);
- while ((obj = ucl_iterate_object(top, &it, true))) {
- key = ucl_object_key(obj);
+ scope_exit finisher(target_finish);
+ for (const auto &obj : top) {
+ std::string key = obj.key();
- if (strcmp(key, "alias") == 0) {
- if (obj->type != UCL_STRING) {
+ if (key == "alias") {
+ if (obj.type() != UCL_STRING) {
log_warnx("\"alias\" property of target "
"\"%s\" is not a string", name);
- goto fail;
+ return false;
}
- if (!target_set_alias(ucl_object_tostring(obj)))
- goto fail;
+ if (!target_set_alias(obj.string_value().c_str()))
+ return false;
}
- if (strcmp(key, "auth-group") == 0) {
- if (obj->type != UCL_STRING) {
+ if (key == "auth-group") {
+ if (obj.type() != UCL_STRING) {
log_warnx("\"auth-group\" property of target "
"\"%s\" is not a string", name);
- goto fail;
+ return false;
}
- if (!target_set_auth_group(ucl_object_tostring(obj)))
- goto fail;
+ if (!target_set_auth_group(obj.string_value().c_str()))
+ return false;
}
- if (strcmp(key, "auth-type") == 0) {
- if (obj->type != UCL_STRING) {
+ if (key == "auth-type") {
+ if (obj.type() != UCL_STRING) {
log_warnx("\"auth-type\" property of target "
"\"%s\" is not a string", name);
- goto fail;
+ return false;
}
- if (!target_set_auth_type(ucl_object_tostring(obj)))
- goto fail;
+ if (!target_set_auth_type(obj.string_value().c_str()))
+ return false;
}
- if (strcmp(key, "chap") == 0) {
- if (obj->type == UCL_OBJECT) {
+ if (key == "chap") {
+ if (obj.type() == UCL_OBJECT) {
if (!uclparse_target_chap(name, obj))
- goto fail;
- } else if (obj->type == UCL_ARRAY) {
- while ((tmp = ucl_iterate_object(obj, &it2,
- true))) {
+ return false;
+ } else if (obj.type() == UCL_ARRAY) {
+ for (const auto &tmp : obj) {
if (!uclparse_target_chap(name, tmp))
- goto fail;
+ return false;
}
} else {
log_warnx("\"chap\" property of target "
"\"%s\" is not an array or object",
name);
- goto fail;
+ return false;
}
}
- if (strcmp(key, "chap-mutual") == 0) {
- if (obj->type == UCL_OBJECT) {
+ if (key == "chap-mutual") {
+ if (obj.type() == UCL_OBJECT) {
if (!uclparse_target_chap_mutual(name, obj))
- goto fail;
- } else if (obj->type == UCL_ARRAY) {
- while ((tmp = ucl_iterate_object(obj, &it2,
- true))) {
+ return false;
+ } else if (obj.type() == UCL_ARRAY) {
+ for (const auto &tmp : obj) {
if (!uclparse_target_chap_mutual(name,
tmp))
- goto fail;
+ return false;
}
} else {
log_warnx("\"chap-mutual\" property of target "
"\"%s\" is not an array or object",
name);
- goto fail;
+ return false;
}
}
- if (strcmp(key, "initiator-name") == 0) {
- if (obj->type == UCL_STRING) {
+ if (key == "initiator-name") {
+ if (obj.type() == UCL_STRING) {
if (!target_add_initiator_name(
- ucl_object_tostring(obj)))
- goto fail;
- } else if (obj->type == UCL_ARRAY) {
- while ((tmp = ucl_iterate_object(obj, &it2,
- true))) {
+ obj.string_value().c_str()))
+ return false;
+ } else if (obj.type() == UCL_ARRAY) {
+ for (const auto &tmp : obj) {
if (!target_add_initiator_name(
- ucl_object_tostring(tmp)))
- goto fail;
+ tmp.string_value().c_str()))
+ return false;
}
} else {
log_warnx("\"initiator-name\" property of "
"target \"%s\" is not an array or string",
name);
- goto fail;
+ return false;
}
}
- if (strcmp(key, "initiator-portal") == 0) {
- if (obj->type == UCL_STRING) {
+ if (key == "initiator-portal") {
+ if (obj.type() == UCL_STRING) {
if (!target_add_initiator_portal(
- ucl_object_tostring(obj)))
- goto fail;
- } else if (obj->type == UCL_ARRAY) {
- while ((tmp = ucl_iterate_object(obj, &it2,
- true))) {
+ obj.string_value().c_str()))
+ return false;
+ } else if (obj.type() == UCL_ARRAY) {
+ for (const auto &tmp : obj) {
if (!target_add_initiator_portal(
- ucl_object_tostring(tmp)))
- goto fail;
+ tmp.string_value().c_str()))
+ return false;
}
} else {
log_warnx("\"initiator-portal\" property of "
"target \"%s\" is not an array or string",
name);
- goto fail;
+ return false;
}
}
- if (strcmp(key, "portal-group") == 0) {
- if (obj->type == UCL_ARRAY) {
- while ((tmp = ucl_iterate_object(obj, &it2,
- true))) {
+ if (key == "portal-group") {
+ if (obj.type() == UCL_ARRAY) {
+ for (const auto &tmp : obj) {
if (!uclparse_target_portal_group(name,
tmp))
- goto fail;
+ return false;
}
} else {
if (!uclparse_target_portal_group(name, obj))
- goto fail;
+ return false;
}
}
- if (strcmp(key, "port") == 0) {
- if (obj->type != UCL_STRING) {
+ if (key == "port") {
+ if (obj.type() != UCL_STRING) {
log_warnx("\"port\" property of target "
"\"%s\" is not a string", name);
- goto fail;
+ return false;
}
- if (!target_set_physical_port(ucl_object_tostring(obj)))
- goto fail;
+ if (!target_set_physical_port(obj.string_value().c_str()))
+ return false;
}
- if (strcmp(key, "redirect") == 0) {
- if (obj->type != UCL_STRING) {
+ if (key == "redirect") {
+ if (obj.type() != UCL_STRING) {
log_warnx("\"redirect\" property of target "
"\"%s\" is not a string", name);
- goto fail;
+ return false;
}
- if (!target_set_redirection(ucl_object_tostring(obj)))
- goto fail;
+ if (!target_set_redirection(obj.string_value().c_str()))
+ return false;
}
- if (strcmp(key, "lun") == 0) {
- while ((tmp = ucl_iterate_object(obj, &it2, true))) {
+ if (key == "lun") {
+ for (const auto &tmp : obj) {
if (!uclparse_target_lun(name, tmp))
- goto fail;
+ return false;
}
}
}
- target_finish();
return (true);
-fail:
- target_finish();
- return (false);
}
static bool
-uclparse_lun(const char *name, const ucl_object_t *top)
+uclparse_lun(const char *name, const ucl::Ucl &top)
{
- char *lun_name;
- bool ok;
-
if (!lun_start(name))
return (false);
- asprintf(&lun_name, "lun \"%s\"", name);
- ok = uclparse_lun_entries(lun_name, top);
- free(lun_name);
- return (ok);
+
+ scope_exit finisher(lun_finish);
+ std::string lun_name = freebsd::stringf("lun \"%s\"", name);
+ return (uclparse_lun_entries(lun_name.c_str(), top));
}
static bool
-uclparse_lun_entries(const char *name, const ucl_object_t *top)
+uclparse_lun_entries(const char *name, const ucl::Ucl &top)
{
- ucl_object_iter_t it = NULL, child_it = NULL;
- const ucl_object_t *obj = NULL, *child = NULL;
- const char *key;
-
- while ((obj = ucl_iterate_object(top, &it, true))) {
- key = ucl_object_key(obj);
+ for (const auto &obj : top) {
+ std::string key = obj.key();
- if (strcmp(key, "backend") == 0) {
- if (obj->type != UCL_STRING) {
+ if (key == "backend") {
+ if (obj.type() != UCL_STRING) {
log_warnx("\"backend\" property of %s "
"is not a string", name);
- goto fail;
+ return false;
}
- if (!lun_set_backend(ucl_object_tostring(obj)))
- goto fail;
+ if (!lun_set_backend(obj.string_value().c_str()))
+ return false;
}
- if (strcmp(key, "blocksize") == 0) {
- if (obj->type != UCL_INT) {
+ if (key == "blocksize") {
+ if (obj.type() != UCL_INT) {
log_warnx("\"blocksize\" property of %s "
"is not an integer", name);
- goto fail;
+ return false;
}
- if (!lun_set_blocksize(ucl_object_toint(obj)))
- goto fail;
+ if (!lun_set_blocksize(obj.int_value()))
+ return false;
}
- if (strcmp(key, "device-id") == 0) {
- if (obj->type != UCL_STRING) {
+ if (key == "device-id") {
+ if (obj.type() != UCL_STRING) {
log_warnx("\"device-id\" property of %s "
"is not an integer", name);
- goto fail;
+ return false;
}
- if (!lun_set_device_id(ucl_object_tostring(obj)))
- goto fail;
+ if (!lun_set_device_id(obj.string_value().c_str()))
+ return false;
}
- if (strcmp(key, "device-type") == 0) {
- if (obj->type != UCL_STRING) {
+ if (key == "device-type") {
+ if (obj.type() != UCL_STRING) {
log_warnx("\"device-type\" property of %s "
"is not an integer", name);
- goto fail;
+ return false;
}
- if (!lun_set_device_type(ucl_object_tostring(obj)))
- goto fail;
+ if (!lun_set_device_type(obj.string_value().c_str()))
+ return false;
}
- if (strcmp(key, "ctl-lun") == 0) {
- if (obj->type != UCL_INT) {
+ if (key == "ctl-lun") {
+ if (obj.type() != UCL_INT) {
log_warnx("\"ctl-lun\" property of %s "
"is not an integer", name);
- goto fail;
+ return false;
}
- if (!lun_set_ctl_lun(ucl_object_toint(obj)))
- goto fail;
+ if (!lun_set_ctl_lun(obj.int_value()))
+ return false;
}
- if (strcmp(key, "options") == 0) {
- if (obj->type != UCL_OBJECT) {
+ if (key == "options") {
+ if (obj.type() != UCL_OBJECT) {
log_warnx("\"options\" property of %s "
"is not an object", name);
- goto fail;
+ return false;
}
- while ((child = ucl_iterate_object(obj, &child_it,
- true))) {
- if (!lun_add_option(ucl_object_key(child),
- ucl_object_tostring_forced(child)))
- goto fail;
+ for (const auto &child : obj) {
+ if (!lun_add_option(child.key().c_str(),
+ child.forced_string_value().c_str()))
+ return false;
}
}
- if (strcmp(key, "path") == 0) {
- if (obj->type != UCL_STRING) {
+ if (key == "path") {
+ if (obj.type() != UCL_STRING) {
log_warnx("\"path\" property of %s "
"is not a string", name);
- goto fail;
+ return false;
}
- if (!lun_set_path(ucl_object_tostring(obj)))
- goto fail;
+ if (!lun_set_path(obj.string_value().c_str()))
+ return false;
}
- if (strcmp(key, "serial") == 0) {
- if (obj->type != UCL_STRING) {
+ if (key == "serial") {
+ if (obj.type() != UCL_STRING) {
log_warnx("\"serial\" property of %s "
"is not a string", name);
- goto fail;
+ return false;
}
- if (!lun_set_serial(ucl_object_tostring(obj)))
- goto fail;
+ if (!lun_set_serial(obj.string_value().c_str()))
+ return false;
}
- if (strcmp(key, "size") == 0) {
- if (obj->type != UCL_INT) {
+ if (key == "size") {
+ if (obj.type() != UCL_INT) {
log_warnx("\"size\" property of %s "
"is not an integer", name);
- goto fail;
+ return false;
}
- if (!lun_set_size(ucl_object_toint(obj)))
- goto fail;
+ if (!lun_set_size(obj.int_value()))
+ return false;
}
}
- lun_finish();
return (true);
-fail:
- lun_finish();
- return (false);
}
bool
uclparse_conf(const char *path)
{
- struct ucl_parser *parser;
- ucl_object_t *top;
- bool parsed;
-
- parser = ucl_parser_new(0);
-
- if (!ucl_parser_add_file(parser, path)) {
- log_warn("unable to parse configuration file %s: %s", path,
- ucl_parser_get_error(parser));
- ucl_parser_free(parser);
+ std::string err;
+ ucl::Ucl top = ucl::Ucl::parse_from_file(path, err);
+ if (!top) {
+ log_warnx("unable to parse configuration file %s: %s", path,
+ err.c_str());
return (false);
}
- top = ucl_parser_get_object(parser);
- parsed = uclparse_toplevel(top);
- ucl_object_unref(top);
- ucl_parser_free(parser);
+ bool parsed;
+ try {
+ parsed = uclparse_toplevel(top);
+ } catch (std::bad_alloc &) {
+ log_warnx("failed to allocate memory parsing %s", path);
+ parsed = false;
+ } catch (...) {
+ log_warnx("unknown exception parsing %s", path);
+ parsed = false;
+ }
return (parsed);
}