Beispiel #1
0
static int
set_ethtool_eee(const ni_netdev_ref_t *ref, ni_ethtool_t *ethtool, struct ethtool_args *args)
{
	ni_ethtool_eee_t *eee;
	char *key = NULL, *val = NULL;
	ni_bool_t enabled;
	int ret = -1, n;

	if (!(eee = ni_ethtool_eee_new()))
		return ret;

	for (n = 0; n < args->argc && args->argv[n]; ++n) {
		key = args->argv[n++];
		if (n < args->argc)
			val = args->argv[n];
		else
			break;
		if (ni_string_eq(key, "eee")) {
			if (ni_parse_boolean(val, &enabled) != 0)
				break;
			ni_tristate_set(&eee->status.enabled, enabled);
		} else
		if (ni_string_eq(key, "tx-lpi")) {
			if (ni_parse_boolean(val, &enabled) != 0)
				break;
			ni_tristate_set(&eee->tx_lpi.enabled, enabled);
		} else
		if (ni_string_eq(key, "tx-timer")) {
			ni_parse_uint(val, &eee->tx_lpi.timer, 10);
		} else
		if (ni_string_eq(key, "advertise")) {
			if (!set_ethtool_link_advertise(val, &eee->speed.advertising))
				break;
		} else {
			val = key;
			key = NULL;
			break;
		}

		key = NULL;
		val = NULL;
	}

	if (key) {
		if (val)
			fprintf(stderr, "%s: cannot parse eee '%s' argument '%s'\n",
					ref->name, key, val);
		else
			fprintf(stderr, "%s: missing eee '%s' value argument\n",
					ref->name, key);
	} else {
		if (val)
			fprintf(stderr, "%s: unknown eee setting name '%s'\n",
					ref->name, val);
		else
			ret = ni_ethtool_set_eee(ref, ethtool, eee);
	}
	ni_ethtool_eee_free(eee);
	return ret;
}
Beispiel #2
0
static int
set_ethtool_pause(const ni_netdev_ref_t *ref, ni_ethtool_t *ethtool, struct ethtool_args *args)
{
	ni_ethtool_pause_t *pause;
	char *key = NULL, *val = NULL;
	ni_bool_t enabled;
	int ret = -1, n;

	if (!(pause = ni_ethtool_pause_new()))
		return ret;

	for (n = 0; n < args->argc && args->argv[n]; ++n) {
		key = args->argv[n++];
		if (n < args->argc)
			val = args->argv[n];
		else
			break;
		if (ni_string_eq(key, "tx")) {
			if (ni_parse_boolean(val, &enabled) != 0)
				break;
			ni_tristate_set(&pause->tx, enabled);
		} else
		if (ni_string_eq(key, "rx")) {
			if (ni_parse_boolean(val, &enabled) != 0)
				break;
			ni_tristate_set(&pause->rx, enabled);
		} else
		if (ni_string_eq(key, "autoneg")) {
			if (ni_parse_boolean(val, &enabled) != 0)
				break;
			ni_tristate_set(&pause->autoneg, enabled);
		} else {
			val = key;
			key = NULL;
			break;
		}

		key = NULL;
		val = NULL;
	}

	if (key) {
		if (val)
			fprintf(stderr, "%s: cannot parse pause '%s' argument '%s'\n",
					ref->name, key, val);
		else
			fprintf(stderr, "%s: missing pause '%s' value argument\n",
					ref->name, key);
	} else {
		if (val)
			fprintf(stderr, "%s: unknown pause setting name '%s'\n",
					ref->name, val);
		else
			ret = ni_ethtool_set_pause(ref, ethtool, pause);
	}
	ni_ethtool_pause_free(pause);
	return ret;
}
Beispiel #3
0
static int
set_ethtool_priv_flags(const ni_netdev_ref_t *ref, ni_ethtool_t *ethtool, struct ethtool_args *args)
{
	ni_ethtool_priv_flags_t *pflags;
	ni_bool_t enabled;
	char *key, *val;
	int ret = -1, n;

	if (!(pflags = ni_ethtool_priv_flags_new()))
		return ret;

	for (n = 0; n + 1 < args->argc && args->argv[n]; ++n) {
		key = args->argv[n++];
		val = args->argv[n];

		if (ni_parse_boolean(val, &enabled) ||
		    ni_string_array_append(&pflags->names, key))
			goto cleanup;

		if (enabled)
			pflags->bitmap |= NI_BIT(pflags->names.count - 1);
	}

	ret = ni_ethtool_set_priv_flags(ref, ethtool, pflags);

cleanup:
	ni_ethtool_priv_flags_free(pflags);
	return ret;
}
Beispiel #4
0
static int
set_ethtool_features(const ni_netdev_ref_t *ref, ni_ethtool_t *ethtool, struct ethtool_args *args)
{
	ni_ethtool_features_t *features;
	char *key = NULL, *val = NULL;
	ni_bool_t enabled;
	int ret = -1, n;

	if (!(features = ni_ethtool_features_new()))
		return ret;

	for (n = 0; n < args->argc && args->argv[n]; ++n) {
		key = args->argv[n++];
		if (n < args->argc)
			val = args->argv[n];
		else
			break;

		if (ni_parse_boolean(val, &enabled) < 0)
			break;

		ni_ethtool_features_set(features, key, enabled ?
				NI_ETHTOOL_FEATURE_ON : NI_ETHTOOL_FEATURE_OFF);

		key = NULL;
		val = NULL;
	}

	if (key) {
		if (val)
			fprintf(stderr, "%s: cannot parse feature '%s' value argument '%s'\n",
					ref->name, key, val);
		else
			fprintf(stderr, "%s: missing feature '%s' value argument\n",
					ref->name, key);
	} else {
		ret = ni_ethtool_set_features(ref, ethtool, features);
	}

	ni_ethtool_features_free(features);
	return ret;
}
Beispiel #5
0
unsigned int
ni_bridge_waittime_from_xml(const xml_node_t *brnode)
{
	unsigned int waittime = 0;
	ni_bridge_t bridge;
	xml_node_t *child;

	if (xml_node_is_empty(brnode))
		return waittime;

	__ni_bridge_init(&bridge);
	for (child = brnode->children; child; child = child->next) {
		if (ni_string_eq(child->name, "stp")) {
			if (ni_parse_boolean(child->cdata, &bridge.stp))
				continue;
		} else
		if (ni_string_eq(child->name, "forward-delay")) {
			if (ni_parse_double(child->cdata, &bridge.forward_delay))
				continue;

			if (bridge.forward_delay > NI_BRIDGE_FORWARD_DELAY_MAX)
				bridge.forward_delay = NI_BRIDGE_FORWARD_DELAY_MAX;
			else
			if (bridge.forward_delay < NI_BRIDGE_FORWARD_DELAY_MIN)
				bridge.forward_delay = NI_BRIDGE_FORWARD_DELAY_MIN;
		} else
		if (ni_string_eq(child->name, "max-age")) {
			if (ni_parse_double(child->cdata, &bridge.max_age))
				continue;

			if (bridge.max_age > NI_BRIDGE_MAX_AGE_MAX)
				bridge.max_age = NI_BRIDGE_MAX_AGE_MAX;
			else
			if (bridge.max_age < NI_BRIDGE_MAX_AGE_MIN)
				bridge.max_age = NI_BRIDGE_MAX_AGE_MIN;
		}
	}

	waittime = ni_bridge_waittime(&bridge);
	return waittime;
}
Beispiel #6
0
static int
set_ethtool_coalesce(const ni_netdev_ref_t *ref, ni_ethtool_t *ethtool, struct ethtool_args *args)
{
	ni_ethtool_coalesce_t *coalesce;
	char *key = NULL, *val = NULL;
	ni_bool_t enabled;
	int ret = -1, n;

	if (!(coalesce = ni_ethtool_coalesce_new()))
		return ret;

	for (n = 0; n < args->argc && args->argv[n]; ++n) {
		key = args->argv[n++];
		if (n < args->argc)
			val = args->argv[n];
		else
			break;
		if (ni_string_eq(key, "adaptive-rx")) {
			if (ni_parse_boolean(val, &enabled) != 0)
				break;
			ni_tristate_set(&coalesce->adaptive_rx, enabled);
		} else
		if (ni_string_eq(key, "adaptive-tx")) {
			if (ni_parse_boolean(val, &enabled) != 0)
				break;
			ni_tristate_set(&coalesce->adaptive_tx, enabled);
		} else
		if (ni_string_eq(key, "rx-usecs")) {
			ni_parse_uint(val, &coalesce->rx_usecs, 10);
		} else
		if (ni_string_eq(key, "rx-frames")) {
			ni_parse_uint(val, &coalesce->rx_frames, 10);
		} else
		if (ni_string_eq(key, "rx-usecs-irq")) {
			ni_parse_uint(val, &coalesce->rx_usecs_irq, 10);
		} else
		if (ni_string_eq(key, "rx-frames-irq")) {
			ni_parse_uint(val, &coalesce->rx_frames_irq, 10);
		} else
		if (ni_string_eq(key, "tx-usecs")) {
			ni_parse_uint(val, &coalesce->tx_usecs, 10);
		} else
		if (ni_string_eq(key, "tx-frames")) {
			ni_parse_uint(val, &coalesce->tx_frames, 10);
		} else
		if (ni_string_eq(key, "tx-usecs-irq")) {
			ni_parse_uint(val, &coalesce->tx_usecs_irq, 10);
		} else
		if (ni_string_eq(key, "tx-frames-irq")) {
			ni_parse_uint(val, &coalesce->rx_frames_irq, 10);
		} else
		if (ni_string_eq(key, "stats-block-usecs")) {
			ni_parse_uint(val, &coalesce->stats_block_usecs, 10);
		} else
		if (ni_string_eq(key, "pkt-rate-low")) {
			ni_parse_uint(val, &coalesce->pkt_rate_low, 10);
		} else
		if (ni_string_eq(key, "rx-usecs-low")) {
			ni_parse_uint(val, &coalesce->rx_usecs_low, 10);
		} else
		if (ni_string_eq(key, "rx-frames-low")) {
			ni_parse_uint(val, &coalesce->rx_frames_low, 10);
		} else
		if (ni_string_eq(key, "tx-usecs-low")) {
			ni_parse_uint(val, &coalesce->tx_usecs_low, 10);
		} else
		if (ni_string_eq(key, "tx-frames-low")) {
			ni_parse_uint(val, &coalesce->tx_frames_low, 10);
		} else
		if (ni_string_eq(key, "pkt-rate-high")) {
			ni_parse_uint(val, &coalesce->pkt_rate_high, 10);
		} else
		if (ni_string_eq(key, "rx-usecs-high")) {
			ni_parse_uint(val, &coalesce->rx_usecs_high, 10);
		} else
		if (ni_string_eq(key, "rx-frames-high")) {
			ni_parse_uint(val, &coalesce->rx_frames_high, 10);
		} else
		if (ni_string_eq(key, "tx-usecs-high")) {
			ni_parse_uint(val, &coalesce->tx_usecs_high, 10);
		} else
		if (ni_string_eq(key, "tx-frames-high")) {
			ni_parse_uint(val, &coalesce->tx_frames_high, 10);
		} else
		if (ni_string_eq(key, "sample_interval")) {
			ni_parse_uint(val, &coalesce->sample_interval, 10);
		} else {
			val = key;
			key = NULL;
			break;
		}

		key = NULL;
		val = NULL;
	}

	if (key) {
		if (val)
			fprintf(stderr, "%s: cannot parse coalesce '%s' argument '%s'\n",
					ref->name, key, val);
		else
			fprintf(stderr, "%s: missing coalesce '%s' value argument\n",
					ref->name, key);
	} else {
		if (val)
			fprintf(stderr, "%s: unknown coalesce setting name '%s'\n",
					ref->name, val);
		else
			ret = ni_ethtool_set_coalesce(ref, ethtool, coalesce);
	}
	ni_ethtool_coalesce_free(coalesce);
	return ret;
}
Beispiel #7
0
static int
set_ethtool_link_settings(const ni_netdev_ref_t *ref, ni_ethtool_t *ethtool, struct ethtool_args *args)
{
	ni_ethtool_link_settings_t *link;
	char *key = NULL, *val = NULL;
	unsigned int value;
	ni_bool_t enabled;
	int ret = -1, n;

	if (!(link = ni_ethtool_link_settings_new()))
		return ret;

	for (n = 0; n < args->argc && args->argv[n]; ++n) {
		key = args->argv[n++];
		if (n < args->argc)
			val = args->argv[n];
		else
			break;

		if (ni_string_eq(key, "autoneg")) {
			if (ni_parse_boolean(val, &enabled) != 0)
				break;
			ni_tristate_set(&link->autoneg, enabled);
		} else
		if (ni_string_eq(key, "speed")) {
			if (ni_parse_uint(val, &value, 10) != 0)
				break;
			link->speed = value;
		} else
		if (ni_string_eq(key, "duplex")) {
			if (!ni_ethtool_link_duplex_type(val, &value))
				break;
			link->duplex = value;
		} else
		if (ni_string_eq(key, "port")) {
			if (!ni_ethtool_link_port_type(val, &value))
				break;
			link->port = value;
		} else
		if (ni_string_eq(key, "mdix")) {
			if (!ni_ethtool_link_mdix_type(val, &value))
				break;
			link->tp_mdix = value;
		} else
		if (ni_string_eq(key, "phy-address")) {
			if (ni_parse_uint(val, &value, 10) != 0)
				break;
			link->phy_address = value;
		} else
		if (ni_string_eq(key, "transceiver")) {
			if (!ni_ethtool_link_xcvr_type(val, &value))
				break;
			link->transceiver = value;
		} else
		if (ni_string_eq(key, "advertise")) {
			if (!set_ethtool_link_advertise(val, &link->advertising))
				break;
		} else {
			val = key;
			key = NULL;
			break;
		}

		key = NULL;
		val = NULL;
	}

	if (key) {
		if (val)
			fprintf(stderr, "%s: cannot parse link '%s' argument '%s'\n",
					ref->name, key, val);
		else
			fprintf(stderr, "%s: missing link '%s' value argument\n",
					ref->name, key);
	} else {
		if (val)
			fprintf(stderr, "%s: unknown link setting name '%s'\n",
					ref->name, val);
		else
			ret = ni_ethtool_set_link_settings(ref, ethtool, link);
	}
	ni_ethtool_link_settings_free(link);
	return ret;
}
Beispiel #8
0
static ni_bool_t
ni_dhcp4_tester_req_xml_init(ni_dhcp4_request_t *req, xml_document_t *doc)
{
	xml_node_t *xml, *child;
	const char *type;

	xml = xml_document_root(doc);
	if (xml && !xml->name && xml->children)
		xml = xml->children;

	if (!xml || !ni_string_eq(xml->name, "request")) {
		ni_error("Invalid dhcp4 request xml '%s'",
				xml ? xml_node_location(xml) : NULL);
		return FALSE;
	}

	type = xml_node_get_attr(xml, "type");
	if (ni_string_eq(type, "offer")) {
		req->dry_run = NI_DHCP4_RUN_OFFER;
	} else
	if (ni_string_eq(type, "lease")) {
		req->dry_run = NI_DHCP4_RUN_LEASE;
	}

	for (child = xml->children; child; child = child->next) {
		if (ni_string_eq(child->name, "uuid")) {
			if (ni_uuid_parse(&req->uuid, child->cdata) != 0)
				goto failure;
		} else
		if (ni_string_eq(child->name, "acquire-timeout")) {
			if (ni_parse_uint(child->cdata, &req->acquire_timeout, 10) != 0)
				goto failure;
		} else
		if (ni_string_eq(child->name, "hostname")) {
			if (!ni_check_domain_name(child->cdata, ni_string_len(child->cdata), 0))
				goto failure;
			ni_string_dup(&req->hostname, child->cdata);
		} else
		if (ni_string_eq(child->name, "fqdn")) {
			const xml_node_t *ptr;

			for (ptr = child->children; ptr; ptr = ptr->next) {
				if (ni_string_eq(ptr->name, "enabled")) {
					ni_bool_t b;
					if (ni_parse_boolean(ptr->cdata, &b) == 0)
						ni_tristate_set(&req->fqdn.enabled, b);
					else
					if (ni_string_eq(ptr->cdata, "default"))
						req->fqdn.enabled = NI_TRISTATE_DEFAULT;
					else
						goto failure;
				} else
				if (ni_string_eq(ptr->name, "update")) {
					if (!ni_dhcp_fqdn_update_name_to_mode(ptr->cdata, &req->fqdn.update))
						goto failure;
				} else
				if (ni_string_eq(ptr->name, "encode")) {
					if (ni_parse_boolean(ptr->cdata, &req->fqdn.encode) != 0)
						goto failure;
				} else
				if (ni_string_eq(ptr->name, "qualify")) {
					if (ni_parse_boolean(ptr->cdata, &req->fqdn.qualify) != 0)
						goto failure;
				}
			}
		} else
		if (ni_string_eq(child->name, "clientid")) {
			ni_opaque_t duid;

			if (ni_parse_hex(child->cdata, duid.data, sizeof(duid.data)) <= 0)
				goto failure;
			ni_string_dup(&req->clientid, child->cdata);
		} else
		if(ni_string_eq(child->name, "start-delay")) {
			if (ni_parse_uint(child->cdata, &req->start_delay, 10) != 0)
				goto failure;
		} else
		if (ni_string_eq(child->name, "lease-time")) {
			if (ni_parse_uint(child->cdata, &req->lease_time, 10) != 0)
				goto failure;
		} else
		if (ni_string_eq(child->name, "recover-lease")) {
			if (ni_parse_boolean(child->cdata, &req->recover_lease) != 0)
				goto failure;
		} else
		if (ni_string_eq(child->name, "release-lease")) {
			if (ni_parse_boolean(child->cdata, &req->release_lease) != 0)
				goto failure;
		} else
		if (ni_string_eq(child->name, "request-options")) {
			xml_node_t *opt;
			for (opt = child->children; opt; opt = opt->next) {
				if (ni_string_empty(opt->cdata))
					continue;
				ni_string_array_append(&req->request_options, opt->cdata);
			}
		}
	}

	return TRUE;
failure:
	if (child) {
		ni_error("Cannot parse dhcp4 request '%s': %s",
				child->name, xml_node_location(child));
	}
	return FALSE;
}
Beispiel #9
0
static ni_bool_t
dhcp4_tester_req_xml_init(ni_dhcp4_request_t *req, xml_document_t *doc)
{
	xml_node_t *xml, *child;
	const char *type;

	xml = xml_document_root(doc);
	if (xml && !xml->name && xml->children)
		xml = xml->children;

	if (!xml || !ni_string_eq(xml->name, "request")) {
		ni_error("Invalid dhcp4 request xml '%s'",
				xml ? xml_node_location(xml) : NULL);
		return FALSE;
	}

	type = xml_node_get_attr(xml, "type");
	if (ni_string_eq(type, "offer")) {
		req->dry_run = NI_DHCP4_RUN_OFFER;
	} else
	if (ni_string_eq(type, "lease")) {
		req->dry_run = NI_DHCP4_RUN_LEASE;
	}

	for (child = xml->children; child; child = child->next) {
		if (ni_string_eq(child->name, "uuid")) {
			if (ni_uuid_parse(&req->uuid, child->cdata) != 0)
				goto failure;
		} else
		if (ni_string_eq(child->name, "acquire-timeout")) {
			if (ni_parse_uint(child->cdata, &req->acquire_timeout, 10) != 0)
				goto failure;
		} else
		if (ni_string_eq(child->name, "hostname")) {
			if (!ni_check_domain_name(child->cdata, ni_string_len(child->cdata), 0))
				goto failure;
			ni_string_dup(&req->hostname, child->cdata);
		} else
		if (ni_string_eq(child->name, "clientid")) {
			ni_opaque_t duid;

			if (ni_parse_hex(child->cdata, duid.data, sizeof(duid.data)) <= 0)
				goto failure;
			ni_string_dup(&req->clientid, child->cdata);
		} else
		if(ni_string_eq(child->name, "start-delay")) {
			if (ni_parse_uint(child->cdata, &req->start_delay, 10) != 0)
				goto failure;
		} else
		if (ni_string_eq(child->name, "lease-time")) {
			if (ni_parse_uint(child->cdata, &req->lease_time, 10) != 0)
				goto failure;
		} else
		if (ni_string_eq(child->name, "recover-lease")) {
			if (ni_parse_boolean(child->cdata, &req->recover_lease) != 0)
				goto failure;
		} else
		if (ni_string_eq(child->name, "release-lease")) {
			if (ni_parse_boolean(child->cdata, &req->release_lease) != 0)
				goto failure;
		}
	}

	return TRUE;
failure:
	if (child) {
		ni_error("Cannot parse dhcp4 request '%s': %s",
				child->name, xml_node_location(child));
	}
	return FALSE;
}
Beispiel #10
0
ni_bool_t
__ni_config_parse(ni_config_t *conf, const char *filename, ni_init_appdata_callback_t *cb, void *appdata)
{
	xml_document_t *doc;
	xml_node_t *node, *child;

	ni_debug_wicked("Reading config file %s", filename);
	doc = xml_document_read(filename);
	if (!doc) {
		ni_error("%s: error parsing configuration file", filename);
		goto failed;
	}

	node = xml_node_get_child(doc->root, "config");
	if (!node) {
		ni_error("%s: no <config> element", filename);
		goto failed;
	}

	/* Loop over all elements in the config file */
	for (child = node->children; child; child = child->next) {
		if (strcmp(child->name, "include") == 0) {
			const char *attrval, *path;

			if ((attrval = xml_node_get_attr(child, "name")) == NULL) {
				ni_error("%s: <include> element lacks filename", xml_node_location(child));
				goto failed;
			}
			if (!(path = ni_config_build_include(filename, attrval)))
				goto failed;
			if (!__ni_config_parse(conf, path, cb, appdata))
				goto failed;
		} else
		if (strcmp(child->name, "use-nanny") == 0) {
			if (ni_parse_boolean(child->cdata, &conf->use_nanny)) {
				ni_error("%s: invalid <%s>%s</%s> element value",
					filename, child->name, child->name, child->cdata);
				goto failed;
			}
		} else
		if (strcmp(child->name, "piddir") == 0) {
			ni_config_parse_fslocation(&conf->piddir, child);
		} else
		if (strcmp(child->name, "statedir") == 0) {
			ni_config_parse_fslocation(&conf->statedir, child);
		} else
		if (strcmp(child->name, "storedir") == 0) {
			ni_config_parse_fslocation(&conf->storedir, child);
		} else
		if (strcmp(child->name, "dbus") == 0) {
			const char *attrval;

			if ((attrval = xml_node_get_attr(child, "name")) != NULL)
				ni_string_dup(&conf->dbus_name, attrval);
			if ((attrval = xml_node_get_attr(child, "type")) != NULL)
				ni_string_dup(&conf->dbus_type, attrval);
		} else 
		if (strcmp(child->name, "schema") == 0) {
			const char *attrval;

			if ((attrval = xml_node_get_attr(child, "name")) != NULL)
				ni_string_dup(&conf->dbus_xml_schema_file, attrval);
		} else
		if (strcmp(child->name, "addrconf") == 0) {
			xml_node_t *gchild;

			for (gchild = child->children; gchild; gchild = gchild->next) {
				if (!strcmp(gchild->name, "default-allow-update"))
					ni_config_parse_update_targets(&conf->addrconf.default_allow_update, gchild);

				if (!strcmp(gchild->name, "dhcp4")
				 && !ni_config_parse_addrconf_dhcp4(&conf->addrconf.dhcp4, gchild))
					goto failed;

				if (!strcmp(gchild->name, "dhcp6")
				 && !ni_config_parse_addrconf_dhcp6(&conf->addrconf.dhcp6, gchild))
					goto failed;
			}
		} else
		if (strcmp(child->name, "sources") == 0) {
			if (!ni_config_parse_sources(conf, child))
				goto failed;
		} else
		if (strcmp(child->name, "extension") == 0
		 || strcmp(child->name, "dbus-service") == 0) {
			if (!ni_config_parse_objectmodel_extension(&conf->dbus_extensions, child))
				goto failed;
		} else
		if (strcmp(child->name, "netif-naming-services") == 0) {
			if (!ni_config_parse_objectmodel_netif_ns(&conf->ns_extensions, child))
				goto failed;
		} else
		if (strcmp(child->name, "netif-firmware-discovery") == 0) {
			if (!ni_config_parse_objectmodel_firmware_discovery(&conf->fw_extensions, child))
				goto failed;
		} else
		if (strcmp(child->name, "system-updater") == 0) {
			if (!ni_config_parse_system_updater(&conf->updater_extensions, child))
				goto failed;
		} else
		if (cb != NULL) {
			if (!cb(appdata, child))
				goto failed;
		}
	}

	if (conf->backupdir.path == NULL) {
		char pathname[PATH_MAX];

		snprintf(pathname, sizeof(pathname), "%s/backup", conf->statedir.path);
		ni_config_fslocation_init(&conf->backupdir, pathname, 0700);
	}

	xml_document_free(doc);
	return TRUE;

failed:
	if (doc)
		xml_document_free(doc);
	return FALSE;
}