static int tr_fspec_destructor(void *obj)
{
TR_FSPEC *fspec = talloc_get_type_abort(obj, TR_FSPEC);
- size_t ii;
if (fspec->field != NULL)
tr_free_name(fspec->field);
- for (ii=0; ii<TR_MAX_FILTER_SPEC_MATCHES; ii++) {
- if (fspec->match[ii] != NULL)
- tr_free_name(fspec->match[ii]);
- }
+
+ if (fspec->match)
+ g_ptr_array_unref(fspec->match);
+
return 0;
}
TR_FSPEC *tr_fspec_new(TALLOC_CTX *mem_ctx)
{
TR_FSPEC *fspec = talloc(mem_ctx, TR_FSPEC);
- size_t ii=0;
if (fspec != NULL) {
fspec->field = NULL;
- for (ii=0; ii<TR_MAX_FILTER_SPEC_MATCHES; ii++)
- fspec->match[ii] = NULL;
-
+ fspec->match = g_ptr_array_new_with_free_func((GDestroyNotify) tr_free_name);
+ if (fspec->match == NULL) {
+ talloc_free(fspec);
+ return NULL;
+ }
talloc_set_destructor((void *)fspec, tr_fspec_destructor);
}
return fspec;
}
-void tr_fspec_add_match(TR_FSPEC *fspec, TR_NAME *match)
+TR_NAME *tr_fspec_add_match(TR_FSPEC *fspec, TR_NAME *match)
{
- size_t ii;
- for (ii=0; ii<TR_MAX_FILTER_SPEC_MATCHES; ii++) {
- if (fspec->match[ii]==NULL) {
- fspec->match[ii]=match;
- break;
- }
- }
- /* TODO: handle case that adding the match failed */
+ guint old_len = fspec->match->len;
+ g_ptr_array_add(fspec->match, match);
+
+ if (fspec->match->len == old_len)
+ return NULL; /* failed to add */
+
+ return match;
}
/* returns 1 if the spec matches */
TR_NAME *name=NULL;
int retval=0;
- size_t ii=0;
+ guint ii=0;
if (fspec==NULL)
return 0;
if (name==NULL)
return 0; /* if there's no value, there's no match */
- for (ii=0; ii<TR_MAX_FILTER_SPEC_MATCHES; ii++) {
- if (fspec->match[ii]!=NULL) {
- if (tr_name_prefix_wildcard_match(name, fspec->match[ii])) {
- retval=1;
- tr_debug("tr_fspec_matches: Field %.*s value \"%.*s\" matches \"%.*s\" for %s filter.",
- fspec->field->len, fspec->field->buf,
- name->len, name->buf,
- fspec->match[ii]->len, fspec->match[ii]->buf,
- tr_filter_type_to_string(ftype));
- break;
- }
- }
+ if (g_ptr_array_find_with_equal_func(fspec->match,
+ name,
+ (GEqualFunc) tr_name_prefix_wildcard_match,
+ &ii)) {
+ retval=1;
+ tr_debug("tr_fspec_matches: Field %.*s value \"%.*s\" matches \"%.*s\" for %s filter.",
+ fspec->field->len, fspec->field->buf,
+ name->len, name->buf,
+ ((TR_NAME *)g_ptr_array_index(fspec->match,ii))->len,
+ ((TR_NAME *)g_ptr_array_index(fspec->match,ii))->buf,
+ tr_filter_type_to_string(ftype));
}
if (!retval) {
return fl;
}
+static int tr_filter_destructor(void *object)
+{
+ TR_FILTER *filt = talloc_get_type_abort(object, TR_FILTER);
+ if (filt->lines)
+ g_ptr_array_unref(filt->lines);
+ return 0;
+}
TR_FILTER *tr_filter_new(TALLOC_CTX *mem_ctx)
{
TR_FILTER *f = talloc(mem_ctx, TR_FILTER);
talloc_free(f);
return NULL;
}
+ talloc_set_destructor((void *)f, tr_filter_destructor);
}
return f;
}
{
guint old_len = filt->lines->len;
g_ptr_array_add(filt->lines, line);
- talloc_steal(filt, line); /* take this no matter what */
+
if (old_len == filt->lines->len)
return NULL; /* failed to add */
+
+ talloc_steal(filt, line);
return line;
}
return tr_filter_iter_next(iter);
}
+TR_FSPEC_ITER *tr_fspec_iter_new(TALLOC_CTX *mem_ctx)
+{
+ TR_FSPEC_ITER *iter = talloc(mem_ctx, TR_FSPEC_ITER);
+ if (iter) {
+ iter->fspec = NULL;
+ }
+ return iter;
+}
+
+void tr_fspec_iter_free(TR_FSPEC_ITER *iter)
+{
+ talloc_free(iter);
+}
+
+TR_NAME *tr_fspec_iter_first(TR_FSPEC_ITER *iter, TR_FSPEC *fspec)
+{
+ if (!iter || !fspec)
+ return NULL;
+
+ iter->fspec = fspec;
+ iter->ii = 0;
+ return tr_fspec_iter_next(iter);
+}
+
+TR_NAME *tr_fspec_iter_next(TR_FSPEC_ITER *iter)
+{
+ if (!iter)
+ return NULL;
+
+ if (iter->ii < iter->fspec->match->len)
+ return g_ptr_array_index(iter->fspec->match, iter->ii++);
+ return NULL;
+}
+
/**
* Check that a filter is valid, i.e., can be processed.
*
int tr_filter_validate(TR_FILTER *filt)
{
TALLOC_CTX *tmp_ctx = talloc_new(NULL);
- size_t jj=0, kk=0;
+ size_t jj=0;
TR_FILTER_ITER *filt_iter = tr_filter_iter_new(tmp_ctx);
TR_FLINE *this_fline = NULL;
return 0;
}
- /* check that at least one match is non-null */
- for (kk=0; kk<TR_MAX_FILTER_SPEC_MATCHES; kk++) {
- if (this_fline->specs[jj]->match[kk]!=NULL)
- break;
- }
- if (kk==TR_MAX_FILTER_SPEC_MATCHES) {
+ /* check that at least one match is defined*/
+ if (this_fline->specs[jj]->match->len == 0) {
talloc_free(tmp_ctx);
return 0;
}
return retval;
}
+static json_t *tr_matches_to_json_array(TR_FSPEC *fspec)
+{
+ json_t *jarray = json_array();
+ json_t *retval = NULL;
+ TR_FSPEC_ITER *iter = tr_fspec_iter_new(NULL);
+ TR_NAME *this_match = NULL;
+
+ if ((jarray == NULL) || (iter == NULL))
+ goto cleanup;
+
+ this_match = tr_fspec_iter_first(iter, fspec);
+ while(this_match) {
+ ARRAY_APPEND_OR_FAIL(jarray, tr_name_to_json_string(this_match));
+ this_match = tr_fspec_iter_next(iter);
+ }
+ /* success */
+ retval = jarray;
+ json_incref(retval);
+
+cleanup:
+ if (jarray)
+ json_decref(jarray);
+ if (iter)
+ tr_fspec_iter_free(iter);
+
+ return retval;
+}
+
static json_t *tr_fspec_to_json(TR_FSPEC *fspec)
{
json_t *fspec_json = NULL;
OBJECT_SET_OR_FAIL(fspec_json, "field",
tr_name_to_json_string(fspec->field));
OBJECT_SET_OR_FAIL(fspec_json, "matches",
- items_to_json_array((void **)fspec->match,
- (ITEM_ENCODER_FUNC *) tr_name_to_json_string,
- TR_MAX_FILTER_SPEC_MATCHES));
+ tr_matches_to_json_array(fspec));
/* succeeded - set the return value and increment the reference count */
retval = fspec_json;
#include <trust_router/trp.h>
#define TR_MAX_FILTER_SPECS 8
-#define TR_MAX_FILTER_SPEC_MATCHES 64
/* Filter actions */
typedef enum tr_filter_action {
typedef struct tr_fspec {
TR_NAME *field;
- TR_NAME *match[TR_MAX_FILTER_SPEC_MATCHES];
+ GPtrArray *match;
} TR_FSPEC;
+typedef struct tr_fspec_iter {
+ TR_FSPEC *fspec;
+ guint ii;
+} TR_FSPEC_ITER;
+
typedef struct tr_fline {
TR_FILTER_ACTION action;
TR_FSPEC *specs[TR_MAX_FILTER_SPECS];
void tr_fspec_free(TR_FSPEC *fspec);
-void tr_fspec_add_match(TR_FSPEC *fspec, TR_NAME *match);
+TR_NAME *tr_fspec_add_match(TR_FSPEC *fspec, TR_NAME *match);
int tr_fspec_matches(TR_FSPEC *fspec, TR_FILTER_TYPE ftype, TR_FILTER_TARGET *target);
TR_FLINE *tr_filter_iter_first(TR_FILTER_ITER *iter, TR_FILTER *filter);
TR_FLINE *tr_filter_iter_next(TR_FILTER_ITER *iter);
+TR_FSPEC_ITER *tr_fspec_iter_new(TALLOC_CTX *mem_ctx);
+void tr_fspec_iter_free(TR_FSPEC_ITER *iter);
+TR_NAME *tr_fspec_iter_first(TR_FSPEC_ITER *iter, TR_FSPEC *fspec);
+TR_NAME *tr_fspec_iter_next(TR_FSPEC_ITER *iter);
+
/*In tr_constraint.c and exported, but not really a public symbol; needed by tr_filter.c and by tr_constraint.c*/
int TR_EXPORT tr_prefix_wildcard_match(const char *str, const char *wc_str);