示例#1
0
static char *canonicalize_path_and_cache(const char *path,
						struct libmnt_cache *cache)
{
	char *p = NULL;
	char *key = NULL;
	char *value = NULL;

	DBG(CACHE, ul_debugobj(cache, "canonicalize path %s", path));
	p = canonicalize_path(path);

	if (p && cache) {
		value = p;
		key = strcmp(path, p) == 0 ? value : strdup(path);

		if (!key || !value)
			goto error;

		if (cache_add_entry(cache, key, value,
				MNT_CACHE_ISPATH))
			goto error;
	}

	return p;
error:
	if (value != key)
		free(value);
	free(key);
	return NULL;
}
示例#2
0
/* add tag to the cache, @devname has to be an allocated string */
static int cache_add_tag(struct libmnt_cache *cache, const char *tagname,
				const char *tagval, char *devname, int flag)
{
	size_t tksz, vlsz;
	char *key;
	int rc;

	assert(cache);
	assert(devname);
	assert(tagname);
	assert(tagval);

	/* add into cache -- cache format for TAGs is
	 *	key    = "TAG_NAME\0TAG_VALUE\0"
	 *	value  = "/dev/foo"
	 */
	tksz = strlen(tagname);
	vlsz = strlen(tagval);

	key = malloc(tksz + vlsz + 2);
	if (!key)
		return -ENOMEM;

	memcpy(key, tagname, tksz + 1);	   /* include '\0' */
	memcpy(key + tksz + 1, tagval, vlsz + 1);

	rc = cache_add_entry(cache, key, devname, flag | MNT_CACHE_ISTAG);
	if (!rc)
		return 0;

	free(key);
	return rc;
}
示例#3
0
文件: schema.c 项目: ZoloZiak/reactos
static void cache_copy(void* data, void* dest, xmlChar* name)
{
    schema_cache* This = (schema_cache*) dest;
    cache_entry* entry = (cache_entry*) data;

    if (xmlHashLookup(This->cache, name) == NULL)
    {
        cache_entry_add_ref(entry);
        cache_add_entry(This, name, entry);
    }
}
示例#4
0
文件: schema.c 项目: ZoloZiak/reactos
/* This one adds all namespaces defined in document to a cache, without anything
   associated with uri obviously.
   Unfortunately namespace:: axis implementation in libxml2 differs from what we need,
   it uses additional node type to describe namespace definition attribute while
   in msxml it's expected to be a normal attribute - as a workaround document is
   queried at libxml2 level here. */
HRESULT cache_from_doc_ns(IXMLDOMSchemaCollection2 *iface, xmlnode *node)
{
    schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface);
    static const xmlChar query[] = "//*/namespace::*";
    xmlXPathObjectPtr nodeset;
    xmlXPathContextPtr ctxt;

    This->read_only = 1;

    ctxt = xmlXPathNewContext(node->node->doc);

    nodeset = xmlXPathEvalExpression(query, ctxt);
    xmlXPathFreeContext(ctxt);

    if (nodeset)
    {
        int pos = 0, len = xmlXPathNodeSetGetLength(nodeset->nodesetval);

        if (len == 0) return S_OK;

        while (pos < len)
        {
            xmlNodePtr node = xmlXPathNodeSetItem(nodeset->nodesetval, pos);
            if (node->type == XML_NAMESPACE_DECL)
            {
                static const xmlChar defns[] = "http://www.w3.org/XML/1998/namespace";
                xmlNsPtr ns = (xmlNsPtr)node;
                cache_entry *entry;

                /* filter out default uri */
                if (xmlStrEqual(ns->href, defns))
                {
                    pos++;
                    continue;
                }

                entry = heap_alloc(sizeof(cache_entry));
                entry->type = CacheEntryType_NS;
                entry->ref = 1;
                entry->schema = NULL;
                entry->doc = NULL;

                cache_add_entry(This, ns->href, entry);
            }
            pos++;
        }

        xmlXPathFreeObject(nodeset);
    }

    return S_OK;
}
示例#5
0
/**
 * mnt_resolve_target:
 * @path: "native" path, a potential mount point
 * @cache: cache for results or NULL.
 *
 * Like mnt_resolve_path(), unless @cache is not NULL and
 * mnt_cache_set_targets(cache, mtab) was called: if @path is found in the
 * cached @mtab and the matching entry was provided by the kernel, assume that
 * @path is already canonicalized. By avoiding a call to realpath(2) on
 * known mount points, there is a lower risk of stepping on a stale mount
 * point, which can result in an application freeze. This is also faster in
 * general, as stat(2) on a mount point is slower than on a regular file.
 *
 * Returns: absolute path or NULL in case of error. The result has to be
 * deallocated by free() if @cache is NULL.
 */
char *mnt_resolve_target(const char *path, struct libmnt_cache *cache)
{
	char *p = NULL;

	/*DBG(CACHE, ul_debugobj(cache, "resolving target %s", path));*/

	if (!cache || !cache->mtab)
		return mnt_resolve_path(path, cache);

	p = (char *) cache_find_path(cache, path);
	if (p)
		return p;
	else {
		struct libmnt_iter itr;
		struct libmnt_fs *fs = NULL;

		mnt_reset_iter(&itr, MNT_ITER_BACKWARD);
		while (mnt_table_next_fs(cache->mtab, &itr, &fs) == 0) {

			if (!mnt_fs_is_kernel(fs)
                            || mnt_fs_is_swaparea(fs)
                            || !mnt_fs_streq_target(fs, path))
				continue;

			p = strdup(path);
			if (!p)
				return NULL;	/* ENOMEM */

			if (cache_add_entry(cache, p, p, MNT_CACHE_ISPATH)) {
				free(p);
				return NULL;	/* ENOMEM */
			}
			break;
		}
	}

	if (!p)
		p = canonicalize_path_and_cache(path, cache);
	return p;
}
示例#6
0
/**
 * mnt_resolve_path:
 * @path: "native" path
 * @cache: cache for results or NULL
 *
 * Converts path:
 *	- to the absolute path
 *	- /dev/dm-N to /dev/mapper/name
 *
 * Returns: absolute path or NULL in case of error. The result has to be
 * deallocated by free() if @cache is NULL.
 */
char *mnt_resolve_path(const char *path, struct libmnt_cache *cache)
{
	char *p = NULL;
	char *key = NULL;
	char *value = NULL;

	/*DBG(CACHE, mnt_debug_h(cache, "resolving path %s", path));*/

	if (!path)
		return NULL;
	if (cache)
		p = (char *) cache_find_path(cache, path);

	if (!p) {
		p = canonicalize_path(path);

		if (p && cache) {
			value = p;
			key = strcmp(path, p) == 0 ? value : strdup(path);

			if (!key || !value)
				goto error;

			if (cache_add_entry(cache, key, value,
							MNT_CACHE_ISPATH))
				goto error;
		}
	}

	return p;
error:
	if (value != key)
		free(value);
	free(key);
	return NULL;
}
示例#7
0
文件: schema.c 项目: ZoloZiak/reactos
static HRESULT WINAPI schema_cache_add(IXMLDOMSchemaCollection2* iface, BSTR uri, VARIANT var)
{
    schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface);
    xmlChar* name = uri ? xmlchar_from_wchar(uri) : xmlchar_from_wchar(emptyW);
    TRACE("(%p)->(%s %s)\n", This, debugstr_w(uri), debugstr_variant(&var));

    if (This->read_only) return E_FAIL;

    switch (V_VT(&var))
    {
        case VT_NULL:
            {
                cache_remove_entry(This, name);
            }
            break;

        case VT_BSTR:
            {
                cache_entry* entry = cache_entry_from_url(var, name, This->version);

                if (entry)
                {
                    cache_entry_add_ref(entry);
                }
                else
                {
                    heap_free(name);
                    return E_FAIL;
                }

                cache_add_entry(This, name, entry);
            }
            break;

        case VT_DISPATCH:
            {
                xmlDocPtr doc = NULL;
                cache_entry* entry;
                CacheEntryType type;
                IXMLDOMNode* domnode = NULL;
                IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IXMLDOMNode, (void**)&domnode);

                if (domnode)
                    doc = xmlNodePtr_from_domnode(domnode, XML_DOCUMENT_NODE)->doc;

                if (!doc)
                {
                    IXMLDOMNode_Release(domnode);
                    heap_free(name);
                    return E_INVALIDARG;
                }
                type = cache_type_from_xmlDocPtr(doc);

                if (type == CacheEntryType_XSD)
                {
                    entry = cache_entry_from_xsd_doc(doc, name, This->version);
                }
                else if (type == CacheEntryType_XDR)
                {
                    entry = cache_entry_from_xdr_doc(doc, name, This->version);
                }
                else
                {
                    WARN("invalid schema!\n");
                    entry = NULL;
                }

                IXMLDOMNode_Release(domnode);

                if (entry)
                {
                    cache_entry_add_ref(entry);
                }
                else
                {
                    heap_free(name);
                    return E_FAIL;
                }

                cache_add_entry(This, name, entry);
            }
            break;

        default:
            {
                heap_free(name);
                return E_INVALIDARG;
            }
    }
    heap_free(name);
    return S_OK;
}