[SR-Dev] git:andrei/script_vars: script engine: lvalue/rvalue assignment and fixups

Andrei Pelinescu-Onciul andrei at iptel.org
Thu Dec 4 01:11:31 CET 2008


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

Author: Andrei Pelinescu-Onciul <andrei at iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei at iptel.org>
Date:   Thu Dec  4 01:12:46 2008 +0100

script engine: lvalue/rvalue assignment and fixups

---

 action.c       |  127 +++++---------------------------------------------------
 route.c        |   61 +++++++++++++--------------
 route.h        |    4 +-
 route_struct.h |    4 +-
 4 files changed, 47 insertions(+), 149 deletions(-)

diff --git a/action.c b/action.c
index ea69e3a..26edcca 100644
--- a/action.c
+++ b/action.c
@@ -47,6 +47,7 @@
  *  2007-06-14  run_actions & do_action need a ctx or handle now, no more 
  *               static vars (andrei)
  *  2008-11-18  support for variable parameter module functions (andrei)
+ *  2008-12-03  use lvalues/rvalues for assignments (andrei)
  */
 
 
@@ -63,6 +64,7 @@
 #include "parser/msg_parser.h"
 #include "parser/parse_uri.h"
 #include "ut.h"
+#include "lvalue.h"
 #include "sr_module.h"
 #include "mem/mem.h"
 #include "globals.h"
@@ -108,8 +110,6 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
 	struct sip_uri uri, next_hop;
 	struct sip_uri *u;
 	unsigned short port;
-	unsigned short flags;
-	int_str name, value;
 	str* dst_host;
 
 	/* reset the value of error to E_UNSPEC so avoid unknowledgable
@@ -870,121 +870,16 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
 			ret=1; /* continue processing */
 			break;
 
-	        case ADD_T:
-	        case ASSIGN_T:
-
-			/* If the left attr was specified without indexing brackets delete
-			 * existing AVPs before adding new ones
-			 */
-			if ((a->val[0].u.attr->type & AVP_INDEX_ALL) != AVP_INDEX_ALL) delete_avp(a->val[0].u.attr->type, a->val[0].u.attr->name);
-
-			if (a->val[1].type == STRING_ST) {
-				value.s = a->val[1].u.str;
-				flags = a->val[0].u.attr->type | AVP_VAL_STR;
-				name = a->val[0].u.attr->name;
-				ret = 1;
-			} else if (a->val[1].type == NUMBER_ST) {
-				value.n = a->val[1].u.number;
-				flags = a->val[0].u.attr->type;
-				name = a->val[0].u.attr->name;
+	 case ADD_T:
+	case ASSIGN_T:
+			v=lval_assign(h, msg, (struct lvalue*)a->val[0].u.data,
+								  (struct rval_expr*)a->val[1].u.data);
+			if (likely(v>=0)) 
 				ret = 1;
-			} else if (a->val[1].type == ACTION_ST) {
-				flags = a->val[0].u.attr->type;
-				name = a->val[0].u.attr->name;
-				if (a->val[1].u.data) {
-					value.n = run_actions(h, (struct action*)a->val[1].u.data,
-											msg);
-				} else {
-					value.n = -1;
-				}
-				ret = value.n;
-			} else if(a->val[1].type == EXPR_ST && a->val[1].u.data) {
-				v = eval_expr(h, (struct expr*)a->val[1].u.data, msg);
-				if (v < 0) {
-					if (v == EXPR_DROP){ /* hack to quit on DROP*/
-						ret = 0;
-						break;
-					} else {
-						LOG(L_WARN,"WARNING: do_action: error in expression\n");
-						v = 0; /* error is treated as false (Miklos) */
-					}
-				}
-
-				flags = a->val[0].u.attr->type;
-				name = a->val[0].u.attr->name;
-				value.n = v;
-			} else if (a->val[1].type == AVP_ST) {
-				struct search_state st;
-				avp_t* avp;
-				avp_t* avp_mark;
-
-				avp_mark = NULL;
-				if ((a->val[1].u.attr->type & AVP_INDEX_ALL) == AVP_INDEX_ALL) {
-					avp = search_first_avp(a->val[1].u.attr->type, a->val[1].u.attr->name, &value, &st);
-					while(avp) {
-						     /* We take only the type of value and name from the source avp
-						      * and reset class and track flags
-						      */
-						flags = (a->val[0].u.attr->type & ~AVP_INDEX_ALL) | (avp->flags & ~(AVP_CLASS_ALL|AVP_TRACK_ALL));
-
-						if (add_avp_before(avp_mark, flags, a->val[0].u.attr->name, value) < 0) {
-							LOG(L_CRIT, "ERROR: Failed to assign value to attribute\n");
-							ret=E_UNSPEC;
-							break;
-						}
-
-						/* move the mark, so the next found AVP will come before the one currently added
-						 * so they will have the same order as in the source list
-						 */
-						if (avp_mark) {
-							avp_mark=avp_mark->next;
-						} else {
-							avp_mark=search_first_avp(flags, a->val[0].u.attr->name, NULL, NULL);
-						}
-
-						avp = search_next_avp(&st, &value);
-					}
-					ret = 1;
-					break;
-				} else {
-					avp = search_avp_by_index(a->val[1].u.attr->type, a->val[1].u.attr->name, &value, a->val[1].u.attr->index);
-					if (avp) {
-						flags = a->val[0].u.attr->type | (avp->flags & ~(AVP_CLASS_ALL|AVP_TRACK_ALL));
-						name = a->val[0].u.attr->name;
-						ret = 1;
-					} else {
-						ret = E_UNSPEC;
-						break;
-					}
-				}
-			} else if (a->val[1].type == SELECT_ST) {
-				int r;
-				r = run_select(&value.s, a->val[1].u.select, msg);
-				if (r < 0) {
-					ret=E_UNSPEC;
-					break;
-				} else if (r > 0) {
-					value.s.s = "";
-					value.s.len = 0;
-				}
-
-				flags = a->val[0].u.attr->type | AVP_VAL_STR;
-				name = a->val[0].u.attr->name;
-				ret = 1;
-			} else {
-				LOG(L_CRIT, "BUG: do_action: Bad right side of avp assignment\n");
-				ret=E_BUG;
-				break;
-			}
-
-			/* If the action is assign then remove the old avp value
-			 * before adding new ones */
-/*			if ((unsigned char)a->type == ASSIGN_T) delete_avp(flags, name); */
-			if (add_avp(flags & ~AVP_INDEX_ALL, name, value) < 0) {
-				LOG(L_CRIT, "ERROR: Failed to assign value to attribute\n");
-				ret=E_UNSPEC;
-				break;
-			}
+			else if (unlikely (v == EXPR_DROP)) /* hack to quit on DROP*/
+				ret=0;
+			else
+				ret=v;
 			break;
 
 		default:
diff --git a/route.c b/route.c
index b57364b..cafe4fa 100644
--- a/route.c
+++ b/route.c
@@ -48,6 +48,7 @@
  *		the expressions does not exist (Miklos)
  *  2008-04-23  errors are treated as false during expression evaluation
  *  		unless the operator is DIFF_OP (Miklos)
+ *  2008-12-03  fixups for rvalues in assignments (andrei)
  */
 
 
@@ -66,6 +67,8 @@
 #include "dprint.h"
 #include "proxy.h"
 #include "action.h"
+#include "lvalue.h"
+#include "rvalue.h"
 #include "sr_module.h"
 #include "ip_addr.h"
 #include "resolve.h"
@@ -276,12 +279,12 @@ int route_lookup(struct route_list* rt, char* name)
 
 
 
-static int fix_actions(struct action* a); /*fwd declaration*/
+int fix_actions(struct action* a); /*fwd declaration*/
 
 
 /* traverses an expr tree and compiles the REs where necessary)
  * returns: 0 for ok, <0 if errors */
-static int fix_expr(struct expr* exp)
+int fix_expr(struct expr* exp)
 {
 	regex_t* re;
 	int ret;
@@ -380,7 +383,7 @@ static int fix_expr(struct expr* exp)
 
 /* adds the proxies in the proxy list & resolves the hostnames */
 /* returns 0 if ok, <0 on error */
-static int fix_actions(struct action* a)
+int fix_actions(struct action* a)
 {
 	struct action *t;
 	struct proxy_l* p;
@@ -391,6 +394,8 @@ static int fix_actions(struct action* a)
 	struct hostent* he;
 	struct ip_addr ip;
 	struct socket_info* si;
+	struct lvalue* lval;
+	
 	char buf[30]; /* tmp buffer needed for module param fixups */
 
 	if (a==0){
@@ -466,40 +471,34 @@ static int fix_actions(struct action* a)
 				}
 				break;
 
-		        case ASSIGN_T:
-		        case ADD_T:
-				if (t->val[0].type != AVP_ST) {
-					LOG(L_CRIT, "BUG: fix_actions: Invalid left side of assignment\n");
+			case ASSIGN_T:
+			case ADD_T:
+				if (t->val[0].type !=LVAL_ST) {
+					LOG(L_CRIT, "BUG: fix_actions: Invalid left side of"
+								" assignment\n");
 					return E_BUG;
 				}
-				if (t->val[0].u.attr->type & AVP_CLASS_DOMAIN) {
-					LOG(L_ERR, "ERROR: You cannot change domain attributes from the script, they are read-only\n");
-					return E_BUG;
-				} else if (t->val[0].u.attr->type & AVP_CLASS_GLOBAL) {
-					LOG(L_ERR, "ERROR: You cannot change global attributes from the script, they are read-only\n");
+				if (t->val[1].type !=RVE_ST) {
+					LOG(L_CRIT, "BUG: fix_actions: Invalid right side of"
+								" assignment (%d)\n", t->val[1].type);
 					return E_BUG;
 				}
-
-				if (t->val[1].type == ACTION_ST && t->val[1].u.data) {
-					if ((ret = fix_actions((struct action*)t->val[1].u.data)) < 0) {
-						return ret;
-					}
-				} else if (t->val[1].type == EXPR_ST && t->val[1].u.data) {
-					if ((ret = fix_expr((struct expr*)t->val[1].u.data)) < 0) {
-						return ret;
-					}
-				} else if (t->val[1].type == STRING_ST) {
-					int len;
-					len = strlen(t->val[1].u.data);
-					t->val[1].u.str.s = t->val[1].u.data;
-					t->val[1].u.str.len = len;
-				} else if (t->val[1].type == SELECT_ST) {
-					if ((ret=resolve_select(t->val[1].u.select)) < 0) {
-						BUG("Unable to resolve select\n");
-						print_select(t->val[1].u.select);
-						return ret;
+				lval=t->val[0].u.data;
+				if (lval->type==LV_AVP){
+					if (lval->lv.avps.type & AVP_CLASS_DOMAIN) {
+						LOG(L_ERR, "ERROR: You cannot change domain"
+									" attributes from the script, they are"
+									" read-only\n");
+						return E_BUG;
+					} else if (lval->lv.avps.type & AVP_CLASS_GLOBAL) {
+						LOG(L_ERR, "ERROR: You cannot change global"
+								   " attributes from the script, they are"
+								   "read-only\n");
+						return E_BUG;
 					}
 				}
+				if ((ret=fix_rval_expr(&t->val[1].u.data))<0)
+					return ret;
 				break;
 
 			case MODULE_T:
diff --git a/route.h b/route.h
index a1486d3..31c9785 100644
--- a/route.h
+++ b/route.h
@@ -73,7 +73,9 @@ int fix_rls();
 int eval_expr(struct run_act_ctx* h, struct expr* e, struct sip_msg* msg);
 
 
-
+/* fixup functions*/
+int fix_actions(struct action* a);
+int fix_expr(struct expr* exp);
 
 
 
diff --git a/route_struct.h b/route_struct.h
index 22b92d9..f3b298a 100644
--- a/route_struct.h
+++ b/route_struct.h
@@ -93,7 +93,9 @@ enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
 };
 enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST, PROXY_ST,
 		EXPR_ST, ACTIONS_ST, MODEXP_ST, MODFIXUP_ST, URIHOST_ST, URIPORT_ST,
-		MYSELF_ST, STR_ST, SOCKID_ST, SOCKETINFO_ST, ACTION_ST, AVP_ST, SELECT_ST,
+		MYSELF_ST, STR_ST, SOCKID_ST, SOCKETINFO_ST, ACTION_ST, AVP_ST,
+		SELECT_ST, /* obsolete */
+		LVAL_ST, RVE_ST,
 		RETCODE_ST};
 
 /* run flags */




More information about the sr-dev mailing list