static void rpc_add_contact(rpc_t* rpc, void* c) { udomain_t* d; int expires, flags, sid; double q; qvalue_t qval; str table, uid, contact; if (rpc->scan(c, "SSSdfd", &table, &uid, &contact, &expires, &q, &flags) < 6) return; qval = double2q(q); if (rpc->scan(c, "d", &sid) < 1) sid = -1; rpc_find_domain(&table, &d); if (d) { lock_udomain(d); if (add_contact(d, &uid, &contact, expires, qval, flags, sid) < 0) { unlock_udomain(d); ERR("Error while adding contact ('%.*s','%.*s') in table '%.*s'\n", uid.len, ZSW(uid.s), contact.len, ZSW(contact.s), table.len, ZSW(table.s)); rpc->fault(c, 500, "Error while adding Contact"); return; } unlock_udomain(d); } else { rpc->fault(c, 400, "Table Not Found"); } }
int preload_udomain(db_con_t* _c, udomain_t* _d) { char b[256]; db_key_t columns[11]; db_res_t* res; db_row_t* row; int i, cseq; unsigned int flags; struct socket_info* sock; str uid, contact, callid, ua, received, instance, aor; str* rec; time_t expires; qvalue_t q; urecord_t* r; ucontact_t* c; columns[0] = uid_col.s; columns[1] = contact_col.s; columns[2] = expires_col.s; columns[3] = q_col.s; columns[4] = callid_col.s; columns[5] = cseq_col.s; columns[6] = flags_col.s; columns[7] = user_agent_col.s; columns[8] = received_col.s; columns[9] = instance_col.s; columns[10] = aor_col.s; memcpy(b, _d->name->s, _d->name->len); b[_d->name->len] = '\0'; if (ul_dbf.use_table(_c, b) < 0) { LOG(L_ERR, "preload_udomain(): Error in use_table\n"); return -1; } if (ul_dbf.query(_c, 0, 0, 0, columns, 0, 11, 0, &res) < 0) { LOG(L_ERR, "preload_udomain(): Error while doing db_query\n"); return -1; } if (RES_ROW_N(res) == 0) { DBG("preload_udomain(): Table is empty\n"); ul_dbf.free_result(_c, res); return 0; } lock_udomain(_d); for(i = 0; i < RES_ROW_N(res); i++) { row = RES_ROWS(res) + i; uid.s = (char*)VAL_STRING(ROW_VALUES(row)); if (uid.s == 0) { LOG(L_CRIT, "preload_udomain: ERROR: bad uid " "record in table %s\n", b); LOG(L_CRIT, "preload_udomain: ERROR: skipping...\n"); continue; } else { uid.len = strlen(uid.s); } contact.s = (char*)VAL_STRING(ROW_VALUES(row) + 1); if (contact.s == 0) { LOG(L_CRIT, "preload_udomain: ERROR: bad contact " "record in table %s\n", b); LOG(L_CRIT, "preload_udomain: ERROR: for username %.*s\n", uid.len, uid.s); LOG(L_CRIT, "preload_udomain: ERROR: skipping...\n"); continue; } else { contact.len = strlen(contact.s); } expires = VAL_TIME (ROW_VALUES(row) + 2); q = double2q(VAL_DOUBLE(ROW_VALUES(row) + 3)); cseq = VAL_INT (ROW_VALUES(row) + 5); callid.s = (char*)VAL_STRING(ROW_VALUES(row) + 4); if (callid.s == 0) { LOG(L_CRIT, "preload_udomain: ERROR: bad callid record in" " table %s\n", b); LOG(L_CRIT, "preload_udomain: ERROR: for username %.*s," " contact %.*s\n", uid.len, uid.s, contact.len, contact.s); LOG(L_CRIT, "preload_udomain: ERROR: skipping...\n"); continue; } else { callid.len = strlen(callid.s); } flags = VAL_BITMAP(ROW_VALUES(row) + 6); ua.s = (char*)VAL_STRING(ROW_VALUES(row) + 7); if (ua.s) { ua.len = strlen(ua.s); } else { ua.len = 0; } if (!VAL_NULL(ROW_VALUES(row) + 8)) { received.s = (char*)VAL_STRING(ROW_VALUES(row) + 8); if (received.s) { received.len = strlen(received.s); rec = &received; sock = find_socket(&received); } else { received.len = 0; rec = 0; sock = 0; } } else { received.s = 0; received.len = 0; rec = 0; sock = 0; } if (!VAL_NULL(ROW_VALUES(row) + 9)) { instance.s = (char*)VAL_STRING(ROW_VALUES(row) + 9); if (instance.s) { instance.len = strlen(instance.s); } else { instance.len = 0; } } else { instance.s = 0; instance.len = 0; } if (!VAL_NULL(ROW_VALUES(row) + 10)) { aor.s = (char*)VAL_STRING(ROW_VALUES(row) + 10); if (aor.s) { aor.len = strlen(aor.s); } else { aor.len = 0; } } else { aor.s = 0; aor.len = 0; } if (get_urecord(_d, &uid, &r) > 0) { if (mem_insert_urecord(_d, &uid, &r) < 0) { LOG(L_ERR, "preload_udomain(): Can't create a record\n"); ul_dbf.free_result(_c, res); unlock_udomain(_d); return -2; } } if (mem_insert_ucontact(r, &aor, &contact, expires, q, &callid, cseq, flags, &c, &ua, rec, sock, &instance) < 0) { LOG(L_ERR, "preload_udomain(): Error while inserting contact\n"); ul_dbf.free_result(_c, res); unlock_udomain(_d); return -3; } db_read_reg_avps(_c, c); /* We have to do this, because insert_ucontact sets state to CS_NEW * and we have the contact in the database already * we also store zombies in database so we have to restore * the correct state */ c->state = CS_SYNC; } ul_dbf.free_result(_c, res); unlock_udomain(_d); return 0; }
/*! * \brief Convert database values into ucontact_info * * Convert database values into ucontact_info, * expects 12 rows (contact, expirs, q, callid, cseq, flags, * ua, received, path, socket, methods, last_modified) * \param vals database values * \param contact contact * \return pointer to the ucontact_info on success, 0 on failure */ static inline ucontact_info_t* dbrow2info( db_val_t *vals, str *contact) { static ucontact_info_t ci; static str callid, ua, received, host, path; int port, proto; char *p; memset( &ci, 0, sizeof(ucontact_info_t)); contact->s = (char*)VAL_STRING(vals); if (VAL_NULL(vals) || contact->s==0 || contact->s[0]==0) { LM_CRIT("bad contact\n"); return 0; } contact->len = strlen(contact->s); if (VAL_NULL(vals+1)) { LM_CRIT("empty expire\n"); return 0; } ci.expires = VAL_TIME(vals+1); if (VAL_NULL(vals+2)) { LM_CRIT("empty q\n"); return 0; } ci.q = double2q(VAL_DOUBLE(vals+2)); if (VAL_NULL(vals+4)) { LM_CRIT("empty cseq_nr\n"); return 0; } ci.cseq = VAL_INT(vals+4); callid.s = (char*)VAL_STRING(vals+3); if (VAL_NULL(vals+3) || !callid.s || !callid.s[0]) { LM_CRIT("bad callid\n"); return 0; } callid.len = strlen(callid.s); ci.callid = &callid; if (VAL_NULL(vals+5)) { LM_CRIT("empty flag\n"); return 0; } ci.flags = VAL_BITMAP(vals+5); if (VAL_NULL(vals+6)) { LM_CRIT("empty cflag\n"); return 0; } ci.cflags = VAL_BITMAP(vals+6); ua.s = (char*)VAL_STRING(vals+7); if (VAL_NULL(vals+7) || !ua.s || !ua.s[0]) { ua.s = 0; ua.len = 0; } else { ua.len = strlen(ua.s); } ci.user_agent = &ua; received.s = (char*)VAL_STRING(vals+8); if (VAL_NULL(vals+8) || !received.s || !received.s[0]) { received.len = 0; received.s = 0; } else { received.len = strlen(received.s); } ci.received = received; path.s = (char*)VAL_STRING(vals+9); if (VAL_NULL(vals+9) || !path.s || !path.s[0]) { path.len = 0; path.s = 0; } else { path.len = strlen(path.s); } ci.path= &path; /* socket name */ p = (char*)VAL_STRING(vals+10); if (VAL_NULL(vals+10) || p==0 || p[0]==0) { ci.sock = 0; } else { if (parse_phostport( p, &host.s, &host.len, &port, &proto)!=0) { LM_ERR("bad socket <%s>\n", p); return 0; } ci.sock = grep_sock_info( &host, (unsigned short)port, proto); if (ci.sock==0) { LM_INFO("non-local socket <%s>...ignoring\n", p); } } /* supported methods */ if (VAL_NULL(vals+11)) { ci.methods = ALL_METHODS; } else { ci.methods = VAL_BITMAP(vals+11); } /* last modified time */ if (!VAL_NULL(vals+12)) { ci.last_modified = VAL_TIME(vals+12); } /* record internal uid */ if (!VAL_NULL(vals+13)) { ci.ruid.s = (char*)VAL_STRING(vals+13); ci.ruid.len = strlen(ci.ruid.s); } /* sip instance */ if (!VAL_NULL(vals+14)) { ci.instance.s = (char*)VAL_STRING(vals+14); ci.instance.len = strlen(ci.instance.s); } /* reg-id */ if (!VAL_NULL(vals+15)) { ci.reg_id = VAL_UINT(vals+15); } return &ci; }