示例#1
0
文件: ifevent.c 项目: nirmoy/wicked
void
ni_server_trace_interface_nduseropt_events(ni_netdev_t *dev, ni_event_t event)
{
	ni_ipv6_devinfo_t *ipv6 = dev->ipv6;

	if (!ni_debug_guard(NI_LOG_DEBUG2, NI_TRACE_IPV6|NI_TRACE_EVENTS))
		return;

	switch (event) {
	case NI_EVENT_RDNSS_UPDATE:
		if (ipv6 && ipv6->radv.rdnss) {
			ni_ipv6_ra_rdnss_t *rdnss;
			char buf[32] = {'\0'};
			const char *rainfo;

			rainfo = ipv6->radv.managed_addr ? "managed" :
				 ipv6->radv.other_config ? "config"  : "unmanaged";

			for (rdnss = ipv6->radv.rdnss; rdnss; rdnss = rdnss->next) {
				ni_stringbuf_t lft = NI_STRINGBUF_INIT_BUFFER(buf);

				ni_trace("%s: update IPv6 RA<%s> RDNSS<%s>[%s]",
					dev->name, rainfo,
					ni_sockaddr_print(&rdnss->server),
					ni_lifetime_print_valid(&lft, rdnss->lifetime));
				ni_stringbuf_destroy(&lft);
			}
		}
		break;

	case NI_EVENT_DNSSL_UPDATE:
		if (ipv6 && ipv6->radv.dnssl) {
			ni_ipv6_ra_dnssl_t *dnssl;
			char buf[32] = {'\0'};
			const char *rainfo;

			rainfo = ipv6->radv.managed_addr ? "managed" :
				 ipv6->radv.other_config ? "config"  : "unmanaged";
			for (dnssl = ipv6->radv.dnssl; dnssl; dnssl = dnssl->next) {
				ni_stringbuf_t lft = NI_STRINGBUF_INIT_BUFFER(buf);

				ni_trace("%s: update IPv6 RA<%s> DNSSL<%s>[%s]",
					dev->name, rainfo, dnssl->domain,
					ni_lifetime_print_valid(&lft, dnssl->lifetime));
				ni_stringbuf_destroy(&lft);
			}
		}
		break;

	default:
		ni_debug_verbose(NI_LOG_DEBUG2, NI_TRACE_IPV6|NI_TRACE_EVENTS,
			"%s: IPv6 RA %s event: ", dev->name, ni_event_type_to_name(event));
		break;
	}
}
示例#2
0
xml_token_type_t
xml_get_tag_attributes(xml_reader_t *xr, xml_node_t *node)
{
	ni_stringbuf_t tokenValue, attrName, attrValue;
	xml_token_type_t token;

	ni_stringbuf_init(&tokenValue);
	ni_stringbuf_init(&attrName);
	ni_stringbuf_init(&attrValue);

	token = xml_get_token(xr, &tokenValue);
	while (1) {
		if (token == RightAngle || token == RightAngleQ || token == RightAngleSlash)
			break;

		if (token != Identifier) {
			xml_parse_error(xr, "Unexpected token in tag attributes");
			token = None;
			break;
		}

		ni_stringbuf_move(&attrName, &tokenValue);

		token = xml_get_token(xr, &tokenValue);
		if (token != Equals) {
			xml_node_add_attr(node, attrName.string, NULL);
			continue;
		}

		token = xml_get_token(xr, &tokenValue);
		if (token != QuotedString) {
			xml_parse_error(xr, "Attribute value not a quoted string!");
			token = None;
			break;
		}

		xml_debug("  attr %s=%s\n", attrName.string, tokenValue.string);
		xml_node_add_attr(node, attrName.string, tokenValue.string);

		token = xml_get_token(xr, &tokenValue);
	}

	ni_stringbuf_destroy(&tokenValue);
	ni_stringbuf_destroy(&attrName);
	ni_stringbuf_destroy(&attrValue);
	return token;
}
示例#3
0
文件: ifevent.c 项目: nirmoy/wicked
void
ni_server_trace_interface_prefix_events(ni_netdev_t *dev, ni_event_t event, const ni_ipv6_ra_pinfo_t *pi)
{
	char vbuf[32] = {'\0'}, pbuf[32] = {'\0'};
	ni_stringbuf_t vlft = NI_STRINGBUF_INIT_BUFFER(vbuf);
	ni_stringbuf_t plft = NI_STRINGBUF_INIT_BUFFER(pbuf);

	ni_debug_verbose(NI_LOG_DEBUG2, NI_TRACE_IPV6|NI_TRACE_EVENTS,
		"%s: %s IPv6 RA<%s> Prefix<%s/%u %s,%s>[%s,%s]", dev->name,
		(event == NI_EVENT_PREFIX_UPDATE ? "update" : "delete"),
		(dev->ipv6 && dev->ipv6->radv.managed_addr ? "managed" :
		(dev->ipv6 && dev->ipv6->radv.other_config ? "config" : "unmanaged")),
		ni_sockaddr_print(&pi->prefix), pi->length,
		(pi->on_link ? "onlink" : "not-onlink"),
		(pi->autoconf ? "autoconf" : "no-autoconf"),
		ni_lifetime_print_valid(&vlft, pi->valid_lft),
		ni_lifetime_print_preferred(&plft, pi->preferred_lft));
	ni_stringbuf_destroy(&vlft);
	ni_stringbuf_destroy(&plft);
}
示例#4
0
文件: ifevent.c 项目: nirmoy/wicked
void
ni_server_trace_interface_addr_events(ni_netdev_t *dev, ni_event_t event, const ni_address_t *ap)
{
	ni_stringbuf_t flags = NI_STRINGBUF_INIT_DYNAMIC;

	ni_address_format_flags(&flags, ap->family, ap->flags, NULL);
	ni_debug_verbose(NI_LOG_DEBUG2, NI_TRACE_IPV6|NI_TRACE_EVENTS,
			"%s: %s event: %s flags[%u] %s",
			dev->name, ni_event_type_to_name(event),
			ni_sockaddr_prefix_print(&ap->local_addr, ap->prefixlen),
			ap->flags, flags.string ? flags.string : "");
	ni_stringbuf_destroy(&flags);
}
示例#5
0
int main(int argc, char **argv)
{
	ni_teamd_client_t *tdc;
	const char *command, *param1, *param2;
	char *val = NULL;
	ni_json_t *json;
	int rv = 0;

	if (argc < 3) {
		printf("Usage: teamd-test ifname command [param1] [param2]\n");
		return -2;
	}
	command = argv[2];
	param1 = argv[3];
	param2 = argv[4];

	if (ni_init("teamd-test") < 0)
		return -1;
	ni_config_teamd_enable(NI_CONFIG_TEAMD_CTL_DETECT_ONCE);

	tdc = ni_teamd_client_open(argv[1]);

	if (ni_string_eq(command, "state-item-get"))
		rv = ni_teamd_ctl_state_get_item(tdc, param1, &val);
	else if (ni_string_eq(command, "state-item-set"))
		rv = ni_teamd_ctl_state_set_item(tdc, param1, param2);
	else if (ni_string_eq(command, "state-dump"))
		rv = ni_teamd_ctl_state_dump(tdc, &val);
	else if (ni_string_eq(command, "config-dump"))
		rv = ni_teamd_ctl_config_dump(tdc, FALSE, &val);
	else if (ni_string_eq(command, "config-dump-actual"))
		rv = ni_teamd_ctl_config_dump(tdc, TRUE, &val);

	printf("%s\n", val ? val : ni_format_boolean(!!rv));

	if (val && (json = ni_json_parse_string(val))) {
		ni_stringbuf_t buf = NI_STRINGBUF_INIT_DYNAMIC;

		ni_json_format_string(&buf, json, NULL);
		printf("type<%s>: %s\n",
			ni_json_type_name(ni_json_type(json)), buf.string);
		ni_stringbuf_destroy(&buf);
		ni_json_free(json);
	} else if (val) {
		printf("json parsing error\n");
	}

	ni_string_free(&val);
	return rv;
}
示例#6
0
文件: ethtool.c 项目: openSUSE/wicked
static dbus_bool_t
ni_objectmodel_ethtool_set_priv_flags(ni_dbus_object_t *object,
		const ni_dbus_property_t *property,
		const ni_dbus_variant_t *argument,
		DBusError *error)
{
	const ni_dbus_variant_t *dict;
	ni_ethtool_t *ethtool;
	unsigned int i, len;
	dbus_bool_t enabled;
	ni_stringbuf_t buf;
	const char *name;

	if (!ni_dbus_variant_is_dict_array(argument))
		return FALSE;
	if (!(ethtool = ni_objectmodel_ethtool_write_handle(object, error)))
		return FALSE;

	ni_ethtool_priv_flags_free(ethtool->priv_flags);
	if (!(ethtool->priv_flags = ni_ethtool_priv_flags_new()))
		return FALSE;

	if ((len = argument->array.len) > 32)
		len = 32;

	ni_stringbuf_init(&buf);
	for (i = 0; i < argument->array.len; ++i) {
		dict = &argument->variant_array_value[i];
		if (!ni_dbus_variant_is_dict(dict))
			continue;

		if (!ni_dbus_dict_get_string(dict, "name", &name) ||
		    !ni_dbus_dict_get_bool(dict, "enabled", &enabled))
			continue;

		ni_stringbuf_put(&buf, name, ni_string_len(name));
		ni_stringbuf_trim_head(&buf, " \t\n");
		ni_stringbuf_trim_tail(&buf, " \t\n");
		if (ni_string_empty(buf.string))
			continue;

		if (ni_string_array_append(&ethtool->priv_flags->names, buf.string) == 0) {
			if (enabled)
				ethtool->priv_flags->bitmap |= NI_BIT(i);
		}
		ni_stringbuf_destroy(&buf);
	}
	return TRUE;
}
示例#7
0
文件: main.c 项目: kmroz/wicked
static void
show_exec_info(int argc, char **argv)
{
	ni_stringbuf_t args = NI_STRINGBUF_INIT_DYNAMIC;
	int i;

	for (i = 0; i < argc && argv[i]; ++i) {
		if (i != 0)
			ni_stringbuf_putc(&args, ' ');
		ni_stringbuf_puts(&args, argv[i]);
	}

	ni_debug_application("Executing: %s", args.string);
	ni_stringbuf_destroy(&args);
}
示例#8
0
文件: json-test.c 项目: gsanso/wicked
void
test_case2()
{
	ni_stringbuf_t buf = NI_STRINGBUF_INIT_DYNAMIC;
	ni_json_t *json;

	json = init2();

	ni_json_format_string(&buf, json, NULL);
	printf("#--> j2:\n%s\n", buf.string);
	printf("#<-- j2:\n");
	test_parse(buf.string);
	printf("\n");
	ni_stringbuf_destroy(&buf);
	ni_json_free(json);
}
示例#9
0
文件: ethtool.c 项目: openSUSE/wicked
/*
 * wake_on_lan
 */
static int
get_ethtool_wake_on_lan(const ni_netdev_ref_t *ref, ni_ethtool_t *ethtool, struct ethtool_args *args)
{
	ni_ethtool_wake_on_lan_t *wol;
	ni_stringbuf_t buf = NI_STRINGBUF_INIT_DYNAMIC;

	(void)args;
	if (ni_ethtool_get_wake_on_lan(ref, ethtool) < 0 || !(wol = ethtool->wake_on_lan))
		return -1;

	printf("wake-on-lan:\n");
	ni_ethtool_wol_flags_format(&buf, wol->options, ",");
	printf("\toptions: %s\n", buf.string ? buf.string : "disabled");
	ni_stringbuf_destroy(&buf);

	return 0;
}
示例#10
0
文件: json-test.c 项目: gsanso/wicked
void
test_parse(const char *string)
{
	ni_stringbuf_t buf = NI_STRINGBUF_INIT_DYNAMIC;
	ni_json_t *json = ni_json_parse_string(string);

	if (json) {
		ni_json_format_string(&buf, json, NULL);
		printf("type<%s>: %s\n",
			ni_json_type_name(ni_json_type(json)), buf.string);
		ni_stringbuf_destroy(&buf);

		ni_json_free(json);
	} else {
		printf("parse error\n");
	}
}
示例#11
0
static inline int
ni_ethtool_get_priv_flags_names(const char *ifname, ni_ethtool_t *ethtool, ni_string_array_t *names)
{
	struct ethtool_gstrings *gstrings;
	unsigned int count, i;
	ni_stringbuf_t buf;
	const char *name;

	count = ni_ethtool_get_gstring_count(ifname, " priv-flags count", ETH_SS_PRIV_FLAGS);
	if (!count) {
		if (errno == EOPNOTSUPP && ethtool->driver_info)
			count = ethtool->driver_info->supports.n_priv_flags;

		if (!count) {
			ni_ethtool_set_supported(ethtool, NI_ETHTOOL_SUPP_GET_PRIV_FLAGS, FALSE);
			return -EOPNOTSUPP;
		}
	}
	if (count > 32)
		count = 32;
	gstrings = ni_ethtool_get_gstrings(ifname, " priv-flags names", ETH_SS_PRIV_FLAGS, count);
	if (!gstrings) {
		if (errno == EOPNOTSUPP)
			ni_ethtool_set_supported(ethtool, NI_ETHTOOL_SUPP_GET_PRIV_FLAGS, FALSE);
		free(gstrings);
		return errno ? -errno : -1;
	}

	ni_stringbuf_init(&buf);
	for (i = 0; i < gstrings->len; ++i) {
		name = (const char *)(gstrings->data + i * ETH_GSTRING_LEN);
		ni_stringbuf_put(&buf, name, ETH_GSTRING_LEN);
		ni_stringbuf_trim_head(&buf, " \t\n");
		ni_stringbuf_trim_tail(&buf, " \t\n");
		ni_string_array_append(names, buf.string);
		ni_stringbuf_destroy(&buf);
	}
	free(gstrings);

	if (names->count == count)
		return 0;

	ni_string_array_destroy(names);
	return -ENOMEM; /* array append */
}
示例#12
0
void
__ni_ifsysctl_vars_map(ni_var_array_t *vars, const char *key, const char *val)
{
	ni_stringbuf_t buf = NI_STRINGBUF_INIT_DYNAMIC;
	const char *ptr;

	/* Normalize the net.ipv4.ip_forward alias */
	if (!strcmp(key, "net.ipv4.ip_forward"))
		key = "net.ipv4.conf.all.forwarding";

	/*
	 * Filter out net.ipv4.conf.* and net.ipv6.conf.* only.
	 */
	if (strncmp(key, "net.ipv4.conf.", sizeof("net.ipv4.conf.")-1)
	&&  strncmp(key, "net.ipv6.conf.", sizeof("net.ipv6.conf.")-1))
		return;

	/*
	 * Resolve $INTERFACE and $SYSCTL_IF wildcard crap
	 */
	if ((ptr = strstr(key, "$INTERFACE"))) {
		ni_stringbuf_puts(&buf, key);
		ni_stringbuf_truncate(&buf, ptr - key);
		ni_stringbuf_puts(&buf, "default");
		ptr += sizeof("$INTERFACE")-1;
		ni_stringbuf_puts(&buf, ptr);
		key = buf.string;
	} else
	if ((ptr = strstr(key, "$SYSCTL_IF"))) {
		ni_stringbuf_puts(&buf, key);
		ni_stringbuf_truncate(&buf, ptr - key);
		ni_stringbuf_puts(&buf, "default");
		ptr += sizeof("$SYSCTL_IF")-1;
		ni_stringbuf_puts(&buf, ptr);
		key = buf.string;
	}

	/*
	 * And finally add it to the array
	 */
	ni_var_array_set(vars, key, val);
	ni_stringbuf_destroy(&buf);
}
示例#13
0
文件: util.c 项目: okirch/testbus
char *
ni_unquote(const char **stringp, const char *sepa)
{
	ni_stringbuf_t buf = NI_STRINGBUF_INIT_DYNAMIC;
	const char *src = *stringp;
	int cc;

	if (sepa)
		src += strspn(src, sepa);

	while ((cc = *src) != '\0') {
		++src;
		if (sepa && strchr(sepa, cc))
			break;
		if (cc == '"') {
			while ((cc = *src++) != '"') {
				if (cc == '\0')
					goto failed;
				if (cc == '\\') {
					cc = *src++;
					if (cc == '\0')
						goto failed;
				}
				ni_stringbuf_putc(&buf, cc);
			}
		} else if (cc == '\'') {
			while ((cc = *src++) != '\'') {
				if (cc == '\0')
					goto failed;
				ni_stringbuf_putc(&buf, cc);
			}
		} else {
			ni_stringbuf_putc(&buf, cc);
		}
	}

	*stringp = src;
	return buf.string;

failed:
	ni_stringbuf_destroy(&buf);
	return NULL;
}
示例#14
0
文件: util.c 项目: okirch/testbus
const char *
ni_string_join(char **str, const ni_string_array_t *nsa, const char *sep)
{
	ni_stringbuf_t buf;
	unsigned int i;

	if (nsa == NULL || sep == NULL || str == NULL)
		return NULL;

	ni_stringbuf_init(&buf);
	for (i=0; i < nsa->count; ++i) {
		if (i)
			ni_stringbuf_puts(&buf, sep);
		ni_stringbuf_puts(&buf, nsa->data[i]);
	}
	ni_string_dup(str, buf.string);
	ni_stringbuf_destroy(&buf);

	return *str;
}
示例#15
0
文件: ifevent.c 项目: nirmoy/wicked
void
ni_server_trace_rule_events(ni_netconfig_t *nc, ni_event_t event, const ni_rule_t *rule)
{
	ni_stringbuf_t buf = NI_STRINGBUF_INIT_DYNAMIC;
	unsigned int family_trace;

	switch (rule->family) {
	case AF_INET:
		family_trace = NI_TRACE_IPV4;
		break;
	case AF_INET6:
		family_trace = NI_TRACE_IPV6;
		break;
	default:
		family_trace = 0;
		break;
	}
	ni_debug_verbose(NI_LOG_DEBUG2, family_trace|NI_TRACE_ROUTE|NI_TRACE_EVENTS,
			"%s event: %s", ni_event_type_to_name(event),
			ni_rule_print(&buf, rule));
	ni_stringbuf_destroy(&buf);
}
示例#16
0
文件: protocol.c 项目: mchf/wicked
/*
 * Decode an RFC3397 DNS search order option.
 */
static int
ni_dhcp_decode_dnssearch(ni_buffer_t *optbuf, ni_string_array_t *list, const char *what)
{
	ni_stringbuf_t namebuf = NI_STRINGBUF_INIT_DYNAMIC;
	unsigned char *base = ni_buffer_head(optbuf);
	unsigned int base_offset = optbuf->head;
	size_t len;

	ni_string_array_destroy(list);

	while (ni_buffer_count(optbuf) && !optbuf->underflow) {
		ni_buffer_t *bp = optbuf;
		ni_buffer_t jumpbuf;

		while (1) {
			unsigned int pos = bp->head - base_offset;
			unsigned int pointer;
			char label[64];
			int length;

			if ((length = ni_buffer_getc(bp)) < 0)
				goto failure; /* unexpected EOF */

			if (length == 0)
				break;	/* end of this name */

			switch (length & 0xC0) {
			case 0:
				/* Plain name component */
				if (ni_buffer_get(bp, label, length) < 0)
					goto failure;

				label[length] = '\0';
				if (!ni_stringbuf_empty(&namebuf))
					ni_stringbuf_putc(&namebuf, '.');
				ni_stringbuf_puts(&namebuf, label);
				break;

			case 0xC0:
				/* Pointer */
				pointer = (length & 0x3F) << 8;
				if ((length = ni_buffer_getc(bp)) < 0)
					goto failure;

				pointer |= length;
				if (pointer >= pos)
					goto failure;

				ni_buffer_init_reader(&jumpbuf, base, pos);
				jumpbuf.head = pointer;
				bp = &jumpbuf;
				break;

			default:
				goto failure;
			}

		}

		if (!ni_stringbuf_empty(&namebuf)) {

			len = ni_string_len(namebuf.string);
			if (ni_check_domain_name(namebuf.string, len, 0)) {
				ni_string_array_append(list, namebuf.string);
			} else {
				ni_debug_dhcp("Discarded suspect %s: %s", what,
					ni_print_suspect(namebuf.string, len));
			}
		}
		ni_stringbuf_destroy(&namebuf);
	}

	return 0;

failure:
	ni_stringbuf_destroy(&namebuf);
	ni_string_array_destroy(list);
	return -1;
}
示例#17
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;
}
示例#18
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;
}
示例#19
0
文件: ifdown.c 项目: mijos/wicked
int
ni_do_ifdown(int argc, char **argv)
{
	enum  { OPT_HELP, OPT_FORCE, OPT_DELETE, OPT_NO_DELETE, OPT_TIMEOUT };
	static struct option ifdown_options[] = {
		{ "help",	no_argument, NULL,		OPT_HELP },
		{ "force",	required_argument, NULL,	OPT_FORCE },
		{ "delete",	no_argument, NULL,	OPT_DELETE },
		{ "no-delete",	no_argument, NULL,	OPT_NO_DELETE },
		{ "timeout",	required_argument, NULL,	OPT_TIMEOUT },
		{ NULL }
	};
	ni_ifmatcher_t ifmatch;
	ni_ifmarker_t ifmarker;
	ni_ifworker_array_t ifmarked;
	ni_string_array_t ifnames = NI_STRING_ARRAY_INIT;
	unsigned int nmarked, max_state = NI_FSM_STATE_DEVICE_DOWN;
	unsigned int timeout = NI_IFWORKER_DEFAULT_TIMEOUT;
	ni_stringbuf_t sb = NI_STRINGBUF_INIT_DYNAMIC;
	ni_fsm_t *fsm;
	int c, status = NI_WICKED_RC_USAGE;

	fsm = ni_fsm_new();
	ni_assert(fsm);
	ni_fsm_require_register_type("reachable", ni_ifworker_reachability_check_new);

	/* Allow ifdown only on non-persistent interfaces previously configured by ifup */
	memset(&ifmatch, 0, sizeof(ifmatch));
	memset(&ifmarker, 0, sizeof(ifmarker));
	memset(&ifmarked, 0, sizeof(ifmarked));

	ifmatch.require_configured = TRUE;
	ifmatch.allow_persistent = FALSE;
	ifmatch.require_config = FALSE;

	ifmarker.target_range.min = NI_FSM_STATE_DEVICE_DOWN;
	ifmarker.target_range.max = __NI_FSM_STATE_MAX - 2;

	optind = 1;
	while ((c = getopt_long(argc, argv, "", ifdown_options, NULL)) != EOF) {
		switch (c) {
		case OPT_FORCE:
			if (!ni_ifworker_state_from_name(optarg, &max_state) ||
			    !ni_ifworker_state_in_range(&ifmarker.target_range, max_state)) {
				ni_error("ifdown: wrong force option \"%s\"", optarg);
				goto usage;
			}
			/* Allow ifdown on persistent, unconfigured interfaces */
			ifmatch.require_configured = FALSE;
			ifmatch.allow_persistent = TRUE;
			ifmatch.require_config = FALSE;
			break;

		case OPT_DELETE:
			max_state = NI_FSM_STATE_DEVICE_DOWN;
			/* Allow ifdown on persistent, unconfigured interfaces */
			ifmatch.require_configured = FALSE;
			ifmatch.allow_persistent = TRUE;
			ifmatch.require_config = FALSE;
			break;

		case OPT_NO_DELETE:
			max_state = NI_FSM_STATE_DEVICE_READY;
			/* Allow ifdown only on non-persistent interfaces previously configured by ifup */
			ifmatch.require_configured = TRUE;
			ifmatch.allow_persistent = FALSE;
			ifmatch.require_config = FALSE;
			break;

		case OPT_TIMEOUT:
			if (!strcmp(optarg, "infinite")) {
				timeout = NI_IFWORKER_INFINITE_TIMEOUT;
			} else if (ni_parse_uint(optarg, &timeout, 10) >= 0) {
				timeout *= 1000; /* sec -> msec */
			} else {
				ni_error("ifdown: cannot parse timeout option \"%s\"", optarg);
				goto usage;
			}
			break;

		default:
		case OPT_HELP:
usage:
			ni_client_get_state_strings(&sb, &ifmarker.target_range);
			fprintf(stderr,
				"wicked [options] ifdown [ifdown-options] <ifname ...>|all\n"
				"\nSupported ifdown-options:\n"
				"  --help\n"
				"      Show this help text.\n"
				"  --force <state>\n"
				"      Force putting interface into the <state> state. Despite of persistent mode being set. Possible states:\n"
				"  %s\n"
				"  --delete\n"
				"      Delete device. Despite of persistent mode being set\n"
				"  --no-delete\n"
				"      Do not attempt to delete a device, neither physical nor virtual\n"
				"  --timeout <nsec>\n"
				"      Timeout after <nsec> seconds\n",
				sb.string
				);
			ni_stringbuf_destroy(&sb);
			return status;
		}
	}

	if (optind >= argc) {
		fprintf(stderr, "Missing interface argument\n");
		goto usage;
	}

	ifmarker.target_range.min = NI_FSM_STATE_NONE;
	ifmarker.target_range.max = max_state;

	fsm->worker_timeout = ni_fsm_find_max_timeout(fsm, timeout);

	if (!ni_fsm_create_client(fsm)) {
		/* Severe error we always explicitly return */
		return NI_WICKED_RC_ERROR;
	}

	if (!ni_fsm_refresh_state(fsm)) {
		/* Severe error we always explicitly return */
		return NI_WICKED_RC_ERROR;
	}

	/* Get workers that match given criteria */
	nmarked = 0;
	while (optind < argc) {
		ifmatch.name = argv[optind++];
		ifmatch.ifdown = TRUE;
		ni_fsm_get_matching_workers(fsm, &ifmatch, &ifmarked);

		if (ni_string_eq(ifmatch.name, "all") ||
		    ni_string_empty(ifmatch.name)) {
			ni_string_array_destroy(&ifnames);
			break;
		}

		if (ni_string_array_index(&ifnames, ifmatch.name) == -1)
			ni_string_array_append(&ifnames, ifmatch.name);
	}

	/* Mark and start selected workers */
	if (ifmarked.count) {
		if (ni_config_use_nanny()) {
			/* Disable devices and delete all related policies from nanny */
			ni_ifdown_fire_nanny(&ifmarked);
		}

		/* Start workers to perform actual ifdown */
		nmarked = ni_fsm_mark_matching_workers(fsm, &ifmarked, &ifmarker);
	}

	if (nmarked == 0) {
		ni_note("ifdown: no matching interfaces");
		status = NI_WICKED_RC_SUCCESS;
	} else {
		if (ni_fsm_schedule(fsm) != 0)
			ni_fsm_mainloop(fsm);

		status = ni_ifstatus_shutdown_result(fsm, &ifnames, &ifmarked);
	}

	ni_string_array_destroy(&ifnames);
	ni_ifworker_array_destroy(&ifmarked);
	return status;
}
示例#20
0
ni_bool_t
xml_process_element_nested(xml_reader_t *xr, xml_node_t *cur, unsigned int nesting)
{
	ni_stringbuf_t tokenValue, identifier;
	xml_token_type_t token;
	xml_node_t *child;

	ni_stringbuf_init(&tokenValue);
	ni_stringbuf_init(&identifier);

	while (1) {
		token = xml_get_token(xr, &tokenValue);

		switch (token) {
		case CData:
			/* process element content */
			xml_node_set_cdata(cur, tokenValue.string);
			break;

		case LeftAngleExclam:
			/* Most likely <!DOCTYPE ...> */
			if (!xml_get_identifier(xr, &identifier)) {
				xml_parse_error(xr, "Bad element: tag open <! not followed by identifier");
				goto error;
			}

			if (strcmp(identifier.string, "DOCTYPE")) {
				xml_parse_error(xr, "Unexpected element: <!%s ...> not supported", identifier.string);
				goto error;
			}

			while (1) {
				token = xml_get_token(xr, &identifier);
				if (token == RightAngle)
					break;
				if (token == Identifier && !xr->doctype)
					ni_string_dup(&xr->doctype, identifier.string);
				if (token != Identifier && token != QuotedString) {
					xml_parse_error(xr, "Error parsing <!DOCTYPE ...> attributes");
					goto error;
				}
			}
			break;

		case LeftAngle:
			/* New element start */
			if (!xml_get_identifier(xr, &identifier)) {
				xml_parse_error(xr, "Bad element: tag open < not followed by identifier");
				goto error;
			}

			child = xml_node_new(identifier.string, cur);
			if (xr->shared_location)
				child->location = xml_location_new(xr->shared_location, xr->lineCount);

			token = xml_get_tag_attributes(xr, child);
			if (token == None) {
				xml_parse_error(xr, "Error parsing <%s ...> tag attributes", child->name);
				goto error;
			} else
			if (token == RightAngle) {
				/* Handle <foo>...</foo> */
				xml_debug("%*.*s<%s>\n", nesting, nesting, "", child->name);
				if (!xml_process_element_nested(xr, child, nesting + 2))
					goto error;
			} else if (token == RightAngleSlash) {
				/* We parsed a "<foo/>" element - nothing left to do, we're done */
				xml_debug("%*.*s<%s/>\n", nesting, nesting, "", child->name);
			} else {
				xml_parse_error(xr, "Unexpected token %s at end of <%s ...",
						xml_token_name(token), child->name);
				goto error;
			}

			break;

		case LeftAngleSlash:
			/* Element end */
			if (!xml_get_identifier(xr, &identifier)) {
				xml_parse_error(xr, "Bad element: end tag open </ not followed by identifier");
				goto error;
			}

			if (xml_get_token(xr, &tokenValue) != RightAngle) {
				xml_parse_error(xr, "Bad element: </%s - missing tag close", identifier.string);
				goto error;
			}

			if (cur->parent == NULL) {
				xml_parse_error(xr, "Unexpected </%s> tag", identifier.string);
				goto error;
			}
			if (strcmp(cur->name, identifier.string)) {
				xml_parse_error(xr, "Closing tag </%s> does not match <%s>",
						identifier.string, cur->name);
				goto error;
			}

			xml_debug("%*.*s</%s>\n", nesting, nesting, "", cur->name);
			goto success;

		case LeftAngleQ:
			/* New PI node starts here */
			if (!xml_get_identifier(xr, &identifier)) {
				xml_parse_error(xr, "Bad element: tag open <? not followed by identifier");
				goto error;
			}

			child = xml_node_new(identifier.string, NULL);
			if (xr->shared_location)
				child->location = xml_location_new(xr->shared_location, xr->lineCount);

			token = xml_get_tag_attributes(xr, child);
			if (token == None) {
				xml_parse_error(xr, "Error parsing <?%s ...?> tag attributes", child->name);
				xml_node_free(child);
				goto error;
			} else
			if (token == RightAngleQ) {
				xml_debug("%*.*s<%s>\n", nesting, nesting, "", child->name);
				xml_process_pi_node(xr, child);
				xml_node_free(child);
			} else {
				xml_parse_error(xr, "Unexpected token %s at end of <?%s ...",
						xml_token_name(token), child->name);
				xml_node_free(child);
				goto error;
			}

			break;

		case EndOfDocument:
			if (cur->parent) {
				xml_parse_error(xr, "End of document while processing element <%s>", cur->name);
				goto error;
			}
			goto success;

		case None:
			/* parser error */
			goto error;

		default:
			xml_parse_error(xr, "Unexpected token %s", xml_token_name(token));
			goto error;
		}
	}

success:
	ni_stringbuf_destroy(&tokenValue);
	ni_stringbuf_destroy(&identifier);
	return TRUE;

error:
	ni_stringbuf_destroy(&tokenValue);
	ni_stringbuf_destroy(&identifier);
	return FALSE;
}
示例#21
0
int
xml_writer_destroy(xml_writer_t *writer)
{
	ni_stringbuf_destroy(&writer->buffer);
	return xml_writer_close(writer);
}