00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00029 #include <stdio.h>
00030 #include <string.h>
00031 #include <stdlib.h>
00032 #include <time.h>
00033 #include <sys/types.h>
00034 #include <unistd.h>
00035
00036 #include "../../dprint.h"
00037 #include "../../mem/mem.h"
00038 #include "../../ut.h"
00039 #include "../../trim.h"
00040 #include "../../pvapi.h"
00041 #include "../../dset.h"
00042
00043 #include "../../parser/parse_param.h"
00044 #include "../../parser/parse_uri.h"
00045 #include "../../parser/parse_to.h"
00046 #include "../../parser/parse_nameaddr.h"
00047
00048 #include "../../lib/kcore/strcommon.h"
00049 #include "pv_trans.h"
00050
00051
00053 #define TR_BUFFER_SIZE 65536
00054 #define TR_BUFFER_SLOTS 4
00055
00057 static char **_tr_buffer_list = NULL;
00058
00059 static char *_tr_buffer = NULL;
00060
00061 static int _tr_buffer_idx = 0;
00062
00066 int tr_init_buffers(void)
00067 {
00068 int i;
00069
00070 _tr_buffer_list = (char**)malloc(TR_BUFFER_SLOTS * sizeof(char*));
00071 if(_tr_buffer_list==NULL)
00072 return -1;
00073 for(i=0; i<TR_BUFFER_SLOTS; i++) {
00074 _tr_buffer_list[i] = (char*)malloc(TR_BUFFER_SIZE);
00075 if(_tr_buffer_list[i]==NULL)
00076 return -1;
00077 }
00078 return 0;
00079 }
00080
00084 char *tr_set_crt_buffer(void)
00085 {
00086 _tr_buffer = _tr_buffer_list[_tr_buffer_idx];
00087 _tr_buffer_idx = (_tr_buffer_idx + 1) % TR_BUFFER_SLOTS;
00088 return _tr_buffer;
00089 }
00090
00099 int tr_eval_string(struct sip_msg *msg, tr_param_t *tp, int subtype,
00100 pv_value_t *val)
00101 {
00102 int i, j, max;
00103 char *p, *s;
00104 str st, st2;
00105 pv_value_t v, w;
00106 time_t t;
00107
00108 if(val==NULL || val->flags&PV_VAL_NULL)
00109 return -1;
00110
00111 tr_set_crt_buffer();
00112
00113 switch(subtype)
00114 {
00115 case TR_S_LEN:
00116 if(!(val->flags&PV_VAL_STR))
00117 val->rs.s = int2str(val->ri, &val->rs.len);
00118
00119 val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
00120 val->ri = val->rs.len;
00121 val->rs.s = int2str(val->ri, &val->rs.len);
00122 break;
00123 case TR_S_INT:
00124 if(!(val->flags&PV_VAL_INT))
00125 {
00126 if(str2sint(&val->rs, &val->ri)!=0)
00127 return -1;
00128 } else {
00129 if(!(val->flags&PV_VAL_STR))
00130 val->rs.s = int2str(val->ri, &val->rs.len);
00131 }
00132
00133 val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
00134 break;
00135 case TR_S_MD5:
00136 if(!(val->flags&PV_VAL_STR))
00137 val->rs.s = int2str(val->ri, &val->rs.len);
00138
00139 compute_md5(_tr_buffer, val->rs.s, val->rs.len);
00140 _tr_buffer[MD5_LEN] = '\0';
00141 val->flags = PV_VAL_STR;
00142 val->ri = 0;
00143 val->rs.s = _tr_buffer;
00144 val->rs.len = MD5_LEN;
00145 break;
00146 case TR_S_ENCODEHEXA:
00147 if(!(val->flags&PV_VAL_STR))
00148 val->rs.s = int2str(val->ri, &val->rs.len);
00149 if(val->rs.len>TR_BUFFER_SIZE/2-1)
00150 return -1;
00151 j = 0;
00152 for(i=0; i<val->rs.len; i++)
00153 {
00154 _tr_buffer[j++] = fourbits2char[val->rs.s[i] >> 4];
00155 _tr_buffer[j++] = fourbits2char[val->rs.s[i] & 0xf];
00156 }
00157 _tr_buffer[j] = '\0';
00158 memset(val, 0, sizeof(pv_value_t));
00159 val->flags = PV_VAL_STR;
00160 val->rs.s = _tr_buffer;
00161 val->rs.len = j;
00162 break;
00163 case TR_S_DECODEHEXA:
00164 if(!(val->flags&PV_VAL_STR))
00165 val->rs.s = int2str(val->ri, &val->rs.len);
00166 if(val->rs.len>TR_BUFFER_SIZE*2-1)
00167 return -1;
00168 for(i=0; i<val->rs.len/2; i++)
00169 {
00170 if(val->rs.s[2*i]>='0'&&val->rs.s[2*i]<='9')
00171 _tr_buffer[i] = (val->rs.s[2*i]-'0') << 4;
00172 else if(val->rs.s[2*i]>='a'&&val->rs.s[2*i]<='f')
00173 _tr_buffer[i] = (val->rs.s[2*i]-'a'+10) << 4;
00174 else if(val->rs.s[2*i]>='A'&&val->rs.s[2*i]<='F')
00175 _tr_buffer[i] = (val->rs.s[2*i]-'A'+10) << 4;
00176 else return -1;
00177
00178 if(val->rs.s[2*i+1]>='0'&&val->rs.s[2*i+1]<='9')
00179 _tr_buffer[i] += val->rs.s[2*i+1]-'0';
00180 else if(val->rs.s[2*i+1]>='a'&&val->rs.s[2*i+1]<='f')
00181 _tr_buffer[i] += val->rs.s[2*i+1]-'a'+10;
00182 else if(val->rs.s[2*i+1]>='A'&&val->rs.s[2*i+1]<='F')
00183 _tr_buffer[i] += val->rs.s[2*i+1]-'A'+10;
00184 else return -1;
00185 }
00186 _tr_buffer[i] = '\0';
00187 memset(val, 0, sizeof(pv_value_t));
00188 val->flags = PV_VAL_STR;
00189 val->rs.s = _tr_buffer;
00190 val->rs.len = i;
00191 break;
00192 case TR_S_ESCAPECOMMON:
00193 if(!(val->flags&PV_VAL_STR))
00194 val->rs.s = int2str(val->ri, &val->rs.len);
00195 if(val->rs.len>TR_BUFFER_SIZE/2-1)
00196 return -1;
00197 i = escape_common(_tr_buffer, val->rs.s, val->rs.len);
00198 _tr_buffer[i] = '\0';
00199 memset(val, 0, sizeof(pv_value_t));
00200 val->flags = PV_VAL_STR;
00201 val->rs.s = _tr_buffer;
00202 val->rs.len = i;
00203 break;
00204 case TR_S_UNESCAPECOMMON:
00205 if(!(val->flags&PV_VAL_STR))
00206 val->rs.s = int2str(val->ri, &val->rs.len);
00207 if(val->rs.len>TR_BUFFER_SIZE-1)
00208 return -1;
00209 i = unescape_common(_tr_buffer, val->rs.s, val->rs.len);
00210 _tr_buffer[i] = '\0';
00211 memset(val, 0, sizeof(pv_value_t));
00212 val->flags = PV_VAL_STR;
00213 val->rs.s = _tr_buffer;
00214 val->rs.len = i;
00215 break;
00216 case TR_S_ESCAPEUSER:
00217 if(!(val->flags&PV_VAL_STR))
00218 val->rs.s = int2str(val->ri, &val->rs.len);
00219 if(val->rs.len>TR_BUFFER_SIZE/2-1)
00220 return -1;
00221 st.s = _tr_buffer;
00222 st.len = TR_BUFFER_SIZE;
00223 if (escape_user(&val->rs, &st))
00224 return -1;
00225 memset(val, 0, sizeof(pv_value_t));
00226 val->flags = PV_VAL_STR;
00227 val->rs = st;
00228 break;
00229 case TR_S_UNESCAPEUSER:
00230 if(!(val->flags&PV_VAL_STR))
00231 val->rs.s = int2str(val->ri, &val->rs.len);
00232 if(val->rs.len>TR_BUFFER_SIZE-1)
00233 return -1;
00234 st.s = _tr_buffer;
00235 st.len = TR_BUFFER_SIZE;
00236 if (unescape_user(&val->rs, &st))
00237 return -1;
00238 memset(val, 0, sizeof(pv_value_t));
00239 val->flags = PV_VAL_STR;
00240 val->rs = st;
00241 break;
00242 case TR_S_ESCAPEPARAM:
00243 if(!(val->flags&PV_VAL_STR))
00244 val->rs.s = int2str(val->ri, &val->rs.len);
00245 if(val->rs.len>TR_BUFFER_SIZE/2-1)
00246 return -1;
00247 st.s = _tr_buffer;
00248 st.len = TR_BUFFER_SIZE;
00249 if (escape_param(&val->rs, &st) < 0)
00250 return -1;
00251 memset(val, 0, sizeof(pv_value_t));
00252 val->flags = PV_VAL_STR;
00253 val->rs = st;
00254 break;
00255 case TR_S_UNESCAPEPARAM:
00256 if(!(val->flags&PV_VAL_STR))
00257 val->rs.s = int2str(val->ri, &val->rs.len);
00258 if(val->rs.len>TR_BUFFER_SIZE-1)
00259 return -1;
00260 st.s = _tr_buffer;
00261 st.len = TR_BUFFER_SIZE;
00262 if (unescape_param(&val->rs, &st) < 0)
00263 return -1;
00264 memset(val, 0, sizeof(pv_value_t));
00265 val->flags = PV_VAL_STR;
00266 val->rs = st;
00267 break;
00268 case TR_S_SUBSTR:
00269 if(tp==NULL || tp->next==NULL)
00270 {
00271 LM_ERR("substr invalid parameters\n");
00272 return -1;
00273 }
00274 if(!(val->flags&PV_VAL_STR))
00275 val->rs.s = int2str(val->ri, &val->rs.len);
00276 if(tp->type==TR_PARAM_NUMBER)
00277 {
00278 i = tp->v.n;
00279 } else {
00280 if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
00281 || (!(v.flags&PV_VAL_INT)))
00282 {
00283 LM_ERR("substr cannot get p1\n");
00284 return -1;
00285 }
00286 i = v.ri;
00287 }
00288 if(tp->next->type==TR_PARAM_NUMBER)
00289 {
00290 j = tp->next->v.n;
00291 } else {
00292 if(pv_get_spec_value(msg, (pv_spec_p)tp->next->v.data, &v)!=0
00293 || (!(v.flags&PV_VAL_INT)))
00294 {
00295 LM_ERR("substr cannot get p2\n");
00296 return -1;
00297 }
00298 j = v.ri;
00299 }
00300 LM_DBG("i=%d j=%d\n", i, j);
00301 if(j<0)
00302 {
00303 LM_ERR("substr negative offset\n");
00304 return -1;
00305 }
00306 val->flags = PV_VAL_STR;
00307 val->ri = 0;
00308 if(i>=0)
00309 {
00310 if(i>=val->rs.len)
00311 {
00312 LM_ERR("substr out of range\n");
00313 return -1;
00314 }
00315 if(i+j>=val->rs.len) j=0;
00316 if(j==0)
00317 {
00318 val->rs.s += i;
00319 val->rs.len -= i;
00320 break;
00321 }
00322 val->rs.s += i;
00323 val->rs.len = j;
00324 break;
00325 }
00326 i = -i;
00327 if(i>val->rs.len)
00328 {
00329 LM_ERR("substr out of range\n");
00330 return -1;
00331 }
00332 if(i<j) j=0;
00333 if(j==0)
00334 {
00335 val->rs.s += val->rs.len-i;
00336 val->rs.len = i;
00337 break;
00338 }
00339 val->rs.s += val->rs.len-i;
00340 val->rs.len = j;
00341 break;
00342
00343 case TR_S_SELECT:
00344 if(tp==NULL || tp->next==NULL)
00345 {
00346 LM_ERR("select invalid parameters\n");
00347 return -1;
00348 }
00349 if(!(val->flags&PV_VAL_STR))
00350 val->rs.s = int2str(val->ri, &val->rs.len);
00351 if(tp->type==TR_PARAM_NUMBER)
00352 {
00353 i = tp->v.n;
00354 } else {
00355 if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
00356 || (!(v.flags&PV_VAL_INT)))
00357 {
00358 LM_ERR("select cannot get p1\n");
00359 return -1;
00360 }
00361 i = v.ri;
00362 }
00363 val->flags = PV_VAL_STR;
00364 val->ri = 0;
00365 if(i<0)
00366 {
00367 s = val->rs.s+val->rs.len-1;
00368 p = s;
00369 i = -i;
00370 i--;
00371 while(p>=val->rs.s)
00372 {
00373 if(*p==tp->next->v.s.s[0])
00374 {
00375 if(i==0)
00376 break;
00377 s = p-1;
00378 i--;
00379 }
00380 p--;
00381 }
00382 if(i==0)
00383 {
00384 val->rs.s = p+1;
00385 val->rs.len = s-p;
00386 } else {
00387 val->rs.s = "";
00388 val->rs.len = 0;
00389 }
00390 } else {
00391 s = val->rs.s;
00392 p = s;
00393 while(p<val->rs.s+val->rs.len)
00394 {
00395 if(*p==tp->next->v.s.s[0])
00396 {
00397 if(i==0)
00398 break;
00399 s = p + 1;
00400 i--;
00401 }
00402 p++;
00403 }
00404 if(i==0)
00405 {
00406 val->rs.s = s;
00407 val->rs.len = p-s;
00408 } else {
00409 val->rs.s = "";
00410 val->rs.len = 0;
00411 }
00412 }
00413 break;
00414
00415 case TR_S_TOLOWER:
00416 if(!(val->flags&PV_VAL_STR))
00417 {
00418 val->rs.s = int2str(val->ri, &val->rs.len);
00419 val->flags |= PV_VAL_STR;
00420 break;
00421 }
00422 if(val->rs.len>TR_BUFFER_SIZE-1)
00423 return -1;
00424 st.s = _tr_buffer;
00425 st.len = val->rs.len;
00426 for (i=0; i<st.len; i++)
00427 st.s[i]=(val->rs.s[i]>='A' && val->rs.s[i]<='Z')
00428 ?('a' + val->rs.s[i] -'A'):val->rs.s[i];
00429 memset(val, 0, sizeof(pv_value_t));
00430 val->flags = PV_VAL_STR;
00431 val->rs = st;
00432 break;
00433
00434 case TR_S_TOUPPER:
00435 if(!(val->flags&PV_VAL_STR))
00436 {
00437 val->rs.s = int2str(val->ri, &val->rs.len);
00438 val->flags |= PV_VAL_STR;
00439 break;
00440 }
00441 if(val->rs.len>TR_BUFFER_SIZE-1)
00442 return -1;
00443 st.s = _tr_buffer;
00444 st.len = val->rs.len;
00445 for (i=0; i<st.len; i++)
00446 st.s[i]=(val->rs.s[i]>='a' && val->rs.s[i]<='z')
00447 ?('A' + val->rs.s[i] -'a'):val->rs.s[i];
00448 memset(val, 0, sizeof(pv_value_t));
00449 val->flags = PV_VAL_STR;
00450 val->rs = st;
00451 break;
00452
00453 case TR_S_STRIP:
00454 case TR_S_STRIPTAIL:
00455 if(tp==NULL)
00456 {
00457 LM_ERR("strip invalid parameters\n");
00458 return -1;
00459 }
00460 if(!(val->flags&PV_VAL_STR))
00461 val->rs.s = int2str(val->ri, &val->rs.len);
00462 if(tp->type==TR_PARAM_NUMBER)
00463 {
00464 i = tp->v.n;
00465 } else {
00466 if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
00467 || (!(v.flags&PV_VAL_INT)))
00468 {
00469 LM_ERR("select cannot get p1\n");
00470 return -1;
00471 }
00472 i = v.ri;
00473 }
00474 val->flags = PV_VAL_STR;
00475 val->ri = 0;
00476 if(i<=0)
00477 break;
00478 if(i>=val->rs.len)
00479 {
00480 _tr_buffer[0] = '\0';
00481 val->rs.s = _tr_buffer;
00482 val->rs.len = 0;
00483 break;
00484 }
00485 if(subtype==TR_S_STRIP)
00486 val->rs.s += i;
00487 val->rs.len -= i;
00488 break;
00489
00490 case TR_S_PREFIXES:
00491 case TR_S_PREFIXES_QUOT:
00492 if(!(val->flags&PV_VAL_STR))
00493 val->rs.s = int2str(val->ri, &val->rs.len);
00494
00495
00496 max = val->rs.len;
00497 if(tp!=NULL) {
00498 if(tp->type==TR_PARAM_NUMBER) {
00499 if (tp->v.n > 0 && tp->v.n < max)
00500 max = tp->v.n;
00501 } else {
00502 if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
00503 || (!(v.flags&PV_VAL_INT)))
00504 {
00505 LM_ERR("prefixes cannot get max\n");
00506 return -1;
00507 }
00508 if (v.ri > 0 && v.ri < max)
00509 max = v.ri;
00510 }
00511 }
00512
00513 if(max * (max/2 + (subtype==TR_S_PREFIXES_QUOT ? 1 : 3)) > TR_BUFFER_SIZE-1) {
00514 LM_ERR("prefixes buffer too short\n");
00515 return -1;
00516 }
00517
00518 j = 0;
00519 for (i=1; i <= max; i++) {
00520 if (subtype==TR_S_PREFIXES_QUOT)
00521 _tr_buffer[j++] = '\'';
00522 memcpy(&(_tr_buffer[j]), val->rs.s, i);
00523 j += i;
00524 if (subtype==TR_S_PREFIXES_QUOT)
00525 _tr_buffer[j++] = '\'';
00526 _tr_buffer[j++] = ',';
00527 }
00528 memset(val, 0, sizeof(pv_value_t));
00529 val->flags = PV_VAL_STR;
00530 val->rs.s = _tr_buffer;
00531 val->rs.len = j-1;
00532 break;
00533
00534
00535 case TR_S_REPLACE:
00536 if(tp==NULL || tp->next==NULL)
00537 {
00538 LM_ERR("select invalid parameters\n");
00539 return -1;
00540 }
00541 if(!(val->flags&PV_VAL_STR))
00542 val->rs.s = int2str(val->ri, &val->rs.len);
00543
00544 if(tp->type==TR_PARAM_STRING)
00545 {
00546 st = tp->v.s;
00547 } else {
00548 if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
00549 || (!(v.flags&PV_VAL_STR)) || v.rs.len<=0)
00550 {
00551 LM_ERR("replace cannot get p1\n");
00552 return -1;
00553 }
00554 st = v.rs;
00555 }
00556
00557 if(tp->next->type==TR_PARAM_STRING)
00558 {
00559 st2 = tp->next->v.s;
00560 } else {
00561 if(pv_get_spec_value(msg, (pv_spec_p)tp->next->v.data, &w)!=0
00562 || (!(w.flags&PV_VAL_STR)) || w.rs.len<=0)
00563 {
00564 LM_ERR("replace cannot get p2\n");
00565 return -1;
00566 }
00567 st2 = w.rs;
00568 }
00569
00570 val->flags = PV_VAL_STR;
00571 val->ri = 0;
00572
00573 i = 0;
00574 j = 0;
00575 max = val->rs.len - st.len;
00576 while (i < val->rs.len && j < TR_BUFFER_SIZE) {
00577 if (i <= max && val->rs.s[i] == st.s[0]
00578 && strncmp(val->rs.s+i, st.s, st.len) == 0) {
00579 strncpy(_tr_buffer+j, st2.s, st2.len);
00580 i += st.len;
00581 j += st2.len;
00582 } else {
00583 _tr_buffer[j++] = val->rs.s[i++];
00584 }
00585 }
00586 val->rs.s = _tr_buffer;
00587 val->rs.len = j;
00588 break;
00589
00590 case TR_S_TIMEFORMAT:
00591 if(tp==NULL)
00592 {
00593 LM_ERR("timeformat invalid parameters\n");
00594 return -1;
00595 }
00596 if(!(val->flags&PV_VAL_INT) && (str2int(&val->rs,
00597 (unsigned int*) &val->ri)!=0))
00598 {
00599 LM_ERR("value is not numeric\n");
00600 return -1;
00601 }
00602 if(tp->type==TR_PARAM_STRING)
00603 {
00604 st = tp->v.s;
00605 } else {
00606 if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
00607 || (!(v.flags&PV_VAL_STR)) || v.rs.len<=0)
00608 {
00609 LM_ERR("timeformat cannot get p1\n");
00610 return -1;
00611 }
00612 st = v.rs;
00613 }
00614 s = pkg_malloc(st.len + 1);
00615 if (s==NULL)
00616 {
00617 LM_ERR("no more pkg memory\n");
00618 return -1;
00619 }
00620 memcpy(s, st.s, st.len);
00621 s[st.len] = '\0';
00622 t = val->ri;
00623 val->rs.len = strftime(_tr_buffer, TR_BUFFER_SIZE-1, s,
00624 localtime(&t));
00625 pkg_free(s);
00626 val->flags = PV_VAL_STR;
00627 val->rs.s = _tr_buffer;
00628 break;
00629
00630 case TR_S_TRIM:
00631 if(!(val->flags&PV_VAL_STR))
00632 val->rs.s = int2str(val->ri, &val->rs.len);
00633 if(val->rs.len>TR_BUFFER_SIZE-2)
00634 return -1;
00635 memcpy(_tr_buffer, val->rs.s, val->rs.len);
00636 val->flags = PV_VAL_STR;
00637 val->rs.s = _tr_buffer;
00638 trim(&val->rs);
00639 val->rs.s[val->rs.len] = '\0';
00640 break;
00641
00642 case TR_S_RTRIM:
00643 if(!(val->flags&PV_VAL_STR))
00644 val->rs.s = int2str(val->ri, &val->rs.len);
00645 if(val->rs.len>TR_BUFFER_SIZE-2)
00646 return -1;
00647 memcpy(_tr_buffer, val->rs.s, val->rs.len);
00648 val->flags = PV_VAL_STR;
00649 val->rs.s = _tr_buffer;
00650 trim_trailing(&val->rs);
00651 val->rs.s[val->rs.len] = '\0';
00652 break;
00653
00654 case TR_S_LTRIM:
00655 if(!(val->flags&PV_VAL_STR))
00656 val->rs.s = int2str(val->ri, &val->rs.len);
00657 if(val->rs.len>TR_BUFFER_SIZE-2)
00658 return -1;
00659 memcpy(_tr_buffer, val->rs.s, val->rs.len);
00660 val->flags = PV_VAL_STR;
00661 val->rs.s = _tr_buffer;
00662 trim_leading(&val->rs);
00663 val->rs.s[val->rs.len] = '\0';
00664 break;
00665
00666 case TR_S_RM:
00667 if(tp==NULL)
00668 {
00669 LM_ERR("invalid parameters\n");
00670 return -1;
00671 }
00672 if(!(val->flags&PV_VAL_STR))
00673 val->rs.s = int2str(val->ri, &val->rs.len);
00674 if(val->rs.len>TR_BUFFER_SIZE-2)
00675 return -1;
00676 if(tp->type==TR_PARAM_STRING)
00677 {
00678 st = tp->v.s;
00679 if(memchr(st.s, '\\', st.len)) {
00680 p = pv_get_buffer();
00681 if(st.len>=pv_get_buffer_size()-1)
00682 return -1;
00683 j=0;
00684 for(i=0; i<st.len-1; i++) {
00685 if(st.s[i]=='\\') {
00686 switch(st.s[i+1]) {
00687 case 'n':
00688 p[j++] = '\n';
00689 break;
00690 case 'r':
00691 p[j++] = '\r';
00692 break;
00693 case 't':
00694 p[j++] = '\t';
00695 break;
00696 case '\\':
00697 p[j++] = '\\';
00698 break;
00699 default:
00700 p[j++] = st.s[i+1];
00701 }
00702 i++;
00703 } else {
00704 p[j++] = st.s[i];
00705 }
00706 }
00707 if(i==st.len-1)
00708 p[j++] = st.s[i];
00709 p[j] = '\0';
00710 st.s = p;
00711 st.len = j;
00712 }
00713 } else {
00714 if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
00715 || (!(v.flags&PV_VAL_STR)) || v.rs.len<=0)
00716 {
00717 LM_ERR("cannot get parameter value\n");
00718 return -1;
00719 }
00720 st = v.rs;
00721 }
00722 LM_DBG("removing [%.*s](%d) in [%.*s](%d)\n",
00723 st.len, st.s, st.len, val->rs.len, val->rs.s, val->rs.len);
00724 val->flags = PV_VAL_STR;
00725 val->ri = 0;
00726
00727 i = 0;
00728 j = 0;
00729 max = val->rs.len - st.len;
00730 while (i < val->rs.len && j < TR_BUFFER_SIZE) {
00731 if (i <= max && val->rs.s[i] == st.s[0]
00732 && strncmp(val->rs.s+i, st.s, st.len) == 0) {
00733 i += st.len;
00734 } else {
00735 _tr_buffer[j++] = val->rs.s[i++];
00736 }
00737 }
00738 val->rs.s = _tr_buffer;
00739 val->rs.s[j] = '\0';
00740 val->rs.len = j;
00741 break;
00742
00743 default:
00744 LM_ERR("unknown subtype %d\n",
00745 subtype);
00746 return -1;
00747 }
00748 return 0;
00749 }
00750
00751 static str _tr_empty = { "", 0 };
00752 static str _tr_uri = {0, 0};
00753 static struct sip_uri _tr_parsed_uri;
00754 static param_t* _tr_uri_params = NULL;
00755
00756
00765 int tr_eval_uri(struct sip_msg *msg, tr_param_t *tp, int subtype,
00766 pv_value_t *val)
00767 {
00768 pv_value_t v;
00769 str sv;
00770 param_hooks_t phooks;
00771 param_t *pit=NULL;
00772
00773 if(val==NULL || (!(val->flags&PV_VAL_STR)) || val->rs.len<=0)
00774 return -1;
00775
00776 if(_tr_uri.len==0 || _tr_uri.len!=val->rs.len ||
00777 strncmp(_tr_uri.s, val->rs.s, val->rs.len)!=0)
00778 {
00779 if(val->rs.len>_tr_uri.len)
00780 {
00781 if(_tr_uri.s) pkg_free(_tr_uri.s);
00782 _tr_uri.s = (char*)pkg_malloc((val->rs.len+1)*sizeof(char));
00783 if(_tr_uri.s==NULL)
00784 {
00785 LM_ERR("no more private memory\n");
00786 if(_tr_uri_params != NULL)
00787 {
00788 free_params(_tr_uri_params);
00789 _tr_uri_params = 0;
00790 }
00791 memset(&_tr_uri, 0, sizeof(str));
00792 memset(&_tr_parsed_uri, 0, sizeof(struct sip_uri));
00793 return -1;
00794 }
00795 }
00796 _tr_uri.len = val->rs.len;
00797 memcpy(_tr_uri.s, val->rs.s, val->rs.len);
00798 _tr_uri.s[_tr_uri.len] = '\0';
00799
00800 memset(&_tr_parsed_uri, 0, sizeof(struct sip_uri));
00801 if(_tr_uri_params != NULL)
00802 {
00803 free_params(_tr_uri_params);
00804 _tr_uri_params = 0;
00805 }
00806
00807 if(parse_uri(_tr_uri.s, _tr_uri.len, &_tr_parsed_uri)!=0)
00808 {
00809 LM_ERR("invalid uri [%.*s]\n", val->rs.len,
00810 val->rs.s);
00811 if(_tr_uri_params != NULL)
00812 {
00813 free_params(_tr_uri_params);
00814 _tr_uri_params = 0;
00815 }
00816 pkg_free(_tr_uri.s);
00817 memset(&_tr_uri, 0, sizeof(str));
00818 memset(&_tr_parsed_uri, 0, sizeof(struct sip_uri));
00819 return -1;
00820 }
00821 }
00822 memset(val, 0, sizeof(pv_value_t));
00823 val->flags = PV_VAL_STR;
00824
00825 switch(subtype)
00826 {
00827 case TR_URI_USER:
00828 val->rs = (_tr_parsed_uri.user.s)?_tr_parsed_uri.user:_tr_empty;
00829 break;
00830 case TR_URI_HOST:
00831 val->rs = (_tr_parsed_uri.host.s)?_tr_parsed_uri.host:_tr_empty;
00832 break;
00833 case TR_URI_PASSWD:
00834 val->rs = (_tr_parsed_uri.passwd.s)?_tr_parsed_uri.passwd:_tr_empty;
00835 break;
00836 case TR_URI_PORT:
00837 val->flags |= PV_TYPE_INT|PV_VAL_INT;
00838 val->rs = (_tr_parsed_uri.port.s)?_tr_parsed_uri.port:_tr_empty;
00839 val->ri = _tr_parsed_uri.port_no;
00840 break;
00841 case TR_URI_PARAMS:
00842 val->rs = (_tr_parsed_uri.params.s)?_tr_parsed_uri.params:_tr_empty;
00843 break;
00844 case TR_URI_PARAM:
00845 if(tp==NULL)
00846 {
00847 LM_ERR("param invalid parameters\n");
00848 return -1;
00849 }
00850 if(_tr_parsed_uri.params.len<=0)
00851 {
00852 val->rs = _tr_empty;
00853 val->flags = PV_VAL_STR;
00854 val->ri = 0;
00855 break;
00856 }
00857
00858 if(_tr_uri_params == NULL)
00859 {
00860 sv = _tr_parsed_uri.params;
00861 if (parse_params(&sv, CLASS_ANY, &phooks, &_tr_uri_params)<0)
00862 return -1;
00863 }
00864 if(tp->type==TR_PARAM_STRING)
00865 {
00866 sv = tp->v.s;
00867 } else {
00868 if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
00869 || (!(v.flags&PV_VAL_STR)) || v.rs.len<=0)
00870 {
00871 LM_ERR("param cannot get p1\n");
00872 return -1;
00873 }
00874 sv = v.rs;
00875 }
00876 for (pit = _tr_uri_params; pit; pit=pit->next)
00877 {
00878 if (pit->name.len==sv.len
00879 && strncasecmp(pit->name.s, sv.s, sv.len)==0)
00880 {
00881 val->rs = pit->body;
00882 goto done;
00883 }
00884 }
00885 val->rs = _tr_empty;
00886 break;
00887 case TR_URI_HEADERS:
00888 val->rs = (_tr_parsed_uri.headers.s)?_tr_parsed_uri.headers:
00889 _tr_empty;
00890 break;
00891 case TR_URI_TRANSPORT:
00892 val->rs = (_tr_parsed_uri.transport_val.s)?
00893 _tr_parsed_uri.transport_val:_tr_empty;
00894 break;
00895 case TR_URI_TTL:
00896 val->rs = (_tr_parsed_uri.ttl_val.s)?
00897 _tr_parsed_uri.ttl_val:_tr_empty;
00898 break;
00899 case TR_URI_UPARAM:
00900 val->rs = (_tr_parsed_uri.user_param_val.s)?
00901 _tr_parsed_uri.user_param_val:_tr_empty;
00902 break;
00903 case TR_URI_MADDR:
00904 val->rs = (_tr_parsed_uri.maddr_val.s)?
00905 _tr_parsed_uri.maddr_val:_tr_empty;
00906 break;
00907 case TR_URI_METHOD:
00908 val->rs = (_tr_parsed_uri.method_val.s)?
00909 _tr_parsed_uri.method_val:_tr_empty;
00910 break;
00911 case TR_URI_LR:
00912 val->rs = (_tr_parsed_uri.lr_val.s)?
00913 _tr_parsed_uri.lr_val:_tr_empty;
00914 break;
00915 case TR_URI_R2:
00916 val->rs = (_tr_parsed_uri.r2_val.s)?
00917 _tr_parsed_uri.r2_val:_tr_empty;
00918 break;
00919 default:
00920 LM_ERR("unknown subtype %d\n",
00921 subtype);
00922 return -1;
00923 }
00924 done:
00925 return 0;
00926 }
00927
00928 static str _tr_params_str = {0, 0};
00929 static param_t* _tr_params_list = NULL;
00930
00931
00940 int tr_eval_paramlist(struct sip_msg *msg, tr_param_t *tp, int subtype,
00941 pv_value_t *val)
00942 {
00943 pv_value_t v;
00944 str sv;
00945 int n, i;
00946 param_hooks_t phooks;
00947 param_t *pit=NULL;
00948
00949 if(val==NULL || (!(val->flags&PV_VAL_STR)) || val->rs.len<=0)
00950 return -1;
00951
00952 if(_tr_params_str.len==0 || _tr_params_str.len!=val->rs.len ||
00953 strncmp(_tr_params_str.s, val->rs.s, val->rs.len)!=0)
00954 {
00955 if(val->rs.len>_tr_params_str.len)
00956 {
00957 if(_tr_params_str.s) pkg_free(_tr_params_str.s);
00958 _tr_params_str.s = (char*)pkg_malloc((val->rs.len+1)*sizeof(char));
00959 if(_tr_params_str.s==NULL)
00960 {
00961 LM_ERR("no more private memory\n");
00962 memset(&_tr_params_str, 0, sizeof(str));
00963 if(_tr_params_list != NULL)
00964 {
00965 free_params(_tr_params_list);
00966 _tr_params_list = 0;
00967 }
00968 return -1;
00969 }
00970 }
00971 _tr_params_str.len = val->rs.len;
00972 memcpy(_tr_params_str.s, val->rs.s, val->rs.len);
00973 _tr_params_str.s[_tr_params_str.len] = '\0';
00974
00975
00976 if(_tr_params_list != NULL)
00977 {
00978 free_params(_tr_params_list);
00979 _tr_params_list = 0;
00980 }
00981
00982
00983 sv = _tr_params_str;
00984 if (parse_params(&sv, CLASS_ANY, &phooks, &_tr_params_list)<0)
00985 return -1;
00986 }
00987
00988 if(_tr_params_list==NULL)
00989 return -1;
00990
00991 memset(val, 0, sizeof(pv_value_t));
00992 val->flags = PV_VAL_STR;
00993
00994 switch(subtype)
00995 {
00996 case TR_PL_VALUE:
00997 if(tp==NULL)
00998 {
00999 LM_ERR("value invalid parameters\n");
01000 return -1;
01001 }
01002
01003 if(tp->type==TR_PARAM_STRING)
01004 {
01005 sv = tp->v.s;
01006 } else {
01007 if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
01008 || (!(v.flags&PV_VAL_STR)) || v.rs.len<=0)
01009 {
01010 LM_ERR("value cannot get p1\n");
01011 return -1;
01012 }
01013 sv = v.rs;
01014 }
01015
01016 for (pit = _tr_params_list; pit; pit=pit->next)
01017 {
01018 if (pit->name.len==sv.len
01019 && strncasecmp(pit->name.s, sv.s, sv.len)==0)
01020 {
01021 val->rs = pit->body;
01022 goto done;
01023 }
01024 }
01025 val->rs = _tr_empty;
01026 break;
01027
01028 case TR_PL_VALUEAT:
01029 if(tp==NULL)
01030 {
01031 LM_ERR("name invalid parameters\n");
01032 return -1;
01033 }
01034
01035 if(tp->type==TR_PARAM_NUMBER)
01036 {
01037 n = tp->v.n;
01038 } else {
01039 if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
01040 || (!(v.flags&PV_VAL_INT)))
01041 {
01042 LM_ERR("name cannot get p1\n");
01043 return -1;
01044 }
01045 n = v.ri;
01046 }
01047 if(n<0)
01048 {
01049 n = -n;
01050 n--;
01051 for (pit = _tr_params_list; pit; pit=pit->next)
01052 {
01053 if(n==0)
01054 {
01055 val->rs = pit->body;
01056 goto done;
01057 }
01058 n--;
01059 }
01060 } else {
01061
01062
01063 i = 0;
01064 for (pit = _tr_params_list; pit; pit=pit->next)
01065 i++;
01066 if(n<i)
01067 {
01068 n = i - n - 1;
01069 for (pit = _tr_params_list; pit; pit=pit->next)
01070 {
01071 if(n==0)
01072 {
01073 val->rs = pit->body;
01074 goto done;
01075 }
01076 n--;
01077 }
01078 }
01079 }
01080 val->rs = _tr_empty;
01081 break;
01082
01083 case TR_PL_NAME:
01084 if(tp==NULL)
01085 {
01086 LM_ERR("name invalid parameters\n");
01087 return -1;
01088 }
01089
01090 if(tp->type==TR_PARAM_NUMBER)
01091 {
01092 n = tp->v.n;
01093 } else {
01094 if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
01095 || (!(v.flags&PV_VAL_INT)))
01096 {
01097 LM_ERR("name cannot get p1\n");
01098 return -1;
01099 }
01100 n = v.ri;
01101 }
01102 if(n<0)
01103 {
01104 n = -n;
01105 n--;
01106 for (pit = _tr_params_list; pit; pit=pit->next)
01107 {
01108 if(n==0)
01109 {
01110 val->rs = pit->name;
01111 goto done;
01112 }
01113 n--;
01114 }
01115 } else {
01116
01117
01118 i = 0;
01119 for (pit = _tr_params_list; pit; pit=pit->next)
01120 i++;
01121 if(n<i)
01122 {
01123 n = i - n - 1;
01124 for (pit = _tr_params_list; pit; pit=pit->next)
01125 {
01126 if(n==0)
01127 {
01128 val->rs = pit->name;
01129 goto done;
01130 }
01131 n--;
01132 }
01133 }
01134 }
01135 val->rs = _tr_empty;
01136 break;
01137
01138 case TR_PL_COUNT:
01139 val->ri = 0;
01140 for (pit = _tr_params_list; pit; pit=pit->next)
01141 val->ri++;
01142 val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
01143 val->rs.s = int2str(val->ri, &val->rs.len);
01144 break;
01145
01146 default:
01147 LM_ERR("unknown subtype %d\n",
01148 subtype);
01149 return -1;
01150 }
01151 done:
01152 return 0;
01153 }
01154
01155 static str _tr_nameaddr_str = {0, 0};
01156 static name_addr_t _tr_nameaddr;
01157
01158
01167 int tr_eval_nameaddr(struct sip_msg *msg, tr_param_t *tp, int subtype,
01168 pv_value_t *val)
01169 {
01170 str sv;
01171 int ret;
01172
01173 if(val==NULL || (!(val->flags&PV_VAL_STR)) || val->rs.len<=0)
01174 return -1;
01175
01176 if(_tr_nameaddr_str.len==0 || _tr_nameaddr_str.len!=val->rs.len ||
01177 strncmp(_tr_nameaddr_str.s, val->rs.s, val->rs.len)!=0)
01178 {
01179 if(val->rs.len>_tr_nameaddr_str.len)
01180 {
01181 if(_tr_nameaddr_str.s)
01182 pkg_free(_tr_nameaddr_str.s);
01183 _tr_nameaddr_str.s = (char*)pkg_malloc((val->rs.len+1)*sizeof(char));
01184
01185 if(_tr_nameaddr_str.s==NULL)
01186 {
01187 LM_ERR("no more private memory\n");
01188 memset(&_tr_nameaddr_str, 0, sizeof(str));
01189 memset(&_tr_nameaddr, 0, sizeof(name_addr_t));
01190 return -1;
01191 }
01192 }
01193 _tr_nameaddr_str.len = val->rs.len;
01194 memcpy(_tr_nameaddr_str.s, val->rs.s, val->rs.len);
01195 _tr_nameaddr_str.s[_tr_nameaddr_str.len] = '\0';
01196
01197
01198 memset(&_tr_nameaddr, 0, sizeof(name_addr_t));
01199
01200
01201 sv = _tr_nameaddr_str;
01202 ret = parse_nameaddr(&sv, &_tr_nameaddr);
01203 if (ret < 0) {
01204 if(ret != -3) return -1;
01205
01206 _tr_nameaddr.uri = _tr_nameaddr_str;
01207 _tr_nameaddr.name = _tr_empty;
01208 _tr_nameaddr.len = _tr_nameaddr_str.len;
01209 }
01210 }
01211
01212 memset(val, 0, sizeof(pv_value_t));
01213 val->flags = PV_VAL_STR;
01214
01215 switch(subtype)
01216 {
01217 case TR_NA_URI:
01218 val->rs = (_tr_nameaddr.uri.s)?_tr_nameaddr.uri:_tr_empty;
01219 break;
01220 case TR_NA_LEN:
01221 val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
01222 val->ri = _tr_nameaddr.len;
01223 val->rs.s = int2str(val->ri, &val->rs.len);
01224 break;
01225 case TR_NA_NAME:
01226 val->rs = (_tr_nameaddr.name.s)?_tr_nameaddr.name:_tr_empty;
01227 break;
01228
01229 default:
01230 LM_ERR("unknown subtype %d\n",
01231 subtype);
01232 return -1;
01233 }
01234 return 0;
01235 }
01236
01237 static str _tr_tobody_str = {0, 0};
01238 static struct to_body _tr_tobody = {0};
01239
01248 int tr_eval_tobody(struct sip_msg *msg, tr_param_t *tp, int subtype,
01249 pv_value_t *val)
01250 {
01251 str sv;
01252
01253 if(val==NULL || (!(val->flags&PV_VAL_STR)) || val->rs.len<=0)
01254 return -1;
01255
01256 if(_tr_tobody_str.len==0 || _tr_tobody_str.len!=val->rs.len ||
01257 strncmp(_tr_tobody_str.s, val->rs.s, val->rs.len)!=0)
01258 {
01259 if(_tr_tobody_str.s==NULL || val->rs.len>_tr_tobody_str.len)
01260 {
01261 if(_tr_tobody_str.s)
01262 pkg_free(_tr_tobody_str.s);
01263 _tr_tobody_str.s = (char*)pkg_malloc((val->rs.len+3)*sizeof(char));
01264
01265 if(_tr_tobody_str.s==NULL)
01266 {
01267 LM_ERR("no more private memory\n");
01268 free_to_params(&_tr_tobody);
01269 memset(&_tr_tobody, 0, sizeof(struct to_body));
01270 memset(&_tr_tobody_str, 0, sizeof(str));
01271 return -1;
01272 }
01273 }
01274 _tr_tobody_str.len = val->rs.len;
01275 memcpy(_tr_tobody_str.s, val->rs.s, val->rs.len);
01276 _tr_tobody_str.s[_tr_tobody_str.len] = '\r';
01277 _tr_tobody_str.s[_tr_tobody_str.len+1] = '\n';
01278 _tr_tobody_str.s[_tr_tobody_str.len+2] = '\0';
01279
01280
01281 free_to_params(&_tr_tobody);
01282 memset(&_tr_tobody, 0, sizeof(struct to_body));
01283
01284
01285 sv = _tr_tobody_str;
01286 parse_to(sv.s, sv.s + sv.len + 2, &_tr_tobody);
01287 if (_tr_tobody.error == PARSE_ERROR)
01288 {
01289 free_to_params(&_tr_tobody);
01290 memset(&_tr_tobody, 0, sizeof(struct to_body));
01291 pkg_free(_tr_tobody_str.s);
01292 memset(&_tr_tobody_str, 0, sizeof(str));
01293 return -1;
01294 }
01295 if (parse_uri(_tr_tobody.uri.s, _tr_tobody.uri.len,
01296 &_tr_tobody.parsed_uri)<0)
01297 {
01298 free_to_params(&_tr_tobody);
01299 memset(&_tr_tobody, 0, sizeof(struct to_body));
01300 pkg_free(_tr_tobody_str.s);
01301 memset(&_tr_tobody_str, 0, sizeof(str));
01302 return -1;
01303 }
01304 }
01305
01306 memset(val, 0, sizeof(pv_value_t));
01307 val->flags = PV_VAL_STR;
01308
01309 switch(subtype)
01310 {
01311 case TR_TOBODY_URI:
01312 val->rs = (_tr_tobody.uri.s)?_tr_tobody.uri:_tr_empty;
01313 break;
01314 case TR_TOBODY_TAG:
01315 val->rs = (_tr_tobody.tag_value.s)?_tr_tobody.tag_value:_tr_empty;
01316 break;
01317 case TR_TOBODY_DISPLAY:
01318 val->rs = (_tr_tobody.display.s)?_tr_tobody.display:_tr_empty;
01319 break;
01320 case TR_TOBODY_URI_USER:
01321 val->rs = (_tr_tobody.parsed_uri.user.s)
01322 ?_tr_tobody.parsed_uri.user:_tr_empty;
01323 break;
01324 case TR_TOBODY_URI_HOST:
01325 val->rs = (_tr_tobody.parsed_uri.host.s)
01326 ?_tr_tobody.parsed_uri.host:_tr_empty;
01327 break;
01328 case TR_TOBODY_PARAMS:
01329 if(_tr_tobody.param_lst!=NULL)
01330 {
01331 val->rs.s = _tr_tobody.param_lst->name.s;
01332 val->rs.len = _tr_tobody_str.s + _tr_tobody_str.len
01333 - val->rs.s;
01334 } else val->rs = _tr_empty;
01335 break;
01336
01337 default:
01338 LM_ERR("unknown subtype %d\n", subtype);
01339 return -1;
01340 }
01341 return 0;
01342 }
01343
01344 void *memfindrchr(const void *buf, int c, size_t n)
01345 {
01346 int i;
01347 unsigned char *p;
01348
01349 p = (unsigned char*)buf;
01350
01351 for (i=n-1; i>=0; i--) {
01352 if (p[i] == (unsigned char)c) {
01353 return (void*)(p+i);
01354 }
01355 }
01356 return NULL;
01357 }
01358
01367 int tr_eval_line(struct sip_msg *msg, tr_param_t *tp, int subtype,
01368 pv_value_t *val)
01369 {
01370 pv_value_t v;
01371 str sv;
01372 str mv;
01373 char *p;
01374 int n, i;
01375
01376 if(val==NULL || (!(val->flags&PV_VAL_STR)) || val->rs.len<=0)
01377 return -1;
01378
01379 switch(subtype)
01380 {
01381 case TR_LINE_SW:
01382 if(tp==NULL)
01383 {
01384 LM_ERR("value invalid parameters\n");
01385 return -1;
01386 }
01387
01388 if(tp->type==TR_PARAM_STRING)
01389 {
01390 sv = tp->v.s;
01391 } else {
01392 if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
01393 || (!(v.flags&PV_VAL_STR)) || v.rs.len<=0)
01394 {
01395 LM_ERR("value cannot get p1\n");
01396 return -1;
01397 }
01398 sv = v.rs;
01399 }
01400
01401 if(val->rs.len < sv.len)
01402 {
01403 val->rs = _tr_empty;
01404 goto done;
01405 }
01406 p = val->rs.s;
01407 do {
01408 if(strncmp(p, sv.s, sv.len)==0)
01409 {
01410
01411 mv.s = p;
01412 p += sv.len;
01413 p = memchr(p, '\n', (val->rs.s + val->rs.len) - p);
01414 if(p==NULL)
01415 {
01416
01417 mv.len = (val->rs.s + val->rs.len) - p;
01418 } else {
01419 mv.len = p - mv.s;
01420 }
01421 val->rs = mv;
01422 goto done;
01423 }
01424 p = memchr(p, '\n', (val->rs.s + val->rs.len) - p);
01425 } while(p && ((++p)<=val->rs.s+val->rs.len-sv.len));
01426 val->rs = _tr_empty;
01427 break;
01428
01429 case TR_LINE_AT:
01430 if(tp==NULL)
01431 {
01432 LM_ERR("name invalid parameters\n");
01433 return -1;
01434 }
01435
01436 if(tp->type==TR_PARAM_NUMBER)
01437 {
01438 n = tp->v.n;
01439 } else {
01440 if(pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
01441 || (!(v.flags&PV_VAL_INT)))
01442 {
01443 LM_ERR("name cannot get p1\n");
01444 return -1;
01445 }
01446 n = v.ri;
01447 }
01448 if(n<0)
01449 {
01450 p = val->rs.s + val->rs.len - 1;
01451 if(*p=='\n')
01452 p--;
01453 mv.s = p;
01454 n = -n;
01455 i=1;
01456 p = memfindrchr(val->rs.s, '\n', p - val->rs.s);
01457 if(p!=NULL)
01458 p--;
01459 while(i<n && p)
01460 {
01461 mv.s = p;
01462 p = memfindrchr(val->rs.s, '\n', p - val->rs.s);
01463 if(p!=NULL)
01464 p--;
01465 i++;
01466 }
01467 if(i==n)
01468 {
01469 if(p==NULL)
01470 {
01471
01472 mv.len = mv.s - val->rs.s + 1;
01473 mv.s = val->rs.s;
01474 } else {
01475 mv.len = mv.s - p - 1;
01476 mv.s = p + 2;
01477 }
01478 val->rs = mv;
01479 goto done;
01480 }
01481 } else {
01482 p = val->rs.s;
01483 i = 0;
01484 while(i<n && p)
01485 {
01486 p = memchr(p, '\n', (val->rs.s + val->rs.len) - p);
01487 if(p!=NULL)
01488 p++;
01489 i++;
01490 }
01491 if(i==n && p!=NULL)
01492 {
01493
01494 mv.s = p;
01495 p = memchr(p, '\n', (val->rs.s + val->rs.len) - p);
01496 if(p==NULL)
01497 {
01498
01499 mv.len = (val->rs.s + val->rs.len) - p;
01500 } else {
01501 mv.len = p - mv.s;
01502 }
01503 val->rs = mv;
01504 goto done;
01505 }
01506 }
01507 val->rs = _tr_empty;
01508 break;
01509
01510 case TR_LINE_COUNT:
01511 n=0;
01512 for(i=0; i<val->rs.len; i++)
01513 if(val->rs.s[i]=='\n')
01514 n++;
01515 if(n==0 && val->rs.len>0)
01516 n = 1;
01517 val->flags = PV_TYPE_INT|PV_VAL_INT|PV_VAL_STR;
01518 val->ri = n;
01519 val->rs.s = int2str(val->ri, &val->rs.len);
01520 break;
01521
01522 break;
01523
01524 default:
01525 LM_ERR("unknown subtype %d\n",
01526 subtype);
01527 return -1;
01528 }
01529 done:
01530 if(val->rs.len>0)
01531 {
01532
01533 if(val->rs.s[val->rs.len-1]=='\r')
01534 val->rs.len--;
01535 }
01536 val->flags = PV_VAL_STR;
01537 return 0;
01538 }
01539
01540
01541 #define _tr_parse_nparam(_p, _p0, _tp, _spec, _n, _sign, _in, _s) \
01542 while(is_in_str(_p, _in) && (*_p==' ' || *_p=='\t' || *_p=='\n')) _p++; \
01543 if(*_p==PV_MARKER) \
01544 { \
01545 _spec = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t)); \
01546 if(_spec==NULL) \
01547 { \
01548 LM_ERR("no more private memory!\n"); \
01549 goto error; \
01550 } \
01551 _s.s = _p; _s.len = _in->s + _in->len - _p; \
01552 _p0 = pv_parse_spec(&_s, _spec); \
01553 if(_p0==NULL) \
01554 { \
01555 LM_ERR("invalid spec in substr transformation: %.*s!\n", \
01556 _in->len, _in->s); \
01557 goto error; \
01558 } \
01559 _p = _p0; \
01560 _tp = (tr_param_t*)pkg_malloc(sizeof(tr_param_t)); \
01561 if(_tp==NULL) \
01562 { \
01563 LM_ERR("no more private memory!\n"); \
01564 goto error; \
01565 } \
01566 memset(_tp, 0, sizeof(tr_param_t)); \
01567 _tp->type = TR_PARAM_SPEC; \
01568 _tp->v.data = (void*)_spec; \
01569 } else { \
01570 if(*_p=='+' || *_p=='-' || (*_p>='0' && *_p<='9')) \
01571 { \
01572 _sign = 1; \
01573 if(*_p=='-') { \
01574 _p++; \
01575 _sign = -1; \
01576 } else if(*_p=='+') _p++; \
01577 _n = 0; \
01578 while(is_in_str(_p, _in) && (*_p==' ' || *_p=='\t' || *_p=='\n')) \
01579 _p++; \
01580 while(is_in_str(_p, _in) && *_p>='0' && *_p<='9') \
01581 { \
01582 _n = _n*10 + *_p - '0'; \
01583 _p++; \
01584 } \
01585 _tp = (tr_param_t*)pkg_malloc(sizeof(tr_param_t)); \
01586 if(_tp==NULL) \
01587 { \
01588 LM_ERR("no more private memory!\n"); \
01589 goto error; \
01590 } \
01591 memset(_tp, 0, sizeof(tr_param_t)); \
01592 _tp->type = TR_PARAM_NUMBER; \
01593 _tp->v.n = sign*n; \
01594 } else { \
01595 LM_ERR("tinvalid param in transformation: %.*s!!\n", \
01596 _in->len, _in->s); \
01597 goto error; \
01598 } \
01599 }
01600
01601 #define _tr_parse_sparam(_p, _p0, _tp, _spec, _ps, _in, _s) \
01602 while(is_in_str(_p, _in) && (*_p==' ' || *_p=='\t' || *_p=='\n')) _p++; \
01603 if(*_p==PV_MARKER) \
01604 { \
01605 _spec = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t)); \
01606 if(_spec==NULL) \
01607 { \
01608 LM_ERR("no more private memory!\n"); \
01609 goto error; \
01610 } \
01611 _s.s = _p; _s.len = _in->s + _in->len - _p; \
01612 _p0 = pv_parse_spec(&_s, _spec); \
01613 if(_p0==NULL) \
01614 { \
01615 LM_ERR("invalid spec in substr transformation: %.*s!\n", \
01616 _in->len, _in->s); \
01617 goto error; \
01618 } \
01619 _p = _p0; \
01620 _tp = (tr_param_t*)pkg_malloc(sizeof(tr_param_t)); \
01621 if(_tp==NULL) \
01622 { \
01623 LM_ERR("no more private memory!\n"); \
01624 goto error; \
01625 } \
01626 memset(_tp, 0, sizeof(tr_param_t)); \
01627 _tp->type = TR_PARAM_SPEC; \
01628 _tp->v.data = (void*)_spec; \
01629 } else { \
01630 _ps = _p; \
01631 while(is_in_str(_p, _in) && *_p!='\t' && *_p!='\n' \
01632 && *_p!=TR_PARAM_MARKER && *_p!=TR_RBRACKET) \
01633 _p++; \
01634 if(*_p=='\0') \
01635 { \
01636 LM_ERR("invalid param in transformation: %.*s!!\n", \
01637 _in->len, _in->s); \
01638 goto error; \
01639 } \
01640 _tp = (tr_param_t*)pkg_malloc(sizeof(tr_param_t)); \
01641 if(_tp==NULL) \
01642 { \
01643 LM_ERR("no more private memory!\n"); \
01644 goto error; \
01645 } \
01646 memset(_tp, 0, sizeof(tr_param_t)); \
01647 _tp->type = TR_PARAM_STRING; \
01648 _tp->v.s.s = _ps; \
01649 _tp->v.s.len = _p - _ps; \
01650 }
01651
01652
01659 char* tr_parse_string(str* in, trans_t *t)
01660 {
01661 char *p;
01662 char *p0;
01663 char *ps;
01664 str name;
01665 str s;
01666 pv_spec_t *spec = NULL;
01667 int n;
01668 int sign;
01669 tr_param_t *tp = NULL;
01670
01671 if(in==NULL || t==NULL)
01672 return NULL;
01673
01674 p = in->s;
01675 name.s = in->s;
01676 t->type = TR_STRING;
01677 t->trf = tr_eval_string;
01678
01679
01680 while(is_in_str(p, in) && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
01681 if(*p=='\0')
01682 {
01683 LM_ERR("invalid transformation: %.*s\n",
01684 in->len, in->s);
01685 goto error;
01686 }
01687 name.len = p - name.s;
01688 trim(&name);
01689
01690 if(name.len==3 && strncasecmp(name.s, "len", 3)==0)
01691 {
01692 t->subtype = TR_S_LEN;
01693 goto done;
01694 } else if(name.len==3 && strncasecmp(name.s, "int", 3)==0) {
01695 t->subtype = TR_S_INT;
01696 goto done;
01697 } else if(name.len==3 && strncasecmp(name.s, "md5", 3)==0) {
01698 t->subtype = TR_S_MD5;
01699 goto done;
01700 } else if(name.len==7 && strncasecmp(name.s, "tolower", 7)==0) {
01701 t->subtype = TR_S_TOLOWER;
01702 goto done;
01703 } else if(name.len==7 && strncasecmp(name.s, "toupper", 7)==0) {
01704 t->subtype = TR_S_TOUPPER;
01705 goto done;
01706 } else if(name.len==11 && strncasecmp(name.s, "encode.hexa", 11)==0) {
01707 t->subtype = TR_S_ENCODEHEXA;
01708 goto done;
01709 } else if(name.len==11 && strncasecmp(name.s, "decode.hexa", 11)==0) {
01710 t->subtype = TR_S_DECODEHEXA;
01711 goto done;
01712 } else if(name.len==13 && strncasecmp(name.s, "escape.common", 13)==0) {
01713 t->subtype = TR_S_ESCAPECOMMON;
01714 goto done;
01715 } else if(name.len==15 && strncasecmp(name.s, "unescape.common", 15)==0) {
01716 t->subtype = TR_S_UNESCAPECOMMON;
01717 goto done;
01718 } else if(name.len==11 && strncasecmp(name.s, "escape.user", 11)==0) {
01719 t->subtype = TR_S_ESCAPEUSER;
01720 goto done;
01721 } else if(name.len==13 && strncasecmp(name.s, "unescape.user", 13)==0) {
01722 t->subtype = TR_S_UNESCAPEUSER;
01723 goto done;
01724 } else if(name.len==12 && strncasecmp(name.s, "escape.param", 12)==0) {
01725 t->subtype = TR_S_ESCAPEPARAM;
01726 goto done;
01727 } else if(name.len==14 && strncasecmp(name.s, "unescape.param", 14)==0) {
01728 t->subtype = TR_S_UNESCAPEPARAM;
01729 goto done;
01730 } else if(name.len==8 && strncasecmp(name.s, "prefixes", 8)==0) {
01731 t->subtype = TR_S_PREFIXES;
01732 if(*p!=TR_PARAM_MARKER)
01733 goto done;
01734 p++;
01735 _tr_parse_nparam(p, p0, tp, spec, n, sign, in, s);
01736 t->params = tp;
01737 tp = 0;
01738 while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++;
01739 if(*p!=TR_RBRACKET)
01740 {
01741 LM_ERR("invalid prefixes transformation: %.*s!!\n",
01742 in->len, in->s);
01743 goto error;
01744 }
01745 goto done;
01746 } else if(name.len==15 && strncasecmp(name.s, "prefixes.quoted", 15)==0) {
01747 t->subtype = TR_S_PREFIXES_QUOT;
01748 if(*p!=TR_PARAM_MARKER)
01749 goto done;
01750 p++;
01751 _tr_parse_nparam(p, p0, tp, spec, n, sign, in, s);
01752 t->params = tp;
01753 tp = 0;
01754 while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++;
01755 if(*p!=TR_RBRACKET)
01756 {
01757 LM_ERR("invalid prefixes transformation: %.*s!!\n",
01758 in->len, in->s);
01759 goto error;
01760 }
01761 goto done;
01762 } else if(name.len==6 && strncasecmp(name.s, "substr", 6)==0) {
01763 t->subtype = TR_S_SUBSTR;
01764 if(*p!=TR_PARAM_MARKER)
01765 {
01766 LM_ERR("invalid substr transformation: %.*s!\n", in->len, in->s);
01767 goto error;
01768 }
01769 p++;
01770 _tr_parse_nparam(p, p0, tp, spec, n, sign, in, s);
01771 t->params = tp;
01772 tp = 0;
01773 while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++;
01774 if(*p!=TR_PARAM_MARKER)
01775 {
01776 LM_ERR("invalid substr transformation: %.*s!\n",
01777 in->len, in->s);
01778 goto error;
01779 }
01780 p++;
01781 _tr_parse_nparam(p, p0, tp, spec, n, sign, in, s);
01782 if(tp->type==TR_PARAM_NUMBER && tp->v.n<0)
01783 {
01784 LM_ERR("substr negative offset\n");
01785 goto error;
01786 }
01787 t->params->next = tp;
01788 tp = 0;
01789 while(is_in_str(p, in) && (*p==' ' || *p=='\t' || *p=='\n')) p++;
01790 if(*p!=TR_RBRACKET)
01791 {
01792 LM_ERR("invalid substr transformation: %.*s!!\n",
01793 in->len, in->s);
01794 goto error;
01795 }
01796 goto done;
01797 } else if(name.len==6 && strncasecmp(name.s, "select", 6)==0) {
01798 t->subtype = TR_S_SELECT;
01799 if(*p!=TR_PARAM_MARKER)
01800 {
01801 LM_ERR("invalid select transformation: %.*s!\n",
01802 in->len, in->s);
01803 goto error;
01804 }
01805 p++;
01806 _tr_parse_nparam(p, p0, tp, spec, n, sign, in, s);
01807 t->params = tp;
01808 tp = 0;
01809 while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++;
01810 if(*p!=TR_PARAM_MARKER || *(p+1)=='\0')
01811 {
01812 LM_ERR("invalid select transformation: %.*s!\n", in->len, in->s);
01813 goto error;
01814 }
01815 p++;
01816 tp = (tr_param_t*)pkg_malloc(sizeof(tr_param_t));
01817 if(tp==NULL)
01818 {
01819 LM_ERR("no more private memory!\n");
01820 goto error;
01821 }
01822 memset(tp, 0, sizeof(tr_param_t));
01823 tp->type = TR_PARAM_STRING;
01824 tp->v.s.s = p;
01825 tp->v.s.len = 1;
01826 t->params->next = tp;
01827 tp = 0;
01828 p++;
01829 while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++;
01830 if(*p!=TR_RBRACKET)
01831 {
01832 LM_ERR("invalid select transformation: %.*s!!\n",
01833 in->len, in->s);
01834 goto error;
01835 }
01836 goto done;
01837 } else if(name.len==5 && strncasecmp(name.s, "strip", 5)==0) {
01838 t->subtype = TR_S_STRIP;
01839 if(*p!=TR_PARAM_MARKER)
01840 {
01841 LM_ERR("invalid strip transformation: %.*s!\n",
01842 in->len, in->s);
01843 goto error;
01844 }
01845 p++;
01846 _tr_parse_nparam(p, p0, tp, spec, n, sign, in, s);
01847 t->params = tp;
01848 tp = 0;
01849 while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++;
01850 if(*p!=TR_RBRACKET)
01851 {
01852 LM_ERR("invalid strip transformation: %.*s!!\n",
01853 in->len, in->s);
01854 goto error;
01855 }
01856 goto done;
01857 } else if(name.len==9 && strncasecmp(name.s, "striptail", 9)==0) {
01858 t->subtype = TR_S_STRIPTAIL;
01859 if(*p!=TR_PARAM_MARKER)
01860 {
01861 LM_ERR("invalid striptail transformation: %.*s!\n",
01862 in->len, in->s);
01863 goto error;
01864 }
01865 p++;
01866 _tr_parse_nparam(p, p0, tp, spec, n, sign, in, s);
01867 t->params = tp;
01868 tp = 0;
01869 while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++;
01870 if(*p!=TR_RBRACKET)
01871 {
01872 LM_ERR("invalid striptail transformation: %.*s!!\n",
01873 in->len, in->s);
01874 goto error;
01875 }
01876 goto done;
01877 } else if(name.len==5 && strncasecmp(name.s, "ftime", 5)==0) {
01878 t->subtype = TR_S_TIMEFORMAT;
01879 if(*p!=TR_PARAM_MARKER)
01880 {
01881 LM_ERR("invalid ftime transformation: %.*s!\n",
01882 in->len, in->s);
01883 goto error;
01884 }
01885 p++;
01886 _tr_parse_sparam(p, p0, tp, spec, ps, in, s);
01887 t->params = tp;
01888 tp = 0;
01889 while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++;
01890 if(*p!=TR_RBRACKET)
01891 {
01892 LM_ERR("invalid ftime transformation: %.*s!!\n",
01893 in->len, in->s);
01894 goto error;
01895 }
01896 goto done;
01897 } else if(name.len==7 && strncasecmp(name.s, "replace", 7)==0) {
01898 t->subtype = TR_S_REPLACE;
01899 if(*p!=TR_PARAM_MARKER)
01900 {
01901 LM_ERR("invalid replace transformation: %.*s!\n", in->len, in->s);
01902 goto error;
01903 }
01904 p++;
01905 _tr_parse_sparam(p, p0, tp, spec, ps, in, s);
01906 t->params = tp;
01907 tp = 0;
01908 while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++;
01909 if(*p!=TR_PARAM_MARKER)
01910 {
01911 LM_ERR("invalid replace transformation: %.*s!\n",
01912 in->len, in->s);
01913 goto error;
01914 }
01915 p++;
01916 _tr_parse_sparam(p, p0, tp, spec, ps, in, s);
01917 t->params->next = tp;
01918 tp = 0;
01919 while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++;
01920 if(*p!=TR_RBRACKET)
01921 {
01922 LM_ERR("invalid replace transformation: %.*s!!\n",
01923 in->len, in->s);
01924 goto error;
01925 }
01926 goto done;
01927 } else if(name.len==4 && strncasecmp(name.s, "trim", 4)==0) {
01928 t->subtype = TR_S_TRIM;
01929 goto done;
01930 } else if(name.len==5 && strncasecmp(name.s, "rtrim", 5)==0) {
01931 t->subtype = TR_S_RTRIM;
01932 goto done;
01933 } else if(name.len==5 && strncasecmp(name.s, "ltrim", 5)==0) {
01934 t->subtype = TR_S_LTRIM;
01935 goto done;
01936 } else if(name.len==2 && strncasecmp(name.s, "rm", 2)==0) {
01937 t->subtype = TR_S_RM;
01938 if(*p!=TR_PARAM_MARKER)
01939 {
01940 LM_ERR("invalid ftime transformation: %.*s!\n",
01941 in->len, in->s);
01942 goto error;
01943 }
01944 p++;
01945 _tr_parse_sparam(p, p0, tp, spec, ps, in, s);
01946 t->params = tp;
01947 tp = 0;
01948 while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++;
01949 if(*p!=TR_RBRACKET)
01950 {
01951 LM_ERR("invalid ftime transformation: %.*s!!\n",
01952 in->len, in->s);
01953 goto error;
01954 }
01955 goto done;
01956 }
01957
01958 LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s,
01959 name.len, name.s, name.len);
01960 error:
01961 if(tp)
01962 tr_param_free(tp);
01963 if(spec)
01964 pv_spec_free(spec);
01965 return NULL;
01966 done:
01967 t->name = name;
01968 return p;
01969 }
01970
01971
01978 char* tr_parse_uri(str* in, trans_t *t)
01979 {
01980 char *p;
01981 char *p0;
01982 char *ps;
01983 str name;
01984 str s;
01985 pv_spec_t *spec = NULL;
01986 tr_param_t *tp = NULL;
01987
01988 if(in==NULL || in->s==NULL || t==NULL)
01989 return NULL;
01990
01991 p = in->s;
01992 name.s = in->s;
01993 t->type = TR_URI;
01994 t->trf = tr_eval_uri;
01995
01996
01997 while(*p && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
01998 if(*p=='\0')
01999 {
02000 LM_ERR("invalid transformation: %.*s\n", in->len, in->s);
02001 goto error;
02002 }
02003 name.len = p - name.s;
02004 trim(&name);
02005
02006 if(name.len==4 && strncasecmp(name.s, "user", 4)==0)
02007 {
02008 t->subtype = TR_URI_USER;
02009 goto done;
02010 } else if((name.len==4 && strncasecmp(name.s, "host", 4)==0)
02011 || (name.len==6 && strncasecmp(name.s, "domain", 6)==0)) {
02012 t->subtype = TR_URI_HOST;
02013 goto done;
02014 } else if(name.len==6 && strncasecmp(name.s, "passwd", 6)==0) {
02015 t->subtype = TR_URI_PASSWD;
02016 goto done;
02017 } else if(name.len==4 && strncasecmp(name.s, "port", 4)==0) {
02018 t->subtype = TR_URI_PORT;
02019 goto done;
02020 } else if(name.len==6 && strncasecmp(name.s, "params", 6)==0) {
02021 t->subtype = TR_URI_PARAMS;
02022 goto done;
02023 } else if(name.len==7 && strncasecmp(name.s, "headers", 7)==0) {
02024 t->subtype = TR_URI_HEADERS;
02025 goto done;
02026 } else if(name.len==5 && strncasecmp(name.s, "param", 5)==0) {
02027 t->subtype = TR_URI_PARAM;
02028 if(*p!=TR_PARAM_MARKER)
02029 {
02030 LM_ERR("invalid param transformation: %.*s\n", in->len, in->s);
02031 goto error;
02032 }
02033 p++;
02034 _tr_parse_sparam(p, p0, tp, spec, ps, in, s);
02035 t->params = tp;
02036 tp = 0;
02037 while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++;
02038 if(*p!=TR_RBRACKET)
02039 {
02040 LM_ERR("invalid param transformation: %.*s!\n", in->len, in->s);
02041 goto error;
02042 }
02043 goto done;
02044 } else if(name.len==9 && strncasecmp(name.s, "transport", 9)==0) {
02045 t->subtype = TR_URI_TRANSPORT;
02046 goto done;
02047 } else if(name.len==3 && strncasecmp(name.s, "ttl", 3)==0) {
02048 t->subtype = TR_URI_TTL;
02049 goto done;
02050 } else if(name.len==6 && strncasecmp(name.s, "uparam", 6)==0) {
02051 t->subtype = TR_URI_UPARAM;
02052 goto done;
02053 } else if(name.len==5 && strncasecmp(name.s, "maddr", 5)==0) {
02054 t->subtype = TR_URI_MADDR;
02055 goto done;
02056 } else if(name.len==6 && strncasecmp(name.s, "method", 6)==0) {
02057 t->subtype = TR_URI_METHOD;
02058 goto done;
02059 } else if(name.len==2 && strncasecmp(name.s, "lr", 2)==0) {
02060 t->subtype = TR_URI_LR;
02061 goto done;
02062 } else if(name.len==2 && strncasecmp(name.s, "r2", 2)==0) {
02063 t->subtype = TR_URI_R2;
02064 goto done;
02065 }
02066
02067 LM_ERR("unknown transformation: %.*s/%.*s!\n", in->len,
02068 in->s, name.len, name.s);
02069 error:
02070 if(tp)
02071 tr_param_free(tp);
02072 if(spec)
02073 pv_spec_free(spec);
02074 return NULL;
02075 done:
02076 t->name = name;
02077 return p;
02078 }
02079
02080
02087 char* tr_parse_paramlist(str* in, trans_t *t)
02088 {
02089 char *p;
02090 char *p0;
02091 char *ps;
02092 str s;
02093 str name;
02094 int n;
02095 int sign;
02096 pv_spec_t *spec = NULL;
02097 tr_param_t *tp = NULL;
02098
02099 if(in==NULL || in->s==NULL || t==NULL)
02100 return NULL;
02101
02102 p = in->s;
02103 name.s = in->s;
02104 t->type = TR_PARAMLIST;
02105 t->trf = tr_eval_paramlist;
02106
02107
02108 while(is_in_str(p, in) && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
02109 if(*p=='\0')
02110 {
02111 LM_ERR("invalid transformation: %.*s\n",
02112 in->len, in->s);
02113 goto error;
02114 }
02115 name.len = p - name.s;
02116 trim(&name);
02117
02118 if(name.len==5 && strncasecmp(name.s, "value", 5)==0)
02119 {
02120 t->subtype = TR_PL_VALUE;
02121 if(*p!=TR_PARAM_MARKER)
02122 {
02123 LM_ERR("invalid value transformation: %.*s\n",
02124 in->len, in->s);
02125 goto error;
02126 }
02127 p++;
02128 _tr_parse_sparam(p, p0, tp, spec, ps, in, s);
02129 t->params = tp;
02130 tp = 0;
02131 while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++;
02132 if(*p!=TR_RBRACKET)
02133 {
02134 LM_ERR("invalid value transformation: %.*s!\n",
02135 in->len, in->s);
02136 goto error;
02137 }
02138 goto done;
02139 } else if(name.len==7 && strncasecmp(name.s, "valueat", 7)==0) {
02140 t->subtype = TR_PL_VALUEAT;
02141 if(*p!=TR_PARAM_MARKER)
02142 {
02143 LM_ERR("invalid name transformation: %.*s\n",
02144 in->len, in->s);
02145 goto error;
02146 }
02147 p++;
02148 _tr_parse_nparam(p, p0, tp, spec, n, sign, in, s)
02149 t->params = tp;
02150 tp = 0;
02151 while(is_in_str(p, in) && (*p==' ' || *p=='\t' || *p=='\n')) p++;
02152 if(*p!=TR_RBRACKET)
02153 {
02154 LM_ERR("invalid name transformation: %.*s!\n",
02155 in->len, in->s);
02156 goto error;
02157 }
02158 goto done;
02159 } else if(name.len==4 && strncasecmp(name.s, "name", 4)==0) {
02160 t->subtype = TR_PL_NAME;
02161 if(*p!=TR_PARAM_MARKER)
02162 {
02163 LM_ERR("invalid name transformation: %.*s\n",
02164 in->len, in->s);
02165 goto error;
02166 }
02167 p++;
02168 _tr_parse_nparam(p, p0, tp, spec, n, sign, in, s)
02169 t->params = tp;
02170 tp = 0;
02171 while(is_in_str(p, in) && (*p==' ' || *p=='\t' || *p=='\n')) p++;
02172 if(*p!=TR_RBRACKET)
02173 {
02174 LM_ERR("invalid name transformation: %.*s!\n",
02175 in->len, in->s);
02176 goto error;
02177 }
02178 goto done;
02179 } else if(name.len==5 && strncasecmp(name.s, "count", 5)==0) {
02180 t->subtype = TR_PL_COUNT;
02181 goto done;
02182 }
02183
02184 LM_ERR("unknown transformation: %.*s/%.*s!\n",
02185 in->len, in->s, name.len, name.s);
02186 error:
02187 if(tp)
02188 tr_param_free(tp);
02189 if(spec)
02190 pv_spec_free(spec);
02191 return NULL;
02192 done:
02193 t->name = name;
02194 return p;
02195 }
02196
02197
02204 char* tr_parse_nameaddr(str* in, trans_t *t)
02205 {
02206 char *p;
02207 str name;
02208
02209 if(in==NULL || t==NULL)
02210 return NULL;
02211
02212 p = in->s;
02213 name.s = in->s;
02214 t->type = TR_NAMEADDR;
02215 t->trf = tr_eval_nameaddr;
02216
02217
02218 while(is_in_str(p, in) && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
02219 if(*p=='\0')
02220 {
02221 LM_ERR("invalid transformation: %.*s\n",
02222 in->len, in->s);
02223 goto error;
02224 }
02225 name.len = p - name.s;
02226 trim(&name);
02227
02228 if(name.len==3 && strncasecmp(name.s, "uri", 3)==0)
02229 {
02230 t->subtype = TR_NA_URI;
02231 goto done;
02232 } else if(name.len==3 && strncasecmp(name.s, "len", 3)==0)
02233 {
02234 t->subtype = TR_NA_LEN;
02235 goto done;
02236 } else if(name.len==4 && strncasecmp(name.s, "name", 4)==0) {
02237 t->subtype = TR_NA_NAME;
02238 goto done;
02239 }
02240
02241
02242 LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s,
02243 name.len, name.s, name.len);
02244 error:
02245 return NULL;
02246 done:
02247 t->name = name;
02248 return p;
02249 }
02250
02257 char* tr_parse_tobody(str* in, trans_t *t)
02258 {
02259 char *p;
02260 str name;
02261
02262 if(in==NULL || t==NULL)
02263 return NULL;
02264
02265 p = in->s;
02266 name.s = in->s;
02267 t->type = TR_TOBODY;
02268 t->trf = tr_eval_tobody;
02269
02270
02271 while(is_in_str(p, in) && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
02272 if(*p=='\0')
02273 {
02274 LM_ERR("invalid transformation: %.*s\n",
02275 in->len, in->s);
02276 goto error;
02277 }
02278 name.len = p - name.s;
02279 trim(&name);
02280
02281 if(name.len==3 && strncasecmp(name.s, "uri", 3)==0)
02282 {
02283 t->subtype = TR_TOBODY_URI;
02284 goto done;
02285 } else if(name.len==3 && strncasecmp(name.s, "tag", 3)==0) {
02286 t->subtype = TR_TOBODY_TAG;
02287 goto done;
02288 } else if(name.len==4 && strncasecmp(name.s, "user", 4)==0) {
02289 t->subtype = TR_TOBODY_URI_USER;
02290 goto done;
02291 } else if(name.len==4 && strncasecmp(name.s, "host", 4)==0) {
02292 t->subtype = TR_TOBODY_URI_HOST;
02293 goto done;
02294 } else if(name.len==6 && strncasecmp(name.s, "params", 6)==0) {
02295 t->subtype = TR_TOBODY_PARAMS;
02296 goto done;
02297 } else if(name.len==7 && strncasecmp(name.s, "display", 7)==0) {
02298 t->subtype = TR_TOBODY_DISPLAY;
02299 goto done;
02300 }
02301
02302
02303 LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s,
02304 name.len, name.s, name.len);
02305 error:
02306 return NULL;
02307 done:
02308 t->name = name;
02309 return p;
02310 }
02311
02318 char* tr_parse_line(str* in, trans_t *t)
02319 {
02320 char *p;
02321 char *p0;
02322 char *ps;
02323 str s;
02324 str name;
02325 int n;
02326 int sign;
02327 pv_spec_t *spec = NULL;
02328 tr_param_t *tp = NULL;
02329
02330
02331 if(in==NULL || t==NULL)
02332 return NULL;
02333
02334 p = in->s;
02335 name.s = in->s;
02336 t->type = TR_LINE;
02337 t->trf = tr_eval_line;
02338
02339
02340 while(is_in_str(p, in) && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
02341 if(*p=='\0')
02342 {
02343 LM_ERR("invalid transformation: %.*s\n",
02344 in->len, in->s);
02345 goto error;
02346 }
02347 name.len = p - name.s;
02348 trim(&name);
02349
02350 if(name.len==2 && strncasecmp(name.s, "at", 2)==0)
02351 {
02352 t->subtype = TR_LINE_AT;
02353 if(*p!=TR_PARAM_MARKER)
02354 {
02355 LM_ERR("invalid name transformation: %.*s\n",
02356 in->len, in->s);
02357 goto error;
02358 }
02359 p++;
02360 _tr_parse_nparam(p, p0, tp, spec, n, sign, in, s)
02361 t->params = tp;
02362 tp = 0;
02363 while(is_in_str(p, in) && (*p==' ' || *p=='\t' || *p=='\n')) p++;
02364 if(*p!=TR_RBRACKET)
02365 {
02366 LM_ERR("invalid name transformation: %.*s!\n",
02367 in->len, in->s);
02368 goto error;
02369 }
02370
02371 goto done;
02372 } else if(name.len==2 && strncasecmp(name.s, "sw", 2)==0) {
02373 t->subtype = TR_LINE_SW;
02374 if(*p!=TR_PARAM_MARKER)
02375 {
02376 LM_ERR("invalid value transformation: %.*s\n",
02377 in->len, in->s);
02378 goto error;
02379 }
02380 p++;
02381 _tr_parse_sparam(p, p0, tp, spec, ps, in, s);
02382 t->params = tp;
02383 tp = 0;
02384 while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++;
02385 if(*p!=TR_RBRACKET)
02386 {
02387 LM_ERR("invalid value transformation: %.*s!\n",
02388 in->len, in->s);
02389 goto error;
02390 }
02391 goto done;
02392 } else if(name.len==5 && strncasecmp(name.s, "count", 5)==0) {
02393 t->subtype = TR_LINE_COUNT;
02394 goto done;
02395 }
02396
02397
02398 LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s,
02399 name.len, name.s, name.len);
02400 error:
02401 return NULL;
02402 done:
02403 t->name = name;
02404 return p;
02405 }