You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
220 lines
5.6 KiB
C
220 lines
5.6 KiB
C
/*
|
|
* Yet another daemon library especially designed to be used
|
|
* with libsxmp based daemons.
|
|
*
|
|
* (c) Alexander Vdolainen 2016 <avdolainen@zoho.com>
|
|
*
|
|
* 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 <http://www.gnu.org/licenses/>.";
|
|
*
|
|
*/
|
|
|
|
#define DMUX_USE 1
|
|
#include <ydaemon/dataobject.h>
|
|
|
|
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;
|
|
}
|
|
|