예제 #1
0
파일: keys.c 프로젝트: acklinr/vifm
/* Executes keys from the start of key sequence or at some offset in it.
 * Returns error code. */
static int
dispatch_keys(const wchar_t keys[], keys_info_t *keys_info, int no_remap,
		int prev_count)
{
	key_info_t key_info;
	int result;

	if(fill_key_info(&keys, &key_info, prev_count, &result) != 0)
	{
		return result;
	}

	result = KEYS_UNKNOWN;
	if(!no_remap)
	{
		result = dispatch_keys_at_root(keys, keys_info,
				&user_cmds_root[vle_mode_get()], key_info, no_remap);
	}

	if(result == KEYS_UNKNOWN)
	{
		result = dispatch_keys_at_root(keys, keys_info,
				&builtin_cmds_root[vle_mode_get()], key_info, no_remap);
	}

	return result;
}
예제 #2
0
TSS_RESULT
TCS_EnumRegisteredKeys_Internal(TCS_CONTEXT_HANDLE hContext,		/* in */
				TSS_UUID * pKeyUUID,			/* in */
				UINT32 * pcKeyHierarchySize,		/* out */
				TSS_KM_KEYINFO ** ppKeyHierarchy)	/* out */
{
	TSS_RESULT result = TSS_SUCCESS;
	UINT32 count = 0, i;
	TSS_KM_KEYINFO *ret = NULL;
	TSS_UUID tmp_uuid;
	struct key_disk_cache *disk_ptr, *tmp_ptrs[MAX_KEY_CHILDREN];
	struct key_mem_cache *mem_ptr;
	TSS_BOOL is_reg = FALSE;

	LogDebug("Enum Reg Keys");

	if (pcKeyHierarchySize == NULL || ppKeyHierarchy == NULL)
		return TCSERR(TSS_E_BAD_PARAMETER);

	if ((result = ctx_verify_context(hContext)))
		return result;

	if (pKeyUUID != NULL) {
		/* First have to verify the key is registered */
		if ((result = isUUIDRegistered(pKeyUUID, &is_reg)))
			return result;

		if (is_reg == FALSE) {
			/* This return code is not listed as possible in the TSS 1.1 spec,
			 * but it makes more sense than just TCS_SUCCESS or TSS_E_FAIL */
			return TCSERR(TSS_E_PS_KEY_NOTFOUND);
		}
	}

	/* this entire operation needs to be atomic wrt registered keys. We must
	 * lock the mem cache as well to test if a given key is loaded. */
	MUTEX_LOCK(disk_cache_lock);
	MUTEX_LOCK(mem_cache_lock);

	/* return an array of all registered keys if pKeyUUID == NULL */
	if (pKeyUUID == NULL) {
		/*  determine the number of registered keys */
		for (disk_ptr = key_disk_cache_head; disk_ptr; disk_ptr = disk_ptr->next) {
			if (disk_ptr->flags & CACHE_FLAG_VALID)
				count++;
		}

		/* malloc a structure for each of them */
		if (count != 0) {
			ret = calloc(count, sizeof(TSS_KM_KEYINFO));
			if (ret == NULL) {
				LogError("malloc of %zd bytes failed.",
						(count * sizeof(TSS_KM_KEYINFO)));
				count = 0;
				result = TCSERR(TSS_E_OUTOFMEMORY);
				goto done;
			}
		} else {
			goto done;
		}

		/* fill out the structure for each key */
		i = 0;
		for (disk_ptr = key_disk_cache_head; disk_ptr; disk_ptr = disk_ptr->next) {
			if (disk_ptr->flags & CACHE_FLAG_VALID) {
				/* look for a mem cache entry to check if its loaded */
				for (mem_ptr = key_mem_cache_head; mem_ptr; mem_ptr = mem_ptr->next) {
					if (!memcmp(&mem_ptr->uuid, &disk_ptr->uuid, sizeof(TSS_UUID))) {
						if ((result = fill_key_info(disk_ptr, mem_ptr, &ret[i]))) {
							free(ret);
							ret = NULL;
							count = 0;
							goto done;
						}
						break;
					}
				}
				/* if there is no mem cache entry for this key, go ahead and call
				 * fill_key_info(), it will pull everything from disk */
				if (mem_ptr == NULL) {
					if ((result = fill_key_info(disk_ptr, NULL, &ret[i]))) {
						free(ret);
						ret = NULL;
						count = 0;
						goto done;
					}
				}
				i++;
			}
		}
	} else {
		/* return a chain of a key and its parents up to the SRK */
		/*  determine the number of keys in the chain */
		memcpy(&tmp_uuid, pKeyUUID, sizeof(TSS_UUID));
		disk_ptr = key_disk_cache_head;
		while (disk_ptr != NULL && count < MAX_KEY_CHILDREN)
		{
			if (disk_ptr->flags & CACHE_FLAG_VALID &&
				!memcmp(&disk_ptr->uuid, &tmp_uuid, sizeof(TSS_UUID)))
			{
				/* increment count, then search for the parent */
				count++;
				/* save a pointer to this cache entry */
				tmp_ptrs[count - 1] = disk_ptr;
				/* if the parent of this key is NULL, we're at the root of the tree */
				if (!memcmp(&disk_ptr->parent_uuid, &NULL_UUID, sizeof(TSS_UUID)))
					break;
				/* overwrite tmp_uuid with the parent, which we will now search for */
				memcpy(&tmp_uuid, &disk_ptr->parent_uuid, sizeof(TSS_UUID));
				disk_ptr = key_disk_cache_head;
				continue;
			}
			disk_ptr = disk_ptr->next;
		}
		/* when we reach this point, we have an array of TSS_UUID's that leads from the
		 * requested key up to the SRK*/

		/* malloc a structure for each of them */
		if (count != 0) {
			ret = calloc(count, sizeof(TSS_KM_KEYINFO));
			if (ret == NULL) {
				LogError("malloc of %zd bytes failed.",
						(count * sizeof(TSS_KM_KEYINFO)));
				count = 0;
				result = TCSERR(TSS_E_OUTOFMEMORY);
				goto done;
			}
		} else {
			goto done;
		}

		for (i = 0; i < count; i++) {
			/* look for a mem cache entry to check if its loaded */
			for (mem_ptr = key_mem_cache_head; mem_ptr; mem_ptr = mem_ptr->next) {
				if (!memcmp(&mem_ptr->uuid, &tmp_ptrs[i]->uuid, sizeof(TSS_UUID))) {
					if ((result = fill_key_info(tmp_ptrs[i], mem_ptr, &ret[i]))) {
						free(ret);
						ret = NULL;
						count = 0;
						goto done;
					}
					break;
				}
			}
			/* if there is no mem cache entry for this key, go ahead and call
			 * fill_key_info(), it will pull everything from disk */
			if (mem_ptr == NULL) {
				if ((result = fill_key_info(tmp_ptrs[i], NULL, &ret[i]))) {
					free(ret);
					ret = NULL;
					count = 0;
					goto done;
				}
			}
		}
	}
done:

	MUTEX_UNLOCK(disk_cache_lock);
	MUTEX_UNLOCK(mem_cache_lock);

	*ppKeyHierarchy = ret;
	*pcKeyHierarchySize = count;

	return result;
}
예제 #3
0
파일: keys.c 프로젝트: acklinr/vifm
/* Dispatches keys passed in as a selector followed by arbitrary other keys.
 * Returns error code. */
static int
dispatch_selector(const wchar_t keys[], keys_info_t *keys_info,
		key_info_t master_key_info, key_chunk_t *master_curr, int no_remap)
{
	const wchar_t *keys_start = keys;
	key_chunk_t *curr = &selectors_root[vle_mode_get()];
	key_info_t key_info;
	int result;

	if(fill_key_info(&keys, &key_info, master_key_info.count, &result) != 0)
	{
		return result;
	}

	/* The loop finds longest match of the input (keys) among registered
	 * shortcuts. */
	while(*keys != L'\0')
	{
		key_chunk_t *p;

		for(p = curr->child; p != NULL && p->key < *keys; p = p->next)
		{
			/* Advance. */
		}
		if(p == NULL || p->key != *keys)
		{
			break;
		}
		++keys;
		curr = p;
	}

	/* Handle ambiguous selector. */
	if(*keys == '\0' && curr->type != BUILTIN_WAIT_POINT &&
			curr->children_count > 0 && curr->conf.data.handler != NULL &&
			!keys_info->after_wait)
	{
		return KEYS_WAIT_SHORT;
	}

	/* Execute the selector. */
	if(curr->conf.followed == FOLLOWED_BY_MULTIKEY && keys[0] != L'\0')
	{
		const wchar_t mk[] = { keys[0], L'\0' };
		result = execute_next_keys(curr, mk, &key_info, keys_info, 0, no_remap);
		++keys;
	}
	else
	{
		result = keys[0] == L'\0'
		       ? execute_next_keys(curr, L"", &key_info, keys_info, 0, no_remap)
		       : dispatch_key(key_info, keys_info, curr, L"");
	}
	if(IS_KEYS_RET_CODE(result))
	{
		return result;
	}

	/* We used this count in selector, so don't pass it to command. */
	master_key_info.count = NO_COUNT_GIVEN;

	/* Execute command that requested the selector. */
	result = execute_mapping_handler(&master_curr->conf, master_key_info,
			keys_info);
	if(IS_KEYS_RET_CODE(result))
	{
		return result;
	}

	inc_counter(keys_info, keys - keys_start);

	/* execute_keys_general() treats empty input as an error. */
	if(keys[0] == L'\0')
	{
		return 0;
	}
	/* Process the rest of the line. */
	return execute_keys_general(keys, keys_info->after_wait, 0, no_remap);
}