txt_var.c

Go to the documentation of this file.
00001 /**
00002  * $Id$
00003  *
00004  * Copyright (C) 2008 Elena-Ramona Modroiu (asipto.com)
00005  *
00006  * This file is part of kamailio, a free SIP server.
00007  *
00008  * openser is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * openser is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  */
00022 
00023 #include <stdio.h>
00024 #include <string.h>
00025 #include <sys/types.h>
00026 #include <unistd.h>
00027 
00028 #include "../../mem/mem.h"
00029 #include "../../dprint.h"
00030 #include "../../trim.h"
00031 #include "../../re.h"
00032 
00033 #include "txt_var.h"
00034 
00035 #define is_in_str(p, in) (p<in->s+in->len && *p)
00036 
00037 int tr_txt_eval_re(struct sip_msg *msg, tr_param_t *tp, int subtype,
00038       pv_value_t *val)
00039 {
00040    struct subst_expr *se = NULL;
00041    int nmatches;
00042    str* result;
00043 #define TR_TXT_BUF_SIZE 2048
00044    char tr_txt_buf[TR_TXT_BUF_SIZE];
00045 
00046    if(val==NULL || (!(val->flags&PV_VAL_STR)) || val->rs.len<=0)
00047       return -1;
00048    
00049    switch(subtype)
00050    {
00051       case TR_TXT_RE_SUBST:
00052          se = (struct subst_expr*)tp->v.data;
00053          if(se==NULL)
00054             return 0;
00055          if(val->rs.len>=TR_TXT_BUF_SIZE-1)
00056          {
00057             LM_ERR("PV value too big %d, increase buffer size\n",
00058                   val->rs.len);
00059             return -1;
00060          }
00061          memcpy(tr_txt_buf, val->rs.s, val->rs.len);
00062          tr_txt_buf[val->rs.len] = '\0';
00063          /* pkg malloc'ed result */
00064          result=subst_str(tr_txt_buf, msg, se, &nmatches);
00065          if (result == NULL)
00066          {
00067             if (nmatches<0)
00068                LM_ERR("subst failed\n");
00069             return -1;
00070          }
00071          if(result->len>=TR_TXT_BUF_SIZE-1)
00072          {
00073             LM_ERR("subst result too big %d, increase buffer size\n",
00074                   result->len);
00075             return -1;
00076          }
00077          memcpy(tr_txt_buf, result->s, result->len);
00078          tr_txt_buf[result->len] = '\0';
00079          memset(val, 0, sizeof(pv_value_t));
00080          val->flags = PV_VAL_STR;
00081          val->rs.s = tr_txt_buf;
00082          val->rs.len = result->len;
00083          pkg_free(result->s);
00084          pkg_free(result);
00085          break;
00086       default:
00087          LM_ERR("unknown subtype %d\n", subtype);
00088          return -1;
00089    }
00090    return 0;
00091 
00092 }
00093 
00094 char* tr_txt_parse_re(str *in, trans_t *t)
00095 {
00096    char *p;
00097    str name;
00098    str tok;
00099    struct subst_expr *se = NULL;
00100    tr_param_t *tp = NULL;
00101    int n;
00102 
00103 
00104    if(in==NULL || t==NULL)
00105       return NULL;
00106 
00107    p = in->s;
00108    name.s = in->s;
00109    t->type = TR_TXT_RE;
00110    t->trf = tr_txt_eval_re;
00111 
00112    /* find next token */
00113    while(is_in_str(p, in) && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
00114    if(*p=='\0')
00115       goto error;
00116    name.len = p - name.s;
00117    trim(&name);
00118 
00119    if(name.len==5 && strncasecmp(name.s, "subst", 5)==0)
00120    {
00121       t->subtype = TR_TXT_RE_SUBST;
00122       if(*p!=TR_PARAM_MARKER)
00123          goto error;
00124       p++;
00125       /* get trans here */
00126       n = 0;
00127       tok.s = p;
00128       while(is_in_str(p, in))
00129       {
00130          if(*p==TR_RBRACKET)
00131          {
00132             if(n==0)
00133                   break;
00134             n--;
00135          }
00136          if(*p == TR_LBRACKET)
00137             n++;
00138          p++;
00139       }
00140       if(!is_in_str(p, in))
00141          goto error;
00142       if(p==tok.s)
00143          goto error;
00144       tok.len = p - tok.s;
00145       tp = (tr_param_t*)pkg_malloc(sizeof(tr_param_t));
00146       if(tp==NULL)
00147       {
00148          LM_ERR("no more private memory!\n");
00149          goto error;
00150       }
00151 
00152       se=subst_parser(&tok);
00153 
00154       if (se==0)
00155          goto error;
00156       tp->type = TR_PARAM_SUBST;
00157       tp->v.data = (void*)se;
00158       t->params = tp;
00159 
00160       while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++;
00161       if(*p!=TR_RBRACKET)
00162          goto error;
00163       goto done;
00164    }
00165 
00166    LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s,
00167          name.len, name.s, name.len);
00168 error:
00169    LM_ERR("invalid transformation [%.*s] <%d>\n", in->len, in->s,
00170          (int)(p-in->s));
00171    if(tp!=NULL)
00172       pkg_free(tp);
00173    if(se!=NULL)
00174       subst_expr_free(se);
00175    return NULL;
00176 done:
00177    t->name = name;
00178    return p;
00179 
00180 }
00181 

Generated on Thu May 24 20:00:33 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6