|
@@ -9,22 +9,41 @@
|
|
#include "../../core/script_cb.h"
|
|
#include "../../core/script_cb.h"
|
|
#include "../../core/hashes.h"
|
|
#include "../../core/hashes.h"
|
|
|
|
|
|
-#define set_str_val(f,s) (f).v.lstr=(s); \
|
|
|
|
|
|
+#define set_str_val(f, s) \
|
|
|
|
+ (f).v.lstr = (s); \
|
|
(f).flags = 0;
|
|
(f).flags = 0;
|
|
|
|
|
|
-#define set_str_val_ex(f,s) if ((s).len) { (f).v.lstr=(s); (f).flags = 0; } \
|
|
|
|
- else (f).flags|=DB_NULL;
|
|
|
|
|
|
+#define set_str_val_ex(f, s) \
|
|
|
|
+ if((s).len) { \
|
|
|
|
+ (f).v.lstr = (s); \
|
|
|
|
+ (f).flags = 0; \
|
|
|
|
+ } else \
|
|
|
|
+ (f).flags |= DB_NULL;
|
|
|
|
|
|
-#define set_int_val(f,t) (f).v.int4=t;\
|
|
|
|
- (f).flags=0;
|
|
|
|
-
|
|
|
|
-#define get_str_val(rvi,dst) do{if(!(rvi.flags&DB_NULL)){dst=rvi.v.lstr;} else dst.len = 0;}while(0)
|
|
|
|
-#define get_int_val(rvi,dst) do{if(!(rvi.flags&DB_NULL)){dst=rvi.v.int4;} else dst = 0;}while(0)
|
|
|
|
|
|
+#define set_int_val(f, t) \
|
|
|
|
+ (f).v.int4 = t; \
|
|
|
|
+ (f).flags = 0;
|
|
|
|
|
|
-typedef struct _registered_table_t {
|
|
|
|
|
|
+#define get_str_val(rvi, dst) \
|
|
|
|
+ do { \
|
|
|
|
+ if(!(rvi.flags & DB_NULL)) { \
|
|
|
|
+ dst = rvi.v.lstr; \
|
|
|
|
+ } else \
|
|
|
|
+ dst.len = 0; \
|
|
|
|
+ } while(0)
|
|
|
|
+#define get_int_val(rvi, dst) \
|
|
|
|
+ do { \
|
|
|
|
+ if(!(rvi.flags & DB_NULL)) { \
|
|
|
|
+ dst = rvi.v.int4; \
|
|
|
|
+ } else \
|
|
|
|
+ dst = 0; \
|
|
|
|
+ } while(0)
|
|
|
|
+
|
|
|
|
+typedef struct _registered_table_t
|
|
|
|
+{
|
|
char *id;
|
|
char *id;
|
|
char *table_name;
|
|
char *table_name;
|
|
-
|
|
|
|
|
|
+
|
|
/* column names */
|
|
/* column names */
|
|
char *key_column;
|
|
char *key_column;
|
|
char *name_column;
|
|
char *name_column;
|
|
@@ -53,8 +72,9 @@ static registered_table_t *tables = NULL;
|
|
registered_table_t *find_registered_table(const char *id)
|
|
registered_table_t *find_registered_table(const char *id)
|
|
{
|
|
{
|
|
registered_table_t *t = tables;
|
|
registered_table_t *t = tables;
|
|
- while (t) {
|
|
|
|
- if (strcmp(t->id, id) == 0) return t;
|
|
|
|
|
|
+ while(t) {
|
|
|
|
+ if(strcmp(t->id, id) == 0)
|
|
|
|
+ return t;
|
|
t = t->next;
|
|
t = t->next;
|
|
}
|
|
}
|
|
return NULL;
|
|
return NULL;
|
|
@@ -62,7 +82,11 @@ registered_table_t *find_registered_table(const char *id)
|
|
|
|
|
|
char *get_token(char *s, str *name, str *value)
|
|
char *get_token(char *s, str *name, str *value)
|
|
{
|
|
{
|
|
- enum { reading_name, reading_value } state = reading_name;
|
|
|
|
|
|
+ enum
|
|
|
|
+ {
|
|
|
|
+ reading_name,
|
|
|
|
+ reading_value
|
|
|
|
+ } state = reading_name;
|
|
/* returns 'token' which has the form name[=value][,]
|
|
/* returns 'token' which has the form name[=value][,]
|
|
* replaces separators ,= by binary 0 to allow char* strings */
|
|
* replaces separators ,= by binary 0 to allow char* strings */
|
|
|
|
|
|
@@ -71,28 +95,29 @@ char *get_token(char *s, str *name, str *value)
|
|
value->s = NULL;
|
|
value->s = NULL;
|
|
value->len = 0;
|
|
value->len = 0;
|
|
|
|
|
|
- while (*s) {
|
|
|
|
- switch (state) {
|
|
|
|
- case reading_name:
|
|
|
|
- switch (*s) {
|
|
|
|
|
|
+ while(*s) {
|
|
|
|
+ switch(state) {
|
|
|
|
+ case reading_name:
|
|
|
|
+ switch(*s) {
|
|
case '=':
|
|
case '=':
|
|
- case ':':
|
|
|
|
|
|
+ case ':':
|
|
state = reading_value;
|
|
state = reading_value;
|
|
value->s = s + 1;
|
|
value->s = s + 1;
|
|
*s = 0; /* replace separator */
|
|
*s = 0; /* replace separator */
|
|
break;
|
|
break;
|
|
- case ',':
|
|
|
|
|
|
+ case ',':
|
|
*s = 0; /* replace separator */
|
|
*s = 0; /* replace separator */
|
|
return s + 1;
|
|
return s + 1;
|
|
- default: name->len++;
|
|
|
|
|
|
+ default:
|
|
|
|
+ name->len++;
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
case reading_value:
|
|
case reading_value:
|
|
- if (*s == ',') {
|
|
|
|
|
|
+ if(*s == ',') {
|
|
*s = 0; /* replace separator */
|
|
*s = 0; /* replace separator */
|
|
return s + 1;
|
|
return s + 1;
|
|
- }
|
|
|
|
- else value->len++;
|
|
|
|
|
|
+ } else
|
|
|
|
+ value->len++;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
s++;
|
|
s++;
|
|
@@ -104,10 +129,13 @@ static int cmp_s(str *a, str *b)
|
|
{
|
|
{
|
|
int i;
|
|
int i;
|
|
/* Warning: none string can be NULL! */
|
|
/* Warning: none string can be NULL! */
|
|
- if (a->len != b->len) return -1;
|
|
|
|
- if (!a->len) return 0; /* equal - empty */
|
|
|
|
- for (i = 0; i < a->len; i++)
|
|
|
|
- if (a->s[i] != b->s[i]) return 1;
|
|
|
|
|
|
+ if(a->len != b->len)
|
|
|
|
+ return -1;
|
|
|
|
+ if(!a->len)
|
|
|
|
+ return 0; /* equal - empty */
|
|
|
|
+ for(i = 0; i < a->len; i++)
|
|
|
|
+ if(a->s[i] != b->s[i])
|
|
|
|
+ return 1;
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -118,13 +146,13 @@ static inline void cpy(char *dst, str *s)
|
|
}
|
|
}
|
|
|
|
|
|
/* adds new 'extra attribute group' (it adds new table for it) */
|
|
/* adds new 'extra attribute group' (it adds new table for it) */
|
|
-int declare_attr_group(modparam_t type, char* _param)
|
|
|
|
|
|
+int declare_attr_group(modparam_t type, char *_param)
|
|
{
|
|
{
|
|
registered_table_t *rt;
|
|
registered_table_t *rt;
|
|
str name, value;
|
|
str name, value;
|
|
str param;
|
|
str param;
|
|
char *p;
|
|
char *p;
|
|
-
|
|
|
|
|
|
+
|
|
static str table = STR_STATIC_INIT("table");
|
|
static str table = STR_STATIC_INIT("table");
|
|
static str flag = STR_STATIC_INIT("flag");
|
|
static str flag = STR_STATIC_INIT("flag");
|
|
static str id = STR_STATIC_INIT("id");
|
|
static str id = STR_STATIC_INIT("id");
|
|
@@ -133,20 +161,20 @@ int declare_attr_group(modparam_t type, char* _param)
|
|
static str value_column = STR_STATIC_INIT("value_column");
|
|
static str value_column = STR_STATIC_INIT("value_column");
|
|
static str type_column = STR_STATIC_INIT("type_column");
|
|
static str type_column = STR_STATIC_INIT("type_column");
|
|
static str flags_column = STR_STATIC_INIT("flags_column");
|
|
static str flags_column = STR_STATIC_INIT("flags_column");
|
|
-
|
|
|
|
- if (!(type & PARAM_STR)) {
|
|
|
|
|
|
+
|
|
|
|
+ if(!(type & PARAM_STR)) {
|
|
ERR("Invalid parameter type\n");
|
|
ERR("Invalid parameter type\n");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
- if (!_param) {
|
|
|
|
|
|
+ if(!_param) {
|
|
ERR("invalid parameter value\n");
|
|
ERR("invalid parameter value\n");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
- param = *((str*)_param);
|
|
|
|
- DBG("group def: %.*s\n", param.len, param.s);
|
|
|
|
-
|
|
|
|
|
|
+ param = *((str *)_param);
|
|
|
|
+ DBG("group def: %.*s\n", param.len, param.s);
|
|
|
|
+
|
|
rt = pkg_malloc(param.len + sizeof(*rt) + 1);
|
|
rt = pkg_malloc(param.len + sizeof(*rt) + 1);
|
|
- if (!rt) {
|
|
|
|
|
|
+ if(!rt) {
|
|
PKG_MEM_ERROR;
|
|
PKG_MEM_ERROR;
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
@@ -164,17 +192,25 @@ int declare_attr_group(modparam_t type, char* _param)
|
|
p = rt->buf;
|
|
p = rt->buf;
|
|
do {
|
|
do {
|
|
p = get_token(p, &name, &value);
|
|
p = get_token(p, &name, &value);
|
|
- if (cmp_s(&name, &table) == 0) rt->table_name = value.s;
|
|
|
|
- else if (cmp_s(&name, &flag) == 0) rt->flag_name = value.s;
|
|
|
|
- else if (cmp_s(&name, &id) == 0) rt->id = value.s;
|
|
|
|
- else if (cmp_s(&name, &key_column) == 0) rt->key_column = value.s;
|
|
|
|
- else if (cmp_s(&name, &name_column) == 0) rt->name_column = value.s;
|
|
|
|
- else if (cmp_s(&name, &type_column) == 0) rt->type_column = value.s;
|
|
|
|
- else if (cmp_s(&name, &value_column) == 0) rt->value_column = value.s;
|
|
|
|
- else if (cmp_s(&name, &flags_column) == 0) rt->flags_column = value.s;
|
|
|
|
- } while (p);
|
|
|
|
-
|
|
|
|
- if ((!rt->id) || (!rt->flag_name)) {
|
|
|
|
|
|
+ if(cmp_s(&name, &table) == 0)
|
|
|
|
+ rt->table_name = value.s;
|
|
|
|
+ else if(cmp_s(&name, &flag) == 0)
|
|
|
|
+ rt->flag_name = value.s;
|
|
|
|
+ else if(cmp_s(&name, &id) == 0)
|
|
|
|
+ rt->id = value.s;
|
|
|
|
+ else if(cmp_s(&name, &key_column) == 0)
|
|
|
|
+ rt->key_column = value.s;
|
|
|
|
+ else if(cmp_s(&name, &name_column) == 0)
|
|
|
|
+ rt->name_column = value.s;
|
|
|
|
+ else if(cmp_s(&name, &type_column) == 0)
|
|
|
|
+ rt->type_column = value.s;
|
|
|
|
+ else if(cmp_s(&name, &value_column) == 0)
|
|
|
|
+ rt->value_column = value.s;
|
|
|
|
+ else if(cmp_s(&name, &flags_column) == 0)
|
|
|
|
+ rt->flags_column = value.s;
|
|
|
|
+ } while(p);
|
|
|
|
+
|
|
|
|
+ if((!rt->id) || (!rt->flag_name)) {
|
|
ERR("at least attribute group ID and flags must be given\n");
|
|
ERR("at least attribute group ID and flags must be given\n");
|
|
pkg_free(rt);
|
|
pkg_free(rt);
|
|
return -1;
|
|
return -1;
|
|
@@ -182,12 +218,12 @@ int declare_attr_group(modparam_t type, char* _param)
|
|
/* insert new element into registered tables */
|
|
/* insert new element into registered tables */
|
|
|
|
|
|
rt->flag = register_avpflag(rt->flag_name);
|
|
rt->flag = register_avpflag(rt->flag_name);
|
|
- if (!rt->flag) {
|
|
|
|
|
|
+ if(!rt->flag) {
|
|
ERR("can't register AVP flag: %s\n", rt->flag_name);
|
|
ERR("can't register AVP flag: %s\n", rt->flag_name);
|
|
pkg_free(rt);
|
|
pkg_free(rt);
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
/* append to the beggining - it doesn't depend on the order */
|
|
/* append to the beggining - it doesn't depend on the order */
|
|
rt->next = tables;
|
|
rt->next = tables;
|
|
tables = rt;
|
|
tables = rt;
|
|
@@ -199,57 +235,56 @@ int declare_attr_group(modparam_t type, char* _param)
|
|
* Variable default_res holds columns which can used by read_attrs. */
|
|
* Variable default_res holds columns which can used by read_attrs. */
|
|
static int init_queries(db_ctx_t *ctx, registered_table_t *t)
|
|
static int init_queries(db_ctx_t *ctx, registered_table_t *t)
|
|
{
|
|
{
|
|
- db_fld_t match[] = {
|
|
|
|
- { .name = t->key_column, .type = DB_STR, .op = DB_EQ },
|
|
|
|
- { .name = NULL }
|
|
|
|
- };
|
|
|
|
|
|
+ db_fld_t match[] = {{.name = t->key_column, .type = DB_STR, .op = DB_EQ},
|
|
|
|
+ {.name = NULL}};
|
|
db_fld_t query_res[] = {
|
|
db_fld_t query_res[] = {
|
|
- /* Warning: be careful here - the query must have the same result
|
|
|
|
|
|
+ /* Warning: be careful here - the query must have the same result
|
|
* as query for user/uri AVPs to be readable by read_attrs */
|
|
* as query for user/uri AVPs to be readable by read_attrs */
|
|
- { .name = t->name_column, .type = DB_STR, .op = DB_EQ },
|
|
|
|
- { .name = t->type_column, .type = DB_INT, .op = DB_EQ },
|
|
|
|
- { .name = t->value_column, .type = DB_STR, .op = DB_EQ },
|
|
|
|
- { .name = t->flags_column, .type = DB_BITMAP, .op = DB_EQ },
|
|
|
|
- { .name = NULL }
|
|
|
|
- };
|
|
|
|
|
|
+ {.name = t->name_column, .type = DB_STR, .op = DB_EQ},
|
|
|
|
+ {.name = t->type_column, .type = DB_INT, .op = DB_EQ},
|
|
|
|
+ {.name = t->value_column, .type = DB_STR, .op = DB_EQ},
|
|
|
|
+ {.name = t->flags_column, .type = DB_BITMAP, .op = DB_EQ},
|
|
|
|
+ {.name = NULL}};
|
|
db_fld_t add_values[] = {
|
|
db_fld_t add_values[] = {
|
|
- { .name = t->key_column, .type = DB_STR, .op = DB_EQ },
|
|
|
|
- { .name = t->name_column, .type = DB_STR, .op = DB_EQ },
|
|
|
|
- { .name = t->type_column, .type = DB_INT, .op = DB_EQ },
|
|
|
|
- { .name = t->value_column, .type = DB_STR, .op = DB_EQ },
|
|
|
|
- { .name = t->flags_column, .type = DB_BITMAP, .op = DB_EQ },
|
|
|
|
- { .name = NULL }
|
|
|
|
- };
|
|
|
|
|
|
+ {.name = t->key_column, .type = DB_STR, .op = DB_EQ},
|
|
|
|
+ {.name = t->name_column, .type = DB_STR, .op = DB_EQ},
|
|
|
|
+ {.name = t->type_column, .type = DB_INT, .op = DB_EQ},
|
|
|
|
+ {.name = t->value_column, .type = DB_STR, .op = DB_EQ},
|
|
|
|
+ {.name = t->flags_column, .type = DB_BITMAP, .op = DB_EQ},
|
|
|
|
+ {.name = NULL}};
|
|
|
|
|
|
t->query = db_cmd(DB_GET, ctx, t->table_name, query_res, match, NULL);
|
|
t->query = db_cmd(DB_GET, ctx, t->table_name, query_res, match, NULL);
|
|
t->remove = db_cmd(DB_DEL, ctx, t->table_name, NULL, match, NULL);
|
|
t->remove = db_cmd(DB_DEL, ctx, t->table_name, NULL, match, NULL);
|
|
t->add = db_cmd(DB_PUT, ctx, t->table_name, NULL, NULL, add_values);
|
|
t->add = db_cmd(DB_PUT, ctx, t->table_name, NULL, NULL, add_values);
|
|
|
|
|
|
- if (t->query && t->remove && t->add) return 0;
|
|
|
|
- else return -1; /* not all queries were initialized */
|
|
|
|
|
|
+ if(t->query && t->remove && t->add)
|
|
|
|
+ return 0;
|
|
|
|
+ else
|
|
|
|
+ return -1; /* not all queries were initialized */
|
|
}
|
|
}
|
|
|
|
|
|
int init_extra_avp_queries(db_ctx_t *ctx)
|
|
int init_extra_avp_queries(db_ctx_t *ctx)
|
|
{
|
|
{
|
|
registered_table_t *t = tables;
|
|
registered_table_t *t = tables;
|
|
- while (t) {
|
|
|
|
- if (init_queries(ctx, t) < 0) return -1;
|
|
|
|
|
|
+ while(t) {
|
|
|
|
+ if(init_queries(ctx, t) < 0)
|
|
|
|
+ return -1;
|
|
t = t->next;
|
|
t = t->next;
|
|
}
|
|
}
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-static void get_avp_value_ex(avp_t *avp, str *dst, int *type) {
|
|
|
|
|
|
+static void get_avp_value_ex(avp_t *avp, str *dst, int *type)
|
|
|
|
+{
|
|
avp_value_t val;
|
|
avp_value_t val;
|
|
|
|
|
|
/* Warning! it uses static buffer from int2str !!! */
|
|
/* Warning! it uses static buffer from int2str !!! */
|
|
|
|
|
|
get_avp_val(avp, &val);
|
|
get_avp_val(avp, &val);
|
|
- if (avp->flags & AVP_VAL_STR) {
|
|
|
|
|
|
+ if(avp->flags & AVP_VAL_STR) {
|
|
*dst = val.s;
|
|
*dst = val.s;
|
|
*type = AVP_VAL_STR;
|
|
*type = AVP_VAL_STR;
|
|
- }
|
|
|
|
- else { /* probably (!) number */
|
|
|
|
|
|
+ } else { /* probably (!) number */
|
|
dst->s = int2str(val.n, &dst->len);
|
|
dst->s = int2str(val.n, &dst->len);
|
|
*type = 0;
|
|
*type = 0;
|
|
}
|
|
}
|
|
@@ -258,24 +293,28 @@ static void get_avp_value_ex(avp_t *avp, str *dst, int *type) {
|
|
/** Saves attribute into DB with given ID. The ID must not be NULL. The
|
|
/** Saves attribute into DB with given ID. The ID must not be NULL. The
|
|
* use_table must be called outside of this function (from interface
|
|
* use_table must be called outside of this function (from interface
|
|
* functions) */
|
|
* functions) */
|
|
-static inline int save_avp(registered_table_t *t, avp_t *avp, str *id) /* id MUST NOT be NULL */
|
|
|
|
|
|
+static inline int save_avp(
|
|
|
|
+ registered_table_t *t, avp_t *avp, str *id) /* id MUST NOT be NULL */
|
|
{
|
|
{
|
|
str *s, v;
|
|
str *s, v;
|
|
int type;
|
|
int type;
|
|
static str empty = STR_STATIC_INIT("");
|
|
static str empty = STR_STATIC_INIT("");
|
|
-
|
|
|
|
|
|
+
|
|
set_str_val(t->add->vals[0], *id);
|
|
set_str_val(t->add->vals[0], *id);
|
|
-
|
|
|
|
|
|
+
|
|
s = get_avp_name(avp);
|
|
s = get_avp_name(avp);
|
|
- if (!s) s = ∅
|
|
|
|
|
|
+ if(!s)
|
|
|
|
+ s = ∅
|
|
set_str_val(t->add->vals[1], *s);
|
|
set_str_val(t->add->vals[1], *s);
|
|
-
|
|
|
|
|
|
+
|
|
get_avp_value_ex(avp, &v, &type);
|
|
get_avp_value_ex(avp, &v, &type);
|
|
set_int_val(t->add->vals[2], type);
|
|
set_int_val(t->add->vals[2], type);
|
|
set_str_val(t->add->vals[3], v);
|
|
set_str_val(t->add->vals[3], v);
|
|
- set_int_val(t->add->vals[4], avp->flags & (AVP_CLASS_ALL | AVP_TRACK_ALL | AVP_NAME_STR | AVP_VAL_STR));
|
|
|
|
-
|
|
|
|
- if (db_exec(NULL, t->add) < 0) {
|
|
|
|
|
|
+ set_int_val(t->add->vals[4], avp->flags
|
|
|
|
+ & (AVP_CLASS_ALL | AVP_TRACK_ALL
|
|
|
|
+ | AVP_NAME_STR | AVP_VAL_STR));
|
|
|
|
+
|
|
|
|
+ if(db_exec(NULL, t->add) < 0) {
|
|
ERR("Can't insert record into DB\n");
|
|
ERR("Can't insert record into DB\n");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
@@ -288,21 +327,23 @@ static int read_avps(db_res_t *res, avp_flags_t flag) /* id must not be NULL */
|
|
db_rec_t *row;
|
|
db_rec_t *row;
|
|
|
|
|
|
row = db_first(res);
|
|
row = db_first(res);
|
|
- while (row) {
|
|
|
|
|
|
+ while(row) {
|
|
int flags = 0;
|
|
int flags = 0;
|
|
int type = 0;
|
|
int type = 0;
|
|
str value = STR_NULL;
|
|
str value = STR_NULL;
|
|
avp_value_t val;
|
|
avp_value_t val;
|
|
avp_name_t name;
|
|
avp_name_t name;
|
|
-
|
|
|
|
|
|
+
|
|
get_str_val(row->fld[0], name.s);
|
|
get_str_val(row->fld[0], name.s);
|
|
get_int_val(row->fld[1], type);
|
|
get_int_val(row->fld[1], type);
|
|
get_str_val(row->fld[2], value);
|
|
get_str_val(row->fld[2], value);
|
|
get_int_val(row->fld[3], flags);
|
|
get_int_val(row->fld[3], flags);
|
|
|
|
|
|
- if (flags & SRDB_LOAD_SER) {
|
|
|
|
- if (type == AVP_VAL_STR) val.s = value;
|
|
|
|
- else str2int(&value, (unsigned int *)&val.n); /* FIXME */
|
|
|
|
|
|
+ if(flags & SRDB_LOAD_SER) {
|
|
|
|
+ if(type == AVP_VAL_STR)
|
|
|
|
+ val.s = value;
|
|
|
|
+ else
|
|
|
|
+ str2int(&value, (unsigned int *)&val.n); /* FIXME */
|
|
|
|
|
|
flags |= flag;
|
|
flags |= flag;
|
|
|
|
|
|
@@ -319,7 +360,7 @@ static int read_avps(db_res_t *res, avp_flags_t flag) /* id must not be NULL */
|
|
static inline int remove_all_avps(registered_table_t *t, str *id)
|
|
static inline int remove_all_avps(registered_table_t *t, str *id)
|
|
{
|
|
{
|
|
set_str_val(t->remove->match[0], *id);
|
|
set_str_val(t->remove->match[0], *id);
|
|
- if (db_exec(NULL, t->remove) < 0) {
|
|
|
|
|
|
+ if(db_exec(NULL, t->remove) < 0) {
|
|
ERR("can't remove attrs\n");
|
|
ERR("can't remove attrs\n");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
@@ -328,24 +369,24 @@ static inline int remove_all_avps(registered_table_t *t, str *id)
|
|
|
|
|
|
/* ----- interface functions ----- */
|
|
/* ----- interface functions ----- */
|
|
|
|
|
|
-int load_extra_attrs(struct sip_msg* msg, char* _table, char* _id)
|
|
|
|
|
|
+int load_extra_attrs(struct sip_msg *msg, char *_table, char *_id)
|
|
{
|
|
{
|
|
registered_table_t *t;
|
|
registered_table_t *t;
|
|
db_res_t *res = NULL;
|
|
db_res_t *res = NULL;
|
|
str id;
|
|
str id;
|
|
|
|
|
|
t = (registered_table_t *)_table;
|
|
t = (registered_table_t *)_table;
|
|
- if ((!t) || (get_str_fparam(&id, msg, (fparam_t*)_id) < 0)) {
|
|
|
|
|
|
+ if((!t) || (get_str_fparam(&id, msg, (fparam_t *)_id) < 0)) {
|
|
ERR("invalid parameter value\n");
|
|
ERR("invalid parameter value\n");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
set_str_val(t->query->match[0], id);
|
|
set_str_val(t->query->match[0], id);
|
|
- if (db_exec(&res, t->query) < 0) {
|
|
|
|
|
|
+ if(db_exec(&res, t->query) < 0) {
|
|
ERR("DB query failed\n");
|
|
ERR("DB query failed\n");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
- if (res) {
|
|
|
|
|
|
+ if(res) {
|
|
read_avps(res, t->flag);
|
|
read_avps(res, t->flag);
|
|
db_res_free(res);
|
|
db_res_free(res);
|
|
}
|
|
}
|
|
@@ -353,14 +394,14 @@ int load_extra_attrs(struct sip_msg* msg, char* _table, char* _id)
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
-int remove_extra_attrs(struct sip_msg* msg, char *_table, char* _id)
|
|
|
|
|
|
+int remove_extra_attrs(struct sip_msg *msg, char *_table, char *_id)
|
|
{
|
|
{
|
|
str id;
|
|
str id;
|
|
registered_table_t *t;
|
|
registered_table_t *t;
|
|
|
|
|
|
t = (registered_table_t *)_table;
|
|
t = (registered_table_t *)_table;
|
|
|
|
|
|
- if ((!t) || (get_str_fparam(&id, msg, (fparam_t*)_id) < 0)) {
|
|
|
|
|
|
+ if((!t) || (get_str_fparam(&id, msg, (fparam_t *)_id) < 0)) {
|
|
ERR("invalid parameter value\n");
|
|
ERR("invalid parameter value\n");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
@@ -369,23 +410,19 @@ int remove_extra_attrs(struct sip_msg* msg, char *_table, char* _id)
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
-int save_extra_attrs(struct sip_msg* msg, char* _table, char *_id)
|
|
|
|
|
|
+int save_extra_attrs(struct sip_msg *msg, char *_table, char *_id)
|
|
{
|
|
{
|
|
str id;
|
|
str id;
|
|
int i;
|
|
int i;
|
|
struct usr_avp *avp;
|
|
struct usr_avp *avp;
|
|
- static unsigned short lists[] = {
|
|
|
|
- AVP_CLASS_USER | AVP_TRACK_FROM,
|
|
|
|
- AVP_CLASS_USER | AVP_TRACK_TO,
|
|
|
|
- AVP_CLASS_URI | AVP_TRACK_FROM,
|
|
|
|
- AVP_CLASS_URI | AVP_TRACK_TO,
|
|
|
|
- 0
|
|
|
|
- };
|
|
|
|
|
|
+ static unsigned short lists[] = {AVP_CLASS_USER | AVP_TRACK_FROM,
|
|
|
|
+ AVP_CLASS_USER | AVP_TRACK_TO, AVP_CLASS_URI | AVP_TRACK_FROM,
|
|
|
|
+ AVP_CLASS_URI | AVP_TRACK_TO, 0};
|
|
registered_table_t *t;
|
|
registered_table_t *t;
|
|
|
|
|
|
t = (registered_table_t *)_table;
|
|
t = (registered_table_t *)_table;
|
|
|
|
|
|
- if ((!t) || (get_str_fparam(&id, msg, (fparam_t*)_id) < 0)) {
|
|
|
|
|
|
+ if((!t) || (get_str_fparam(&id, msg, (fparam_t *)_id) < 0)) {
|
|
ERR("invalid parameter value\n");
|
|
ERR("invalid parameter value\n");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
@@ -393,49 +430,54 @@ int save_extra_attrs(struct sip_msg* msg, char* _table, char *_id)
|
|
/* delete all attrs under given id */
|
|
/* delete all attrs under given id */
|
|
remove_all_avps(t, &id);
|
|
remove_all_avps(t, &id);
|
|
|
|
|
|
- /* save all attrs flagged with flag under id */
|
|
|
|
- for (i = 0; lists[i]; i++) {
|
|
|
|
- for (avp = get_avp_list(lists[i]); avp; avp = avp->next) {
|
|
|
|
- if ((avp->flags & t->flag) != 0) save_avp(t, avp, &id);
|
|
|
|
|
|
+ /* save all attrs flagged with flag under id */
|
|
|
|
+ for(i = 0; lists[i]; i++) {
|
|
|
|
+ for(avp = get_avp_list(lists[i]); avp; avp = avp->next) {
|
|
|
|
+ if((avp->flags & t->flag) != 0)
|
|
|
|
+ save_avp(t, avp, &id);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
-int extra_attrs_fixup(void** param, int param_no)
|
|
|
|
|
|
+int extra_attrs_fixup(void **param, int param_no)
|
|
{
|
|
{
|
|
registered_table_t *t;
|
|
registered_table_t *t;
|
|
|
|
|
|
- switch (param_no) {
|
|
|
|
|
|
+ switch(param_no) {
|
|
case 1: /* try to find registered table, error if not found */
|
|
case 1: /* try to find registered table, error if not found */
|
|
- t = find_registered_table(*param);
|
|
|
|
- if (!t) {
|
|
|
|
- ERR("can't find attribute group with id: %s\n", (char*)*param);
|
|
|
|
- return -1;
|
|
|
|
- }
|
|
|
|
- *param = (void*)t;
|
|
|
|
- break;
|
|
|
|
- case 2: return fixup_var_str_2(param, param_no);
|
|
|
|
|
|
+ t = find_registered_table(*param);
|
|
|
|
+ if(!t) {
|
|
|
|
+ ERR("can't find attribute group with id: %s\n", (char *)*param);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ *param = (void *)t;
|
|
|
|
+ break;
|
|
|
|
+ case 2:
|
|
|
|
+ return fixup_var_str_2(param, param_no);
|
|
}
|
|
}
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-/******* locking *******/
|
|
|
|
|
|
+/******* locking *******/
|
|
|
|
|
|
-#define LOCK_CNT 32
|
|
|
|
|
|
+#define LOCK_CNT 32
|
|
|
|
|
|
gen_lock_t *locks = NULL; /* set of mutexes allocated in shared memory */
|
|
gen_lock_t *locks = NULL; /* set of mutexes allocated in shared memory */
|
|
-int lock_counters[LOCK_CNT]; /* set of counters (each proces has its own counters) */
|
|
|
|
|
|
+int lock_counters
|
|
|
|
+ [LOCK_CNT]; /* set of counters (each proces has its own counters) */
|
|
|
|
|
|
-static int avpdb_post_script_cb(struct sip_msg *msg, unsigned int flags, void *param) {
|
|
|
|
|
|
+static int avpdb_post_script_cb(
|
|
|
|
+ struct sip_msg *msg, unsigned int flags, void *param)
|
|
|
|
+{
|
|
int i;
|
|
int i;
|
|
|
|
|
|
- for (i=0; i<LOCK_CNT; i++) {
|
|
|
|
- if (lock_counters[i] > 0) {
|
|
|
|
- if (auto_unlock) {
|
|
|
|
|
|
+ for(i = 0; i < LOCK_CNT; i++) {
|
|
|
|
+ if(lock_counters[i] > 0) {
|
|
|
|
+ if(auto_unlock) {
|
|
DEBUG("post script auto unlock extra attrs <%d>\n", i);
|
|
DEBUG("post script auto unlock extra attrs <%d>\n", i);
|
|
lock_release(&locks[i]);
|
|
lock_release(&locks[i]);
|
|
- lock_counters[i]=0;
|
|
|
|
|
|
+ lock_counters[i] = 0;
|
|
} else {
|
|
} else {
|
|
BUG("script writer didn't unlock extra attrs !!!\n");
|
|
BUG("script writer didn't unlock extra attrs !!!\n");
|
|
return 1;
|
|
return 1;
|
|
@@ -451,7 +493,8 @@ int init_extra_avp_locks()
|
|
registered_table_t *t = tables;
|
|
registered_table_t *t = tables;
|
|
|
|
|
|
if(register_script_cb(avpdb_post_script_cb,
|
|
if(register_script_cb(avpdb_post_script_cb,
|
|
- REQUEST_CB | ONREPLY_CB | POST_SCRIPT_CB, 0)<0) {
|
|
|
|
|
|
+ REQUEST_CB | ONREPLY_CB | POST_SCRIPT_CB, 0)
|
|
|
|
+ < 0) {
|
|
LM_ERR("failed to register script callbacks\n");
|
|
LM_ERR("failed to register script callbacks\n");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
@@ -460,18 +503,19 @@ int init_extra_avp_locks()
|
|
memset(lock_counters, 0, sizeof(lock_counters));
|
|
memset(lock_counters, 0, sizeof(lock_counters));
|
|
|
|
|
|
locks = shm_malloc(sizeof(gen_lock_t) * LOCK_CNT);
|
|
locks = shm_malloc(sizeof(gen_lock_t) * LOCK_CNT);
|
|
- if (!locks) {
|
|
|
|
|
|
+ if(!locks) {
|
|
SHM_MEM_ERROR;
|
|
SHM_MEM_ERROR;
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
- for (i = 0; i < LOCK_CNT; i++) {
|
|
|
|
|
|
+ for(i = 0; i < LOCK_CNT; i++) {
|
|
lock_init(&locks[i]);
|
|
lock_init(&locks[i]);
|
|
}
|
|
}
|
|
|
|
|
|
/* initializes mutexes for extra AVPs */
|
|
/* initializes mutexes for extra AVPs */
|
|
i = 0;
|
|
i = 0;
|
|
- while (t) {
|
|
|
|
- t->group_mutex_idx = get_hash1_raw(t->table_name, strlen(t->table_name)) % LOCK_CNT;
|
|
|
|
|
|
+ while(t) {
|
|
|
|
+ t->group_mutex_idx =
|
|
|
|
+ get_hash1_raw(t->table_name, strlen(t->table_name)) % LOCK_CNT;
|
|
t = t->next;
|
|
t = t->next;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -484,14 +528,14 @@ static inline int find_mutex(registered_table_t *t, str *id)
|
|
return ((t->group_mutex_idx + get_hash1_raw(id->s, id->len)) % LOCK_CNT);
|
|
return ((t->group_mutex_idx + get_hash1_raw(id->s, id->len)) % LOCK_CNT);
|
|
}
|
|
}
|
|
|
|
|
|
-int lock_extra_attrs(struct sip_msg* msg, char *_table, char* _id)
|
|
|
|
|
|
+int lock_extra_attrs(struct sip_msg *msg, char *_table, char *_id)
|
|
{
|
|
{
|
|
str id;
|
|
str id;
|
|
registered_table_t *t;
|
|
registered_table_t *t;
|
|
int mutex_idx;
|
|
int mutex_idx;
|
|
|
|
|
|
t = (registered_table_t *)_table;
|
|
t = (registered_table_t *)_table;
|
|
- if ((!t) || (get_str_fparam(&id, msg, (fparam_t*)_id) < 0)) {
|
|
|
|
|
|
+ if((!t) || (get_str_fparam(&id, msg, (fparam_t *)_id) < 0)) {
|
|
ERR("invalid parameter value\n");
|
|
ERR("invalid parameter value\n");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
@@ -499,11 +543,10 @@ int lock_extra_attrs(struct sip_msg* msg, char *_table, char* _id)
|
|
/* find right mutex according to id/table */
|
|
/* find right mutex according to id/table */
|
|
mutex_idx = find_mutex(t, &id);
|
|
mutex_idx = find_mutex(t, &id);
|
|
|
|
|
|
- if (lock_counters[mutex_idx] > 0) {
|
|
|
|
|
|
+ if(lock_counters[mutex_idx] > 0) {
|
|
/* mutex is already locked by this process */
|
|
/* mutex is already locked by this process */
|
|
lock_counters[mutex_idx]++;
|
|
lock_counters[mutex_idx]++;
|
|
- }
|
|
|
|
- else {
|
|
|
|
|
|
+ } else {
|
|
/* the mutex was not locked => lock it and set counter */
|
|
/* the mutex was not locked => lock it and set counter */
|
|
lock_get(&locks[mutex_idx]);
|
|
lock_get(&locks[mutex_idx]);
|
|
lock_counters[mutex_idx] = 1;
|
|
lock_counters[mutex_idx] = 1;
|
|
@@ -512,14 +555,14 @@ int lock_extra_attrs(struct sip_msg* msg, char *_table, char* _id)
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
-int unlock_extra_attrs(struct sip_msg* msg, char *_table, char* _id)
|
|
|
|
|
|
+int unlock_extra_attrs(struct sip_msg *msg, char *_table, char *_id)
|
|
{
|
|
{
|
|
str id;
|
|
str id;
|
|
registered_table_t *t;
|
|
registered_table_t *t;
|
|
int mutex_idx;
|
|
int mutex_idx;
|
|
|
|
|
|
t = (registered_table_t *)_table;
|
|
t = (registered_table_t *)_table;
|
|
- if ((!t) || (get_str_fparam(&id, msg, (fparam_t*)_id) < 0)) {
|
|
|
|
|
|
+ if((!t) || (get_str_fparam(&id, msg, (fparam_t *)_id) < 0)) {
|
|
ERR("invalid parameter value\n");
|
|
ERR("invalid parameter value\n");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
@@ -527,19 +570,17 @@ int unlock_extra_attrs(struct sip_msg* msg, char *_table, char* _id)
|
|
/* find right mutex according to id/table */
|
|
/* find right mutex according to id/table */
|
|
mutex_idx = find_mutex(t, &id);
|
|
mutex_idx = find_mutex(t, &id);
|
|
|
|
|
|
- if (lock_counters[mutex_idx] > 1) {
|
|
|
|
|
|
+ if(lock_counters[mutex_idx] > 1) {
|
|
/* mutex is locked more times by this process */
|
|
/* mutex is locked more times by this process */
|
|
lock_counters[mutex_idx]--;
|
|
lock_counters[mutex_idx]--;
|
|
- }
|
|
|
|
- else if (lock_counters[mutex_idx] == 1) {
|
|
|
|
|
|
+ } else if(lock_counters[mutex_idx] == 1) {
|
|
/* the mutex is locked once => unlock it and reset counter */
|
|
/* the mutex is locked once => unlock it and reset counter */
|
|
lock_release(&locks[mutex_idx]);
|
|
lock_release(&locks[mutex_idx]);
|
|
lock_counters[mutex_idx] = 0;
|
|
lock_counters[mutex_idx] = 0;
|
|
- }
|
|
|
|
- else {
|
|
|
|
- BUG("trying to unlock without lock group=\"%s\" id=\"%.*s\"\n", t->id, id.len, id.s);
|
|
|
|
|
|
+ } else {
|
|
|
|
+ BUG("trying to unlock without lock group=\"%s\" id=\"%.*s\"\n", t->id,
|
|
|
|
+ id.len, id.s);
|
|
}
|
|
}
|
|
|
|
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
-
|
|
|