Browse code

posops: added posops_set_char() function

Daniel-Constantin Mierla authored on 07/11/2021 17:17:21
Showing 1 changed files
... ...
@@ -41,6 +41,7 @@ static void mod_destroy(void);
41 41
 static int w_posops_pos_append(sip_msg_t* msg, char* p1idx, char* p2val);
42 42
 static int w_posops_pos_insert(sip_msg_t* msg, char* p1idx, char* p2val);
43 43
 static int w_posops_pos_rm(sip_msg_t* msg, char* p1idx, char* p2len);
44
+static int w_posops_pos_set_char(sip_msg_t* msg, char* p1idx, char* p2val);
44 45
 static int w_posops_pos_headers_start(sip_msg_t* msg, char* p1, char* p2);
45 46
 static int w_posops_pos_headers_end(sip_msg_t* msg, char* p1, char* p2);
46 47
 static int w_posops_pos_body_start(sip_msg_t* msg, char* p1, char* p2);
... ...
@@ -83,6 +84,8 @@ static cmd_export_t cmds[]={
83 84
 		fixup_free_igp_spve, ANY_ROUTE},
84 85
 	{"pos_rm", (cmd_function)w_posops_pos_rm, 2, fixup_igp_igp,
85 86
 		fixup_free_igp_igp, ANY_ROUTE},
87
+	{"pos_set_char", (cmd_function)w_posops_pos_set_char, 2, fixup_igp_spve,
88
+		fixup_free_igp_spve, ANY_ROUTE},
86 89
 	{"pos_headers_start", (cmd_function)w_posops_pos_headers_start, 0, 0,
87 90
 		0, ANY_ROUTE},
88 91
 	{"pos_headers_end", (cmd_function)w_posops_pos_headers_end, 0, 0,
... ...
@@ -342,6 +345,56 @@ static int w_posops_pos_rm(sip_msg_t* msg, char* p1idx, char* p2len)
342 345
 	return ki_posops_pos_rm(msg, idx, len);
343 346
 }
344 347
 
348
+/**
349
+ *
350
+ */
351
+static int ki_posops_pos_set_char(sip_msg_t *msg, int idx, str *val)
352
+{
353
+	int offset;
354
+
355
+	posops_data_init();
356
+	if(val==NULL || val->s==NULL || val->len<=0) {
357
+		LM_ERR("invalid val parameter\n");
358
+		return -1;
359
+	}
360
+
361
+	if(idx<0) {
362
+		offset = msg->len + idx;
363
+	} else {
364
+		offset = idx;
365
+	}
366
+	if(offset>msg->len) {
367
+		LM_ERR("offset invalid: %d (msg-len: %d)\n", offset, msg->len);
368
+		return -1;
369
+	}
370
+
371
+	msg->buf[offset] = val->s[0];
372
+
373
+	return 1;
374
+}
375
+
376
+/**
377
+ *
378
+ */
379
+static int w_posops_pos_set_char(sip_msg_t* msg, char* p1idx, char* p2val)
380
+{
381
+	int idx = 0;
382
+	str val = STR_NULL;
383
+
384
+	posops_data_init();
385
+	if(fixup_get_ivalue(msg, (gparam_t*)p1idx, &idx)!=0) {
386
+		LM_ERR("unable to get idx parameter\n");
387
+		return -1;
388
+	}
389
+
390
+	if(fixup_get_svalue(msg, (gparam_t*)p2val, &val)!=0) {
391
+		LM_ERR("unable to get val parameter\n");
392
+		return -1;
393
+	}
394
+
395
+	return ki_posops_pos_set_char(msg, idx, &val);
396
+}
397
+
345 398
 /**
346 399
  *
347 400
  */
... ...
@@ -878,6 +931,11 @@ static sr_kemi_t sr_kemi_posops_exports[] = {
878 931
 		{ SR_KEMIP_INT, SR_KEMIP_INT, SR_KEMIP_NONE,
879 932
 			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
880 933
 	},
934
+	{ str_init("posops"), str_init("pos_set_char"),
935
+		SR_KEMIP_INT, ki_posops_pos_set_char,
936
+		{ SR_KEMIP_INT, SR_KEMIP_STR, SR_KEMIP_NONE,
937
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
938
+	},
881 939
 	{ str_init("posops"), str_init("pos_headers_start"),
882 940
 		SR_KEMIP_INT, ki_posops_pos_headers_start,
883 941
 		{ SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
Browse code

posops: safety check for change anchor

Daniel-Constantin Mierla authored on 29/10/2021 11:28:07
Showing 1 changed files
... ...
@@ -186,6 +186,10 @@ static int ki_posops_pos_append(sip_msg_t *msg, int idx, str *val)
186 186
 	}
187 187
 
188 188
 	anchor = anchor_lump(msg, offset, 0, 0);
189
+	if(anchor == NULL) {
190
+		LM_ERR("failed to create the anchor\n");
191
+		return -1;
192
+	}
189 193
 	if (insert_new_lump_after(anchor, val->s, val->len, 0) == 0) {
190 194
 		LM_ERR("unable to add lump\n");
191 195
 		return -1;
... ...
@@ -241,6 +245,10 @@ static int ki_posops_pos_insert(sip_msg_t *msg, int idx, str *val)
241 245
 	}
242 246
 
243 247
 	anchor = anchor_lump(msg, offset, 0, 0);
248
+	if(anchor == NULL) {
249
+		LM_ERR("failed to create the anchor\n");
250
+		return -1;
251
+	}
244 252
 	if (insert_new_lump_before(anchor, val->s, val->len, 0) == 0) {
245 253
 		LM_ERR("unable to add lump\n");
246 254
 		return -1;
Browse code

posops: set index relative to the buffer for search functions

Daniel-Constantin Mierla authored on 01/10/2021 06:43:22
Showing 1 changed files
... ...
@@ -684,7 +684,7 @@ static int ki_posops_pos_search_helper(sip_msg_t *msg, int idx, regex_t *re)
684 684
 		return -1;
685 685
 	}
686 686
 
687
-	_posops_data.idx = (int)(msg->buf + idx + pmatch.rm_so);
687
+	_posops_data.idx = idx + pmatch.rm_so;
688 688
 	_posops_data.ret = (_posops_data.idx==0)?posops_idx0:_posops_data.idx;
689 689
 	_posops_data.len = pmatch.rm_eo-pmatch.rm_so;
690 690
 
... ...
@@ -757,7 +757,7 @@ static int ki_posops_pos_rsearch_helper(sip_msg_t *msg, int idx, regex_t *re)
757 757
 		return -1;
758 758
 	}
759 759
 
760
-	_posops_data.idx = (int)(msg->buf + i + pmatch.rm_so);
760
+	_posops_data.idx = i + pmatch.rm_so;
761 761
 	_posops_data.ret = (_posops_data.idx==0)?posops_idx0:_posops_data.idx;
762 762
 	_posops_data.len = pmatch.rm_eo-pmatch.rm_so;
763 763
 
Browse code

posops: pos_rsearch() - search last occurence of a regex

Daniel-Constantin Mierla authored on 30/09/2021 06:43:08
Showing 1 changed files
... ...
@@ -50,6 +50,7 @@ static int w_posops_pos_findi_str(sip_msg_t* msg, char* p1idx, char* p2val);
50 50
 static int w_posops_pos_rfind_str(sip_msg_t* msg, char* p1idx, char* p2val);
51 51
 static int w_posops_pos_rfindi_str(sip_msg_t* msg, char* p1idx, char* p2val);
52 52
 static int w_posops_pos_search(sip_msg_t* msg, char* p1idx, char* p2re);
53
+static int w_posops_pos_rsearch(sip_msg_t* msg, char* p1idx, char* p2re);
53 54
 
54 55
 typedef struct posops_data {
55 56
 	int ret;
... ...
@@ -100,6 +101,8 @@ static cmd_export_t cmds[]={
100 101
 		fixup_free_igp_spve, ANY_ROUTE},
101 102
 	{"pos_search",    (cmd_function)w_posops_pos_search, 2, fixup_igp_regexp,
102 103
 		fixup_free_igp_regexp, ANY_ROUTE},
104
+	{"pos_rsearch",    (cmd_function)w_posops_pos_rsearch, 2, fixup_igp_regexp,
105
+		fixup_free_igp_regexp, ANY_ROUTE},
103 106
 
104 107
 	{0, 0, 0, 0, 0, 0}
105 108
 };
... ...
@@ -688,6 +691,9 @@ static int ki_posops_pos_search_helper(sip_msg_t *msg, int idx, regex_t *re)
688 691
 	return _posops_data.ret;
689 692
 }
690 693
 
694
+/**
695
+ *
696
+ */
691 697
 static int ki_posops_pos_search(sip_msg_t* msg, int idx, str* sre)
692 698
 {
693 699
 	regex_t mre;
... ...
@@ -725,6 +731,79 @@ static int w_posops_pos_search(sip_msg_t* msg, char* p1idx, char* p2re)
725 731
 	return ki_posops_pos_search_helper(msg, idx, re);
726 732
 }
727 733
 
734
+/**
735
+ *
736
+ */
737
+static int ki_posops_pos_rsearch_helper(sip_msg_t *msg, int idx, regex_t *re)
738
+{
739
+	regmatch_t pmatch;
740
+	int i;
741
+	int ret = -1;
742
+
743
+	if(idx<0) {
744
+		idx += msg->len;
745
+	}
746
+	if(idx<0 || idx >= msg->len) {
747
+		return -1;
748
+	}
749
+
750
+	for(i=msg->len-1; i>=idx; i--) {
751
+		ret = regexec(re, msg->buf + i, 1, &pmatch, 0);
752
+		if(ret==0) {
753
+			break;
754
+		}
755
+	}
756
+	if (ret!=0) {
757
+		return -1;
758
+	}
759
+
760
+	_posops_data.idx = (int)(msg->buf + i + pmatch.rm_so);
761
+	_posops_data.ret = (_posops_data.idx==0)?posops_idx0:_posops_data.idx;
762
+	_posops_data.len = pmatch.rm_eo-pmatch.rm_so;
763
+
764
+	return _posops_data.ret;
765
+}
766
+
767
+/**
768
+ *
769
+ */
770
+static int ki_posops_pos_rsearch(sip_msg_t* msg, int idx, str* sre)
771
+{
772
+	regex_t mre;
773
+	int ret;
774
+
775
+	posops_data_init();
776
+	memset(&mre, 0, sizeof(regex_t));
777
+	if (regcomp(&mre, sre->s, REG_EXTENDED|REG_ICASE|REG_NEWLINE)!=0) {
778
+		LM_ERR("failed to compile regex: %.*s\n", sre->len, sre->s);
779
+		return -1;
780
+	}
781
+
782
+	ret = ki_posops_pos_rsearch_helper(msg, idx, &mre);
783
+
784
+	regfree(&mre);
785
+
786
+	return ret;
787
+}
788
+
789
+/**
790
+ *
791
+ */
792
+static int w_posops_pos_rsearch(sip_msg_t* msg, char* p1idx, char* p2re)
793
+{
794
+	int idx = 0;
795
+	regex_t *re = NULL;
796
+
797
+	posops_data_init();
798
+	if(fixup_get_ivalue(msg, (gparam_t*)p1idx, &idx)!=0) {
799
+		LM_ERR("unable to get idx parameter\n");
800
+		return -1;
801
+	}
802
+	re = (regex_t*)p2re;
803
+
804
+	return ki_posops_pos_rsearch_helper(msg, idx, re);
805
+}
806
+
728 807
 /**
729 808
  *
730 809
  */
... ...
@@ -836,6 +915,11 @@ static sr_kemi_t sr_kemi_posops_exports[] = {
836 915
 		{ SR_KEMIP_INT, SR_KEMIP_STR, SR_KEMIP_NONE,
837 916
 			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
838 917
 	},
918
+	{ str_init("posops"), str_init("pos_rsearch"),
919
+		SR_KEMIP_INT, ki_posops_pos_rsearch,
920
+		{ SR_KEMIP_INT, SR_KEMIP_STR, SR_KEMIP_NONE,
921
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
922
+	},
839 923
 
840 924
 	{ {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
841 925
 };
Browse code

posops: init data structure for each function

Daniel-Constantin Mierla authored on 29/09/2021 07:32:50
Showing 1 changed files
... ...
@@ -149,6 +149,15 @@ static void mod_destroy(void)
149 149
 	return;
150 150
 }
151 151
 
152
+/**
153
+ *
154
+ */
155
+static void posops_data_init(void)
156
+{
157
+	memset(&_posops_data, 0, sizeof(posops_data_t));
158
+	_posops_data.ret = -1;
159
+}
160
+
152 161
 /**
153 162
  *
154 163
  */
... ...
@@ -157,6 +166,7 @@ static int ki_posops_pos_append(sip_msg_t *msg, int idx, str *val)
157 166
 	int offset;
158 167
 	sr_lump_t *anchor = NULL;
159 168
 
169
+	posops_data_init();
160 170
 	if(val==NULL || val->s==NULL || val->len<=0) {
161 171
 		LM_ERR("invalid val parameter\n");
162 172
 		return -1;
... ...
@@ -189,6 +199,7 @@ static int w_posops_pos_append(sip_msg_t* msg, char* p1idx, char* p2val)
189 199
 	int idx = 0;
190 200
 	str val = STR_NULL;
191 201
 
202
+	posops_data_init();
192 203
 	if(fixup_get_ivalue(msg, (gparam_t*)p1idx, &idx)!=0) {
193 204
 		LM_ERR("unable to get idx parameter\n");
194 205
 		return -1;
... ...
@@ -210,6 +221,7 @@ static int ki_posops_pos_insert(sip_msg_t *msg, int idx, str *val)
210 221
 	int offset;
211 222
 	sr_lump_t *anchor = NULL;
212 223
 
224
+	posops_data_init();
213 225
 	if(val==NULL || val->s==NULL || val->len<=0) {
214 226
 		LM_ERR("invalid val parameter\n");
215 227
 		return -1;
... ...
@@ -242,6 +254,7 @@ static int w_posops_pos_insert(sip_msg_t* msg, char* p1idx, char* p2val)
242 254
 	int idx = 0;
243 255
 	str val = STR_NULL;
244 256
 
257
+	posops_data_init();
245 258
 	if(fixup_get_ivalue(msg, (gparam_t*)p1idx, &idx)!=0) {
246 259
 		LM_ERR("unable to get idx parameter\n");
247 260
 		return -1;
... ...
@@ -264,6 +277,7 @@ static int ki_posops_pos_rm(sip_msg_t *msg, int idx, int len)
264 277
 	int offset;
265 278
 	sr_lump_t *anchor = NULL;
266 279
 
280
+	posops_data_init();
267 281
 	if(len<=0) {
268 282
 		LM_ERR("length invalid: %d (msg-len: %d)\n", len, msg->len);
269 283
 		return -1;
... ...
@@ -304,6 +318,7 @@ static int w_posops_pos_rm(sip_msg_t* msg, char* p1idx, char* p2len)
304 318
 	int idx = 0;
305 319
 	int len = 0;
306 320
 
321
+	posops_data_init();
307 322
 	if(fixup_get_ivalue(msg, (gparam_t*)p1idx, &idx)!=0) {
308 323
 		LM_ERR("unable to get idx parameter\n");
309 324
 		return -1;
... ...
@@ -321,7 +336,7 @@ static int w_posops_pos_rm(sip_msg_t* msg, char* p1idx, char* p2len)
321 336
  */
322 337
 static int ki_posops_pos_headers_start(sip_msg_t* msg)
323 338
 {
324
-	memset(&_posops_data, 0, sizeof(posops_data_t));
339
+	posops_data_init();
325 340
 	if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
326 341
 		LM_ERR("failed to parse headers\n");
327 342
 		return -1;
... ...
@@ -346,7 +361,7 @@ static int w_posops_pos_headers_start(sip_msg_t* msg, char* p1, char* p2)
346 361
  */
347 362
 static int ki_posops_pos_headers_end(sip_msg_t* msg)
348 363
 {
349
-	memset(&_posops_data, 0, sizeof(posops_data_t));
364
+	posops_data_init();
350 365
 	if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
351 366
 		LM_ERR("failed to parse headers\n");
352 367
 		return -1;
... ...
@@ -373,7 +388,7 @@ static int ki_posops_pos_body_start(sip_msg_t* msg)
373 388
 {
374 389
 	char *body = 0;
375 390
 
376
-	memset(&_posops_data, 0, sizeof(posops_data_t));
391
+	posops_data_init();
377 392
 	if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
378 393
 		LM_ERR("failed to parse headers\n");
379 394
 		return -1;
... ...
@@ -404,7 +419,7 @@ static int w_posops_pos_body_start(sip_msg_t* msg, char* p1, char* p2)
404 419
  */
405 420
 static int ki_posops_pos_body_end(sip_msg_t* msg)
406 421
 {
407
-	memset(&_posops_data, 0, sizeof(posops_data_t));
422
+	posops_data_init();
408 423
 	if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
409 424
 		LM_ERR("failed to parse headers\n");
410 425
 		return -1;
... ...
@@ -437,6 +452,7 @@ static int ki_posops_pos_find_str(sip_msg_t *msg, int idx, str *val)
437 452
 	char *p;
438 453
 	str text;
439 454
 
455
+	posops_data_init();
440 456
 	if(val==NULL || val->s==NULL || val->len<=0) {
441 457
 		return -1;
442 458
 	}
... ...
@@ -467,6 +483,7 @@ static int w_posops_pos_find_str(sip_msg_t* msg, char* p1idx, char* p2val)
467 483
 	int idx = 0;
468 484
 	str val = STR_NULL;
469 485
 
486
+	posops_data_init();
470 487
 	if(fixup_get_ivalue(msg, (gparam_t*)p1idx, &idx)!=0) {
471 488
 		LM_ERR("unable to get idx parameter\n");
472 489
 		return -1;
... ...
@@ -488,6 +505,7 @@ static int ki_posops_pos_findi_str(sip_msg_t *msg, int idx, str *val)
488 505
 	char *p;
489 506
 	str text;
490 507
 
508
+	posops_data_init();
491 509
 	if(val==NULL || val->s==NULL || val->len<=0) {
492 510
 		return -1;
493 511
 	}
... ...
@@ -519,6 +537,7 @@ static int w_posops_pos_findi_str(sip_msg_t* msg, char* p1idx, char* p2val)
519 537
 	int idx = 0;
520 538
 	str val = STR_NULL;
521 539
 
540
+	posops_data_init();
522 541
 	if(fixup_get_ivalue(msg, (gparam_t*)p1idx, &idx)!=0) {
523 542
 		LM_ERR("unable to get idx parameter\n");
524 543
 		return -1;
... ...
@@ -542,6 +561,7 @@ static int ki_posops_pos_rfind_str(sip_msg_t *msg, int idx, str *val)
542 561
 	char *p;
543 562
 	str text;
544 563
 
564
+	posops_data_init();
545 565
 	if(val==NULL || val->s==NULL || val->len<=0) {
546 566
 		return -1;
547 567
 	}
... ...
@@ -572,6 +592,7 @@ static int w_posops_pos_rfind_str(sip_msg_t* msg, char* p1idx, char* p2val)
572 592
 	int idx = 0;
573 593
 	str val = STR_NULL;
574 594
 
595
+	posops_data_init();
575 596
 	if(fixup_get_ivalue(msg, (gparam_t*)p1idx, &idx)!=0) {
576 597
 		LM_ERR("unable to get idx parameter\n");
577 598
 		return -1;
... ...
@@ -593,6 +614,7 @@ static int ki_posops_pos_rfindi_str(sip_msg_t *msg, int idx, str *val)
593 614
 	char *p;
594 615
 	str text;
595 616
 
617
+	posops_data_init();
596 618
 	if(val==NULL || val->s==NULL || val->len<=0) {
597 619
 		return -1;
598 620
 	}
... ...
@@ -624,6 +646,7 @@ static int w_posops_pos_rfindi_str(sip_msg_t* msg, char* p1idx, char* p2val)
624 646
 	int idx = 0;
625 647
 	str val = STR_NULL;
626 648
 
649
+	posops_data_init();
627 650
 	if(fixup_get_ivalue(msg, (gparam_t*)p1idx, &idx)!=0) {
628 651
 		LM_ERR("unable to get idx parameter\n");
629 652
 		return -1;
... ...
@@ -670,6 +693,7 @@ static int ki_posops_pos_search(sip_msg_t* msg, int idx, str* sre)
670 693
 	regex_t mre;
671 694
 	int ret;
672 695
 
696
+	posops_data_init();
673 697
 	memset(&mre, 0, sizeof(regex_t));
674 698
 	if (regcomp(&mre, sre->s, REG_EXTENDED|REG_ICASE|REG_NEWLINE)!=0) {
675 699
 		LM_ERR("failed to compile regex: %.*s\n", sre->len, sre->s);
... ...
@@ -691,6 +715,7 @@ static int w_posops_pos_search(sip_msg_t* msg, char* p1idx, char* p2re)
691 715
 	int idx = 0;
692 716
 	regex_t *re = NULL;
693 717
 
718
+	posops_data_init();
694 719
 	if(fixup_get_ivalue(msg, (gparam_t*)p1idx, &idx)!=0) {
695 720
 		LM_ERR("unable to get idx parameter\n");
696 721
 		return -1;
Browse code

posops: store len of matched string with search function

Daniel-Constantin Mierla authored on 29/09/2021 07:23:42
Showing 1 changed files
... ...
@@ -54,6 +54,7 @@ static int w_posops_pos_search(sip_msg_t* msg, char* p1idx, char* p2re);
54 54
 typedef struct posops_data {
55 55
 	int ret;
56 56
 	int idx;
57
+	int len;
57 58
 } posops_data_t;
58 59
 
59 60
 static int posops_idx0 = -255;
... ...
@@ -659,6 +660,7 @@ static int ki_posops_pos_search_helper(sip_msg_t *msg, int idx, regex_t *re)
659 660
 
660 661
 	_posops_data.idx = (int)(msg->buf + idx + pmatch.rm_so);
661 662
 	_posops_data.ret = (_posops_data.idx==0)?posops_idx0:_posops_data.idx;
663
+	_posops_data.len = pmatch.rm_eo-pmatch.rm_so;
662 664
 
663 665
 	return _posops_data.ret;
664 666
 }
... ...
@@ -708,6 +710,8 @@ static int pv_posops_get_pos(sip_msg_t *msg, pv_param_t *param, pv_value_t *res)
708 710
 			return pv_get_sintval(msg, param, res, _posops_data.idx);
709 711
 		case 1: /* ret */
710 712
 			return pv_get_sintval(msg, param, res, _posops_data.ret);
713
+		case 2: /* len */
714
+			return pv_get_sintval(msg, param, res, _posops_data.len);
711 715
 	}
712 716
 	return pv_get_null(msg, param, res);
713 717
 }
... ...
@@ -723,6 +727,8 @@ static int pv_posops_parse_pos_name(pv_spec_t *sp, str *in)
723 727
 				sp->pvp.pvn.u.isname.name.n = 0;
724 728
 			else if(strncmp(in->s, "ret", 3)==0)
725 729
 				sp->pvp.pvn.u.isname.name.n = 1;
730
+			else if(strncmp(in->s, "len", 3)==0)
731
+				sp->pvp.pvn.u.isname.name.n = 2;
726 732
 			else goto error;
727 733
 		break;
728 734
 
Browse code

posops: function to get the position of a regexp match

Daniel-Constantin Mierla authored on 27/09/2021 10:35:47
Showing 1 changed files
... ...
@@ -49,6 +49,7 @@ static int w_posops_pos_find_str(sip_msg_t* msg, char* p1idx, char* p2val);
49 49
 static int w_posops_pos_findi_str(sip_msg_t* msg, char* p1idx, char* p2val);
50 50
 static int w_posops_pos_rfind_str(sip_msg_t* msg, char* p1idx, char* p2val);
51 51
 static int w_posops_pos_rfindi_str(sip_msg_t* msg, char* p1idx, char* p2val);
52
+static int w_posops_pos_search(sip_msg_t* msg, char* p1idx, char* p2re);
52 53
 
53 54
 typedef struct posops_data {
54 55
 	int ret;
... ...
@@ -96,6 +97,8 @@ static cmd_export_t cmds[]={
96 97
 		fixup_free_igp_spve, ANY_ROUTE},
97 98
 	{"pos_rfindi_str", (cmd_function)w_posops_pos_rfindi_str, 2, fixup_igp_spve,
98 99
 		fixup_free_igp_spve, ANY_ROUTE},
100
+	{"pos_search",    (cmd_function)w_posops_pos_search, 2, fixup_igp_regexp,
101
+		fixup_free_igp_regexp, ANY_ROUTE},
99 102
 
100 103
 	{0, 0, 0, 0, 0, 0}
101 104
 };
... ...
@@ -633,6 +636,68 @@ static int w_posops_pos_rfindi_str(sip_msg_t* msg, char* p1idx, char* p2val)
633 636
 	return ki_posops_pos_rfindi_str(msg, idx, &val);
634 637
 }
635 638
 
639
+/**
640
+ *
641
+ */
642
+static int ki_posops_pos_search_helper(sip_msg_t *msg, int idx, regex_t *re)
643
+{
644
+	regmatch_t pmatch;
645
+
646
+	if(idx<0) {
647
+		idx += msg->len;
648
+	}
649
+	if(idx<0 || idx >= msg->len) {
650
+		return -1;
651
+	}
652
+
653
+	if (regexec(re, msg->buf + idx, 1, &pmatch, 0)!=0) {
654
+		return -1;
655
+	}
656
+	if (pmatch.rm_so==-1) {
657
+		return -1;
658
+	}
659
+
660
+	_posops_data.idx = (int)(msg->buf + idx + pmatch.rm_so);
661
+	_posops_data.ret = (_posops_data.idx==0)?posops_idx0:_posops_data.idx;
662
+
663
+	return _posops_data.ret;
664
+}
665
+
666
+static int ki_posops_pos_search(sip_msg_t* msg, int idx, str* sre)
667
+{
668
+	regex_t mre;
669
+	int ret;
670
+
671
+	memset(&mre, 0, sizeof(regex_t));
672
+	if (regcomp(&mre, sre->s, REG_EXTENDED|REG_ICASE|REG_NEWLINE)!=0) {
673
+		LM_ERR("failed to compile regex: %.*s\n", sre->len, sre->s);
674
+		return -1;
675
+	}
676
+
677
+	ret = ki_posops_pos_search_helper(msg, idx, &mre);
678
+
679
+	regfree(&mre);
680
+
681
+	return ret;
682
+}
683
+
684
+/**
685
+ *
686
+ */
687
+static int w_posops_pos_search(sip_msg_t* msg, char* p1idx, char* p2re)
688
+{
689
+	int idx = 0;
690
+	regex_t *re = NULL;
691
+
692
+	if(fixup_get_ivalue(msg, (gparam_t*)p1idx, &idx)!=0) {
693
+		LM_ERR("unable to get idx parameter\n");
694
+		return -1;
695
+	}
696
+	re = (regex_t*)p2re;
697
+
698
+	return ki_posops_pos_search_helper(msg, idx, re);
699
+}
700
+
636 701
 /**
637 702
  *
638 703
  */
... ...
@@ -735,6 +800,11 @@ static sr_kemi_t sr_kemi_posops_exports[] = {
735 800
 		{ SR_KEMIP_INT, SR_KEMIP_STR, SR_KEMIP_NONE,
736 801
 			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
737 802
 	},
803
+	{ str_init("posops"), str_init("pos_search"),
804
+		SR_KEMIP_INT, ki_posops_pos_search,
805
+		{ SR_KEMIP_INT, SR_KEMIP_STR, SR_KEMIP_NONE,
806
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
807
+	},
738 808
 
739 809
 	{ {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
740 810
 };
Browse code

posops: functions for getting the position by reverse search

Daniel-Constantin Mierla authored on 23/09/2021 07:25:43
Showing 1 changed files
... ...
@@ -47,6 +47,8 @@ static int w_posops_pos_body_start(sip_msg_t* msg, char* p1, char* p2);
47 47
 static int w_posops_pos_body_end(sip_msg_t* msg, char* p1, char* p2);
48 48
 static int w_posops_pos_find_str(sip_msg_t* msg, char* p1idx, char* p2val);
49 49
 static int w_posops_pos_findi_str(sip_msg_t* msg, char* p1idx, char* p2val);
50
+static int w_posops_pos_rfind_str(sip_msg_t* msg, char* p1idx, char* p2val);
51
+static int w_posops_pos_rfindi_str(sip_msg_t* msg, char* p1idx, char* p2val);
50 52
 
51 53
 typedef struct posops_data {
52 54
 	int ret;
... ...
@@ -90,6 +92,10 @@ static cmd_export_t cmds[]={
90 92
 		fixup_free_igp_spve, ANY_ROUTE},
91 93
 	{"pos_findi_str", (cmd_function)w_posops_pos_findi_str, 2, fixup_igp_spve,
92 94
 		fixup_free_igp_spve, ANY_ROUTE},
95
+	{"pos_rfind_str", (cmd_function)w_posops_pos_rfind_str, 2, fixup_igp_spve,
96
+		fixup_free_igp_spve, ANY_ROUTE},
97
+	{"pos_rfindi_str", (cmd_function)w_posops_pos_rfindi_str, 2, fixup_igp_spve,
98
+		fixup_free_igp_spve, ANY_ROUTE},
93 99
 
94 100
 	{0, 0, 0, 0, 0, 0}
95 101
 };
... ...
@@ -522,6 +528,111 @@ static int w_posops_pos_findi_str(sip_msg_t* msg, char* p1idx, char* p2val)
522 528
 	return ki_posops_pos_findi_str(msg, idx, &val);
523 529
 }
524 530
 
531
+
532
+
533
+/**
534
+ *
535
+ */
536
+static int ki_posops_pos_rfind_str(sip_msg_t *msg, int idx, str *val)
537
+{
538
+	char *p;
539
+	str text;
540
+
541
+	if(val==NULL || val->s==NULL || val->len<=0) {
542
+		return -1;
543
+	}
544
+	if(idx<0) {
545
+		idx += msg->len;
546
+	}
547
+	if(idx<0 || idx > msg->len - val->len) {
548
+		return -1;
549
+	}
550
+	text.s = msg->buf + idx;
551
+	text.len = msg->len - idx;
552
+	p = str_rsearch(&text, val);
553
+	if(p==NULL) {
554
+		return -1;
555
+	}
556
+
557
+	_posops_data.idx = (int)(p - msg->buf);
558
+	_posops_data.ret = (_posops_data.idx==0)?posops_idx0:_posops_data.idx;
559
+
560
+	return _posops_data.ret;
561
+}
562
+
563
+/**
564
+ *
565
+ */
566
+static int w_posops_pos_rfind_str(sip_msg_t* msg, char* p1idx, char* p2val)
567
+{
568
+	int idx = 0;
569
+	str val = STR_NULL;
570
+
571
+	if(fixup_get_ivalue(msg, (gparam_t*)p1idx, &idx)!=0) {
572
+		LM_ERR("unable to get idx parameter\n");
573
+		return -1;
574
+	}
575
+
576
+	if(fixup_get_svalue(msg, (gparam_t*)p2val, &val)!=0) {
577
+		LM_ERR("unable to get val parameter\n");
578
+		return -1;
579
+	}
580
+
581
+	return ki_posops_pos_rfind_str(msg, idx, &val);
582
+}
583
+
584
+/**
585
+ *
586
+ */
587
+static int ki_posops_pos_rfindi_str(sip_msg_t *msg, int idx, str *val)
588
+{
589
+	char *p;
590
+	str text;
591
+
592
+	if(val==NULL || val->s==NULL || val->len<=0) {
593
+		return -1;
594
+	}
595
+	if(idx<0) {
596
+		idx += msg->len;
597
+	}
598
+	if(idx<0 || idx > msg->len - val->len) {
599
+		return -1;
600
+	}
601
+
602
+	text.s = msg->buf + idx;
603
+	text.len = msg->len - idx;
604
+	p = str_rcasesearch(&text, val);
605
+	if(p==NULL) {
606
+		return -1;
607
+	}
608
+
609
+	_posops_data.idx = (int)(p - msg->buf);
610
+	_posops_data.ret = (_posops_data.idx==0)?posops_idx0:_posops_data.idx;
611
+
612
+	return _posops_data.ret;
613
+}
614
+
615
+/**
616
+ *
617
+ */
618
+static int w_posops_pos_rfindi_str(sip_msg_t* msg, char* p1idx, char* p2val)
619
+{
620
+	int idx = 0;
621
+	str val = STR_NULL;
622
+
623
+	if(fixup_get_ivalue(msg, (gparam_t*)p1idx, &idx)!=0) {
624
+		LM_ERR("unable to get idx parameter\n");
625
+		return -1;
626
+	}
627
+
628
+	if(fixup_get_svalue(msg, (gparam_t*)p2val, &val)!=0) {
629
+		LM_ERR("unable to get val parameter\n");
630
+		return -1;
631
+	}
632
+
633
+	return ki_posops_pos_rfindi_str(msg, idx, &val);
634
+}
635
+
525 636
 /**
526 637
  *
527 638
  */
... ...
@@ -614,6 +725,16 @@ static sr_kemi_t sr_kemi_posops_exports[] = {
614 725
 		{ SR_KEMIP_INT, SR_KEMIP_STR, SR_KEMIP_NONE,
615 726
 			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
616 727
 	},
728
+	{ str_init("posops"), str_init("pos_rfind_str"),
729
+		SR_KEMIP_INT, ki_posops_pos_rfind_str,
730
+		{ SR_KEMIP_INT, SR_KEMIP_STR, SR_KEMIP_NONE,
731
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
732
+	},
733
+	{ str_init("posops"), str_init("pos_rfindi_str"),
734
+		SR_KEMIP_INT, ki_posops_pos_rfindi_str,
735
+		{ SR_KEMIP_INT, SR_KEMIP_STR, SR_KEMIP_NONE,
736
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
737
+	},
617 738
 
618 739
 	{ {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
619 740
 };
Browse code

posops: handle negative index parameter for find functions

Daniel-Constantin Mierla authored on 23/09/2021 07:06:51
Showing 1 changed files
... ...
@@ -427,13 +427,15 @@ static int ki_posops_pos_find_str(sip_msg_t *msg, int idx, str *val)
427 427
 	char *p;
428 428
 	str text;
429 429
 
430
-	if(idx<0 || val==NULL || val->s==NULL || val->len<=0) {
430
+	if(val==NULL || val->s==NULL || val->len<=0) {
431 431
 		return -1;
432 432
 	}
433
-	if(idx > msg->len - val->len) {
433
+	if(idx<0) {
434
+		idx += msg->len;
435
+	}
436
+	if(idx<0 || idx > msg->len - val->len) {
434 437
 		return -1;
435 438
 	}
436
-
437 439
 	text.s = msg->buf + idx;
438 440
 	text.len = msg->len - idx;
439 441
 	p = str_search(&text, val);
... ...
@@ -476,10 +478,13 @@ static int ki_posops_pos_findi_str(sip_msg_t *msg, int idx, str *val)
476 478
 	char *p;
477 479
 	str text;
478 480
 
479
-	if(idx<0 || val==NULL || val->s==NULL || val->len<=0) {
481
+	if(val==NULL || val->s==NULL || val->len<=0) {
480 482
 		return -1;
481 483
 	}
482
-	if(idx > msg->len - val->len) {
484
+	if(idx<0) {
485
+		idx += msg->len;
486
+	}
487
+	if(idx<0 || idx > msg->len - val->len) {
483 488
 		return -1;
484 489
 	}
485 490
 
Browse code

posops: adjust offset on negative index for update ops

Daniel-Constantin Mierla authored on 22/09/2021 19:19:01
Showing 1 changed files
... ...
@@ -153,7 +153,7 @@ static int ki_posops_pos_append(sip_msg_t *msg, int idx, str *val)
153 153
 	}
154 154
 
155 155
 	if(idx<0) {
156
-		offset = msg->len + idx + 1;
156
+		offset = msg->len + idx;
157 157
 	} else {
158 158
 		offset = idx;
159 159
 	}
... ...
@@ -206,7 +206,7 @@ static int ki_posops_pos_insert(sip_msg_t *msg, int idx, str *val)
206 206
 	}
207 207
 
208 208
 	if(idx<0) {
209
-		offset = msg->len + idx + 1;
209
+		offset = msg->len + idx;
210 210
 	} else {
211 211
 		offset = idx;
212 212
 	}
... ...
@@ -259,7 +259,7 @@ static int ki_posops_pos_rm(sip_msg_t *msg, int idx, int len)
259 259
 		return -1;
260 260
 	}
261 261
 	if(idx<0) {
262
-		offset = msg->len + idx + 1;
262
+		offset = msg->len + idx;
263 263
 	} else {
264 264
 		offset = idx;
265 265
 	}
Browse code

posops: functions to get the position of a string in message buffer

Daniel-Constantin Mierla authored on 21/09/2021 13:50:33
Showing 1 changed files
... ...
@@ -45,6 +45,8 @@ static int w_posops_pos_headers_start(sip_msg_t* msg, char* p1, char* p2);
45 45
 static int w_posops_pos_headers_end(sip_msg_t* msg, char* p1, char* p2);
46 46
 static int w_posops_pos_body_start(sip_msg_t* msg, char* p1, char* p2);
47 47
 static int w_posops_pos_body_end(sip_msg_t* msg, char* p1, char* p2);
48
+static int w_posops_pos_find_str(sip_msg_t* msg, char* p1idx, char* p2val);
49
+static int w_posops_pos_findi_str(sip_msg_t* msg, char* p1idx, char* p2val);
48 50
 
49 51
 typedef struct posops_data {
50 52
 	int ret;
... ...
@@ -84,6 +86,10 @@ static cmd_export_t cmds[]={
84 86
 		0, ANY_ROUTE},
85 87
 	{"pos_body_end", (cmd_function)w_posops_pos_body_end, 0, 0,
86 88
 		0, ANY_ROUTE},
89
+	{"pos_find_str", (cmd_function)w_posops_pos_find_str, 2, fixup_igp_spve,
90
+		fixup_free_igp_spve, ANY_ROUTE},
91
+	{"pos_findi_str", (cmd_function)w_posops_pos_findi_str, 2, fixup_igp_spve,
92
+		fixup_free_igp_spve, ANY_ROUTE},
87 93
 
88 94
 	{0, 0, 0, 0, 0, 0}
89 95
 };
... ...
@@ -413,6 +419,104 @@ static int w_posops_pos_body_end(sip_msg_t* msg, char* p1, char* p2)
413 419
 	return  ki_posops_pos_body_end(msg);
414 420
 }
415 421
 
422
+/**
423
+ *
424
+ */
425
+static int ki_posops_pos_find_str(sip_msg_t *msg, int idx, str *val)
426
+{
427
+	char *p;
428
+	str text;
429
+
430
+	if(idx<0 || val==NULL || val->s==NULL || val->len<=0) {
431
+		return -1;
432
+	}
433
+	if(idx > msg->len - val->len) {
434
+		return -1;
435
+	}
436
+
437
+	text.s = msg->buf + idx;
438
+	text.len = msg->len - idx;
439
+	p = str_search(&text, val);
440
+	if(p==NULL) {
441
+		return -1;
442
+	}
443
+
444
+	_posops_data.idx = (int)(p - msg->buf);
445
+	_posops_data.ret = (_posops_data.idx==0)?posops_idx0:_posops_data.idx;
446
+
447
+	return _posops_data.ret;
448
+}
449
+
450
+/**
451
+ *
452
+ */
453
+static int w_posops_pos_find_str(sip_msg_t* msg, char* p1idx, char* p2val)
454
+{
455
+	int idx = 0;
456
+	str val = STR_NULL;
457
+
458
+	if(fixup_get_ivalue(msg, (gparam_t*)p1idx, &idx)!=0) {
459
+		LM_ERR("unable to get idx parameter\n");
460
+		return -1;
461
+	}
462
+
463
+	if(fixup_get_svalue(msg, (gparam_t*)p2val, &val)!=0) {
464
+		LM_ERR("unable to get val parameter\n");
465
+		return -1;
466
+	}
467
+
468
+	return ki_posops_pos_find_str(msg, idx, &val);
469
+}
470
+
471
+/**
472
+ *
473
+ */
474
+static int ki_posops_pos_findi_str(sip_msg_t *msg, int idx, str *val)
475
+{
476
+	char *p;
477
+	str text;
478
+
479
+	if(idx<0 || val==NULL || val->s==NULL || val->len<=0) {
480
+		return -1;
481
+	}
482
+	if(idx > msg->len - val->len) {
483
+		return -1;
484
+	}
485
+
486
+	text.s = msg->buf + idx;
487
+	text.len = msg->len - idx;
488
+	p = str_casesearch(&text, val);
489
+	if(p==NULL) {
490
+		return -1;
491
+	}
492
+
493
+	_posops_data.idx = (int)(p - msg->buf);
494
+	_posops_data.ret = (_posops_data.idx==0)?posops_idx0:_posops_data.idx;
495
+
496
+	return _posops_data.ret;
497
+}
498
+
499
+/**
500
+ *
501
+ */
502
+static int w_posops_pos_findi_str(sip_msg_t* msg, char* p1idx, char* p2val)
503
+{
504
+	int idx = 0;
505
+	str val = STR_NULL;
506
+
507
+	if(fixup_get_ivalue(msg, (gparam_t*)p1idx, &idx)!=0) {
508
+		LM_ERR("unable to get idx parameter\n");
509
+		return -1;
510
+	}
511
+
512
+	if(fixup_get_svalue(msg, (gparam_t*)p2val, &val)!=0) {
513
+		LM_ERR("unable to get val parameter\n");
514
+		return -1;
515
+	}
516
+
517
+	return ki_posops_pos_findi_str(msg, idx, &val);
518
+}
519
+
416 520
 /**
417 521
  *
418 522
  */
... ...
@@ -495,6 +599,16 @@ static sr_kemi_t sr_kemi_posops_exports[] = {
495 599
 		{ SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
496 600
 			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
497 601
 	},
602
+	{ str_init("posops"), str_init("pos_find_str"),
603
+		SR_KEMIP_INT, ki_posops_pos_find_str,
604
+		{ SR_KEMIP_INT, SR_KEMIP_STR, SR_KEMIP_NONE,
605
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
606
+	},
607
+	{ str_init("posops"), str_init("pos_findi_str"),
608
+		SR_KEMIP_INT, ki_posops_pos_findi_str,
609
+		{ SR_KEMIP_INT, SR_KEMIP_STR, SR_KEMIP_NONE,
610
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
611
+	},
498 612
 
499 613
 	{ {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
500 614
 };
Browse code

posops: added idx0 mod param

- set the value to return by function when position is at index 0
- default -255

Daniel-Constantin Mierla authored on 21/09/2021 08:23:53
Showing 1 changed files
... ...
@@ -51,6 +51,8 @@ typedef struct posops_data {
51 51
 	int idx;
52 52
 } posops_data_t;
53 53