00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "udomain.h"
00039 #include <string.h>
00040 #include "../../parser/parse_methods.h"
00041 #include "../../mem/shm_mem.h"
00042 #include "../../dprint.h"
00043 #include "../../db/db.h"
00044 #include "../../socket_info.h"
00045 #include "../../ut.h"
00046 #include "../../hash_func.h"
00047 #include "ul_mod.h"
00048 #include "utime.h"
00049
00050
00051 #ifdef STATISTICS
00052 static char *build_stat_name( str* domain, char *var_name)
00053 {
00054 int n;
00055 char *s;
00056 char *p;
00057
00058 n = domain->len + 1 + strlen(var_name) + 1;
00059 s = (char*)shm_malloc( n );
00060 if (s==0) {
00061 LM_ERR("no more shm mem\n");
00062 return 0;
00063 }
00064 memcpy( s, domain->s, domain->len);
00065 p = s + domain->len;
00066 *(p++) = '-';
00067 memcpy( p , var_name, strlen(var_name));
00068 p += strlen(var_name);
00069 *(p++) = 0;
00070 return s;
00071 }
00072 #endif
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 int new_udomain(str* _n, int _s, udomain_t** _d)
00084 {
00085 int i;
00086 #ifdef STATISTICS
00087 char *name;
00088 #endif
00089
00090
00091
00092
00093
00094 *_d = (udomain_t*)shm_malloc(sizeof(udomain_t));
00095 if (!(*_d)) {
00096 LM_ERR("new_udomain(): No memory left\n");
00097 goto error0;
00098 }
00099 memset(*_d, 0, sizeof(udomain_t));
00100
00101 (*_d)->table = (hslot_t*)shm_malloc(sizeof(hslot_t) * _s);
00102 if (!(*_d)->table) {
00103 LM_ERR("no memory left 2\n");
00104 goto error1;
00105 }
00106
00107 (*_d)->name = _n;
00108
00109 for(i = 0; i < _s; i++) {
00110 init_slot(*_d, &((*_d)->table[i]), i);
00111 }
00112
00113 (*_d)->size = _s;
00114
00115 #ifdef STATISTICS
00116
00117 if ( (name=build_stat_name(_n,"users"))==0 || register_stat("usrloc",
00118 name, &(*_d)->users, STAT_NO_RESET|STAT_SHM_NAME)!=0 ) {
00119 LM_ERR("failed to add stat variable\n");
00120 goto error2;
00121 }
00122 if ( (name=build_stat_name(_n,"contacts"))==0 || register_stat("usrloc",
00123 name, &(*_d)->contacts, STAT_NO_RESET|STAT_SHM_NAME)!=0 ) {
00124 LM_ERR("failed to add stat variable\n");
00125 goto error2;
00126 }
00127 if ( (name=build_stat_name(_n,"expires"))==0 || register_stat("usrloc",
00128 name, &(*_d)->expires, STAT_SHM_NAME)!=0 ) {
00129 LM_ERR("failed to add stat variable\n");
00130 goto error2;
00131 }
00132 #endif
00133
00134 return 0;
00135 error2:
00136 shm_free((*_d)->table);
00137 error1:
00138 shm_free(*_d);
00139 error0:
00140 return -1;
00141 }
00142
00143
00144
00145
00146
00147
00148 void free_udomain(udomain_t* _d)
00149 {
00150 int i;
00151
00152 if (_d->table) {
00153 for(i = 0; i < _d->size; i++) {
00154 lock_ulslot(_d, i);
00155 deinit_slot(_d->table + i);
00156 unlock_ulslot(_d, i);
00157 }
00158 shm_free(_d->table);
00159 }
00160 shm_free(_d);
00161 }
00162
00163
00164
00165
00166
00167
00168
00169
00170 static inline void get_static_urecord(udomain_t* _d, str* _aor,
00171 struct urecord** _r)
00172 {
00173 static struct urecord r;
00174
00175 memset( &r, 0, sizeof(struct urecord) );
00176 r.aor = *_aor;
00177 r.domain = _d->name;
00178 *_r = &r;
00179 }
00180
00181
00182
00183
00184
00185 void print_udomain(FILE* _f, udomain_t* _d)
00186 {
00187 int i;
00188 int max=0, slot=0, n=0;
00189 struct urecord* r;
00190 fprintf(_f, "---Domain---\n");
00191 fprintf(_f, "name : '%.*s'\n", _d->name->len, ZSW(_d->name->s));
00192 fprintf(_f, "size : %d\n", _d->size);
00193 fprintf(_f, "table: %p\n", _d->table);
00194
00195 fprintf(_f, "\n");
00196 for(i=0; i<_d->size; i++)
00197 {
00198 r = _d->table[i].first;
00199 n += _d->table[i].n;
00200 if(max<_d->table[i].n){
00201 max= _d->table[i].n;
00202 slot = i;
00203 }
00204 while(r) {
00205 print_urecord(_f, r);
00206 r = r->next;
00207 }
00208 }
00209 fprintf(_f, "\nMax slot: %d (%d/%d)\n", max, slot, n);
00210 fprintf(_f, "\n---/Domain---\n");
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 static inline ucontact_info_t* dbrow2info( db_val_t *vals, str *contact)
00225 {
00226 static ucontact_info_t ci;
00227 static str callid, ua, received, host, path;
00228 int port, proto;
00229 char *p;
00230
00231 memset( &ci, 0, sizeof(ucontact_info_t));
00232
00233 contact->s = (char*)VAL_STRING(vals);
00234 if (VAL_NULL(vals) || contact->s==0 || contact->s[0]==0) {
00235 LM_CRIT("bad contact\n");
00236 return 0;
00237 }
00238 contact->len = strlen(contact->s);
00239
00240 if (VAL_NULL(vals+1)) {
00241 LM_CRIT("empty expire\n");
00242 return 0;
00243 }
00244 ci.expires = VAL_TIME(vals+1);
00245
00246 if (VAL_NULL(vals+2)) {
00247 LM_CRIT("empty q\n");
00248 return 0;
00249 }
00250 ci.q = double2q(VAL_DOUBLE(vals+2));
00251
00252 if (VAL_NULL(vals+4)) {
00253 LM_CRIT("empty cseq_nr\n");
00254 return 0;
00255 }
00256 ci.cseq = VAL_INT(vals+4);
00257
00258 callid.s = (char*)VAL_STRING(vals+3);
00259 if (VAL_NULL(vals+3) || !callid.s || !callid.s[0]) {
00260 LM_CRIT("bad callid\n");
00261 return 0;
00262 }
00263 callid.len = strlen(callid.s);
00264 ci.callid = &callid;
00265
00266 if (VAL_NULL(vals+5)) {
00267 LM_CRIT("empty flag\n");
00268 return 0;
00269 }
00270 ci.flags = VAL_BITMAP(vals+5);
00271
00272 if (VAL_NULL(vals+6)) {
00273 LM_CRIT("empty cflag\n");
00274 return 0;
00275 }
00276 ci.cflags = VAL_BITMAP(vals+6);
00277
00278 ua.s = (char*)VAL_STRING(vals+7);
00279 if (VAL_NULL(vals+7) || !ua.s || !ua.s[0]) {
00280 ua.s = 0;
00281 ua.len = 0;
00282 } else {
00283 ua.len = strlen(ua.s);
00284 }
00285 ci.user_agent = &ua;
00286
00287 received.s = (char*)VAL_STRING(vals+8);
00288 if (VAL_NULL(vals+8) || !received.s || !received.s[0]) {
00289 received.len = 0;
00290 received.s = 0;
00291 } else {
00292 received.len = strlen(received.s);
00293 }
00294 ci.received = received;
00295
00296 path.s = (char*)VAL_STRING(vals+9);
00297 if (VAL_NULL(vals+9) || !path.s || !path.s[0]) {
00298 path.len = 0;
00299 path.s = 0;
00300 } else {
00301 path.len = strlen(path.s);
00302 }
00303 ci.path= &path;
00304
00305
00306 p = (char*)VAL_STRING(vals+10);
00307 if (VAL_NULL(vals+10) || p==0 || p[0]==0){
00308 ci.sock = 0;
00309 } else {
00310 if (parse_phostport( p, strlen(p), &host.s, &host.len,
00311 &port, &proto)!=0) {
00312 LM_ERR("bad socket <%s>\n", p);
00313 return 0;
00314 }
00315 ci.sock = grep_sock_info( &host, (unsigned short)port, proto);
00316 if (ci.sock==0) {
00317 LM_WARN("non-local socket <%s>...ignoring\n", p);
00318 }
00319 }
00320
00321
00322 if (VAL_NULL(vals+11)) {
00323 ci.methods = ALL_METHODS;
00324 } else {
00325 ci.methods = VAL_BITMAP(vals+11);
00326 }
00327
00328
00329 if (!VAL_NULL(vals+12)) {
00330 ci.last_modified = VAL_TIME(vals+12);
00331 }
00332
00333 return &ci;
00334 }
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 int preload_udomain(db_con_t* _c, udomain_t* _d)
00347 {
00348 char uri[MAX_URI_SIZE];
00349 ucontact_info_t *ci;
00350 db_row_t *row;
00351 db_key_t columns[15];
00352 db_res_t* res = NULL;
00353 str user, contact;
00354 char* domain;
00355 int i;
00356 int n;
00357
00358 urecord_t* r;
00359 ucontact_t* c;
00360
00361 columns[0] = &user_col;
00362 columns[1] = &contact_col;
00363 columns[2] = &expires_col;
00364 columns[3] = &q_col;
00365 columns[4] = &callid_col;
00366 columns[5] = &cseq_col;
00367 columns[6] = &flags_col;
00368 columns[7] = &cflags_col;
00369 columns[8] = &user_agent_col;
00370 columns[9] = &received_col;
00371 columns[10] = &path_col;
00372 columns[11] = &sock_col;
00373 columns[12] = &methods_col;
00374 columns[13] = &last_mod_col;
00375 columns[14] = &domain_col;
00376
00377 if (ul_dbf.use_table(_c, _d->name) < 0) {
00378 LM_ERR("sql use_table failed\n");
00379 return -1;
00380 }
00381
00382 #ifdef EXTRA_DEBUG
00383 LM_NOTICE("load start time [%d]\n", (int)time(NULL));
00384 #endif
00385
00386 if (DB_CAPABILITY(ul_dbf, DB_CAP_FETCH)) {
00387 if (ul_dbf.query(_c, 0, 0, 0, columns, 0, (use_domain)?(15):(14), 0,
00388 0) < 0) {
00389 LM_ERR("db_query (1) failed\n");
00390 return -1;
00391 }
00392 if(ul_dbf.fetch_result(_c, &res, ul_fetch_rows)<0) {
00393 LM_ERR("fetching rows failed\n");
00394 return -1;
00395 }
00396 } else {
00397 if (ul_dbf.query(_c, 0, 0, 0, columns, 0, (use_domain)?(15):(14), 0,
00398 &res) < 0) {
00399 LM_ERR("db_query failed\n");
00400 return -1;
00401 }
00402 }
00403
00404 if (RES_ROW_N(res) == 0) {
00405 LM_DBG("table is empty\n");
00406 ul_dbf.free_result(_c, res);
00407 return 0;
00408 }
00409
00410
00411 n = 0;
00412 do {
00413 LM_DBG("loading records - cycle [%d]\n", ++n);
00414 for(i = 0; i < RES_ROW_N(res); i++) {
00415 row = RES_ROWS(res) + i;
00416
00417 user.s = (char*)VAL_STRING(ROW_VALUES(row));
00418 if (VAL_NULL(ROW_VALUES(row)) || user.s==0 || user.s[0]==0) {
00419 LM_CRIT("empty username record in table %s...skipping\n",
00420 _d->name->s);
00421 continue;
00422 }
00423 user.len = strlen(user.s);
00424
00425 ci = dbrow2info( ROW_VALUES(row)+1, &contact);
00426 if (ci==0) {
00427 LM_ERR("sipping record for %.*s in table %s\n",
00428 user.len, user.s, _d->name->s);
00429 continue;
00430 }
00431
00432 if (use_domain) {
00433 domain = (char*)VAL_STRING(ROW_VALUES(row) + 14);
00434 if (VAL_NULL(ROW_VALUES(row)+13) || domain==0 || domain[0]==0){
00435 LM_CRIT("empty domain record for user %.*s...skipping\n",
00436 user.len, user.s);
00437 continue;
00438 }
00439
00440 user.len = snprintf(uri, MAX_URI_SIZE, "%.*s@%s",
00441 user.len, user.s, domain);
00442 user.s = uri;
00443 if (user.s[user.len]!=0) {
00444 LM_CRIT("URI '%.*s@%s' longer than %d\n", user.len, user.s,
00445 domain, MAX_URI_SIZE);
00446 continue;
00447 }
00448 }
00449
00450
00451 lock_udomain(_d, &user);
00452 if (get_urecord(_d, &user, &r) > 0) {
00453 if (mem_insert_urecord(_d, &user, &r) < 0) {
00454 LM_ERR("failed to create a record\n");
00455 unlock_udomain(_d, &user);
00456 goto error;
00457 }
00458 }
00459
00460 if ( (c=mem_insert_ucontact(r, &contact, ci)) == 0) {
00461 LM_ERR("inserting contact failed\n");
00462 unlock_udomain(_d, &user);
00463 goto error1;
00464 }
00465
00466
00467
00468 c->state = CS_SYNC;
00469 unlock_udomain(_d, &user);
00470 }
00471
00472 if (DB_CAPABILITY(ul_dbf, DB_CAP_FETCH)) {
00473 if(ul_dbf.fetch_result(_c, &res, ul_fetch_rows)<0) {
00474 LM_ERR("fetching rows (1) failed\n");
00475 ul_dbf.free_result(_c, res);
00476 return -1;
00477 }
00478 } else {
00479 break;
00480 }
00481 } while(RES_ROW_N(res)>0);
00482
00483 ul_dbf.free_result(_c, res);
00484
00485 #ifdef EXTRA_DEBUG
00486 LM_NOTICE("load end time [%d]\n", (int)time(NULL));
00487 #endif
00488
00489 return 0;
00490 error1:
00491 free_ucontact(c);
00492 error:
00493 ul_dbf.free_result(_c, res);
00494 return -1;
00495 }
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 urecord_t* db_load_urecord(db_con_t* _c, udomain_t* _d, str *_aor)
00506 {
00507 ucontact_info_t *ci;
00508 db_key_t columns[13];
00509 db_key_t keys[2];
00510 db_key_t order;
00511 db_val_t vals[2];
00512 db_res_t* res = NULL;
00513 str contact;
00514 char *domain;
00515 int i;
00516
00517 urecord_t* r;
00518 ucontact_t* c;
00519
00520 keys[0] = &user_col;
00521 vals[0].type = DB_STR;
00522 vals[0].nul = 0;
00523 if (use_domain) {
00524 keys[1] = &domain_col;
00525 vals[1].type = DB_STR;
00526 vals[1].nul = 0;
00527 domain = memchr(_aor->s, '@', _aor->len);
00528 vals[0].val.str_val.s = _aor->s;
00529 if (domain==0) {
00530 vals[0].val.str_val.len = 0;
00531 vals[1].val.str_val = *_aor;
00532 } else {
00533 vals[0].val.str_val.len = domain - _aor->s;
00534 vals[1].val.str_val.s = domain+1;
00535 vals[1].val.str_val.len = _aor->s + _aor->len - domain - 1;
00536 }
00537 } else {
00538 vals[0].val.str_val = *_aor;
00539 }
00540
00541 columns[0] = &contact_col;
00542 columns[1] = &expires_col;
00543 columns[2] = &q_col;
00544 columns[3] = &callid_col;
00545 columns[4] = &cseq_col;
00546 columns[5] = &flags_col;
00547 columns[6] = &cflags_col;
00548 columns[7] = &user_agent_col;
00549 columns[8] = &received_col;
00550 columns[9] = &path_col;
00551 columns[10] = &sock_col;
00552 columns[11] = &methods_col;
00553 columns[12] = &last_mod_col;
00554
00555 if (desc_time_order)
00556 order = &last_mod_col;
00557 else
00558 order = &q_col;
00559
00560 if (ul_dbf.use_table(_c, _d->name) < 0) {
00561 LM_ERR("failed to use table %.*s\n", _d->name->len, _d->name->s);
00562 return 0;
00563 }
00564
00565 if (ul_dbf.query(_c, keys, 0, vals, columns, (use_domain)?2:1, 13, order,
00566 &res) < 0) {
00567 LM_ERR("db_query failed\n");
00568 return 0;
00569 }
00570
00571 if (RES_ROW_N(res) == 0) {
00572 LM_DBG("aor %.*s not found in table %.*s\n",_aor->len, _aor->s, _d->name->len, _d->name->s);
00573 ul_dbf.free_result(_c, res);
00574 return 0;
00575 }
00576
00577 r = 0;
00578
00579 for(i = 0; i < RES_ROW_N(res); i++) {
00580 ci = dbrow2info( ROW_VALUES(RES_ROWS(res) + i), &contact);
00581 if (ci==0) {
00582 LM_ERR("skipping record for %.*s in table %s\n",
00583 _aor->len, _aor->s, _d->name->s);
00584 continue;
00585 }
00586
00587 if ( r==0 )
00588 get_static_urecord( _d, _aor, &r);
00589
00590 if ( (c=mem_insert_ucontact(r, &contact, ci)) == 0) {
00591 LM_ERR("mem_insert failed\n");
00592 free_urecord(r);
00593 ul_dbf.free_result(_c, res);
00594 return 0;
00595 }
00596
00597
00598
00599 c->state = CS_SYNC;
00600 }
00601
00602 ul_dbf.free_result(_c, res);
00603 return r;
00604 }
00605
00606
00607
00608
00609
00610
00611
00612 int db_timer_udomain(udomain_t* _d)
00613 {
00614 db_key_t keys[2];
00615 db_op_t ops[2];
00616 db_val_t vals[2];
00617
00618 keys[0] = &expires_col;
00619 ops[0] = "<";
00620 vals[0].type = DB_DATETIME;
00621 vals[0].nul = 0;
00622 vals[0].val.time_val = act_time + 1;
00623
00624 keys[1] = &expires_col;
00625 ops[1] = "!=";
00626 vals[1].type = DB_DATETIME;
00627 vals[1].nul = 0;
00628 vals[1].val.time_val = 0;
00629
00630 if (ul_dbf.use_table(ul_dbh, _d->name) < 0) {
00631 LM_ERR("use_table failed\n");
00632 return -1;
00633 }
00634
00635 if (ul_dbf.delete(ul_dbh, keys, ops, vals, 2) < 0) {
00636 LM_ERR("failed to delete from table %s\n",_d->name->s);
00637 return -1;
00638 }
00639
00640 return 0;
00641 }
00642
00643
00644
00645
00646
00647
00648
00649 int testdb_udomain(db_con_t* con, udomain_t* d)
00650 {
00651 db_key_t key[1], col[1];
00652 db_val_t val[1];
00653 db_res_t* res = NULL;
00654
00655 if (ul_dbf.use_table(con, d->name) < 0) {
00656 LM_ERR("failed to change table\n");
00657 return -1;
00658 }
00659
00660 key[0] = &user_col;
00661
00662 col[0] = &user_col;
00663 VAL_TYPE(val) = DB_STRING;
00664 VAL_NULL(val) = 0;
00665 VAL_STRING(val) = "dummy_user";
00666
00667 if (ul_dbf.query( con, key, 0, val, col, 1, 1, 0, &res) < 0) {
00668 LM_ERR("failure in db_query\n");
00669 return -1;
00670 }
00671
00672 ul_dbf.free_result( con, res);
00673 return 0;
00674 }
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684 int mem_insert_urecord(udomain_t* _d, str* _aor, struct urecord** _r)
00685 {
00686 int sl;
00687
00688 if (new_urecord(_d->name, _aor, _r) < 0) {
00689 LM_ERR("creating urecord failed\n");
00690 return -1;
00691 }
00692
00693 sl = ((*_r)->aorhash)&(_d->size-1);
00694 slot_add(&_d->table[sl], *_r);
00695 update_stat( _d->users, 1);
00696 return 0;
00697 }
00698
00699
00700
00701
00702
00703
00704
00705 void mem_delete_urecord(udomain_t* _d, struct urecord* _r)
00706 {
00707 slot_rem(_r->slot, _r);
00708 free_urecord(_r);
00709 update_stat( _d->users, -1);
00710 }
00711
00712
00713
00714
00715
00716
00717 void mem_timer_udomain(udomain_t* _d)
00718 {
00719 struct urecord* ptr, *t;
00720 int i;
00721
00722 for(i=0; i<_d->size; i++)
00723 {
00724 lock_ulslot(_d, i);
00725
00726 ptr = _d->table[i].first;
00727
00728 while(ptr) {
00729 timer_urecord(ptr);
00730
00731 if (ptr->contacts == 0) {
00732 t = ptr;
00733 ptr = ptr->next;
00734 mem_delete_urecord(_d, t);
00735 } else {
00736 ptr = ptr->next;
00737 }
00738 }
00739 unlock_ulslot(_d, i);
00740 }
00741 }
00742
00743
00744
00745
00746
00747
00748
00749 void lock_udomain(udomain_t* _d, str* _aor)
00750 {
00751 unsigned int sl;
00752 if (db_mode!=DB_ONLY)
00753 {
00754 sl = core_hash(_aor, 0, _d->size);
00755
00756 #ifdef GEN_LOCK_T_PREFERED
00757 lock_get(_d->table[sl].lock);
00758 #else
00759 ul_lock_idx(_d->table[sl].lockidx);
00760 #endif
00761 }
00762 }
00763
00764
00765
00766
00767
00768
00769
00770 void unlock_udomain(udomain_t* _d, str* _aor)
00771 {
00772 unsigned int sl;
00773 if (db_mode!=DB_ONLY)
00774 {
00775 sl = core_hash(_aor, 0, _d->size);
00776 #ifdef GEN_LOCK_T_PREFERED
00777 lock_release(_d->table[sl].lock);
00778 #else
00779 ul_release_idx(_d->table[sl].lockidx);
00780 #endif
00781 }
00782 }
00783
00784
00785
00786
00787
00788
00789 void lock_ulslot(udomain_t* _d, int i)
00790 {
00791 if (db_mode!=DB_ONLY)
00792 #ifdef GEN_LOCK_T_PREFERED
00793 lock_get(_d->table[i].lock);
00794 #else
00795 ul_lock_idx(_d->table[i].lockidx);
00796 #endif
00797 }
00798
00799
00800
00801
00802
00803
00804
00805 void unlock_ulslot(udomain_t* _d, int i)
00806 {
00807 if (db_mode!=DB_ONLY)
00808 #ifdef GEN_LOCK_T_PREFERED
00809 lock_release(_d->table[i].lock);
00810 #else
00811 ul_release_idx(_d->table[i].lockidx);
00812 #endif
00813 }
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824 int insert_urecord(udomain_t* _d, str* _aor, struct urecord** _r)
00825 {
00826 if (db_mode!=DB_ONLY) {
00827 if (mem_insert_urecord(_d, _aor, _r) < 0) {
00828 LM_ERR("inserting record failed\n");
00829 return -1;
00830 }
00831 } else {
00832 get_static_urecord( _d, _aor, _r);
00833 }
00834 return 0;
00835 }
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845 int get_urecord(udomain_t* _d, str* _aor, struct urecord** _r)
00846 {
00847 unsigned int sl, i, aorhash;
00848 urecord_t* r;
00849
00850 if (db_mode!=DB_ONLY) {
00851
00852 aorhash = core_hash(_aor, 0, 0);
00853 sl = aorhash&(_d->size-1);
00854 r = _d->table[sl].first;
00855
00856 for(i = 0; i < _d->table[sl].n; i++) {
00857 if((r->aorhash==aorhash) && (r->aor.len==_aor->len)
00858 && !memcmp(r->aor.s,_aor->s,_aor->len)){
00859 *_r = r;
00860 return 0;
00861 }
00862
00863 r = r->next;
00864 }
00865 } else {
00866
00867 r = db_load_urecord( ul_dbh, _d, _aor);
00868 if (r) {
00869 *_r = r;
00870 return 0;
00871 }
00872 }
00873
00874 return 1;
00875 }
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885 int delete_urecord(udomain_t* _d, str* _aor, struct urecord* _r)
00886 {
00887 struct ucontact* c, *t;
00888
00889 if (db_mode==DB_ONLY) {
00890 if (_r==0)
00891 get_static_urecord( _d, _aor, &_r);
00892 if (db_delete_urecord(_r)<0) {
00893 LM_ERR("DB delete failed\n");
00894 return -1;
00895 }
00896 free_urecord(_r);
00897 return 0;
00898 }
00899
00900 if (_r==0) {
00901 if (get_urecord(_d, _aor, &_r) > 0) {
00902 return 0;
00903 }
00904 }
00905
00906 c = _r->contacts;
00907 while(c) {
00908 t = c;
00909 c = c->next;
00910 if (delete_ucontact(_r, t) < 0) {
00911 LM_ERR("deleting contact failed\n");
00912 return -1;
00913 }
00914 }
00915 release_urecord(_r);
00916 return 0;
00917 }