📄 avpops_parse.c
字号:
/* * $Id: avpops_parse.c,v 1.8 2006/05/07 20:48:51 miconda Exp $ * * Copyright (C) 2004 Voice Sistem SRL * * This file is part of Open SIP Express Router. * * AVPOPS OpenSER-module is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * AVPOPS OpenSER-module is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * For any questions about this software and its license, please contact * Voice Sistem at following e-mail address: * office@voice-sistem.ro * * * History: * --------- * 2004-10-04 first version (ramona) * 2004-11-11 DB scheme added (ramona) * 2004-11-17 aligned to new AVP core global aliases (ramona) */#include <stdlib.h>#include <ctype.h>#include "../../ut.h"#include "../../dprint.h"#include "../../usr_avp.h"#include "../../mem/mem.h"#include "avpops_parse.h"#define SCHEME_UUID_COL "uuid_col"#define SCHEME_UUID_COL_LEN (sizeof(SCHEME_UUID_COL)-1)#define SCHEME_USERNAME_COL "username_col"#define SCHEME_USERNAME_COL_LEN (sizeof(SCHEME_USERNAME_COL)-1)#define SCHEME_DOMAIN_COL "domain_col"#define SCHEME_DOMAIN_COL_LEN (sizeof(SCHEME_DOMAIN_COL)-1)#define SCHEME_VALUE_COL "value_col"#define SCHEME_VALUE_COL_LEN (sizeof(SCHEME_VALUE_COL)-1)#define SCHEME_TABLE "table"#define SCHEME_TABLE_LEN (sizeof(SCHEME_TABLE)-1)#define SCHEME_VAL_TYPE "value_type"#define SCHEME_VAL_TYPE_LEN (sizeof(SCHEME_VAL_TYPE)-1)#define SCHEME_INT_TYPE "integer"#define SCHEME_INT_TYPE_LEN (sizeof(SCHEME_INT_TYPE)-1)#define SCHEME_STR_TYPE "string"#define SCHEME_STR_TYPE_LEN (sizeof(SCHEME_STR_TYPE)-1)char *parse_avp_attr(char *s, struct fis_param *attr, char end){ unsigned int uint; str tmp; /*DBG("s=%p s=%c(%d)\n",s,*s,*s);*/ /* search for type identifier */ if ( s[0] && s[1]==':' ) { switch (s[0]) { case 'i': case 'I': attr->opd |= AVPOPS_VAL_INT; break; case 's': case 'S': attr->opd |= AVPOPS_VAL_STR; break; default: LOG(L_ERR,"ERROR:avpops:parse_avp_attr: invalid type '%c'\n", s[0]); goto error; } s += 2; } /* search for the avp name */ tmp.s = s; while ( *s && *s!=end && !isspace((int)*s)) s++; tmp.len = s - tmp.s; if (tmp.len==0) { attr->opd |= AVPOPS_VAL_NONE; } else { if ( attr->opd&AVPOPS_VAL_INT) { /* convert to ID (int) */ if ( str2int( &tmp, &uint)==-1 ) { LOG(L_ERR,"ERROR:avpops:parse_avp_attr: attribute is not " "int as type says <%s>\n", tmp.s); goto error; } attr->sval.p.val.s = 0; attr->sval.p.val.len = (int)uint; } else { /* duplicate name as str NULL terminated */ attr->sval.p.val.s = (char*)pkg_malloc(tmp.len + 1); if (attr->sval.p.val.s==0) { LOG(L_ERR,"ERROR:avpops:parse_avp_attr: no more pkg mem\n"); goto error; } attr->sval.p.val.len = tmp.len; memcpy(attr->sval.p.val.s, tmp.s, tmp.len); attr->sval.p.val.s[attr->sval.p.val.len] = 0; } } return s;error: return 0;}struct fis_param *avpops_parse_pvar(char *s, int flags){ struct fis_param *ap; char *p; /* compose the param structure */ ap = (struct fis_param*)pkg_malloc(sizeof(struct fis_param)); if (ap==0) { LOG(L_ERR,"ERROR:avpops:avpops_parse_pvar: no more pkg mem\n"); return NULL; } memset( ap, 0, sizeof(struct fis_param)); p = xl_parse_spec(s, &ap->sval, flags); if(p==0) { pkg_free(ap); return NULL; } ap->opd |= AVPOPS_VAL_PVAR; return ap;}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) { LOG(L_ERR,"ERROR:avops:parse_avp_db: 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: LOG(L_ERR,"ERROR:avops:parse_avp_db: 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) { LOG(L_ERR, "ERROR:avops:parse_avp_db:: error - bad avp flags\n"); goto error; } } dbp->a.sval.flags |= flags<<24; } else { p = xl_parse_spec(s, &dbp->a.sval, XL_THROW_ERROR|XL_DISABLE_MULTI|XL_DISABLE_COLORS); if (p==0 || *p!='\0' || dbp->a.sval.type!=XL_AVP) { LOG(L_ERR,"ERROR:avops:parse_avp_db: bad param - " "expected : $avp(name) or int/str value\n"); return E_UNSPEC; } if(dbp->a.sval.flags&XL_DPARAM) { dbp->a.opd = AVPOPS_VAL_PVAR; } else { dbp->a.opd = (dbp->a.sval.p.val.s)?AVPOPS_VAL_STR:AVPOPS_VAL_INT; } } /* optimize and keep the attribute name as str also to * speed up db querie builds */ if (!(dbp->a.opd&AVPOPS_VAL_PVAR) && !(dbp->a.opd&AVPOPS_VAL_NONE)) { if (dbp->a.opd&AVPOPS_VAL_STR) { dbp->sa = dbp->a.sval.p.val; dbp->sa.s[dbp->sa.len] = '\0'; } else { ul = (unsigned long)dbp->a.sval.p.val.len; 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; } } /* restore '/' */ if(p0) *p0 = '/'; /* is there a table name ? */ s = p0; 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.opd&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.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) { 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;}struct fis_param* parse_intstr_value(char *p, int len){ struct fis_param *vp; int uint; str val_str; int flags; if (p==0 || len==0) goto error; if (len>1 && *(p+1)==':') { if (*p=='i' || *p=='I') flags = AVPOPS_VAL_INT; else if (*p=='s' || *p=='S') flags = AVPOPS_VAL_STR; else { LOG(L_ERR,"ERROR:avpops:parse_intstr_value: unknown value type " "<%c>\n",*p); goto error; } p += 2; len -= 2; if (*p==0 || len<=0 ) { LOG(L_ERR,"ERROR:avpops:parse_intstr_value: parse error arround " "<%.*s>\n",len,p); goto error; } } else { flags = AVPOPS_VAL_STR; } /* get the value */ vp = (struct fis_param*)pkg_malloc(sizeof(struct fis_param)); if (vp==0) { LOG(L_ERR,"ERROR:avpops:parse_intstr_value: no more pkg mem\n"); goto error;; } memset( vp, 0, sizeof(struct fis_param)); vp->opd = flags; val_str.s = p; val_str.len = len; if (flags&AVPOPS_VAL_INT) { /* convert the value to integer */ if(val_str.len>2 && p[0]=='0' && (p[1]=='x' || p[1]=='X')) { if(hexstr2int(val_str.s+2, val_str.len-2, &uint)) { LOG(L_ERR,"ERROR:avpops:parse_intstr_value: value is not hex" " int as type says <%.*s>\n", val_str.len, val_str.s); goto error; } } else { if(str2sint( &val_str, &uint)==-1) { LOG(L_ERR,"ERROR:avpops:parse_intstr_value: value is not int" " as type says <%.*s>\n", val_str.len, val_str.s); goto error; } } vp->sval.p.val.len = uint; } else { /* duplicate the value as string */ vp->sval.p.val.s = (char*)pkg_malloc((val_str.len+1)*sizeof(char)); if (vp->sval.p.val.s==0) { LOG(L_ERR,"ERROR:avpops:parse_intstr_value: no more pkg mem\n"); goto error; } vp->sval.p.val.len = val_str.len; memcpy(vp->sval.p.val.s, val_str.s, val_str.len); vp->sval.p.val.s[vp->sval.p.val.len] = 0; } return vp;error: return 0;}#define duplicate_str(_p, _str, _error) \ do { \ _p = (char*)pkg_malloc(_str.len+1); \ if (_p==0) \ { \ LOG(L_ERR,"ERROR:avpops:parse_avp_sb_scheme: " \ "no more pkg memory\n");\ goto _error; \ } \ memcpy( _p, _str.s, _str.len); \ _p[_str.len] = 0; \ }while(0)int parse_avp_db_scheme( char *s, struct db_scheme *scheme){ str foo; str bar; char *p; if (s==0 || *s==0) goto error;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -