示例#1
0
文件: config.c 项目: mijos/wicked
void
ni_config_parse_fslocation(ni_config_fslocation_t *fsloc, xml_node_t *node)
{
	const char *attrval;

	if ((attrval = xml_node_get_attr(node, "path")) != NULL)
		ni_string_dup(&fsloc->path, attrval);
	if ((attrval = xml_node_get_attr(node, "mode")) != NULL)
		ni_parse_uint(attrval, &fsloc->mode, 8);
}
示例#2
0
文件: config.c 项目: mijos/wicked
ni_bool_t
ni_config_parse_addrconf_dhcp4(struct ni_config_dhcp4 *dhcp4, xml_node_t *node)
{
	xml_node_t *child;

	for (child = node->children; child; child = child->next) {
		const char *attrval;

		if (!strcmp(child->name, "vendor-class"))
			ni_string_dup(&dhcp4->vendor_class, child->cdata);
		if (!strcmp(child->name, "lease-time") && child->cdata)
			dhcp4->lease_time = strtoul(child->cdata, NULL, 0);
		if (!strcmp(child->name, "ignore-server")
		 && (attrval = xml_node_get_attr(child, "ip")) != NULL)
			ni_string_array_append(&dhcp4->ignore_servers, attrval);
		if (!strcmp(child->name, "prefer-server")
		 && (attrval = xml_node_get_attr(child, "ip")) != NULL) {
			ni_server_preference_t *pref;

			if (dhcp4->num_preferred_servers >= NI_DHCP_SERVER_PREFERENCES_MAX) {
				ni_warn("config: too many <prefer-server> elements");
				continue;
			}

			pref = &dhcp4->preferred_server[dhcp4->num_preferred_servers++];
			if (ni_sockaddr_parse(&pref->address, attrval, AF_INET) < 0) {
				ni_error("config: unable to parse <prefer-server ip=\"%s\"",
						attrval);
				return FALSE;
			}

			pref->weight = 100;
			if ((attrval = xml_node_get_attr(child, "weight")) != NULL) {
				if (!strcmp(attrval, "always")) {
					pref->weight = 100;
				} else if (!strcmp(attrval, "never")) {
					pref->weight = -1;
				} else {
					pref->weight = strtol(attrval, NULL, 0);
					if (pref->weight > 100) {
						pref->weight = 100;
						ni_warn("preferred dhcp server weight exceeds max, "
							"clamping to %d",
							pref->weight);
					}
				}
			}
		}
		if (!strcmp(child->name, "allow-update"))
			ni_config_parse_update_targets(&dhcp4->allow_update, child);
	}
	return TRUE;
}
示例#3
0
ni_bool_t
ni_iaid_map_to_vars(const ni_iaid_map_t *map, ni_var_array_t *vars)
{
	xml_node_t *root, *node = NULL;
	const char *name;

	if (!vars)
		return FALSE;

	if (!(root = ni_iaid_map_root_node(map)))
		return FALSE;

	ni_var_array_destroy(vars);
	while ((node = ni_iaid_map_next_node(root, node))) {
		if (ni_string_empty(node->cdata))
			continue;

		name = xml_node_get_attr(node, NI_CONFIG_DEFAULT_IAID_DEVICE);
		if (ni_string_empty(name))
			continue;

		ni_var_array_set(vars, name, node->cdata);
	}
	return TRUE;
}
示例#4
0
ni_bool_t
ni_iaid_map_set(ni_iaid_map_t *map, const char *name, unsigned int iaid)
{
	xml_node_t *root, *node = NULL;
	const char *attr;

	if (!(root = ni_iaid_map_root_node(map)) || ni_string_empty(name))
		return FALSE;

	while ((node = ni_iaid_map_next_node(root, node))) {
		attr = xml_node_get_attr(node, NI_CONFIG_DEFAULT_IAID_DEVICE);
		if (!ni_string_eq(name, attr))
			continue;

		xml_node_set_uint(node, iaid);
		return TRUE;
	}

	if ((node = xml_node_new(NI_CONFIG_DEFAULT_IAID_NODE, root))) {
		xml_node_add_attr(node, NI_CONFIG_DEFAULT_IAID_DEVICE, name);
		xml_node_set_uint(node, iaid);
		return TRUE;
	}
	return FALSE;
}
示例#5
0
文件: state.c 项目: gsanso/wicked
static ni_bool_t
ni_objectmodel_recover_state_xml(xml_node_t *list, const char **prefix_list)
{
	ni_dbus_object_t *root_object;
	xml_node_t *object_node;

	root_object = ni_dbus_server_get_root_object(__ni_objectmodel_server);
	for (object_node = list->children; object_node; object_node = object_node->next) {
		ni_dbus_object_t *object;
		const char *name;

		if (!ni_string_eq(object_node->name, "object")) {
			ni_error("%s: not an <object> element", xml_node_location(object_node));
			return FALSE;
		}

		if (!(name = xml_node_get_attr(object_node, "path"))) {
			ni_error("%s: <object> lacks path attribute", xml_node_location(object_node));
			return FALSE;
		}
		if (!(name = ni_dbus_object_get_relative_path(root_object, name))) {
			ni_error("%s: <object> has invalid path attribute", xml_node_location(object_node));
			return FALSE;
		}

		if (!(object = ni_dbus_object_lookup(root_object, name)))
			continue;

		if (!ni_objectmodel_recover_object_state_xml(object_node, object, prefix_list))
			return FALSE;

	}

	return TRUE;
}
示例#6
0
static ni_bool_t
ni_iaid_map_node_to_name(const xml_node_t *node, const char **name)
{
	if (!node || !name)
		return FALSE;

	*name = xml_node_get_attr(node, NI_CONFIG_DEFAULT_IAID_DEVICE);
	return !ni_string_empty(*name);
}
示例#7
0
static void
xml_process_pi_node(xml_reader_t *xr, xml_node_t *pi)
{
	const char *attrval;

	if (!strcmp(pi->name, "xml")) {
		if ((attrval = xml_node_get_attr(pi, "version")) != NULL
		 && strcmp(attrval, "1.0"))
			ni_warn("unexpected XML version %s", attrval);

		if ((attrval = xml_node_get_attr(pi, "encoding")) != NULL
		 && strcasecmp(attrval, "utf8")) {
			/* TBD: set up iconv to translate from encoding to utf8,
			   and make sure we process all input that way. */
		}
	}
		
}
示例#8
0
文件: config.c 项目: mijos/wicked
/*
 * Another class of extensions helps with updating system files such as resolv.conf
 * This expects scripts for install, backup and restore (named accordingly).
 *
 * <system-updater name="resolver">
 *  <script name="install" command="/some/crazy/path/to/script install" />
 *  <script name="backup" command="/some/crazy/path/to/script backup" />
 *  <script name="restore" command="/some/crazy/path/to/script restore" />
 *  ...
 * </system-updater>
 */
ni_bool_t
ni_config_parse_system_updater(ni_extension_t **list, xml_node_t *node)
{
	ni_extension_t *ex;
	const char *name;

	if (!(name = xml_node_get_attr(node, "name"))) {
		ni_error("%s: <%s> element lacks name attribute",
				node->name, xml_node_location(node));
		return FALSE;
	}

	ex = ni_extension_new(list, name);

	/* If the updater has a format type, extract. */
	ni_string_dup(&ex->format, xml_node_get_attr(node, "format"));

	return ni_config_parse_extension(ex, node);
}
示例#9
0
ni_bool_t
xml_node_get_attr_ulong(const xml_node_t *node, const char *name, unsigned long *valp)
{
	const char *value;

	if (!valp || !(value = xml_node_get_attr(node, name)))
		return FALSE;

	if (ni_parse_ulong(value, valp, 10) < 0)
		return FALSE;

	return TRUE;
}
示例#10
0
ni_bool_t
xml_node_get_attr_double(const xml_node_t *node, const char *name, double *valp)
{
	const char *value;

	if (!valp || !(value = xml_node_get_attr(node, name)))
		return FALSE;

	if (ni_parse_double(value, valp) < 0)
		return FALSE;

	return TRUE;
}
示例#11
0
文件: config.c 项目: mijos/wicked
static ni_bool_t
ni_config_parse_extension(ni_extension_t *ex, xml_node_t *node)
{
	xml_node_t *child;

	for (child = node->children; child; child = child->next) {
		if (!strcmp(child->name, "action") || !strcmp(child->name, "script")) {
			const char *name, *command;

			if (!(name = xml_node_get_attr(child, "name"))) {
				ni_error("action element without name attribute");
				return FALSE;
			}
			if (!(command = xml_node_get_attr(child, "command"))) {
				ni_error("action element without command attribute");
				return FALSE;
			}

			if (!ni_extension_script_new(ex, name, command))
				return FALSE;
		} else
		if (!strcmp(child->name, "builtin")) {
			const char *name, *library, *symbol;

			if (!(name = xml_node_get_attr(child, "name"))) {
				ni_error("builtin element without name attribute");
				return FALSE;
			}
			if (!(symbol = xml_node_get_attr(child, "symbol"))) {
				ni_error("action element without command attribute");
				return FALSE;
			}
			library = xml_node_get_attr(child, "library");

			ni_c_binding_new(&ex->c_bindings, name, library, symbol);
		} else
		if (!strcmp(child->name, "putenv")) {
			const char *name, *value;

			if (!(name = xml_node_get_attr(child, "name"))) {
				ni_error("%s: <putenv> element without name attribute",
						xml_node_location(child));
				return FALSE;
			}
			value = xml_node_get_attr(child, "value");
			ni_var_array_set(&ex->environment, name, value);
		}
	}

	return TRUE;
}
示例#12
0
文件: config.c 项目: mijos/wicked
/*
 * Object model extensions let you implement parts of a dbus interface separately
 * from the main wicked body of code; either through a shared library or an
 * external command/shell script
 *
 * <extension interface="org.opensuse.Network.foobar">
 *  <action name="dbusMethodName" command="/some/shell/scripts some-args"/>
 *  <builtin name="dbusOtherMethodName" library="/usr/lib/libfoo.so" symbol="c_method_impl_name"/>
 *
 *  <putenv name="WICKED_OBJECT_PATH" value="$object-path"/>
 *  <putenv name="WICKED_INTERFACE_NAME" value="$property:name"/>
 *  <putenv name="WICKED_INTERFACE_INDEX" value="$property:index"/>
 * </extension>
 */
ni_bool_t
ni_config_parse_objectmodel_extension(ni_extension_t **list, xml_node_t *node)
{
	ni_extension_t *ex;
	const char *name;

	if (!(name = xml_node_get_attr(node, "interface"))) {
		ni_error("%s: <%s> element lacks interface attribute",
				node->name, xml_node_location(node));
		return FALSE;
	}

	ex = ni_extension_new(list, name);

	return ni_config_parse_extension(ex, node);
}
示例#13
0
文件: xpath.c 项目: openSUSE/wicked
/*
 * @attribute
 */
static xpath_result_t *
__xpath_enode_getattr_evaluate(const xpath_enode_t *op, xpath_result_t *in)
{
	xpath_result_t *result = xpath_result_new(XPATH_STRING);
	const char *attr_name = op->identifier;
	unsigned int n;

	for (n = 0; n < in->count; ++n) {
		xml_node_t *xn = in->node[n].value.node;
		const char *attrval;

		if ((attrval = xml_node_get_attr(xn, attr_name)) != NULL) {
			xtrace("  found node <%s %s=\"%s\">", xn->name, attr_name, attrval? : "");
			xpath_result_append_string(result, attrval);
		}
	}
示例#14
0
static void
extract_net(xmlNodePtr entry, GList ** mail_addrs)
{
    while (entry) {
	gchar *uri_type = NULL;
	gchar *mail_addr;

	if (!xmlStrcmp(entry->name, CXMLCHARP("Uri"))
	    && g_strcmp0(uri_type = xml_node_get_attr(entry, CXMLCHARP("type")),
                         "email") == 0
	    && (mail_addr = xml_node_get_text(entry)) != NULL)
	    *mail_addrs = g_list_prepend(*mail_addrs, mail_addr);
	g_free(uri_type);

	entry = entry->next;
    }
}
示例#15
0
/*
 * XML node matching functions
 */
ni_bool_t
xml_node_match_attrs(const xml_node_t *node, const ni_var_array_t *attrlist)
{
	unsigned int i;
	ni_var_t *attr;

	for (i = 0, attr = attrlist->data; i < attrlist->count; ++i, ++attr) {
		const char *value;

		value = xml_node_get_attr(node, attr->name);
		if (attr->value == NULL || value == NULL) {
			if (attr->value != value)
				return FALSE;
		} else if (strcmp(attr->value, value)) {
			return FALSE;
		}
	}
	return TRUE;
}
示例#16
0
文件: config.c 项目: mijos/wicked
/*
 * This specifies sources of client configuration.
 *
 * The ifconfig source specifies the type, location and the
 * priority / load order of the interface configurations.
 *
 * <sources>
 *   <ifconfig location="firmware:" />
 *   <ifconfig location="compat:" />
 *   <ifconfig location="wicked:/etc/wicked/ifconfig" />
 * </sources>
 *
 */
static ni_bool_t
__ni_config_parse_ifconfig_source(ni_string_array_t *sources, xml_node_t *node)
{
	const char *attrval = NULL;
	unsigned int i;

	if ((attrval = xml_node_get_attr(node, "location")) != NULL && *attrval) {
		const char **p = __ni_ifconfig_source_types;
		for (i = 0; p[i]; i++) {
			if (!strncasecmp(attrval, p[i], ni_string_len(p[i]))) {
				ni_debug_readwrite("%s: Adding ifconfig %s", __func__, attrval);
				ni_string_array_append(sources, attrval);
				return TRUE;
			}
		}
	}

	ni_error("Unknown ifconfig location: %s", attrval);
	return FALSE;
}
示例#17
0
ni_bool_t
ni_iaid_map_get_iaid(const ni_iaid_map_t *map, const char *name, unsigned int *iaid)
{
	xml_node_t *root, *node = NULL;
	const char *attr;

	if (!iaid || ni_string_empty(name))
		return FALSE;

	if (!(root = ni_iaid_map_root_node(map)))
		return FALSE;

	while ((node = ni_iaid_map_next_node(root, node))) {
		attr = xml_node_get_attr(node, NI_CONFIG_DEFAULT_IAID_DEVICE);
		if (!ni_string_eq(name, attr))
			continue;

		return ni_iaid_map_node_to_iaid(node, iaid);
	}
	return FALSE;
}
示例#18
0
/* XML stuff to extract the data we need from the Rubrica file */
static GSList *
extract_cards(xmlNodePtr card)
{
    GSList *addrlist = NULL;

    while (card) {
	if (!xmlStrcmp(card->name, CXMLCHARP("Card"))) {
	    LibBalsaAddress *address = libbalsa_address_new();
	    xmlNodePtr children;

	    address->full_name =
		xml_node_get_attr(card, CXMLCHARP("name"));
	    children = card->children;
	    while (children) {
		if (!xmlStrcmp(children->name, CXMLCHARP("Data")))
		    extract_data(children->children, &address->first_name,
				 &address->last_name, &address->nick_name);
		else if (!xmlStrcmp(children->name, CXMLCHARP("Work")))
		    extract_work(children->children,
				 &address->organization);
		else if (!xmlStrcmp(children->name, CXMLCHARP("Net")))
		    extract_net(children->children,
				&address->address_list);

		children = children->next;
	    }

	    if (address->address_list)
		addrlist = g_slist_prepend(addrlist, address);
	    else
		g_object_unref(address);
	}

	card = card->next;
    }

    return addrlist;
}
示例#19
0
ni_bool_t
ni_iaid_map_del_name(ni_iaid_map_t *map, const char *name)
{
	xml_node_t *root, *node = NULL;
	const char *attr;

	if (ni_string_empty(name))
		return FALSE;

	if (!(root = ni_iaid_map_root_node(map)))
		return FALSE;

	while ((node = ni_iaid_map_next_node(root, node))) {
		attr = xml_node_get_attr(node, NI_CONFIG_DEFAULT_IAID_DEVICE);
		if (!ni_string_eq(name, attr))
			continue;

		xml_node_detach(node);
		xml_node_free(node);
		return TRUE;
	}
	return FALSE;
}
示例#20
0
文件: config.c 项目: mijos/wicked
static int
__ni_config_parse_dhcp6_class_data(xml_node_t *node, ni_string_array_t *data, const char *parent)
{
	const char *attrval;
	enum {
		FORMAT_STR,	/* normal string */
		FORMAT_HEX,	/* XX:XX format  */
	};
	int format = FORMAT_STR;
	size_t len;

	if (strcmp(node->name, "class-data")) {
		ni_error("config: <%s> is not a valid <%s> class-data node",
			node->name, parent);
		return -1;
	}

	len = ni_string_len(node->cdata);
	if (len == 0) {
		ni_warn("config: empty %s <class-data> node",
			parent);
		return 0;
	}

	if ((attrval = xml_node_get_attr(node, "format")) != NULL) {
		if (!strcmp(attrval, "hex") || !strcmp(attrval, "mac")) {
			format = FORMAT_HEX;
		} else
		if (!strcmp(attrval, "str") || !strcmp(attrval, "string")) {
			format = FORMAT_STR;
		} else {
			ni_error("config: unknown %s <class-data format=\"%s\"",
				parent, attrval);
			return -1;
		}
	}

	if(format == FORMAT_HEX) {
		unsigned char *buf;

		/* verify the format early ... */
		len = (len / 3) + 1;
		buf = xcalloc(1, len);
		if (ni_parse_hex(node->cdata, buf, len) <= 0) {
			ni_error("config: unable to parse %s hex class-data",
				parent);
			free(buf);
			return -1;
		}
		free(buf);

		ni_string_array_append(data, node->cdata);
	} else {
		ni_stringbuf_t buf = NI_STRINGBUF_INIT_DYNAMIC;

		/* convert to hex-string format */
		ni_stringbuf_grow(&buf, (len * 3));
		ni_format_hex((unsigned char *)node->cdata, len, buf.string, buf.size);

		ni_string_array_append(data, buf.string);
		ni_stringbuf_destroy(&buf);
	}

	return 0;
}
示例#21
0
文件: config.c 项目: mijos/wicked
static int
__ni_config_parse_dhcp6_vendor_opt_node(xml_node_t *node, ni_var_array_t *opts, const char *parent)
{
	const char *attrval;
	const char *code = NULL;
	enum {
		FORMAT_STR,	/* normal string */
		FORMAT_HEX,	/* XX:XX format  */
	};
	int format = FORMAT_STR;
	size_t len;

	if (strcmp(node->name, "option")) {
		ni_error("config: <%s> is not a valid <%s> option node",
			node->name, parent);
		return -1;
	}

	if ((attrval = xml_node_get_attr(node, "code")) != NULL) {
		char *      err;
		long        num;

		num = strtol(attrval, &err, 0);
		if (*err != '\0' || num < 0 || num > 0xffff) {
			ni_error("config: unable to parse %s <option code=\"%s\"",
				parent, attrval);
			return -1;
		}
		code = attrval;
	} else {
		ni_error("config: missed %s <option> without code attribute",
			parent);
		return -1;
	}

	if ((attrval = xml_node_get_attr(node, "format")) != NULL) {
		if (!strcmp(attrval, "hex") || !strcmp(attrval, "mac")) {
			format = FORMAT_HEX;
		} else
		if (!strcmp(attrval, "str") || !strcmp(attrval, "string")) {
			format = FORMAT_STR;
		} else {
			ni_error("config: unknown %s <option format=\"%s\"",
				parent, attrval);
			return -1;
		}
	}

	len = ni_string_len(node->cdata);
	if(format == FORMAT_HEX) {
		unsigned char *buf;

		/* verify the format early ... */
		if (len > 0) {
			len = (len / 3) + 1;
			buf = xcalloc(1, len);
			if (ni_parse_hex(node->cdata, buf, len) <= 0) {
				ni_error("config: unable to parse %s hex option data",
					parent);
				free(buf);
				return -1;
			}
			free(buf);
		}

		ni_var_array_set(opts, code, node->cdata);
	} else {
		ni_stringbuf_t buf = NI_STRINGBUF_INIT_DYNAMIC;

		/* convert to hex-string format */
		if (len > 0) {
			ni_stringbuf_grow(&buf, (len * 3));
			ni_format_hex((unsigned char *)node->cdata, len, buf.string, buf.size);
		}

		ni_var_array_set(opts, code, buf.string);
		ni_stringbuf_destroy(&buf);
	}

	return 0;
}
示例#22
0
文件: config.c 项目: mijos/wicked
ni_bool_t
ni_config_parse_addrconf_dhcp6(struct ni_config_dhcp6 *dhcp6, xml_node_t *node)
{
	xml_node_t *child;

	for (child = node->children; child; child = child->next) {
		const char *attrval;

		if (!strcmp(child->name, "default-duid") && !ni_string_empty(child->cdata)) {
			ni_string_dup(&dhcp6->default_duid, child->cdata);
		} else
		if (!strcmp(child->name, "user-class")) {
			ni_string_array_destroy(&dhcp6->user_class_data);

			if (__ni_config_parse_dhcp6_class_data_nodes(child, &dhcp6->user_class_data) < 0) {
				ni_string_array_destroy(&dhcp6->user_class_data);
				return FALSE;
			}

			if (dhcp6->user_class_data.count == 0) {
				ni_warn("config: discarding <user-class> without any <class-data>");
			}
		} else
		if (!strcmp(child->name, "vendor-class") &&
		    (attrval = xml_node_get_attr(child, "enterprise-number")) != NULL) {
			char *      err;
			long        num;
			
			num = strtol(attrval, &err, 0);
			if (*err != '\0' || num < 0 || num >= 0xffffffff) {
				ni_error("config: unable to parse <vendor-class enterprise-number=\"%s\"",
						attrval);
				return FALSE;
			}

			ni_string_array_destroy(&dhcp6->vendor_class_data);
			if (__ni_config_parse_dhcp6_class_data_nodes(child, &dhcp6->vendor_class_data) < 0) {
				ni_string_array_destroy(&dhcp6->vendor_class_data);
				return FALSE;
			}

			if (dhcp6->vendor_class_data.count == 0) {
				ni_warn("config: discarding <vendor-class> without any <class-data>");
			} else {
				dhcp6->vendor_class_en = num;
			}
		} else
		if (!strcmp(child->name, "vendor-opts") &&
		    (attrval = xml_node_get_attr(child, "enterprise-number")) != NULL) {
			char *      err;
			long        num;
			
			num = strtol(attrval, &err, 0);
			if (*err != '\0' || num < 0 || num >= 0xffffffff) {
				ni_error("config: unable to parse <vendor-class enterprise-number=\"%s\"",
						attrval);
				return FALSE;
			}

			ni_var_array_destroy(&dhcp6->vendor_opts_data);
			if (__ni_config_parse_dhcp6_vendor_opts_nodes(child, &dhcp6->vendor_opts_data) < 0) {
				ni_var_array_destroy(&dhcp6->vendor_opts_data);
			}

			if (dhcp6->vendor_opts_data.count == 0) {
				ni_warn("config: discarding <vendor-opts> without any <option>");
			} else {
				dhcp6->vendor_opts_en = num;
			}
		} else
		if (!strcmp(child->name, "lease-time") && child->cdata) {
			dhcp6->lease_time = strtoul(child->cdata, NULL, 0);
		} else
		if (!strcmp(child->name, "ignore-server")
		 && (attrval = xml_node_get_attr(child, "ip")) != NULL) {
			ni_string_array_append(&dhcp6->ignore_servers, attrval);
		} else
		if (!strcmp(child->name, "prefer-server")) {
			ni_server_preference_t *pref;
			const char *id, *ip;

			ip = xml_node_get_attr(child, "ip"); 
			id = xml_node_get_attr(child, "id");

			if (ip == NULL && id == NULL)
				continue;

			if (dhcp6->num_preferred_servers >= NI_DHCP_SERVER_PREFERENCES_MAX) {
				ni_warn("config: too many <prefer-server> elements");
				continue;
			}

			pref = &dhcp6->preferred_server[dhcp6->num_preferred_servers++];

			if (ip && ni_sockaddr_parse(&pref->address, ip, AF_INET6) < 0) {
				ni_error("config: unable to parse <prefer-server ip=\"%s\"",
						ip);
				return FALSE;
			}

			if (id) {
				int len;

				/* DUID is "opaque", but has 2 bytes type + up to 128 bytes */
				if ((len = sizeof(pref->serverid.data)) > 130)
					len = 130;

				 /* DUID-LL has 2+2 fixed bytes + variable length hwaddress
				  * and seems to be the shortest one I'm aware of ...       */
				if ((len = ni_parse_hex(id, pref->serverid.data, len)) <= 4) {
					ni_error("config: unable to parse <prefer-server id=\"%s\"",
							id);
					return FALSE;
				}
				pref->serverid.len = (size_t)len;
			}

			pref->weight = 255;
			if ((attrval = xml_node_get_attr(child, "weight")) != NULL) {
				if (!strcmp(attrval, "always")) {
					pref->weight = 255;
				} else if (!strcmp(attrval, "never")) {
					pref->weight =  -1;
				} else {
					pref->weight = strtol(attrval, NULL, 0);
					if (pref->weight > 255) {
						pref->weight = 255;
						ni_warn("preferred dhcp server weight exceeds max, "
							"clamping to %d",
							pref->weight);
					}
				}
			}
		} else
		if (!strcmp(child->name, "allow-update")) {
			ni_config_parse_update_targets(&dhcp6->allow_update, child);
		}
	}
	return TRUE;
}
示例#23
0
文件: tester.c 项目: nirmoy/wicked
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;
}
示例#24
0
static ni_bool_t
ni_ifup_hire_nanny(ni_ifworker_t *w)
{
	xml_node_t *ifcfg = NULL, *policy = NULL;
	ni_netdev_t *dev;
	unsigned int i;
	ni_bool_t rv = FALSE;
	char *pname;

	if (!w)
		return rv;

	ni_debug_application("%s: hiring nanny", w->name);

	/* Create a config duplicate for a policy */
	ifcfg = xml_node_clone(w->config.node, NULL);
	if (!ifcfg)
		goto error;

	pname  = ni_ifpolicy_name_from_ifname(w->name);
	ni_debug_application("%s: converting config into policy '%s'",
			w->name, pname);

	policy = ni_convert_cfg_into_policy_node(ifcfg,
			__ni_ifup_generate_match(w),
			pname, w->config.origin);
	ni_string_free(&pname);
	if (!policy) {
		policy = ifcfg; /* Free cloned config*/
		goto error;
	}

#if 0
	/* Do we need this? */

	/* Add link type to match node*/
	if (dev) {
		ni_debug_application("%s: adding link type (%s) to match",
			w->name, ni_linktype_type_to_name(dev->link.type));
		ni_ifpolicy_match_add_link_type(policy, dev->link.type);
	}

	ni_debug_application("%s: adding minimum device state (%s) to match",
		w->name, ni_ifworker_state_name(w->fsm.state));

	/* Add minimum device state to match node */
	if (!ni_ifpolicy_match_add_min_state(policy, w->fsm.state))
		goto error;
#endif

	dev = w->device;
	if (dev) {
		ni_debug_application("%s: enabling device for nanny", w->name);
		if (!ni_nanny_call_device_enable(w->name))
			goto error;
	}

	ni_debug_application("%s: adding policy %s to nanny", w->name,
		xml_node_get_attr(policy, NI_NANNY_IFPOLICY_NAME));

	if (ni_nanny_addpolicy_node(policy, w->config.origin) <= 0) {
		ni_nanny_call_device_disable(w->name);
		goto error;
	}

	ni_debug_application("%s: nanny hired!", w->name);
	ni_ifworker_success(w);

	/* Append policies for all children in case they contain some special options */
	for (i = 0; i < w->children.count; i++) {
		ni_ifworker_t *child = w->children.data[i];

		if (!ni_ifup_hire_nanny(child))
			ni_error("%s: unable to apply configuration to nanny", child->name);
	}

	rv = TRUE;

error:
	if (!rv)
		ni_ifworker_fail(w, "%s: unable to apply configuration to nanny", w->name);
	xml_node_free(policy);
	return rv;
}
示例#25
0
文件: config.c 项目: mijos/wicked
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;
}
示例#26
0
/* Remove address method */
static LibBalsaABErr
libbalsa_address_book_rubrica_modify_address(LibBalsaAddressBook * ab,
					     LibBalsaAddress * address,
					     LibBalsaAddress * newval)
{
    LibBalsaAddressBookRubrica *ab_rubrica =
	LIBBALSA_ADDRESS_BOOK_RUBRICA(ab);
    LibBalsaAddressBookText *ab_text = LIBBALSA_ADDRESS_BOOK_TEXT(ab);
    int fd;
    xmlDocPtr doc = NULL;
    xmlNodePtr root_element;
    xmlNodePtr card;
    LibBalsaABErr result;
    gboolean found;

    /* try to load the current file */
    if ((result = lbab_rubrica_load_xml(ab_rubrica, &doc)) != LBABERR_OK)
	return result;

    /* check if we have a node with the correct full name */
    if (!(root_element = xmlDocGetRootElement(doc)) ||
	xmlStrcmp(root_element->name, CXMLCHARP("Rubrica"))) {
	xmlFreeDoc(doc);
	return LBABERR_ADDRESS_NOT_FOUND;
    }
    card = root_element->children;
    found = FALSE;
    while (card && !found) {
	if (xmlStrcmp(card->name, CXMLCHARP("Card"))) {
	    gchar *full_name = xml_node_get_attr(card, CXMLCHARP("name"));

	    if (full_name) {
		found = !g_ascii_strcasecmp(address->full_name, full_name);
		g_free(full_name);
	    }
	}
    }
    if (!found) {
	xmlFreeDoc(doc);
	return LBABERR_ADDRESS_NOT_FOUND;
    }

    /* remove the card from the document */
    xmlUnlinkNode(card);
    xmlFreeNode(card);

    /* add the new card */
    if (newval)
	lbab_insert_address_node(newval, root_element);

    /* try to open the address book for writing */
    if ((fd = open(ab_text->path, O_WRONLY | O_CREAT, 0666)) == -1) {
	xmlFreeDoc(doc);
	return LBABERR_CANNOT_WRITE;
    }
    if (libbalsa_lock_file(ab_text->path, fd, TRUE, TRUE, FALSE) < 0) {
	xmlFreeDoc(doc);
	close(fd);
	return LBABERR_CANNOT_WRITE;
    }

    /* store the document */
    if (xmlSaveFormatFileEnc(ab_text->path, doc, "UTF-8", 1) == -1)
	result = LBABERR_CANNOT_WRITE;
    else
	result = LBABERR_OK;
    libbalsa_unlock_file(ab_text->path, fd, FALSE);
    close(fd);
    xmlFreeDoc(doc);
    ab_text->mtime = 0;	/* force re-load upon the next access */

    /* done */
    return result;
}
示例#27
0
文件: tester.c 项目: kmroz/wicked
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;
}