/* * Yet another daemon library especially designed to be used * with libsxmp based daemons. * * (c) Alexander Vdolainen 2016 * * libsxmp is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * libsxmp is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see ."; * */ #define DMUX_USE 1 #include yd_filter_t *yd_filter_create(domx_t *refobj) { yd_filter_t *f = malloc(sizeof(yd_filter_t)); if(f) { f->domx = refobj; list_init_head(&f->filter); } return f; } void yd_filter_destroy(yd_filter_t *f) { list_head_t *lhead; list_node_t *iter, *siter, *liter, *lsiter; yd_filter_item_t *filter_item; yd_inlist_item_t *inl_item; dataobject_t *obj; uint64_t len; uint8_t type; if(!f) return; else { lhead = &f->filter; obj = f->domx->dox; } list_for_each_safe(lhead, iter, siter) { filter_item = container_of(iter, yd_filter_item_t, node); type = dotr_item_type(obj, filter_item->name, &len); if(type && len) { switch(filter_item->ftype) { case YDEQUAL: case YDNOTEQUAL: if(type == CSTR || type == TBLOB) free(filter_item->cstr); break; case YDINLIST: /* we must destroy the list */ list_for_each_safe(filter_item->inlist, liter, lsiter) { inl_item = container_of(liter, yd_inlist_item_t, node); if(type == CSTR || type == TBLOB) free(inl_item->dta); list_del(&inl_item->node); free(inl_item); } free(filter_item->inlist); break; default: break; /* nothing to do */ } } /* free struct itself */ list_del(&filter_item->node); free(filter_item); } free(f); return; } static yd_filter_item_t *__alloc_init_fitem(filt_t ftype, char *name) { yd_filter_item_t *fitem = NULL; if(name && (fitem = malloc(sizeof(yd_filter_item_t)))) { memset(fitem, 0, sizeof(yd_filter_item_t)); fitem->name = name; fitem->ftype = ftype; list_init_node(&fitem->node); } return fitem; } int yd_filter_add_sf(yd_filter_t *f, const char *name, filt_t ftype, uint64_t vf, uint64_t vc) { yd_filter_item_t *fitem; dataobject_t *obj; uint64_t len; uint8_t type; if(!f || !name) return EINVAL; /* lookup for existing entry and check it */ obj = f->domx->dox; type = dotr_item_type(obj, name, &len); if(!type && !len) return EINVAL; /* check validity */ if((type < CSTR) && (len > tltable[type].len)) return EINVAL; /* we cannot filter by array here */ if(type > S64) return EINVAL; /* we're adding a simple filter rule */ if(ftype == YDINLIST) return EINVAL; /* we're not working with that in this function */ fitem = __alloc_init_fitem(ftype, dotr_item_nameptr(obj, name)); if(!fitem) return ENOMEM; fitem->vf = vf; if(ftype == YDINLIST) fitem->vc = vc; /* add this entry */ list_add2tail(&f->filter, &fitem->node); return 0; } int yd_filter_add_str(yd_filter_t *f, const char *name, const char *value, int eq) { yd_filter_item_t *fitem; dataobject_t *obj; filt_t ftype; uint64_t len; uint8_t type; if(!f || !name) return EINVAL; /* lookup for existing entry and check it */ obj = f->domx->dox; type = dotr_item_type(obj, name, &len); if(!type && !len) return EINVAL; if(type != CSTR) return EINVAL; /* cannot do it, invalid */ if(!eq) ftype = YDNOTEQUAL; else ftype = YDEQUAL; fitem = __alloc_init_fitem(ftype, dotr_item_nameptr(obj, name)); if(!fitem) return ENOMEM; if(!(fitem->cstr = strndup(value, len - sizeof(char)))) { free(fitem); return ENOMEM; } /* add this entry */ list_add2tail(&f->filter, &fitem->node); return 0; } int yd_filter_add_inlist(yd_filter_t *f, const char *name, int length, void **array) { yd_filter_item_t *fitem; yd_inlist_item_t *list_item; dataobject_t *obj; list_node_t *iter, *siter; uint64_t len; int i; uint8_t type; if(!f || !name) return EINVAL; if(!length || !array) return EINVAL; /* lookup for existing entry and check it */ obj = f->domx->dox; type = dotr_item_type(obj, name, &len); if(!type && !len) return EINVAL; fitem = __alloc_init_fitem(YDINLIST, dotr_item_nameptr(obj, name)); if(!fitem) return ENOMEM; if(!(fitem->inlist = malloc(sizeof(list_head_t)))) { __enomem: free(fitem); return ENOMEM; } /* fill the list */ for(i = 0; i < length; i++) { if(!(list_item = malloc(sizeof(yd_inlist_item_t)))) { __deep_enomem: list_for_each_safe(fitem->inlist, iter, siter) { list_item = container_of(iter, yd_inlist_item_t, node); if(type == CSTR || type == TBLOB) free(list_item->dta); list_del(&list_item->node); free(list_item); } /* free the list */ free(fitem->inlist); goto __enomem; } if(type < CSTR) list_item->val = *(uint64_t *)array[i]; else if(!(list_item->dta = strndup((const char *)array[i], len - sizeof(char)))) goto __deep_enomem; list_init_node(&list_item->node); list_add2tail(fitem->inlist, &list_item->node); } /* add this entry */ list_add2tail(&f->filter, &fitem->node); return 0; }