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; } }
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; }
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); }
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); }
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; }
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(ðtool->priv_flags->names, buf.string) == 0) { if (enabled) ethtool->priv_flags->bitmap |= NI_BIT(i); } ni_stringbuf_destroy(&buf); } return TRUE; }
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); }
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); }
/* * 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; }
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"); } }
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 */ }
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); }
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; }
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; }
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); }
/* * 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; }
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; }
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; }
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; }
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; }
int xml_writer_destroy(xml_writer_t *writer) { ni_stringbuf_destroy(&writer->buffer); return xml_writer_close(writer); }