static ni_bool_t ni_iaid_map_set_default_file(char **filename) { return ni_string_printf(filename, "%s/%s", ni_config_storedir(), NI_CONFIG_DEFAULT_IAID_FILE) != NULL; }
/* * Use some locking here... */ int ni_dhcp6_load_duid(ni_opaque_t *duid, const char *filename) { char path[PATH_MAX]; const char *name = CONFIG_DHCP6_DUID_NODE; xml_node_t *xml = NULL; xml_node_t *node; FILE *fp; int rv; if (!filename) { snprintf(path, sizeof(path), "%s/%s", ni_config_storedir(), CONFIG_DHCP6_DUID_FILE); filename = path; } else { name = "duid"; } if ((fp = fopen(filename, "r")) == NULL) { if (errno != ENOENT) ni_error("unable to open %s for reading: %m", filename); return -1; } xml = xml_node_scan(fp, NULL); fclose(fp); if (xml == NULL) { ni_error("%s: unable to parse xml file", filename); return -1; } if (xml->name == NULL) node = xml->children; else node = xml; if (!node || !ni_string_eq(node->name, name)) { ni_error("%s: does not contain %s", filename, name); xml_node_free(xml); return -1; } rv = 0; if (!node->cdata || !ni_duid_parse_hex(duid, node->cdata)) { ni_error("%s: unable to parse %s xml file", filename, name); rv = -1; } xml_node_free(xml); return rv; }
int ni_dhcp6_save_duid(const ni_opaque_t *duid, const char *filename) { char path[PATH_MAX]; const char *name = CONFIG_DHCP6_DUID_NODE; ni_opaque_t temp = NI_OPAQUE_INIT; xml_node_t *node; FILE *fp; int rv = -1; if (!duid || !duid->len) { ni_error("BUG: Refusing to save empty duid"); return -1; } if(ni_dhcp6_load_duid(&temp, filename) == 0) return 1; if (!filename) { snprintf(path, sizeof(path), "%s/%s", ni_config_storedir(), CONFIG_DHCP6_DUID_FILE); filename = path; } else { name = "duid"; } if ((node = xml_node_new(name, NULL)) == NULL) { ni_error("Unable to create %s xml node: %m", name); return -1; } ni_duid_format_hex(&node->cdata, duid); if ((fp = fopen(filename, "w")) == NULL) { ni_error("%s: unable to open file for writing: %m", filename); } else if ((rv = xml_node_print(node, fp)) < 0) { ni_error("%s: unable to write %s xml representation", filename, name); } xml_node_free(node); fclose(fp); if(rv < 0) unlink(filename); return rv; }
void ni_addrconf_lease_file_remove(const char *ifname, int type, int family) { __ni_addrconf_lease_file_remove(ni_config_statedir(), ifname, type, family); __ni_addrconf_lease_file_remove(ni_config_storedir(), ifname, type, family); }
/* * 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; }
/* * Write a lease to a file */ int ni_addrconf_lease_file_write(const char *ifname, ni_addrconf_lease_t *lease) { char tempname[PATH_MAX] = {'\0'}; ni_bool_t fallback = FALSE; char *filename = NULL; xml_node_t *xml = NULL; FILE *fp = NULL; int ret = -1; int fd; if (lease->state == NI_ADDRCONF_STATE_RELEASED) { ni_addrconf_lease_file_remove(ifname, lease->type, lease->family); return 0; } if (!__ni_addrconf_lease_file_path(&filename, ni_config_storedir(), ifname, lease->type, lease->family)) { ni_error("Cannot construct lease file name: %m"); return -1; } ni_debug_dhcp("Preparing xml lease data for '%s'", filename); if ((ret = ni_addrconf_lease_to_xml(lease, &xml)) != 0) { if (ret > 0) { ni_debug_dhcp("Skipped, %s:%s leases are disabled", ni_addrfamily_type_to_name(lease->family), ni_addrconf_type_to_name(lease->type)); } else { ni_error("Unable to represent %s:%s lease as XML", ni_addrfamily_type_to_name(lease->family), ni_addrconf_type_to_name(lease->type)); } goto failed; } snprintf(tempname, sizeof(tempname), "%s.XXXXXX", filename); if ((fd = mkstemp(tempname)) < 0) { if (errno == EROFS && __ni_addrconf_lease_file_path(&filename, ni_config_statedir(), ifname, lease->type, lease->family)) { ni_debug_dhcp("Read-only filesystem, try fallback to %s", filename); snprintf(tempname, sizeof(tempname), "%s.XXXXXX", filename); fd = mkstemp(tempname); fallback = TRUE; } if (fd < 0) { ni_error("Cannot create temporary lease file '%s': %m", tempname); tempname[0] = '\0'; ret = -1; goto failed; } } if ((fp = fdopen(fd, "we")) == NULL) { ret = -1; close(fd); ni_error("Cannot reopen temporary lease file '%s': %m", tempname); goto failed; } ni_debug_dhcp("Writing lease to temporary file for '%s'", filename); xml_node_print(xml, fp); fclose(fp); xml_node_free(xml); if ((ret = rename(tempname, filename)) != 0) { ni_error("Unable to rename temporary lease file '%s' to '%s': %m", tempname, filename); goto failed; } else if (!fallback) { __ni_addrconf_lease_file_remove(ni_config_statedir(), ifname, lease->type, lease->family); } ni_debug_dhcp("Lease written to file '%s'", filename); ni_string_free(&filename); return 0; failed: if (fp) fclose(fp); if (xml) xml_node_free(xml); if (tempname[0]) unlink(tempname); ni_string_free(&filename); return -1; }