/* Increment 1 location and then scan for next field */ const char *auparse_find_field_next(auparse_state_t *au) { if (au->le == NULL) return NULL; if (au->find_field == NULL) { errno = EINVAL; return NULL; } if (au->le->e.sec) { int moved = 0; rnode *r = aup_list_get_cur(au->le); while (r) { // For each record in the event... if (!moved) { nvlist_next(&r->nv); moved=1; } if (nvlist_find_name(&r->nv, au->find_field)) return nvlist_get_cur_val(&r->nv); r = aup_list_next(au->le); if (r) { aup_list_first_field(au->le); load_interpretation_list(r->interp); } } } return NULL; }
/* Return the "raw" 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_raw_value(auparse_state_t *au, rnode *record, const struct expr *expr, int *free_it) { if (expr->virtual_field == 0) { nvlist_first(&record->nv); if (nvlist_find_name(&record->nv, expr->v.p.field.name) == 0) return NULL; *free_it = 0; return (char *)nvlist_get_cur_val(&record->nv); } switch (expr->v.p.field.id) { case EF_TIMESTAMP: case EF_RECORD_TYPE: return NULL; default: abort(); } }
/* Evaluate EXPR on RECORD in AU->le. Return 1 if EXPR is true, 0 if it false or if it fails. (No error reporting facility is provided; an invalid term is considered to be false; e.g. !invalid is true.) */ int expr_eval(auparse_state_t *au, rnode *record, const struct expr *expr) { switch (expr->op) { case EO_NOT: return !expr_eval(au, record, expr->v.sub[0]); case EO_AND: return (expr_eval(au, record, expr->v.sub[0]) && expr_eval(au, record, expr->v.sub[1])); case EO_OR: return (expr_eval(au, record, expr->v.sub[0]) || expr_eval(au, record, expr->v.sub[1])); case EO_RAW_EQ: case EO_RAW_NE: { int free_it, ne; char *value; value = eval_raw_value(au, record, expr, &free_it); if (value == NULL) return 0; assert(expr->precomputed_value == 0); ne = strcmp(expr->v.p.value.string, value); if (free_it != 0) free(value); return expr->op == EO_RAW_EQ ? ne == 0 : ne != 0; } case EO_INTERPRETED_EQ: case EO_INTERPRETED_NE: { int free_it, ne; char *value; value = eval_interpreted_value(au, record, expr, &free_it); if (value == NULL) return 0; assert(expr->precomputed_value == 0); ne = strcmp(expr->v.p.value.string, value); if (free_it != 0) free(value); return expr->op == EO_INTERPRETED_EQ ? ne == 0 : ne != 0; } case EO_VALUE_EQ: case EO_VALUE_NE: case EO_VALUE_LT: case EO_VALUE_LE: case EO_VALUE_GT: case EO_VALUE_GE: { int err, cmp; cmp = compare_values(au, record, expr, &err); if (err != 0) return 0; switch (expr->op) { case EO_VALUE_EQ: return cmp == 0; case EO_VALUE_NE: return cmp != 0; case EO_VALUE_LT: return cmp < 0; case EO_VALUE_LE: return cmp <= 0; case EO_VALUE_GT: return cmp > 0; case EO_VALUE_GE: return cmp >= 0; default: abort(); } } case EO_FIELD_EXISTS: assert(expr->virtual_field == 0); nvlist_first(&record->nv); return nvlist_find_name(&record->nv, expr->v.p.field.name) != 0; case EO_REGEXP_MATCHES: return regexec(expr->v.regexp, record->record, 0, NULL, 0) == 0; default: abort(); } }