int pv_parse_index(pv_spec_p sp, str *in) { char *p; char *s; int sign; pv_spec_p nsp = 0; if(in==NULL || in->s==NULL || sp==NULL) return -1; p = in->s; if(*p==PV_MARKER) { nsp = (pv_spec_p)pkg_malloc(sizeof(pv_spec_t)); if(nsp==NULL) { LM_ERR("no more memory\n"); return -1; } s = pv_parse_spec(in, nsp); if(s==NULL) { LM_ERR("invalid index [%.*s]\n", in->len, in->s); pv_spec_free(nsp); return -1; } sp->pvp.pvi.type = PV_IDX_PVAR; sp->pvp.pvi.u.dval = (void*)nsp; return 0; } if(*p=='*' && in->len==1) { sp->pvp.pvi.type = PV_IDX_ALL; return 0; } if(*p=='+' && in->len==1) { sp->pvp.pvi.type = PV_IDX_ITR; return 0; } sign = 1; if(*p=='-') { sign = -1; p++; } sp->pvp.pvi.u.ival = 0; while(p<in->s+in->len && *p>='0' && *p<='9') { sp->pvp.pvi.u.ival = sp->pvp.pvi.u.ival * 10 + *p - '0'; p++; } if(p!=in->s+in->len) { LM_ERR("invalid index [%.*s]\n", in->len, in->s); return -1; } sp->pvp.pvi.u.ival *= sign; sp->pvp.pvi.type = PV_IDX_INT; return 0; }
static int pv_parse_rl_count(pv_spec_p sp, str *in) { char *p; char *s; pv_spec_p nsp = 0; if(in==NULL || in->s==NULL || sp==NULL) return -1; p = in->s; if(*p==PV_MARKER) { nsp = (pv_spec_p)pkg_malloc(sizeof(pv_spec_t)); if(nsp==NULL) { LM_ERR("no more memory\n"); return -1; } s = pv_parse_spec(in, nsp); if(s==NULL) { LM_ERR("invalid name [%.*s]\n", in->len, in->s); pv_spec_free(nsp); return -1; } sp->pvp.pvn.type = PV_NAME_PVAR; sp->pvp.pvn.u.dname = (void*)nsp; return 0; } sp->pvp.pvn.type = PV_NAME_INTSTR; sp->pvp.pvn.u.isname.name.s = *in; return 0; }
/*! * \brief Group ID fixup * \param param fixed parameter * \param param_no number of parameters * \return 0 on success, negative on failure */ static int get_gid_fixup(void** param, int param_no) { pv_spec_t *sp; void *ptr; str name; if (param_no == 1) { ptr = *param; if ( (*param = (void*)get_hf( ptr ))==0 ) return E_UNSPEC; } else if (param_no == 2) { name.s = (char*)*param; name.len = strlen(name.s); sp = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t)); if (sp == NULL) { LM_ERR("no more pkg memory\n"); return E_UNSPEC; } if(pv_parse_spec(&name, sp)==NULL || sp->type!=PVT_AVP) { LM_ERR("bad AVP spec <%s>\n", name.s); pv_spec_free(sp); return E_UNSPEC; } *param = sp; } return 0; }
/*! * \brief Free transformation parameter list * \param tp transformation list */ void tr_param_free(tr_param_t *tp) { tr_param_t *tp0; if(tp==NULL) return; while(tp) { tp0 = tp; tp = tp->next; if(tp0->type==TR_PARAM_SPEC) pv_spec_free((pv_spec_t*)tp0->v.data); pkg_free(tp0); } }
/** fparam_t free function. * Frees the "content" of a fparam, but not the fparam itself. * Note: it doesn't free fp->orig! * Assumes pkg_malloc'ed content. * @param fp - fparam to be freed * */ void fparam_free_contents(fparam_t* fp) { if (fp==0) return; switch(fp->type) { case FPARAM_UNSPEC: case FPARAM_STRING: /* asciiz string, not str */ case FPARAM_INT: case FPARAM_STR: /* nothing to do */ break; case FPARAM_REGEX: if (fp->v.regex){ regfree(fp->v.regex); pkg_free(fp->v.regex); fp->v.regex=0; } break; case FPARAM_AVP: free_avp_name(&fp->v.avp.flags, &fp->v.avp.name); break; case FPARAM_SELECT: if (fp->v.select){ free_select(fp->v.select); fp->v.select=0; } break; case FPARAM_SUBST: if (fp->v.subst){ subst_expr_free(fp->v.subst); fp->v.subst=0; } break; case FPARAM_PVS: if (fp->v.pvs){ pv_spec_free(fp->v.pvs); fp->v.pvs=0; } break; case FPARAM_PVE: if (fp->v.pve){ pv_elem_free_all(fp->v.pve); fp->v.pve=0; } break; } }
int pv_parse_acc_leg_index(pv_spec_p sp, str* in) { int idx; pv_spec_p e; if (in == NULL || in->s == NULL || in->len == 0) { LM_ERR("bad index!\n"); return -1; } if (sp == NULL) { LM_ERR("bad pv spec!\n"); return -1; } str_trim_spaces_lr(*in); if (in->s[0] == PV_MARKER) { e=pkg_malloc(sizeof(pv_spec_t)); if (e==NULL) { LM_ERR("no more pkg mem!\n"); return -1; } memset(e, 0, sizeof(pv_spec_t)); if (pv_parse_spec(in, e) == NULL) { LM_ERR("failed to parse index variable!\n"); pv_spec_free(e); return -1; } sp->pvp.pvi.type = PV_IDX_PVAR; sp->pvp.pvi.u.dval = (void *)e; } else { if (str2sint(in, &idx) < 0) { LM_ERR("bad index! not a number! <%.*s>!\n", in->len, in->s); return -1; } sp->pvp.pvi.type = PV_IDX_INT; sp->pvp.pvi.u.ival = idx; } return 0; }
/** * parse AVP name * @return 0 on success, -1 on error */ int pv_parse_avp_name(pv_spec_p sp, str *in) { char *p; char *s; pv_spec_p nsp = 0; if(in==NULL || in->s==NULL || sp==NULL) return -1; p = in->s; if(*p==PV_MARKER) { nsp = (pv_spec_p)pkg_malloc(sizeof(pv_spec_t)); if(nsp==NULL) { LM_ERR("no more memory\n"); return -1; } s = pv_parse_spec(in, nsp); if(s==NULL) { LM_ERR("invalid name [%.*s]\n", in->len, in->s); pv_spec_free(nsp); return -1; } //LM_ERR("dynamic name [%.*s]\n", in->len, in->s); //pv_print_spec(nsp); sp->pvp.pvn.type = PV_NAME_PVAR; sp->pvp.pvn.u.dname = (void*)nsp; return 0; } /*LM_DBG("static name [%.*s]\n", in->len, in->s);*/ if(km_parse_avp_spec(in, &sp->pvp.pvn.u.isname.type, &sp->pvp.pvn.u.isname.name)!=0) { LM_ERR("bad avp name [%.*s]\n", in->len, in->s); return -1; } sp->pvp.pvn.type = PV_NAME_INTSTR; return 0; }
/*! * \brief Helper fuction to parse a kazoo transformation * \param in parsed string * \param t transformation * \return pointer to the end of the transformation in the string - '}', null on error */ char* kz_tr_parse(str* in, trans_t *t) { char *p; char *p0; char *ps; str name; str s; pv_spec_t *spec = NULL; tr_param_t *tp = NULL; if(in==NULL || t==NULL) return NULL; p = in->s; name.s = in->s; t->type = TR_KAZOO; t->trf = kz_tr_eval; /* find next token */ while(is_in_str(p, in) && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++; if(*p=='\0') { LM_ERR("invalid transformation: %.*s\n", in->len, in->s); goto error; } name.len = p - name.s; trim(&name); if(name.len==6 && strncasecmp(name.s, "encode", 6)==0) { t->subtype = TR_KAZOO_ENCODE; goto done; } else if(name.len==4 && strncasecmp(name.s, "json", 4)==0) { t->subtype = TR_KAZOO_JSON; if(*p!=TR_PARAM_MARKER) { LM_ERR("invalid json transformation: %.*s!\n", in->len, in->s); goto error; } p++; _kz_tr_parse_sparam(p, p0, tp, spec, ps, in, s); t->params = tp; tp = 0; while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++; if(*p!=TR_RBRACKET) { LM_ERR("invalid json transformation: %.*s!!\n", in->len, in->s); goto error; } goto done; } LM_ERR("unknown kazoo transformation: %.*s/%.*s/%d!\n", in->len, in->s, name.len, name.s, name.len); error: if(tp) tr_param_free(tp); if(spec) pv_spec_free(spec); return NULL; done: t->name = name; return p; }