Browse code

- rewritten module function parsing and call processing (mk_action, struct action, action_u_t) - API to get other fixup params from fixup - full function overloading - optional NUMBER/STRING param in config for module functions - added oveloaded functions to print_stdout (demostrates overloading)

Tomas Mandys authored on 09/01/2006 19:42:35
Showing 9 changed files
... ...
@@ -21,8 +21,8 @@
21 21
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 22
  * GNU General Public License for more details.
23 23
  *
24
- * You should have received a copy of the GNU General Public License 
25
- * along with this program; if not, write to the Free Software 
24
+ * You should have received a copy of the GNU General Public License
25
+ * along with this program; if not, write to the Free Software
26 26
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27 27
  *
28 28
  * History:
... ...
@@ -88,7 +88,7 @@ struct onsend_info* p_onsend=0; /* onsend route send info */
88 88
 static unsigned int run_flags=0;
89 89
 int last_retcode=0; /* last return from a route() */
90 90
 
91
-/* ret= 0! if action -> end of list(e.g DROP), 
91
+/* ret= 0! if action -> end of list(e.g DROP),
92 92
       > 0 to continue processing next actions
93 93
    and <0 on error */
94 94
 int do_action(struct action* a, struct sip_msg* msg)
... ...
@@ -119,11 +119,11 @@ int do_action(struct action* a, struct sip_msg* msg)
119 119
 	ret=E_BUG;
120 120
 	switch ((unsigned char)a->type){
121 121
 		case DROP_T:
122
-				if (a->p1_type==RETCODE_ST)
122
+				if (a->val[0].type==RETCODE_ST)
123 123
 					ret=last_retcode;
124 124
 				else
125
-					ret=(int)a->p1.number;
126
-				run_flags|=(unsigned int)a->p2.number;
125
+					ret=(int) a->val[0].u.number;
126
+				run_flags|=(unsigned int)a->val[1].u.number;
127 127
 			break;
128 128
 		case FORWARD_T:
129 129
 #ifdef USE_TCP
... ...
@@ -142,7 +142,7 @@ int do_action(struct action* a, struct sip_msg* msg)
142 142
 			else if (a->type==FORWARD_TLS_T) proto= PROTO_TLS;
143 143
 #endif
144 144
 			else proto= PROTO_NONE;
145
-			if (a->p1_type==URIHOST_ST){
145
+			if (a->val[0].type==URIHOST_ST){
146 146
 				/*parse uri*/
147 147
 
148 148
 				if (msg->dst_uri.len) {
... ...
@@ -158,17 +158,17 @@ int do_action(struct action* a, struct sip_msg* msg)
158 158
 								" dropping packet\n");
159 159
 					break;
160 160
 				}
161
-				
162
-				switch (a->p2_type){
161
+
162
+				switch (a->val[1].type){
163 163
 					case URIPORT_ST:
164 164
 									port=u->port_no;
165 165
 									break;
166 166
 					case NUMBER_ST:
167
-									port=a->p2.number;
167
+									port=a->val[1].u.number;
168 168
 									break;
169 169
 					default:
170 170
 							LOG(L_CRIT, "BUG: do_action bad forward 2nd"
171
-										" param type (%d)\n", a->p2_type);
171
+										" param type (%d)\n", a->val[1].type);
172 172
 							ret=E_UNSPEC;
173 173
 							goto error_fwd_uri;
174 174
 				}
... ...
@@ -219,22 +219,22 @@ int do_action(struct action* a, struct sip_msg* msg)
219 219
 				free_proxy(p); /* frees only p content, not p itself */
220 220
 				pkg_free(p);
221 221
 				if (ret>=0) ret=1;
222
-			}else if ((a->p1_type==PROXY_ST) && (a->p2_type==NUMBER_ST)){
222
+			}else if ((a->val[0].type==PROXY_ST) && (a->val[1].type==NUMBER_ST)){
223 223
 				if (proto==PROTO_NONE)
224 224
 					proto=msg->rcv.proto;
225
-				ret=forward_request(msg,(struct proxy_l*)a->p1.data, proto);
225
+				ret=forward_request(msg,(struct proxy_l*)a->val[0].u.data, proto);
226 226
 				if (ret>=0) ret=1;
227 227
 			}else{
228 228
 				LOG(L_CRIT, "BUG: do_action: bad forward() types %d, %d\n",
229
-						a->p1_type, a->p2_type);
229
+						a->val[0].type, a->val[1].type);
230 230
 				ret=E_BUG;
231 231
 			}
232 232
 			break;
233 233
 		case SEND_T:
234 234
 		case SEND_TCP_T:
235
-			if ((a->p1_type!= PROXY_ST)|(a->p2_type!=NUMBER_ST)){
235
+			if ((a->val[0].type!= PROXY_ST)|(a->val[1].type!=NUMBER_ST)){
236 236
 				LOG(L_CRIT, "BUG: do_action: bad send() types %d, %d\n",
237
-						a->p1_type, a->p2_type);
237
+						a->val[0].type, a->val[1].type);
238 238
 				ret=E_BUG;
239 239
 				break;
240 240
 			}
... ...
@@ -246,13 +246,13 @@ int do_action(struct action* a, struct sip_msg* msg)
246 246
 				ret=E_OUT_OF_MEM;
247 247
 				break;
248 248
 			}
249
-			
250
-			p=(struct proxy_l*)a->p1.data;
251
-			
249
+
250
+			p=(struct proxy_l*)a->val[0].u.data;
251
+
252 252
 			if (p->ok==0){
253 253
 				if (p->host.h_addr_list[p->addr_idx+1])
254 254
 					p->addr_idx++;
255
-				else 
255
+				else
256 256
 					p->addr_idx=0;
257 257
 				p->ok=1;
258 258
 			}
... ...
@@ -289,132 +289,132 @@ int do_action(struct action* a, struct sip_msg* msg)
289 289
 				p->errors++;
290 290
 				p->ok=0;
291 291
 			}else ret=1;
292
-			
292
+
293 293
 			break;
294 294
 		case LOG_T:
295
-			if ((a->p1_type!=NUMBER_ST)|(a->p2_type!=STRING_ST)){
295
+			if ((a->val[0].type!=NUMBER_ST)|(a->val[1].type!=STRING_ST)){
296 296
 				LOG(L_CRIT, "BUG: do_action: bad log() types %d, %d\n",
297
-						a->p1_type, a->p2_type);
297
+						a->val[0].type, a->val[1].type);
298 298
 				ret=E_BUG;
299 299
 				break;
300 300
 			}
301
-			LOG(a->p1.number, "%s", a->p2.string);
301
+			LOG(a->val[0].u.number, "%s", a->val[1].u.string);
302 302
 			ret=1;
303 303
 			break;
304 304
 
305 305
 		/* jku -- introduce a new branch */
306 306
 		case APPEND_BRANCH_T:
307
-			if ((a->p1_type!=STRING_ST)) {
307
+			if ((a->val[0].type!=STRING_ST)) {
308 308
 				LOG(L_CRIT, "BUG: do_action: bad append_branch_t %d\n",
309
-					a->p1_type );
309
+					a->val[0].type );
310 310
 				ret=E_BUG;
311 311
 				break;
312 312
 			}
313
-			ret=append_branch( msg, a->p1.string, 
314
-					   a->p1.string ? strlen(a->p1.string):0,
315
-					   0, 0, a->p2.number, 0);
313
+			ret=append_branch( msg, a->val[0].u.string,
314
+					   a->val[0].u.string ? strlen(a->val[0].u.string):0,
315
+					   0, 0, a->val[1].u.number, 0);
316 316
 			break;
317 317
 
318 318
 		/* jku begin: is_length_greater_than */
319 319
 		case LEN_GT_T:
320
-			if (a->p1_type!=NUMBER_ST) {
320
+			if (a->val[0].type!=NUMBER_ST) {
321 321
 				LOG(L_CRIT, "BUG: do_action: bad len_gt type %d\n",
322
-					a->p1_type );
322
+					a->val[0].type );
323 323
 				ret=E_BUG;
324 324
 				break;
325 325
 			}
326
-			/* DBG("XXX: message length %d, max %d\n", 
327
-				msg->len, a->p1.number ); */
328
-			ret = msg->len >= a->p1.number ? 1 : -1;
326
+			/* DBG("XXX: message length %d, max %d\n",
327
+				msg->len, a->val[0].u.number ); */
328
+			ret = msg->len >= a->val[0].u.number ? 1 : -1;
329 329
 			break;
330 330
 		/* jku end: is_length_greater_than */
331
-			
331
+
332 332
 		/* jku - begin : flag processing */
333 333
 
334 334
 		case SETFLAG_T:
335
-			if (a->p1_type!=NUMBER_ST) {
335
+			if (a->val[0].type!=NUMBER_ST) {
336 336
 				LOG(L_CRIT, "BUG: do_action: bad setflag() type %d\n",
337
-					a->p1_type );
337
+					a->val[0].type );
338 338
 				ret=E_BUG;
339 339
 				break;
340 340
 			}
341
-			if (!flag_in_range( a->p1.number )) {
341
+			if (!flag_in_range( a->val[0].u.number )) {
342 342
 				ret=E_CFG;
343 343
 				break;
344 344
 			}
345
-			setflag( msg, a->p1.number );
345
+			setflag( msg, a->val[0].u.number );
346 346
 			ret=1;
347 347
 			break;
348 348
 
349 349
 		case RESETFLAG_T:
350
-			if (a->p1_type!=NUMBER_ST) {
350
+			if (a->val[0].type!=NUMBER_ST) {
351 351
 				LOG(L_CRIT, "BUG: do_action: bad resetflag() type %d\n",
352
-					a->p1_type );
352
+					a->val[0].type );
353 353
 				ret=E_BUG;
354 354
 				break;
355 355
 			}
356
-			if (!flag_in_range( a->p1.number )) {
356
+			if (!flag_in_range( a->val[0].u.number )) {
357 357
 				ret=E_CFG;
358 358
 				break;
359 359
 			}
360
-			resetflag( msg, a->p1.number );
360
+			resetflag( msg, a->val[0].u.number );
361 361
 			ret=1;
362 362
 			break;
363
-			
363
+
364 364
 		case ISFLAGSET_T:
365
-			if (a->p1_type!=NUMBER_ST) {
365
+			if (a->val[0].type!=NUMBER_ST) {
366 366
 				LOG(L_CRIT, "BUG: do_action: bad isflagset() type %d\n",
367
-					a->p1_type );
367
+					a->val[0].type );
368 368
 				ret=E_BUG;
369 369
 				break;
370 370
 			}
371
-			if (!flag_in_range( a->p1.number )) {
371
+			if (!flag_in_range( a->val[0].u.number )) {
372 372
 				ret=E_CFG;
373 373
 				break;
374 374
 			}
375
-			ret=isflagset( msg, a->p1.number );
375
+			ret=isflagset( msg, a->val[0].u.number );
376 376
 			break;
377 377
 		/* jku - end : flag processing */
378 378
 
379 379
 		case ERROR_T:
380
-			if ((a->p1_type!=STRING_ST)|(a->p2_type!=STRING_ST)){
380
+			if ((a->val[0].type!=STRING_ST)|(a->val[1].type!=STRING_ST)){
381 381
 				LOG(L_CRIT, "BUG: do_action: bad error() types %d, %d\n",
382
-						a->p1_type, a->p2_type);
382
+						a->val[0].type, a->val[1].type);
383 383
 				ret=E_BUG;
384 384
 				break;
385 385
 			}
386 386
 			LOG(L_NOTICE, "WARNING: do_action: error(\"%s\", \"%s\") "
387
-					"not implemented yet\n", a->p1.string, a->p2.string);
387
+					"not implemented yet\n", a->val[0].u.string, a->val[1].u.string);
388 388
 			ret=1;
389 389
 			break;
390 390
 		case ROUTE_T:
391
-			if (a->p1_type!=NUMBER_ST){
391
+			if (a->val[0].type!=NUMBER_ST){
392 392
 				LOG(L_CRIT, "BUG: do_action: bad route() type %d\n",
393
-						a->p1_type);
393
+						a->val[0].type);
394 394
 				ret=E_BUG;
395 395
 				break;
396 396
 			}
397
-			if ((a->p1.number>RT_NO)||(a->p1.number<0)){
397
+			if ((a->val[0].u.number>RT_NO)||(a->val[0].u.number<0)){
398 398
 				LOG(L_ERR, "ERROR: invalid routing table number in"
399
-							"route(%lu)\n", a->p1.number);
399
+							"route(%lu)\n", a->val[0].u.number);
400 400
 				ret=E_CFG;
401 401
 				break;
402 402
 			}
403
-			/*ret=((ret=run_actions(rlist[a->p1.number], msg))<0)?ret:1;*/
404
-			ret=run_actions(rlist[a->p1.number], msg);
403
+			/*ret=((ret=run_actions(rlist[a->val[0].u.number], msg))<0)?ret:1;*/
404
+			ret=run_actions(rlist[a->val[0].u.number], msg);
405 405
 			last_retcode=ret;
406 406
 			run_flags&=~RETURN_R_F; /* absorb returns */
407 407
 			break;
408 408
 		case EXEC_T:
409
-			if (a->p1_type!=STRING_ST){
409
+			if (a->val[0].type!=STRING_ST){
410 410
 				LOG(L_CRIT, "BUG: do_action: bad exec() type %d\n",
411
-						a->p1_type);
411
+						a->val[0].type);
412 412
 				ret=E_BUG;
413 413
 				break;
414 414
 			}
415 415
 			LOG(L_NOTICE, "WARNING: exec(\"%s\") not fully implemented,"
416
-						" using dumb version...\n", a->p1.string);
417
-			ret=system(a->p1.string);
416
+						" using dumb version...\n", a->val[0].u.string);
417
+			ret=system(a->val[0].u.string);
418 418
 			if (ret!=0){
419 419
 				LOG(L_NOTICE, "WARNING: exec() returned %d\n", ret);
420 420
 			}
... ...
@@ -440,14 +440,14 @@ int do_action(struct action* a, struct sip_msg* msg)
440 440
 		case STRIP_TAIL_T:
441 441
 				user=0;
442 442
 				if (a->type==STRIP_T || a->type==STRIP_TAIL_T) {
443
-					if (a->p1_type!=NUMBER_ST) {
443
+					if (a->val[0].type!=NUMBER_ST) {
444 444
 						LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
445
-							a->p1_type);
445
+							a->val[0].type);
446 446
 						break;
447 447
 					}
448
-				} else if (a->p1_type!=STRING_ST){
448
+				} else if (a->val[0].type!=STRING_ST){
449 449
 					LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
450
-							a->p1_type);
450
+							a->val[0].type);
451 451
 					ret=E_BUG;
452 452
 					break;
453 453
 				}
... ...
@@ -457,7 +457,7 @@ int do_action(struct action* a, struct sip_msg* msg)
457 457
 							msg->new_uri.len=0;
458 458
 					}
459 459
 					msg->parsed_uri_ok=0;
460
-					len=strlen(a->p1.string);
460
+					len=strlen(a->val[0].u.string);
461 461
 					msg->new_uri.s=pkg_malloc(len+1);
462 462
 					if (msg->new_uri.s==0){
463 463
 						LOG(L_ERR, "ERROR: do_action: memory allocation"
... ...
@@ -465,10 +465,10 @@ int do_action(struct action* a, struct sip_msg* msg)
465 465
 						ret=E_OUT_OF_MEM;
466 466
 						break;
467 467
 					}
468
-					memcpy(msg->new_uri.s, a->p1.string, len);
468
+					memcpy(msg->new_uri.s, a->val[0].u.string, len);
469 469
 					msg->new_uri.s[len]=0;
470 470
 					msg->new_uri.len=len;
471
-					
471
+
472 472
 					ret=1;
473 473
 					break;
474 474
 				}
... ...
@@ -485,7 +485,7 @@ int do_action(struct action* a, struct sip_msg* msg)
485 485
 					ret=E_UNSPEC;
486 486
 					break;
487 487
 				}
488
-				
488
+
489 489
 				new_uri=pkg_malloc(MAX_URI_SIZE);
490 490
 				if (new_uri==0){
491 491
 					LOG(L_ERR, "ERROR: do_action: memory allocation "
... ...
@@ -503,40 +503,40 @@ int do_action(struct action* a, struct sip_msg* msg)
503 503
 
504 504
 				/* prefix (-jiri) */
505 505
 				if (a->type==PREFIX_T) {
506
-					tmp=a->p1.string;
506
+					tmp=a->val[0].u.string;
507 507
 					len=strlen(tmp); if(crt+len>end) goto error_uri;
508 508
 					memcpy(crt,tmp,len);crt+=len;
509
-					/* whatever we had before, with prefix we have username 
509
+					/* whatever we had before, with prefix we have username
510 510
 					   now */
511 511
 					user=1;
512 512
 				}
513 513
 
514 514
 				if ((a->type==SET_USER_T)||(a->type==SET_USERPASS_T)) {
515
-					tmp=a->p1.string;
515
+					tmp=a->val[0].u.string;
516 516
 					len=strlen(tmp);
517 517
 				} else if (a->type==STRIP_T) {
518
-					if (a->p1.number>uri.user.len) {
518
+					if (a->val[0].u.number>uri.user.len) {
519 519
 						LOG(L_WARN, "Error: too long strip asked; "
520 520
 									" deleting username: %lu of <%.*s>\n",
521
-									a->p1.number, uri.user.len, uri.user.s );
521
+									a->val[0].u.number, uri.user.len, uri.user.s );
522 522
 						len=0;
523
-					} else if (a->p1.number==uri.user.len) {
523
+					} else if (a->val[0].u.number==uri.user.len) {
524 524
 						len=0;
525 525
 					} else {
526
-						tmp=uri.user.s + a->p1.number;
527
-						len=uri.user.len - a->p1.number;
526
+						tmp=uri.user.s + a->val[0].u.number;
527
+						len=uri.user.len - a->val[0].u.number;
528 528
 					}
529 529
 				} else if (a->type==STRIP_TAIL_T) {
530
-					if (a->p1.number>uri.user.len) {
530
+					if (a->val[0].u.number>uri.user.len) {
531 531
 						LOG(L_WARN, "WARNING: too long strip_tail asked; "
532 532
 									" deleting username: %lu of <%.*s>\n",
533
-									a->p1.number, uri.user.len, uri.user.s );
533
+									a->val[0].u.number, uri.user.len, uri.user.s );
534 534
 						len=0;
535
-					} else if (a->p1.number==uri.user.len) {
535
+					} else if (a->val[0].u.number==uri.user.len) {
536 536
 						len=0;
537 537
 					} else {
538 538
 						tmp=uri.user.s;
539
-						len=uri.user.len - a->p1.number;
539
+						len=uri.user.len - a->val[0].u.number;
540 540
 					}
541 541
 				} else {
542 542
 					tmp=uri.user.s;
... ...
@@ -563,7 +563,7 @@ int do_action(struct action* a, struct sip_msg* msg)
563 563
 					*crt='@'; crt++;
564 564
 				}
565 565
 				if ((a->type==SET_HOST_T) ||(a->type==SET_HOSTPORT_T)) {
566
-					tmp=a->p1.string;
566
+					tmp=a->val[0].u.string;
567 567
 					if (tmp) len = strlen(tmp);
568 568
 					else len=0;
569 569
 				} else {
... ...
@@ -577,7 +577,7 @@ int do_action(struct action* a, struct sip_msg* msg)
577 577
 				/* port */
578 578
 				if (a->type==SET_HOSTPORT_T) tmp=0;
579 579
 				else if (a->type==SET_PORT_T) {
580
-					tmp=a->p1.string;
580
+					tmp=a->val[0].u.string;
581 581
 					if (tmp) len = strlen(tmp);
582 582
 					else len = 0;
583 583
 				} else {
... ...
@@ -613,8 +613,8 @@ int do_action(struct action* a, struct sip_msg* msg)
613 613
 				break;
614 614
 		case IF_T:
615 615
 				/* if null expr => ignore if? */
616
-				if ((a->p1_type==EXPR_ST)&&a->p1.data){
617
-					v=eval_expr((struct expr*)a->p1.data, msg);
616
+				if ((a->val[0].type==EXPR_ST)&&a->val[0].u.data){
617
+					v=eval_expr((struct expr*)a->val[0].u.data, msg);
618 618
 #if 0
619 619
 					if (v<0){
620 620
 						if (v==EXPR_DROP){ /* hack to quit on DROP*/
... ...
@@ -633,21 +633,22 @@ int do_action(struct action* a, struct sip_msg* msg)
633 633
 					run_flags &= ~RETURN_R_F; /* catch returns in expr */
634 634
 					ret=1;  /*default is continue */
635 635
 					if (v>0) {
636
-						if ((a->p2_type==ACTIONS_ST)&&a->p2.data){
637
-							ret=run_actions((struct action*)a->p2.data, msg);
636
+						if ((a->val[1].type==ACTIONS_ST)&&a->val[1].u.data){
637
+							ret=run_actions((struct action*)a->val[1].u.data, msg);
638 638
 						}
639
-					}else if ((a->p3_type==ACTIONS_ST)&&a->p3.data){
640
-							ret=run_actions((struct action*)a->p3.data, msg);
639
+					}else if ((a->val[2].type==ACTIONS_ST)&&a->val[2].u.data){
640
+							ret=run_actions((struct action*)a->val[2].u.data, msg);
641 641
 					}
642 642
 				}
643 643
 			break;
644 644
 		case MODULE_T:
645
-			if ( ((a->p1_type==CMDF_ST)&&a->p1.data)/*&&
646
-					((a->p2_type==STRING_ST)&&a->p2.data)*/ ){
647
-				ret=((cmd_function)(a->p1.data))(msg, (char*)a->p2.data,
648
-													  (char*)a->p3.data);
645
+			if ( a->val[0].type==MODEXP_ST && a->val[0].u.data && ((cmd_export_t*)a->val[0].u.data)->function ){
646
+				ret=((cmd_export_t*)a->val[0].u.data)->function(msg,
647
+					(char*)a->val[2].u.data,
648
+					(char*)a->val[3].u.data
649
+				);
649 650
 				if (ret==0) run_flags|=EXIT_R_F;
650
-			}else{
651
+			} else {
651 652
 				LOG(L_CRIT,"BUG: do_action: bad module call\n");
652 653
 			}
653 654
 			break;
... ...
@@ -656,23 +657,23 @@ int do_action(struct action* a, struct sip_msg* msg)
656 656
 			ret=1; /* continue processing */
657 657
 			break;
658 658
 		case SET_ADV_ADDR_T:
659
-			if (a->p1_type!=STR_ST){
659
+			if (a->val[0].type!=STR_ST){
660 660
 				LOG(L_CRIT, "BUG: do_action: bad set_advertised_address() "
661
-						"type %d\n", a->p1_type);
661
+						"type %d\n", a->val[0].type);
662 662
 				ret=E_BUG;
663 663
 				break;
664 664
 			}
665
-			msg->set_global_address=*((str*)a->p1.data);
665
+			msg->set_global_address=*((str*)a->val[0].u.data);
666 666
 			ret=1; /* continue processing */
667 667
 			break;
668 668
 		case SET_ADV_PORT_T:
669
-			if (a->p1_type!=STR_ST){
669
+			if (a->val[0].type!=STR_ST){
670 670
 				LOG(L_CRIT, "BUG: do_action: bad set_advertised_port() "
671
-						"type %d\n", a->p1_type);
671
+						"type %d\n", a->val[0].type);
672 672
 				ret=E_BUG;
673 673
 				break;
674 674
 			}
675
-			msg->set_global_port=*((str*)a->p1.data);
675
+			msg->set_global_port=*((str*)a->val[0].u.data);
676 676
 			ret=1; /* continue processing */
677 677
 			break;
678 678
 #ifdef USE_TCP
... ...
@@ -682,16 +683,16 @@ int do_action(struct action* a, struct sip_msg* msg)
682 682
 					|| msg->rcv.proto==PROTO_TLS
683 683
 #endif
684 684
 			   ){
685
-				
686
-				if (a->p1_type==NOSUBTYPE)	port=msg->via1->port;
687
-				else if (a->p1_type==NUMBER_ST) port=(int)a->p1.number;
685
+
686
+				if (a->val[0].type==NOSUBTYPE)	port=msg->via1->port;
687
+				else if (a->val[0].type==NUMBER_ST) port=(int)a->val[0].u.number;
688 688
 				else{
689 689
 					LOG(L_CRIT, "BUG: do_action: bad force_tcp_alias"
690
-							" port type %d\n", a->p1_type);
690
+							" port type %d\n", a->val[0].type);
691 691
 					ret=E_BUG;
692 692
 					break;
693 693
 				}
694
-						
694
+
695 695
 				if (tcpconn_add_alias(msg->rcv.proto_reserved1, port,
696 696
 									msg->rcv.proto)!=0){
697 697
 					LOG(L_ERR, " ERROR: receive_msg: tcp alias failed\n");
... ...
@@ -703,45 +704,45 @@ int do_action(struct action* a, struct sip_msg* msg)
703 703
 			ret=1; /* continue processing */
704 704
 			break;
705 705
 		case FORCE_SEND_SOCKET_T:
706
-			if (a->p1_type!=SOCKETINFO_ST){
706
+			if (a->val[0].type!=SOCKETINFO_ST){
707 707
 				LOG(L_CRIT, "BUG: do_action: bad force_send_socket argument"
708
-						" type: %d\n", a->p1_type);
708
+						" type: %d\n", a->val[0].type);
709 709
 				ret=E_BUG;
710 710
 				break;
711 711
 			}
712
-			msg->force_send_socket=(struct socket_info*)a->p1.data;
712
+			msg->force_send_socket=(struct socket_info*)a->val[0].u.data;
713 713
 			ret=1; /* continue processing */
714 714
 			break;
715 715
 
716 716
 	        case ADD_T:
717 717
 	        case ASSIGN_T:
718
-		
718
+
719 719
 			/* If the left attr was specified withou indexing brackets delete
720 720
 			 * existing AVPs before adding new ones
721 721
 			 */
722
-			if ((a->p1.attr->type & AVP_INDEX_ALL) != AVP_INDEX_ALL) delete_avp(a->p1.attr->type, a->p1.attr->name);
723
-			
724
-			if (a->p2_type == STRING_ST) {
725
-				value.s = a->p2.str;
726
-				flags = a->p1.attr->type | AVP_VAL_STR;
727
-				name = a->p1.attr->name;
722
+			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);
723
+
724
+			if (a->val[1].type == STRING_ST) {
725
+				value.s = a->val[1].u.str;
726
+				flags = a->val[0].u.attr->type | AVP_VAL_STR;
727
+				name = a->val[0].u.attr->name;
728 728
 				ret = 1;
729
-			} else if (a->p2_type == NUMBER_ST) {
730
-				value.n = a->p2.number;
731
-				flags = a->p1.attr->type;
732
-				name = a->p1.attr->name;
729
+			} else if (a->val[1].type == NUMBER_ST) {
730
+				value.n = a->val[1].u.number;
731
+				flags = a->val[0].u.attr->type;
732
+				name = a->val[0].u.attr->name;
733 733
 				ret = 1;
734
-			} else if (a->p2_type == ACTION_ST) {
735
-				flags = a->p1.attr->type;
736
-				name = a->p1.attr->name;
737
-				if (a->p2.data) {
738
-					value.n = run_actions((struct action*)a->p2.data, msg);
734
+			} else if (a->val[1].type == ACTION_ST) {
735
+				flags = a->val[0].u.attr->type;
736
+				name = a->val[0].u.attr->name;
737
+				if (a->val[1].u.data) {
738
+					value.n = run_actions((struct action*)a->val[1].u.data, msg);
739 739
 				} else {
740 740
 					value.n = -1;
741 741
 				}
742 742
 				ret = value.n;
743
-			} else if(a->p2_type == EXPR_ST && a->p2.data) {
744
-				v = eval_expr((struct expr*)a->p2.data, msg);
743
+			} else if(a->val[1].type == EXPR_ST && a->val[1].u.data) {
744
+				v = eval_expr((struct expr*)a->val[1].u.data, msg);
745 745
 				if (v < 0) {
746 746
 					if (v == EXPR_DROP){ /* hack to quit on DROP*/
747 747
 						ret = 0;
... ...
@@ -750,55 +751,55 @@ int do_action(struct action* a, struct sip_msg* msg)
750 750
 						LOG(L_WARN,"WARNING: do_action: error in expression\n");
751 751
 					}
752 752
 				}
753
-				
754
-				flags = a->p1.attr->type;
755
-				name = a->p1.attr->name;
753
+
754
+				flags = a->val[0].u.attr->type;
755
+				name = a->val[0].u.attr->name;
756 756
 				value.n = v;
757
-			} else if (a->p2_type == AVP_ST) {
757
+			} else if (a->val[1].type == AVP_ST) {
758 758
 				struct search_state st;
759
-				avp_t* avp; 
759
+				avp_t* avp;
760 760
 				avp_t* avp_mark;
761
-				
761
+
762 762
 				avp_mark = NULL;
763
-				if ((a->p2.attr->type & AVP_INDEX_ALL) == AVP_INDEX_ALL) {
764
-					avp = search_first_avp(a->p2.attr->type, a->p2.attr->name, &value, &st);
763
+				if ((a->val[1].u.attr->type & AVP_INDEX_ALL) == AVP_INDEX_ALL) {
764
+					avp = search_first_avp(a->val[1].u.attr->type, a->val[1].u.attr->name, &value, &st);
765 765
 					while(avp) {
766 766
 						     /* We take only the type of value and name from the source avp
767 767
 						      * and reset class and track flags
768 768
 						      */
769
-						flags = (a->p1.attr->type & ~AVP_INDEX_ALL) | (avp->flags & ~(AVP_CLASS_ALL|AVP_TRACK_ALL));
770
-						
771
-						if (add_avp_before(avp_mark, flags, a->p1.attr->name, value) < 0) {
769
+						flags = (a->val[0].u.attr->type & ~AVP_INDEX_ALL) | (avp->flags & ~(AVP_CLASS_ALL|AVP_TRACK_ALL));
770
+
771
+						if (add_avp_before(avp_mark, flags, a->val[0].u.attr->name, value) < 0) {
772 772
 							LOG(L_CRIT, "ERROR: Failed to assign value to attribute\n");
773 773
 							ret=E_UNSPEC;
774 774
 							break;
775 775
 						}
776
-						
776
+
777 777
 						/* move the mark, so the next found AVP will come before the one currently added
778 778
 						 * so they will have the same order as in the source list
779 779
 						 */
780 780
 						if (avp_mark) {
781 781
 							avp_mark=avp_mark->next;
782 782
 						} else {
783
-							avp_mark=search_first_avp(flags, a->p1.attr->name, NULL, NULL);
783
+							avp_mark=search_first_avp(flags, a->val[0].u.attr->name, NULL, NULL);
784 784
 						}
785
-							
785
+
786 786
 						avp = search_next_avp(&st, &value);
787 787
 					}
788 788
 					ret = 1;
789 789
 					break;
790 790
 				} else {
791
-					avp = search_avp_by_index(a->p2.attr->type, a->p2.attr->name, &value, a->p2.attr->index);
791
+					avp = search_avp_by_index(a->val[1].u.attr->type, a->val[1].u.attr->name, &value, a->val[1].u.attr->index);
792 792
 					if (avp) {
793
-						flags = a->p1.attr->type | (avp->flags & ~(AVP_CLASS_ALL|AVP_TRACK_ALL));
793
+						flags = a->val[0].u.attr->type | (avp->flags & ~(AVP_CLASS_ALL|AVP_TRACK_ALL));
794 794
 					} else {
795 795
 						ret = E_UNSPEC;
796 796
 						break;
797 797
 					}
798 798
 				}
799
-			} else if (a->p2_type == SELECT_ST) {
799
+			} else if (a->val[1].type == SELECT_ST) {
800 800
 				int r;
801
-				r = run_select(&value.s, a->p2.select, msg);
801
+				r = run_select(&value.s, a->val[1].u.select, msg);
802 802
 				if (r < 0) {
803 803
 					ret=E_UNSPEC;
804 804
 					break;
... ...
@@ -807,8 +808,8 @@ int do_action(struct action* a, struct sip_msg* msg)
807 807
 					value.s.len = 0;
808 808
 				}
809 809
 
810
-				flags = a->p1.attr->type | AVP_VAL_STR;
811
-				name = a->p1.attr->name;
810
+				flags = a->val[0].u.attr->type | AVP_VAL_STR;
811
+				name = a->val[0].u.attr->name;
812 812
 				ret = 1;
813 813
 			} else {
814 814
 				LOG(L_CRIT, "BUG: do_action: Bad right side of avp assignment\n");
... ...
@@ -831,7 +832,7 @@ int do_action(struct action* a, struct sip_msg* msg)
831 831
 	}
832 832
 /*skip:*/
833 833
 	return ret;
834
-	
834
+
835 835
 error_uri:
836 836
 	LOG(L_ERR, "ERROR: do_action: set*: uri too long\n");
837 837
 	if (new_uri) pkg_free(new_uri);
... ...
@@ -869,9 +870,9 @@ int run_actions(struct action* a, struct sip_msg* msg)
869 869
 			goto end;
870 870
 		}
871 871
 	}
872
-		
872
+
873 873
 	if (a==0){
874
-		LOG(L_ERR, "WARNING: run_actions: null action list (rec_level=%d)\n", 
874
+		LOG(L_ERR, "WARNING: run_actions: null action list (rec_level=%d)\n",
875 875
 			rec_lev);
876 876
 		ret=0;
877 877
 	}
... ...
@@ -887,18 +888,18 @@ int run_actions(struct action* a, struct sip_msg* msg)
887 887
 		}
888 888
 		/* ignore error returns */
889 889
 	}
890
-	
890
+
891 891
 	rec_lev--;
892 892
 end:
893 893
 	/* process module onbreak handlers if present */
894
-	if (rec_lev==0 && ret==0) 
895
-		for (mod=modules;mod;mod=mod->next) 
894
+	if (rec_lev==0 && ret==0)
895
+		for (mod=modules;mod;mod=mod->next)
896 896
 			if (mod->exports && mod->exports->onbreak_f) {
897 897
 				mod->exports->onbreak_f( msg );
898 898
 				DBG("DEBUG: %s onbreak handler called\n", mod->exports->name);
899 899
 			}
900 900
 	return ret;
901
-	
901
+
902 902
 
903 903
 error:
904 904
 	rec_lev--;
... ...
@@ -117,7 +117,6 @@ extern int yylex();
117 117
 static void yyerror(char* s);
118 118
 static char* tmp;
119 119
 static int i_tmp;
120
-static void* f_tmp;
121 120
 static struct socket_id* lst_tmp;
122 121
 static int rt;  /* Type of route block for find_export */
123 122
 static str* str_tmp;
... ...
@@ -126,7 +125,7 @@ static struct ip_addr* ip_tmp;
126 126
 static struct avp_spec* s_attr;
127 127
 static select_t sel;
128 128
 static select_t* sel_ptr;
129
-
129
+static struct action *mod_func_action;
130 130
 
131 131
 static void warn(char* s);
132 132
 static struct socket_id* mk_listen_id(char*, int, int);
... ...
@@ -349,1700 +348,1282 @@ static struct socket_id* mk_listen_id(char*, int, int);
349 349
   %type <route_el> rule;
350 350
 */
351 351
 
352
-
353
-
354 352
 %%
355 353
 
356 354
 
357
-cfg:	statements
355
+cfg:
356
+	statements
358 357
 	;
359
-
360
-statements:	statements statement {}
361
-		| statement {}
362
-		| statements error { yyerror(""); YYABORT;}
358
+statements:
359
+	statements statement {}
360
+	| statement {}
361
+	| statements error { yyerror(""); YYABORT;}
363 362
 	;
364
-
365
-statement:	assign_stm
366
-		| module_stm
367
-		| {rt=REQUEST_ROUTE;} route_stm
368
-		| {rt=FAILURE_ROUTE;} failure_route_stm
369
-		| {rt=ONREPLY_ROUTE;} onreply_route_stm
370
-		| {rt=BRANCH_ROUTE;} branch_route_stm
371
-		| {rt=ONSEND_ROUTE;}   send_route_stm
372
-		| SEMICOLON	/* null statement */
373
-		| CR	/* null statement*/
363
+statement:
364
+	assign_stm
365
+	| module_stm
366
+	| {rt=REQUEST_ROUTE;} route_stm
367
+	| {rt=FAILURE_ROUTE;} failure_route_stm
368
+	| {rt=ONREPLY_ROUTE;} onreply_route_stm
369
+	| {rt=BRANCH_ROUTE;} branch_route_stm
370
+	| {rt=ONSEND_ROUTE;}   send_route_stm
371
+	| SEMICOLON	/* null statement */
372
+	| CR	/* null statement*/
374 373
 	;
375
-
376
-listen_id:	ip			{	tmp=ip_addr2a($1);
377
-		 					if(tmp==0){
378
-								LOG(L_CRIT, "ERROR: cfg. parser: bad ip "
379
-										"address.\n");
380
-								$$=0;
381
-							}else{
382
-								$$=pkg_malloc(strlen(tmp)+1);
383
-								if ($$==0){
384
-									LOG(L_CRIT, "ERROR: cfg. parser: out of "
385
-											"memory.\n");
386
-								}else{
387
-									strncpy($$, tmp, strlen(tmp)+1);
388
-								}
389
-							}
390
-						}
391
-		 |	STRING			{	$$=pkg_malloc(strlen($1)+1);
392
-		 					if ($$==0){
393
-									LOG(L_CRIT, "ERROR: cfg. parser: out of "
394
-											"memory.\n");
395
-							}else{
396
-									strncpy($$, $1, strlen($1)+1);
397
-							}
398
-						}
399
-		 |	host		{	$$=pkg_malloc(strlen($1)+1);
400
-		 					if ($$==0){
401
-									LOG(L_CRIT, "ERROR: cfg. parser: out of "
402
-											"memory.\n");
403
-							}else{
404
-									strncpy($$, $1, strlen($1)+1);
405
-							}
406
-						}
374
+listen_id:
375
+	ip {
376
+		tmp=ip_addr2a($1);
377
+		if (tmp==0) {
378
+			LOG(L_CRIT, "ERROR: cfg. parser: bad ip "
379
+					"address.\n");
380
+			$$=0;
381
+		} else {
382
+			$$=pkg_malloc(strlen(tmp)+1);
383
+			if ($$==0) {
384
+				LOG(L_CRIT, "ERROR: cfg. parser: out of "
385
+						"memory.\n");
386
+			} else {
387
+				strncpy($$, tmp, strlen(tmp)+1);
388
+			}
389
+		}
390
+	}
391
+	| STRING {
392
+		$$=pkg_malloc(strlen($1)+1);
393
+		if ($$==0) {
394
+				LOG(L_CRIT, "ERROR: cfg. parser: out of "
395
+						"memory.\n");
396
+		} else {
397
+				strncpy($$, $1, strlen($1)+1);
398
+		}
399
+	}
400
+	| host {
401
+		$$=pkg_malloc(strlen($1)+1);
402
+		if ($$==0) {
403
+				LOG(L_CRIT, "ERROR: cfg. parser: out of "
404
+						"memory.\n");
405
+		} else {
406
+				strncpy($$, $1, strlen($1)+1);
407
+		}
408
+	}
407 409
 	;
408
-
409
-proto:	  UDP	{ $$=PROTO_UDP; }
410
-		| TCP	{ $$=PROTO_TCP; }
411
-		| TLS	{ $$=PROTO_TLS; }
412
-		| STAR	{ $$=0; }
413
-		;
414
-
415
-port:	  NUMBER	{ $$=$1; }
416
-		| STAR		{ $$=0; }
410
+proto:
411
+	UDP	{ $$=PROTO_UDP; }
412
+	| TCP	{ $$=PROTO_TCP; }
413
+	| TLS	{ $$=PROTO_TLS; }
414
+	| STAR	{ $$=0; }
415
+	;
416
+port:
417
+	NUMBER	{ $$=$1; }
418
+	| STAR	{ $$=0; }
417 419
 ;
418
-
419
-phostport:	listen_id				{ $$=mk_listen_id($1, 0, 0); }
420
-			| listen_id COLON port	{ $$=mk_listen_id($1, 0, $3); }
421
-			| proto COLON listen_id	{ $$=mk_listen_id($3, $1, 0); }
422
-			| proto COLON listen_id COLON port	{ $$=mk_listen_id($3, $1, $5);}
423
-			| listen_id COLON error { $$=0; yyerror(" port number expected"); }
424
-			;
425
-
426
-id_lst:		phostport		{  $$=$1 ; }
427
-		| phostport id_lst	{ $$=$1; $$->next=$2; }
428
-		;
429
-
430
-
431
-assign_stm:	DEBUG_V EQUAL NUMBER { debug=$3; }
432
-		| DEBUG_V EQUAL error  { yyerror("number  expected"); }
433
-		| FORK  EQUAL NUMBER { dont_fork= ! $3; }
434
-		| FORK  EQUAL error  { yyerror("boolean value expected"); }
435
-		| LOGSTDERROR EQUAL NUMBER { if (!config_check) log_stderr=$3; }
436
-		| LOGSTDERROR EQUAL error { yyerror("boolean value expected"); }
437
-		| LOGFACILITY EQUAL ID {
438
-					if ( (i_tmp=str2facility($3))==-1)
439
-						yyerror("bad facility (see syslog(3) man page)");
440
-					if (!config_check)
441
-						log_facility=i_tmp;
442
-									}
443
-		| LOGFACILITY EQUAL error { yyerror("ID expected"); }
444
-		| DNS EQUAL NUMBER   { received_dns|= ($3)?DO_DNS:0; }
445
-		| DNS EQUAL error { yyerror("boolean value expected"); }
446
-		| REV_DNS EQUAL NUMBER { received_dns|= ($3)?DO_REV_DNS:0; }
447
-		| REV_DNS EQUAL error { yyerror("boolean value expected"); }
448
-		| DNS_TRY_IPV6 EQUAL NUMBER   { dns_try_ipv6=$3; }
449
-		| DNS_TRY_IPV6 error { yyerror("boolean value expected"); }
450
-		| DNS_RETR_TIME EQUAL NUMBER   { dns_retr_time=$3; }
451
-		| DNS_RETR_TIME error { yyerror("number expected"); }
452
-		| DNS_RETR_NO EQUAL NUMBER   { dns_retr_no=$3; }
453
-		| DNS_RETR_NO error { yyerror("number expected"); }
454
-		| DNS_SERVERS_NO EQUAL NUMBER   { dns_servers_no=$3; }
455
-		| DNS_SERVERS_NO error { yyerror("number expected"); }
456
-		| DNS_USE_SEARCH EQUAL NUMBER   { dns_search_list=$3; }
457
-		| DNS_USE_SEARCH error { yyerror("boolean value expected"); }
458
-		| PORT EQUAL NUMBER   { port_no=$3; }
459
-		| STAT EQUAL STRING {
460
-					#ifdef STATS
461
-							stat_file=$3;
462
-					#endif
463
-							}
464
-		| MAXBUFFER EQUAL NUMBER { maxbuffer=$3; }
465
-		| MAXBUFFER EQUAL error { yyerror("number expected"); }
466
-		| PORT EQUAL error    { yyerror("number expected"); }
467
-		| CHILDREN EQUAL NUMBER { children_no=$3; }
468
-		| CHILDREN EQUAL error { yyerror("number expected"); }
469
-		| CHECK_VIA EQUAL NUMBER { check_via=$3; }
470
-		| CHECK_VIA EQUAL error { yyerror("boolean value expected"); }
471
-		| SYN_BRANCH EQUAL NUMBER { syn_branch=$3; }
472
-		| SYN_BRANCH EQUAL error { yyerror("boolean value expected"); }
473
-		| MEMLOG EQUAL NUMBER { memlog=$3; }
474
-		| MEMLOG EQUAL error { yyerror("int value expected"); }
475
-		| SIP_WARNING EQUAL NUMBER { sip_warning=$3; }
476
-		| SIP_WARNING EQUAL error { yyerror("boolean value expected"); }
477
-		| USER EQUAL STRING     { user=$3; }
478
-		| USER EQUAL ID         { user=$3; }
479
-		| USER EQUAL error      { yyerror("string value expected"); }
480
-		| GROUP EQUAL STRING     { group=$3; }
481
-		| GROUP EQUAL ID         { group=$3; }
482
-		| GROUP EQUAL error      { yyerror("string value expected"); }
483
-		| CHROOT EQUAL STRING     { chroot_dir=$3; }
484
-		| CHROOT EQUAL ID         { chroot_dir=$3; }
485
-		| CHROOT EQUAL error      { yyerror("string value expected"); }
486
-		| WDIR EQUAL STRING     { working_dir=$3; }
487
-		| WDIR EQUAL ID         { working_dir=$3; }
488
-		| WDIR EQUAL error      { yyerror("string value expected"); }
489
-		| MHOMED EQUAL NUMBER { mhomed=$3; }
490
-		| MHOMED EQUAL error { yyerror("boolean value expected"); }
491
-		| DISABLE_TCP EQUAL NUMBER {
492
-									#ifdef USE_TCP
493
-										tcp_disable=$3;
494
-									#else
495
-										warn("tcp support not compiled in");
496
-									#endif
497
-									}
498
-		| DISABLE_TCP EQUAL error { yyerror("boolean value expected"); }
499
-		| TCP_ACCEPT_ALIASES EQUAL NUMBER {
500
-									#ifdef USE_TCP
501
-										tcp_accept_aliases=$3;
502
-									#else
503
-										warn("tcp support not compiled in");
504
-									#endif
505
-									}
506
-		| TCP_ACCEPT_ALIASES EQUAL error { yyerror("boolean value expected"); }
507
-		| TCP_CHILDREN EQUAL NUMBER {
508
-									#ifdef USE_TCP
509
-										tcp_children_no=$3;
510
-									#else
511
-										warn("tcp support not compiled in");
512
-									#endif
513
-									}
514
-		| TCP_CHILDREN EQUAL error { yyerror("number expected"); }
515
-		| TCP_CONNECT_TIMEOUT EQUAL NUMBER {
516
-									#ifdef USE_TCP
517
-										tcp_connect_timeout=$3;
518
-									#else
519
-										warn("tcp support not compiled in");
520
-									#endif
521
-									}
522
-		| TCP_CONNECT_TIMEOUT EQUAL error { yyerror("number expected"); }
523
-		| TCP_SEND_TIMEOUT EQUAL NUMBER {
524
-									#ifdef USE_TCP
525
-										tcp_send_timeout=$3;
526
-									#else
527
-										warn("tcp support not compiled in");
528
-									#endif
529
-									}
530
-		| TCP_SEND_TIMEOUT EQUAL error { yyerror("number expected"); }
531
-		| TCP_CON_LIFETIME EQUAL NUMBER {
532
-									#ifdef USE_TCP
533
-										tcp_con_lifetime=$3;
534
-									#else
535
-										warn("tcp support not compiled in");
536
-									#endif
537
-									}
538
-		| TCP_CON_LIFETIME EQUAL error { yyerror("number expected"); }
539
-		| TCP_POLL_METHOD EQUAL ID {
540
-									#ifdef USE_TCP
541
-										tcp_poll_method=get_poll_type($3);
542
-										if (tcp_poll_method==POLL_NONE){
543
-											LOG(L_CRIT, "bad poll method name:"
544
-													" %s\n, try one of %s.\n",
545
-													$3, poll_support);
546
-											yyerror("bad tcp_poll_method "
547
-													"value");
548
-										}
549
-									#else
550
-										warn("tcp support not compiled in");
551
-									#endif
552
-									}
553
-		| TCP_POLL_METHOD EQUAL STRING {
554
-									#ifdef USE_TCP
555
-										tcp_poll_method=get_poll_type($3);
556
-										if (tcp_poll_method==POLL_NONE){
557
-											LOG(L_CRIT, "bad poll method name:"
558
-													" %s\n, try one of %s.\n",
559
-													$3, poll_support);
560
-											yyerror("bad tcp_poll_method "
561
-													"value");
562
-										}
563
-									#else
564
-										warn("tcp support not compiled in");
565
-									#endif
566
-									}
567
-		| TCP_POLL_METHOD EQUAL error { yyerror("poll method name expected"); }
568
-		| TCP_MAX_CONNECTIONS EQUAL NUMBER {
569
-									#ifdef USE_TCP
570
-										tcp_max_connections=$3;
571
-									#else
572
-										warn("tcp support not compiled in");
573
-									#endif
574
-									}
575
-		| TCP_MAX_CONNECTIONS EQUAL error { yyerror("number expected"); }
576
-		| DISABLE_TLS EQUAL NUMBER {
577
-									#ifdef USE_TLS
578
-										tls_disable=$3;
579
-									#else
580
-										warn("tls support not compiled in");
581
-									#endif
582
-									}
583
-		| DISABLE_TLS EQUAL error { yyerror("boolean value expected"); }
584
-		| TLSLOG EQUAL NUMBER 		{
585
-									#ifdef USE_TLS
586
-										tls_log=$3;
587
-									#else
588
-										warn("tls support not compiled in");
589
-									#endif
590
-									}
591
-		| TLSLOG EQUAL error { yyerror("int value expected"); }
592
-		| TLS_PORT_NO EQUAL NUMBER {
593
-									#ifdef USE_TLS
594
-										tls_port_no=$3;
595
-									#else
596
-										warn("tls support not compiled in");
597
-									#endif
598
-									}
599
-		| TLS_PORT_NO EQUAL error { yyerror("number expected"); }
600
-		| TLS_METHOD EQUAL SSLv23 {
601
-									#ifdef USE_TLS
602
-										tls_method=TLS_USE_SSLv23;
603
-									#else
604
-										warn("tls support not compiled in");
605
-									#endif
606
-									}
607
-		| TLS_METHOD EQUAL SSLv2 {
608
-									#ifdef USE_TLS
609
-										tls_method=TLS_USE_SSLv2;
610
-									#else
611
-										warn("tls support not compiled in");
612
-									#endif
613
-									}
614
-		| TLS_METHOD EQUAL SSLv3 {
615
-									#ifdef USE_TLS
616
-										tls_method=TLS_USE_SSLv3;
617
-									#else
618
-										warn("tls support not compiled in");
619
-									#endif
620
-									}
621
-		| TLS_METHOD EQUAL TLSv1 {
622
-									#ifdef USE_TLS
623
-										tls_method=TLS_USE_TLSv1;
624
-									#else
625
-										warn("tls support not compiled in");
626
-									#endif
627
-									}
628
-		| TLS_METHOD EQUAL error {
629
-									#ifdef USE_TLS
630
-										yyerror("SSLv23, SSLv2, SSLv3 or TLSv1"
631
-													" expected");
632
-									#else
633
-										warn("tls support not compiled in");
634
-									#endif
635
-									}
636
-
637
-		| TLS_VERIFY EQUAL NUMBER {
638
-									#ifdef USE_TLS
639
-										tls_verify_cert=$3;
640
-									#else
641
-										warn("tls support not compiled in");
642
-									#endif
643
-									}
644
-		| TLS_VERIFY EQUAL error { yyerror("boolean value expected"); }
645
-		| TLS_REQUIRE_CERTIFICATE EQUAL NUMBER {
646
-									#ifdef USE_TLS
647
-										tls_require_cert=$3;
648
-									#else
649
-										warn( "tls support not compiled in");
650
-									#endif
651
-									}
652
-		| TLS_REQUIRE_CERTIFICATE EQUAL error { yyerror("boolean value"
653
-																" expected"); }
654
-		| TLS_CERTIFICATE EQUAL STRING {
655
-									#ifdef USE_TLS
656
-											tls_cert_file=$3;
657
-									#else
658
-										warn("tls support not compiled in");
659
-									#endif
660
-									}
661
-		| TLS_CERTIFICATE EQUAL error { yyerror("string value expected"); }
662
-		| TLS_PRIVATE_KEY EQUAL STRING {
663
-									#ifdef USE_TLS
664
-											tls_pkey_file=$3;
665
-									#else
666
-										warn("tls support not compiled in");
667
-									#endif
668
-									}
669
-		| TLS_PRIVATE_KEY EQUAL error { yyerror("string value expected"); }
670
-		| TLS_CA_LIST EQUAL STRING {
671
-									#ifdef USE_TLS
672
-											tls_ca_file=$3;
673
-									#else
674
-										warn("tls support not compiled in");
675
-									#endif
676
-									}
677
-		| TLS_CA_LIST EQUAL error { yyerror("string value expected"); }
678
-		| TLS_HANDSHAKE_TIMEOUT EQUAL NUMBER {
679
-									#ifdef USE_TLS
680
-										tls_handshake_timeout=$3;
681
-									#else
682
-										warn("tls support not compiled in");
683
-									#endif
684
-									}
685
-		| TLS_HANDSHAKE_TIMEOUT EQUAL error { yyerror("number expected"); }
686
-		| TLS_SEND_TIMEOUT EQUAL NUMBER {
687
-									#ifdef USE_TLS
688
-										tls_send_timeout=$3;
689
-									#else
690
-										warn("tls support not compiled in");
691
-									#endif
692
-									}
693
-		| TLS_SEND_TIMEOUT EQUAL error { yyerror("number expected"); }
694
-		| SERVER_SIGNATURE EQUAL NUMBER { server_signature=$3; }
695
-		| SERVER_SIGNATURE EQUAL error { yyerror("boolean value expected"); }
696
-		| REPLY_TO_VIA EQUAL NUMBER { reply_to_via=$3; }
697
-		| REPLY_TO_VIA EQUAL error { yyerror("boolean value expected"); }
698
-		| LISTEN EQUAL id_lst {
699
-							for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next){
700
-								if (add_listen_iface(	lst_tmp->name,
701
-														lst_tmp->port,
702
-														lst_tmp->proto,
703
-														0
704
-													)!=0){
705
-									LOG(L_CRIT,  "ERROR: cfg. parser: failed"
706
-											" to add listen address\n");
707
-									break;
708
-								}
709
-							}
710
-							 }
711
-		| LISTEN EQUAL  error { yyerror("ip address or hostname"
712
-						"expected"); }
713
-		| ALIAS EQUAL  id_lst {
714
-							for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next)
715
-								add_alias(lst_tmp->name, strlen(lst_tmp->name),
716
-											lst_tmp->port, lst_tmp->proto);
717
-							  }
718
-		| ALIAS  EQUAL error  { yyerror(" hostname expected"); }
719
-		| ADVERTISED_ADDRESS EQUAL listen_id {
720
-								default_global_address.s=$3;
721
-								default_global_address.len=strlen($3);
722
-								}
723
-		|ADVERTISED_ADDRESS EQUAL error {yyerror("ip address or hostname "
724
-												"expected"); }
725
-		| ADVERTISED_PORT EQUAL NUMBER {
726
-								tmp=int2str($3, &i_tmp);
727
-								if ((default_global_port.s=pkg_malloc(i_tmp))
728
-										==0){
729
-										LOG(L_CRIT, "ERROR: cfg. parser:"
730
-													" out of memory.\n");
731
-										default_global_port.len=0;
732
-								}else{
733
-									default_global_port.len=i_tmp;
734
-									memcpy(default_global_port.s, tmp,
735
-											default_global_port.len);
736
-								};
737
-								}
738
-		|ADVERTISED_PORT EQUAL error {yyerror("ip address or hostname "
739
-												"expected"); }
740
-		| DISABLE_CORE EQUAL NUMBER {
741
-										disable_core_dump=$3;
742
-									}
743
-		| DISABLE_CORE EQUAL error { yyerror("boolean value expected"); }
744
-		| OPEN_FD_LIMIT EQUAL NUMBER {
745
-										open_files_limit=$3;
746
-									}
747
-		| OPEN_FD_LIMIT EQUAL error { yyerror("number expected"); }
748
-		| MCAST_LOOPBACK EQUAL NUMBER {
749
-								#ifdef USE_MCAST
750
-										mcast_loopback=$3;
751
-								#else
752
-									warn("no multicast support compiled in");
753
-								#endif
754
-		  }
755
-		| MCAST_LOOPBACK EQUAL error { yyerror("boolean value expected"); }
756
-		| MCAST_TTL EQUAL NUMBER {
757
-								#ifdef USE_MCAST
758
-										mcast_ttl=$3;
759
-								#else
760
-									warn("no multicast support compiled in");
761
-								#endif
762
-		  }
763
-		| MCAST_TTL EQUAL error { yyerror("number expected"); }
764
-		| TOS EQUAL NUMBER { tos=$3; }
765
-		| TOS EQUAL error { yyerror("number expected"); }
766
-		| error EQUAL { yyerror("unknown config variable"); }
420
+phostport:
421
+	listen_id		{ $$=mk_listen_id($1, 0, 0); }
422
+	| listen_id COLON port	{ $$=mk_listen_id($1, 0, $3); }
423
+	| proto COLON listen_id	{ $$=mk_listen_id($3, $1, 0); }
424
+	| proto COLON listen_id COLON port	{ $$=mk_listen_id($3, $1, $5);}
425
+	| listen_id COLON error { $$=0; yyerror(" port number expected"); }
767 426
 	;
768
-
769
-module_stm:	LOADMODULE STRING	{ DBG("loading module %s\n", $2);
770
-		  						  if (load_module($2)!=0){
771
-								  		yyerror("failed to load module");
772
-								  }
773
-								}
774
-		 | LOADMODULE error	{ yyerror("string expected");  }
775
-                 | MODPARAM LPAREN STRING COMMA STRING COMMA STRING RPAREN {
776
-			 if (set_mod_param_regex($3, $5, PARAM_STRING, $7) != 0) {
777
-				 yyerror("Can't set module parameter");
778
-			 }
779
-		   }
780
-                 | MODPARAM LPAREN STRING COMMA STRING COMMA NUMBER RPAREN {
781
-			 if (set_mod_param_regex($3, $5, PARAM_INT, (void*)$7) != 0) {
782
-				 yyerror("Can't set module parameter");
783
-			 }
784
-		   }
785
-                 | MODPARAM error { yyerror("Invalid arguments"); }
786
-		 ;
787
-
788
-
789
-ip:		 ipv4  { $$=$1; }
790
-		|ipv6  { $$=$1; }
791
-		;
792
-
793
-ipv4:	NUMBER DOT NUMBER DOT NUMBER DOT NUMBER {
794
-											$$=pkg_malloc(
795
-													sizeof(struct ip_addr));
796
-											if ($$==0){
797
-												LOG(L_CRIT, "ERROR: cfg. "
798
-													"parser: out of memory.\n"
799
-													);
800
-											}else{
801
-												memset($$, 0,
802
-													sizeof(struct ip_addr));
803
-												$$->af=AF_INET;
804
-												$$->len=4;
805
-												if (($1>255) || ($1<0) ||
806
-													($3>255) || ($3<0) ||
807
-													($5>255) || ($5<0) ||
808
-													($7>255) || ($7<0)){
809
-													yyerror("invalid ipv4"
810
-															"address");
811
-													$$->u.addr32[0]=0;
812
-													/* $$=0; */
813
-												}else{
814
-													$$->u.addr[0]=$1;
815
-													$$->u.addr[1]=$3;
816
-													$$->u.addr[2]=$5;
817
-													$$->u.addr[3]=$7;
818
-													/*
819
-													$$=htonl( ($1<<24)|
820
-													($3<<16)| ($5<<8)|$7 );
821
-													*/
822
-												}
823
-											}
824
-												}
427
+id_lst:
428
+	phostport		{  $$=$1 ; }
429
+	| phostport id_lst	{ $$=$1; $$->next=$2; }
825 430
 	;
826
-
827
-ipv6addr:	IPV6ADDR {
828
-					$$=pkg_malloc(sizeof(struct ip_addr));
829
-					if ($$==0){
830
-						LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
831
-					}else{
832
-						memset($$, 0, sizeof(struct ip_addr));
833
-						$$->af=AF_INET6;
834
-						$$->len=16;
835
-					#ifdef USE_IPV6
836
-						if (inet_pton(AF_INET6, $1, $$->u.addr)<=0){
837
-							yyerror("bad ipv6 address");
838
-						}
839
-					#else
840
-						yyerror("ipv6 address & no ipv6 support compiled in");
841
-						YYABORT;
842
-					#endif
843
-					}
844
-				}
431
+assign_stm:
432
+	DEBUG_V EQUAL NUMBER { debug=$3; }
433
+	| DEBUG_V EQUAL error  { yyerror("number  expected"); }
434
+	| FORK  EQUAL NUMBER { dont_fork= ! $3; }
435
+	| FORK  EQUAL error  { yyerror("boolean value expected"); }
436
+	| LOGSTDERROR EQUAL NUMBER { if (!config_check) log_stderr=$3; }
437
+	| LOGSTDERROR EQUAL error { yyerror("boolean value expected"); }
438
+	| LOGFACILITY EQUAL ID {
439
+		if ( (i_tmp=str2facility($3))==-1)
440
+			yyerror("bad facility (see syslog(3) man page)");
441
+		if (!config_check)
442
+			log_facility=i_tmp;
443
+	}
444
+	| LOGFACILITY EQUAL error { yyerror("ID expected"); }
445
+	| DNS EQUAL NUMBER   { received_dns|= ($3)?DO_DNS:0; }
446
+	| DNS EQUAL error { yyerror("boolean value expected"); }
447
+	| REV_DNS EQUAL NUMBER { received_dns|= ($3)?DO_REV_DNS:0; }
448
+	| REV_DNS EQUAL error { yyerror("boolean value expected"); }
449
+	| DNS_TRY_IPV6 EQUAL NUMBER   { dns_try_ipv6=$3; }
450
+	| DNS_TRY_IPV6 error { yyerror("boolean value expected"); }
451
+	| DNS_RETR_TIME EQUAL NUMBER   { dns_retr_time=$3; }
452
+	| DNS_RETR_TIME error { yyerror("number expected"); }
453
+	| DNS_RETR_NO EQUAL NUMBER   { dns_retr_no=$3; }
454
+	| DNS_RETR_NO error { yyerror("number expected"); }
455
+	| DNS_SERVERS_NO EQUAL NUMBER   { dns_servers_no=$3; }
456
+	| DNS_SERVERS_NO error { yyerror("number expected"); }
457
+	| DNS_USE_SEARCH EQUAL NUMBER   { dns_search_list=$3; }
458
+	| DNS_USE_SEARCH error { yyerror("boolean value expected"); }
459
+	| PORT EQUAL NUMBER   { port_no=$3; }
460
+	| STAT EQUAL STRING {
461
+		#ifdef STATS
462
+				stat_file=$3;
463
+		#endif
464
+	}
465
+	| MAXBUFFER EQUAL NUMBER { maxbuffer=$3; }
466
+	| MAXBUFFER EQUAL error { yyerror("number expected"); }
467
+	| PORT EQUAL error    { yyerror("number expected"); }
468
+	| CHILDREN EQUAL NUMBER { children_no=$3; }
469
+	| CHILDREN EQUAL error { yyerror("number expected"); }
470
+	| CHECK_VIA EQUAL NUMBER { check_via=$3; }
471
+	| CHECK_VIA EQUAL error { yyerror("boolean value expected"); }
472
+	| SYN_BRANCH EQUAL NUMBER { syn_branch=$3; }
473
+	| SYN_BRANCH EQUAL error { yyerror("boolean value expected"); }
474
+	| MEMLOG EQUAL NUMBER { memlog=$3; }
475
+	| MEMLOG EQUAL error { yyerror("int value expected"); }
476
+	| SIP_WARNING EQUAL NUMBER { sip_warning=$3; }
477
+	| SIP_WARNING EQUAL error { yyerror("boolean value expected"); }
478
+	| USER EQUAL STRING     { user=$3; }
479
+	| USER EQUAL ID         { user=$3; }
480
+	| USER EQUAL error      { yyerror("string value expected"); }
481
+	| GROUP EQUAL STRING     { group=$3; }
482
+	| GROUP EQUAL ID         { group=$3; }
483
+	| GROUP EQUAL error      { yyerror("string value expected"); }
484
+	| CHROOT EQUAL STRING     { chroot_dir=$3; }
485
+	| CHROOT EQUAL ID         { chroot_dir=$3; }
486
+	| CHROOT EQUAL error      { yyerror("string value expected"); }
487
+	| WDIR EQUAL STRING     { working_dir=$3; }
488
+	| WDIR EQUAL ID         { working_dir=$3; }
489
+	| WDIR EQUAL error      { yyerror("string value expected"); }
490
+	| MHOMED EQUAL NUMBER { mhomed=$3; }
491
+	| MHOMED EQUAL error { yyerror("boolean value expected"); }
492
+	| DISABLE_TCP EQUAL NUMBER {
493
+		#ifdef USE_TCP
494
+			tcp_disable=$3;
495
+		#else
496
+			warn("tcp support not compiled in");
497
+		#endif
498
+	}
499
+	| DISABLE_TCP EQUAL error { yyerror("boolean value expected"); }
500
+	| TCP_ACCEPT_ALIASES EQUAL NUMBER {
501
+		#ifdef USE_TCP
502
+			tcp_accept_aliases=$3;
503
+		#else
504
+			warn("tcp support not compiled in");
505
+		#endif
506
+	}
507
+	| TCP_ACCEPT_ALIASES EQUAL error { yyerror("boolean value expected"); }
508
+	| TCP_CHILDREN EQUAL NUMBER {
509
+		#ifdef USE_TCP
510
+			tcp_children_no=$3;
511
+		#else
512
+			warn("tcp support not compiled in");
513
+		#endif
514
+	}
515
+	| TCP_CHILDREN EQUAL error { yyerror("number expected"); }
516
+	| TCP_CONNECT_TIMEOUT EQUAL NUMBER {
517
+		#ifdef USE_TCP
518
+			tcp_connect_timeout=$3;
519
+		#else
520
+			warn("tcp support not compiled in");
521
+		#endif
522
+	}
523
+	| TCP_CONNECT_TIMEOUT EQUAL error { yyerror("number expected"); }
524
+	| TCP_SEND_TIMEOUT EQUAL NUMBER {
525
+		#ifdef USE_TCP
526
+			tcp_send_timeout=$3;
527
+		#else
528
+			warn("tcp support not compiled in");
529
+		#endif
530
+	}
531
+	| TCP_SEND_TIMEOUT EQUAL error { yyerror("number expected"); }
532
+	| TCP_CON_LIFETIME EQUAL NUMBER {
533
+		#ifdef USE_TCP
534
+			tcp_con_lifetime=$3;
535
+		#else
536
+			warn("tcp support not compiled in");
537
+		#endif
538
+	}
539
+	| TCP_CON_LIFETIME EQUAL error { yyerror("number expected"); }
540
+	| TCP_POLL_METHOD EQUAL ID {
541
+		#ifdef USE_TCP
542
+			tcp_poll_method=get_poll_type($3);
543
+			if (tcp_poll_method==POLL_NONE) {
544
+				LOG(L_CRIT, "bad poll method name:"
545
+						" %s\n, try one of %s.\n",
546
+						$3, poll_support);
547
+				yyerror("bad tcp_poll_method "
548
+						"value");
549
+			}
550
+		#else
551
+			warn("tcp support not compiled in");
552
+		#endif
553
+	}
554
+	| TCP_POLL_METHOD EQUAL STRING {
555
+		#ifdef USE_TCP
556
+			tcp_poll_method=get_poll_type($3);
557
+			if (tcp_poll_method==POLL_NONE) {
558
+				LOG(L_CRIT, "bad poll method name:"
559
+						" %s\n, try one of %s.\n",
560
+						$3, poll_support);
561
+				yyerror("bad tcp_poll_method "
562
+						"value");
563
+			}
564
+		#else
565
+			warn("tcp support not compiled in");
566
+		#endif
567