[sr-dev] git:master: pdt(k): added pdt.list command to dump memory structure via rpc

Elena-Ramona Modroiu ramona at rosdev.ro
Sat Dec 8 18:23:23 CET 2012


Module: sip-router
Branch: master
Commit: bfa4d86a7a18b321a14b65c90d32c5aed32c10d3
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=bfa4d86a7a18b321a14b65c90d32c5aed32c10d3

Author: Elena-Ramona Modroiu <ramona at asipto.com>
Committer: Elena-Ramona Modroiu <ramona at 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}
 };
 




More information about the sr-dev mailing list