Browse code

script engine: lvalue/rvalue assignment and fixups

Andrei Pelinescu-Onciul authored on 04/12/2008 00:12:46
Showing 4 changed files
... ...
@@ -47,6 +47,7 @@
47 47
  *  2007-06-14  run_actions & do_action need a ctx or handle now, no more 
48 48
  *               static vars (andrei)
49 49
  *  2008-11-18  support for variable parameter module functions (andrei)
50
+ *  2008-12-03  use lvalues/rvalues for assignments (andrei)
50 51
  */
51 52
 
52 53
 
... ...
@@ -63,6 +64,7 @@
63 63
 #include "parser/msg_parser.h"
64 64
 #include "parser/parse_uri.h"
65 65
 #include "ut.h"
66
+#include "lvalue.h"
66 67
 #include "sr_module.h"
67 68
 #include "mem/mem.h"
68 69
 #include "globals.h"
... ...
@@ -108,8 +110,6 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
108 108
 	struct sip_uri uri, next_hop;
109 109
 	struct sip_uri *u;
110 110
 	unsigned short port;
111
-	unsigned short flags;
112
-	int_str name, value;
113 111
 	str* dst_host;
114 112
 
115 113
 	/* 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)
870 870
 			ret=1; /* continue processing */
871 871
 			break;
872 872
 
873
-	        case ADD_T:
874
-	        case ASSIGN_T:
875
-
876
-			/* If the left attr was specified without indexing brackets delete
877
-			 * existing AVPs before adding new ones
878
-			 */
879
-			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);
880
-
881
-			if (a->val[1].type == STRING_ST) {
882
-				value.s = a->val[1].u.str;
883
-				flags = a->val[0].u.attr->type | AVP_VAL_STR;
884
-				name = a->val[0].u.attr->name;
885
-				ret = 1;
886
-			} else if (a->val[1].type == NUMBER_ST) {
887
-				value.n = a->val[1].u.number;
888
-				flags = a->val[0].u.attr->type;
889
-				name = a->val[0].u.attr->name;
873
+	 case ADD_T:
874
+	case ASSIGN_T:
875
+			v=lval_assign(h, msg, (struct lvalue*)a->val[0].u.data,
876
+								  (struct rval_expr*)a->val[1].u.data);
877
+			if (likely(v>=0)) 
890 878
 				ret = 1;
891
-			} else if (a->val[1].type == ACTION_ST) {
892
-				flags = a->val[0].u.attr->type;
893
-				name = a->val[0].u.attr->name;
894
-				if (a->val[1].u.data) {
895
-					value.n = run_actions(h, (struct action*)a->val[1].u.data,
896
-											msg);
897
-				} else {
898
-					value.n = -1;
899
-				}
900
-				ret = value.n;
901
-			} else if(a->val[1].type == EXPR_ST && a->val[1].u.data) {
902
-				v = eval_expr(h, (struct expr*)a->val[1].u.data, msg);
903
-				if (v < 0) {
904
-					if (v == EXPR_DROP){ /* hack to quit on DROP*/
905
-						ret = 0;
906
-						break;
907
-					} else {
908
-						LOG(L_WARN,"WARNING: do_action: error in expression\n");
909
-						v = 0; /* error is treated as false (Miklos) */
910
-					}
911
-				}
912
-
913
-				flags = a->val[0].u.attr->type;
914
-				name = a->val[0].u.attr->name;
915
-				value.n = v;
916
-			} else if (a->val[1].type == AVP_ST) {
917
-				struct search_state st;
918
-				avp_t* avp;
919
-				avp_t* avp_mark;
920
-
921
-				avp_mark = NULL;
922
-				if ((a->val[1].u.attr->type & AVP_INDEX_ALL) == AVP_INDEX_ALL) {
923
-					avp = search_first_avp(a->val[1].u.attr->type, a->val[1].u.attr->name, &value, &st);
924
-					while(avp) {
925
-						     /* We take only the type of value and name from the source avp
926
-						      * and reset class and track flags
927
-						      */
928
-						flags = (a->val[0].u.attr->type & ~AVP_INDEX_ALL) | (avp->flags & ~(AVP_CLASS_ALL|AVP_TRACK_ALL));
929
-
930
-						if (add_avp_before(avp_mark, flags, a->val[0].u.attr->name, value) < 0) {
931
-							LOG(L_CRIT, "ERROR: Failed to assign value to attribute\n");
932
-							ret=E_UNSPEC;
933
-							break;
934
-						}
935
-
936
-						/* move the mark, so the next found AVP will come before the one currently added
937
-						 * so they will have the same order as in the source list
938
-						 */
939
-						if (avp_mark) {
940
-							avp_mark=avp_mark->next;
941
-						} else {
942
-							avp_mark=search_first_avp(flags, a->val[0].u.attr->name, NULL, NULL);
943
-						}
944
-
945
-						avp = search_next_avp(&st, &value);
946
-					}
947
-					ret = 1;
948
-					break;
949
-				} else {
950
-					avp = search_avp_by_index(a->val[1].u.attr->type, a->val[1].u.attr->name, &value, a->val[1].u.attr->index);
951
-					if (avp) {
952
-						flags = a->val[0].u.attr->type | (avp->flags & ~(AVP_CLASS_ALL|AVP_TRACK_ALL));
953
-						name = a->val[0].u.attr->name;
954
-						ret = 1;
955
-					} else {
956
-						ret = E_UNSPEC;
957
-						break;
958
-					}
959
-				}
960
-			} else if (a->val[1].type == SELECT_ST) {
961
-				int r;
962
-				r = run_select(&value.s, a->val[1].u.select, msg);
963
-				if (r < 0) {
964
-					ret=E_UNSPEC;
965
-					break;
966
-				} else if (r > 0) {
967
-					value.s.s = "";
968
-					value.s.len = 0;
969
-				}
970
-
971
-				flags = a->val[0].u.attr->type | AVP_VAL_STR;
972
-				name = a->val[0].u.attr->name;
973
-				ret = 1;
974
-			} else {
975
-				LOG(L_CRIT, "BUG: do_action: Bad right side of avp assignment\n");
976
-				ret=E_BUG;
977
-				break;
978
-			}
979
-
980
-			/* If the action is assign then remove the old avp value
981
-			 * before adding new ones */
982
-/*			if ((unsigned char)a->type == ASSIGN_T) delete_avp(flags, name); */
983
-			if (add_avp(flags & ~AVP_INDEX_ALL, name, value) < 0) {
984
-				LOG(L_CRIT, "ERROR: Failed to assign value to attribute\n");
985
-				ret=E_UNSPEC;
986
-				break;
987
-			}
879
+			else if (unlikely (v == EXPR_DROP)) /* hack to quit on DROP*/
880
+				ret=0;
881
+			else
882
+				ret=v;
988 883
 			break;
989 884
 
990 885
 		default:
... ...
@@ -48,6 +48,7 @@
48 48
  *		the expressions does not exist (Miklos)
49 49
  *  2008-04-23  errors are treated as false during expression evaluation
50 50
  *  		unless the operator is DIFF_OP (Miklos)
51
+ *  2008-12-03  fixups for rvalues in assignments (andrei)
51 52
  */
52 53
 
53 54
 
... ...
@@ -66,6 +67,8 @@
66 66
 #include "dprint.h"
67 67
 #include "proxy.h"
68 68
 #include "action.h"
69
+#include "lvalue.h"
70
+#include "rvalue.h"
69 71
 #include "sr_module.h"
70 72
 #include "ip_addr.h"
71 73
 #include "resolve.h"
... ...
@@ -276,12 +279,12 @@ int route_lookup(struct route_list* rt, char* name)
276 276
 
277 277
 
278 278
 
279
-static int fix_actions(struct action* a); /*fwd declaration*/
279
+int fix_actions(struct action* a); /*fwd declaration*/
280 280
 
281 281
 
282 282
 /* traverses an expr tree and compiles the REs where necessary)
283 283
  * returns: 0 for ok, <0 if errors */
284
-static int fix_expr(struct expr* exp)
284
+int fix_expr(struct expr* exp)
285 285
 {
286 286
 	regex_t* re;
287 287
 	int ret;
... ...
@@ -380,7 +383,7 @@ static int fix_expr(struct expr* exp)
380 380
 
381 381
 /* adds the proxies in the proxy list & resolves the hostnames */
382 382
 /* returns 0 if ok, <0 on error */
383
-static int fix_actions(struct action* a)
383
+int fix_actions(struct action* a)
384 384
 {
385 385
 	struct action *t;
386 386
 	struct proxy_l* p;
... ...
@@ -391,6 +394,8 @@ static int fix_actions(struct action* a)
391 391
 	struct hostent* he;
392 392
 	struct ip_addr ip;
393 393
 	struct socket_info* si;
394
+	struct lvalue* lval;
395
+	
394 396
 	char buf[30]; /* tmp buffer needed for module param fixups */
395 397
 
396 398
 	if (a==0){
... ...
@@ -466,40 +471,34 @@ static int fix_actions(struct action* a)
466 466
 				}
467 467
 				break;
468 468
 
469
-		        case ASSIGN_T:
470
-		        case ADD_T:
471
-				if (t->val[0].type != AVP_ST) {
472
-					LOG(L_CRIT, "BUG: fix_actions: Invalid left side of assignment\n");
469
+			case ASSIGN_T:
470
+			case ADD_T:
471
+				if (t->val[0].type !=LVAL_ST) {
472
+					LOG(L_CRIT, "BUG: fix_actions: Invalid left side of"
473
+								" assignment\n");
473 474
 					return E_BUG;
474 475
 				}
475
-				if (t->val[0].u.attr->type & AVP_CLASS_DOMAIN) {
476
-					LOG(L_ERR, "ERROR: You cannot change domain attributes from the script, they are read-only\n");
477
-					return E_BUG;
478
-				} else if (t->val[0].u.attr->type & AVP_CLASS_GLOBAL) {
479
-					LOG(L_ERR, "ERROR: You cannot change global attributes from the script, they are read-only\n");
476
+				if (t->val[1].type !=RVE_ST) {
477
+					LOG(L_CRIT, "BUG: fix_actions: Invalid right side of"
478
+								" assignment (%d)\n", t->val[1].type);
480 479
 					return E_BUG;
481 480
 				}
482
-
483
-				if (t->val[1].type == ACTION_ST && t->val[1].u.data) {
484
-					if ((ret = fix_actions((struct action*)t->val[1].u.data)) < 0) {
485
-						return ret;
486
-					}
487
-				} else if (t->val[1].type == EXPR_ST && t->val[1].u.data) {
488
-					if ((ret = fix_expr((struct expr*)t->val[1].u.data)) < 0) {
489
-						return ret;
490
-					}
491
-				} else if (t->val[1].type == STRING_ST) {
492
-					int len;
493
-					len = strlen(t->val[1].u.data);
494
-					t->val[1].u.str.s = t->val[1].u.data;
495
-					t->val[1].u.str.len = len;
496
-				} else if (t->val[1].type == SELECT_ST) {
497
-					if ((ret=resolve_select(t->val[1].u.select)) < 0) {
498
-						BUG("Unable to resolve select\n");
499
-						print_select(t->val[1].u.select);
500
-						return ret;
481
+				lval=t->val[0].u.data;
482
+				if (lval->type==LV_AVP){
483
+					if (lval->lv.avps.type & AVP_CLASS_DOMAIN) {
484
+						LOG(L_ERR, "ERROR: You cannot change domain"
485
+									" attributes from the script, they are"
486
+									" read-only\n");
487
+						return E_BUG;
488
+					} else if (lval->lv.avps.type & AVP_CLASS_GLOBAL) {
489
+						LOG(L_ERR, "ERROR: You cannot change global"
490
+								   " attributes from the script, they are"
491
+								   "read-only\n");
492
+						return E_BUG;
501 493
 					}
502 494
 				}
495
+				if ((ret=fix_rval_expr(&t->val[1].u.data))<0)
496
+					return ret;
503 497
 				break;
504 498
 
505 499
 			case MODULE_T:
... ...
@@ -73,7 +73,9 @@ int fix_rls();
73 73
 int eval_expr(struct run_act_ctx* h, struct expr* e, struct sip_msg* msg);
74 74
 
75 75
 
76
-
76
+/* fixup functions*/
77
+int fix_actions(struct action* a);
78
+int fix_expr(struct expr* exp);
77 79
 
78 80
 
79 81
 
... ...
@@ -93,7 +93,9 @@ enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
93 93
 };
94 94
 enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST, PROXY_ST,
95 95
 		EXPR_ST, ACTIONS_ST, MODEXP_ST, MODFIXUP_ST, URIHOST_ST, URIPORT_ST,
96
-		MYSELF_ST, STR_ST, SOCKID_ST, SOCKETINFO_ST, ACTION_ST, AVP_ST, SELECT_ST,
96
+		MYSELF_ST, STR_ST, SOCKID_ST, SOCKETINFO_ST, ACTION_ST, AVP_ST,
97
+		SELECT_ST, /* obsolete */
98
+		LVAL_ST, RVE_ST,
97 99
 		RETCODE_ST};
98 100
 
99 101
 /* run flags */