Module: sip-router Branch: master Commit: bfa4d86a7a18b321a14b65c90d32c5aed32c10d3 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=bfa4d86a...
Author: Elena-Ramona Modroiu ramona@asipto.com Committer: Elena-Ramona Modroiu ramona@asipto.com Date: Sat Dec 8 14:20:43 2012 +0100
pdt(k): added pdt.list command to dump memory structure via rpc
---
modules_k/pdt/pdt.c | 174 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 174 insertions(+), 0 deletions(-)
diff --git a/modules_k/pdt/pdt.c b/modules_k/pdt/pdt.c index 085c7bf..f5f3bdc 100644 --- a/modules_k/pdt/pdt.c +++ b/modules_k/pdt/pdt.c @@ -735,9 +735,183 @@ static void pdt_rpc_reload(rpc_t* rpc, void* ctx) }
+static const char* pdt_rpc_list_doc[2] = { + "List PDT memory records", + 0 +}; + + +int pdt_rpc_print_node(rpc_t* rpc, void* ctx, void *ih, pdt_node_t *pt, char *code, + int len, str *sdomain, str *tdomain, str *tprefix) +{ + int i; + str *cl; + str prefix; + void* vh; + + if(pt==NULL || len>=PDT_MAX_DEPTH) + return 0; + + cl = pdt_get_char_list(); + + for(i=0; i<cl->len; i++) + { + code[len]=cl->s[i]; + if(pt[i].domain.s!=NULL) + { + if((tprefix->s==NULL && tdomain->s==NULL) + || (tprefix->s==NULL && (tdomain->s!=NULL && pt[i].domain.len==tdomain->len + && strncasecmp(pt[i].domain.s, tdomain->s, tdomain->len)==0)) + || (tdomain->s==NULL && (len+1>=tprefix->len + && strncmp(code, tprefix->s, tprefix->len)==0)) + || ((tprefix->s!=NULL && len+1>=tprefix->len + && strncmp(code, tprefix->s, tprefix->len)==0) + && (tdomain->s!=NULL && pt[i].domain.len>=tdomain->len + && strncasecmp(pt[i].domain.s, tdomain->s, tdomain->len)==0))) + { + if(rpc->struct_add(ih, "{", + "ENTRY", &vh)<0) + { + LM_ERR("Internal error creating entry\n"); + return -1; + } + prefix.s = code; + prefix.len = len + 1; + if(rpc->struct_add(vh, "SS", + "DOMAIN", &pt[i].domain, + "PREFIX", &prefix)<0) + { + LM_ERR("Internal error filling entry struct\n"); + return -1; + } + } + } + if(pdt_rpc_print_node(rpc, ctx, ih, pt[i].child, code, len+1, sdomain, + tdomain, tprefix)<0) + goto error; + } + return 0; +error: + return -1; +} + +/* + * RPC command to list pdt memory records + */ +/** + * "pdt.list" parameters: + * sdomain + * prefix + * domain + * + * - '.' (dot) means NULL value and will match anything + * - the comparison operation is 'START WITH' -- if domain is 'a' then + * all domains starting with 'a' are listed + * + * Examples + * pdt_list o 2 . - lists the entries where sdomain is starting with 'o', + * prefix is starting with '2' and domain is anything + * + * pdt_list . 2 open - lists the entries where sdomain is anything, prefix + * starts with '2' and domain starts with 'open' + */ +static void pdt_rpc_list(rpc_t* rpc, void* ctx) +{ + str sdomain = {0}; + str tprefix = {0}; + str tdomain = {0}; + pdt_tree_t *pt; + unsigned int i; + static char code_buf[PDT_MAX_DEPTH+1]; + int len; + str *cl; + pdt_tree_t **ptree; + void* th; + void* ih; + + ptree = pdt_get_ptree(); + + if(ptree==NULL || *ptree==NULL) + { + LM_ERR("empty domain list\n"); + rpc->fault(ctx, 404, "No records"); + return; + } + + len = rpc->scan(ctx, "*S.SS", &sdomain, &tprefix, &tdomain); + if(len<0) + { + rpc->fault(ctx, 500, "Error Reading Parameters"); + return; + } + if(len<1 || sdomain.len==0 || (sdomain.len==1 && sdomain.s[0]=='.')) { + sdomain.len = 0; + sdomain.s = 0; + } + cl = pdt_get_char_list(); + if(len<2 || tprefix.len==0 || (tprefix.len==1 && tprefix.s[0]=='.')) { + tprefix.len = 0; + tprefix.s = 0; + } else if(tprefix.len>0) { + /* validate prefix */ + i = 0; + while(tprefix.s!=NULL && i!=tprefix.len) + { + if(strpos(cl->s, tprefix.s[i]) < 0) + { + LM_ERR("bad prefix [%.*s]\n", tprefix.len, tprefix.s); + rpc->fault(ctx, 400, "Bad Prefix"); + return; + } + i++; + } + } + if(len<3 || tdomain.len==0 || (tdomain.len==1 && tdomain.s[0]=='.')) { + tdomain.len = 0; + tdomain.s = 0; + } + + pt = *ptree; + + if (rpc->add(ctx, "{", &th) < 0) + { + rpc->fault(ctx, 500, "Internal error root reply"); + return; + } + while(pt!=NULL) + { + LM_ERR("---- 1 (%d [%.*s])\n", sdomain.len, sdomain.len, sdomain.s); + if(sdomain.s==NULL || + (sdomain.s!=NULL && pt->sdomain.len>=sdomain.len && + strncmp(pt->sdomain.s, sdomain.s, sdomain.len)==0)) + { + LM_ERR("---- 2\n"); + len = 0; + if(rpc->struct_add(th, "S{", + "SDOMAIN", &pt->sdomain, + "RECORDS", &ih)<0) + { + rpc->fault(ctx, 500, "Internal error creating sdomain structure"); + return; + } + if(pdt_rpc_print_node(rpc, ctx, ih, pt->head, code_buf, len, &pt->sdomain, + &tdomain, &tprefix)<0) + goto error; + } + pt = pt->next; + } + return; +error: + rpc->fault(ctx, 500, "Internal error printing records"); + return; +} + + rpc_export_t pdt_rpc_cmds[] = { {"pdt.reload", pdt_rpc_reload, pdt_rpc_reload_doc, 0}, + {"pdt.list", pdt_rpc_list, + pdt_rpc_list_doc, 0}, {0, 0, 0, 0} };