Beispiel #1
0
static xml_node_t *
__ni_ifup_generate_match(ni_ifworker_t *w)
{
	xml_node_t *match, *op;
	unsigned int i;

	if (!(match = xml_node_new(NI_NANNY_IFPOLICY_MATCH, NULL)))
		return NULL;

	if (w->children.count) {
		op = xml_node_new(NI_NANNY_IFPOLICY_MATCH_COND_OR, match);

		if (!__ni_ifup_generate_match_dev(op, w)) {
			xml_node_free(match);
			return NULL;
		}

		for (i = 0; i < w->children.count; i++) {
			ni_ifworker_t *child = w->children.data[i];

			if (!__ni_ifup_generate_match_dev(op, child)) {
				xml_node_free(match);
				return NULL;
			}
		}

	} else {
		if (!__ni_ifup_generate_match_dev(match, w)) {
			xml_node_free(match);
			return NULL;
		}
	}
	return match;
}
Beispiel #2
0
xml_node_t *
xml_node_scan(FILE *fp, const char *location)
{
	xml_reader_t reader;
	xml_node_t *root = xml_node_new(NULL, NULL);

	if (xml_reader_init_file(&reader, fp, location) < 0)
		return NULL;

	if (reader.shared_location)
		root->location = xml_location_new(reader.shared_location, reader.lineCount);

	/* Note! We do not deal with properly formatted XML documents here.
	 * Specifically, we do not expect them to have a document header. */
	if (!xml_process_element_nested(&reader, root, 0)) {
		xml_node_free(root);
		return NULL;
	}

	if (xml_reader_destroy(&reader) < 0) {
		xml_node_free(root);
		return NULL;
	}
	return root;
}
Beispiel #3
0
/*
 * 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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
/*
 * Free an XML node
 */
void
xml_node_free(xml_node_t *node)
{
	xml_node_t *child;

	if (!node)
		return;

	ni_assert(node->refcount);
	if (--(node->refcount) != 0)
		return;

	while ((child = node->children) != NULL) {
		node->children = child->next;
		xml_node_free(child);
	}

	if (node->location)
		xml_location_free(node->location);

	ni_var_array_destroy(&node->attrs);
	free(node->cdata);
	free(node->name);
	free(node);
}
Beispiel #6
0
void
xml_document_free(xml_document_t *doc)
{
	xml_node_free(doc->root);
	ni_string_free(&doc->dtd);
	free(doc);
}
Beispiel #7
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;
}
Beispiel #8
0
static inline void
__xml_node_list_drop(xml_node_t **pos)
{
	xml_node_t *np;

	if ((np = __xml_node_list_remove(pos)) != NULL)
		xml_node_free(np);
}
Beispiel #9
0
void
xml_document_set_root(xml_document_t *doc, xml_node_t *root)
{
	if (doc->root != root) {
		xml_node_free(doc->root);
		doc->root = root;
	}
}
Beispiel #10
0
void
ni_managed_device_set_policy(ni_managed_device_t *mdev, ni_managed_policy_t *mpolicy, xml_node_t *config)
{
	if (!xml_node_is_empty(mdev->selected_config))
		xml_node_free(mdev->selected_config);
	mdev->selected_config = config;

	mdev->selected_policy = mpolicy;
	mdev->selected_policy_seq = mpolicy? mpolicy->seqno : 0;
}
Beispiel #11
0
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;
}
Beispiel #12
0
void
xml_node_array_destroy(xml_node_array_t *array)
{
	unsigned int i;

	for (i = 0; i < array->count; ++i)
		xml_node_free(array->data[i]);

	if (array->data)
		free(array->data);
	memset(array, 0, sizeof(*array));
}
Beispiel #13
0
int main(int argc, char *argv[])
{
  XMLROOT *root = NULL;
  XMLNODE *node = NULL;
  struct cstring *xml_string=NULL;
  CLOG_INFO *log = NULL;

  printf("cXML test program\n");

  log = clog_open("test.log", clog_getlevel("TRACE"),NULL,0);

  root = xml_root_new(log);
  if(0==xml_fread(log, root, argv[1])) {
    fprintf(stderr, "Something was wrong with the XML File, please check the log!\n");
    xml_root_free(log, root);
    exit(1);
  }

  xml_string = xml_node_tostring(log, root->data);
  if(NULL!=xml_string) {
    fprintf(stderr, "%s\n", xml_string->string);
    cstring_free(&xml_string);
  }

  xml_root_free(log, root);


  { // test xml creation functionality..
    XMLNODE* tmpx = NULL;
    XMLNODE* tmpy = NULL;
    node = xml_node_create(log, NULL, "tickets_container", 17);
    xml_node_addattribute(log, node, "bob", "3");
    tmpx = xml_node_create(log, node, "ticket", 6);
    tmpy = xml_node_create(log, tmpx, "id", 2);
    xml_node_adddata(log, tmpy, "3", 1);

    xml_string = xml_node_tostring(log, node);

    if(0!=xml_string->length) {
      fprintf(stderr, "%s\n", xml_string->string);
      cstring_free(&xml_string);
    }

    xml_node_free(log, node);
  }

  clog_close(log);

  return EXIT_SUCCESS;
}
Beispiel #14
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;
}
Beispiel #15
0
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;
}
Beispiel #16
0
static void
ni_dhcp4_tester_protocol_event(enum ni_dhcp4_event ev, const ni_dhcp4_device_t *dev,
		ni_addrconf_lease_t *lease)
{
	ni_debug_dhcp("%s(ev=%u, dev=%s[%u], config-uuid=%s)", __func__, ev,
			dev->ifname, dev->link.ifindex,
			dev->config ? ni_uuid_print(&dev->config->uuid) : "<none>");

	switch (ev) {
	case NI_DHCP4_EVENT_ACQUIRED:
		if (lease && lease->state == NI_ADDRCONF_STATE_GRANTED) {
			FILE *fp = stdout;

			if (dhcp4_tester_opts.output != NULL) {
				fp = fopen(dhcp4_tester_opts.output, "w");
				if (!fp) {
					ni_error("Cannot open %s for output",
						dhcp4_tester_opts.output);
					dhcp4_tester_status = NI_WICKED_RC_ERROR;
					return;
				}
			}
			if (dhcp4_tester_opts.outfmt == NI_DHCP4_TESTER_OUT_LEASE_XML) {
				xml_node_t *xml = NULL;

				if (ni_addrconf_lease_to_xml(lease, &xml, dev->ifname) != 0) {
					if (dhcp4_tester_opts.output)
						fclose(fp);
					dhcp4_tester_status = NI_WICKED_RC_ERROR;
					return;
				}
				xml_node_print(xml, fp);
				xml_node_free(xml);
			} else {
				ni_leaseinfo_dump(fp, lease, dev->ifname, NULL);
			}
			fflush(fp);
			if (dhcp4_tester_opts.output)
				fclose(fp);
			dhcp4_tester_status = NI_WICKED_RC_SUCCESS;
		}
		break;
	default:
		break;
	}
}
Beispiel #17
0
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;
}
Beispiel #18
0
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;
}
Beispiel #19
0
void xml_node_delete_callbacked(xml_node_t *node, void (*callback)(void *))
{
	xml_node_t *child, *child_next;

	if (node->client_data && callback) callback(node->client_data);

	xml_node_unlink(node);

	/* Delete children. */
	for (child = node->children; child; child = child_next) {
		child_next = child->next;
		child->parent = NULL;
		xml_node_delete_callbacked(child, callback);
	}

	/* Free memory taken by node. */
	xml_node_free(node);
}
Beispiel #20
0
ni_bool_t
ni_iaid_map_del_iaid(ni_iaid_map_t *map, unsigned int iaid)
{
	xml_node_t *root, *node = NULL;
	unsigned int curr;

	if (!(root = ni_iaid_map_root_node(map)))
		return FALSE;

	while ((node = ni_iaid_map_next_node(root, node))) {
		if (!ni_iaid_map_node_to_iaid(node, &curr) || iaid != curr)
			continue;

		xml_node_detach(node);
		xml_node_free(node);
		return TRUE;
	}
	return FALSE;
}
Beispiel #21
0
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;
}
Beispiel #22
0
int
ni_addrconf_lease_to_xml(const ni_addrconf_lease_t *lease, xml_node_t **result)
{
	xml_node_t *node;
	int ret = -1;

	if (!lease || !result) {
		errno = EINVAL;
		return -1;
	}

	*result = NULL; /* initialize... */
	node = xml_node_new(NI_ADDRCONF_LEASE_XML_NODE, NULL);
	switch (lease->type) {
	case NI_ADDRCONF_STATIC:
	case NI_ADDRCONF_AUTOCONF:
	case NI_ADDRCONF_INTRINSIC:
		if ((ret = __ni_addrconf_lease_info_to_xml(lease, node)) != 0)
			break;

		if ((ret = __ni_addrconf_lease_static_to_xml(lease, node)) != 0)
			break;
		break;

	case NI_ADDRCONF_DHCP:
		if ((ret = __ni_addrconf_lease_info_to_xml(lease, node)) != 0)
			break;

		if ((ret = __ni_addrconf_lease_dhcp_to_xml(lease, node)) != 0)
			break;

		break;
	default: ;		/* fall through error */
	}

	if (ret == 0) {
		*result = node;
	} else {
		xml_node_free(node);
	}
	return ret;
}
Beispiel #23
0
static xml_node_t *
__ni_ifup_generate_match_type_dev(ni_netdev_t *dev)
{
	const char *type;
	xml_node_t *ret;

	if (!dev || dev->link.type == NI_IFTYPE_UNKNOWN)
		return NULL;

	if (!(type = ni_linktype_type_to_name(dev->link.type)))
		return NULL;

	if (!(ret = xml_node_new(NI_NANNY_IFPOLICY_MATCH_COND_AND, NULL)))
		return NULL;

	if (!xml_node_new_element(NI_NANNY_IFPOLICY_MATCH_DEV, ret, dev->name) ||
	    !xml_node_new_element(NI_NANNY_IFPOLICY_MATCH_LINK_TYPE, ret, type)) {
		xml_node_free(ret);
		return NULL;
	}
	return ret;
}
Beispiel #24
0
ni_bool_t
ni_iaid_map_del_name(ni_iaid_map_t *map, const char *name)
{
	xml_node_t *root, *node = NULL;
	const char *attr;

	if (ni_string_empty(name))
		return FALSE;

	if (!(root = ni_iaid_map_root_node(map)))
		return FALSE;

	while ((node = ni_iaid_map_next_node(root, node))) {
		attr = xml_node_get_attr(node, NI_CONFIG_DEFAULT_IAID_DEVICE);
		if (!ni_string_eq(name, attr))
			continue;

		xml_node_detach(node);
		xml_node_free(node);
		return TRUE;
	}
	return FALSE;
}
Beispiel #25
0
/*
 * Provide all possible descriptions of a device.
 */
xml_node_t *
ni_objectmodel_get_names(const ni_dbus_object_t *object)
{
	xml_node_t *result;
	unsigned int i;
	ni_bool_t ok = FALSE;

	result = xml_node_new(NULL, NULL);
	for (i = 0; i < ni_objectmodel_ns_count; ++i) {
		ni_objectmodel_ns_t *ns;

		ns = ni_objectmodel_ns_list[i];
		if (ns->describe && ns->describe(ns, object, result))
			ok = TRUE;
	}

	if (!ok) {
		xml_node_free(result);
		result = NULL;
	}

	return result;
}
Beispiel #26
0
/**
 * @brief	Return the contact/abuse page with a marked error indicator for the user in the event of a user submission error.
 * @param	branch		a null-terminated string containing the source  of the error: "Abuse" or "Contact"
 * @param	xpath		a null-terminated string containing the xpath of the element in the returned page that should be colored red.
 * @param	id			a null-terminated string containing the id of the error text <span> element to be added to the document.
 * @param	message		a null-terminated string containing the actual error message text to be displayed to the user.
 * @return	NULL on failure, or a pointer to the processed contact page with error message on success.
 */
http_page_t * contact_business_add_error(chr_t *branch, uchr_t *xpath, uchr_t *id, uchr_t *message) {

	http_page_t *page = NULL;
	xmlNodePtr node, error;
	xmlXPathObjectPtr xpath_obj;

	// We are here either for the contact or abuse page.
	if (!st_cmp_cs_eq(NULLER(branch), PLACER("Abuse", 5)) && !((page = http_page_get("contact/abuse")))) {
		return NULL;
	}
	else if (!page && !(page = http_page_get("contact/contact"))) {
		return NULL;
	}

	if ((xpath_obj = xml_xpath_eval(xpath, page->xpath_ctx)) && xpath_obj->nodesetval &&
		xpath_obj->nodesetval->nodeNr && xpath_obj->nodesetval->nodeTab[0]) {

		node = (xmlNodePtr)xpath_obj->nodesetval->nodeTab[0];

		// Make the field red.
		xml_node_set_property(node, (uchr_t *)"class", (uchr_t *)"red");

		// Add the error message.
		if ((error = xml_node_new((uchr_t *)"span"))) {
			xml_node_set_property(error, (uchr_t *)"id", id);
			xml_node_set_content(error, message);

			if (!(xml_node_add_sibling(node, error))) {
				xml_node_free(error);
			}

		}
	}

	return page;
}
Beispiel #27
0
static ni_bool_t
ni_ifup_hire_nanny(ni_ifworker_t *w)
{
	xml_node_t *ifcfg = NULL, *policy = NULL;
	ni_netdev_t *dev;
	unsigned int i;
	ni_bool_t rv = FALSE;
	char *pname;

	if (!w)
		return rv;

	ni_debug_application("%s: hiring nanny", w->name);

	/* Create a config duplicate for a policy */
	ifcfg = xml_node_clone(w->config.node, NULL);
	if (!ifcfg)
		goto error;

	pname  = ni_ifpolicy_name_from_ifname(w->name);
	ni_debug_application("%s: converting config into policy '%s'",
			w->name, pname);

	policy = ni_convert_cfg_into_policy_node(ifcfg,
			__ni_ifup_generate_match(w),
			pname, w->config.origin);
	ni_string_free(&pname);
	if (!policy) {
		policy = ifcfg; /* Free cloned config*/
		goto error;
	}

#if 0
	/* Do we need this? */

	/* Add link type to match node*/
	if (dev) {
		ni_debug_application("%s: adding link type (%s) to match",
			w->name, ni_linktype_type_to_name(dev->link.type));
		ni_ifpolicy_match_add_link_type(policy, dev->link.type);
	}

	ni_debug_application("%s: adding minimum device state (%s) to match",
		w->name, ni_ifworker_state_name(w->fsm.state));

	/* Add minimum device state to match node */
	if (!ni_ifpolicy_match_add_min_state(policy, w->fsm.state))
		goto error;
#endif

	dev = w->device;
	if (dev) {
		ni_debug_application("%s: enabling device for nanny", w->name);
		if (!ni_nanny_call_device_enable(w->name))
			goto error;
	}

	ni_debug_application("%s: adding policy %s to nanny", w->name,
		xml_node_get_attr(policy, NI_NANNY_IFPOLICY_NAME));

	if (ni_nanny_addpolicy_node(policy, w->config.origin) <= 0) {
		ni_nanny_call_device_disable(w->name);
		goto error;
	}

	ni_debug_application("%s: nanny hired!", w->name);
	ni_ifworker_success(w);

	/* Append policies for all children in case they contain some special options */
	for (i = 0; i < w->children.count; i++) {
		ni_ifworker_t *child = w->children.data[i];

		if (!ni_ifup_hire_nanny(child))
			ni_error("%s: unable to apply configuration to nanny", child->name);
	}

	rv = TRUE;

error:
	if (!rv)
		ni_ifworker_fail(w, "%s: unable to apply configuration to nanny", w->name);
	xml_node_free(policy);
	return rv;
}
Beispiel #28
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;
}
static int process(struct hs20_svc *ctx)
{
	int dmacc = 0;
	xml_node_t *soap, *spp, *resp;
	char *user, *realm, *post, *str;

	ctx->addr = getenv("HS20ADDR");
	if (ctx->addr)
		debug_print(ctx, 1, "Connection from %s", ctx->addr);

	user = getenv("HS20USER");
	if (user && strlen(user) == 0)
		user = NULL;
	realm = getenv("HS20REALM");
	if (realm == NULL) {
		debug_print(ctx, 1, "HS20REALM not set");
		return -1;
	}
	post = getenv("HS20POST");
	if (post == NULL) {
		debug_print(ctx, 1, "HS20POST not set");
		return -1;
	}

	soap = xml_node_from_buf(ctx->xml, post);
	if (soap == NULL) {
		debug_print(ctx, 1, "Could not parse SOAP data");
		return -1;
	}
	debug_dump_node(ctx, "Received SOAP message", soap);
	spp = soap_get_body(ctx->xml, soap);
	if (spp == NULL) {
		debug_print(ctx, 1, "Could not get SPP message");
		xml_node_free(ctx->xml, soap);
		return -1;
	}
	debug_dump_node(ctx, "Received SPP message", spp);

	resp = hs20_spp_server_process(ctx, spp, user, realm, dmacc);
	xml_node_free(ctx->xml, soap);
	if (resp == NULL && user == NULL) {
		debug_print(ctx, 1, "Request HTTP authentication");
		return 2; /* Request authentication */
	}
	if (resp == NULL) {
		debug_print(ctx, 1, "No response");
		return -1;
	}

	soap = soap_build_envelope(ctx->xml, resp);
	if (soap == NULL) {
		debug_print(ctx, 1, "SOAP envelope building failed");
		return -1;
	}
	str = xml_node_to_str(ctx->xml, soap);
	xml_node_free(ctx->xml, soap);
	if (str == NULL) {
		debug_print(ctx, 1, "Could not get node string");
		return -1;
	}
	printf("%s", str);
	free(str);

	return 0;
}
Beispiel #30
0
/******************************************************************************
 **函数名称: xml_mark_get_attr
 **功    能: 解析有属性的标签
 **输入参数:
 **     
 **     stack: XML栈
 **     parse: 解析文件缓存信息
 **输出参数:
 **返    回: 0: 成功  !0: 失败
 **实现描述: 
 **注意事项: 
 **     1. 属性值可使用双引号或单引号确定属性值范围
 **     2. 转义符号的转换对应关系如下:
 **       &lt;    <    小于
 **       &gt;    >    大于
 **       &amp;   &    和号
 **       &apos;  '    单引号
 **       &quot;  "    引号
 **作    者: # Qifeng.zou # 2013.02.18 #
 **修    改: # Qifeng.zou # 2014.01.06 #
 ******************************************************************************/
static int xml_mark_get_attr(xml_tree_t *xml, Stack_t *stack, xml_parse_t *parse)
{
    char border = '"';
    xml_node_t *node, *top;
    int len, errflg = 0;
    const char *ptr = parse->ptr;
#if defined(__XML_ESC_PARSE__)
    int ret, size;
    xml_esc_split_t split;
    const xml_esc_t *esc = NULL;

    memset(&split, 0, sizeof(split));
#endif /*__XML_ESC_PARSE__*/

    /* 1. 获取正在处理的标签 */
    top = (xml_node_t*)stack_gettop(stack);
    if (NULL == top) {
        log_error(xml->log, "Get stack top failed!");
        return XML_ERR_STACK;
    }

    /* 3. 将属性节点依次加入标签子节点链表 */
    do {
        /* 3.1 新建节点,并初始化 */
        node = xml_node_creat(xml, XML_NODE_ATTR);
        if (NULL == node) {
            log_error(xml->log, "Create xml node failed!");
            return XML_ERR_CREAT_NODE;
        }

        /* 3.2 获取属性名 */
        while (XmlIsIgnoreChar(*ptr)) { ++ptr; }/* 跳过属性名之前无意义的空格 */

        parse->ptr = ptr;
        while (XmlIsMarkChar(*ptr)) { ++ptr; }  /* 查找属性名的边界 */

        len = ptr - parse->ptr;
        node->name.str = (char *)xml->alloc(xml->pool, (len+1)*sizeof(char));
        if (NULL == node->name.str) {
            errflg = 1;
            log_error(xml->log, "Calloc failed!");
            break;
        }

        memcpy(node->name.str, parse->ptr, len);
        node->name.len = len;
        node->name.str[len] = '\0';
        
        /* 3.3 获取属性值 */
        while (XmlIsIgnoreChar(*ptr)) { ++ptr; }        /* 跳过=之前的无意义字符 */

        if (!XmlIsEqualChar(*ptr)) {                    /* 不为等号,则格式错误 */
            errflg = 1;
            log_error(xml->log, "Attribute format is incorrect![%-.32s]", parse->ptr);
            break;
        }
        ptr++;                                  /* 跳过"=" */
        while (XmlIsIgnoreChar(*ptr)) { ++ptr; }/* 跳过=之后的无意义字符 */

        /* 判断是单引号(')还是双引号(")为属性的边界 */
        if (XmlIsQuotChar(*ptr) || XmlIsSQuotChar(*ptr)) {
            border = *ptr;
        }
        else {                /* 不为 双/单 引号,则格式错误 */
            errflg = 1;
            log_error(xml->log, "XML format is wrong![%-.32s]", parse->ptr);
            break;
        }

        ptr++;
        parse->ptr = ptr;
        while ((*ptr != border) && !XmlIsStrEndChar(*ptr))/* 计算 双/单 引号之间的数据长度 */
        {
        #if defined(__XML_ESC_PARSE__)
            if (XmlIsAndChar(*ptr)) {
                /* 判断并获取转义字串类型及相关信息 */
                esc = xml_esc_get(ptr);

                /* 对包含有转义字串的字串进行切割 */
                ret = xml_esc_split(xml, esc, parse->ptr, ptr-parse->ptr+1, &split);
                if (XML_OK != ret) {
                    errflg = 1;
                    log_error(xml->log, "Parse forwad string failed!");
                    break;
                }

                ptr += esc->len;
                parse->ptr = ptr;
            }
            else
        #endif /*__XML_ESC_PARSE__*/
            {
                ptr++;
            }
        }

        if (*ptr != border) {
            errflg = 1;
            log_error(xml->log, "Mismatch border [%c]![%-.32s]", border, parse->ptr);
            break;
        }

        len = ptr - parse->ptr;
        ptr++;  /* 跳过" */

    #if defined(__XML_ESC_PARSE__)
        if (NULL != split.head) {
            size = xml_esc_size(&split);
            size += len+1;
    
            node->value = (char *)xml->alloc(xml->pool, size);
            if (NULL == node->value) {
                errflg = 1;
                log_error(xml->log, "Alloc memory failed!");
                break;
            }

            xml_esc_merge(&split, node->value);
            
            strncat(node->value, parse->ptr, len);

            xml_esc_free(&split);
        }
        else
    #endif /*__XML_ESC_PARSE__*/
        {
            node->value.str = (char *)xml->alloc(xml->pool, len+1);
            if (NULL == node->value.str) {
                errflg = 1;
                log_error(xml->log, "Calloc failed!");
                break;
            }

            memcpy(node->value.str, parse->ptr, len);
            node->value.len = len;
            node->value.str[len] = '\0';
        }

        /* 3.4 将节点加入属性链表 */
        if (NULL == top->tail) { /* 还没有孩子节点 */
            top->child = node;
        }
        else {
            top->tail->next = node;
        }
        node->parent = top;
        top->tail = node;
        
        /* 3.5 指针向后移动 */
        while (XmlIsIgnoreChar(*ptr)) { ++ptr; }

    }while (XmlIsMarkChar(*ptr));

#if defined(__XML_ESC_PARSE__)
    xml_esc_free(&split);
#endif /*__XML_ESC_PARSE__*/

    if (1 == errflg) {       /* 防止内存泄漏 */
        xml_node_free(xml, node);
        node = NULL;
        return XML_ERR_GET_ATTR;
    }

    parse->ptr = ptr;
    xml_set_attr_flag(top);

    return XML_OK;
}