const char *auparse_interpret_field(auparse_state_t *au)
{
	if (au->le == NULL)
		return NULL;

	if (au->le->e.sec) {
		rnode *r = aup_list_get_cur(au->le);
		if (r) {
			r->cwd = NULL;
			return nvlist_interp_cur_val(r, au->escape_mode);
		}
	}
	return NULL;
}
const char *auparse_interpret_realpath(auparse_state_t *au)
{
	if (au->le == NULL)
		return NULL;

        if (au->le->e.sec) {
                rnode *r = aup_list_get_cur(au->le);
                if (r) {
			if (nvlist_get_cur_type(r) != AUPARSE_TYPE_ESCAPED_FILE)
				return NULL;

			// Tell it to make a realpath
			r->cwd = au->le->cwd;
                        return nvlist_interp_cur_val(r, au->escape_mode);
		}
        }
	return NULL;
}
static const char *auparse_interpret_sock_parts(auparse_state_t *au,
	const char *field)
{
	if (au->le == NULL)
		return NULL;

        if (au->le->e.sec) {
        	rnode *r = aup_list_get_cur(au->le);
		if (r == NULL)
			return NULL;
		// This is limited to socket address fields
		if (nvlist_get_cur_type(r) != AUPARSE_TYPE_SOCKADDR)
			return NULL;
		// Get interpretation
		const char *val = nvlist_interp_cur_val(r, au->escape_mode);
		if (val == NULL)
			return NULL;
		// make a copy since we modify it
		char *tmp = strdup(val);
		if (tmp == NULL)
			return NULL;
		// Locate the address part
		val = strstr(tmp, field);
		if (val) {
			// Get past the =
			val += strlen(field);
			// find other side
			char *ptr = strchr(val, ' ');
			if (ptr) {
				// terminate, copy, and return it
				*ptr = 0;
				const char *final = strdup(val);
				free(tmp);
				free((void *)au->tmp_translation);
				au->tmp_translation = final;
				return final;
			}
		}
		free(tmp);
        }
/* Return the "interpreted" value of the field in EXPR for RECORD in AU->le.
   Set *FREE_IT to 1 if the return value should free()'d.
   Return NULL on *error.  */
static char *
eval_interpreted_value(auparse_state_t *au, rnode *record,
		       const struct expr *expr, int *free_it)
{
	if (expr->virtual_field == 0) {
		const char *res;

		nvlist_first(&record->nv);
		if (nvlist_find_name(&record->nv, expr->v.p.field.name) == 0)
			return NULL;
		*free_it = 0;
		res = nvlist_interp_cur_val(record);
		if (res == NULL)
			res = nvlist_get_cur_val(&record->nv);
		return (char *)res;
	}
	switch (expr->v.p.field.id) {
	case EF_TIMESTAMP: case EF_RECORD_TYPE:
		return NULL;

	default:
		abort();
	}
}