/* * Helper function: given the config document, find out which essid we are * about to configure. */ const char * ni_managed_device_get_essid(xml_node_t *config) { xml_node_t *node; if (config == NULL) return NULL; if (!(node = xml_node_get_child(config, "wireless")) || !(node = xml_node_get_child(node, "essid"))) return NULL; return node->cdata; }
static inline const char * __ni_dhcp_get_cdata(const xml_node_t *node, const char *name) { if (!(node = xml_node_get_child(node, name))) return NULL; return node->cdata; }
int ni_addrconf_lease_dns_from_xml(ni_addrconf_lease_t *lease, const xml_node_t *node) { if (!(node = xml_node_get_child(node, "dns"))) return 1; return ni_addrconf_lease_dns_data_from_xml(lease, node); }
const xml_node_t * ni_addrconf_lease_xml_get_type_node(const ni_addrconf_lease_t *lease, const xml_node_t *node) { const char *name = NULL; name = ni_addrconf_lease_xml_new_type_name(lease); return name ? xml_node_get_child(node, name) : NULL; }
/* * XML helper functions */ static xml_node_t * xml_node_create(xml_node_t *parent, const char *name) { xml_node_t *child; if ((child = xml_node_get_child(parent, name)) == NULL) child = xml_node_new(name, parent); return child; }
int ni_addrconf_lease_from_xml(ni_addrconf_lease_t **leasep, const xml_node_t *root) { const xml_node_t *node = root; ni_addrconf_lease_t *lease; int ret = -1; if (root && !ni_string_eq(root->name, NI_ADDRCONF_LEASE_XML_NODE)) node = xml_node_get_child(root, NI_ADDRCONF_LEASE_XML_NODE); if (!node || !leasep) return ret; *leasep = NULL; /* initialize... */ if (!(lease = ni_addrconf_lease_new(__NI_ADDRCONF_MAX, AF_UNSPEC))) return ret; if ((ret = __ni_addrconf_lease_info_from_xml(lease, node)) != 0) { ni_addrconf_lease_free(lease); return ret; } switch (lease->type) { case NI_ADDRCONF_STATIC: case NI_ADDRCONF_AUTOCONF: case NI_ADDRCONF_INTRINSIC: ret = __ni_addrconf_lease_static_from_xml(lease, node); break; case NI_ADDRCONF_DHCP: ret = __ni_addrconf_lease_dhcp_from_xml(lease, node); break; default: ; /* fall through error */ } if (ret) { ni_addrconf_lease_free(lease); } else { *leasep = lease; } return ret; }
int ni_dhcp_xml_to_lease(ni_addrconf_lease_t *lease, const xml_node_t *node) { char *server_name = NULL; if (!(node = xml_node_get_child(node, "dhcp"))) return -1; __ni_dhcp_get_string(node, "server-name", &server_name); if (server_name) { strncpy(lease->dhcp.servername, server_name, sizeof(lease->dhcp.servername)-1); ni_string_free(&server_name); } __ni_dhcp_get_addr(node, "server-address", &lease->dhcp.serveraddress); __ni_dhcp_get_addr(node, "address", &lease->dhcp.address); __ni_dhcp_get_addr(node, "netmask", &lease->dhcp.netmask); __ni_dhcp_get_addr(node, "broadcast", &lease->dhcp.broadcast); __ni_dhcp_get_uint32(node, "lease-time", &lease->dhcp.lease_time); __ni_dhcp_get_uint32(node, "renewal-time", &lease->dhcp.renewal_time); __ni_dhcp_get_uint32(node, "rebind-time", &lease->dhcp.rebind_time); __ni_dhcp_get_uint16(node, "mtu", &lease->dhcp.mtu); return 0; }
static int __ni_addrconf_lease_addr_from_xml(ni_address_t **ap_list, unsigned int family, const xml_node_t *node) { const xml_node_t *child; ni_sockaddr_t addr; unsigned int plen; ni_address_t *ap; if (!(child = xml_node_get_child(node, "local"))) return 1; if (ni_sockaddr_prefix_parse(child->cdata, &addr, &plen)) return -1; if (family != addr.ss_family || (family == AF_INET && plen > 32) || (family == AF_INET6 && plen > 128)) return -1; if (!(ap = ni_address_new(family, plen, &addr, NULL))) return -1; if ((child = xml_node_get_child(node, "peer"))) { if (ni_sockaddr_parse(&ap->peer_addr, child->cdata, family) != 0) goto failure; } if ((child = xml_node_get_child(node, "anycast"))) { if (ni_sockaddr_parse(&ap->anycast_addr, child->cdata, family) != 0) goto failure; } if ((child = xml_node_get_child(node, "broadcast"))) { if (ni_sockaddr_parse(&ap->bcast_addr, child->cdata, family) != 0) goto failure; } if (family == AF_INET && (child = xml_node_get_child(node, "label"))) { ni_string_dup(&ap->label, child->cdata); } if ((child = xml_node_get_child(node, "cache-info"))) { xml_node_t *cnode; unsigned int lft; if ((cnode = xml_node_get_child(child, "preferred-lifetime"))) { if (ni_parse_uint(child->cdata, &lft, 10) != 0) goto failure; ap->ipv6_cache_info.preferred_lft = lft; } if ((cnode = xml_node_get_child(child, "valid-lifetime"))) { if (ni_parse_uint(child->cdata, &lft, 10) != 0) goto failure; ap->ipv6_cache_info.valid_lft = lft; } } ni_address_list_append(ap_list, ap); return 0; failure: ni_address_free(ap); return -1; }
/* * Read a lease from a file */ ni_addrconf_lease_t * ni_addrconf_lease_file_read(const char *ifname, int type, int family) { ni_addrconf_lease_t *lease = NULL; xml_node_t *xml = NULL, *lnode; char *filename = NULL; FILE *fp; if (!__ni_addrconf_lease_file_path(&filename, ni_config_statedir(), ifname, type, family)) { ni_error("Unable to construct lease file name: %m"); return NULL; } if ((fp = fopen(filename, "re")) == NULL) { if (errno == ENOENT) { if (__ni_addrconf_lease_file_path(&filename, ni_config_storedir(), ifname, type, family)) fp = fopen(filename, "re"); } if (fp == NULL) { if (errno != ENOENT) { ni_error("Unable to open %s for reading: %m", filename); } ni_string_free(&filename); return NULL; } } ni_debug_dhcp("Reading lease from %s", filename); xml = xml_node_scan(fp, filename); fclose(fp); if (xml == NULL) { ni_error("Unable to parse %s", filename); ni_string_free(&filename); return NULL; } /* find the lease node already here, so we can report it */ if (!ni_string_eq(xml->name, NI_ADDRCONF_LEASE_XML_NODE)) lnode = xml_node_get_child(xml, NI_ADDRCONF_LEASE_XML_NODE); else lnode = xml; if (!lnode) { ni_error("File '%s' does not contain a valid lease", filename); ni_string_free(&filename); xml_node_free(xml); return NULL; } if (ni_addrconf_lease_from_xml(&lease, xml) < 0) { ni_error("Unable to parse xml lease file '%s'", filename); ni_string_free(&filename); xml_node_free(xml); return NULL; } ni_string_free(&filename); xml_node_free(xml); return lease; }
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; }