|
@@ -24,7 +24,9 @@
|
|
|
|
|
|
#include "../../mem/shm_mem.h"
|
|
|
#include "../../mem/mem.h"
|
|
|
+#include "../../shm_init.h"
|
|
|
#include "../../dprint.h"
|
|
|
+#include "../../parser/parse_param.h"
|
|
|
#include "../../lib/kcore/hash_func.h"
|
|
|
#include "../../ut.h"
|
|
|
#include "../../re.h"
|
|
@@ -38,8 +40,104 @@
|
|
|
|
|
|
|
|
|
ht_t *_ht_root = NULL;
|
|
|
-ht_t *_ht_pkg_root = NULL;
|
|
|
|
|
|
+typedef struct _keyvalue {
|
|
|
+ str key;
|
|
|
+ str value;
|
|
|
+ int type;
|
|
|
+ union {
|
|
|
+ param_t *params;
|
|
|
+ } u;
|
|
|
+} keyvalue_t;
|
|
|
+
|
|
|
+
|
|
|
+#define KEYVALUE_TYPE_NONE 0
|
|
|
+#define KEYVALUE_TYPE_PARAMS 1
|
|
|
+
|
|
|
+/**
|
|
|
+ * parse a string like: 'key=>value'
|
|
|
+ * - the value can be parameter list: 'name1=value1;...;nameX=valueX'
|
|
|
+ */
|
|
|
+int keyvalue_parse_str(str *data, int type, keyvalue_t *res)
|
|
|
+{
|
|
|
+ char *p;
|
|
|
+ str s;
|
|
|
+ str in;
|
|
|
+ param_hooks_t phooks;
|
|
|
+
|
|
|
+ if(data==NULL || data->s==NULL || data->len<=0 || res==NULL)
|
|
|
+ {
|
|
|
+ LM_ERR("invalid parameters\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ memset(res, 0, sizeof(keyvalue_t));
|
|
|
+
|
|
|
+ in.s = data->s;
|
|
|
+ in.len = data->len;
|
|
|
+
|
|
|
+ p = in.s;
|
|
|
+ while(p<in.s+in.len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
|
|
|
+ p++;
|
|
|
+ if(p>in.s+in.len || *p=='\0')
|
|
|
+ goto error;
|
|
|
+ res->key.s = p;
|
|
|
+ while(p < in.s + in.len)
|
|
|
+ {
|
|
|
+ if(*p=='=' || *p==' ' || *p=='\t' || *p=='\n' || *p=='\r')
|
|
|
+ break;
|
|
|
+ p++;
|
|
|
+ }
|
|
|
+ if(p>in.s+in.len || *p=='\0')
|
|
|
+ goto error;
|
|
|
+ res->key.len = (int)(p - res->key.s);
|
|
|
+ if(*p!='=')
|
|
|
+ {
|
|
|
+ while(p<in.s+in.len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
|
|
|
+ p++;
|
|
|
+ if(p>in.s+in.len || *p=='\0' || *p!='=')
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
+ p++;
|
|
|
+ if(*p!='>')
|
|
|
+ goto error;
|
|
|
+ p++;
|
|
|
+ while(p<in.s+in.len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
|
|
|
+ p++;
|
|
|
+
|
|
|
+ s.s = p;
|
|
|
+ s.len = in.s + in.len - p;
|
|
|
+ res->value.s = s.s;
|
|
|
+ res->value.len = s.len;
|
|
|
+ res->type = type;
|
|
|
+ if(type==KEYVALUE_TYPE_PARAMS)
|
|
|
+ {
|
|
|
+ if(s.s[s.len-1]==';')
|
|
|
+ s.len--;
|
|
|
+ if (parse_params(&s, CLASS_ANY, &phooks, &res->u.params)<0)
|
|
|
+ {
|
|
|
+ LM_ERR("failed parsing params value\n");
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+error:
|
|
|
+ LM_ERR("invalid input parameter [%.*s] at [%d]\n", in.len, in.s,
|
|
|
+ (int)(p-in.s));
|
|
|
+ return -1;
|
|
|
+}
|
|
|
+
|
|
|
+void keyvalue_destroy(keyvalue_t *res)
|
|
|
+{
|
|
|
+ if(res==NULL)
|
|
|
+ return;
|
|
|
+ if(res->type==KEYVALUE_TYPE_PARAMS)
|
|
|
+ {
|
|
|
+ if(res->u.params!=NULL)
|
|
|
+ free_params(res->u.params);
|
|
|
+ }
|
|
|
+ memset(res, 0, sizeof(keyvalue_t));
|
|
|
+}
|
|
|
|
|
|
ht_cell_t* ht_cell_new(str *name, int type, int_str *val, unsigned int cellid)
|
|
|
{
|
|
@@ -86,7 +184,6 @@ int ht_cell_free(ht_cell_t *cell)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
int ht_cell_pkg_free(ht_cell_t *cell)
|
|
|
{
|
|
|
if(cell==NULL)
|
|
@@ -95,6 +192,7 @@ int ht_cell_pkg_free(ht_cell_t *cell)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
ht_t* ht_get_table(str *name)
|
|
|
{
|
|
|
unsigned int htid;
|
|
@@ -117,7 +215,7 @@ ht_t* ht_get_table(str *name)
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
-int ht_pkg_init(str *name, int autoexp, str *dbtable, int size, int dbmode)
|
|
|
+int ht_add_table(str *name, int autoexp, str *dbtable, int size, int dbmode)
|
|
|
{
|
|
|
unsigned int htid;
|
|
|
ht_t *ht;
|
|
@@ -125,7 +223,7 @@ int ht_pkg_init(str *name, int autoexp, str *dbtable, int size, int dbmode)
|
|
|
htid = ht_compute_hash(name);
|
|
|
|
|
|
/* does it exist */
|
|
|
- ht = _ht_pkg_root;
|
|
|
+ ht = _ht_root;
|
|
|
while(ht!=NULL)
|
|
|
{
|
|
|
if(htid == ht->htid && name->len==ht->name.len
|
|
@@ -137,10 +235,10 @@ int ht_pkg_init(str *name, int autoexp, str *dbtable, int size, int dbmode)
|
|
|
ht = ht->next;
|
|
|
}
|
|
|
|
|
|
- ht = (ht_t*)pkg_malloc(sizeof(ht_t));
|
|
|
+ ht = (ht_t*)shm_malloc(sizeof(ht_t));
|
|
|
if(ht==NULL)
|
|
|
{
|
|
|
- LM_ERR("no more pkg\n");
|
|
|
+ LM_ERR("no more shared memory\n");
|
|
|
return -1;
|
|
|
}
|
|
|
memset(ht, 0, sizeof(ht_t));
|
|
@@ -157,35 +255,24 @@ int ht_pkg_init(str *name, int autoexp, str *dbtable, int size, int dbmode)
|
|
|
ht->dbtable = *dbtable;
|
|
|
ht->dbmode = dbmode;
|
|
|
|
|
|
- ht->next = _ht_pkg_root;
|
|
|
- _ht_pkg_root = ht;
|
|
|
+ ht->next = _ht_root;
|
|
|
+ _ht_root = ht;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-int ht_shm_init(void)
|
|
|
+int ht_init_tables(void)
|
|
|
{
|
|
|
- ht_t *htp;
|
|
|
- ht_t *htp0;
|
|
|
ht_t *ht;
|
|
|
int i;
|
|
|
|
|
|
- htp = _ht_pkg_root;
|
|
|
+ ht = _ht_root;
|
|
|
|
|
|
- while(htp)
|
|
|
+ while(ht)
|
|
|
{
|
|
|
- htp0 = htp->next;
|
|
|
- ht = (ht_t*)shm_malloc(sizeof(ht_t));
|
|
|
- if(ht==NULL)
|
|
|
- {
|
|
|
- LM_ERR("no more shm\n");
|
|
|
- return -1;
|
|
|
- }
|
|
|
- memcpy(ht, htp, sizeof(ht_t));
|
|
|
-
|
|
|
ht->entries = (ht_entry_t*)shm_malloc(ht->htsize*sizeof(ht_entry_t));
|
|
|
if(ht->entries==NULL)
|
|
|
{
|
|
|
- LM_ERR("no more shm.\n");
|
|
|
+ LM_ERR("no more shm for [%.*s]\n", ht->name.len, ht->name.s);
|
|
|
shm_free(ht);
|
|
|
return -1;
|
|
|
}
|
|
@@ -195,7 +282,8 @@ int ht_shm_init(void)
|
|
|
{
|
|
|
if(lock_init(&ht->entries[i].lock)==0)
|
|
|
{
|
|
|
- LM_ERR("cannot initalize lock[%d]\n", i);
|
|
|
+ LM_ERR("cannot initalize lock[%d] in [%.*s]\n", i,
|
|
|
+ ht->name.len, ht->name.s);
|
|
|
i--;
|
|
|
while(i>=0)
|
|
|
{
|
|
@@ -208,12 +296,8 @@ int ht_shm_init(void)
|
|
|
|
|
|
}
|
|
|
}
|
|
|
- ht->next = _ht_root;
|
|
|
- _ht_root = ht;
|
|
|
- pkg_free(htp);
|
|
|
- htp = htp0;
|
|
|
+ ht = ht->next;
|
|
|
}
|
|
|
- _ht_pkg_root = NULL;
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -512,129 +596,60 @@ int ht_dbg(void)
|
|
|
|
|
|
int ht_table_spec(char *spec)
|
|
|
{
|
|
|
+ keyvalue_t kval;
|
|
|
str name;
|
|
|
str dbtable = {0, 0};
|
|
|
unsigned int autoexpire = 0;
|
|
|
unsigned int size = 4;
|
|
|
- int type = 0;
|
|
|
unsigned int dbmode = 0;
|
|
|
str in;
|
|
|
str tok;
|
|
|
- char *p;
|
|
|
+ param_t *pit=NULL;
|
|
|
|
|
|
+ if(!shm_initialized())
|
|
|
+ {
|
|
|
+ LM_ERR("shared memory was not initialized\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
/* parse: name=>dbtable=abc;autoexpire=123;size=123*/
|
|
|
in.s = spec;
|
|
|
in.len = strlen(in.s);
|
|
|
-
|
|
|
- p = in.s;
|
|
|
- while(p<in.s+in.len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
|
|
|
- p++;
|
|
|
- if(p>in.s+in.len || *p=='\0')
|
|
|
- goto error;
|
|
|
- name.s = p;
|
|
|
- while(p < in.s + in.len)
|
|
|
- {
|
|
|
- if(*p=='=' || *p==' ' || *p=='\t' || *p=='\n' || *p=='\r')
|
|
|
- break;
|
|
|
- p++;
|
|
|
- }
|
|
|
- if(p>in.s+in.len || *p=='\0')
|
|
|
- goto error;
|
|
|
- name.len = p - name.s;
|
|
|
- if(*p!='=')
|
|
|
- {
|
|
|
- while(p<in.s+in.len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
|
|
|
- p++;
|
|
|
- if(p>in.s+in.len || *p=='\0' || *p!='=')
|
|
|
- goto error;
|
|
|
- }
|
|
|
- p++;
|
|
|
- if(*p!='>')
|
|
|
- goto error;
|
|
|
- p++;
|
|
|
- while(p<in.s+in.len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
|
|
|
- p++;
|
|
|
-
|
|
|
-next_token:
|
|
|
- tok.s = p;
|
|
|
- while(p < in.s + in.len)
|
|
|
+ if(keyvalue_parse_str(&in, KEYVALUE_TYPE_PARAMS, &kval)<0)
|
|
|
{
|
|
|
- if(*p=='=' || *p==' ' || *p=='\t' || *p=='\n' || *p=='\r')
|
|
|
- break;
|
|
|
- p++;
|
|
|
+ LM_ERR("failed parsing: %.*s\n", in.len, in.s);
|
|
|
+ return -1;
|
|
|
}
|
|
|
- if(p>in.s+in.len || *p=='\0')
|
|
|
- goto error;
|
|
|
- tok.len = p - tok.s;
|
|
|
- if(tok.len==7 && strncmp(tok.s, "dbtable", 7)==0)
|
|
|
- type = 1;
|
|
|
- else if(tok.len==10 && strncmp(tok.s, "autoexpire", 10)==0)
|
|
|
- type = 2;
|
|
|
- else if(tok.len==4 && strncmp(tok.s, "size", 4)==0)
|
|
|
- type = 3;
|
|
|
- else if(tok.len==6 && strncmp(tok.s, "dbmode", 6)==0)
|
|
|
- type = 4;
|
|
|
- else goto error;
|
|
|
+ name = kval.key;
|
|
|
|
|
|
- if(*p!='=')
|
|
|
+ for (pit = kval.u.params; pit; pit=pit->next)
|
|
|
{
|
|
|
- while(p<in.s+in.len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
|
|
|
- p++;
|
|
|
- if(p>in.s+in.len || *p=='\0' || *p!='=')
|
|
|
- goto error;
|
|
|
- }
|
|
|
- p++;
|
|
|
- while(p<in.s+in.len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
|
|
|
- p++;
|
|
|
- if(p>in.s+in.len || *p=='\0')
|
|
|
- goto error;
|
|
|
- tok.s = p;
|
|
|
- while(p < in.s + in.len)
|
|
|
- {
|
|
|
- if(*p==';' || *p==' ' || *p=='\t' || *p=='\n' || *p=='\r')
|
|
|
- break;
|
|
|
- p++;
|
|
|
- }
|
|
|
- if(p>in.s+in.len || *p=='\0')
|
|
|
- goto error;
|
|
|
- tok.len = p - tok.s;
|
|
|
- switch(type)
|
|
|
- {
|
|
|
- case 1:
|
|
|
+ tok = pit->body;
|
|
|
+ if(pit->name.len==7 && strncmp(pit->name.s, "dbtable", 7)==0) {
|
|
|
dbtable = tok;
|
|
|
LM_DBG("htable [%.*s] - dbtable [%.*s]\n", name.len, name.s,
|
|
|
dbtable.len, dbtable.s);
|
|
|
- break;
|
|
|
- case 2:
|
|
|
+ } else if(pit->name.len==10 && strncmp(pit->name.s, "autoexpire", 10)==0) {
|
|
|
if(str2int(&tok, &autoexpire)!=0)
|
|
|
goto error;
|
|
|
LM_DBG("htable [%.*s] - expire [%u]\n", name.len, name.s,
|
|
|
autoexpire);
|
|
|
- break;
|
|
|
- case 3:
|
|
|
+ } else if(pit->name.len==4 && strncmp(pit->name.s, "size", 4)==0) {
|
|
|
if(str2int(&tok, &size)!=0)
|
|
|
goto error;
|
|
|
LM_DBG("htable [%.*s] - size [%u]\n", name.len, name.s,
|
|
|
size);
|
|
|
- break;
|
|
|
- case 4:
|
|
|
+ } else if(pit->name.len==6 && strncmp(pit->name.s, "dbmode", 6)==0) {
|
|
|
if(str2int(&tok, &dbmode)!=0)
|
|
|
goto error;
|
|
|
LM_DBG("htable [%.*s] - dbmode [%u]\n", name.len, name.s,
|
|
|
dbmode);
|
|
|
- break;
|
|
|
+ } else { goto error; }
|
|
|
}
|
|
|
- while(p<in.s+in.len && (*p==';' || *p==' ' || *p=='\t'
|
|
|
- || *p=='\n' || *p=='\r'))
|
|
|
- p++;
|
|
|
- if(p<in.s+in.len)
|
|
|
- goto next_token;
|
|
|
|
|
|
- return ht_pkg_init(&name, autoexpire, &dbtable, size, dbmode);
|
|
|
+ return ht_add_table(&name, autoexpire, &dbtable, size, dbmode);
|
|
|
|
|
|
error:
|
|
|
- LM_ERR("invalid htable parameter [%.*s] at [%d]\n", in.len, in.s,
|
|
|
- (int)(p-in.s));
|
|
|
+ LM_ERR("invalid htable parameter [%.*s]\n", in.len, in.s);
|
|
|
return -1;
|
|
|
}
|
|
|
|