void xml_node_reparent(xml_node_t *parent, xml_node_t *child) { if (child->parent) xml_node_detach(child); xml_node_add_child(parent, child); }
static int __ni_dhcp6_lease_ia_type_to_xml(const ni_dhcp6_ia_t *ia_list, unsigned ia_type, xml_node_t *node) { const ni_dhcp6_ia_t *ia; xml_node_t *ia_node; const char *ia_name = ni_dhcp6_option_name(ia_type); unsigned int count = 0; int ret; for (ia = ia_list; ia; ia = ia->next) { if (ia->type != ia_type) continue; ia_node = xml_node_new(ia_name, NULL); if ((ret = __ni_dhcp6_lease_ia_data_to_xml(ia, ia_node) == 0)) { xml_node_add_child(node, ia_node); count++; } else { xml_node_free(ia_node); if (ret < 0) return ret; } } return count == 0 ? 1 : 0; }
static int ni_addrconf_lease_static_data_to_xml(const ni_addrconf_lease_t *lease, xml_node_t *node) { static const struct group_map { const char *name; int (*func)(const ni_addrconf_lease_t *lease, xml_node_t *node); } *g, group_map[] = { { NI_ADDRCONF_LEASE_XML_ADDRS_DATA_NODE, ni_addrconf_lease_addrs_data_to_xml }, { NI_ADDRCONF_LEASE_XML_ROUTES_DATA_NODE, ni_addrconf_lease_routes_data_to_xml }, { NI_ADDRCONF_LEASE_XML_DNS_DATA_NODE, ni_addrconf_lease_dns_data_to_xml }, { NULL, NULL } }; xml_node_t *data; if (!ni_string_empty(lease->hostname)) xml_node_new_element("hostname", node, lease->hostname); for (g = group_map; g && g->name && g->func; ++g) { data = xml_node_new(g->name, NULL); if (g->func(lease, data) == 0) { xml_node_add_child(node, data); } else { xml_node_free(data); } } return 0; }
int ni_addrconf_lease_nis_data_to_xml(const ni_addrconf_lease_t *lease, xml_node_t *node) { unsigned int count = 0; unsigned int i, j; ni_nis_info_t *nis; xml_node_t *data; nis = lease->nis; if (!nis) return 1; /* Default domain */ data = xml_node_new("default", NULL); if (!ni_string_empty(nis->domainname)) { count++; xml_node_new_element("domain", data, nis->domainname); } if (nis->default_binding == NI_NISCONF_BROADCAST || nis->default_binding == NI_NISCONF_STATIC) { /* no SLP here */ count++; xml_node_new_element("binding", data, ni_nis_binding_type_to_name(nis->default_binding)); } /* Only in when static binding? */ for (i = 0; i < nis->default_servers.count; ++i) { const char *server = nis->default_servers.data[i]; if (ni_string_empty(server)) continue; count++; xml_node_new_element("server", data, server); } if (count) { xml_node_add_child(node, data); } /* Further domains */ for (i = 0; i < nis->domains.count; ++i) { ni_nis_domain_t *dom = nis->domains.data[i]; if (!dom || ni_string_empty(dom->domainname)) continue; count++; data = xml_node_new("domain", node); xml_node_new_element("domain", data, dom->domainname); if (ni_nis_binding_type_to_name(nis->default_binding)) { xml_node_new_element("binding", data, ni_nis_binding_type_to_name(nis->default_binding)); } for (j = 0; j < dom->servers.count; ++j) { const char *server = dom->servers.data[j]; if (ni_string_empty(server)) continue; xml_node_new_element("server", data, server); } } return count ? 0 : 1; }
static int __ni_dhcp6_lease_ia_data_to_xml(const ni_dhcp6_ia_t *ia, xml_node_t *node) { const char *ia_address = ni_dhcp6_option_name(NI_DHCP6_OPTION_IA_ADDRESS); const char *ia_prefix = ni_dhcp6_option_name(NI_DHCP6_OPTION_IA_PREFIX); const ni_dhcp6_ia_addr_t *iadr; xml_node_t *iadr_node; unsigned int count = 0; char buf[32] = { '\0' }; int ret; switch (ia->type) { case NI_DHCP6_OPTION_IA_TA: xml_node_new_element_uint("interface-id", node, ia->iaid); snprintf(buf, sizeof(buf), "%"PRId64, (int64_t)ia->acquired.tv_sec); xml_node_new_element("acquired", node, buf); break; case NI_DHCP6_OPTION_IA_NA: case NI_DHCP6_OPTION_IA_PD: xml_node_new_element_uint("interface-id", node, ia->iaid); snprintf(buf, sizeof(buf), "%"PRId64, (int64_t)ia->acquired.tv_sec); xml_node_new_element("acquired", node, buf); xml_node_new_element_uint("renewal-time", node, ia->renewal_time); xml_node_new_element_uint("rebind-time", node, ia->rebind_time); break; default: return -1; } for (iadr = ia->addrs; iadr; iadr = iadr->next) { switch (ia->type) { case NI_DHCP6_OPTION_IA_NA: case NI_DHCP6_OPTION_IA_TA: iadr_node = xml_node_new(ia_address, NULL); break; case NI_DHCP6_OPTION_IA_PD: iadr_node = xml_node_new(ia_prefix, NULL); break; default: return -1; } ret = __ni_dhcp6_lease_ia_addr_to_xml(iadr, ia->type, iadr_node); if (ret) { xml_node_free(iadr_node); if (ret < 0) return -1; } else { count++; xml_node_add_child(node, iadr_node); } } __ni_dhcp6_lease_status_to_xml(&ia->status, node); return count == 0 ? 1 : 0; }
int ni_dhcp6_lease_data_to_xml(const ni_addrconf_lease_t *lease, xml_node_t *node, const char *ifname) { static const struct group_map { const char *name; int (*func)(const ni_addrconf_lease_t *, xml_node_t *, const char *); } *g, group_map[] = { { NI_ADDRCONF_LEASE_XML_DNS_DATA_NODE, ni_addrconf_lease_dns_data_to_xml }, { NI_ADDRCONF_LEASE_XML_NTP_DATA_NODE, ni_addrconf_lease_ntp_data_to_xml }, { NI_ADDRCONF_LEASE_XML_SIP_DATA_NODE, ni_addrconf_lease_sip_data_to_xml }, { NI_ADDRCONF_LEASE_XML_PTZ_DATA_NODE, ni_addrconf_lease_ptz_data_to_xml }, { NI_ADDRCONF_LEASE_XML_OPTS_DATA_NODE, ni_addrconf_lease_opts_data_to_xml }, { NULL, NULL } }; xml_node_t *data; if (!node || !lease) return -1; if (lease->family != AF_INET6 || lease->type != NI_ADDRCONF_DHCP) return -1; if (__ni_dhcp6_lease_head_to_xml(lease, node) != 0) return -1; if (__ni_dhcp6_lease_ia_type_to_xml(lease->dhcp6.ia_list, NI_DHCP6_OPTION_IA_NA, node) < 0) return -1; if (__ni_dhcp6_lease_ia_type_to_xml(lease->dhcp6.ia_list, NI_DHCP6_OPTION_IA_TA, node) < 0) return -1; if (__ni_dhcp6_lease_ia_type_to_xml(lease->dhcp6.ia_list, NI_DHCP6_OPTION_IA_PD, node) < 0) return -1; if (__ni_dhcp6_lease_boot_to_xml(lease, node) < 0) return -1; for (g = group_map; g && g->name && g->func; ++g) { data = xml_node_new(g->name, NULL); if (g->func(lease, data, ifname) == 0) { xml_node_add_child(node, data); } else { xml_node_free(data); } } return 0; }
xml_node_t * xml_node_new(const char *ident, xml_node_t *parent) { xml_node_t *node; node = xcalloc(1, sizeof(xml_node_t)); if (ident) node->name = xstrdup(ident); if (parent) xml_node_add_child(parent, node); node->refcount = 1; return node; }
int ni_dhcp6_lease_to_xml(const ni_addrconf_lease_t *lease, xml_node_t *node, const char *ifname) { xml_node_t *data; int ret; if (!lease || !node) return -1; if (!(data = ni_addrconf_lease_xml_new_type_node(lease, NULL))) return -1; if ((ret = ni_dhcp6_lease_data_to_xml(lease, data, ifname)) == 0) xml_node_add_child(node, data); else xml_node_free(data); return ret; }
static int __ni_addrconf_lease_static_to_xml(const ni_addrconf_lease_t *lease, xml_node_t *node) { xml_node_t *data; int ret = 1; if (!lease || !node) return -1; if (!(data = ni_addrconf_lease_xml_new_type_node(lease, NULL))) return -1; if ((ret = ni_addrconf_lease_static_data_to_xml(lease, data)) == 0) xml_node_add_child(node, data); else xml_node_free(data); return ret; }
int ni_addrconf_lease_routes_data_to_xml(const ni_addrconf_lease_t *lease, xml_node_t *node) { ni_route_table_t *tab; ni_route_nexthop_t *nh; xml_node_t *route, *hop; ni_route_t *rp; unsigned int count = 0; unsigned int i; /* A very limitted view */ for (tab = lease->routes; tab; tab = tab->next) { if (tab->tid != 254) /* RT_TABLE_MAIN for now */ continue; for (i = 0; i < tab->routes.count; ++i) { if (!(rp = tab->routes.data[i])) continue; route = xml_node_new("route", NULL); if (ni_sockaddr_is_specified(&rp->destination)) { xml_node_new_element("destination", route, ni_sockaddr_prefix_print(&rp->destination, rp->prefixlen)); } for (nh = &rp->nh; nh; nh = nh->next) { if (!ni_sockaddr_is_specified(&nh->gateway)) continue; hop = xml_node_new("nexthop", route); xml_node_new_element("gateway", hop, ni_sockaddr_print(&nh->gateway)); } if (route->children) { xml_node_add_child(node, route); count++; } else { xml_node_free(route); } } } return count ? 0 : 1; }
static xml_node_t * __ni_ifup_generate_match_dev(xml_node_t *node, ni_ifworker_t *w) { if (!node || !w || !w->name) return NULL; /* TODO: the type has to be from config, _not_ from device * (dev is probably a not ready one just using our name), * but this info is lost in translation... isn't it? */ if (w->device && ni_string_eq(w->name, w->device->name)) { xml_node_t * ret = NULL; if ((ret = __ni_ifup_generate_match_type_dev(w->device))) { xml_node_add_child(node, ret); return ret; } } return xml_node_new_element(NI_NANNY_IFPOLICY_MATCH_DEV, node, w->name); }
void __ni_compat_generate_static_route(xml_node_t *aconf, const ni_route_t *rp, const char *ifname) { xml_node_t *rnode, *mnode, *knode; char *tmp = NULL; const char *ptr; rnode = xml_node_new("route", aconf); if (rp->destination.ss_family != AF_UNSPEC && rp->prefixlen != 0) { xml_node_new_element("destination", rnode, ni_sockaddr_prefix_print(&rp->destination, rp->prefixlen)); } __ni_compat_generate_static_route_hops(rnode, &rp->nh, ifname); knode = NULL; if (rp->table != RT_TABLE_UNSPEC && rp->table != RT_TABLE_MAIN) { if (!(ptr = ni_route_table_type_to_name(rp->table))) ptr = ni_sprint_uint(rp->table); if (knode == NULL) knode = xml_node_new("kern", rnode); xml_node_new_element("table", knode, ptr); } if (rp->type != RTN_UNSPEC && rp->type != RTN_UNICAST) { if (!(ptr = ni_route_type_type_to_name(rp->type))) ptr = ni_sprint_uint(rp->type); if (knode == NULL) knode = xml_node_new("kern", rnode); xml_node_new_element("type", knode, ptr); } if (rp->scope != RT_SCOPE_UNIVERSE) { if (!(ptr = ni_route_scope_type_to_name(rp->scope))) ptr = ni_sprint_uint(rp->scope); if (knode == NULL) knode = xml_node_new("kern", rnode); xml_node_new_element("scope", knode, ptr); } if (rp->protocol != RTPROT_UNSPEC && rp->protocol != RTPROT_BOOT) { if (!(ptr = ni_route_protocol_type_to_name(rp->protocol))) ptr = ni_sprint_uint(rp->protocol); if (knode == NULL) knode = xml_node_new("kern", rnode); xml_node_new_element("protocol", knode, ptr); } if (rp->priority > 0) { xml_node_new_element("priority", rnode, ni_sprint_uint(rp->priority)); } if (ni_sockaddr_is_specified(&rp->pref_src)) { xml_node_new_element("source", rnode, ni_sockaddr_print(&rp->pref_src)); } if (rp->realm > 0) { /* Hmm */ xml_node_new_element("realm", rnode, ni_sprint_uint(rp->realm)); } if (rp->mark > 0 && ni_string_printf(&tmp, "0x%02x", rp->mark)) { xml_node_new_element("mark", rnode, tmp); ni_string_free(&tmp); } if (rp->flags > 0) { ni_string_array_t names = NI_STRING_ARRAY_INIT; xml_node_t *fnode = NULL; unsigned int i; ni_route_flags_get_names(rp->flags, &names); for (i = 0; i < names.count; ++i) { if (fnode == NULL) fnode = xml_node_new("flags", rnode); xml_node_new(names.data[i], fnode); } } if (rp->tos > 0 && ni_string_printf(&tmp, "0x%02x", rp->tos)) { xml_node_new_element("tos", rnode, tmp); ni_string_free(&tmp); } mnode = xml_node_new("metrics", NULL); __ni_compat_generate_static_route_metrics(mnode, rp); if (mnode->children || mnode->attrs.count || mnode->cdata) xml_node_add_child(rnode, mnode); else xml_node_free(mnode); }