diff --git a/phoned/config.l b/phoned/config.l index a4f9c31..6820578 100644 --- a/phoned/config.l +++ b/phoned/config.l @@ -26,6 +26,10 @@ filters return FILTERS; action return ACTION; name return NAME; number return PHNUM; +flags return FLAGS; +stopproc yylval.number = CTFLG_STOPPROC; return FLAG; +cname yylval.number = CTFLG_CHECKNAME; return FLAG; +cnumber yylval.number = CTFLG_CHECKNUMB; return FLAG; mail yylval.number = CTACT_RNOT; return ACTN; hangup yylval.number = CTACT_HUP; return ACTN; ignore yylval.number = CTACT_IGN; return ACTN; diff --git a/phoned/config.y b/phoned/config.y index 873108e..11ca766 100644 --- a/phoned/config.y +++ b/phoned/config.y @@ -14,6 +14,7 @@ int lincnt = 1; int yylex(void); char *numrx = 0x0, *namrx = 0x0; int factn = 0x0; +int ctflags = 0x0; extern char* yytext; extern struct conf cf; void yyerror(str) @@ -29,9 +30,9 @@ int yywrap(void) } %} %token NOTIFY OBRACE CBRACE SCOLON QUOTE MODDEV MAIN LLEVEL OR -%token FILTERS ACTION NAME PHNUM FILTER +%token FILTERS ACTION NAME PHNUM FILTER FLAGS /* HANGUP IGNOREIT PLAY RECORD */ -%token LNUML ACTN +%token LNUML ACTN FLAG %token IPADDR PATH REGEX FNAME %% commands: @@ -101,11 +102,12 @@ filtbds: filtbd: FILTER FNAME OBRACE filtersts CBRACE { - add_condition($2, namrx, numrx, factn); + add_condition($2, namrx, numrx, factn, ctflags); free($2); if(namrx != 0x0) free(namrx); if(numrx != 0x0) free(numrx); factn = 0x0; + ctflags = 0x0; } ; filtersts: @@ -118,6 +120,8 @@ filterst: fnumb | faction + | + fflags ; fname: NAME REGEX @@ -131,6 +135,24 @@ fnumb: numrx = $2; } ; +fflags: + FLAGS flgs + ; +flgs: + | + flg flgs + ; +flg: + FLAG OR + { + ctflags |= $1; + } + | + ACTN + { + ctflags |= $1; + } + ; faction: ACTION facts ; diff --git a/phoned/filters.c b/phoned/filters.c index 8406c49..1341c10 100644 --- a/phoned/filters.c +++ b/phoned/filters.c @@ -27,7 +27,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -/* $Amigan: phoned/phoned/filters.c,v 1.7 2005/06/12 18:56:20 dcp1990 Exp $ */ +/* $Amigan: phoned/phoned/filters.c,v 1.8 2005/06/12 22:01:23 dcp1990 Exp $ */ #include #include #include @@ -43,7 +43,8 @@ void free_cond_elms(cond) free(cond->name); free(cond->number); free(cond->filtername); - free(cond->namerx.prex); + if(cond->namerx.prex != NULL) free(cond->namerx.prex); + if(cond->numbrx.prex != NULL) free(cond->numbrx.prex); } void free_condition(h, traverse) cond_t* h; @@ -68,16 +69,17 @@ void free_condition(h, traverse) pthread_mutex_unlock(&condmx); } -cond_t* add_condition(filtname, nameregex, numregex, action) +cond_t* add_condition(filtname, nameregex, numregex, action, flags) char* filtname; char* nameregex; char* numregex; int action; + int flags; { cond_t *c, *nc; nc = malloc(sizeof(cond_t)); memset(nc, 0, sizeof(cond_t)); - pthread_mutex_lock(&condmx); /* ALWAYS do this if dealing with next, last or topcond!! */ + pthread_mutex_lock(&condmx); /* ALWAYS do this if dealing with any part, for it may be freed! */ if(topcond == 0x0) topcond = nc; else { @@ -90,22 +92,120 @@ cond_t* add_condition(filtname, nameregex, numregex, action) nc->name = strdup(nameregex); nc->namerx.prex = pcre_compile(nc->name, 0x0, &nc->namerx.error, &nc->namerx.erroroffset, NULL); + if(nc->namerx.prex == NULL) { + lprintf(error, "NAME PCRE compilation failed at offset %d: %s\n", nc->namerx.erroroffset, nc->namerx.error); + } else { + pcre_fullinfo(nc->namerx.prex, NULL, PCRE_INFO_SIZE, &nc->namerx.pcresize); + } } else { nc->name = NULL; nc->namerx.prex = 0x0; } if(numregex != 0x0) { nc->number = strdup(numregex); + nc->numbrx.pcresize = 0x0; nc->numbrx.prex = pcre_compile(nc->number, 0x0, &nc->numbrx.error, &nc->numbrx.erroroffset, NULL); + if(nc->numbrx.prex == NULL) { + lprintf(error, "NUMBER PCRE compilation failed at offset %d: %s\n", nc->numbrx.erroroffset, nc->numbrx.error); + } else { + pcre_fullinfo(nc->numbrx.prex, NULL, PCRE_INFO_SIZE, &nc->numbrx.pcresize); + } } else { nc->number = NULL; nc->numbrx.prex = 0x0; } nc->action = action; + nc->flags = flags; lprintf(info, "Added filter %s, namerx = %s, numrx = %s, action = %b\n", filtname, nameregex, numregex, action, "\10" SCTACT_IGN "IGNORE" SCTACT_HUP "HANGUP" SCTACT_RNOT "MAIL" SCTACT_ANS "ANSWER" SCTACT_PLAY "PLAY" SCTACT_REC "RECORD\n"); pthread_mutex_unlock(&condmx); /* done */ return nc; } +cond_t* copy_condition(con) + cond_t* con; +{ + cond_t* c; + c = malloc(sizeof(cond_t)); + memset(c, 0, sizeof(cond_t)); + c->filtername = strdup(con->filtername); + if(con->name != NULL) + c->name = strdup(con->name); + /* XXX: is this safe? */ + if(con->namerx.prex != NULL) { + c->namerx.pcresize = con->namerx.pcresize; + c->namerx.prex = malloc(c->namerx.pcresize); + memmove(c->namerx.prex, con->namerx.prex, c->namerx.pcresize); + } + if(con->number != NULL) + c->number = strdup(con->number); + if(con->numbrx.prex != NULL) { + c->numbrx.pcresize = con->numbrx.pcresize; + c->numbrx.prex = malloc(c->numbrx.pcresize); + memmove(c->numbrx.prex, con->numbrx.prex, c->numbrx.pcresize); + } + c->action = con->action; + c->flags = con->flags; + /* next and last won't be copied; this is for a *single* node */ + return c; +} +void check_condition(cid) + cid_t* cid; +{ + cond_t *ourcond = 0x0, *c, *d, *e; + int rcna = -1, rcnu = -1; + int ovec[30]; + int result = 0; + pthread_mutex_lock(&condmx); + c = topcond; + while(c != NULL) { + if(c->namerx.prex != NULL) + rcna = pcre_exec(c->namerx.prex, NULL, cid->name, strlen(cid->name), 0, 0, ovec, 30); + if(c->numbrx.prex != NULL) + rcnu = pcre_exec(c->numbrx.prex, NULL, cid->number, strlen(cid->number), 0, 0, ovec, 30); + if(rcna > -1) result |= CTFLG_CHECKNAME; + if(rcnu > -1) result |= CTFLG_CHECKNUMB; + result = result >> 1; + if(result >= (c->flags >> 1)) { /* aren't we clever? */ + if(ourcond == 0x0) { + ourcond = copy_condition(c); /* we copy this so if something blocks later on, threads can still continue */ + } else { + e = copy_condition(c); + for(d = ourcond; d->next != 0x0; d = d->next); + e->last = d; + d->next = e; + } + } + if(c->flags & CTFLG_STOPPROC) break; + result = 0x0; + rcna = -1; + rcnu = -1; + c = c->next; + } + pthread_mutex_unlock(&condmx); /* we're done with that stuff now since we have our own copies */ + c = ourcond; + while(c != NULL) { + if(c->action & CTACT_IGN) { + c = c->next; + continue; + } + if(c->action & CTACT_HUP) { + lprintf(error, "Hangup not yet implemented! Check back later. (cond %s)\n", c->filtername); + } + if(c->action & CTACT_RNOT) { + lprintf(error, "Mail not yet implemented! Check back later. (cond %s)\n", c->filtername); + } + if(c->action & CTACT_ANS) { + lprintf(error, "Answer not yet implemented! Check back later. (cond %s)\n", c->filtername); + } + if(c->action & CTACT_PLAY) { + lprintf(error, "Play not yet implemented! Check back later. (cond %s)\n", c->filtername); + } + if(c->action & CTACT_REC) { + lprintf(error, "Record not yet implemented! Check back later. (cond %s)\n", c->filtername); + } + c = c->next; + } + free_condition(ourcond, 0x1); +} diff --git a/phoned/phoned.conf b/phoned/phoned.conf index 2804f01..1b63aac 100644 --- a/phoned/phoned.conf +++ b/phoned/phoned.conf @@ -7,6 +7,7 @@ filters { name /PONTE/; number /^782.*/; action ignore|hangup; + flags cname|cnumber; }; }; notify {