int cil_resolve_name_keep_aliases(struct cil_tree_node *ast_node, char *name, enum cil_sym_index sym_index, void *extra_args, struct cil_symtab_datum **datum)
{
	int rc = SEPOL_ERR;
	struct cil_args_resolve *args = extra_args;
	struct cil_db *db = args->db;
	struct cil_tree_node *node = NULL;

	if (name == NULL) {
		cil_log(CIL_ERR, "Invalid call to cil_resolve_name\n");
		goto exit;
	}

	*datum = NULL;

	if (strchr(name,'.') == NULL) {
		/* No '.' in name */
		rc = __cil_resolve_name_helper(db, ast_node->parent, name, sym_index, datum);
		if (rc != SEPOL_OK) {
			goto exit;
		}
	} else {
		char *sp = NULL;
		char *name_dup = cil_strdup(name);
		char *current = strtok_r(name_dup, ".", &sp);
		char *next = strtok_r(NULL, ".", &sp);
		symtab_t *symtab = NULL;

		if (current == NULL) {
			/* Only dots */
			cil_tree_log(ast_node, CIL_ERR, "Invalid name %s", name);
			free(name_dup);
			goto exit;
		}

		node = ast_node;
		if (*name == '.') {
			/* Leading '.' */
			symtab = &((struct cil_root *)db->ast->root->data)->symtab[CIL_SYM_BLOCKS];
		} else {
			rc = __cil_resolve_name_helper(db, node->parent, current, CIL_SYM_BLOCKS, datum);
			if (rc != SEPOL_OK) {
				free(name_dup);
				goto exit;
			}
			symtab = (*datum)->symtab;
		}
		/* Keep looking up blocks by name until only last part of name remains */
		while (next != NULL) {
			rc = cil_symtab_get_datum(symtab, current, datum);
			if (rc != SEPOL_OK) {
				free(name_dup);
				goto exit;
			}
			node = NODE(*datum);
			if (node->flavor == CIL_BLOCK) {
				symtab = &((struct cil_block*)node->data)->symtab[CIL_SYM_BLOCKS];
			} else {
				if (ast_node->flavor != CIL_IN) {
					cil_log(CIL_WARN, "Can only use %s name for name resolution in \"in\" blocks\n", cil_node_to_string(node));
					free(name_dup);
					rc = SEPOL_ERR;
					goto exit;
				}
				if (node->flavor == CIL_MACRO) {
					struct cil_macro *macro = node->data;
					symtab = &macro->symtab[sym_index];
				}
			}
			current = next;
			next = strtok_r(NULL, ".", &sp);
		}
		symtab = &(symtab[sym_index]);
		rc = cil_symtab_get_datum(symtab, current, datum);
		free(name_dup);
		if (rc != SEPOL_OK) {
			goto exit;
		}
	}

	rc = SEPOL_OK;

exit:
	if (rc != SEPOL_OK) {
		*datum = NULL;
	}

	return rc;
}
int cil_resolve_name_keep_aliases(struct cil_tree_node *ast_node, char *name, enum cil_sym_index sym_index, void *extra_args, struct cil_symtab_datum **datum)
{
	int rc = SEPOL_ERR;
	struct cil_args_resolve *args = extra_args;
	struct cil_db *db = args->db;
	struct cil_tree_node *node = NULL;

	if (name == NULL) {
		cil_log(CIL_ERR, "Invalid call to cil_resolve_name\n");
		goto exit;
	}

	*datum = NULL;

	if (strchr(name,'.') == NULL) {
		 
		rc = __cil_resolve_name_helper(db, ast_node->parent, name, sym_index, datum);
		if (rc != SEPOL_OK) {
			goto exit;
		}
	} else {
		char *sp = NULL;
		char *name_dup = cil_strdup(name);
		char *current = strtok_r(name_dup, ".", &sp);
		char *next = strtok_r(NULL, ".", &sp);
		symtab_t *symtab = NULL;

		if (current == NULL) {
			 
			cil_tree_log(ast_node, CIL_ERR, "Invalid name %s", name);
			free(name_dup);
			goto exit;
		}

		node = ast_node;
		if (*name == '.') {
			 
			symtab = &((struct cil_root *)db->ast->root->data)->symtab[CIL_SYM_BLOCKS];
		} else {
			rc = __cil_resolve_name_helper(db, node->parent, current, CIL_SYM_BLOCKS, datum);
			if (rc != SEPOL_OK) {
				free(name_dup);
				goto exit;
			}
			symtab = (*datum)->symtab;
		}
		 
		while (next != NULL) {
			rc = cil_symtab_get_datum(symtab, current, datum);
			if (rc != SEPOL_OK) {
				free(name_dup);
				goto exit;
			}
			node = NODE(*datum);
			if (node->flavor == CIL_BLOCK) {
				symtab = &((struct cil_block*)node->data)->symtab[CIL_SYM_BLOCKS];
			} else {
				if (ast_node->flavor != CIL_IN) {
					cil_log(CIL_WARN, "Can only use %s name for name resolution in \"in\" blocks\n", cil_node_to_string(node));
					free(name_dup);
					rc = SEPOL_ERR;
					goto exit;
				}
				if (node->flavor == CIL_MACRO) {
					struct cil_macro *macro = node->data;
					symtab = &macro->symtab[sym_index];
				}
			}
			current = next;
			next = strtok_r(NULL, ".", &sp);
		}
		symtab = &(symtab[sym_index]);
		rc = cil_symtab_get_datum(symtab, current, datum);
		free(name_dup);
		if (rc != SEPOL_OK) {
			goto exit;
		}
	}

	rc = SEPOL_OK;

exit:
	if (rc != SEPOL_OK) {
		*datum = NULL;
	}

	return rc;
}