celix_status_t filter_match(filter_pt filter, properties_pt properties, bool *result) { switch (filter->operand) { case AND: { array_list_pt filters = (array_list_pt) filter->value; unsigned int i; for (i = 0; i < arrayList_size(filters); i++) { filter_pt sfilter = (filter_pt) arrayList_get(filters, i); bool mresult; filter_match(sfilter, properties, &mresult); if (!mresult) { *result = 0; return CELIX_SUCCESS; } } *result = 1; return CELIX_SUCCESS; } case OR: { array_list_pt filters = (array_list_pt) filter->value; unsigned int i; for (i = 0; i < arrayList_size(filters); i++) { filter_pt sfilter = (filter_pt) arrayList_get(filters, i); bool mresult; filter_match(sfilter, properties, &mresult); if (mresult) { *result = 1; return CELIX_SUCCESS; } } *result = 0; return CELIX_SUCCESS; } case NOT: { filter_pt sfilter = (filter_pt) filter->value; bool mresult; filter_match(sfilter, properties, &mresult); *result = !mresult; return CELIX_SUCCESS; } case SUBSTRING : case EQUAL : case GREATER : case GREATEREQUAL : case LESS : case LESSEQUAL : case APPROX : { char * value = (properties == NULL) ? NULL: (char*)properties_get(properties, filter->attribute); return filter_compare(filter->operand, value, filter->value, result); } case PRESENT: { char * value = (properties == NULL) ? NULL: (char*)properties_get(properties, filter->attribute); *result = value != NULL; return CELIX_SUCCESS; } } *result = 0; return CELIX_SUCCESS; }
celix_status_t serviceRegistry_getServiceReferences(service_registry_pt registry, bundle_pt owner, const char *serviceName, filter_pt filter, array_list_pt *references) { celix_status_t status = CELIX_SUCCESS; hash_map_values_pt registrations; hash_map_iterator_pt iterator; arrayList_create(references); celixThreadMutex_lock(®istry->mutex); registrations = hashMapValues_create(registry->serviceRegistrations); iterator = hashMapValues_iterator(registrations); while (hashMapIterator_hasNext(iterator)) { array_list_pt regs = (array_list_pt) hashMapIterator_nextValue(iterator); unsigned int regIdx; for (regIdx = 0; (regs != NULL) && regIdx < arrayList_size(regs); regIdx++) { service_registration_pt registration = (service_registration_pt) arrayList_get(regs, regIdx); properties_pt props = NULL; status = serviceRegistration_getProperties(registration, &props); if (status == CELIX_SUCCESS) { bool matched = false; bool matchResult = false; if (filter != NULL) { filter_match(filter, props, &matchResult); } if ((serviceName == NULL) && ((filter == NULL) || matchResult)) { matched = true; } else if (serviceName != NULL) { char *className = NULL; bool matchResult = false; serviceRegistration_getServiceName(registration, &className); if (filter != NULL) { filter_match(filter, props, &matchResult); } if ((strcmp(className, serviceName) == 0) && ((filter == NULL) || matchResult)) { matched = true; } } if (matched) { if (serviceRegistration_isValid(registration)) { service_reference_pt reference = NULL; serviceRegistry_createServiceReference(registry, owner, registration, &reference); arrayList_add(*references, reference); } } } } } hashMapIterator_destroy(iterator); hashMapValues_destroy(registrations); celixThreadMutex_unlock(®istry->mutex); framework_logIfError(logger, status, NULL, "Cannot get service references"); return status; }
TEST(filter, match_false){ char * filter_str = my_strdup("(&(test_attr1=attr1)(&(test_attr2=attr2)(test_attr3=attr3)))"); filter_pt filter = filter_create(filter_str); properties_pt props = properties_create(); char * key = my_strdup("test_attr1"); char * val = my_strdup("attr1"); char * key2 = my_strdup("test_attr2"); char * val2 = my_strdup("attr2"); properties_set(props, key, val); properties_set(props, key2, val2); bool result = true; filter_match(filter, props, &result); CHECK_FALSE(result); //cleanup properties_destroy(props); filter_destroy(filter); free(filter_str); free(key); free(key2); free(val); free(val2); mock().checkExpectations(); }
short filter_evaluate(struct intercept_tlq *tls, struct filterq *fls, struct intercept_pid *icpid) { struct filter *filter, *last = NULL; short action; TAILQ_FOREACH(filter, fls, next) { action = filter->match_action; if (filter_predicate(icpid, &filter->match_predicate) && filter_match(icpid, tls, filter->logicroot)) { /* Profile feedback optimization */ filter->match_count++; if (last != NULL && last->match_action == action && last->match_flags == filter->match_flags && filter->match_count > last->match_count) { TAILQ_REMOVE(fls, last, next); TAILQ_INSERT_AFTER(fls, filter, last, next); } if (action == ICPOLICY_NEVER) action = filter->match_error; icpid->uflags = filter->match_flags; /* Policy requests privilege elevation */ if (filter->elevate.e_flags) icpid->elevate = &filter->elevate; return (action); } /* Keep track of last processed filtered in a group */ last = filter; }
/** * find a client */ p_client next_client_by_message(p_client client, char *message) { static int oldclient = 0; // return to start if client is null if (client == 0) { oldclient =0; } p_client check = get_client_idx(oldclient); // if some unknown client is given, find it. if (client != check) { oldclient = find_client_idx(client); } // check next client oldclient++; if ( oldclient < count_clients()) { // if it matches the message, return it check = get_client_idx(oldclient); if (filter_match(check, message)) { return check; } // else check next client return next_client_by_message(check, message); } return 0; }
celix_status_t wiringTopologyManager_wiringEndpointListenerAdded(void* handle, service_reference_pt reference, void* service) { celix_status_t status = CELIX_SUCCESS; wiring_topology_manager_pt manager = handle; char *scope = NULL; char* wtm = NULL; serviceReference_getProperty(reference, (char *) INAETICS_WIRING_ENDPOINT_LISTENER_SCOPE, &scope); serviceReference_getProperty(reference, "WTM", &wtm); if (wtm != NULL && strcmp(wtm, "true") == 0) { printf("WTM: Ignoring own ENDPOINT_LISTENER\n"); } else { status = celixThreadMutex_lock(&manager->listenerListLock); if (status == CELIX_SUCCESS) { hashMap_put(manager->listenerList, reference, NULL); celixThreadMutex_unlock(&manager->listenerListLock); } filter_pt filter = filter_create(scope); status = celixThreadMutex_lock(&manager->exportedWiringEndpointsLock); if (status == CELIX_SUCCESS) { hash_map_iterator_pt propIter = hashMapIterator_create(manager->exportedWiringEndpoints); while (hashMapIterator_hasNext(propIter)) { hash_map_pt wiringAdminList = hashMapIterator_nextValue(propIter); hash_map_iterator_pt waIter = hashMapIterator_create(wiringAdminList); while (hashMapIterator_hasNext(waIter)) { wiring_endpoint_description_pt wEndpoint = hashMapIterator_nextValue(waIter); bool matchResult = false; filter_match(filter, wEndpoint->properties, &matchResult); if (matchResult) { wiring_endpoint_listener_pt listener = (wiring_endpoint_listener_pt) service; status = listener->wiringEndpointAdded(listener->handle, wEndpoint, scope); } } hashMapIterator_destroy(waIter); } hashMapIterator_destroy(propIter); celixThreadMutex_unlock(&manager->exportedWiringEndpointsLock); } filter_destroy(filter); } return status; }
static int do_filter(struct filter *f, const unsigned char *id, const unsigned char *prefix, unsigned short plen, const unsigned char *neigh, unsigned int ifindex, int proto) { while(f) { if(filter_match(f, id, prefix, plen, neigh, ifindex, proto)) return f->result; f = f->next; } return -1; }
static const filter_element_t *filter_match(const filter_element_t *const fe, const uint32_t channel, const char *message, const char *signal) { if(fe != NULL) { if(fe->channel_wildcard || (fe->channel == channel)) if(0 == fnmatch(fe->message, message,0)) if(0 == fnmatch(fe->signal, signal,0)) return fe; return filter_match(fe->next, channel, message, signal); } else { return NULL; } }
static void process_items(rss_t rss, struct target *t) { int i; struct rss_item item; while(rss_walk_next(rss, &item)) { struct http_file *file = NULL; if (proc_cache_lookup(item.link)) continue; for(i=0; i < t->nr; i++) { struct filter *filter = &t->filter[i]; if (dlhist_lookup(item.title, filter->dest) || !filter_match(filter->pattern, item.title)) continue; /* fetch the file if we haven't already. */ if (file == NULL) { file = http_fetch_file(item.link); if (file == NULL) { error("download failed"); continue; } } /* At this point, mark the item as downloaded. Even if we encounter an error while saving to disk. */ dlhist_mark(item.title, filter->dest); if (write_http_file(file, filter->dest) < 0) continue; printf("Downloaded: %s (%s) to %s\n", item.title, item.link, filter->dest); } proc_cache_update(item.link); http_free_file(file); } }
char * filter_apply(const filter_t *filter, const uint32_t channel, const char *message, const char *signal) { char *mat_name = NULL; const filter_element_t *el; if(filter) { el = filter_match(filter->first, channel, message, signal); if(el != NULL) { /* element found? */ if(el->operation == '+') { /* accept? */ if(el->newname) { /* new name given? */ mat_name = strdup(el->newname); } else { /* no new name given */ mat_name = standard_name(message, signal); } } } } else { /* no filter */ mat_name = standard_name(message, signal); } return mat_name; }
int packet_filter_match(struct filter *f, struct proto_process_stack *stack) { return filter_match(f, stack); }
int stream_pfring_read(struct stream_pfring* st, cap_head** header, const struct filter* filter, struct timeval* timeout){ /* I heard ext is a pretty cool guy, uses goto and doesn't afraid of anything */ retry: /* empty buffer */ if ( !st->read_ptr ){ if ( !read_packet(st, BLOCK) ){ return EAGAIN; } char* frame = st->frame[st->base.readPos]; struct sendhead* sh = (struct sendhead*)(frame + sizeof(struct ethhdr)); st->read_ptr = frame + sizeof(struct ethhdr) + sizeof(struct sendhead); st->num_packets = ntohl(sh->nopkts); } /* always read if there is space available */ if ( st->base.writePos != st->base.readPos ){ read_packet(st, NONBLOCK); } /* no packets available */ if ( st->num_packets == 0 ){ return EAGAIN; } /* fetch next matching packet */ struct cap_header* cp = (struct cap_header*)(st->read_ptr); const size_t packet_size = sizeof(struct cap_header) + cp->caplen; st->num_packets--; st->read_ptr += packet_size; if ( st->num_packets == 0 ){ st->base.readPos = (st->base.readPos+1) % st->num_frames; if ( st->base.readPos == st->base.writePos ){ st->read_ptr = NULL; } else { char* frame = st->frame[st->base.readPos]; struct sendhead* sh = (struct sendhead*)(frame + sizeof(struct ethhdr)); st->read_ptr = frame + sizeof(struct ethhdr) + sizeof(struct sendhead); st->num_packets = ntohl(sh->nopkts); } } if ( cp->caplen == 0 ){ return ERROR_CAPFILE_INVALID; } assert(packet_size > 0); /* set next packet and advance the read pointer */ *header = cp; st->base.stat.read++; st->base.stat.buffer_usage = 0; if ( filter && !filter_match(filter, cp->payload, cp) ){ goto retry; } st->base.stat.matched++; return 0; }
TEST(filter, match_operators){ char * filter_str; filter_pt filter; properties_pt props = properties_create(); char * key = my_strdup("test_attr1"); char * val = my_strdup("attr1"); char * key2 = my_strdup("test_attr2"); char * val2 = my_strdup("attr2"); properties_set(props, key, val); properties_set(props, key2, val2); //test EQUALS filter_str = my_strdup("(test_attr1=attr1)"); filter = filter_create(filter_str); bool result = false; filter_match(filter, props, &result); CHECK(result); //test EQUALS false filter_destroy(filter); free(filter_str); filter_str = my_strdup("(test_attr1=falseString)"); filter = filter_create(filter_str); result = true; filter_match(filter, props, &result); CHECK_FALSE(result); //test APPROX TODO: update this test once APPROX is implemented filter_destroy(filter); free(filter_str); filter_str = my_strdup("(test_attr1~=attr1)"); filter = filter_create(filter_str); result = false; filter_match(filter, props, &result); CHECK(result); //test APROX false TODO: update this test once APPROX is implemented filter_destroy(filter); free(filter_str); filter_str = my_strdup("(test_attr1~=ATTR1)"); filter = filter_create(filter_str); result = true; filter_match(filter, props, &result); CHECK_FALSE(result); //test PRESENT filter_destroy(filter); free(filter_str); filter_str = my_strdup("(test_attr1=*)"); filter = filter_create(filter_str); result = false; filter_match(filter, props, &result); CHECK(result); //test PRESENT false filter_destroy(filter); free(filter_str); filter_str = my_strdup("(test_attr3=*)"); filter = filter_create(filter_str); result = true; filter_match(filter, props, &result); CHECK_FALSE(result); //test LESSEQUAL less filter_destroy(filter); free(filter_str); filter_str = my_strdup("(test_attr1<=attr5)"); filter = filter_create(filter_str); result = false; filter_match(filter, props, &result); CHECK(result); //test LESSEQUAL equals filter_destroy(filter); free(filter_str); filter_str = my_strdup("(test_attr2<=attr2)"); filter = filter_create(filter_str); result = false; filter_match(filter, props, &result); CHECK(result); //test LESSEQUAL false filter_destroy(filter); free(filter_str); filter_str = my_strdup("(test_attr2<=attr1)"); filter = filter_create(filter_str); result = true; filter_match(filter, props, &result); CHECK_FALSE(result); //test GREATEREQUAL greater filter_destroy(filter); free(filter_str); filter_str = my_strdup("(test_attr2>=attr1)"); filter = filter_create(filter_str); result = false; filter_match(filter, props, &result); CHECK(result); //test GREATEREQUAL equals filter_destroy(filter); free(filter_str); filter_str = my_strdup("(test_attr2>=attr2)"); filter = filter_create(filter_str); result = false; filter_match(filter, props, &result); CHECK(result); //test GREATEREQUAL false filter_destroy(filter); free(filter_str); filter_str = my_strdup("(test_attr1>=attr5)"); filter = filter_create(filter_str); result = true; filter_match(filter, props, &result); CHECK_FALSE(result); //test LESS less filter_destroy(filter); free(filter_str); filter_str = my_strdup("(test_attr1<attr5)"); filter = filter_create(filter_str); result = false; filter_match(filter, props, &result); CHECK(result); //test LESS equals filter_destroy(filter); free(filter_str); filter_str = my_strdup("(test_attr2<attr2)"); filter = filter_create(filter_str); result = true; filter_match(filter, props, &result); CHECK_FALSE(result); //test LESS false filter_destroy(filter); free(filter_str); filter_str = my_strdup("(test_attr2<attr1)"); filter = filter_create(filter_str); result = true; filter_match(filter, props, &result); CHECK_FALSE(result); //test GREATER greater filter_destroy(filter); free(filter_str); filter_str = my_strdup("(test_attr2>attr1)"); filter = filter_create(filter_str); result = false; filter_match(filter, props, &result); CHECK(result); //test GREATER equals filter_destroy(filter); free(filter_str); filter_str = my_strdup("(test_attr2>attr2)"); filter = filter_create(filter_str); result = true; filter_match(filter, props, &result); CHECK_FALSE(result); //test GREATER false filter_destroy(filter); free(filter_str); filter_str = my_strdup("(test_attr1>attr5)"); filter = filter_create(filter_str); result = true; filter_match(filter, props, &result); CHECK_FALSE(result); //test SUBSTRING equals filter_destroy(filter); free(filter_str); filter_str = my_strdup("(test_attr1=attr*)"); filter = filter_create(filter_str); result = true; filter_match(filter, props, &result); CHECK(result); //test SUBSTRING false filter_destroy(filter); free(filter_str); filter_str = my_strdup("(test_attr1=attr*charsNotPresent)"); filter = filter_create(filter_str); result = true; filter_match(filter, props, &result); CHECK_FALSE(result); //cleanup properties_destroy(props); filter_destroy(filter); free(filter_str); free(key); free(key2); free(val); free(val2); mock().checkExpectations(); }
/* dispatch one inotify event the cookies are used to correctly handle renames */ static void inotify_dispatch(struct inotify_private *in, struct inotify_event *e, uint32_t prev_cookie, struct inotify_event *e2) { struct inotify_watch_context *w, *next; struct notify_event ne; DEBUG(10, ("inotify_dispatch called with mask=%x, name=[%s]\n", e->mask, e->len ? e->name : "")); /* ignore extraneous events, such as unmount and IN_IGNORED events */ if ((e->mask & (IN_ATTRIB|IN_MODIFY|IN_CREATE|IN_DELETE| IN_MOVED_FROM|IN_MOVED_TO)) == 0) { return; } /* map the inotify mask to a action. This gets complicated for renames */ if (e->mask & IN_CREATE) { ne.action = NOTIFY_ACTION_ADDED; } else if (e->mask & IN_DELETE) { ne.action = NOTIFY_ACTION_REMOVED; } else if (e->mask & IN_MOVED_FROM) { if (e2 != NULL && e2->cookie == e->cookie) { ne.action = NOTIFY_ACTION_OLD_NAME; } else { ne.action = NOTIFY_ACTION_REMOVED; } } else if (e->mask & IN_MOVED_TO) { if (e->cookie == prev_cookie) { ne.action = NOTIFY_ACTION_NEW_NAME; } else { ne.action = NOTIFY_ACTION_ADDED; } } else { ne.action = NOTIFY_ACTION_MODIFIED; } ne.path = e->name; DEBUG(10, ("inotify_dispatch: ne.action = %d, ne.path = %s\n", ne.action, ne.path)); /* find any watches that have this watch descriptor */ for (w=in->watches; w; w=next) { next = w->next; if (w->wd == e->wd && filter_match(w, e)) { w->callback(in->ctx, w->private_data, &ne); } } /* SMB expects a file rename to generate three events, two for the rename and the other for a modify of the destination. Strange! */ if (ne.action != NOTIFY_ACTION_NEW_NAME || (e->mask & IN_ISDIR) != 0) { return; } ne.action = NOTIFY_ACTION_MODIFIED; e->mask = IN_ATTRIB; for (w=in->watches; w; w=next) { next = w->next; if (w->wd == e->wd && filter_match(w, e) && !(w->filter & FILE_NOTIFY_CHANGE_CREATION)) { w->callback(in->ctx, w->private_data, &ne); } } }
static int filter_match(struct intercept_pid *icpid, struct intercept_tlq *tls, struct logic *logic) { struct intercept_translate *tl; int off = 0, res; switch (logic->op) { case LOGIC_NOT: return (!filter_match(icpid, tls, logic->left)); case LOGIC_OR: if (filter_match(icpid, tls, logic->left)) return (1); return (filter_match(icpid, tls, logic->right)); case LOGIC_AND: if (!filter_match(icpid, tls, logic->left)) return (0); return (filter_match(icpid, tls, logic->right)); default: break; } /* Now we just have a logic single */ if (logic->type == NULL) goto match; if (tls == NULL) errx(1, "filter_match has no translators"); TAILQ_FOREACH(tl, tls, next) { if (!tl->trans_valid) continue; if (strcasecmp(tl->name, logic->type)) continue; if (logic->typeoff == -1 || logic->typeoff == off) break; off++; } if (tl == NULL) return (0); match: /* We need to do dynamic expansion on the data */ if (logic->filterdata && (logic->flags & LOGIC_NEEDEXPAND)) { char *old = logic->filterdata; size_t oldlen = logic->filterlen; logic->filterdata = filter_dynamicexpand(icpid, old); logic->filterlen = strlen(logic->filterdata) + 1; res = logic->filter_match(tl, logic); logic->filterdata = old; logic->filterlen = oldlen; } else res = logic->filter_match(tl, logic); return (res); }
int main(int argc, char **argv){ /* extract program name from path. e.g. /path/to/MArCd -> MArCd */ const char* separator = strrchr(argv[0], '/'); if ( separator ){ program_name = separator + 1; } else { program_name = argv[0]; } struct filter filter; if ( filter_from_argv(&argc, argv, &filter) != 0 ){ return 0; /* error already shown */ } int op, option_index = -1; while ( (op = getopt_long(argc, argv, shortopts, longopts, &option_index)) != -1 ){ switch (op){ case 0: /* long opt */ case '?': /* unknown opt */ break; case '1': case '2': case '3': case '4': { const unsigned int mask = (7<<FORMAT_LAYER_BIT); flags &= ~mask; /* reset all layer bits */ flags |= (op-'0')<<FORMAT_LAYER_BIT; break; } case 'd': /* --calender */ flags |= FORMAT_DATE_STR | FORMAT_DATE_UTC; break; case 'D': /* --localtime */ flags |= FORMAT_DATE_STR | FORMAT_DATE_LOCALTIME; break; case 'a': /* --absolute */ flags &= ~FORMAT_REL_TIMESTAMP; break; case 'r': /* --relative */ flags |= FORMAT_REL_TIMESTAMP; break; case 'H': /* --headers */ flags |= FORMAT_HEADER; break; case 'p': /* --packets */ max_packets = atoi(optarg); break; case 'c': /* --packets */ max_matched_packets = atoi(optarg); break; case 't': /* --timeout */ { int tmp = atoi(optarg); timeout.tv_sec = tmp / 1000; timeout.tv_usec = tmp % 1000 * 1000; } break; case 'x': /* --hexdump */ flags |= FORMAT_HEXDUMP; break; case 'i': /* --iface */ iface = optarg; break; case ARGUMENT_VERSION: /* --version */ show_version(); return 0; case 'h': /* --help */ show_usage(); return 0; default: fprintf (stderr, "%s: argument '-%c' declared but not handled\n", argv[0], op); } } int ret; /* Open stream(s) */ struct stream* stream; if ( (ret=stream_from_getopt(&stream, argv, optind, argc, iface, "-", program_name, 0)) != 0 ) { return ret; /* Error already shown */ } const stream_stat_t* stat = stream_get_stat(stream); stream_print_info(stream, stderr); /* handle C-c */ signal(SIGINT, handle_sigint); /* setup formatter */ struct format format; format_setup(&format, flags); uint64_t matched = 0; while ( keep_running ) { /* A short timeout is used to allow the application to "breathe", i.e * terminate if SIGINT was received. */ struct timeval tv = timeout; /* Read the next packet */ cap_head* cp; ret = stream_read(stream, &cp, NULL, &tv); if ( ret == EAGAIN ){ continue; /* timeout */ } else if ( ret != 0 ){ break; /* shutdown or error */ } /* identify connection even if filter doesn't match so id will be * deterministic when changing the filter */ connection_id(cp); if ( filter_match(&filter, cp->payload, cp) ){ format_pkg(stdout, &format, cp); matched++; } else { format_ignore(stdout, &format, cp); } if ( max_packets > 0 && stat->matched >= max_packets) { /* Read enough pkts lets break. */ break; } if ( max_matched_packets > 0 && matched >= max_matched_packets) { /* Read enough pkts lets break. */ break; } } /* if ret == -1 the stream was closed properly (e.g EOF or TCP shutdown) * In addition EINTR should not give any errors because it is implied when the * user presses C-c */ if ( ret > 0 && ret != EINTR ){ fprintf(stderr, "stream_read() returned 0x%08X: %s\n", ret, caputils_error_string(ret)); } /* Write stats */ fprintf(stderr, "%"PRIu64" packets read.\n", stat->read); fprintf(stderr, "%"PRIu64" packets matched filter.\n", matched); /* Release resources */ stream_close(stream); filter_close(&filter); return 0; }