pv_trans.c

Go to the documentation of this file.
00001 /*
00002  * $Id$
00003  *
00004  * Copyright (C) 2007 voice-system.ro
00005  * Copyright (C) 2009 asipto.com
00006  *
00007  * This file is part of Kamailio, a free SIP server.
00008  *
00009  * Kamailio is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version
00013  *
00014  * Kamailio is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License 
00020  * along with this program; if not, write to the Free Software 
00021  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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                                 { /* to end */
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                         { /* to end */
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                         /* Set maximum prefix length */
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                 /* reset old values */
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                 /* parse uri -- params only when requested */
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                 /* reset old values */
00976                 if(_tr_params_list != NULL)
00977                 {
00978                         free_params(_tr_params_list);
00979                         _tr_params_list = 0;
00980                 }
00981                 
00982                 /* parse params */
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                                 /* ugly hack -- params are in reverse order 
01062                                  * - first count then find */
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                                 /* ugly hack -- params are in reverse order 
01117                                  * - first count then find */
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                 /* reset old values */
01198                 memset(&_tr_nameaddr, 0, sizeof(name_addr_t));
01199                 
01200                 /* parse params */
01201                 sv = _tr_nameaddr_str;
01202                 ret = parse_nameaddr(&sv, &_tr_nameaddr);
01203                 if (ret < 0) {
01204                         if(ret != -3) return -1;
01205                         /* -3 means no "<" found so treat whole nameaddr as an URI */
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                 /* reset old values */
01281                 free_to_params(&_tr_tobody);
01282                 memset(&_tr_tobody, 0, sizeof(struct to_body));
01283                 
01284                 /* parse params */
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                                         /* match */
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                                                 /* last line */
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                                                 /* first line */
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                                         /* line found */
01494                                         mv.s = p;
01495                                         p = memchr(p, '\n', (val->rs.s + val->rs.len) - p);
01496                                         if(p==NULL)
01497                                         {
01498                                                 /* last line */
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                 /* skip ending '\r' if present */
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         { /* pseudo-variable */ \
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                 { /* number */ \
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         { /* pseudo-variable */ \
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 { /* string */ \
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         /* find next token */
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         /* find next token */
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         /* find next token */
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         /* find next token */
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         /* find next token */
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         /* find next token */
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 }