/* loads data from the db */ int load_info(db_func_t *dr_dbf, db_con_t* db_hdl, str *db_table, struct tls_domain **serv_dom, struct tls_domain **cli_dom) { int int_vals[4]; char *str_vals[11]; int i, n; int no_rows = 5; int db_cols = 15; /* the columns from the db table */ db_key_t columns[15]; /* result from a db query */ db_res_t* res; /* a row from the db table */ db_row_t* row; res = 0; columns[0] = &id_col; columns[1] = &address_col; columns[2] = &type_col; columns[3] = &method_col; columns[4] = &verify_cert_col; columns[5] = &require_cert_col; columns[6] = &certificate_col; columns[7] = &pk_col; columns[8] = &crl_check_col; columns[9] = &crl_dir_col; columns[10] = &calist_col; columns[11] = &cadir_col; columns[12] = &cplist_col; columns[13] = &dhparams_col; columns[14] = &eccurve_col; /* checking if the table version is up to date*/ if (db_check_table_version(dr_dbf, db_hdl, db_table, 1/*version*/) != 0) goto error; /* table to use*/ if (dr_dbf->use_table(db_hdl, db_table) < 0) { LM_ERR("cannot select table \"%.*s\"\n", db_table->len, db_table->s); goto error; } if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) { if (dr_dbf->query(db_hdl, 0, 0, 0, columns, 0, db_cols, 0, 0) < 0) { LM_ERR("DB query failed - retrieve valid connections \n"); goto error; } no_rows = estimate_available_rows(10 + 45 + 4 + 45 + 4 + 4 + 45 + 45 + 4 + 45 + 45 + 45 + 45 + 45 + 45, db_cols); if (no_rows == 0) no_rows = 5; if (dr_dbf->fetch_result(db_hdl, &res, no_rows) < 0) { LM_ERR("Error fetching rows\n"); goto error; } } else { if (dr_dbf->query(db_hdl, 0, 0, 0, columns, 0, db_cols, 0, &res) < 0) { LM_ERR("DB query failed - retrieve valid connections\n"); goto error; } } LM_DBG("%d rows found in %.*s\n", RES_ROW_N(res), db_table->len, db_table->s); n = 0; do { for (i = 0; i < RES_ROW_N(res); i++) { row = RES_ROWS(res) + i; check_val(id_col, ROW_VALUES(row), DB_STRING, 1, 1); str_vals[STR_VALS_ID_COL] = (char *) VAL_STRING(ROW_VALUES(row)); check_val(address_col, ROW_VALUES(row) + 1, DB_STRING, 1, 1); str_vals[STR_VALS_ADDRESS_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 1); check_val(type_col, ROW_VALUES(row) + 2, DB_INT, 1, 0); int_vals[INT_VALS_TYPE_COL] = VAL_INT(ROW_VALUES(row) + 2); check_val(method_col, ROW_VALUES(row) + 3, DB_STRING, 0, 0); str_vals[STR_VALS_METHOD_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 3); check_val(verify_cert_col, ROW_VALUES(row) + 4, DB_INT, 0, 0); int_vals[INT_VALS_VERIFY_CERT_COL] = VAL_INT(ROW_VALUES(row) + 4); check_val(require_cert_col, ROW_VALUES(row) + 5, DB_INT, 0, 0); int_vals[INT_VALS_REQUIRE_CERT_COL] = VAL_INT(ROW_VALUES(row) + 5); check_val(certificate_col, ROW_VALUES(row) + 6, DB_STRING, 0, 0); str_vals[STR_VALS_CERTIFICATE_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 6); check_val(pk_col, ROW_VALUES(row) + 7, DB_STRING, 0, 0); str_vals[STR_VALS_PK_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 7); check_val(crl_check_col, ROW_VALUES(row) + 8, DB_INT, 0, 0); int_vals[INT_VALS_CRL_CHECK_COL] = VAL_INT(ROW_VALUES(row) + 8); check_val(crl_dir_col, ROW_VALUES(row) + 9, DB_STRING, 0, 0); str_vals[STR_VALS_CRL_DIR_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 9); check_val(calist_col, ROW_VALUES(row) + 10, DB_STRING, 0, 0); str_vals[STR_VALS_CALIST_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 10); check_val(cadir_col, ROW_VALUES(row) + 11, DB_STRING, 0, 0); str_vals[STR_VALS_CADIR_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 11); check_val(cplist_col, ROW_VALUES(row) + 12, DB_STRING, 0, 0); str_vals[STR_VALS_CPLIST_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 12); check_val(dhparams_col, ROW_VALUES(row) + 13, DB_STRING, 0, 0); str_vals[STR_VALS_DHPARAMS_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 13); check_val(eccurve_col, ROW_VALUES(row) + 14, DB_STRING, 0, 0); str_vals[STR_VALS_ECCURVE_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 14); tlsp_db_add_domain(str_vals, int_vals, serv_dom, cli_dom); n++; } if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) { if (dr_dbf->fetch_result(db_hdl, &res, no_rows) < 0) { LM_ERR("fetching rows\n"); goto error; } } else { break; } } while (RES_ROW_N(res) > 0); LM_DBG("%d records found in %.*s\n", n, db_table->len, db_table->s); dr_dbf->free_result(db_hdl, res); res = 0; return 0; error: LM_ERR("database"); return -1; }
int acc_db_cdrs(struct dlg_cell *dlg, struct sip_msg *msg) { int total, nr_vals, i, j, ret, res = -1; time_t created, start_time; str core_s, leg_s, extra_s, table; short nr_legs; static db_ps_t my_ps = NULL; static query_list_t *ins_list = NULL; core_s.s = extra_s.s = leg_s.s = 0; ret = prebuild_core_arr(dlg, &core_s, &start_time); if (ret < 0) { LM_ERR("cannot copy core arguments\n"); goto end; } ret = prebuild_extra_arr(dlg, msg, &extra_s, &db_extra_str, db_extra_bye, ret); if (ret < 0) { LM_ERR("cannot copy extra arguments\n"); goto end; } /* here starts the extra leg */ nr_vals = prebuild_leg_arr(dlg, &leg_s, &nr_legs); if (nr_vals < 0) { LM_ERR("cannot compute leg values\n"); goto end; } if (!(created = acc_get_created(dlg))) { LM_ERR("cannot get created\n"); goto end; } if (dlg_api.fetch_dlg_value(dlg, &table_str, &table, 0) < 0) { LM_ERR("error getting table name\n"); return -1; } for (i=0;i<ACC_CORE_LEN;i++) VAL_STR(db_vals+i) = val_arr[i]; for (i=ACC_CORE_LEN; i<ret; i++) VAL_STR(db_vals+i+1) = val_arr[i]; VAL_TIME(db_vals+ACC_CORE_LEN) = start_time; VAL_INT(db_vals+ret+nr_vals+1) = time(NULL) - start_time; VAL_INT(db_vals+ret+nr_vals+2) = start_time - created; VAL_TIME(db_vals+ret+nr_vals+3) = created; total = ret + 4; acc_dbf.use_table(db_handle, &table); CON_PS_REFERENCE(db_handle) = &my_ps; if (!leg_info) { if (con_set_inslist(&acc_dbf,db_handle,&ins_list,db_keys,total) < 0 ) CON_RESET_INSLIST(db_handle); if (acc_dbf.insert(db_handle, db_keys, db_vals, total) < 0) { LM_ERR("failed to insert into database\n"); goto end; } } else { total += nr_vals; leg_s.len = 4; for (i=0;i<nr_legs;i++) { complete_dlg_values(&leg_s,val_arr+ret,nr_vals); for (j = 0; j<nr_vals; j++) VAL_STR(db_vals+ret+j+1) = val_arr[ret+j]; if (con_set_inslist(&acc_dbf,db_handle,&ins_list,db_keys,total) < 0 ) CON_RESET_INSLIST(db_handle); if (acc_dbf.insert(db_handle,db_keys,db_vals,total) < 0) { LM_ERR("failed inserting into database\n"); goto end; } } } res = 1; end: if (core_s.s) pkg_free(core_s.s); if (extra_s.s) pkg_free(extra_s.s); if (leg_s.s) pkg_free(leg_s.s); return res; }
/* * Insert a row into specified table * h: structure representing database connection * k: key names * v: values of the keys * n: number of key=value pairs */ int flat_db_insert(db_con_t* h, db_key_t* k, db_val_t* v, int n) { FILE* f; int i; char delims[4], *s; size_t len; f = CON_FILE(h); if (!f) { LOG(L_CRIT, "BUG: flat_db_insert: Uninitialized connection\n"); return -1; } if (local_timestamp < *flat_rotate) { flat_rotate_logs(); local_timestamp = *flat_rotate; } for(i = 0; i < n; i++) { if (!VAL_NULL(v + i)) { // TODO: how to distinguish NULL from empty switch(VAL_TYPE(v + i)) { case DB_INT: fprintf(f, "%d", VAL_INT(v + i)); break; case DB_FLOAT: fprintf(f, "%f", VAL_FLOAT(v + i)); break; case DB_DOUBLE: fprintf(f, "%f", VAL_DOUBLE(v + i)); break; case DB_STRING: { s = (char*) VAL_STRING(v + i); delims[0] = flat_delimiter[0]; delims[1] = flat_record_delimiter[0]; delims[2] = flat_escape[0]; delims[3] = '\0'; while (*s) { len = strcspn(s, delims); fprintf(f, "%.*s", (int)len, s); s+= len; if (*s) { fprintf(f, "%c%c", flat_escape[0], *s); s++; } } break; } case DB_STR: case DB_BLOB: if (VAL_TYPE(v + i) == DB_STR) { s = VAL_STR(v + i).s; len = VAL_STR(v + i).len; } else { s = VAL_BLOB(v + i).s; len = VAL_BLOB(v + i).len; } while (len > 0) { char *c; for (c = s; len > 0 && *c != flat_delimiter[0] && *c != flat_record_delimiter[0] && *c != flat_escape[0]; c++, len--); fprintf(f, "%.*s", (int)(c-s), s); s = c; if (len > 0) { fprintf(f, "%c%c", flat_escape[0], *s); s++; len--; } } break; case DB_DATETIME: fprintf(f, "%u", (unsigned int)VAL_TIME(v + i)); break; case DB_BITMAP: fprintf(f, "%u", VAL_BITMAP(v + i)); break; } } if (i < (n - 1)) { fprintf(f, "%c", flat_delimiter[0]); } } fprintf(f, "%c", flat_record_delimiter[0]); if (flat_flush) { fflush(f); } return 0; }
/* * Get and convert columns from a result. Define handlers and buffers */ static int get_columns(ora_con_t* con, db1_res_t* _r, OCIStmt* _c, dmap_t* _d) { OCIParam *param; size_t tsz; ub4 i, n; sword status; status = OCIAttrGet(_c, OCI_HTYPE_STMT, &n, NULL, OCI_ATTR_PARAM_COUNT, con->errhp); if (status != OCI_SUCCESS) { LM_ERR("driver: %s\n", db_oracle_error(con, status)); return -1; } if (!n) { LM_ERR("no columns\n"); return -2; } if (n >= MAX_DEF_HANDLES) { LM_ERR("too many res. Rebuild with MAX_DEF_HANDLES >= %u\n", n); return -3; } if (db_allocate_columns(_r, n) != 0) { LM_ERR("could not allocate columns"); return -4; } memset(RES_NAMES(_r), 0, sizeof(db_key_t) * n); RES_COL_N(_r) = n; tsz = 0; memset(_d->defh, 0, sizeof(_d->defh[0]) * n); for (i = 0; i < n; i++) { ub4 len; ub2 dtype; status = OCIParamGet(_c, OCI_HTYPE_STMT, con->errhp, (dvoid**)(dvoid*)¶m, i+1); if (status != OCI_SUCCESS) goto ora_err; { text* name; str* sname; status = OCIAttrGet(param, OCI_DTYPE_PARAM, (dvoid**)(dvoid*)&name, &len, OCI_ATTR_NAME, con->errhp); if (status != OCI_SUCCESS) goto ora_err; sname = (str*)pkg_malloc(sizeof(str)+len+1); if (!sname) { db_free_columns(_r); LM_ERR("no private memory left\n"); return -5; } sname->len = len; sname->s = (char*)sname + sizeof(str); memcpy(sname->s, name, len); sname->s[len] = '\0'; RES_NAMES(_r)[i] = sname; } status = OCIAttrGet(param, OCI_DTYPE_PARAM, (dvoid**)(dvoid*)&dtype, NULL, OCI_ATTR_DATA_TYPE, con->errhp); if (status != OCI_SUCCESS) goto ora_err; switch (dtype) { case SQLT_UIN: /* unsigned integer */ set_bitmap: LM_DBG("use DB1_BITMAP type"); RES_TYPES(_r)[i] = DB1_BITMAP; len = sizeof(VAL_BITMAP((db_val_t*)NULL)); break; case SQLT_INT: /* (ORANET TYPE) integer */ set_int: LM_DBG("use DB1_INT result type"); RES_TYPES(_r)[i] = DB1_INT; len = sizeof(VAL_INT((db_val_t*)NULL)); break; // case SQLT_LNG: /* long */ case SQLT_VNU: /* NUM with preceding length byte */ case SQLT_NUM: /* (ORANET TYPE) oracle numeric */ len = 0; /* PRECISION is ub1 */ status = OCIAttrGet(param, OCI_DTYPE_PARAM, (dvoid**)(dvoid*)&len, NULL, OCI_ATTR_PRECISION, con->errhp); if (status != OCI_SUCCESS) goto ora_err; if (len <= 11) { sb1 sc; status = OCIAttrGet(param, OCI_DTYPE_PARAM, (dvoid**)(dvoid*)&sc, NULL, OCI_ATTR_SCALE, con->errhp); if (status != OCI_SUCCESS) goto ora_err; if (!sc) { dtype = SQLT_INT; if (len != 11) goto set_int; dtype = SQLT_UIN; goto set_bitmap; } } case SQLT_FLT: /* (ORANET TYPE) Floating point number */ case SQLT_BFLOAT: /* Native Binary float*/ case SQLT_BDOUBLE: /* NAtive binary double */ case SQLT_IBFLOAT: /* binary float canonical */ case SQLT_IBDOUBLE: /* binary double canonical */ case SQLT_PDN: /* (ORANET TYPE) Packed Decimal Numeric */ LM_DBG("use DB1_DOUBLE result type"); RES_TYPES(_r)[i] = DB1_DOUBLE; len = sizeof(VAL_DOUBLE((db_val_t*)NULL)); dtype = SQLT_FLT; break; // case SQLT_TIME: /* TIME */ // case SQLT_TIME_TZ: /* TIME WITH TIME ZONE */ case SQLT_DATE: /* ANSI Date */ case SQLT_DAT: /* date in oracle format */ case SQLT_ODT: /* OCIDate type */ case SQLT_TIMESTAMP: /* TIMESTAMP */ case SQLT_TIMESTAMP_TZ: /* TIMESTAMP WITH TIME ZONE */ case SQLT_TIMESTAMP_LTZ:/* TIMESTAMP WITH LOCAL TZ */ // case SQLT_INTERVAL_YM: /* INTERVAL YEAR TO MONTH */ // case SQLT_INTERVAL_DS: /* INTERVAL DAY TO SECOND */ LM_DBG("use DB1_DATETIME result type"); RES_TYPES(_r)[i] = DB1_DATETIME; len = sizeof(OCIDate); dtype = SQLT_ODT; break; case SQLT_CLOB: /* character lob */ case SQLT_BLOB: /* binary lob */ // case SQLT_BFILEE: /* binary file lob */ // case SQLT_CFILEE: /* character file lob */ // case SQLT_BIN: /* binary data(DTYBIN) */ // case SQLT_LBI: /* long binary */ LM_DBG("use DB1_BLOB result type"); RES_TYPES(_r)[i] = DB1_BLOB; goto dyn_str; case SQLT_CHR: /* (ORANET TYPE) character string */ case SQLT_STR: /* zero terminated string */ case SQLT_VST: /* OCIString type */ case SQLT_VCS: /* Variable character string */ case SQLT_AFC: /* Ansi fixed char */ case SQLT_AVC: /* Ansi Var char */ // case SQLT_RID: /* rowid */ LM_DBG("use DB1_STR result type"); RES_TYPES(_r)[i] = DB1_STR; dyn_str: dtype = SQLT_CHR; len = 0; /* DATA_SIZE is ub2 */ status = OCIAttrGet(param, OCI_DTYPE_PARAM, (dvoid**)(dvoid*)&len, NULL, OCI_ATTR_DATA_SIZE, con->errhp); if (status != OCI_SUCCESS) goto ora_err; if (len >= 4000) { LM_DBG("use DB1_BLOB result type"); RES_TYPES(_r)[i] = DB1_BLOB; } ++len; break; default: LM_ERR("unsupported datatype %d\n", dtype); goto stop_load; } _d->ilen[i] = (ub2)len; _d->pv[i].v = st_buf + tsz; tsz += len; status = OCIDefineByPos(_c, &_d->defh[i], con->errhp, i+1, _d->pv[i].v, len, dtype, &_d->ind[i], &_d->len[i], NULL, OCI_DEFAULT); if (status != OCI_SUCCESS) goto ora_err; } #if STATIC_BUF_LEN < 65536 #error #endif if (tsz > 65536) { LM_ERR("Row size exceed 65K. IOB's are not supported"); goto stop_load; } return 0; ora_err: LM_ERR("driver: %s\n", db_oracle_error(con, status)); stop_load: db_free_columns(_r); return -6; }
/* select data from emergency_service_prvider for put in xml to VPC * coluns key: attribution and nodeIP. * coluns attributs: OrganizationName, hostId, nenaId, contact, certUri. */ int get_db_provider(str table_name, rw_lock_t *ref_lock ){ db_key_t query_cols[] = {&id_col, &organizationName_col, &hostId_col, &nenaId_col, &contact_col, &certUri_col, &nodeIP_col, &attribution_col}; db_res_t * res; db_val_t * values; db_row_t * rows; str OrganizationName; str hostId; str nenaId; str contact; str certUri; str nodeIP; int attribution; int nr_rows, i, size, id; struct service_provider *provider_cell, *old_list, *it, *aux, *new_list; struct service_provider *init_provider = NULL; db_funcs.use_table(db_con, &table_name); if (db_funcs.query(db_con, 0, 0, 0, query_cols, 0, 8, 0, &res) != 0) { LM_ERR("Failure to issue query\n"); return -1; } nr_rows = RES_ROW_N(res); rows = RES_ROWS(res); new_list = NULL; LM_DBG("NUMBER OF LINES %d \n", nr_rows); for (i = 0; i < nr_rows; i++) { values = ROW_VALUES(rows + i); if (VAL_NULL(values) || (VAL_TYPE(values) != DB_INT)) { LM_ERR("Invalid value returned 1\n"); goto end; } id = VAL_INT(values); if (VAL_NULL(values + 1) || (VAL_TYPE(values + 1) != DB_STR && VAL_TYPE(values + 1) != DB_STRING)) { LM_ERR("Invalid translated returned 2\n"); goto end; } if (VAL_TYPE(values + 1) == DB_STR) { OrganizationName = VAL_STR(values + 1); } else { OrganizationName.s = (char*) VAL_STRING(values + 1); OrganizationName.len = strlen(OrganizationName.s); } if (VAL_NULL(values + 2) || (VAL_TYPE(values + 2) != DB_STR && VAL_TYPE(values + 2) != DB_STRING)) { LM_ERR("Invalid translated returned 2\n"); goto end; } if (VAL_TYPE(values + 2) == DB_STR) { hostId = VAL_STR(values + 2); } else { hostId.s = (char*) VAL_STRING(values + 2); hostId.len = strlen(hostId.s); } if (VAL_NULL(values + 3) || (VAL_TYPE(values + 3) != DB_STR && VAL_TYPE(values + 3) != DB_STRING)) { LM_ERR("Invalid translated returned 3\n"); goto end; } if (VAL_TYPE(values + 3) == DB_STR) { nenaId = VAL_STR(values + 3); } else { nenaId.s = (char*) VAL_STRING(values + 3); nenaId.len = strlen(nenaId.s); } if (VAL_NULL(values + 4) || (VAL_TYPE(values + 4) != DB_STR && VAL_TYPE(values + 4) != DB_STRING)) { LM_ERR("Invalid translated returned 4\n"); goto end; } if (VAL_TYPE(values + 4) == DB_STR) { contact = VAL_STR(values + 4); } else { contact.s = (char*) VAL_STRING(values + 4); contact.len = strlen(contact.s); } if (VAL_NULL(values + 5) || (VAL_TYPE(values + 5) != DB_STR && VAL_TYPE(values + 5) != DB_STRING)) { LM_ERR("Invalid translated returned 3\n"); goto end; } if (VAL_TYPE(values + 5) == DB_STR) { certUri = VAL_STR(values + 5); } else { certUri.s = (char*) VAL_STRING(values + 5); certUri.len = strlen(certUri.s); } if (VAL_NULL(values + 6) || (VAL_TYPE(values + 6) != DB_STR && VAL_TYPE(values + 6) != DB_STRING)) { LM_ERR("Invalid translated returned 6\n"); goto end; } if (VAL_TYPE(values + 6) == DB_STR) { nodeIP = VAL_STR(values + 6); } else { nodeIP.s = (char*) VAL_STRING(values + 6); nodeIP.len = strlen(nodeIP.s); } if (VAL_NULL(values + 7) || (VAL_TYPE(values + 7) != DB_INT)) { LM_ERR("Invalid translated returned 7\n"); goto end; } attribution = VAL_INT(values + 7); if (attribution == 0){ if (hostId.len == 0 || contact.len == 0) { LM_ERR("source_hostname and source_contact are mandatory \n"); mandatory_parm[0] = '1'; mandatory_parm[1] = 0; } else{ mandatory_parm[0] = '0'; mandatory_parm[1] = 0; } } size = sizeof (struct service_provider)+ nodeIP.len + OrganizationName.len + hostId.len + nenaId.len + contact.len + certUri.len; provider_cell = shm_malloc(size); if (!provider_cell) { LM_ERR("no more shm\n"); goto end; } memset(provider_cell, 0, size); provider_cell->nodeIP.len = nodeIP.len; provider_cell->nodeIP.s = (char *) (provider_cell + 1); memcpy(provider_cell->nodeIP.s, nodeIP.s, nodeIP.len); provider_cell->OrganizationName.len = OrganizationName.len; provider_cell->OrganizationName.s = (char *) (provider_cell + 1) + nodeIP.len; memcpy(provider_cell->OrganizationName.s, OrganizationName.s, OrganizationName.len); provider_cell->hostId.len = hostId.len; provider_cell->hostId.s = (char *) (provider_cell + 1) + nodeIP.len + OrganizationName.len; memcpy(provider_cell->hostId.s, hostId.s, hostId.len); provider_cell->nenaId.len = nenaId.len; provider_cell->nenaId.s = (char *) (provider_cell + 1) + nodeIP.len + OrganizationName.len + hostId.len; memcpy(provider_cell->nenaId.s, nenaId.s, nenaId.len); provider_cell->contact.len = contact.len; provider_cell->contact.s = (char *) (provider_cell + 1) + nodeIP.len + OrganizationName.len + hostId.len + nenaId.len; memcpy(provider_cell->contact.s, contact.s, contact.len); provider_cell->certUri.len = certUri.len; provider_cell->certUri.s = (char *) (provider_cell + 1) + nodeIP.len + OrganizationName.len + hostId.len + nenaId.len + contact.len; memcpy(provider_cell->certUri.s, certUri.s, certUri.len); provider_cell->attribution = attribution; if (new_list != NULL) { new_list->next = provider_cell; new_list = provider_cell; } else { new_list = provider_cell; init_provider = new_list; } } new_list = init_provider; lock_start_write(ref_lock); old_list = *db_service_provider; *db_service_provider = init_provider; lock_stop_write(ref_lock); it = old_list; while (it) { aux = it; it = it->next; shm_free(aux); } end: db_funcs.free_result(db_con, res); return 1; }
/* * Convert a row from result into db API representation */ int dbt_convert_row(db_con_t* _h, db_res_t* _res, db_row_t* _r) { int i; if ((!_h) || (!_r) || (!_res)) { #ifdef DBT_EXTRA_DEBUG LOG(L_ERR, "DBT:dbt_convert_row: Invalid parameter value\n"); #endif return -1; } ROW_VALUES(_r) = (db_val_t*)pkg_malloc(sizeof(db_val_t) * RES_COL_N(_res)); ROW_N(_r) = RES_COL_N(_res); if (!ROW_VALUES(_r)) { LOG(L_ERR, "DBT:dbt_convert_row: No memory left\n"); return -1; } for(i = 0; i < RES_COL_N(_res); i++) { (ROW_VALUES(_r)[i]).nul = DBT_CON_ROW(_h)->fields[i].nul; switch(RES_TYPES(_res)[i]) { case DB_INT: VAL_INT(&(ROW_VALUES(_r)[i])) = DBT_CON_ROW(_h)->fields[i].val.int_val; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_INT; break; case DB_FLOAT: VAL_FLOAT(&(ROW_VALUES(_r)[i])) = DBT_CON_ROW(_h)->fields[i].val.float_val; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_FLOAT; break; case DB_DOUBLE: VAL_DOUBLE(&(ROW_VALUES(_r)[i])) = DBT_CON_ROW(_h)->fields[i].val.double_val; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_DOUBLE; break; case DB_STRING: VAL_STR(&(ROW_VALUES(_r)[i])).s = DBT_CON_ROW(_h)->fields[i].val.str_val.s; VAL_STR(&(ROW_VALUES(_r)[i])).len = DBT_CON_ROW(_h)->fields[i].val.str_val.len; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_STR; break; case DB_STR: VAL_STR(&(ROW_VALUES(_r)[i])).s = DBT_CON_ROW(_h)->fields[i].val.str_val.s; VAL_STR(&(ROW_VALUES(_r)[i])).len = DBT_CON_ROW(_h)->fields[i].val.str_val.len; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_STR; break; case DB_DATETIME: VAL_INT(&(ROW_VALUES(_r)[i])) = DBT_CON_ROW(_h)->fields[i].val.int_val; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_INT; break; case DB_BLOB: VAL_STR(&(ROW_VALUES(_r)[i])).s = DBT_CON_ROW(_h)->fields[i].val.str_val.s; VAL_STR(&(ROW_VALUES(_r)[i])).len = DBT_CON_ROW(_h)->fields[i].val.str_val.len; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_STR; break; case DB_BITMAP: VAL_INT(&(ROW_VALUES(_r)[i])) = DBT_CON_ROW(_h)->fields[i].val.bitmap_val; VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB_INT; break; } } return 0; }
static int load_dialog_info_from_db(int dlg_hash_size) { db_res_t * res; db_val_t * values; db_row_t * rows; int i, nr_rows; struct dlg_cell *dlg; str callid, from_uri, to_uri, from_tag, to_tag; str cseq1,cseq2,contact1,contact2,rroute1,rroute2,mangled_fu,mangled_tu; unsigned int next_id; int no_rows = 10; struct socket_info *caller_sock,*callee_sock; res = 0; if((nr_rows = select_entire_dialog_table(&res,&no_rows)) < 0) goto end; nr_rows = RES_ROW_N(res); do { LM_DBG("loading information from database for %i dialogs\n", nr_rows); rows = RES_ROWS(res); /* for every row---dialog */ for(i=0; i<nr_rows; i++){ values = ROW_VALUES(rows + i); if (VAL_NULL(values) || VAL_NULL(values+1)) { LM_ERR("columns %.*s or/and %.*s cannot be null -> skipping\n", h_entry_column.len, h_entry_column.s, h_id_column.len, h_id_column.s); continue; } if (VAL_NULL(values+7) || VAL_NULL(values+8)) { LM_ERR("columns %.*s or/and %.*s cannot be null -> skipping\n", start_time_column.len, start_time_column.s, state_column.len, state_column.s); continue; } if ( VAL_INT(values+8) == DLG_STATE_DELETED ) { LM_DBG("dialog already terminated -> skipping\n"); continue; } caller_sock = create_socket_info(values, 16); callee_sock = create_socket_info(values, 17); if (caller_sock == NULL || callee_sock == NULL) { LM_ERR("Dialog in DB doesn't match any listening sockets"); continue; } /*restore the dialog info*/ GET_STR_VALUE(callid, values, 2, 1, 0); GET_STR_VALUE(from_uri, values, 3, 1, 0); GET_STR_VALUE(from_tag, values, 4, 1, 0); GET_STR_VALUE(to_uri, values, 5, 1, 0); if((dlg=build_new_dlg(&callid, &from_uri, &to_uri, &from_tag))==0){ LM_ERR("failed to build new dialog\n"); goto error; } if(dlg->h_entry != VAL_INT(values)){ LM_ERR("inconsistent hash data in the dialog database: " "you may have restarted opensips using a different " "hash_size: please erase %.*s database and restart\n", dialog_table_name.len, dialog_table_name.s); shm_free(dlg); goto error; } /*link the dialog*/ link_dlg(dlg, 0); dlg->h_id = VAL_INT(values+1); next_id = d_table->entries[dlg->h_entry].next_id; d_table->entries[dlg->h_entry].next_id = (next_id < dlg->h_id) ? (dlg->h_id+1) : next_id; GET_STR_VALUE(to_tag, values, 6, 1, 1); dlg->start_ts = VAL_INT(values+7); dlg->state = VAL_INT(values+8); if (dlg->state==DLG_STATE_CONFIRMED_NA || dlg->state==DLG_STATE_CONFIRMED) { active_dlgs_cnt++; } else if (dlg->state==DLG_STATE_EARLY) { early_dlgs_cnt++; } GET_STR_VALUE(cseq1, values, 10 , 1, 1); GET_STR_VALUE(cseq2, values, 11 , 1, 1); GET_STR_VALUE(rroute1, values, 12, 0, 0); GET_STR_VALUE(rroute2, values, 13, 0, 0); GET_STR_VALUE(contact1, values, 14, 0, 1); GET_STR_VALUE(contact2, values, 15, 0, 1); GET_STR_VALUE(mangled_fu, values, 24,0,1); GET_STR_VALUE(mangled_tu, values, 25,0,1); /* add the 2 legs */ if ( (dlg_add_leg_info( dlg, &from_tag, &rroute1, &contact1, &cseq1, caller_sock,0,0)!=0) || (dlg_add_leg_info( dlg, &to_tag, &rroute2, &contact2, &cseq2, callee_sock,&mangled_fu,&mangled_tu)!=0) ) { LM_ERR("dlg_set_leg_info failed\n"); /* destroy the dialog */ unref_dlg(dlg,1); continue; } dlg->legs_no[DLG_LEG_200OK] = DLG_FIRST_CALLEE_LEG; /* script variables */ if (!VAL_NULL(values+18)) read_dialog_vars( VAL_STR(values+18).s, VAL_STR(values+18).len, dlg); /* profiles */ if (!VAL_NULL(values+19)) read_dialog_profiles( VAL_STR(values+19).s, strlen(VAL_STR(values+19).s), dlg,0); /* script flags */ if (!VAL_NULL(values+20)) { dlg->user_flags = VAL_INT(values+20); } /* top hiding */ dlg->flags = VAL_INT(values+23); if (dlg_db_mode==DB_MODE_SHUTDOWN) dlg->flags |= DLG_FLAG_NEW; /* calculcate timeout */ dlg->tl.timeout = (unsigned int)(VAL_INT(values+9)) + get_ticks(); if (dlg->tl.timeout<=(unsigned int)time(0)) dlg->tl.timeout = 0; else dlg->tl.timeout -= (unsigned int)time(0); /* restore the timer values */ if (0 != insert_dlg_timer( &(dlg->tl), (int)dlg->tl.timeout )) { LM_CRIT("Unable to insert dlg %p [%u:%u] " "with clid '%.*s' and tags '%.*s' '%.*s'\n", dlg, dlg->h_entry, dlg->h_id, dlg->callid.len, dlg->callid.s, dlg->legs[DLG_CALLER_LEG].tag.len, dlg->legs[DLG_CALLER_LEG].tag.s, dlg->legs[callee_idx(dlg)].tag.len, ZSW(dlg->legs[callee_idx(dlg)].tag.s)); /* destroy the dialog */ unref_dlg(dlg,1); continue; } /* reference the dialog as kept in the timer list */ ref_dlg(dlg,1); LM_DBG("current dialog timeout is %u\n", dlg->tl.timeout); dlg->lifetime = 0; dlg->legs[DLG_CALLER_LEG].last_gen_cseq = (unsigned int)(VAL_INT(values+21)); dlg->legs[callee_idx(dlg)].last_gen_cseq = (unsigned int)(VAL_INT(values+22)); if (dlg->flags & DLG_FLAG_PING_CALLER || dlg->flags & DLG_FLAG_PING_CALLEE) { if (0 != insert_ping_timer(dlg)) LM_CRIT("Unable to insert dlg %p into ping timer\n",dlg); else { /* reference dialog as kept in ping timer list */ ref_dlg(dlg,1); } } next_dialog: ; } /* any more data to be fetched ?*/ if (DB_CAPABILITY(dialog_dbf, DB_CAP_FETCH)) { if (dialog_dbf.fetch_result( dialog_db_handle, &res,no_rows) < 0) { LM_ERR("fetching more rows failed\n"); goto error; } nr_rows = RES_ROW_N(res); } else { nr_rows = 0; } }while (nr_rows>0); end: dialog_dbf.free_result(dialog_db_handle, res); return 0; error: dialog_dbf.free_result(dialog_db_handle, res); return -1; }
int process_ins_list(str* _d) { struct ins_itm* p; char b[256]; db_key_t keys[8]; db_val_t vals[8]; keys[0] = user_col; keys[1] = contact_col; keys[2] = expires_col; keys[3] = q_col; keys[4] = callid_col; keys[5] = cseq_col; keys[6] = replicate_col; keys[7] = state_col; if (ins_root) { /* FIXME */ memcpy(b, _d->s, _d->len); b[_d->len] = '\0'; db_use_table(db, b); VAL_TYPE(vals) = DB_STR; VAL_TYPE(vals + 1) = DB_STR; VAL_TYPE(vals + 2) = DB_DATETIME; VAL_TYPE(vals + 3) = DB_DOUBLE; VAL_TYPE(vals + 4) = DB_STR; VAL_TYPE(vals + 5) = DB_INT; VAL_TYPE(vals + 6) = DB_INT; VAL_TYPE(vals + 7) = DB_INT; VAL_NULL(vals) = 0; VAL_NULL(vals + 1) = 0; VAL_NULL(vals + 2) = 0; VAL_NULL(vals + 3) = 0; VAL_NULL(vals + 4) = 0; VAL_NULL(vals + 5) = 0; VAL_NULL(vals + 6) = 0; VAL_NULL(vals + 7) = 0; } while(ins_root) { p = ins_root; ins_root = ins_root->next; VAL_STR(vals).len = p->user->len; VAL_STR(vals).s = p->user->s; VAL_STR(vals + 1).len = p->cont->len; VAL_STR(vals + 1).s = p->cont->s; VAL_TIME(vals + 2) = p->expires; VAL_DOUBLE(vals + 3) = p->q; VAL_STR(vals + 4).len = p->cid_len; VAL_STR(vals + 4).s = p->callid; VAL_INT(vals + 5) = p->cseq; VAL_INT(vals + 6) = p->replicate; VAL_INT(vals + 7) = p->state; if (db_insert(db, keys, vals, 8) < 0) { LOG(L_ERR, "process_ins_list(): Error while inserting into database\n"); return -1; } pkg_free(p); } return 0; }
rt_data_t* dr_load_routing_info( db_func_t *dr_dbf, db_con_t* db_hdl, str *drd_table, str *drc_table, str* drr_table, int persistent_state) { int int_vals[5]; char * str_vals[6]; str tmp; db_key_t columns[10]; db_res_t* res; db_row_t* row; rt_info_t *ri; rt_data_t *rdata; tmrec_t *time_rec; int i,n; int no_rows = 10; int db_cols; struct socket_info *sock; str s_sock, host; int proto, port; res = 0; ri = 0; rdata = 0; /* init new data structure */ if ( (rdata=build_rt_data())==0 ) { LM_ERR("failed to build rdata\n"); goto error; } if (db_check_table_version(dr_dbf, db_hdl, drd_table, 6/*version*/ )!= 0) goto error; /* read the destinations */ if (dr_dbf->use_table( db_hdl, drd_table) < 0) { LM_ERR("cannot select table \"%.*s\"\n", drd_table->len,drd_table->s); goto error; } columns[0] = &id_drd_col; columns[1] = &gwid_drd_col; columns[2] = &address_drd_col; columns[3] = &strip_drd_col; columns[4] = &prefix_drd_col; columns[5] = &type_drd_col; columns[6] = &attrs_drd_col; columns[7] = &probe_drd_col; columns[8] = &sock_drd_col; if (persistent_state) { columns[9] = &state_drd_col; db_cols = 10; } else { db_cols = 9; } if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) { if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, db_cols, 0, 0 ) < 0) { LM_ERR("DB query failed\n"); goto error; } no_rows = estimate_available_rows( 4+32+15+4+32+4+128+4+32+4, db_cols); if (no_rows==0) no_rows = 10; if(dr_dbf->fetch_result(db_hdl, &res, no_rows )<0) { LM_ERR("Error fetching rows\n"); goto error; } } else { if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, db_cols, 0, &res) < 0) { LM_ERR("DB query failed\n"); goto error; } } LM_DBG("%d records found in %.*s\n", RES_ROW_N(res), drd_table->len,drd_table->s); n = 0; do { for(i=0; i < RES_ROW_N(res); i++) { row = RES_ROWS(res) + i; /* DB ID column */ check_val( id_drd_col, ROW_VALUES(row), DB_INT, 1, 0); int_vals[INT_VALS_ID_DRD_COL] = VAL_INT(ROW_VALUES(row)); /* GW ID column */ check_val( gwid_drd_col, ROW_VALUES(row)+1, DB_STRING, 1, 1); str_vals[STR_VALS_GWID_DRD_COL] = (char*)VAL_STRING(ROW_VALUES(row)+1); /* ADDRESS column */ check_val( address_drd_col, ROW_VALUES(row)+2, DB_STRING, 1, 1); str_vals[STR_VALS_ADDRESS_DRD_COL] = (char*)VAL_STRING(ROW_VALUES(row)+2); /* STRIP column */ check_val( strip_drd_col, ROW_VALUES(row)+3, DB_INT, 1, 0); int_vals[INT_VALS_STRIP_DRD_COL] = VAL_INT (ROW_VALUES(row)+3); /* PREFIX column */ check_val( prefix_drd_col, ROW_VALUES(row)+4, DB_STRING, 0, 0); str_vals[STR_VALS_PREFIX_DRD_COL] = (char*)VAL_STRING(ROW_VALUES(row)+4); /* TYPE column */ check_val( type_drd_col, ROW_VALUES(row)+5, DB_INT, 1, 0); int_vals[INT_VALS_TYPE_DRD_COL] = VAL_INT(ROW_VALUES(row)+5); /* ATTRS column */ check_val( attrs_drd_col, ROW_VALUES(row)+6, DB_STRING, 0, 0); str_vals[STR_VALS_ATTRS_DRD_COL] = (char*)VAL_STRING(ROW_VALUES(row)+6); /*PROBE_MODE column */ check_val( probe_drd_col, ROW_VALUES(row)+7, DB_INT, 1, 0); int_vals[INT_VALS_PROBE_DRD_COL] = VAL_INT(ROW_VALUES(row)+7); /*SOCKET column */ check_val( sock_drd_col, ROW_VALUES(row)+8, DB_STRING, 0, 0); if ( !VAL_NULL(ROW_VALUES(row)+8) && (s_sock.s=(char*)VAL_STRING(ROW_VALUES(row)+8))[0]!=0 ) { s_sock.len = strlen(s_sock.s); if (parse_phostport( s_sock.s, s_sock.len, &host.s, &host.len, &port, &proto)!=0){ LM_ERR("GW <%s>(%d): socket description <%.*s> " "is not valid -> ignoring socket\n", str_vals[STR_VALS_GWID_DRD_COL], int_vals[INT_VALS_ID_DRD_COL], s_sock.len,s_sock.s); sock = NULL; } else { sock = grep_sock_info( &host, port, proto); if (sock == NULL) { LM_ERR("GW <%s>(%d): socket <%.*s> is not local to" " OpenSIPS (we must listen on it) -> ignoring socket\n", str_vals[STR_VALS_GWID_DRD_COL], int_vals[INT_VALS_ID_DRD_COL], s_sock.len,s_sock.s); } } } else { sock = NULL; } /*STATE column */ if (persistent_state) { check_val( state_drd_col, ROW_VALUES(row)+9, DB_INT, 1, 0); int_vals[INT_VALS_STATE_DRD_COL] = VAL_INT(ROW_VALUES(row)+9); } else { int_vals[INT_VALS_STATE_DRD_COL] = 0; /* by default enabled */ } /* add the destinaton definition in */ if ( add_dst( rdata, str_vals[STR_VALS_GWID_DRD_COL], str_vals[STR_VALS_ADDRESS_DRD_COL], int_vals[INT_VALS_STRIP_DRD_COL], str_vals[STR_VALS_PREFIX_DRD_COL], int_vals[INT_VALS_TYPE_DRD_COL], str_vals[STR_VALS_ATTRS_DRD_COL], int_vals[INT_VALS_PROBE_DRD_COL], sock, int_vals[INT_VALS_STATE_DRD_COL] )<0 ) { LM_ERR("failed to add destination <%s>(%d) -> skipping\n", str_vals[STR_VALS_GWID_DRD_COL],int_vals[INT_VALS_ID_DRD_COL]); continue; } n++; } if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) { if(dr_dbf->fetch_result(db_hdl, &res, no_rows)<0) { LM_ERR( "fetching rows (1)\n"); goto error; } } else { break; } } while(RES_ROW_N(res)>0); dr_dbf->free_result(db_hdl, res); res = 0; /* read the carriers, if any */ if (dr_dbf->use_table( db_hdl, drc_table) < 0) { LM_ERR("cannot select table \"%.*s\"\n", drc_table->len,drc_table->s); goto error; } columns[0] = &id_drc_col; columns[1] = &cid_drc_col; columns[2] = &flags_drc_col; columns[3] = &gwlist_drc_col; columns[4] = &attrs_drc_col; if (persistent_state) { columns[5] = &state_drc_col; db_cols = 6; } else { db_cols = 5; } if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) { if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, db_cols, 0, 0 ) < 0) { LM_ERR("DB query failed\n"); goto error; } no_rows = estimate_available_rows( 4+4+32+64+64, db_cols); if (no_rows==0) no_rows = 10; if(dr_dbf->fetch_result(db_hdl, &res, no_rows)<0) { LM_ERR("Error fetching rows\n"); goto error; } } else { if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, db_cols, 0, &res) < 0) { LM_ERR("DB query failed\n"); goto error; } } if (RES_ROW_N(res) == 0) { LM_DBG("table \"%.*s\" empty\n", drc_table->len,drc_table->s ); } else { LM_DBG("%d records found in %.*s\n", RES_ROW_N(res), drc_table->len,drc_table->s); do { for(i=0; i < RES_ROW_N(res); i++) { row = RES_ROWS(res) + i; /* ID column */ check_val( id_drc_col, ROW_VALUES(row), DB_INT, 1, 0); int_vals[INT_VALS_ID_DRC_COL] = VAL_INT(ROW_VALUES(row)); /* CARRIER_ID column */ check_val( cid_drc_col, ROW_VALUES(row)+1, DB_STRING, 1, 1); str_vals[STR_VALS_CID_DRC_COL] = (char*)VAL_STRING(ROW_VALUES(row)+1); /* flags column */ check_val( flags_drc_col, ROW_VALUES(row)+2, DB_INT, 1, 0); int_vals[INT_VALS_FLAGS_DRC_COL] = VAL_INT(ROW_VALUES(row)+2); /* GWLIST column */ check_val( gwlist_drc_col, ROW_VALUES(row)+3, DB_STRING, 1, 1); str_vals[STR_VALS_GWLIST_DRC_COL] = (char*)VAL_STRING(ROW_VALUES(row)+3); /* ATTRS column */ check_val( attrs_drc_col, ROW_VALUES(row)+4, DB_STRING, 0, 0); str_vals[STR_VALS_ATTRS_DRC_COL] = (char*)VAL_STRING(ROW_VALUES(row)+4); /* STATE column */ if (persistent_state) { check_val( state_drc_col, ROW_VALUES(row)+5, DB_INT, 1, 0); int_vals[INT_VALS_STATE_DRC_COL] = VAL_INT(ROW_VALUES(row)+5); } else { int_vals[INT_VALS_STATE_DRC_COL] = 0; /* by default enabled */ } /* add the new carrier */ if ( add_carrier( str_vals[STR_VALS_CID_DRC_COL], int_vals[INT_VALS_FLAGS_DRC_COL], str_vals[STR_VALS_GWLIST_DRC_COL], str_vals[STR_VALS_ATTRS_DRC_COL], int_vals[INT_VALS_STATE_DRC_COL], rdata) != 0 ) { LM_ERR("failed to add carrier db_id %d -> skipping\n", int_vals[INT_VALS_ID_DRC_COL]); continue; } } if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) { if(dr_dbf->fetch_result(db_hdl, &res, no_rows)<0) { LM_ERR( "fetching rows (1)\n"); goto error; } } else { break; } } while(RES_ROW_N(res)>0); } dr_dbf->free_result(db_hdl, res); res = 0; /* read the routing rules */ if (dr_dbf->use_table( db_hdl, drr_table) < 0) { LM_ERR("cannot select table \"%.*s\"\n", drr_table->len, drr_table->s); goto error; } columns[0] = &rule_id_drr_col; columns[1] = &group_drr_col; columns[2] = &prefix_drr_col; columns[3] = &time_drr_col; columns[4] = &priority_drr_col; columns[5] = &routeid_drr_col; columns[6] = &dstlist_drr_col; columns[7] = &attrs_drr_col; if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) { if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 8, 0, 0) < 0) { LM_ERR("DB query failed\n"); goto error; } no_rows = estimate_available_rows( 4+32+32+128+32+64+128, 8/*cols*/); if (no_rows==0) no_rows = 10; if(dr_dbf->fetch_result(db_hdl, &res, no_rows)<0) { LM_ERR("Error fetching rows\n"); goto error; } } else { if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 8, 0, &res) < 0) { LM_ERR("DB query failed\n"); goto error; } } if (RES_ROW_N(res) == 0) { LM_WARN("table \"%.*s\" is empty\n", drr_table->len, drr_table->s); } LM_DBG("initial %d records found in %.*s\n", RES_ROW_N(res), drr_table->len, drr_table->s); n = 0; do { for(i=0; i < RES_ROW_N(res); i++) { row = RES_ROWS(res) + i; /* RULE_ID column */ check_val( rule_id_drr_col, ROW_VALUES(row), DB_INT, 1, 0); int_vals[INT_VALS_RULE_ID_DRR_COL] = VAL_INT (ROW_VALUES(row)); /* GROUP column */ check_val( group_drr_col, ROW_VALUES(row)+1, DB_STRING, 1, 1); str_vals[STR_VALS_GROUP_DRR_COL] = (char*)VAL_STRING(ROW_VALUES(row)+1); /* PREFIX column - it may be null or empty */ check_val( prefix_drr_col, ROW_VALUES(row)+2, DB_STRING, 0, 0); if ((ROW_VALUES(row)+2)->nul || VAL_STRING(ROW_VALUES(row)+2)==0){ tmp.s = NULL; tmp.len = 0; } else { str_vals[STR_VALS_PREFIX_DRR_COL] = (char*)VAL_STRING(ROW_VALUES(row)+2); tmp.s = str_vals[STR_VALS_PREFIX_DRR_COL]; tmp.len = strlen(str_vals[STR_VALS_PREFIX_DRR_COL]); } /* TIME column */ check_val( time_drr_col, ROW_VALUES(row)+3, DB_STRING, 0, 0); str_vals[STR_VALS_TIME_DRR_COL] = (char*)VAL_STRING(ROW_VALUES(row)+3); /* PRIORITY column */ check_val( priority_drr_col, ROW_VALUES(row)+4, DB_INT, 1, 0); int_vals[INT_VALS_PRIORITY_DRR_COL] = VAL_INT (ROW_VALUES(row)+4); /* ROUTE_ID column */ check_val( routeid_drr_col, ROW_VALUES(row)+5, DB_STRING, 0, 0); str_vals[STR_VALS_ROUTEID_DRR_COL] = (char*)VAL_STRING(ROW_VALUES(row)+5); /* DSTLIST column */ check_val( dstlist_drr_col, ROW_VALUES(row)+6, DB_STRING, 1, 1); str_vals[STR_VALS_DSTLIST_DRR_COL] = (char*)VAL_STRING(ROW_VALUES(row)+6); /* ATTRS column */ check_val( attrs_drr_col, ROW_VALUES(row)+7, DB_STRING, 0, 0); str_vals[STR_VALS_ATTRS_DRR_COL] = (char*)VAL_STRING(ROW_VALUES(row)+7); /* parse the time definition */ if (str_vals[STR_VALS_TIME_DRR_COL] == NULL || *(str_vals[STR_VALS_TIME_DRR_COL]) == 0) time_rec = NULL; else if ((time_rec=parse_time_def(str_vals[STR_VALS_TIME_DRR_COL]))==0) { LM_ERR("bad time definition <%s> for rule id %d -> skipping\n", str_vals[STR_VALS_TIME_DRR_COL], int_vals[INT_VALS_RULE_ID_DRR_COL]); continue; } /* lookup for the script route ID */ if (str_vals[STR_VALS_ROUTEID_DRR_COL] && str_vals[STR_VALS_ROUTEID_DRR_COL][0]) { int_vals[INT_VALS_SCRIPT_ROUTE_ID] = get_script_route_ID_by_name( str_vals[STR_VALS_ROUTEID_DRR_COL], rlist, RT_NO); if (int_vals[INT_VALS_SCRIPT_ROUTE_ID]==-1) { LM_WARN("route <%s> does not exist\n", str_vals[STR_VALS_ROUTEID_DRR_COL]); int_vals[INT_VALS_SCRIPT_ROUTE_ID] = 0; } } else { int_vals[INT_VALS_SCRIPT_ROUTE_ID] = 0; } /* build the routing rule */ if ((ri = build_rt_info( int_vals[INT_VALS_RULE_ID_DRR_COL], int_vals[INT_VALS_PRIORITY_DRR_COL], time_rec, int_vals[INT_VALS_SCRIPT_ROUTE_ID], str_vals[STR_VALS_DSTLIST_DRR_COL], str_vals[STR_VALS_ATTRS_DRR_COL], rdata))== 0 ) { LM_ERR("failed to add routing info for rule id %d -> " "skipping\n", int_vals[INT_VALS_RULE_ID_DRR_COL]); tmrec_free( time_rec ); continue; } /* add the rule */ if (add_rule( rdata, str_vals[STR_VALS_GROUP_DRR_COL], &tmp, ri)!=0) { LM_ERR("failed to add rule id %d -> skipping\n", int_vals[INT_VALS_RULE_ID_DRR_COL]); free_rt_info( ri ); continue; } n++; } if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) { if(dr_dbf->fetch_result(db_hdl, &res, no_rows)<0) { LM_ERR( "fetching rows (1)\n"); goto error; } LM_DBG("additional %d records found in %.*s\n", RES_ROW_N(res), drr_table->len, drr_table->s); } else { break; } } while(RES_ROW_N(res)>0); dr_dbf->free_result(db_hdl, res); res = 0; LM_DBG("%d total records loaded from table %.*s\n", n, drr_table->len, drr_table->s); return rdata; error: if (res) dr_dbf->free_result(db_hdl, res); if (rdata) free_rt_data( rdata, 1 ); rdata = NULL; return 0; }
rt_data_t* dr_load_routing_info( db_func_t *dr_dbf, db_con_t* db_hdl, str *drd_table, str *drc_table, str* drr_table ) { int int_vals[4]; char * str_vals[6]; str tmp; db_key_t columns[8]; db_res_t* res; db_row_t* row; rt_info_t *ri; rt_data_t *rdata; tmrec_t *time_rec; int i,n; int no_rows = 10; res = 0; ri = 0; rdata = 0; /* init new data structure */ if ( (rdata=build_rt_data())==0 ) { LM_ERR("failed to build rdata\n"); goto error; } if (db_check_table_version(dr_dbf, db_hdl, drd_table, 5 )!= 0) goto error; /* read the destinations */ if (dr_dbf->use_table( db_hdl, drd_table) < 0) { LM_ERR("cannot select table \"%.*s\"\n", drd_table->len,drd_table->s); goto error; } columns[0] = &id_drd_col; columns[1] = &gwid_drd_col; columns[2] = &address_drd_col; columns[3] = &strip_drd_col; columns[4] = &prefix_drd_col; columns[5] = &type_drd_col; columns[6] = &attrs_drd_col; columns[7] = &probe_drd_col; if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) { if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 8, 0, 0 ) < 0) { LM_ERR("DB query failed\n"); goto error; } no_rows = estimate_available_rows( 4+32+15+4+32+4+128+4, 8); if (no_rows==0) no_rows = 10; if(dr_dbf->fetch_result(db_hdl, &res, no_rows )<0) { LM_ERR("Error fetching rows\n"); goto error; } } else { if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 8, 0, &res) < 0) { LM_ERR("DB query failed\n"); goto error; } } LM_DBG("%d records found in %.*s\n", RES_ROW_N(res), drd_table->len,drd_table->s); n = 0; do { for(i=0; i < RES_ROW_N(res); i++) { row = RES_ROWS(res) + i; /* DB ID column */ check_val(ID_DRD_COL, ROW_VALUES(row), DB_INT, 1, 0); int_vals[0] = VAL_INT(ROW_VALUES(row)); /* GW ID column */ check_val(GWID_DRD_COL, ROW_VALUES(row)+1, DB_STRING, 1, 1); str_vals[3] = (char*)VAL_STRING(ROW_VALUES(row)+1); /* ADDRESS column */ check_val(ADDRESS_DRD_COL, ROW_VALUES(row)+2, DB_STRING, 1, 1); str_vals[0] = (char*)VAL_STRING(ROW_VALUES(row)+2); /* STRIP column */ check_val(STRIP_DRD_COL, ROW_VALUES(row)+3, DB_INT, 1, 0); int_vals[1] = VAL_INT (ROW_VALUES(row)+3); /* PREFIX column */ check_val(PREFIX_DRD_COL, ROW_VALUES(row)+4, DB_STRING, 0, 0); str_vals[1] = (char*)VAL_STRING(ROW_VALUES(row)+4); /* TYPE column */ check_val(TYPE_DRD_COL, ROW_VALUES(row)+5, DB_INT, 1, 0); int_vals[2] = VAL_INT(ROW_VALUES(row)+5); /* ATTRS column */ check_val(ATTRS_DRD_COL, ROW_VALUES(row)+6, DB_STRING, 0, 0); str_vals[2] = (char*)VAL_STRING(ROW_VALUES(row)+6); /*PROBE_MODE column */ check_val(PROBE_DRD_COL, ROW_VALUES(row)+7, DB_INT, 1, 0); int_vals[3] = VAL_INT(ROW_VALUES(row)+7); /* add the destinaton definition in */ if ( add_dst( rdata, str_vals[3], str_vals[0], int_vals[1], str_vals[1], int_vals[2], str_vals[2], int_vals[3])<0 ) { LM_ERR("failed to add destination id %d -> skipping\n", int_vals[0]); continue; } n++; } if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) { if(dr_dbf->fetch_result(db_hdl, &res, no_rows)<0) { LM_ERR( "fetching rows (1)\n"); goto error; } } else { break; } } while(RES_ROW_N(res)>0); dr_dbf->free_result(db_hdl, res); res = 0; /* read the carriers, if any */ if (dr_dbf->use_table( db_hdl, drc_table) < 0) { LM_ERR("cannot select table \"%.*s\"\n", drc_table->len,drc_table->s); goto error; } columns[0] = &id_drc_col; columns[1] = &cid_drc_col; columns[2] = &flags_drc_col; columns[3] = &gwlist_drc_col; columns[4] = &attrs_drc_col; if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) { if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 5, 0, 0 ) < 0) { LM_ERR("DB query failed\n"); goto error; } no_rows = estimate_available_rows( 4+4+32+64+64, 5/*cols*/); if (no_rows==0) no_rows = 10; if(dr_dbf->fetch_result(db_hdl, &res, no_rows)<0) { LM_ERR("Error fetching rows\n"); goto error; } } else { if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 5, 0, &res) < 0) { LM_ERR("DB query failed\n"); goto error; } } if (RES_ROW_N(res) == 0) { LM_DBG("table \"%.*s\" empty\n", drc_table->len,drc_table->s ); } else { LM_DBG("%d records found in %.*s\n", RES_ROW_N(res), drc_table->len,drc_table->s); do { for(i=0; i < RES_ROW_N(res); i++) { row = RES_ROWS(res) + i; /* ID column */ check_val(ID_DRC_COL, ROW_VALUES(row), DB_INT, 1, 0); int_vals[0] = VAL_INT(ROW_VALUES(row)); /* CARRIER_ID column */ check_val(CID_DRC_COL, ROW_VALUES(row)+1, DB_STRING, 1, 1); str_vals[0] = (char*)VAL_STRING(ROW_VALUES(row)+1); /* ID column */ check_val(ID_DRC_COL, ROW_VALUES(row)+2, DB_INT, 1, 0); int_vals[1] = VAL_INT(ROW_VALUES(row)+2); /* GWLIST column */ check_val(GWLIST_DRC_COL, ROW_VALUES(row)+3, DB_STRING, 1, 1); str_vals[1] = (char*)VAL_STRING(ROW_VALUES(row)+3); /* ATTRS column */ check_val(ATTRS_DRC_COL, ROW_VALUES(row)+4, DB_STRING, 0, 0); str_vals[2] = (char*)VAL_STRING(ROW_VALUES(row)+4); /* add the new carrier */ if ( add_carrier( int_vals[0], str_vals[0], int_vals[1], str_vals[1], str_vals[2], rdata) != 0 ) { LM_ERR("failed to add carrier db_id %d -> skipping\n", int_vals[0]); continue; } } if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) { if(dr_dbf->fetch_result(db_hdl, &res, no_rows)<0) { LM_ERR( "fetching rows (1)\n"); goto error; } } else { break; } } while(RES_ROW_N(res)>0); } dr_dbf->free_result(db_hdl, res); res = 0; /* read the routing rules */ if (dr_dbf->use_table( db_hdl, drr_table) < 0) { LM_ERR("cannot select table \"%.*s\"\n", drr_table->len, drr_table->s); goto error; } columns[0] = &rule_id_drr_col; columns[1] = &group_drr_col; columns[2] = &prefix_drr_col; columns[3] = &time_drr_col; columns[4] = &priority_drr_col; columns[5] = &routeid_drr_col; columns[6] = &dstlist_drr_col; columns[7] = &attrs_drd_col; if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) { if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 8, 0, 0) < 0) { LM_ERR("DB query failed\n"); goto error; } no_rows = estimate_available_rows( 4+32+32+128+32+64+128, 8/*cols*/); if (no_rows==0) no_rows = 10; if(dr_dbf->fetch_result(db_hdl, &res, no_rows)<0) { LM_ERR("Error fetching rows\n"); goto error; } } else { if ( dr_dbf->query( db_hdl, 0, 0, 0, columns, 0, 8, 0, &res) < 0) { LM_ERR("DB query failed\n"); goto error; } } if (RES_ROW_N(res) == 0) { LM_WARN("table \"%.*s\" is empty\n", drr_table->len, drr_table->s); } LM_DBG("%d records found in %.*s\n", RES_ROW_N(res), drr_table->len, drr_table->s); n = 0; do { for(i=0; i < RES_ROW_N(res); i++) { row = RES_ROWS(res) + i; /* RULE_ID column */ check_val(RULE_ID_DRR_COL, ROW_VALUES(row), DB_INT, 1, 0); int_vals[0] = VAL_INT (ROW_VALUES(row)); /* GROUP column */ check_val(GROUP_DRR_COL, ROW_VALUES(row)+1, DB_STRING, 1, 1); str_vals[0] = (char*)VAL_STRING(ROW_VALUES(row)+1); /* PREFIX column - it may be null or empty */ check_val(PREFIX_DRR_COL, ROW_VALUES(row)+2, DB_STRING, 0, 0); if ((ROW_VALUES(row)+2)->nul || VAL_STRING(ROW_VALUES(row)+2)==0){ tmp.s = NULL; tmp.len = 0; } else { str_vals[1] = (char*)VAL_STRING(ROW_VALUES(row)+2); tmp.s = str_vals[1]; tmp.len = strlen(str_vals[1]); } /* TIME column */ check_val(TIME_DRR_COL, ROW_VALUES(row)+3, DB_STRING, 0, 0); str_vals[2] = (char*)VAL_STRING(ROW_VALUES(row)+3); /* PRIORITY column */ check_val(PRIORITY_DRR_COL, ROW_VALUES(row)+4, DB_INT, 1, 0); int_vals[2] = VAL_INT (ROW_VALUES(row)+4); /* ROUTE_ID column */ check_val(ROUTEID_DRR_COL, ROW_VALUES(row)+5, DB_STRING, 1, 0); str_vals[3] = (char*)VAL_STRING(ROW_VALUES(row)+5); /* DSTLIST column */ check_val(DSTLIST_DRR_COL, ROW_VALUES(row)+6, DB_STRING, 1, 1); str_vals[4] = (char*)VAL_STRING(ROW_VALUES(row)+6); /* ATTRS column */ check_val(ATTRS_DRD_COL, ROW_VALUES(row)+7, DB_STRING, 0, 0); str_vals[5] = (char*)VAL_STRING(ROW_VALUES(row)+7); /* parse the time definition */ if ((time_rec=parse_time_def(str_vals[2]))==0) { LM_ERR("bad time definition <%s> for rule id %d -> skipping\n", str_vals[2], int_vals[0]); continue; } /* lookup for the script route ID */ if (str_vals[3][0]) { int_vals[3] = get_script_route_ID_by_name( str_vals[3], rlist, RT_NO); if (int_vals[3]==-1) { LM_WARN("route <%s> does not exist\n",str_vals[3]); int_vals[3] = 0; } } else { int_vals[3] = 0; } /* build the routing rule */ if ((ri = build_rt_info( int_vals[0], int_vals[2], time_rec, int_vals[3], str_vals[4], str_vals[5], rdata))== 0 ) { LM_ERR("failed to add routing info for rule id %d -> " "skipping\n", int_vals[0]); tmrec_free( time_rec ); continue; } /* add the rule */ if (add_rule( rdata, str_vals[0], &tmp, ri)!=0) { LM_ERR("failed to add rule id %d -> skipping\n", int_vals[0]); free_rt_info( ri ); continue; } n++; } if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) { if(dr_dbf->fetch_result(db_hdl, &res, no_rows)<0) { LM_ERR( "fetching rows (1)\n"); goto error; } } else { break; } } while(RES_ROW_N(res)>0); dr_dbf->free_result(db_hdl, res); res = 0; if (n==0) { LM_WARN("no valid routing rules -> discarding all destinations\n"); free_rt_data( rdata, 0 ); } return rdata; error: if (res) dr_dbf->free_result(db_hdl, res); if (rdata) free_rt_data( rdata, 1 ); rdata = NULL; return 0; }
/* loads info from the db */ int load_db_info(db_func_t *dr_dbf, db_con_t* db_hdl, str *db_table, cluster_info_t **cl_list) { int int_vals[NO_DB_INT_VALS]; char *str_vals[NO_DB_STR_VALS]; int no_clusters; int i; int rc; node_info_t *new_info = NULL; db_key_t columns[NO_DB_COLS]; /* the columns from the db table */ db_res_t *res = NULL; db_row_t *row; static db_key_t clusterer_node_id_key = &node_id_col; static db_val_t clusterer_node_id_value = { .type = DB_INT, .nul = 0, }; *cl_list = NULL; columns[0] = &id_col; columns[1] = &cluster_id_col; columns[2] = &node_id_col; columns[3] = &url_col; columns[4] = &state_col; columns[5] = &no_ping_retries_col; columns[6] = &priority_col; columns[7] = &sip_addr_col; columns[8] = &flags_col; columns[9] = &description_col; CON_OR_RESET(db_hdl); if (db_check_table_version(dr_dbf, db_hdl, db_table, CLUSTERER_TABLE_VERSION)) goto error; if (dr_dbf->use_table(db_hdl, db_table) < 0) { LM_ERR("cannot select table: \"%.*s\"\n", db_table->len, db_table->s); goto error; } LM_DBG("DB query - retrieve the list of clusters" " in which the local node runs\n"); VAL_INT(&clusterer_node_id_value) = current_id; /* first we see in which clusters the local node runs*/ if (dr_dbf->query(db_hdl, &clusterer_node_id_key, &op_eq, &clusterer_node_id_value, columns+1, 1, 1, 0, &res) < 0) { LM_ERR("DB query failed - cannot retrieve the list of clusters in which" " the local node runs\n"); goto error; } LM_DBG("%d rows found in %.*s\n", RES_ROW_N(res), db_table->len, db_table->s); if (RES_ROW_N(res) > MAX_NO_CLUSTERS) { LM_ERR("Defined: %d clusters for local node, maximum number of clusters " "supported(%d) exceeded\n", RES_ROW_N(res), MAX_NO_CLUSTERS); goto error; } if (RES_ROW_N(res) == 0) { LM_WARN("No nodes found in cluster\n"); return 1; } clusterer_cluster_id_key = pkg_realloc(clusterer_cluster_id_key, RES_ROW_N(res) * sizeof(db_key_t)); if (!clusterer_cluster_id_key) { LM_ERR("no more pkg memory\n"); goto error; } for (i = 0; i < RES_ROW_N(res); i++) clusterer_cluster_id_key[i] = &cluster_id_col; clusterer_cluster_id_value = pkg_realloc(clusterer_cluster_id_value, RES_ROW_N(res) * sizeof(db_val_t)); if (!clusterer_cluster_id_value) { LM_ERR("no more pkg memory\n"); goto error; } for (i = 0; i < RES_ROW_N(res); i++) { VAL_TYPE(clusterer_cluster_id_value + i) = DB_INT; VAL_NULL(clusterer_cluster_id_value + i) = 0; } for (i = 0; i < RES_ROW_N(res); i++) { row = RES_ROWS(res) + i; check_val(cluster_id_col, ROW_VALUES(row), DB_INT, 1, 0); VAL_INT(clusterer_cluster_id_value + i) = VAL_INT(ROW_VALUES(row)); } no_clusters = RES_ROW_N(res); dr_dbf->free_result(db_hdl, res); res = NULL; LM_DBG("DB query - retrieve nodes info\n"); CON_USE_OR_OP(db_hdl); if (dr_dbf->query(db_hdl, clusterer_cluster_id_key, 0, clusterer_cluster_id_value, columns, no_clusters, NO_DB_COLS, 0, &res) < 0) { LM_ERR("DB query failed - retrieve valid connections\n"); goto error; } LM_DBG("%d rows found in %.*s\n", RES_ROW_N(res), db_table->len, db_table->s); if (RES_ROW_N(res) > MAX_NO_NODES) { LM_ERR("Defined: %d nodes in local node's clusters, maximum number of nodes " "supported(%d) exceeded\n", RES_ROW_N(res), MAX_NO_NODES); goto error; } for (i = 0; i < RES_ROW_N(res); i++) { row = RES_ROWS(res) + i; check_val(id_col, ROW_VALUES(row), DB_INT, 1, 0); int_vals[INT_VALS_ID_COL] = VAL_INT(ROW_VALUES(row)); check_val(cluster_id_col, ROW_VALUES(row) + 1, DB_INT, 1, 0); int_vals[INT_VALS_CLUSTER_ID_COL] = VAL_INT(ROW_VALUES(row) + 1); check_val(node_id_col, ROW_VALUES(row) + 2, DB_INT, 1, 0); int_vals[INT_VALS_NODE_ID_COL] = VAL_INT(ROW_VALUES(row) + 2); check_val(url_col, ROW_VALUES(row) + 3, DB_STRING, 1, 1); str_vals[STR_VALS_URL_COL] = (char*) VAL_STRING(ROW_VALUES(row) + 3); check_val(state_col, ROW_VALUES(row) + 4, DB_INT, 1, 0); int_vals[INT_VALS_STATE_COL] = VAL_INT(ROW_VALUES(row) + 4); check_val(no_ping_retries_col, ROW_VALUES(row) + 5, DB_INT, 1, 0); int_vals[INT_VALS_NO_PING_RETRIES_COL] = VAL_INT(ROW_VALUES(row) + 5); check_val(priority_col, ROW_VALUES(row) + 6, DB_INT, 1, 0); int_vals[INT_VALS_PRIORITY_COL] = VAL_INT(ROW_VALUES(row) + 6); check_val(sip_addr_col, ROW_VALUES(row) + 7, DB_STRING, 0, 0); str_vals[STR_VALS_SIP_ADDR_COL] = (char*) VAL_STRING(ROW_VALUES(row) + 7); check_val(flags_col, ROW_VALUES(row) + 8, DB_STRING, 0, 0); str_vals[STR_VALS_FLAGS_COL] = (char*) VAL_STRING(ROW_VALUES(row) + 8); check_val(description_col, ROW_VALUES(row) + 9, DB_STRING, 0, 0); str_vals[STR_VALS_DESCRIPTION_COL] = (char*) VAL_STRING(ROW_VALUES(row) + 9); /* add info to backing list */ if ((rc = add_node_info(&new_info, cl_list, int_vals, str_vals)) != 0) { LM_ERR("Unable to add node info to backing list\n"); if (rc < 0) return -1; else return 2; } } /* warn if no seed node is defined in a cluster */ check_seed_flag(cl_list); if (RES_ROW_N(res) == 1) LM_INFO("The local node is the only one in the cluster\n"); dr_dbf->free_result(db_hdl, res); return 0; error: if (res) dr_dbf->free_result(db_hdl, res); if (*cl_list) free_info(*cl_list); *cl_list = NULL; return -1; } int provision_neighbor(modparam_t type, void *val) { int int_vals[NO_DB_INT_VALS]; char *str_vals[NO_DB_STR_VALS]; str prov_str; node_info_t *new_info; if (db_mode) { LM_INFO("Running in db mode, provisioning from the script is ignored\n"); return 0; } prov_str.s = (char*)val; prov_str.len = strlen(prov_str.s); if (parse_param_node_info(&prov_str, int_vals, str_vals) < 0) { LM_ERR("Unable to define a neighbor node\n"); return -1; } if (int_vals[INT_VALS_CLUSTER_ID_COL] == -1 || int_vals[INT_VALS_NODE_ID_COL] == -1 || str_vals[STR_VALS_URL_COL] == NULL) { LM_ERR("At least the cluster id, node id and url are required for a neighbor node\n"); return -1; } int_vals[INT_VALS_STATE_COL] = 1; if (int_vals[INT_VALS_NO_PING_RETRIES_COL] == -1) int_vals[INT_VALS_NO_PING_RETRIES_COL] = DEFAULT_NO_PING_RETRIES; if (int_vals[INT_VALS_PRIORITY_COL] == -1) int_vals[INT_VALS_PRIORITY_COL] = DEFAULT_NO_PING_RETRIES; str_vals[STR_VALS_DESCRIPTION_COL] = NULL; int_vals[INT_VALS_ID_COL] = -1; if (cluster_list == NULL) { cluster_list = shm_malloc(sizeof *cluster_list); if (!cluster_list) { LM_CRIT("No more shm memory\n"); return -1; } *cluster_list = NULL; } if (add_node_info(&new_info, cluster_list, int_vals, str_vals) < 0) { LM_ERR("Unable to add node info to backing list\n"); return -1; } return 0; }
static int ul_db_failover_get_spare(db_func_t * dbf, db1_con_t * dbh, ul_db_t * db) { db1_res_t * res = NULL; db_row_t * row; int query_len; str tmp; if(!dbf || !dbh || !db) { LM_ERR("Null pointer as parameter.\n"); return -1; } memset(&spare, 0, sizeof(ul_db_handle_t)); memset(query, 0, UL_DB_QUERY_LEN); query_len = 100 + id_col.len + num_col.len + url_col.len + 2 * risk_group_col.len + reg_table.len + spare_col.len + status_col.len; if(query_len >= UL_DB_QUERY_LEN){ LM_ERR("weird: extremely long query.\n"); return -1; } if (sprintf(query, "SELECT " "%.*s, " "%.*s, " "%.*s, " "%.*s " "FROM %.*s " "WHERE " "%.*s=1 AND " "%.*s!=%i AND " "%.*s=%i " "LIMIT 1 " "FOR UPDATE", id_col.len, id_col.s, num_col.len, num_col.s, url_col.len, url_col.s, risk_group_col.len, risk_group_col.s, reg_table.len, reg_table.s, spare_col.len, spare_col.s, risk_group_col.len, risk_group_col.s, db->rg, status_col.len, status_col.s, DB_ON) < 0) { LM_ERR("could not print query\n"); return -1; } tmp.s = query; tmp.len = strlen(query); if(dbf->raw_query(dbh, &tmp, &res) < 0) { LM_ERR("could not query database.\n"); return -1; } if(RES_ROW_N(res) == 0) { LM_ERR("no spare left.\n"); dbf->free_result(dbh, res); return -1; } row = RES_ROWS(res); spare.id = VAL_INT(ROW_VALUES(row) + 0); spare.db[0].no = VAL_INT(ROW_VALUES(row) + 1); if(strlen(VAL_STRING(ROW_VALUES(row) + 2)) >= UL_DB_URL_LEN){ LM_ERR("weird: " "db URL longer than %i.\n", UL_DB_URL_LEN); dbf->free_result(dbh, res); return -1; } strcpy(spare.db[0].url.s, VAL_STRING(ROW_VALUES(row) + 2)); spare.db[0].url.len = strlen(spare.db[0].url.s); spare.db[0].rg = VAL_INT(ROW_VALUES(row) + 3); dbf->free_result(dbh, res); return 0; }
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; }
/* * Used when converting result from a query */ int val2str(MYSQL* _c, db_val_t* _v, char* _s, int* _len) { int l; char* old_s; if (!_c || !_v || !_s || !_len || !*_len) { LOG(L_ERR, "val2str: Invalid parameter value\n"); return -1; } if (VAL_NULL(_v)) { if (*_len < sizeof("NULL")) { LOG(L_ERR, "val2str: Buffer too small\n"); return -1; } *_len = snprintf(_s, *_len, "NULL"); return 0; } switch(VAL_TYPE(_v)) { case DB_INT: if (int2str(VAL_INT(_v), _s, _len) < 0) { LOG(L_ERR, "val2str: Error while converting string to int\n"); return -2; } else { return 0; } break; case DB_BITMAP: if (int2str(VAL_BITMAP(_v), _s, _len) < 0) { LOG(L_ERR, "val2str: Error while converting string to int\n"); return -3; } else { return 0; } break; case DB_DOUBLE: if (double2str(VAL_DOUBLE(_v), _s, _len) < 0) { LOG(L_ERR, "val2str: Error while converting string to double\n"); return -4; } else { return 0; } break; case DB_STRING: l = strlen(VAL_STRING(_v)); if (*_len < (l * 2 + 3)) { LOG(L_ERR, "val2str: Destination buffer too short\n"); return -5; } else { old_s = _s; *_s++ = '\''; _s += mysql_real_escape_string(_c, _s, VAL_STRING(_v), l); *_s++ = '\''; *_s = '\0'; /* FIXME */ *_len = _s - old_s; return 0; } break; case DB_STR: l = VAL_STR(_v).len; if (*_len < (l * 2 + 3)) { LOG(L_ERR, "val2str: Destination buffer too short\n"); return -6; } else { old_s = _s; *_s++ = '\''; _s += mysql_real_escape_string(_c, _s, VAL_STR(_v).s, l); *_s++ = '\''; *_s = '\0'; *_len = _s - old_s; return 0; } break; case DB_DATETIME: if (time2str(VAL_TIME(_v), _s, _len) < 0) { LOG(L_ERR, "val2str: Error while converting string to time_t\n"); return -7; } else { return 0; } break; case DB_BLOB: l = VAL_BLOB(_v).len; if (*_len < (l * 2 + 3)) { LOG(L_ERR, "val2str: Destination buffer too short\n"); return -8; } else { old_s = _s; *_s++ = '\''; _s += mysql_escape_string(_s, VAL_STR(_v).s, l); *_s++ = '\''; *_s = '\0'; *_len = _s - old_s; return 0; } break; default: DBG("val2str: Unknown data type\n"); return -9; } /*return -8; --not reached*/ }
static int xcaps_get_directory(struct sip_msg *msg, str *user, str *domain, str *directory) { db_key_t qcols[2]; db_val_t qvals[2], *values; db_key_t rcols[3]; db_row_t *rows; db1_res_t* db_res = NULL; int n_qcols = 0, n_rcols = 0; int i, cur_type = 0, cur_pos = 0; int doc_type_col, doc_uri_col, etag_col; str auid_string = {0, 0}; struct hdr_field *hdr = msg->headers; str server_name = {0, 0}; qcols[n_qcols] = &str_username_col; qvals[n_qcols].type = DB1_STR; qvals[n_qcols].nul = 0; qvals[n_qcols].val.str_val = *user; n_qcols++; qcols[n_qcols] = &str_domain_col; qvals[n_qcols].type = DB1_STR; qvals[n_qcols].nul = 0; qvals[n_qcols].val.str_val = *domain; n_qcols++; rcols[doc_type_col = n_rcols++] = &str_doc_type_col; rcols[doc_uri_col = n_rcols++] = &str_doc_uri_col; rcols[etag_col = n_rcols++] = &str_etag_col; if (xcaps_dbf.use_table(xcaps_db, &xcaps_db_table) < 0) { LM_ERR("in use_table-[table]= %.*s\n", xcaps_db_table.len, xcaps_db_table.s); goto error; } if (xcaps_dbf.query(xcaps_db, qcols, 0, qvals, rcols, n_qcols, n_rcols, &str_doc_type_col, &db_res) < 0) { LM_ERR("in sql query\n"); goto error; } if (db_res == NULL) goto error; directory->s = xcaps_buf.s; directory->len = 0; directory->len += snprintf(directory->s + directory->len, xcaps_buf.len - directory->len, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" "<xcap-directory xmlns=\"urn:oma:xml:xdm:xcap-directory\">\r\n"); rows = RES_ROWS(db_res); for (i = 0; i < RES_ROW_N(db_res); i++) { values = ROW_VALUES(&rows[i]); if (cur_type != VAL_INT(&values[doc_type_col])) { if (cur_type != 0) { directory->len += snprintf(directory->s + directory->len, xcaps_buf.len - directory->len, "</folder>\r\n"); } cur_type = VAL_INT(&values[doc_type_col]); memset(&auid_string, 0, sizeof(str)); while(xcaps_auid_list[cur_pos].auid.s != NULL) { if (xcaps_auid_list[cur_pos].type == cur_type) { auid_string.s = xcaps_auid_list[cur_pos].auid.s; auid_string.len = xcaps_auid_list[cur_pos].auid.len; break; } cur_pos++; } if (auid_string.s == NULL) { goto error; } directory->len += snprintf(directory->s + directory->len, xcaps_buf.len - directory->len, "<folder auid=\"%.*s\">\r\n", auid_string.len, auid_string.s); } switch(xcaps_directory_scheme) { case -1: directory->len += snprintf(directory->s + directory->len, xcaps_buf.len - directory->len, "<entry uri=\"%s://", msg->rcv.proto == PROTO_TLS ? "https" : "http"); break; case 0: directory->len += snprintf(directory->s + directory->len, xcaps_buf.len - directory->len, "<entry uri=\"http://"); break; case 1: directory->len += snprintf(directory->s + directory->len, xcaps_buf.len - directory->len, "<entry uri=\"https://"); break; } if (xcaps_directory_hostname.len > 0) { directory->len += snprintf(directory->s + directory->len, xcaps_buf.len - directory->len, "%.*s", xcaps_directory_hostname.len, xcaps_directory_hostname.s); } else { if (parse_headers(msg, HDR_EOH_F, 0) < 0) { LM_ERR("error parsing headers\n"); goto error; } while (hdr != NULL) { if (cmp_hdrname_strzn(&hdr->name, "Host", 4) == 0) { server_name = hdr->body; break; } hdr = hdr->next; } if (server_name.len > 0) { directory->len += snprintf(directory->s + directory->len, xcaps_buf.len - directory->len, "%.*s", server_name.len, server_name.s); } else { server_name.s = pkg_malloc(IP6_MAX_STR_SIZE + 6); server_name.len = ip_addr2sbuf(&msg->rcv.dst_ip, server_name.s, IP6_MAX_STR_SIZE); directory->len += snprintf(directory->s + directory->len, xcaps_buf.len - directory->len, "%.*s:%d", server_name.len, server_name.s, msg->rcv.dst_port); pkg_free(server_name.s); } } directory->len += snprintf(directory->s + directory->len, xcaps_buf.len - directory->len, "%s\" etag=\"%s\"/>\r\n", VAL_STRING(&values[doc_uri_col]), VAL_STRING(&values[etag_col])); } if (cur_type != 0) { directory->len += snprintf(directory->s + directory->len, xcaps_buf.len - directory->len, "</folder>\r\n"); } directory->len += snprintf(directory->s + directory->len, xcaps_buf.len - directory->len, "</xcap-directory>"); if (db_res != NULL) xcaps_dbf.free_result(xcaps_db, db_res); return 0; error: if (db_res != NULL) xcaps_dbf.free_result(xcaps_db, db_res); return -1; }
/* * Used when converting values to be used in a DB query */ int db_sqlite_val2str(const db_con_t* _c, const db_val_t* _v, char* _s, int* _len) { int l; if (!_c || !_v || !_s || !_len || !*_len) { LM_ERR("invalid parameter value\n"); return -1; } if (VAL_NULL(_v)) { if (*_len < sizeof("NULL")) { LM_ERR("buffer too small\n"); return -1; } *_len = snprintf(_s, *_len, "NULL"); return 0; } switch(VAL_TYPE(_v)) { case DB_INT: if (db_int2str(VAL_INT(_v), _s, _len) < 0) { LM_ERR("error while converting string to int\n"); return -2; } else { return 0; } break; case DB_BIGINT: if (db_bigint2str(VAL_BIGINT(_v), _s, _len) < 0) { LM_ERR("error while converting bigint to string\n"); return -2; } else { return 0; } break; case DB_BITMAP: if (db_int2str(VAL_BITMAP(_v), _s, _len) < 0) { LM_ERR("error while converting string to int\n"); return -3; } else { return 0; } break; case DB_DOUBLE: if (db_double2str(VAL_DOUBLE(_v), _s, _len) < 0) { LM_ERR("error while converting string to double\n"); return -4; } else { return 0; } break; case DB_STRING: /* TODO check escpaing */ l = strlen(VAL_STRING(_v)); if (*_len < l ) { LM_ERR("Destination buffer too short for string\n"); return -4; } else { LM_DBG("Converted string to string\n"); strncpy(_s, VAL_STRING(_v) , l); _s[l] = 0; *_len = l+1; /* count the 0 also */ return 0; } break; case DB_STR: /* TODO check escpaing */ l = VAL_STR(_v).len; if (*_len < l) { LM_ERR("Destination buffer too short for str\n"); return -5; } else { LM_DBG("Converted str to string\n"); strncpy(_s, VAL_STR(_v).s , l); *_len = l; return 0; } break; break; case DB_DATETIME: if (db_time2str(VAL_TIME(_v), _s, _len) < 0) { LM_ERR("error while converting string to time_t\n"); return -7; } else { return 0; } break; case DB_BLOB: /* TODO check escpaing */ l = VAL_BLOB(_v).len; if (*_len < l) { LM_ERR("Destination buffer too short for blob\n"); return -7; } else { strncpy(_s, VAL_BLOB(_v).s , l); LM_DBG("Converting BLOB [%.*s]\n", l,_s); *_len = l; return 0; } break; default: LM_DBG("unknown data type\n"); return -9; } }
/* * Reload domain table to new hash table and when done, make new hash table * current one. */ int reload_tables ( void ) { db_key_t cols[4]; db1_res_t* res = NULL; db_row_t* row; struct domain_list **new_hash_table; int i; short type; str did, domain, name, value; int_str val; /* Choose new hash table and free its old contents */ if (*hash_table == hash_table_1) { hash_table_free(hash_table_2); new_hash_table = hash_table_2; } else { hash_table_free(hash_table_1); new_hash_table = hash_table_1; } cols[0] = &did_col; cols[1] = &name_col; cols[2] = &type_col; cols[3] = &value_col; if (domain_db_init(&d_db_url) < 0) { LM_ERR("unable to open database connection\n"); return -1; } if (domain_dbf.use_table(db_handle, &domain_attrs_table) < 0) { LM_ERR("error while trying to use domain_attrs table\n"); goto err; } if (domain_dbf.query(db_handle, NULL, 0, NULL, cols, 0, 4, 0, &res) < 0) { LM_ERR("error while querying database\n"); goto err; } row = RES_ROWS(res); LM_DBG("number of rows in domain_attrs table: %d\n", RES_ROW_N(res)); for (i = 0; i < RES_ROW_N(res); i++) { row = RES_ROWS(res) + i; if ((VAL_NULL(ROW_VALUES(row)) == 1) || (VAL_TYPE(ROW_VALUES(row)) != DB1_STRING)) { LM_ERR("did at row <%u> is null or not string\n", i); goto err; } did.s = (char *)VAL_STRING(ROW_VALUES(row)); did.len = strlen(did.s); if (did.len == 0) { LM_ERR("did at row <%u> is empty string\n", i); goto err; } if ((VAL_NULL(ROW_VALUES(row) + 1) == 1) || (VAL_TYPE(ROW_VALUES(row) + 1) != DB1_STRING)) { LM_ERR("name at row <%u> is null or not string\n", i); goto err; } name.s = (char *)VAL_STRING(ROW_VALUES(row) + 1); name.len = strlen(name.s); if (name.len == 0) { LM_ERR("name at row <%u> is empty string\n", i); goto err; } if ((VAL_NULL(ROW_VALUES(row) + 2) == 1) || ((VAL_TYPE(ROW_VALUES(row) + 2) != DB1_INT) && (VAL_TYPE(ROW_VALUES(row) + 2) != DB1_BIGINT))) { LM_ERR("type at row <%u> is null or not int\n", i); goto err; } if(VAL_TYPE(ROW_VALUES(row) + 2) == DB1_BIGINT) { type = (int)VAL_BIGINT(ROW_VALUES(row) + 2); } else { type = (int)VAL_INT(ROW_VALUES(row) + 2); } if ((type != 0) && (type != 2)) { LM_ERR("unknown type <%d> at row <%u>\n", type, i); goto err; } if ((VAL_NULL(ROW_VALUES(row) + 3) == 1) || (VAL_TYPE(ROW_VALUES(row) + 3) != DB1_STRING)) { LM_ERR("value at row <%u> is null or not string\n", i); goto err; } value.s = (char *)VAL_STRING(ROW_VALUES(row) + 3); value.len = strlen(value.s); if (type == 0) { if (str2sint(&value, &(val.n)) == -1) { LM_ERR("value at row <%u> is invalid int\n", i); goto err; } } else { val.s = value; } if (type == 0) LM_DBG("inserting <did/name/type/value> = <%s/%s/%d/%d> into attribute list\n", did.s, name.s, type, val.n); else LM_DBG("inserting <did/name/type/value> = <%s/%s/%d/%s> into attribute list\n", did.s, name.s, type, val.s.s); if (hash_table_attr_install(new_hash_table, &did, &name, type, &val) == -1) { LM_ERR("could not install attribute into hash table\n"); goto err; } } domain_dbf.free_result(db_handle, res); res = NULL; cols[0] = &domain_col; cols[1] = &did_col; if (domain_dbf.use_table(db_handle, &domain_table) < 0) { LM_ERR("error while trying to use domain table\n"); goto err; } if (domain_dbf.query(db_handle, NULL, 0, NULL, cols, 0, 2, 0, &res) < 0) { LM_ERR("error while querying database\n"); goto err; } row = RES_ROWS(res); LM_DBG("number of rows in domain table: %d\n", RES_ROW_N(res)); for (i = 0; i < RES_ROW_N(res); i++) { row = RES_ROWS(res) + i; if ((VAL_NULL(ROW_VALUES(row)) == 1) || (VAL_TYPE(ROW_VALUES(row)) != DB1_STRING)) { LM_ERR("domain at row <%u> is null or not string\n", i); goto err; } domain.s = (char *)VAL_STRING(ROW_VALUES(row)); domain.len = strlen(domain.s); if (domain.len == 0) { LM_ERR("domain at row <%u> is empty string\n", i); goto err; } if ((VAL_NULL(ROW_VALUES(row) + 1) != 1) && (VAL_TYPE(ROW_VALUES(row) + 1) != DB1_STRING)) { LM_ERR("did at row <%u> is not null or string\n", i); goto err; } if (VAL_NULL(ROW_VALUES(row) + 1) == 1) { did.s = domain.s; did.len = domain.len; } else { did.s = (char *)VAL_STRING(ROW_VALUES(row) + 1); did.len = strlen(did.s); if (did.len == 0) { LM_ERR("did at row <%u> is empty string\n", i); goto err; } } LM_DBG("inserting <did/domain> = <%s/%s> into hash table\n", did.s, domain.s); if (hash_table_install(new_hash_table, &did, &domain) == -1) { LM_ERR("could not install domain into hash table\n"); domain_dbf.free_result(db_handle, res); goto err; } } domain_dbf.free_result(db_handle, res); res = NULL; *hash_table = new_hash_table; domain_db_close(); return 1; err: domain_dbf.free_result(db_handle, res); res = NULL; domain_db_close(); return -1; }
int db_sqlite_val2bind(const db_val_t* v, MYSQL_BIND *binds, unsigned int i) { struct tm *t; MYSQL_TIME *mt; if (VAL_NULL(v)) { *(binds[i].is_null) = 1; *(binds[i].length) = 0; binds[i].buffer= NULL; switch(VAL_TYPE(v)) { case DB_INT: binds[i].buffer_type= MYSQL_TYPE_LONG; break; case DB_BIGINT: binds[i].buffer_type= MYSQL_TYPE_LONGLONG; break; case DB_BITMAP: binds[i].buffer_type= MYSQL_TYPE_LONG; break; case DB_DOUBLE: binds[i].buffer_type= MYSQL_TYPE_DOUBLE; break; case DB_STRING: binds[i].buffer_type= MYSQL_TYPE_STRING; break; case DB_STR: binds[i].buffer_type= MYSQL_TYPE_STRING; break; case DB_DATETIME: binds[i].buffer_type= MYSQL_TYPE_DATETIME; break; case DB_BLOB: binds[i].buffer_type= MYSQL_TYPE_BLOB; break; default: LM_ERR("unknown NULL data type (%d)\n",VAL_TYPE(v)); return -10; } return 0; } else { *(binds[i].is_null) = 0; } switch(VAL_TYPE(v)) { case DB_INT: binds[i].buffer_type= MYSQL_TYPE_LONG; binds[i].buffer= (char*)&(VAL_INT(v)); *binds[i].length= sizeof(VAL_INT(v)); break; case DB_BIGINT: binds[i].buffer_type= MYSQL_TYPE_LONGLONG; binds[i].buffer= (char*)&(VAL_BIGINT(v)); *binds[i].length= sizeof(VAL_BIGINT(v)); break; case DB_BITMAP: binds[i].buffer_type= MYSQL_TYPE_LONG; binds[i].buffer= (char*)&(VAL_BITMAP(v)); *binds[i].length= sizeof(VAL_BITMAP(v)); break; case DB_DOUBLE: binds[i].buffer_type= MYSQL_TYPE_DOUBLE; binds[i].buffer= (char*)&(VAL_DOUBLE(v)); *binds[i].length= sizeof(VAL_DOUBLE(v)); break; case DB_STRING: binds[i].buffer_type= MYSQL_TYPE_STRING; binds[i].buffer= (char*)VAL_STRING(v); *binds[i].length= strlen(VAL_STRING(v)); break; case DB_STR: binds[i].buffer_type= MYSQL_TYPE_STRING; binds[i].buffer= VAL_STR(v).s; *binds[i].length= VAL_STR(v).len; break; case DB_DATETIME: binds[i].buffer_type= MYSQL_TYPE_DATETIME; t = localtime( &VAL_TIME(v) ); mt = (MYSQL_TIME*)binds[i].buffer; mt->year = 1900 + t->tm_year; mt->month = (t->tm_mon)+1; mt->day = t->tm_mday; mt->hour = t->tm_hour; mt->minute = t->tm_min; mt->second = t->tm_sec; *binds[i].length= sizeof(MYSQL_TIME); break; case DB_BLOB: binds[i].buffer_type= MYSQL_TYPE_BLOB; binds[i].buffer= VAL_BLOB(v).s; *binds[i].length= VAL_BLOB(v).len; break; default: LM_ERR("unknown data type (%d)\n",VAL_TYPE(v)); return -9; } LM_DBG("added val (%d): len=%ld; type=%d; is_null=%d\n", i, *(binds[i].length), binds[i].buffer_type, *(binds[i].is_null)); return 0; }
static int sync_dlg_db_mem(void) { db_res_t * res; db_val_t * values; db_row_t * rows; struct dlg_entry *d_entry; struct dlg_cell *it,*known_dlg,*dlg=NULL; int i, nr_rows,callee_leg_idx,next_id,db_timeout; int no_rows = 10; unsigned int db_caller_cseq,db_callee_cseq,dlg_caller_cseq,dlg_callee_cseq; struct socket_info *caller_sock,*callee_sock; str callid, from_uri, to_uri, from_tag, to_tag; str cseq1,cseq2,contact1,contact2,rroute1,rroute2,mangled_fu,mangled_tu; res = 0; if((nr_rows = select_entire_dialog_table(&res,&no_rows)) < 0) goto error; nr_rows = RES_ROW_N(res); do { LM_DBG("loading information from database for %i dialogs\n", nr_rows); rows = RES_ROWS(res); /* for every row---dialog */ for(i=0; i<nr_rows; i++){ values = ROW_VALUES(rows + i); if (VAL_NULL(values) || VAL_NULL(values+1)) { LM_ERR("columns %.*s or/and %.*s cannot be null -> skipping\n", h_entry_column.len, h_entry_column.s, h_id_column.len, h_id_column.s); continue; } if (VAL_NULL(values+7) || VAL_NULL(values+8)) { LM_ERR("columns %.*s or/and %.*s cannot be null -> skipping\n", start_time_column.len, start_time_column.s, state_column.len, state_column.s); continue; } if ( VAL_INT(values+8) == DLG_STATE_DELETED ) { LM_DBG("dialog already terminated -> skipping\n"); continue; } /*restore the dialog info*/ GET_STR_VALUE(callid, values, 2, 1, 0); GET_STR_VALUE(from_tag, values, 4, 1, 0); GET_STR_VALUE(to_tag, values, 6, 1, 1); /* TODO - check about hash resize ? maybe hash was lowered & we overflow the hash */ known_dlg = 0; d_entry = &(d_table->entries[VAL_INT(values)]); for (it=d_entry->first;it;it=it->next) if (it->callid.len == callid.len && it->legs[DLG_CALLER_LEG].tag.len == from_tag.len && memcmp(it->callid.s,callid.s,callid.len)==0 && memcmp(it->legs[DLG_CALLER_LEG].tag.s,from_tag.s,from_tag.len)==0) { /* callid & ftag match */ callee_leg_idx = callee_idx(it); if (it->legs[callee_leg_idx].tag.len == to_tag.len && memcmp(it->legs[callee_leg_idx].tag.s,to_tag.s,to_tag.len)==0) { /* full dlg match */ known_dlg = it; break; } } if (known_dlg == 0) { LM_DBG("First seen dialog - load all stuff - callid = [%.*s]\n",callid.len,callid.s); GET_STR_VALUE(from_uri, values, 3, 1, 0); GET_STR_VALUE(to_uri, values, 5, 1, 0); caller_sock = create_socket_info(values, 16); callee_sock = create_socket_info(values, 17); if (caller_sock == NULL || callee_sock == NULL) { LM_ERR("Dialog in DB doesn't match any listening sockets"); continue; } /* first time we see this dialog - build it from scratch */ if((dlg=build_new_dlg(&callid, &from_uri, &to_uri, &from_tag))==0){ LM_ERR("failed to build new dialog\n"); goto error; } if(dlg->h_entry != VAL_INT(values)){ LM_ERR("inconsistent hash data in the dialog database: " "you may have restarted opensips using a different " "hash_size: please erase %.*s database and restart\n", dialog_table_name.len, dialog_table_name.s); shm_free(dlg); goto error; } /*link the dialog*/ link_dlg(dlg, 0); dlg->h_id = VAL_INT(values+1); next_id = d_table->entries[dlg->h_entry].next_id; d_table->entries[dlg->h_entry].next_id = (next_id < dlg->h_id) ? (dlg->h_id+1) : next_id; dlg->start_ts = VAL_INT(values+7); dlg->state = VAL_INT(values+8); if (dlg->state==DLG_STATE_CONFIRMED_NA || dlg->state==DLG_STATE_CONFIRMED) { if_update_stat(dlg_enable_stats, active_dlgs, 1); } else if (dlg->state==DLG_STATE_EARLY) { if_update_stat(dlg_enable_stats, early_dlgs, 1); } GET_STR_VALUE(cseq1, values, 10 , 1, 1); GET_STR_VALUE(cseq2, values, 11 , 1, 1); GET_STR_VALUE(rroute1, values, 12, 0, 0); GET_STR_VALUE(rroute2, values, 13, 0, 0); GET_STR_VALUE(contact1, values, 14, 0, 1); GET_STR_VALUE(contact2, values, 15, 0, 1); GET_STR_VALUE(mangled_fu, values, 24,0,1); GET_STR_VALUE(mangled_tu, values, 25,0,1); /* add the 2 legs */ if ( (dlg_add_leg_info( dlg, &from_tag, &rroute1, &contact1, &cseq1, caller_sock,0,0)!=0) || (dlg_add_leg_info( dlg, &to_tag, &rroute2, &contact2, &cseq2, callee_sock,&mangled_fu,&mangled_tu)!=0) ) { LM_ERR("dlg_set_leg_info failed\n"); /* destroy the dialog */ unref_dlg(dlg,1); continue; } dlg->legs_no[DLG_LEG_200OK] = DLG_FIRST_CALLEE_LEG; /* script variables */ if (!VAL_NULL(values+18)) read_dialog_vars( VAL_STR(values+18).s, VAL_STR(values+18).len, dlg); /* profiles */ if (!VAL_NULL(values+19)) read_dialog_profiles( VAL_STR(values+19).s, strlen(VAL_STR(values+19).s), dlg,0); /* script flags */ if (!VAL_NULL(values+20)) { dlg->user_flags = VAL_INT(values+20); } /* top hiding */ dlg->flags = VAL_INT(values+23); if (dlg_db_mode==DB_MODE_SHUTDOWN) dlg->flags |= DLG_FLAG_NEW; /* calculcate timeout */ dlg->tl.timeout = (unsigned int)(VAL_INT(values+9)) + get_ticks(); if (dlg->tl.timeout<=(unsigned int)time(0)) dlg->tl.timeout = 0; else dlg->tl.timeout -= (unsigned int)time(0); /* restore the timer values */ if (0 != insert_dlg_timer( &(dlg->tl), (int)dlg->tl.timeout )) { LM_CRIT("Unable to insert dlg %p [%u:%u] " "with clid '%.*s' and tags '%.*s' '%.*s'\n", dlg, dlg->h_entry, dlg->h_id, dlg->callid.len, dlg->callid.s, dlg->legs[DLG_CALLER_LEG].tag.len, dlg->legs[DLG_CALLER_LEG].tag.s, dlg->legs[callee_idx(dlg)].tag.len, ZSW(dlg->legs[callee_idx(dlg)].tag.s)); /* destroy the dialog */ unref_dlg(dlg,1); continue; } /* reference the dialog as kept in the timer list */ ref_dlg(dlg,1); LM_DBG("current dialog timeout is %u\n", dlg->tl.timeout); dlg->lifetime = 0; dlg->legs[DLG_CALLER_LEG].last_gen_cseq = (unsigned int)(VAL_INT(values+21)); dlg->legs[callee_idx(dlg)].last_gen_cseq = (unsigned int)(VAL_INT(values+22)); if (dlg->flags & DLG_FLAG_PING_CALLER || dlg->flags & DLG_FLAG_PING_CALLEE) { if (0 != insert_ping_timer(dlg)) LM_CRIT("Unable to insert dlg %p into ping timer\n",dlg); else { /* reference dialog as kept in ping timer list */ ref_dlg(dlg,1); } } } else { /* we already saw this dialog before * check which is the newer version */ if (known_dlg->state > VAL_INT(values+8)) { LM_DBG("mem has a newer state - ignore \n"); /* we know a newer version compared to the DB * ignore it */ goto next_dialog; } else if (known_dlg->state == VAL_INT(values+8)) { LM_DBG("mem has same state as DB \n"); /* same state :-( no way to tell which is newer */ /* play nice and store longest timeout, although not always correct*/ db_timeout = (unsigned int)(VAL_INT(values+9)) + get_ticks(); if (db_timeout<=(unsigned int)time(0)) db_timeout = 0; else db_timeout -= (unsigned int)time(0); if (known_dlg->tl.timeout < db_timeout) known_dlg->tl.timeout = db_timeout; /* check with is newer cseq for caller leg */ if (!VAL_NULL(values+10)) { cseq1.s = VAL_STR(values+10).s; cseq1.len = strlen(cseq1.s); str2int(&cseq1,&db_caller_cseq); str2int(&known_dlg->legs[DLG_CALLER_LEG].r_cseq,&dlg_caller_cseq); /* Is DB cseq newer ? */ if (db_caller_cseq > dlg_caller_cseq) { if (known_dlg->legs[DLG_CALLER_LEG].r_cseq.len < cseq1.len) { known_dlg->legs[DLG_CALLER_LEG].r_cseq.s = shm_realloc(known_dlg->legs[DLG_CALLER_LEG].r_cseq.s,cseq1.len); if (!known_dlg->legs[DLG_CALLER_LEG].r_cseq.s) { LM_ERR("no more shm\n"); goto next_dialog; } } memcpy(known_dlg->legs[DLG_CALLER_LEG].r_cseq.s,cseq1.s,cseq1.len); known_dlg->legs[DLG_CALLER_LEG].r_cseq.len = cseq1.len; } } else { /* DB has a null cseq - just keep * what we have so far */ ; } /* check with is newer cseq for caller leg */ if (!VAL_NULL(values+11)) { cseq2.s = VAL_STR(values+11).s; cseq2.len = strlen(cseq2.s); callee_leg_idx = callee_idx(known_dlg); str2int(&cseq2,&db_callee_cseq); str2int(&known_dlg->legs[callee_leg_idx].r_cseq,&dlg_callee_cseq); /* Is DB cseq newer ? */ if (db_callee_cseq > dlg_callee_cseq) { if (known_dlg->legs[callee_leg_idx].r_cseq.len < cseq2.len) { known_dlg->legs[callee_leg_idx].r_cseq.s = shm_realloc(known_dlg->legs[callee_leg_idx].r_cseq.s,cseq2.len); if (!known_dlg->legs[callee_leg_idx].r_cseq.s) { LM_ERR("no more shm\n"); goto next_dialog; } } memcpy(known_dlg->legs[callee_leg_idx].r_cseq.s,cseq2.s,cseq2.len); known_dlg->legs[callee_leg_idx].r_cseq.len = cseq2.len; } } else { /* DB has a null cseq - just keep * what we have so far */ ; } /* update ping cseqs, whichever is newer */ if (known_dlg->legs[DLG_CALLER_LEG].last_gen_cseq < (unsigned int)(VAL_INT(values+21))) known_dlg->legs[DLG_CALLER_LEG].last_gen_cseq = (unsigned int)(VAL_INT(values+21)); if (known_dlg->legs[callee_idx(known_dlg)].last_gen_cseq < (unsigned int)(VAL_INT(values+22))) known_dlg->legs[callee_idx(known_dlg)].last_gen_cseq = (unsigned int)(VAL_INT(values+22)); /* update script variables * if already found, delete the old ones * and replace with new one */ if (!VAL_NULL(values+18)) read_dialog_vars( VAL_STR(values+18).s, VAL_STR(values+18).len, known_dlg); /* skip flags - keep what we have - anyway can't tell which is new */ /* profiles - do not insert into a profile * is dlg is already in that profile*/ if (!VAL_NULL(values+19)) read_dialog_profiles( VAL_STR(values+19).s, strlen(VAL_STR(values+19).s), known_dlg,1); } else { /* DB has newer state, just update fields from DB */ LM_DBG("DB has newer state \n"); /* set new state */ known_dlg->state = VAL_INT(values+8); /* update timeout */ known_dlg->tl.timeout = (unsigned int)(VAL_INT(values+9)) + get_ticks(); if (known_dlg->tl.timeout<=(unsigned int)time(0)) known_dlg->tl.timeout = 0; else known_dlg->tl.timeout -= (unsigned int)time(0); /* update cseqs */ if (!VAL_NULL(values+10)) { cseq1.s = VAL_STR(values+10).s; cseq1.len = strlen(cseq1.s); if (known_dlg->legs[DLG_CALLER_LEG].r_cseq.len < cseq1.len) { known_dlg->legs[DLG_CALLER_LEG].r_cseq.s = shm_realloc(known_dlg->legs[DLG_CALLER_LEG].r_cseq.s,cseq1.len); if (!known_dlg->legs[DLG_CALLER_LEG].r_cseq.s) { LM_ERR("no more shm\n"); goto next_dialog; } } memcpy(known_dlg->legs[DLG_CALLER_LEG].r_cseq.s,cseq1.s,cseq1.len); known_dlg->legs[DLG_CALLER_LEG].r_cseq.len = cseq1.len; } if (!VAL_NULL(values+11)) { cseq2.s = VAL_STR(values+11).s; cseq2.len = strlen(cseq1.s); callee_leg_idx = callee_idx(known_dlg); if (known_dlg->legs[callee_leg_idx].r_cseq.len < cseq2.len) { known_dlg->legs[callee_leg_idx].r_cseq.s = shm_realloc(known_dlg->legs[callee_leg_idx].r_cseq.s,cseq2.len); if (!known_dlg->legs[callee_leg_idx].r_cseq.s) { LM_ERR("no more shm\n"); goto next_dialog; } } memcpy(known_dlg->legs[callee_leg_idx].r_cseq.s,cseq2.s,cseq2.len); known_dlg->legs[callee_leg_idx].r_cseq.len = cseq2.len; } /* update ping cseqs */ known_dlg->legs[DLG_CALLER_LEG].last_gen_cseq = (unsigned int)(VAL_INT(values+21)); known_dlg->legs[callee_idx(known_dlg)].last_gen_cseq = (unsigned int)(VAL_INT(values+22)); /* update flags */ known_dlg->flags = VAL_INT(values+23); if (dlg_db_mode==DB_MODE_SHUTDOWN) known_dlg->flags |= DLG_FLAG_NEW; /* update script variables * if already found, delete the old one * and replace with new one */ if (!VAL_NULL(values+18)) read_dialog_vars( VAL_STR(values+18).s, VAL_STR(values+18).len, known_dlg); /* profiles - do not insert into a profile * is dlg is already in that profile*/ if (!VAL_NULL(values+19)) read_dialog_profiles( VAL_STR(values+19).s, strlen(VAL_STR(values+19).s), known_dlg,1); } } next_dialog: ; } /* any more data to be fetched ?*/ if (DB_CAPABILITY(dialog_dbf, DB_CAP_FETCH)) { if (dialog_dbf.fetch_result( dialog_db_handle, &res,no_rows) < 0) { LM_ERR("fetching more rows failed\n"); goto error; } nr_rows = RES_ROW_N(res); } else { nr_rows = 0; } }while (nr_rows>0); return 0; error: return -1; }
/* * Convert str to db value, does not copy strings */ int db_sqlite_str2val(const db_type_t _t, db_val_t* _v, const char* _s, const int _l) { static str dummy_string = {"", 0}; if (!_v) { LM_ERR("invalid parameter value\n"); return -1; } if (!_s) { memset(_v, 0, sizeof(db_val_t)); /* Initialize the string pointers to a dummy empty * string so that we do not crash when the NULL flag * is set but the module does not check it properly */ VAL_STRING(_v) = dummy_string.s; VAL_STR(_v) = dummy_string; VAL_BLOB(_v) = dummy_string; VAL_TYPE(_v) = _t; VAL_NULL(_v) = 1; return 0; } VAL_NULL(_v) = 0; switch(_t) { case DB_INT: LM_DBG("converting INT [%s]\n", _s); if (db_str2int(_s, &VAL_INT(_v)) < 0) { LM_ERR("error while converting integer value from string\n"); return -2; } else { VAL_TYPE(_v) = DB_INT; return 0; } break; case DB_BIGINT: LM_DBG("converting INT BIG[%s]\n", _s); if (db_str2bigint(_s, &VAL_BIGINT(_v)) < 0) { LM_ERR("error while converting big integer value from string\n"); return -2; } else { VAL_TYPE(_v) = DB_BIGINT; return 0; } break; case DB_BITMAP: LM_DBG("converting BITMAP [%s]\n", _s); if (db_str2int(_s, &VAL_INT(_v)) < 0) { LM_ERR("error while converting bitmap value from string\n"); return -3; } else { VAL_TYPE(_v) = DB_BITMAP; return 0; } break; case DB_DOUBLE: LM_DBG("converting DOUBLE [%s]\n", _s); if (db_str2double(_s, &VAL_DOUBLE(_v)) < 0) { LM_ERR("error while converting double value from string\n"); return -4; } else { VAL_TYPE(_v) = DB_DOUBLE; return 0; } break; case DB_STRING: LM_DBG("converting STRING [%s]\n", _s); VAL_STRING(_v) = _s; VAL_TYPE(_v) = DB_STRING; return 0; case DB_STR: LM_DBG("converting STR [%.*s]\n", _l, _s); VAL_STR(_v).s = (char*)_s; VAL_STR(_v).len = _l; VAL_TYPE(_v) = DB_STR; return 0; case DB_DATETIME: LM_DBG("converting DATETIME [%s]\n", _s); if (db_str2time(_s, &VAL_TIME(_v)) < 0) { LM_ERR("error while converting datetime value from string\n"); return -5; } else { VAL_TYPE(_v) = DB_DATETIME; return 0; } break; case DB_BLOB: LM_DBG("converting BLOB [%.*s]\n", _l, _s); VAL_BLOB(_v).s = (char*)_s; VAL_BLOB(_v).len = _l; VAL_TYPE(_v) = DB_BLOB; return 0; } return -6; }
/* * Convert data fron db format to internal format */ static int convert_row(db1_res_t* _res, db_row_t* _r, dmap_t* _d) { unsigned i, n = RES_COL_N(_res); ROW_N(_r) = n; ROW_VALUES(_r) = (db_val_t*)pkg_malloc(sizeof(db_val_t) * n); if (!ROW_VALUES(_r)) { nomem: LM_ERR("no private memory left\n"); return -1; } memset(ROW_VALUES(_r), 0, sizeof(db_val_t) * n); for (i = 0; i < n; i++) { static const str dummy_string = {"", 0}; db_val_t* v = &ROW_VALUES(_r)[i]; db_type_t t = RES_TYPES(_res)[i]; if (_d->ind[i] == -1) { /* Initialize the string pointers to a dummy empty * string so that we do not crash when the NULL flag * is set but the module does not check it properly */ VAL_STRING(v) = dummy_string.s; VAL_STR(v) = dummy_string; VAL_BLOB(v) = dummy_string; VAL_TYPE(v) = t; VAL_NULL(v) = 1; continue; } if (_d->ind[i]) LM_WARN("truncated value in DB\n"); VAL_TYPE(v) = t; switch (t) { case DB1_INT: VAL_INT(v) = *_d->pv[i].i; break; case DB1_BIGINT: LM_ERR("BIGINT not supported"); return -1; case DB1_BITMAP: VAL_BITMAP(v) = *_d->pv[i].i; break; case DB1_DOUBLE: VAL_DOUBLE(v) = *_d->pv[i].f; break; case DB1_DATETIME: { struct tm tm; memset(&tm, 0, sizeof(tm)); OCIDateGetTime(_d->pv[i].o, &tm.tm_hour, &tm.tm_min, &tm.tm_sec); OCIDateGetDate(_d->pv[i].o, &tm.tm_year, &tm.tm_mon, &tm.tm_mday); if (tm.tm_mon) --tm.tm_mon; if (tm.tm_year >= 1900) tm.tm_year -= 1900; VAL_TIME(v) = mktime(&tm); } break; case DB1_STR: case DB1_BLOB: case DB1_STRING: { size_t len = _d->len[i]; char *pstr = pkg_malloc(len+1); if (!pstr) goto nomem; memcpy(pstr, _d->pv[i].c, len); pstr[len] = '\0'; VAL_FREE(v) = 1; if (t == DB1_STR) { VAL_STR(v).s = pstr; VAL_STR(v).len = len; } else if (t == DB1_BLOB) { VAL_BLOB(v).s = pstr; VAL_BLOB(v).len = len; } else { VAL_STRING(v) = pstr; } } break; default: LM_ERR("unknown type mapping (%u)\n", t); return -2; } } return 0; }
/*compile the expressions, and if ok, build the rule */ dpl_node_t * build_rule(db_val_t * values) { pcre * match_comp, *subst_comp; struct subst_expr * repl_comp; dpl_node_t * new_rule; str match_exp, subst_exp, repl_exp, attrs; int matchop; int namecount; matchop = VAL_INT(values+2); if((matchop != REGEX_OP) && (matchop!=EQUAL_OP)){ LM_ERR("invalid value for match operator\n"); return NULL; } match_comp = subst_comp =0; repl_comp = 0; new_rule = 0; GET_STR_VALUE(match_exp, values, 3); if(matchop == REGEX_OP){ match_comp = wrap_pcre_compile(match_exp.s); if(!match_comp){ LM_ERR("failed to compile match expression %.*s\n", match_exp.len, match_exp.s); goto err; } } LM_DBG("building subst rule\n"); GET_STR_VALUE(subst_exp, values, 5); if(subst_exp.s && subst_exp.len){ /* subst regexp */ subst_comp = wrap_pcre_compile(subst_exp.s); if(subst_comp == NULL){ LM_ERR("failed to compile subst expression\n"); goto err; } } /* replace exp */ GET_STR_VALUE(repl_exp, values, 6); if(repl_exp.len && repl_exp.s){ repl_comp = repl_exp_parse(repl_exp); if(!repl_comp){ LM_ERR("failed to compile replacing expression %.*s\n", repl_exp.len, repl_exp.s); goto err; } } pcre_fullinfo( subst_comp, /* the compiled pattern */ NULL, /* no extra data - we didn't study the pattern */ PCRE_INFO_CAPTURECOUNT, /* number of named substrings */ &namecount); /* where to put the answer */ LM_DBG("references:%d , max:%d\n",namecount, repl_comp?repl_comp->max_pmatch:0); if ( (repl_comp!=NULL) && (namecount<repl_comp->max_pmatch) && (repl_comp->max_pmatch!=0) ){ LM_ERR("repl_exp uses a non existing subexpression\n"); goto err; } new_rule = (dpl_node_t *)shm_malloc(sizeof(dpl_node_t)); if(!new_rule){ LM_ERR("out of shm memory(new_rule)\n"); goto err; } memset(new_rule, 0, sizeof(dpl_node_t)); if(str_to_shm(match_exp, &new_rule->match_exp)!=0) goto err; if (subst_comp) if(str_to_shm(subst_exp, &new_rule->subst_exp)!=0) goto err; if (repl_comp) if(str_to_shm(repl_exp, &new_rule->repl_exp)!=0) goto err; /*set the rest of the rule fields*/ new_rule->dpid = VAL_INT(values); new_rule->pr = VAL_INT(values+1); new_rule->matchlen = VAL_INT(values+4); new_rule->matchop = matchop; GET_STR_VALUE(attrs, values, 7); if(str_to_shm(attrs, &new_rule->attrs)!=0) goto err; LM_DBG("attrs are %.*s\n", new_rule->attrs.len, new_rule->attrs.s); if (match_comp) new_rule->match_comp = match_comp; if (subst_comp) new_rule->subst_comp = subst_comp; if (repl_comp) new_rule->repl_comp = repl_comp; return new_rule; err: if(subst_comp) wrap_pcre_free(subst_comp); if(repl_comp) repl_expr_free(repl_comp); if(new_rule) destroy_rule(new_rule); return NULL; }
/* select data from emergency_routing and put in memory * coluns keys: srid(selectiveRoutingID), resn(routingESN) and npa. * coluns translate: esgwri */ int get_db_routing(str table_name, rw_lock_t *ref_lock ){ db_key_t query_cols[] = {&id_col, &srid_col, &resn_col, &npa_col, &esgwri_col}; db_res_t * res; db_val_t * values; db_row_t * rows; str esgwri; str SRID; int RESN; int NPA; int nr_rows, i, size, id; struct esrn_routing *esrn_cell, *old_list, *it, *aux, *new_list; struct esrn_routing *init_esrn = NULL; db_funcs.use_table(db_con, &table_name); /* select value from routing table * the keys of routing table: selectiveRoutingID, routingESN, npa * the result of routing lookup: esgwri */ if (db_funcs.query(db_con, 0, 0, 0, query_cols, 0, 5, 0, &res) != 0) { LM_ERR("Failure to issue query\n"); return -1; } nr_rows = RES_ROW_N(res); rows = RES_ROWS(res); new_list = NULL; LM_DBG("NUMBER OF LINES ROUTING %d \n", nr_rows); for (i = 0; i < nr_rows; i++) { values = ROW_VALUES(rows + i); if (VAL_NULL(values) || (VAL_TYPE(values) != DB_INT)) { LM_ERR("Invalid value returned 1\n"); goto end; } id = VAL_INT(values); if (VAL_NULL(values + 1) || (VAL_TYPE(values + 1) != DB_STR && VAL_TYPE(values + 1) != DB_STRING)) { LM_ERR("Invalid translated returned 2\n"); goto end; } if (VAL_TYPE(values + 1) == DB_STR) { SRID = VAL_STR(values + 1); } else { SRID.s = (char*) VAL_STRING(values + 1); SRID.len = strlen(SRID.s); } if (VAL_NULL(values + 2) || (VAL_TYPE(values + 2) != DB_INT)) { LM_ERR("Invalid translated returned 3\n"); goto end; } RESN = VAL_INT(values + 2); if (VAL_NULL(values + 3) || (VAL_TYPE(values + 3) != DB_INT)) { LM_ERR("Invalid translated returned 4\n"); goto end; } NPA = VAL_INT(values + 3); if (VAL_NULL(values + 4) || (VAL_TYPE(values + 4) != DB_STR && VAL_TYPE(values + 4) != DB_STRING)) { LM_ERR("Invalid translated returned 5\n"); goto end; } if (VAL_TYPE(values + 4) == DB_STR) { esgwri = VAL_STR(values + 4); } else { esgwri.s = (char*) VAL_STRING(values + 4); esgwri.len = strlen(esgwri.s); } size = sizeof (struct esrn_routing)+SRID.len + esgwri.len; esrn_cell = shm_malloc(size); if (!esrn_cell) { LM_ERR("no more shm\n"); goto end; } memset(esrn_cell, 0, size); esrn_cell->srid.len = SRID.len; esrn_cell->srid.s = (char *) (esrn_cell + 1); memcpy(esrn_cell->srid.s, SRID.s, SRID.len); esrn_cell->resn = RESN; esrn_cell->npa = NPA; esrn_cell->esgwri.len = esgwri.len; esrn_cell->esgwri.s = (char *) (esrn_cell + 1) + SRID.len; memcpy(esrn_cell->esgwri.s, esgwri.s, esgwri.len); LM_DBG("-SRID %.*s \n", SRID.len, SRID.s); LM_DBG("-RESN %d \n", RESN); LM_DBG("-NPA %d \n", NPA); LM_DBG("-esgwri %.*s \n", esgwri.len, esgwri.s); if (new_list != NULL) { new_list->next = esrn_cell; new_list = esrn_cell; } else { new_list = esrn_cell; init_esrn = new_list; } } new_list = init_esrn; lock_start_write(ref_lock); old_list = *db_esrn_esgwri; *db_esrn_esgwri = init_esrn; lock_stop_write(ref_lock); it = old_list; while (it) { aux = it; it = it->next; shm_free(aux); } end: db_funcs.free_result(db_con, res); return 1; }
/* * Reload addr table to new hash table and when done, make new hash table * current one. */ int reload_address_table(void) { db_key_t cols[5]; db1_res_t* res = NULL; db_row_t* row; db_val_t* val; struct addr_list **new_hash_table; struct subnet *new_subnet_table; struct domain_name_list **new_domain_name_table; int i; unsigned int gid; unsigned int port; unsigned int mask; str ips; ip_addr_t *ipa; char *tagv; cols[0] = &grp_col; cols[1] = &ip_addr_col; cols[2] = &mask_col; cols[3] = &port_col; cols[4] = &tag_col; if (perm_dbf.use_table(db_handle, &address_table) < 0) { LM_ERR("failed to use table\n"); return -1; } if (perm_dbf.query(db_handle, NULL, 0, NULL, cols, 0, 5, 0, &res) < 0) { LM_ERR("failed to query database\n"); return -1; } /* Choose new hash table and free its old contents */ if (*addr_hash_table == addr_hash_table_1) { empty_addr_hash_table(addr_hash_table_2); new_hash_table = addr_hash_table_2; } else { empty_addr_hash_table(addr_hash_table_1); new_hash_table = addr_hash_table_1; } /* Choose new subnet table */ if (*subnet_table == subnet_table_1) { empty_subnet_table(subnet_table_2); new_subnet_table = subnet_table_2; } else { empty_subnet_table(subnet_table_1); new_subnet_table = subnet_table_1; } /* Choose new domain name table */ if (*domain_list_table == domain_list_table_1) { empty_domain_name_table(domain_list_table_2); new_domain_name_table = domain_list_table_2; } else { empty_domain_name_table(domain_list_table_1); new_domain_name_table = domain_list_table_1; } row = RES_ROWS(res); LM_DBG("Number of rows in address table: %d\n", RES_ROW_N(res)); for (i = 0; i < RES_ROW_N(res); i++) { val = ROW_VALUES(row + i); /* basic checks to db values */ if (ROW_N(row + i) != 5) { LM_DBG("failure during checks of db address table: Colums %d - expected 5\n", ROW_N(row + i)); goto dberror; } if ((VAL_TYPE(val) != DB1_INT) || VAL_NULL(val) || (VAL_INT(val) <= 0)) { LM_DBG("failure during checks of database value 1 (group) in address table\n"); goto dberror; } if ((VAL_TYPE(val + 1) != DB1_STRING) && (VAL_TYPE(val + 1) != DB1_STR)) { LM_DBG("failure during checks of database value 2 (IP address) in address table - not a string value\n"); goto dberror; } if (VAL_NULL(val + 1)) { LM_DBG("failure during checks of database value 2 (IP address) in address table - NULL value not permitted\n"); goto dberror; } if ((VAL_TYPE(val + 2) != DB1_INT) || VAL_NULL(val + 2)) { LM_DBG("failure during checks of database value 3 (subnet size/CIDR) in address table\n"); goto dberror; } if ((VAL_TYPE(val + 3) != DB1_INT) || VAL_NULL(val + 3)) { LM_DBG("failure during checks of database value 4 (port) in address table\n"); goto dberror; } gid = VAL_UINT(val); ips.s = (char *)VAL_STRING(val + 1); ips.len = strlen(ips.s); mask = VAL_UINT(val + 2); port = VAL_UINT(val + 3); tagv = VAL_NULL(val + 4)?NULL:(char *)VAL_STRING(val + 4); ipa = strtoipX(&ips); if ( ipa==NULL ) { LM_DBG("Domain name: %.*s\n", ips.len, ips.s); // goto dberror; } else { if(ipa->af == AF_INET6) { if((int)mask<0 || mask>128) { LM_DBG("failure during IP mask check for v6\n"); goto dberror; } } else { if((int)mask<0 || mask>32) { LM_DBG("failure during IP mask check for v4\n"); goto dberror; } } } if ( ipa ) { if ( (ipa->af==AF_INET6 && mask==128) || (ipa->af==AF_INET && mask==32) ) { if (addr_hash_table_insert(new_hash_table, gid, ipa, port, tagv) == -1) { LM_ERR("hash table problem\n"); perm_dbf.free_result(db_handle, res); return -1; } LM_DBG("Tuple <%u, %s, %u> inserted into address hash table\n", gid, ips.s, port); } else { if (subnet_table_insert(new_subnet_table, gid, ipa, mask, port, tagv) == -1) { LM_ERR("subnet table problem\n"); perm_dbf.free_result(db_handle, res); return -1; } LM_DBG("Tuple <%u, %s, %u, %u> inserted into subnet table\n", gid, ips.s, port, mask); } } else { if (domain_name_table_insert(new_domain_name_table, gid, &ips, port, tagv) == -1) { LM_ERR("domain name table problem\n"); perm_dbf.free_result(db_handle, res); return -1; } LM_DBG("Tuple <%u, %s, %u> inserted into domain name table\n", gid, ips.s, port); } } perm_dbf.free_result(db_handle, res); *addr_hash_table = new_hash_table; *subnet_table = new_subnet_table; *domain_list_table = new_domain_name_table; LM_DBG("address table reloaded successfully.\n"); return 1; dberror: LM_ERR("database problem - invalid record\n"); perm_dbf.free_result(db_handle, res); return -1; }
static void timer_send_full_state_notifies(int round) { db_key_t query_cols[1], result_cols[22], update_cols[1]; db_val_t query_vals[1], update_vals[1], *values; db_row_t *rows; db1_res_t *result = NULL; int n_result_cols = 0, i; int pres_uri_col, tuser_col, tdomain_col, fuser_col, fdomain_col; int wuser_col, wdomain_col, callid_col, to_tag_col, from_tag_col; int sockinfo_col, lcontact_col, contact_col, rroute_col, event_id_col; int reason_col, event_col, lcseq_col, rcseq_col, status_col; int version_col, expires_col; subs_t sub; str ev_sname; event_t parsed_event; xmlDocPtr doc = NULL; xmlNodePtr service_node = NULL; int now = (int)time(NULL); db_query_f query_fn = rls_dbf.query_lock ? rls_dbf.query_lock : rls_dbf.query; query_cols[0] = &str_updated_col; query_vals[0].type = DB1_INT; query_vals[0].nul = 0; query_vals[0].val.int_val = round; result_cols[pres_uri_col = n_result_cols++] = &str_presentity_uri_col; result_cols[tuser_col = n_result_cols++] = &str_to_user_col; result_cols[tdomain_col = n_result_cols++] = &str_to_domain_col; result_cols[fuser_col = n_result_cols++] = &str_from_user_col; result_cols[fdomain_col = n_result_cols++] = &str_from_domain_col; result_cols[wuser_col = n_result_cols++] = &str_watcher_username_col; result_cols[wdomain_col = n_result_cols++] = &str_watcher_domain_col; result_cols[callid_col = n_result_cols++] = &str_callid_col; result_cols[to_tag_col = n_result_cols++] = &str_to_tag_col; result_cols[from_tag_col = n_result_cols++] = &str_from_tag_col; result_cols[sockinfo_col = n_result_cols++] = &str_socket_info_col; result_cols[lcontact_col = n_result_cols++] = &str_local_contact_col; result_cols[contact_col = n_result_cols++] = &str_contact_col; result_cols[rroute_col = n_result_cols++] = &str_record_route_col; result_cols[event_id_col = n_result_cols++] = &str_event_id_col; result_cols[reason_col = n_result_cols++] = &str_reason_col; result_cols[event_col = n_result_cols++] = &str_event_col; result_cols[lcseq_col = n_result_cols++] = &str_local_cseq_col; result_cols[rcseq_col = n_result_cols++] = &str_remote_cseq_col; result_cols[status_col = n_result_cols++] = &str_status_col; result_cols[version_col = n_result_cols++] = &str_version_col; result_cols[expires_col = n_result_cols++] = &str_expires_col; update_cols[0] = &str_updated_col; update_vals[0].type = DB1_INT; update_vals[0].nul = 0; update_vals[0].val.int_val = NO_UPDATE_TYPE; if (rls_dbf.use_table(rls_db, &rlsubs_table) < 0) { LM_ERR("use table failed\n"); goto done; } if (dbmode == RLS_DB_ONLY && rls_dbf.start_transaction) { if (rls_dbf.start_transaction(rls_db, DB_LOCKING_WRITE) < 0) { LM_ERR("in start_transaction\n"); goto done; } } /* Step 1: Find rls_watchers that require full-state notification */ if (query_fn(rls_db, query_cols, 0, query_vals, result_cols, 1, n_result_cols, 0, &result) < 0) { LM_ERR("in sql query\n"); goto done; } if(result== NULL || result->n<= 0) goto done; /* Step 2: Reset the update flag so we do not full-state notify these watchers again */ if(rls_dbf.update(rls_db, query_cols, 0, query_vals, update_cols, update_vals, 1, 1)< 0) { LM_ERR("in sql update\n"); goto done; } if (dbmode == RLS_DB_ONLY && rls_dbf.end_transaction) { if (rls_dbf.end_transaction(rls_db) < 0) { LM_ERR("in end_transaction\n"); goto done; } } /* Step 3: Full-state notify each watcher we found */ rows = RES_ROWS(result); for (i = 0; i < RES_ROW_N(result); i++) { memset(&sub, 0, sizeof(subs_t)); values = ROW_VALUES(&rows[i]); EXTRACT_STRING(sub.pres_uri, VAL_STRING(&values[pres_uri_col])); EXTRACT_STRING(sub.to_user, VAL_STRING(&values[tuser_col])); EXTRACT_STRING(sub.to_domain, VAL_STRING(&values[tdomain_col])); EXTRACT_STRING(sub.from_user, VAL_STRING(&values[fuser_col])); EXTRACT_STRING(sub.from_domain, VAL_STRING(&values[fdomain_col])); EXTRACT_STRING(sub.watcher_user, VAL_STRING(&values[wuser_col])); EXTRACT_STRING(sub.watcher_domain, VAL_STRING(&values[wdomain_col])); EXTRACT_STRING(sub.callid, VAL_STRING(&values[callid_col])); EXTRACT_STRING(sub.to_tag, VAL_STRING(&values[to_tag_col])); EXTRACT_STRING(sub.from_tag, VAL_STRING(&values[from_tag_col])); EXTRACT_STRING(sub.sockinfo_str, VAL_STRING(&values[sockinfo_col])); EXTRACT_STRING(sub.local_contact, VAL_STRING(&values[lcontact_col])); EXTRACT_STRING(sub.contact, VAL_STRING(&values[contact_col])); EXTRACT_STRING(sub.record_route, VAL_STRING(&values[rroute_col])); EXTRACT_STRING(sub.event_id, VAL_STRING(&values[event_id_col])); EXTRACT_STRING(sub.reason, VAL_STRING(&values[reason_col])); EXTRACT_STRING(ev_sname, VAL_STRING(&values[event_col])); sub.event = pres_contains_event(&ev_sname, &parsed_event); if (sub.event == NULL) { LM_ERR("event not found and set to NULL\n"); goto done; } sub.local_cseq = VAL_INT(&values[lcseq_col]); sub.remote_cseq = VAL_INT(&values[rcseq_col]); sub.status = VAL_INT(&values[status_col]); sub.version = VAL_INT(&values[version_col]); if (VAL_INT(&values[expires_col]) > now + rls_expires_offset) { sub.expires = VAL_INT(&values[expires_col]) - now; if (rls_get_service_list(&sub.pres_uri, &sub.watcher_user, &sub.watcher_domain, &service_node, &doc) < 0) { LM_ERR("failed getting resource list\n"); goto done; } if (doc == NULL) { LM_WARN("no document returned for uri <%.*s>\n", sub.pres_uri.len, sub.pres_uri.s); goto done; } if (send_full_notify(&sub, service_node, &sub.pres_uri, 0) < 0) { LM_ERR("failed sending full state notify\n"); goto done; } xmlFreeDoc(doc); doc = NULL; } else { sub.expires = 0; rls_send_notify(&sub, NULL, NULL, NULL); delete_rlsdb(&sub.callid, &sub.to_tag, &sub.from_tag); } } done: if (result != NULL) rls_dbf.free_result(rls_db, result); if (doc != NULL) xmlFreeDoc(doc); if (dbmode == RLS_DB_ONLY && rls_dbf.abort_transaction) { if (rls_dbf.abort_transaction(rls_db) < 0) LM_ERR("in abort_transaction\n"); } }
/* * Used when converting result from a query */ int bdb_val2str(db_val_t* _v, char* _s, int* _len) { int l; if (VAL_NULL(_v)) { *_len = snprintf(_s, *_len, "NULL"); return 0; } switch(VAL_TYPE(_v)) { case DB_INT: if (db_int2str(VAL_INT(_v), _s, _len) < 0) { LM_ERR("Error while converting int to string\n"); return -2; } else { LM_DBG("Converted int to string\n"); return 0; } break; case DB_BIGINT: if (db_bigint2str(VAL_BIGINT(_v), _s, _len) < 0) { LM_ERR("Error while converting bigint to string\n"); return -2; } else { LM_DBG("Converted bigint to string\n"); return 0; } break; case DB_BITMAP: if (db_int2str(VAL_INT(_v), _s, _len) < 0) { LM_ERR("Error while converting bitmap to string\n"); return -3; } else { LM_DBG("Converted bitmap to string\n"); return 0; } break; case DB_DOUBLE: if (db_double2str(VAL_DOUBLE(_v), _s, _len) < 0) { LM_ERR("Error while converting double to string\n"); return -3; } else { LM_DBG("Converted double to string\n"); return 0; } break; case DB_STRING: l = strlen(VAL_STRING(_v)); if (*_len < l ) { LM_ERR("Destination buffer too short for string\n"); return -4; } else { LM_DBG("Converted string to string\n"); strncpy(_s, VAL_STRING(_v) , l); _s[l] = 0; *_len = l+1; /* count the 0 also */ return 0; } break; case DB_STR: l = VAL_STR(_v).len; if (*_len < l) { LM_ERR("Destination buffer too short for str\n"); return -5; } else { LM_DBG("Converted str to string\n"); strncpy(_s, VAL_STR(_v).s , l); *_len = l; return 0; } break; case DB_DATETIME: if (bdb_time2str(VAL_TIME(_v), _s, _len) < 0) { LM_ERR("Error while converting time_t to string\n"); return -6; } else { LM_DBG("Converted time_t to string\n"); return 0; } break; case DB_BLOB: l = VAL_BLOB(_v).len; if (*_len < l) { LM_ERR("Destination buffer too short for blob\n"); return -7; } else { strncpy(_s, VAL_BLOB(_v).s , l); LM_DBG("Converting BLOB [%.*s]\n", l,_s); *_len = l; return 0; } break; default: LM_DBG("Unknown data type\n"); return -8; } }
/*compile the expressions, and if ok, build the rule */ dpl_node_t * build_rule(db_val_t * values) { pcre *match_comp, *subst_comp; struct subst_expr *repl_comp; dpl_node_t * new_rule; str match_exp, subst_exp, repl_exp, attrs; int matchop; int cap_cnt=0; matchop = VAL_INT(values+2); if((matchop != DP_REGEX_OP) && (matchop!=DP_EQUAL_OP) && (matchop!=DP_FNMATCH_OP)){ LM_ERR("invalid value for match operator\n"); return NULL; } match_comp = subst_comp =0; repl_comp = 0; new_rule = 0; GET_STR_VALUE(match_exp, values, 3); if(matchop == DP_REGEX_OP){ match_comp = reg_ex_comp(match_exp.s, &cap_cnt); if(!match_comp){ LM_ERR("failed to compile match expression %.*s\n", match_exp.len, match_exp.s); goto err; } } LM_DBG("build_rule\n"); GET_STR_VALUE(repl_exp, values, 6); if(repl_exp.len && repl_exp.s){ repl_comp = repl_exp_parse(repl_exp); if(!repl_comp){ LM_ERR("failed to compile replacing expression %.*s\n", repl_exp.len, repl_exp.s); goto err; } } GET_STR_VALUE(subst_exp, values, 5); if(subst_exp.s && subst_exp.len){ subst_comp = reg_ex_comp(subst_exp.s, &cap_cnt); if(!subst_comp){ LM_ERR("failed to compile subst expression %.*s\n", subst_exp.len, subst_exp.s); goto err; } if (cap_cnt > MAX_REPLACE_WITH) { LM_ERR("subst expression %.*s has too many sub-expressions\n", subst_exp.len, subst_exp.s); goto err; } } if (repl_comp && (cap_cnt < repl_comp->max_pmatch) && (repl_comp->max_pmatch != 0)) { LM_ERR("repl_exp %.*s refers to %d sub-expressions, but " "subst_exp %.*s has only %d\n", repl_exp.len, repl_exp.s, repl_comp->max_pmatch, subst_exp.len, subst_exp.s, cap_cnt); goto err; } new_rule = (dpl_node_t *)shm_malloc(sizeof(dpl_node_t)); if(!new_rule){ LM_ERR("out of shm memory(new_rule)\n"); goto err; } memset(new_rule, 0, sizeof(dpl_node_t)); if(str_to_shm(match_exp, &new_rule->match_exp)!=0) goto err; if(str_to_shm(subst_exp, &new_rule->subst_exp)!=0) goto err; if(str_to_shm(repl_exp, &new_rule->repl_exp)!=0) goto err; /*set the rest of the rule fields*/ new_rule->dpid = VAL_INT(values); new_rule->pr = VAL_INT(values+1); new_rule->matchlen = VAL_INT(values+4); new_rule->matchop = matchop; GET_STR_VALUE(attrs, values, 7); if(str_to_shm(attrs, &new_rule->attrs)!=0) goto err; LM_DBG("attrs are %.*s\n", new_rule->attrs.len, new_rule->attrs.s); new_rule->match_comp = match_comp; new_rule->subst_comp = subst_comp; new_rule->repl_comp = repl_comp; return new_rule; err: if(match_comp) shm_free(match_comp); if(subst_comp) shm_free(subst_comp); if(repl_comp) repl_expr_free(repl_comp); if(new_rule) destroy_rule(new_rule); return NULL; }
/** * Does not copy strings */ int bdb_str2val(db_type_t _t, db_val_t* _v, char* _s, int _l) { static str dummy_string = {"", 0}; if(!_s) { memset(_v, 0, sizeof(db_val_t)); /* Initialize the string pointers to a dummy empty * string so that we do not crash when the NULL flag * is set but the module does not check it properly */ VAL_STRING(_v) = dummy_string.s; VAL_STR(_v) = dummy_string; VAL_BLOB(_v) = dummy_string; VAL_TYPE(_v) = _t; VAL_NULL(_v) = 1; return 0; } VAL_NULL(_v) = 0; switch(_t) { case DB_INT: if (db_str2int(_s, &VAL_INT(_v)) < 0) { LM_ERR("Error while converting INT value from string\n"); return -2; } else { VAL_TYPE(_v) = DB_INT; return 0; } break; case DB_BIGINT: if (db_str2bigint(_s, &VAL_BIGINT(_v)) < 0) { LM_ERR("Error while converting BIGINT value from string\n"); return -2; } else { VAL_TYPE(_v) = DB_BIGINT; return 0; } break; case DB_BITMAP: if (db_str2int(_s, &VAL_INT(_v)) < 0) { LM_ERR("Error while converting BITMAP value from string\n"); return -3; } else { VAL_TYPE(_v) = DB_BITMAP; return 0; } break; case DB_DOUBLE: if (db_str2double(_s, &VAL_DOUBLE(_v)) < 0) { LM_ERR("Error while converting DOUBLE value from string\n"); return -4; } else { VAL_TYPE(_v) = DB_DOUBLE; return 0; } break; case DB_STRING: if( strlen(_s)==4 && !strncasecmp(_s, "NULL", 4) ) VAL_NULL(_v) = 1; else { VAL_STRING(_v) = _s; VAL_TYPE(_v) = DB_STRING; VAL_FREE(_v) = 1; } return 0; case DB_STR: if( strlen(_s)==4 && !strncasecmp(_s, "NULL", 4) ) VAL_NULL(_v) = 1; else { VAL_STR(_v).s = (char*)_s; VAL_STR(_v).len = _l; VAL_TYPE(_v) = DB_STR; VAL_FREE(_v) = 1; } return 0; case DB_DATETIME: if( *_s == '\'') _s++; if (db_str2time(_s, &VAL_TIME(_v)) < 0) { LM_ERR("Error converting datetime\n"); return -5; } else { VAL_TYPE(_v) = DB_DATETIME; return 0; } break; case DB_BLOB: VAL_BLOB(_v).s = _s; VAL_BLOB(_v).len = _l; VAL_TYPE(_v) = DB_BLOB; VAL_FREE(_v) = 1; LM_DBG("got blob len %d\n", _l); return 0; } return -6; }
/* * Insert a row into specified table * h: structure representing database connection * k: key names * v: values of the keys * n: number of key=value pairs */ int flat_db_insert(const db1_con_t* h, const db_key_t* k, const db_val_t* v, const int n) { FILE* f; int i; int l; char *s, *p; if (km_local_timestamp < *km_flat_rotate) { flat_rotate_logs(); km_local_timestamp = *km_flat_rotate; } f = CON_FILE(h); if (!f) { LM_ERR("uninitialized connection\n"); return -1; } for(i = 0; i < n; i++) { switch(VAL_TYPE(v + i)) { case DB1_INT: fprintf(f, "%d", VAL_INT(v + i)); break; case DB1_BIGINT: LM_ERR("BIGINT not supported"); return -1; case DB1_DOUBLE: fprintf(f, "%f", VAL_DOUBLE(v + i)); break; case DB1_STRING: fprintf(f, "%s", VAL_STRING(v + i)); break; case DB1_STR: fprintf(f, "%.*s", VAL_STR(v + i).len, VAL_STR(v + i).s); break; case DB1_DATETIME: fprintf(f, "%u", (unsigned int)VAL_TIME(v + i)); break; case DB1_BLOB: l = VAL_BLOB(v+i).len; s = p = VAL_BLOB(v+i).s; while (l--) { if ( !(isprint((int)*s) && *s != '\\' && *s != '|')) { fprintf(f,"%.*s\\x%02X",(int)(s-p),p,(*s & 0xff)); p = s+1; } ++s; } if (p!=s) fprintf(f,"%.*s",(int)(s-p),p); break; case DB1_BITMAP: fprintf(f, "%u", VAL_BITMAP(v + i)); break; } if (i < (n - 1)) { fprintf(f, "%c", *km_flat_delimiter); } } fprintf(f, "\n"); if (flat_flush) { fflush(f); } return 0; }
/* * Called after val2str to realy binding */ int db_oracle_val2bind(bmap_t* _m, const db_val_t* _v, OCIDate* _o) { if (VAL_NULL(_v)) { _m->addr = NULL; _m->size = 0; _m->type = SQLT_NON; return 0; } switch (VAL_TYPE(_v)) { case DB_INT: _m->addr = (int*)&VAL_INT(_v); _m->size = sizeof(VAL_INT(_v)); _m->type = SQLT_INT; break; case DB_BIGINT: _m->addr = (int*)&VAL_BIGINT(_v); _m->size = sizeof(VAL_BIGINT(_v)); _m->type = SQLT_NUM; break; case DB_BITMAP: _m->addr = (unsigned*)&VAL_BITMAP(_v); _m->size = sizeof(VAL_BITMAP(_v)); _m->type = SQLT_UIN; break; case DB_DOUBLE: _m->addr = (double*)&VAL_DOUBLE(_v); _m->size = sizeof(VAL_DOUBLE(_v)); _m->type = SQLT_FLT; break; case DB_STRING: _m->addr = (char*)VAL_STRING(_v); _m->size = strlen(VAL_STRING(_v))+1; _m->type = SQLT_STR; break; case DB_STR: { unsigned len = VAL_STR(_v).len; char *estr, *pstr = VAL_STR(_v).s; estr = (char*)memchr(pstr, 0, len); if (estr) { LM_WARN("truncate STR len from %u to: '%s'\n", len, pstr); len = (unsigned)(estr - pstr) + 1; } _m->size = len; _m->addr = pstr; _m->type = SQLT_CHR; } break; case DB_DATETIME: { struct tm* tm = localtime(&VAL_TIME(_v)); if (tm->tm_sec == 60) --tm->tm_sec; OCIDateSetDate(_o, (ub2)(tm->tm_year + 1900), (ub1)(tm->tm_mon + 1), (ub1)tm->tm_mday); OCIDateSetTime(_o, (ub1)tm->tm_hour, (ub1)tm->tm_min, (ub1)tm->tm_sec); _m->addr = _o; _m->size = sizeof(*_o); _m->type = SQLT_ODT; } break; case DB_BLOB: _m->addr = VAL_BLOB(_v).s; _m->size = VAL_BLOB(_v).len; _m->type = SQLT_CLOB; break; default: LM_ERR("unknown data type\n"); return -1; } return 0; }