diff --git a/src/modules/htable/ht_api.c b/src/modules/htable/ht_api.c index 0f1c74f8960..204965e79a1 100644 --- a/src/modules/htable/ht_api.c +++ b/src/modules/htable/ht_api.c @@ -1878,6 +1878,106 @@ int ht_iterator_rm(str *iname) return -2; } +int ht_iterator_sets(str *iname, str *sval) +{ + int k; + ht_cell_t *itb; + unsigned int hid; + ht_cell_t *cell; + int_str isvalue; + + k = ht_iterator_find(iname); + if(k==-1) { + LM_ERR("iterator not found [%.*s]\n", iname->len, iname->s); + return -1; + } + if(_ht_iterators[k].ht==NULL) { + LM_ERR("iterator not initialized [%.*s]\n", iname->len, iname->s); + return -1; + } + if(_ht_iterators[k].it==NULL) { + LM_ERR("iterator not used [%.*s]\n", iname->len, iname->s); + return -1; + } + + itb = _ht_iterators[k].it; + + /* update value */ + if(itb->flags&AVP_VAL_STR) { + if(itb->value.s.len >= sval->len) { + /* copy */ + itb->value.s.len = sval->len; + memcpy(itb->value.s.s, sval->s, sval->len); + itb->value.s.s[itb->value.s.len] = '\0'; + + if(_ht_iterators[k].ht->updateexpire) { + itb->expire = time(NULL) + _ht_iterators[k].ht->htexpire; + } + return 0; + } + } + /* new */ + hid = ht_compute_hash(&itb->name); + + isvalue.s = *sval; + + cell = ht_cell_new(&itb->name, AVP_VAL_STR, &isvalue, hid); + if(cell == NULL) { + LM_ERR("cannot create new cell\n"); + return -1; + } + cell->next = itb->next; + cell->prev = itb->prev; + if(_ht_iterators[k].ht->updateexpire) { + cell->expire = time(NULL) + _ht_iterators[k].ht->htexpire; + } else { + cell->expire = itb->expire; + } + if(itb->prev) + itb->prev->next = cell; + else + _ht_iterators[k].ht->entries[_ht_iterators[k].slot].first = cell; + if(itb->next) + itb->next->prev = cell; + ht_cell_free(itb); + _ht_iterators[k].it = cell; + + return 0; +} + +int ht_iterator_seti(str *iname, int ival) +{ + int k; + ht_cell_t *itb; + + k = ht_iterator_find(iname); + if(k==-1) { + LM_ERR("iterator not found [%.*s]\n", iname->len, iname->s); + return -1; + } + if(_ht_iterators[k].ht==NULL) { + LM_ERR("iterator not initialized [%.*s]\n", iname->len, iname->s); + return -1; + } + if(_ht_iterators[k].it==NULL) { + LM_ERR("iterator not used [%.*s]\n", iname->len, iname->s); + return -1; + } + + itb = _ht_iterators[k].it; + + /* update value */ + if(itb->flags&AVP_VAL_STR) { + itb->flags &= ~AVP_VAL_STR; + } + itb->value.n = ival; + + if(_ht_iterators[k].ht->updateexpire) { + itb->expire = time(NULL) + _ht_iterators[k].ht->htexpire; + } + return 0; +} + ht_cell_t* ht_iterator_get_current(str *iname) { int k; diff --git a/src/modules/htable/ht_api.h b/src/modules/htable/ht_api.h index 213206b7d75..47388d1289d 100644 --- a/src/modules/htable/ht_api.h +++ b/src/modules/htable/ht_api.h @@ -130,6 +130,8 @@ int ht_iterator_start(str *iname, str *hname); int ht_iterator_next(str *iname); int ht_iterator_end(str *iname); int ht_iterator_rm(str *iname); +int ht_iterator_sets(str *iname, str *sval); +int ht_iterator_seti(str *iname, int ival); ht_cell_t* ht_iterator_get_current(str *iname); void ht_slot_lock(ht_t *ht, int idx); diff --git a/src/modules/htable/htable.c b/src/modules/htable/htable.c index 526af32e190..7fa26320ab0 100644 --- a/src/modules/htable/htable.c +++ b/src/modules/htable/htable.c @@ -81,6 +81,8 @@ static int w_ht_iterator_start(struct sip_msg* msg, char* iname, char* hname); static int w_ht_iterator_next(struct sip_msg* msg, char* iname, char* foo); static int w_ht_iterator_end(struct sip_msg* msg, char* iname, char* foo); static int w_ht_iterator_rm(struct sip_msg* msg, char* iname, char* foo); +static int w_ht_iterator_sets(struct sip_msg* msg, char* iname, char* val); +static int w_ht_iterator_seti(struct sip_msg* msg, char* iname, char* val); int ht_param(modparam_t type, void* val); @@ -143,6 +145,11 @@ static cmd_export_t cmds[]={ ANY_ROUTE}, {"sht_iterator_rm", (cmd_function)w_ht_iterator_rm, 1, fixup_spve_null, 0, ANY_ROUTE}, + {"sht_iterator_sets", (cmd_function)w_ht_iterator_sets, 2, fixup_spve_spve, + fixup_free_spve_spve, ANY_ROUTE}, + {"sht_iterator_seti", (cmd_function)w_ht_iterator_seti, 2, fixup_spve_igp, + fixup_free_spve_igp, ANY_ROUTE}, + {"bind_htable", (cmd_function)bind_htable, 0, 0, 0, ANY_ROUTE}, {0,0,0,0,0,0} @@ -819,6 +826,70 @@ static int ki_ht_iterator_rm(sip_msg_t *msg, str *iname) return (ret==0)?1:ret; } +static int ki_ht_iterator_sets(sip_msg_t *msg, str *iname, str *sval) +{ + int ret; + + if(iname==NULL || iname->s==NULL || iname->len<=0) { + LM_ERR("invalid parameters\n"); + return -1; + } + + ret = ht_iterator_sets(iname, sval); + return (ret==0)?1:ret; +} + +static int w_ht_iterator_sets(struct sip_msg* msg, char* iname, char* val) +{ + str siname; + str sval; + + if(fixup_get_svalue(msg, (gparam_t*)iname, &siname)<0) + { + LM_ERR("cannot get iterator name\n"); + return -1; + } + if(fixup_get_svalue(msg, (gparam_t*)val, &sval)<0) + { + LM_ERR("cannot get value\n"); + return -1; + } + + return ki_ht_iterator_sets(msg, &siname, &sval); +} + +static int ki_ht_iterator_seti(sip_msg_t *msg, str *iname, int ival) +{ + int ret; + + if(iname==NULL || iname->s==NULL || iname->len<=0) { + LM_ERR("invalid parameters\n"); + return -1; + } + + ret = ht_iterator_seti(iname, ival); + return (ret==0)?1:ret; +} + +static int w_ht_iterator_seti(struct sip_msg* msg, char* iname, char* val) +{ + str siname; + int ival; + + if(fixup_get_svalue(msg, (gparam_t*)iname, &siname)<0 || siname.len<=0) + { + LM_ERR("cannot get iterator name\n"); + return -1; + } + if(fixup_get_ivalue(msg, (gparam_t*)val, &ival)<0) + { + LM_ERR("cannot get value\n"); + return -1; + } + + return ki_ht_iterator_seti(msg, &siname, ival); +} + static int ki_ht_slot_xlock(sip_msg_t *msg, str *htname, str *skey, int lmode) { ht_t *ht; @@ -1907,6 +1978,16 @@ static sr_kemi_t sr_kemi_htable_exports[] = { { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } }, + { str_init("htable"), str_init("sht_iterator_sets"), + SR_KEMIP_INT, ki_ht_iterator_sets, + { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, + { str_init("htable"), str_init("sht_iterator_seti"), + SR_KEMIP_INT, ki_ht_iterator_seti, + { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, { str_init("htable"), str_init("sht_rm"), SR_KEMIP_INT, ki_ht_rm, { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,