int parse_avp_db(char *s, struct db_param *dbp, int allow_scheme) { unsigned long ul; str tmp; str s0; char have_scheme; char *p; char *p0; unsigned int flags; tmp.s = s; /* parse the attribute name - check first if it's not an alias */ p0=strchr(tmp.s, '/'); if(p0!=NULL) *p0=0; if ( *s!='$') { if(strlen(s)<1) { LM_ERR("bad param - expected : $avp(name), *, s or i value\n"); return E_UNSPEC; } switch(*s) { case 's': case 'S': dbp->a.opd = AVPOPS_VAL_NONE|AVPOPS_VAL_STR; break; case 'i': case 'I': dbp->a.opd = AVPOPS_VAL_NONE|AVPOPS_VAL_INT; break; case '*': case 'a': case 'A': dbp->a.opd = AVPOPS_VAL_NONE; break; default: LM_ERR("bad param - expected : *, s or i AVP flag\n"); return E_UNSPEC; } /* flags */ flags = 0; if(*(s+1)!='\0') { s0.s = s+1; s0.len = strlen(s0.s); if(str2int(&s0, &flags)!=0) { LM_ERR("error - bad avp flags\n"); goto error; } } dbp->a.u.sval.pvp.pvn.u.isname.type |= (flags<<8)&0xff00; dbp->a.type = AVPOPS_VAL_NONE; } else { s0.s = s; s0.len = strlen(s0.s); p = pv_parse_spec(&s0, &dbp->a.u.sval); if (p==0 || *p!='\0' || dbp->a.u.sval.type!=PVT_AVP) { LM_ERR("bad param - expected : $avp(name) or int/str value\n"); return E_UNSPEC; } dbp->a.type = AVPOPS_VAL_PVAR; } /* optimize and keep the attribute name as str also to * speed up db querie builds */ if (dbp->a.type == AVPOPS_VAL_PVAR) { dbp->a.opd = AVPOPS_VAL_PVAR; if(pv_has_sname(&dbp->a.u.sval)) { dbp->sa.s=(char*)pkg_malloc( dbp->a.u.sval.pvp.pvn.u.isname.name.s.len+1); if (dbp->sa.s==0) { LM_ERR("no more pkg mem\n"); goto error; } memcpy(dbp->sa.s, dbp->a.u.sval.pvp.pvn.u.isname.name.s.s, dbp->a.u.sval.pvp.pvn.u.isname.name.s.len); dbp->sa.len = dbp->a.u.sval.pvp.pvn.u.isname.name.s.len; dbp->sa.s[dbp->sa.len] = 0; dbp->a.opd = AVPOPS_VAL_PVAR|AVPOPS_VAL_STR; } else if(pv_has_iname(&dbp->a.u.sval)) { ul = (unsigned long)dbp->a.u.sval.pvp.pvn.u.isname.name.n; tmp.s = int2str( ul, &(tmp.len) ); dbp->sa.s = (char*)pkg_malloc( tmp.len + 1 ); if (dbp->sa.s==0) { LM_ERR("no more pkg mem\n"); goto error; } memcpy( dbp->sa.s, tmp.s, tmp.len); dbp->sa.len = tmp.len; dbp->sa.s[dbp->sa.len] = 0; dbp->a.opd = AVPOPS_VAL_PVAR|AVPOPS_VAL_INT; } } /* restore '/' */ if(p0) *p0 = '/'; /* is there a table name ? */ s = p0; if (s && *s) { s++; if (*s=='$') { if (allow_scheme==0) { LM_ERR("function doesn't support DB schemes\n"); goto error; } if (dbp->a.opd&AVPOPS_VAL_NONE) { LM_ERR("inconsistent usage of " "DB scheme without complet specification of AVP name\n"); goto error; } have_scheme = 1; s++; } else { have_scheme = 0; } tmp.s = s; tmp.len = 0; while ( *s ) s++; tmp.len = s - tmp.s; if (tmp.len==0) { LM_ERR("empty scheme/table name\n"); goto error; } if (have_scheme) { dbp->scheme = avp_get_db_scheme( tmp.s ); if (dbp->scheme==0) { LM_ERR("scheme <%s> not found\n", tmp.s); goto error; } /* update scheme flags with AVP name type*/ dbp->scheme->db_flags|=dbp->a.opd&AVPOPS_VAL_STR?AVP_NAME_STR:0; } else { /* duplicate table as str NULL terminated */ dbp->table = (char*)pkg_malloc( tmp.len + 1 ); if (dbp->table==0) { LM_ERR("no more pkg mem\n"); goto error;; } memcpy( dbp->table, tmp.s, tmp.len); dbp->table[tmp.len] = 0; } } return 0; error: return -1; }
int parse_avp_db(char *s, struct db_param *dbp, int allow_scheme) { unsigned long ul; str tmp; char c; char have_scheme; int type; /* parse the attribute name - check first if it's not an alias */ if ( *s=='$') { tmp.s = ++s; /* is an avp alias -> see where it ends */ if ( (s=strchr(tmp.s, '/'))!=0 ) { c = *s; tmp.len = s - tmp.s; } else { c = 0; tmp.len = strlen(tmp.s); } if (tmp.len==0) { LOG(L_ERR,"ERROR:avpops:parse_avp_db: empty alias in <%s>\n", s); goto error; } /* search the alias */ if ( lookup_avp_galias( &tmp, &type, &dbp->a.val)!=0 ) { LOG(L_ERR,"ERROR:avpops:parse_avp_db: unknow alias" "\"%s\"\n", tmp.s); goto error; } dbp->a.flags = (type&AVP_NAME_STR)?AVPOPS_VAL_STR:AVPOPS_VAL_INT; } else { if ( (s=parse_avp_attr( s, &(dbp->a), '/'))==0 ) goto error; if (*s!=0 && *s!='/') { LOG(L_ERR,"ERROR:avpops:parse_avp_db: parse error arround " "<%s>\n",s); goto error; } } dbp->a.flags |= AVPOPS_VAL_AVP; /* optimize asn keep the attribute name as str also to * speed up db querie builds */ if (!(dbp->a.flags&AVPOPS_VAL_NONE)) { if (dbp->a.flags&AVPOPS_VAL_STR) { dbp->sa = dbp->a.val.s; } else { ul = (unsigned long)dbp->a.val.n; tmp.s = int2str( ul, &(tmp.len) ); dbp->sa.s = (char*)pkg_malloc( tmp.len + 1 ); if (dbp->sa.s==0) { LOG(L_ERR,"ERROR:avpops:parse_avp_db: no more pkg mem\n"); goto error; } memcpy( dbp->sa.s, tmp.s, tmp.len); dbp->sa.len = tmp.len; dbp->sa.s[dbp->sa.len] = 0; } } /* is there a table name ? */ if (s && *s) { s++; if (*s=='$') { if (allow_scheme==0) { LOG(L_ERR,"ERROR:avpops:parse_avp_db: function doesn't " "support DB schemes\n"); goto error; } if (dbp->a.flags&AVPOPS_VAL_NONE) { LOG(L_ERR,"ERROR:avpops:parse_avp_db: inconsistent usage of " "DB scheme without complet specification of AVP name\n"); goto error; } have_scheme = 1; s++; } else { have_scheme = 0; } tmp.s = s; tmp.len = 0; while ( *s ) s++; tmp.len = s - tmp.s; if (tmp.len==0) { LOG(L_ERR,"ERROR:avpops:parse_av_dbp: empty scheme/table name\n"); goto error; } if (have_scheme) { dbp->scheme = avp_get_db_scheme( tmp.s ); if (dbp->scheme==0) { LOG(L_ERR,"ERROR:avpops:parse_avp_db: scheme <%s> not found\n", tmp.s); goto error; } /* update scheme flags with AVP name type*/ dbp->scheme->db_flags|=dbp->a.flags&AVPOPS_VAL_STR?AVP_NAME_STR:0; } else { /* duplicate table as str NULL terminated */ dbp->table = (char*)pkg_malloc( tmp.len + 1 ); if (dbp->table==0) { LOG(L_ERR,"ERROR:avpops:parse_avp_db: no more pkg mem\n"); goto error;; } memcpy( dbp->table, tmp.s, tmp.len); dbp->table[tmp.len] = 0; } } return 0; error: return -1; }