Daniel-Constantin Mierla wrote:
Hello,
On 2/9/10 4:00 PM, marius zbihlei wrote:
Hello (replying on myself)
Sorry for the broken output
Feb 9 16:46:03 marius ../../ser[32584]: ERROR: *** cfgtrace:
c=[(null)] l=0 a=13 descr=seturi("sip:49721123456785@127.0.0.1:10000");
Feb 9 16:46:03 marius ../../ser[32584]: ERROR:
*** cfgtrace: c=[30.cfg] l=33 a=17 descr=if (type<22>) {} else {};
Feb 9 16:46:03 marius ../../ser[32584]: ERROR: *** cfgtrace:
c=[30.cfg] l=30 a=25 descr= external_module_call(f_ptr<0xb7dfc13c>, 0);
I will also check to see why the first line has no config file or
line info...
it is in my roadmap to make it more verbose, but if you can do it is
better :-) (so I can say was in my roadmap).
The name of the action is in the structure if it is a module function,
for the core functions and statements (if, while, ...) I was thinking
on having a mapping table (type, name).
Another idea was to open the cfg, read the respective line and print
it next. But would be quite i/o intesive...
When you have the patch ready, send it over. I will look over it and
if ok I will tell you to commit.
Thanks,
Daniel
Hello Daniel,
I have attacked a patch that enables print_action like printing of
module functions, core function and statements . It is usefull if the
action line is no longer that 512 characters(it truncates at 512 ..
still to test)
The module export is printed like this (call to t_relay)
cfgtrace: c=[/home/marius/dev/sip-router/test/unit/30.cfg] l=30 a=25
descr=external_module_call(t_relay)(f_ptr<0xb7ee815c>, 0);
I also liked the file read solution but strangely for some action the
file is NULL (*** cfgtrace: c=[(null)] l=0 a=13
descr=seturi("sip:49721123456787@127.0.0.1:8000"); )
BTW it is normal for a line like xlog(...) to appear as an action:
cfgtrace: c=[/home/marius/dev/sip-router/test/unit/30.cfg] l=30 a=17
descr=if (type<22>external_module_call(xlog)(f_ptr<0xb8062898>, 2,
type<10>); drop(1, 1); } else {};
?
The patch is a little on the long side, and a bit intrusive to my liking
, it you have other suggestion please let me now.
Cheers
Marius
diff --git a/modules/debugger/debugger_api.c b/modules/debugger/debugger_api.c
index 12dc872..eaf19a6 100644
--- a/modules/debugger/debugger_api.c
+++ b/modules/debugger/debugger_api.c
@@ -140,6 +140,7 @@ typedef struct _dbg_bp
*/
static dbg_bp_t *_dbg_bp_list = NULL;
+
/**
* callback executed for each cfg action
*/
@@ -151,9 +152,9 @@ int dbg_cfg_trace(void *data)
int olen;
str pvn;
pv_spec_t pvs;
- pv_value_t val;
+ pv_value_t val;
void **srevp;
-
+ char *p;
srevp = (void**)data;
a = (struct action *)srevp[0];
@@ -166,11 +167,20 @@ int dbg_cfg_trace(void *data)
{
if(is_printable(_dbg_cfgtrace_level))
{
- LOG_(_dbg_cfgtrace_facility, _dbg_cfgtrace_level,
+ p = print_action_str(a, 1);
+ if(p){
+ LOG_(_dbg_cfgtrace_facility, _dbg_cfgtrace_level,
_dbg_cfgtrace_prefix,
- " c=[%s] l=%d a=%d\n",
- a->cfile, a->cline, a->type
- );
+ " c=[%s] l=%d a=%d descr=%s\n",
+ a->cfile, a->cline, a->type, p);
+ pkg_free(p);
+ }
+ else{
+ LOG_(_dbg_cfgtrace_facility, _dbg_cfgtrace_level,
+ _dbg_cfgtrace_prefix,
+ " c=[%s] l=%d a=%d \n",
+ a->cfile, a->cline, a->type );
+ }
}
}
if(!(_dbg_pid_list[process_no].set&DBG_ABKPOINT_ON))
diff --git a/route_struct.c b/route_struct.c
index 85ebcc5..6d94131 100644
--- a/route_struct.c
+++ b/route_struct.c
@@ -187,120 +187,148 @@ struct action* append_action(struct action* a, struct action* b)
return a;
}
+#define BLEN 512
-
-void print_expr(struct expr* exp)
+char* print_expr_str(struct expr* exp, int no_print)
{
+
+ char *p, *tmp;
+ int len;
+ char *aux = pkg_malloc(512*sizeof(char));
+ if(!aux){
+ LOG(L_ERR, "Could not allocate memory\n");
+ return 0;
+ }
+ tmp = aux;
if (exp==0){
- LOG(L_CRIT, "ERROR: print_expr: null expression!\n");
- return;
+ LOG(L_CRIT, "ERROR: print_expr_str: null expression!\n");
+ goto error;
}
if (exp->type==ELEM_T){
switch(exp->l_type){
case METHOD_O:
- DBG("method");
+ snprintf(tmp, BLEN, "method");
break;
case URI_O:
- DBG("uri");
+ snprintf(tmp, BLEN, "uri");
break;
case FROM_URI_O:
- DBG("from_uri");
+ snprintf(tmp, BLEN, "from_uri");
break;
case TO_URI_O:
- DBG("to_uri");
+ snprintf(tmp, BLEN, "to_uri");
break;
case SRCIP_O:
- DBG("srcip");
+ snprintf(tmp, BLEN, "srcip");
break;
case SRCPORT_O:
- DBG("srcport");
+ snprintf(tmp, BLEN, "srcport");
break;
case DSTIP_O:
- DBG("dstip");
+ snprintf(tmp, BLEN, "dstip");
break;
case DSTPORT_O:
- DBG("dstport");
+ snprintf(tmp, BLEN, "dstport");
break;
case PROTO_O:
- DBG("proto");
+ snprintf(tmp, BLEN, "proto");
break;
case AF_O:
- DBG("af");
+ snprintf(tmp, BLEN, "af");
break;
case MSGLEN_O:
- DBG("msglen");
+ snprintf(tmp, BLEN, "msglen");
break;
case ACTION_O:
break;
case NUMBER_O:
break;
case AVP_O:
- DBG("avp");
+ snprintf(tmp, BLEN, "avp");
break;
case SNDIP_O:
- DBG("sndip");
+ snprintf(tmp, BLEN, "sndip");
break;
case SNDPORT_O:
- DBG("sndport");
+ snprintf(tmp, BLEN, "sndport");
break;
case TOIP_O:
- DBG("toip");
+ snprintf(tmp, BLEN, "toip");
break;
case TOPORT_O:
- DBG("toport");
+ snprintf(tmp, BLEN, "toport");
break;
case SNDPROTO_O:
- DBG("sndproto");
+ snprintf(tmp, BLEN, "sndproto");
break;
case SNDAF_O:
- DBG("sndaf");
+ snprintf(tmp, BLEN, "sndaf");
break;
case RETCODE_O:
- DBG("retcode");
+ snprintf(tmp, BLEN, "retcode");
break;
case SELECT_O:
- DBG("select");
+ snprintf(tmp, BLEN, "select");
break;
case RVEXP_O:
- DBG("rval");
+ snprintf(tmp, BLEN, "rval");
break;
default:
- DBG("UNKNOWN");
+ snprintf(tmp, BLEN, "UNKNOWN");
+ }
+
+ if(no_print){
+ len = strlen(aux);
+ tmp = aux + strlen(aux);
+ }
+ else{
+ len = 0;
+ DBG("%s", aux);
+ tmp = aux;
}
switch(exp->op){
case EQUAL_OP:
- DBG("==");
+ snprintf(tmp, BLEN - len, "==");
break;
case MATCH_OP:
- DBG("=~");
+ snprintf(tmp, BLEN - len, "=~");
break;
case NO_OP:
break;
case GT_OP:
- DBG(">");
+ snprintf(tmp, BLEN - len, ">");
break;
case GTE_OP:
- DBG(">=");
+ snprintf(tmp, BLEN - len, ">=");
break;
case LT_OP:
- DBG("<");
+ snprintf(tmp, BLEN - len, "<");
break;
case LTE_OP:
- DBG("<=");
+ snprintf(tmp, BLEN - len, "<=");
break;
case DIFF_OP:
- DBG("!=");
+ snprintf(tmp, BLEN - len, "!=");
break;
default:
- DBG("<UNKNOWN>");
+ snprintf(tmp, BLEN - len, "<UNKNOWN>");
+ }
+
+ if(no_print){
+ len = strlen(aux);
+ tmp = aux + len;
+ }else{
+ DBG("%s", aux);
+ len = 0;
+ tmp = aux;
}
switch(exp->r_type){
case NOSUBTYPE:
- DBG("N/A");
+ snprintf(tmp, BLEN - len, "N/A");
break;
case STRING_ST:
- DBG("\"%s\"", ZSW((char*)exp->r.param));
+ snprintf(tmp, BLEN - len, "\"%s\"",
ZSW((char*)exp->r.param));
break;
case NET_ST:
print_net((struct net*)exp->r.param);
@@ -309,139 +337,208 @@ void print_expr(struct expr* exp)
print_ip("", (struct ip_addr*)exp->r.param, "");
break;
case ACTIONS_ST:
- print_actions((struct action*)exp->r.param);
+ p = print_actions_str((struct action*)exp->r.param, no_print);
+ if(p){
+ snprintf(tmp, BLEN - len, "%s", p);
+ pkg_free(p);
+ }else goto error;
break;
case NUMBER_ST:
- DBG("%ld",exp->r.numval);
+ snprintf(tmp, BLEN - len, "%ld",exp->r.numval);
break;
case MYSELF_ST:
- DBG("_myself_");
+ snprintf(tmp, BLEN - len, "_myself_");
break;
case AVP_ST:
- DBG("attr");
+ snprintf(tmp, BLEN - len, "attr");
break;
case SELECT_ST:
- DBG("select");
+ snprintf(tmp, BLEN - len, "select");
break;
default:
- DBG("type<%d>", exp->r_type);
+ snprintf(tmp, BLEN - len, "type<%d>", exp->r_type);
+ }
+
+ if(no_print){
+ len = strlen(aux);
+ tmp = aux + len;
+ }else{
+ DBG("%s", aux);
+ len = 0;
+ tmp = aux;
}
}else if (exp->type==EXP_T){
switch(exp->op){
case LOGAND_OP:
- DBG("AND( ");
- print_expr(exp->l.expr);
- DBG(", ");
- print_expr(exp->r.expr);
- DBG(" )");
+ snprintf(tmp, BLEN, "AND( ");
+ p = print_expr_str(exp->l.expr, no_print);
+ if(p){
+ snprintf(tmp, BLEN - strlen(tmp), "%s", p);
+ pkg_free(p);
+ }else goto error;
+ snprintf(tmp, BLEN, ", ");
+ p = print_expr_str(exp->r.expr, no_print);
+ if(p){
+ snprintf(tmp, BLEN - strlen(tmp), "%s", p);
+ pkg_free(p);
+ }else goto error;
+ snprintf(tmp, BLEN - strlen(tmp), " )");
break;
case LOGOR_OP:
- DBG("OR( ");
- print_expr(exp->l.expr);
- DBG(", ");
- print_expr(exp->r.expr);
- DBG(" )");
+ snprintf(tmp, BLEN, "OR( ");
+ p = print_expr_str(exp->l.expr, no_print);
+ if(p){
+ snprintf(tmp, BLEN - strlen(tmp), "%s", p);
+ pkg_free(p);
+ }else goto error;
+ snprintf(tmp, BLEN - strlen(tmp), ", ");
+ p = print_expr_str(exp->r.expr, no_print);
+ if(p){
+ snprintf(tmp, BLEN - strlen(tmp), "%s", p);
+ pkg_free(p);
+ }else goto error;
+ snprintf(tmp, BLEN-strlen(tmp), " )");
break;
case NOT_OP:
- DBG("NOT( ");
- print_expr(exp->l.expr);
- DBG(" )");
+ snprintf(tmp, BLEN, "NOT( ");
+ p = print_expr_str(exp->l.expr, no_print);
+ if(p){
+ snprintf(tmp, BLEN - strlen(tmp), "%s", p);
+ pkg_free(p);
+ }else goto error;
+ snprintf(tmp, BLEN - strlen(tmp), " )");
break;
default:
- DBG("UNKNOWN_EXP ");
+ snprintf(tmp, BLEN, "UNKNOWN_EXP ");
+ }
+ if(no_print)
+ tmp = aux + strlen(aux);
+ else{
+ DBG("%s", aux);
+ tmp = aux;
}
}else{
- DBG("ERROR:print_expr: unknown type\n");
+ snprintf(tmp, BLEN, "ERROR:print_expr: unknown type\n");
+ if(no_print)
+ tmp = aux + strlen(aux);
+ else{
+ DBG("%s", aux);
+ tmp = aux;
+ }
}
+ return aux;
+error:
+ pkg_free(aux);
+ return 0;
}
+void print_expr(struct expr* expr)
+{
+ /* some compilers might complain that result from function is not used */
+ if(print_expr_str(expr, 0));
+}
+void print_action(struct action* t)
+{
+ if(print_action_str(t, 0));
+}
+void print_actions(struct action* t)
+{
+ if(print_actions_str(t, 0));
+}
-
-void print_action(struct action* t)
+char* print_action_str(struct action* t, int no_print)
{
+ char *aux = pkg_malloc(sizeof(char) * BLEN);
+ char *tmp = aux;
+ int len;
+ char *p;
+ if(!aux){
+ LOG(L_ERR, "Could not allocate memory\n");
+ return 0;
+ }
switch(t->type){
case FORWARD_T:
- DBG("forward(");
+ snprintf(tmp, BLEN, "%s", "forward(");
break;
case FORWARD_TCP_T:
- DBG("forward_tcp(");
+ snprintf(tmp, BLEN, "%s", "forward_tcp(");
break;
case FORWARD_UDP_T:
- DBG("forward_udp(");
+ snprintf(tmp, BLEN, "%s", "forward_udp(");
break;
case SEND_T:
- DBG("send(");
+ snprintf(tmp, BLEN, "%s", "send(");
break;
case SEND_TCP_T:
- DBG("send_tcp(");
+ snprintf(tmp, BLEN, "%s", "send_tcp(");
break;
case DROP_T:
- DBG("drop(");
+ snprintf(tmp, BLEN, "%s", "drop(");
break;
case LOG_T:
- DBG("log(");
+ snprintf(tmp, BLEN, "%s", "log(");
break;
case ERROR_T:
- DBG("error(");
+ snprintf(tmp, BLEN, "%s", "error(");
break;
case ROUTE_T:
- DBG("route(");
+ snprintf(tmp, BLEN, "%s", "route(");
break;
case EXEC_T:
- DBG("exec(");
+ snprintf(tmp, BLEN, "%s", "exec(");
break;
case REVERT_URI_T:
- DBG("revert_uri(");
+ snprintf(tmp, BLEN, "%s", "revert_uri(");
break;
case STRIP_T:
- DBG("strip(");
+ snprintf(tmp, BLEN, "%s", "strip(");
break;
case APPEND_BRANCH_T:
- DBG("append_branch(");
+ snprintf(tmp, BLEN, "%s", "append_branch(");
break;
case PREFIX_T:
- DBG("prefix(");
+ snprintf(tmp, BLEN, "%s", "prefix(");
break;
case LEN_GT_T:
- DBG("len_gt(");
+ snprintf(tmp, BLEN, "%s", "len_gt(");
break;
case SETFLAG_T:
- DBG("setflag(");
+ snprintf(tmp, BLEN, "%s", "setflag(");
break;
case RESETFLAG_T:
- DBG("resetflag(");
+ snprintf(tmp, BLEN, "%s", "resetflag(");
break;
case ISFLAGSET_T:
- DBG("isflagset(");
+ snprintf(tmp, BLEN, "%s", "isflagset(");
break;
case AVPFLAG_OPER_T:
- DBG("avpflagoper(");
+ snprintf(tmp, BLEN, "%s", "avpflagoper(");
break;
case SET_HOST_T:
- DBG("sethost(");
+ snprintf(tmp, BLEN, "%s", "sethost(");
break;
case SET_HOSTPORT_T:
- DBG("sethostport(");
+ snprintf(tmp, BLEN, "%s", "sethostport(");
break;
case SET_HOSTPORTTRANS_T:
- DBG("sethostporttrans(");
+ snprintf(tmp, BLEN, "%s", "sethostporttrans(");
break;
case SET_USER_T:
- DBG("setuser(");
+ snprintf(tmp, BLEN, "%s", "setuser(");
break;
case SET_USERPASS_T:
- DBG("setuserpass(");
+ snprintf(tmp, BLEN, "%s", "setuserpass(");
break;
case SET_PORT_T:
- DBG("setport(");
+ snprintf(tmp, BLEN, "%s", "setport(");
break;
case SET_URI_T:
- DBG("seturi(");
+ snprintf(tmp, BLEN, "%s", "seturi(");
break;
case IF_T:
- DBG("if (");
+ snprintf(tmp, BLEN, "%s", "if (");
break;
case MODULE_T:
case MODULE3_T:
@@ -449,141 +546,238 @@ void print_action(struct action* t)
case MODULE5_T:
case MODULE6_T:
case MODULEX_T:
- DBG(" external_module_call(");
+ snprintf(tmp, BLEN, "external_module_call(%s)(", ((union
cmd_export_u*)t->val[0].u.data)->c.name);
break;
case FORCE_RPORT_T:
- DBG("force_rport(");
+ snprintf(tmp, BLEN, "%s", "force_rport(");
break;
case SET_ADV_ADDR_T:
- DBG("set_advertised_address(");
+ snprintf(tmp, BLEN, "%s", "set_advertised_address(");
break;
case SET_ADV_PORT_T:
- DBG("set_advertised_port(");
+ snprintf(tmp, BLEN, "%s", "set_advertised_port(");
break;
case FORCE_TCP_ALIAS_T:
- DBG("force_tcp_alias(");
+ snprintf(tmp, BLEN, "%s", "force_tcp_alias(");
break;
case LOAD_AVP_T:
- DBG("load_avp(");
+ snprintf(tmp, BLEN, "%s", "load_avp(");
break;
case AVP_TO_URI_T:
- DBG("avp_to_attr");
+ snprintf(tmp, BLEN, "%s", "avp_to_attr");
break;
case FORCE_SEND_SOCKET_T:
- DBG("force_send_socket");
+ snprintf(tmp, BLEN, "%s", "force_send_socket");
break;
- case ASSIGN_T
- : DBG("assign(");
+ case ASSIGN_T:
+ snprintf(tmp, BLEN, "%s", "assign(");
break;
case ADD_T:
- DBG("assign_add(");
+ snprintf(tmp, BLEN, "%s", "assign_add(");
break;
default:
- DBG("UNKNOWN(");
+ snprintf(tmp, BLEN, "%s", "UNKNOWN(");
+ }
+
+ if(no_print){
+ len = strlen(aux);
+ tmp = aux + strlen(aux);
+ }else{
+ len = 0;
+ DBG("%s", aux);
+ tmp = aux;
}
switch(t->val[0].type){
case STRING_ST:
- DBG("\"%s\"", ZSW(t->val[0].u.string));
+ snprintf(tmp, BLEN - len, "\"%s\"", ZSW(t->val[0].u.string));
break;
case NUMBER_ST:
- DBG("%lu",t->val[0].u.number);
+ snprintf(tmp, BLEN - len, "%lu",t->val[0].u.number);
break;
case IP_ST:
print_ip("", (struct ip_addr*)t->val[0].u.data, "");
break;
case EXPR_ST:
- print_expr((struct expr*)t->val[0].u.data);
+ p = print_expr_str((struct expr*)t->val[0].u.data, no_print);
+ if(p){
+ snprintf(tmp, BLEN - len, "%s", p);
+ pkg_free(p);
+ }else goto error;
break;
case ACTIONS_ST:
- print_actions((struct action*)t->val[0].u.data);
+ if((p = print_actions_str((struct action*)t->val[1].u.data, no_print))){
+ snprintf(tmp, BLEN - len, "%s", p);
+ pkg_free(p);
+ }else goto error;
break;
case MODEXP_ST:
- DBG("f_ptr<%p>",t->val[0].u.data);
+ snprintf(tmp, BLEN - len, "f_ptr<%p>",t->val[0].u.data);
break;
case SOCKID_ST:
- DBG("%d:%s:%d",
+ snprintf(tmp, BLEN - len, "%d:%s:%d",
((struct socket_id*)t->val[0].u.data)->proto,
ZSW(((struct socket_id*)t->val[0].u.data)->addr_lst->name),
((struct socket_id*)t->val[0].u.data)->port
);
break;
case AVP_ST:
- DBG("avp(%u,%.*s)", t->val[0].u.attr->type,
t->val[0].u.attr->name.s.len, ZSW(t->val[0].u.attr->name.s.s));
+ snprintf(tmp, BLEN - len, "avp(%u,%.*s)", t->val[0].u.attr->type,
t->val[0].u.attr->name.s.len, ZSW(t->val[0].u.attr->name.s.s));
break;
case SELECT_ST:
- DBG("select");
+ snprintf(tmp, BLEN - len, "select");
break;
default:
- DBG("type<%d>", t->val[0].type);
+ snprintf(tmp, BLEN - len, "type<%d>", t->val[0].type);
}
- if (t->type==IF_T) DBG(") {");
+ if(no_print){
+ len = strlen(aux);
+ tmp = aux + len;
+ }else{
+ len = 0;
+ DBG("%s", aux);
+ tmp = aux;
+ }
+ if (t->type==IF_T) snprintf(tmp, BLEN - len, ") {");
switch(t->val[1].type){
case NOSUBTYPE:
break;
case STRING_ST:
- DBG(", \"%s\"", ZSW(t->val[1].u.string));
+ snprintf(tmp, BLEN - len, ", \"%s\"",
ZSW(t->val[1].u.string));
break;
case NUMBER_ST:
- DBG(", %lu",t->val[1].u.number);
+ snprintf(tmp, BLEN - len, ", %lu",t->val[1].u.number);
break;
case EXPR_ST:
- print_expr((struct expr*)t->val[1].u.data);
+ p = print_expr_str((struct expr*)t->val[1].u.data, no_print);
+ if(p){
+ snprintf(tmp, BLEN - len, "%s", p);
+ pkg_free(p);
+ }else goto error;
+
break;
case ACTION_ST:
case ACTIONS_ST:
- print_actions((struct action*)t->val[1].u.data);
+ if((p = print_actions_str((struct action*)t->val[1].u.data, no_print))){
+ snprintf(tmp, BLEN - len, "%s", p);
+ pkg_free(p);
+ }else goto error;
break;
case SOCKID_ST:
- DBG("%d:%s:%d",
+ snprintf(tmp, BLEN - len, "%d:%s:%d",
((struct socket_id*)t->val[0].u.data)->proto,
ZSW(((struct socket_id*)t->val[0].u.data)->addr_lst->name),
((struct socket_id*)t->val[0].u.data)->port
);
break;
case AVP_ST:
- DBG(", avp(%u,%.*s)", t->val[1].u.attr->type,
t->val[1].u.attr->name.s.len, ZSW(t->val[1].u.attr->name.s.s));
+ snprintf(tmp, BLEN - len, ", avp(%u,%.*s)", t->val[1].u.attr->type,
t->val[1].u.attr->name.s.len, ZSW(t->val[1].u.attr->name.s.s));
break;
case SELECT_ST:
- DBG("select");
+ snprintf(tmp, BLEN - len, "select");
break;
default:
- DBG(", type<%d>", t->val[1].type);
+ snprintf(tmp, BLEN - len, ", type<%d>", t->val[1].type);
+ }
+ if(no_print){
+ len = strlen(aux);
+ tmp = aux + strlen(aux);
+ }else{
+ len = 0;
+ DBG("%s", aux);
+ tmp = aux;
+ }
+ if (t->type==IF_T) snprintf(tmp, BLEN - len, "} else {");
+ if(no_print){
+ len = strlen(aux);
+ tmp = aux + len;
+ }else{
+ len = 0;
+ DBG("%s", aux);
+ tmp = aux;
}
- if (t->type==IF_T) DBG("} else {");
switch(t->val[2].type){
case NOSUBTYPE:
break;
case STRING_ST:
- DBG(", \"%s\"", ZSW(t->val[2].u.string));
+ snprintf(tmp, BLEN - len, ", \"%s\"",
ZSW(t->val[2].u.string));
break;
case NUMBER_ST:
- DBG(", %lu",t->val[2].u.number);
+ snprintf(tmp, BLEN - len, ", %lu",t->val[2].u.number);
break;
case EXPR_ST:
- print_expr((struct expr*)t->val[2].u.data);
+ p = print_expr_str((struct expr*)t->val[2].u.data, no_print);
+ if(p){
+ snprintf(tmp, BLEN - len, "%s", p);
+ pkg_free(p);
+ }else goto error;
break;
case ACTIONS_ST:
- print_actions((struct action*)t->val[2].u.data);
+ p = print_action_str((struct action*)t->val[2].u.data, no_print);
+ if(p){
+ snprintf(tmp, BLEN - len, "%s", p);
+ pkg_free(p);
+ }else goto error;
break;
case SOCKID_ST:
- DBG("%d:%s:%d",
+ snprintf(tmp, BLEN - len, "%d:%s:%d",
((struct socket_id*)t->val[0].u.data)->proto,
ZSW(((struct socket_id*)t->val[0].u.data)->addr_lst->name),
((struct socket_id*)t->val[0].u.data)->port
);
break;
default:
- DBG(", type<%d>", t->val[2].type);
+ snprintf(tmp, BLEN - len, ", type<%d>", t->val[2].type);
+ }
+ if(no_print){
+ len = strlen(aux);
+ tmp = aux + len;
+ }else{
+ len = 0;
+ DBG("%s", aux);
+ tmp = aux;
}
- if (t->type==IF_T) DBG("}; ");
- else DBG("); ");
+
+ if (t->type==IF_T) snprintf(tmp, BLEN - len, "}; ");
+ else snprintf(tmp, BLEN - len, "); ");
+
+ if(no_print)
+ tmp = aux + strlen(aux);
+ else{
+ DBG("%s", aux);
+ tmp = aux;
+ }
+
+ return aux;
+error:
+ pkg_free(aux);
+ return 0;
}
-void print_actions(struct action* a)
+char* print_actions_str(struct action* a, int no_print)
{
+ char *aux = pkg_malloc(sizeof(char)*BLEN);
+ char *tmp;
+ char *p;
+ int len;
+ if(!aux){
+ ERR("No more free memory");
+ return 0;
+ }
+ tmp = aux;
+ len = 0;
while(a) {
- print_action(a);
+ p = print_action_str(a, no_print);
+ if(p){
+ snprintf(tmp, BLEN - len, "%s", p);
+ len = strlen(aux);
+ tmp = aux + len;
+ pkg_free(p); /* buffer allocated by print_action_str*/
+ }else goto error;
a = a->next;
}
+ return aux;
+error:
+ pkg_free(aux);
+ return 0;
}
diff --git a/route_struct.h b/route_struct.h
index 4894bd5..d7181f7 100644
--- a/route_struct.h
+++ b/route_struct.h
@@ -207,6 +207,14 @@ void print_action(struct action* a);
void print_actions(struct action* a);
void print_expr(struct expr* exp);
+/* new str function that can return a pointer to a new allocated buffer containing the
description */
+/* if flag is 0 then print, else keep data in returned buffer */
+/* returned buffer must be deallocated by user*/
+/* return 0 if error */
+char* print_action_str(struct action* a, int);
+char* print_actions_str(struct action* a, int);
+char* print_expr_str(struct expr* exp, int);
+
/** joins to cfg file positions into a new one. */
void cfg_pos_join(struct cfg_pos* res,
struct cfg_pos* pos1, struct cfg_pos* pos2);