/* callback intercepting all notifications. The registeration is done in y_interfaces_alarms_init */ status_t notification_cb(agt_not_msg_t *notif) { val_value_t *payload_val; char description_str[1024]; status_t res; int ret; if((0==strcmp(obj_get_name(notif->notobj),"link-up")) || (0==strcmp(obj_get_name(notif->notobj),"link-down"))) { int down; down = (0==strcmp(obj_get_name(notif->notobj),"link-down")); for (payload_val = (val_value_t *)dlq_firstEntry(¬if->payloadQ); payload_val != NULL; payload_val = (val_value_t *)dlq_nextEntry(payload_val)) { if(0==strcmp("if-name",obj_get_name(payload_val->obj))) { char* resource_str; sprintf(description_str,"Link down - %s",VAL_STRING(payload_val)); //alarm_event_w_type(description_str, "minor", "communications", down?1:0); resource_str=malloc(strlen("/interfaces/interface[name=\'%s\']")+strlen(VAL_STRING(payload_val))+1); sprintf(resource_str,"/interfaces/interface[name=\'%s\']",VAL_STRING(payload_val)); ret=alarmctrl_event(resource_str, "link-alarm"/*alarm_type_id_str*/, ""/*alarm_type_qualifier_str*/, "major", "Probably someone disconnected something?!", down?1:0); //assert(ret==0); free(resource_str); break; } } } return NO_ERR; }
static int db_sqlite_bind_values(sqlite3_stmt* stmt, const db_val_t* v, const int n) { int i, ret; if (n>0 && v) { for (i=0; i<n; i++) { if (VAL_NULL(v+i)) { ret=sqlite3_bind_null(stmt, i+1); goto check_ret; } switch(VAL_TYPE(v+i)) { /* every param has '+1' index because in sqlite the leftmost * parameter has index '1' */ case DB_INT: ret=sqlite3_bind_int(stmt, i+1, VAL_INT(v+i)); break; case DB_BIGINT: ret=sqlite3_bind_int64(stmt, i+1, VAL_BIGINT(v+i)); break; case DB_DOUBLE: ret=sqlite3_bind_double(stmt, i+1, VAL_DOUBLE(v+i)); break; case DB_STRING: ret=sqlite3_bind_text(stmt, i+1, VAL_STRING(v+i), strlen(VAL_STRING(v+i)), SQLITE_STATIC); break; case DB_STR: ret=sqlite3_bind_text(stmt, i+1, VAL_STR(v+i).s, VAL_STR(v+i).len, SQLITE_STATIC); break; case DB_DATETIME: ret=sqlite3_bind_int64(stmt, i+1, (long int)VAL_TIME(v+i)); break; case DB_BLOB: ret=sqlite3_bind_blob(stmt, i+1, (void*)VAL_BLOB(v+i).s, VAL_BLOB(v+i).len, SQLITE_STATIC); break; case DB_BITMAP: ret=sqlite3_bind_int(stmt, i+1, (int)VAL_BITMAP(v+i)); break; default: LM_BUG("invalid db type\n"); return 1; } check_ret: if (ret != SQLITE_OK) { return ret; } } } return SQLITE_OK; }
int bdb_ufield_db2bdb(bdb_uval_p v, db_val_t* _v) { char *s; VAL_NULL(&(v->v)) = VAL_NULL(_v); VAL_TYPE(&(v->v)) = VAL_TYPE(_v); if (!VAL_NULL(&(v->v))) { switch (VAL_TYPE(_v)) { case DB_INT: VAL_INT(&(v->v)) = VAL_INT(_v); break; case DB_FLOAT: VAL_FLOAT(&(v->v)) = VAL_FLOAT(_v); break; case DB_DATETIME: VAL_TIME(&(v->v)) = VAL_TIME(_v); break; case DB_BLOB: s = pkg_malloc(VAL_BLOB(_v).len); memcpy(s, VAL_BLOB(_v).s, VAL_BLOB(_v).len); VAL_BLOB(&(v->v)).s = s; VAL_BLOB(&(v->v)).len = VAL_BLOB(_v).len; break; case DB_DOUBLE: VAL_DOUBLE(&(v->v)) = VAL_DOUBLE(_v); break; case DB_STRING: VAL_STR(&(v->v)).len = strlen(VAL_STRING(_v)) + 1; s = pkg_malloc(VAL_STR(&(v->v)).len); strcpy(s, VAL_STRING(_v)); VAL_STRING(&(v->v)) = s; break; case DB_STR: s = pkg_malloc(VAL_STR(_v).len); memcpy(s, VAL_STR(_v).s, VAL_STR(_v).len); VAL_STR(&(v->v)).s = s; VAL_STR(&(v->v)).len = VAL_STR(_v).len; break; case DB_BITMAP: VAL_BITMAP(&(v->v)) = VAL_BITMAP(_v); break; default: LOG(L_ERR, "BDB:bdb_ufield_db2bdb: unknown column type: %0X\n", VAL_TYPE(_v)); return -1; break; } } return 0; };
int bdb_set_key(bdb_row_p _r, bdb_val_p _v) { /* NULL is not allowed for primary key */ if (VAL_NULL(&(_v->v))) { LOG(L_ERR, "BDB:bdb_set_key: NULL is not allowed for primary key\n"); return -1; } switch (VAL_TYPE(&(_v->v))) { case DB_INT: _r->key.data = &VAL_INT(&(_v->v)); _r->key.size = sizeof(VAL_INT(&(_v->v))); break; case DB_FLOAT: _r->key.data = &VAL_FLOAT(&(_v->v)); _r->key.size = sizeof(VAL_FLOAT(&(_v->v))); break; case DB_DATETIME: _r->key.data = &VAL_TIME(&(_v->v)); _r->key.size = sizeof(VAL_TIME(&(_v->v))); break; case DB_BLOB: _r->key.data = VAL_BLOB(&(_v->v)).s; _r->key.size = VAL_BLOB(&(_v->v)).len; break; case DB_DOUBLE: _r->key.data = &VAL_DOUBLE(&(_v->v)); _r->key.size = sizeof(VAL_DOUBLE(&(_v->v))); break; case DB_STRING: _r->key.data = (void *)VAL_STRING(&(_v->v)); _r->key.size = strlen(VAL_STRING(&(_v->v))) + 1; break; case DB_STR: _r->key.data = VAL_STR(&(_v->v)).s; _r->key.size = VAL_STR(&(_v->v)).len; break; case DB_BITMAP: _r->key.data = &VAL_BITMAP(&(_v->v)); _r->key.size = sizeof(VAL_BITMAP(&(_v->v))); break; default: LOG(L_ERR, "BDB:bdb_set_skey: unknown column type: %0X\n", VAL_TYPE(&(_v->v))); return -1; break; } return 0; };
void bdb_set_skey(bdb_srow_p _r, bdb_sval_p _v) { /* NULL is not allowed for primary key */ if (VAL_NULL(&(_v->v))) return; switch (VAL_TYPE(&(_v->v))) { case DB_INT: _r->key.data = &VAL_INT(&(_v->v)); _r->key.size = sizeof(VAL_INT(&(_v->v))); break; case DB_FLOAT: _r->key.data = &VAL_FLOAT(&(_v->v)); _r->key.size = sizeof(VAL_FLOAT(&(_v->v))); break; case DB_DATETIME: _r->key.data = &VAL_TIME(&(_v->v)); _r->key.size = sizeof(VAL_TIME(&(_v->v))); break; case DB_BLOB: _r->key.data = VAL_BLOB(&(_v->v)).s; _r->key.size = VAL_BLOB(&(_v->v)).len; break; case DB_DOUBLE: _r->key.data = &VAL_DOUBLE(&(_v->v)); _r->key.size = sizeof(VAL_DOUBLE(&(_v->v))); break; case DB_STRING: _r->key.data = (void *)VAL_STRING(&(_v->v)); _r->key.size = strlen(VAL_STRING(&(_v->v))) + 1; break; case DB_STR: _r->key.data = VAL_STR(&(_v->v)).s; _r->key.size = VAL_STR(&(_v->v)).len; break; case DB_BITMAP: _r->key.data = &VAL_BITMAP(&(_v->v)); _r->key.size = sizeof(VAL_BITMAP(&(_v->v))); break; default: LOG(L_ERR, "BDB:bdb_set_skey: unknown column type: %0X\n", VAL_TYPE(&(_v->v))); break; } #ifdef BDB_EXTRA_DEBUG LOG(L_NOTICE, "BDB:bdb_set_skey: use key '%.*s' (%d bytes)\n", _r->key.size, (char *)_r->key.data, _r->key.size); #endif };
/* * Generate AVPs from the database result */ static int generate_avps(db_res_t* result) { struct aaa_avp *cred; int_str ivalue; str value; int i; for ( cred=credentials,i=1 ; cred ; cred=cred->next,i++ ) { value.s = (char*)VAL_STRING(&(result->rows[0].values[i])); if ( VAL_NULL(&(result->rows[0].values[i])) || value.s == NULL ) { continue; } value.len = strlen(value.s); ivalue.s = &value; if (add_avp( cred->avp_type|AVP_VAL_STR, cred->avp_name, ivalue)!=0) { LOG(L_ERR,"ERROR:auth_db:generate_avps: failed to add AVP\n"); return -1; } DBG("generate_avps: set string AVP \"%s\"/%d = \"%.*s\"\n", (cred->avp_type&AVP_NAME_STR)?cred->avp_name.s->s:"", (cred->avp_type&AVP_NAME_STR)?0:cred->avp_name.n, value.len, ZSW(value.s)); } return 0; }
/******************************************************************** * FUNCTION y_starter_starter_kill_vnf_invoke * * RPC invocation phase * All constraints have passed at this point. * Call device instrumentation code in this function. * * INPUTS: * see agt/agt_rpc.h for details * * RETURNS: * error status ********************************************************************/ static status_t y_starter_starter_kill_vnf_invoke ( ses_cb_t *scb, rpc_msg_t *msg, xml_node_t *methnode) { status_t res = NO_ERR; val_value_t *vnfID_val; const xmlChar *vnfID; vnfID_val = val_find_child( msg->rpc_input, y_starter_M_starter, y_starter_N_vnfID); if (vnfID_val != NULL && vnfID_val->res == NO_ERR) { vnfID = VAL_STRING(vnfID_val); } /* remove the next line if scb is used */ (void)scb; /* remove the next line if methnode is used */ (void)methnode; /* invoke your device instrumentation code here */ return res; } /* y_starter_starter_kill_vnf_invoke */
/******************************************************************** * FUNCTION y_starter_starter_kill_vnf_validate * * RPC validation phase * All YANG constraints have passed at this point. * Add description-stmt checks in this function. * * INPUTS: * see agt/agt_rpc.h for details * * RETURNS: * error status ********************************************************************/ static status_t y_starter_starter_kill_vnf_validate ( ses_cb_t *scb, rpc_msg_t *msg, xml_node_t *methnode) { status_t res = NO_ERR; val_value_t *errorval = NULL; val_value_t *vnfID_val; const xmlChar *vnfID; vnfID_val = val_find_child( msg->rpc_input, y_starter_M_starter, y_starter_N_vnfID); if (vnfID_val != NULL && vnfID_val->res == NO_ERR) { vnfID = VAL_STRING(vnfID_val); } if (res != NO_ERR) { agt_record_error( scb, &msg->mhdr, NCX_LAYER_OPERATION, res, methnode, (errorval) ? NCX_NT_VAL : NCX_NT_NONE, errorval, (errorval) ? NCX_NT_VAL : NCX_NT_NONE, errorval); } return res; } /* y_starter_starter_kill_vnf_validate */
/******************************************************************** * FUNCTION y_starter_starter_start_vnf_validate * * RPC validation phase * All YANG constraints have passed at this point. * Add description-stmt checks in this function. * * INPUTS: * see agt/agt_rpc.h for details * * RETURNS: * error status ********************************************************************/ static status_t y_starter_starter_start_vnf_validate ( ses_cb_t *scb, rpc_msg_t *msg, xml_node_t *methnode) { status_t res = NO_ERR; val_value_t *errorval = NULL; val_value_t *port_val; const xmlChar *port; val_value_t *clickDescription_val; const xmlChar *clickDescription; port_val = val_find_child( msg->rpc_input, y_starter_M_starter, y_starter_N_port); if (port_val != NULL && port_val->res == NO_ERR) { port = VAL_STRING(port_val); } clickDescription_val = val_find_child( msg->rpc_input, y_starter_M_starter, y_starter_N_clickDescription); if (clickDescription_val != NULL && clickDescription_val->res == NO_ERR) { clickDescription = VAL_STRING(clickDescription_val); } if (res != NO_ERR) { agt_record_error( scb, &msg->mhdr, NCX_LAYER_OPERATION, res, methnode, (errorval) ? NCX_NT_VAL : NCX_NT_NONE, errorval, (errorval) ? NCX_NT_VAL : NCX_NT_NONE, errorval); } return res; } /* y_starter_starter_start_vnf_validate */
inline SV *valdata(db_val_t* val) { SV *data = &PL_sv_undef; const char* stringval; switch(VAL_TYPE(val)) { case DB1_INT: data = newSViv(VAL_INT(val)); break; case DB1_BIGINT: LM_ERR("BIGINT not supported"); data = &PL_sv_undef; break; case DB1_DOUBLE: data = newSVnv(VAL_DOUBLE(val)); break; case DB1_STRING: stringval = VAL_STRING(val); if (strlen(stringval) > 0) data = newSVpv(stringval, strlen(stringval)); else data = &PL_sv_undef; break; case DB1_STR: if (VAL_STR(val).len > 0) data = newSVpv(VAL_STR(val).s, VAL_STR(val).len); else data = &PL_sv_undef; break; case DB1_DATETIME: data = newSViv((unsigned int)VAL_TIME(val)); break; case DB1_BLOB: if (VAL_BLOB(val).len > 0) data = newSVpv(VAL_BLOB(val).s, VAL_BLOB(val).len); else data = &PL_sv_undef; break; case DB1_BITMAP: data = newSViv(VAL_BITMAP(val)); break; } return data; }
// // Shuffle_String: C // // Randomize a string. Return a new string series. // Handles both BYTE and UNICODE strings. // void Shuffle_String(REBVAL *value, bool secure) { REBSTR *s = VAL_STRING(value); REBCNT idx = VAL_INDEX(value); REBCNT n; for (n = VAL_LEN_AT(value); n > 1;) { REBCNT k = idx + cast(REBCNT, Random_Int(secure)) % n; n--; REBUNI swap = GET_CHAR_AT(s, k); SET_CHAR_AT(s, k, GET_CHAR_AT(s, n + idx)); SET_CHAR_AT(s, n + idx, swap); } }
/* * Checks based on given source IP address and protocol, and From URI * of request if request can be trusted without authentication. */ int allow_trusted(struct sip_msg* msg, char *src_ip, int proto) { int result; db1_res_t* res = NULL; db_key_t keys[1]; db_val_t vals[1]; db_key_t cols[4]; if (db_mode == DISABLE_CACHE) { db_key_t order = &priority_col; if (db_handle == 0) { LM_ERR("no connection to database\n"); return -1; } keys[0] = &source_col; cols[0] = &proto_col; cols[1] = &from_col; cols[2] = &ruri_col; cols[3] = &tag_col; if (perm_dbf.use_table(db_handle, &trusted_table) < 0) { LM_ERR("failed to use trusted table\n"); return -1; } VAL_TYPE(vals) = DB1_STRING; VAL_NULL(vals) = 0; VAL_STRING(vals) = src_ip; if (perm_dbf.query(db_handle, keys, 0, vals, cols, 1, 4, order, &res) < 0){ LM_ERR("failed to query database\n"); return -1; } if (RES_ROW_N(res) == 0) { perm_dbf.free_result(db_handle, res); return -1; } result = match_res(msg, proto, res); perm_dbf.free_result(db_handle, res); return result; } else { return match_hash_table(*hash_table, msg, src_ip, proto); } }
/* * Used when converting the query to a result */ int db_unixodbc_str2val(const db_type_t _t, db_val_t* _v, const char* _s, const int _l, const unsigned int _cpy) { /* db_unixodbc uses the NULL string for NULL SQL values */ if (_v && _s && !strcmp(_s, "NULL")) { LM_DBG("converting NULL value"); static str dummy_string = {"", 0}; 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; } else { return db_str2val(_t, _v, _s, _l, _cpy); } }
/* loads data from the db */ table_entry_t* load_info(db_func_t *dr_dbf, db_con_t* db_hdl, str *db_table) { int int_vals[7]; char *str_vals[2]; int no_of_results; int i, n; int no_rows = 5; int db_cols = 10; unsigned long last_attempt; static db_key_t clusterer_machine_id_key = &machine_id_col; static db_val_t clusterer_machine_id_value = { .type = DB_INT, .nul = 0, }; VAL_INT(&clusterer_machine_id_value) = server_id; /* the columns from the db table */ db_key_t columns[10]; /* result from a db query */ db_res_t* res; /* a row from the db table */ db_row_t* row; /* the processed result */ table_entry_t *data; res = 0; data = 0; columns[0] = &cluster_id_col; columns[1] = &machine_id_col; columns[2] = &state_col; columns[3] = &description_col; columns[4] = &url_col; columns[5] = &id_col; columns[6] = &last_attempt_col; columns[7] = &failed_attempts_col; columns[8] = &no_tries_col; columns[9] = &duration_col; CON_OR_RESET(db_hdl); /* 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; /* read data */ 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 clusters list" "in which the specified server runs\n"); /* first we see in which clusters the specified server runs*/ if (dr_dbf->query(db_hdl, &clusterer_machine_id_key, &op_eq, &clusterer_machine_id_value, columns, 1, 1, 0, &res) < 0) { LM_ERR("DB query failed - cannot retrieve the clusters list in which" " the specified server 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) == 0) { LM_WARN("No machines found in cluster %d\n", server_id); return 0; } 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_of_results = RES_ROW_N(res); dr_dbf->free_result(db_hdl, res); res = 0; LM_DBG("DB query - retrieve valid connections\n"); /* fetch is the best strategy */ CON_USE_OR_OP(db_hdl); if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) { if (dr_dbf->query(db_hdl, clusterer_cluster_id_key, 0, clusterer_cluster_id_value, columns, no_of_results, db_cols, 0, 0) < 0) { LM_ERR("DB query failed - retrieve valid connections \n"); goto error; } no_rows = estimate_available_rows(4 + 4 + 4 + 64 + 4 + 45 + 4 + 8 + 4 + 4, 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, clusterer_cluster_id_key, 0, clusterer_cluster_id_value, columns, no_of_results, 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; /* CLUSTER ID column */ check_val(cluster_id_col, ROW_VALUES(row), DB_INT, 1, 0); int_vals[INT_VALS_CLUSTER_ID_COL] = VAL_INT(ROW_VALUES(row)); /* MACHINE ID column */ check_val(machine_id_col, ROW_VALUES(row) + 1, DB_INT, 1, 0); int_vals[INT_VALS_MACHINE_ID_COL] = VAL_INT(ROW_VALUES(row) + 1); /* STATE column */ check_val(state_col, ROW_VALUES(row) + 2, DB_INT, 1, 0); int_vals[INT_VALS_STATE_COL] = VAL_INT(ROW_VALUES(row) + 2); /* DESCRIPTION column */ check_val(description_col, ROW_VALUES(row) + 3, DB_STRING, 0, 0); str_vals[STR_VALS_DESCRIPTION_COL] = (char*) VAL_STRING(ROW_VALUES(row) + 3); /* URL column */ check_val(url_col, ROW_VALUES(row) + 4, DB_STRING, 1, 1); str_vals[STR_VALS_URL_COL] = (char*) VAL_STRING(ROW_VALUES(row) + 4); /* CLUSTERER_ID column */ check_val(id_col, ROW_VALUES(row) + 5, DB_INT, 1, 0); int_vals[INT_VALS_CLUSTERER_ID_COL] = VAL_INT(ROW_VALUES(row) + 5); /* LAST_ATTEMPT column */ check_val(last_attempt_col, ROW_VALUES(row) + 6, DB_BIGINT, 1, 0); last_attempt = VAL_BIGINT(ROW_VALUES(row) + 6); /* FAILED_ATTEMPTS column */ check_val(failed_attempts_col, ROW_VALUES(row) + 7, DB_INT, 1, 0); int_vals[INT_VALS_FAILED_ATTEMPTS_COL] = VAL_INT(ROW_VALUES(row) + 7); /* NO_TRIES column */ check_val(no_tries_col, ROW_VALUES(row) + 8, DB_INT, 1, 0); int_vals[INT_VALS_NO_TRIES_COL] = VAL_INT(ROW_VALUES(row) + 8); /* DURATION column */ check_val(duration_col, ROW_VALUES(row) + 9, DB_INT, 1, 0); int_vals[INT_VALS_DURATION_COL] = VAL_INT(ROW_VALUES(row) + 9); /* store data */ if (add_info(&data, int_vals, last_attempt, str_vals) < 0) { LM_DBG("error while adding info to shm\n"); goto error; } LM_DBG("machine id %d\n", int_vals[0]); LM_DBG("cluster id %d\n", int_vals[1]); LM_DBG("state %d\n", int_vals[2]); LM_DBG("clusterer_id %d\n", int_vals[3]); LM_DBG("description %s\n", str_vals[0]); LM_DBG("url %s\n", str_vals[1]); n++; } if (n == 1) LM_WARN("The server is the only one in the cluster\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); 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 data; error: if (res) dr_dbf->free_result(db_hdl, res); if (data) free_data(data); data = NULL; return 0; } /* deallocates data */ void free_data(table_entry_t *data) { table_entry_t *tmp_entry; table_entry_info_t *info; table_entry_info_t *tmp_info; table_entry_value_t *value; table_entry_value_t *tmp_value; struct module_timestamp *timestamp; struct module_timestamp *tmp_timestamp; while (data != NULL) { tmp_entry = data; data = data->next; info = tmp_entry->info; while (info != NULL) { value = info->value; while (value != NULL) { if (value->path.s) shm_free(value->path.s); if (value->description.s) shm_free(value->description.s); timestamp = value->in_timestamps; while (timestamp != NULL) { tmp_timestamp = timestamp; timestamp = timestamp->next; shm_free(tmp_timestamp); } tmp_value = value; value = value->next; shm_free(tmp_value); } tmp_info = info; info = info->next; shm_free(tmp_info); } shm_free(tmp_entry); } }
/* * Convert str to db value, does not copy strings */ int db_mysql_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; }
/******************************************************************** * FUNCTION y_starter_starter_start_vnf_invoke * * RPC invocation phase * All constraints have passed at this point. * Call device instrumentation code in this function. * * INPUTS: * see agt/agt_rpc.h for details * * RETURNS: * error status ********************************************************************/ static status_t y_starter_starter_start_vnf_invoke ( ses_cb_t *scb, rpc_msg_t *msg, xml_node_t *methnode) { status_t res = NO_ERR; val_value_t *port_val; const xmlChar *port; val_value_t *clickDescription_val; const xmlChar *clickDescription; port_val = val_find_child( msg->rpc_input, y_starter_M_starter, y_starter_N_port); if (port_val != NULL && port_val->res == NO_ERR) { port = VAL_STRING(port_val); } clickDescription_val = val_find_child( msg->rpc_input, y_starter_M_starter, y_starter_N_clickDescription); if (clickDescription_val != NULL && clickDescription_val->res == NO_ERR) { clickDescription = VAL_STRING(clickDescription_val); } /* remove the next line if scb is used */ (void)scb; /* remove the next line if methnode is used */ (void)methnode; /* invoke your device instrumentation code here */ /*********************** THIS PART IS ADDED MANUALLY BY LEVI *************************/ log_info("\nStart VNF RPC is invoked with the following settings: \n"); log_info("\n%s",clickDescription); int processID; int status; log_info("\nFORKING\n"); /* in order to avoid block main thread otherwise, yangcli also waits for termination of child process */ signal(SIGCHLD, SIG_IGN); if((processID = fork() == 0 )) { /* the child process */ log_info("\nPID of child: %d ",getpid()); /*lastProcess.name = "sleep"; lastProcess.pid = getpid();*/ //dumping data into the processes_array process p; p.uniqueID = uniqueID; p.name = "click"; p.pid = getpid(); process_array[uniqueID]=p; uniqueID++; log_info("\nPID of netconfd: %d ", getppid()); // setting up the default params for starting click char control_socket[3] = "-R"; char port_param[8] = "-p"; strcat(port_param,(char*)port); char p3[3] = "-e"; /* char p4[100] = "FromDevice(eth1)->Discard;";*/ char click_path[100]="/home/unify/click_binaries/bin/click"; int errorCode = execlp(click_path, click_path, control_socket, port_param, p3, clickDescription, NULL); /* if everything went fine, we do not reach this point */ log_info("\nThe result of the execution is %d", errorCode); _exit(127); } else { log_info("\n\n--------------- RPC END ------------------\n\n"); } /********************************** END OF LEVI **************************************/ return res; } /* y_starter_starter_start_vnf_invoke */
/*! * \brief Converting a value to a string * * Converting a value to a string, used when converting result from a query * \param _c database connection * \param _v source value * \param _s target string * \param _len target string length * \return 0 on success, negative on error */ int db_mysql_val2str(const db1_con_t* _c, const db_val_t* _v, char* _s, int* _len) { int l, tmp; char* old_s; tmp = db_val2str(_c, _v, _s, _len); if (tmp < 1) return tmp; switch(VAL_TYPE(_v)) { case DB1_STRING: l = strlen(VAL_STRING(_v)); if (*_len < (l * 2 + 3)) { LM_ERR("destination buffer too short\n"); return -6; } else { old_s = _s; *_s++ = '\''; _s += mysql_real_escape_string(CON_CONNECTION(_c), _s, VAL_STRING(_v), l); *_s++ = '\''; *_s = '\0'; /* FIXME */ *_len = _s - old_s; return 0; } break; case DB1_STR: if (*_len < (VAL_STR(_v).len * 2 + 3)) { LM_ERR("destination buffer too short\n"); return -7; } else { old_s = _s; *_s++ = '\''; _s += mysql_real_escape_string(CON_CONNECTION(_c), _s, VAL_STR(_v).s, VAL_STR(_v).len); *_s++ = '\''; *_s = '\0'; *_len = _s - old_s; return 0; } break; case DB1_BLOB: l = VAL_BLOB(_v).len; if (*_len < (l * 2 + 3)) { LM_ERR("destination buffer too short\n"); return -9; } else { old_s = _s; *_s++ = '\''; _s += mysql_real_escape_string(CON_CONNECTION(_c), _s, VAL_STR(_v).s, l); *_s++ = '\''; *_s = '\0'; *_len = _s - old_s; return 0; } break; default: LM_DBG("unknown data type\n"); return -10; } }
static int mt_load_db(m_tree_t *pt) { db_key_t db_cols[MT_MAX_COLS] = {&tprefix_column, &tvalue_column}; db_key_t key_cols[1]; db_op_t op[1] = {OP_EQ}; db_val_t vals[1]; str tprefix, tvalue; db1_res_t* db_res = NULL; int i, ret, c; m_tree_t new_tree; m_tree_t *old_tree = NULL; mt_node_t *bk_head = NULL; if(pt->ncols>0) { for(c=0; c<pt->ncols; c++) { db_cols[c] = &pt->scols[c]; } } else { db_cols[0] = &tprefix_column; db_cols[1] = &tvalue_column; c = 2; } key_cols[0] = &tname_column; VAL_TYPE(vals) = DB1_STRING; VAL_NULL(vals) = 0; VAL_STRING(vals) = pt->tname.s; if(db_con==NULL) { LM_ERR("no db connection\n"); return -1; } old_tree = mt_get_tree(&(pt->tname)); if(old_tree==NULL) { LM_ERR("tree definition not found [%.*s]\n", pt->tname.len, pt->tname.s); return -1; } memcpy(&new_tree, old_tree, sizeof(m_tree_t)); new_tree.head = 0; new_tree.next = 0; new_tree.nrnodes = 0; new_tree.nritems = 0; new_tree.memsize = 0; new_tree.reload_count++; new_tree.reload_time = (unsigned int)time(NULL); if (mt_dbf.use_table(db_con, &old_tree->dbtable) < 0) { LM_ERR("failed to use_table\n"); return -1; } if (DB_CAPABILITY(mt_dbf, DB_CAP_FETCH)) { if(mt_dbf.query(db_con, key_cols, op, vals, db_cols, pt->multi, c, 0, 0) < 0) { LM_ERR("Error while querying db\n"); return -1; } if(mt_dbf.fetch_result(db_con, &db_res, mt_fetch_rows)<0) { LM_ERR("Error while fetching result\n"); goto error; } else { if(RES_ROW_N(db_res)==0) { goto dbreloaded; } } } else { if((ret=mt_dbf.query(db_con, key_cols, op, vals, db_cols, pt->multi, 2, 0, &db_res))!=0 || RES_ROW_N(db_res)<=0 ) { if(ret==0) { goto dbreloaded; } else { goto error; } } } if(RES_ROW_N(db_res)>0) { if(RES_ROWS(db_res)[0].values[0].type != DB1_STRING || RES_ROWS(db_res)[0].values[1].type != DB1_STRING) { LM_ERR("wrond column types in db table (%d / %d)\n", RES_ROWS(db_res)[0].values[0].type, RES_ROWS(db_res)[0].values[1].type); goto error; } } do { for(i=0; i<RES_ROW_N(db_res); i++) { /* check for NULL values ?!?! */ tprefix.s = (char*)(RES_ROWS(db_res)[i].values[0].val.string_val); tprefix.len = strlen(ZSW(tprefix.s)); if(c>2) { if(mt_pack_values(&new_tree, db_res, i, c, &tvalue)<0) { LM_ERR("Error packing values\n"); goto error; } } else { tvalue.s = (char*)(RES_ROWS(db_res)[i].values[1].val.string_val); tvalue.len = strlen(ZSW(tvalue.s)); } if(tprefix.s==NULL || tvalue.s==NULL || tprefix.len<=0 || tvalue.len<=0) { LM_ERR("Error - bad record in db" " (prefix: %p/%d - value: %p/%d)\n", tprefix.s, tprefix.len, tvalue.s, tvalue.len); continue; } if(mt_add_to_tree(&new_tree, &tprefix, &tvalue)<0) { LM_ERR("Error adding info to tree\n"); goto error; } } if (DB_CAPABILITY(mt_dbf, DB_CAP_FETCH)) { if(mt_dbf.fetch_result(db_con, &db_res, mt_fetch_rows)<0) { LM_ERR("Error while fetching!\n"); if (db_res) mt_dbf.free_result(db_con, db_res); goto error; } } else { break; } } while(RES_ROW_N(db_res)>0); dbreloaded: mt_dbf.free_result(db_con, db_res); /* block all readers */ lock_get( mt_lock ); mt_reload_flag = 1; lock_release( mt_lock ); while (mt_tree_refcnt) { sleep_us(10); } bk_head = old_tree->head; old_tree->head = new_tree.head; old_tree->nrnodes = new_tree.nrnodes; old_tree->nritems = new_tree.nritems; old_tree->memsize = new_tree.memsize; old_tree->reload_count = new_tree.reload_count; old_tree->reload_time = new_tree.reload_time; mt_reload_flag = 0; /* free old data */ if (bk_head!=NULL) mt_free_node(bk_head, new_tree.type); return 0; error: mt_dbf.free_result(db_con, db_res); if (new_tree.head!=NULL) mt_free_node(new_tree.head, new_tree.type); return -1; }
/* * Reload trusted table to new hash table and when done, make new hash table * current one. */ int reload_trusted_table(void) { db_key_t cols[6]; db1_res_t* res = NULL; db_row_t* row; db_val_t* val; struct trusted_list **new_hash_table; struct trusted_list **old_hash_table; int i; int priority; char *pattern, *ruri_pattern, *tag; if (hash_table == 0) { LM_ERR("in-memory hash table not initialized\n"); return -1; } if (db_handle == 0) { LM_ERR("no connection to database\n"); return -1; } cols[0] = &source_col; cols[1] = &proto_col; cols[2] = &from_col; cols[3] = &ruri_col; cols[4] = &tag_col; cols[5] = &priority_col; if (perm_dbf.use_table(db_handle, &trusted_table) < 0) { LM_ERR("failed to use trusted table\n"); return -1; } if (perm_dbf.query(db_handle, NULL, 0, NULL, cols, 0, 6, 0, &res) < 0) { LM_ERR("failed to query database\n"); return -1; } /* Choose new hash table and free its old contents */ if (*hash_table == hash_table_1) { new_hash_table = hash_table_2; } else { new_hash_table = hash_table_1; } empty_hash_table(new_hash_table); row = RES_ROWS(res); LM_DBG("number of rows in trusted table: %d\n", RES_ROW_N(res)); for (i = 0; i < RES_ROW_N(res); i++) { val = ROW_VALUES(row + i); if ((ROW_N(row + i) == 6) && ((VAL_TYPE(val) == DB1_STRING) || (VAL_TYPE(val) == DB1_STR) ) && !VAL_NULL(val) && ((VAL_TYPE(val + 1) == DB1_STRING) || (VAL_TYPE(val + 1) == DB1_STR)) && !VAL_NULL(val + 1) && (VAL_NULL(val + 2) || (((VAL_TYPE(val + 2) == DB1_STRING) || (VAL_TYPE(val + 2) == DB1_STR)) && !VAL_NULL(val + 2))) && (VAL_NULL(val + 3) || (((VAL_TYPE(val + 3) == DB1_STRING) || (VAL_TYPE(val + 3) == DB1_STR) )&& !VAL_NULL(val + 3))) && (VAL_NULL(val + 4) || (((VAL_TYPE(val + 4) == DB1_STRING) || (VAL_TYPE(val + 4) == DB1_STR) )&& !VAL_NULL(val + 4)))) { if (VAL_NULL(val + 2)) { pattern = 0; } else { pattern = (char *)VAL_STRING(val + 2); } if (VAL_NULL(val + 3)) { ruri_pattern = 0; } else { ruri_pattern = (char *)VAL_STRING(val + 3); } if (VAL_NULL(val + 4)) { tag = 0; } else { tag = (char *)VAL_STRING(val + 4); } if (VAL_NULL(val + 5)) { priority = 0; } else { priority = (int)VAL_INT(val + 5); } if (hash_table_insert(new_hash_table, (char *)VAL_STRING(val), (char *)VAL_STRING(val + 1), pattern, ruri_pattern, tag, priority) == -1) { LM_ERR("hash table problem\n"); perm_dbf.free_result(db_handle, res); empty_hash_table(new_hash_table); return -1; } LM_DBG("tuple <%s, %s, %s, %s, %s> inserted into trusted hash " "table\n", VAL_STRING(val), VAL_STRING(val + 1), pattern, ruri_pattern, tag); } else { LM_ERR("database problem\n"); perm_dbf.free_result(db_handle, res); empty_hash_table(new_hash_table); return -1; } } perm_dbf.free_result(db_handle, res); old_hash_table = *hash_table; *hash_table = new_hash_table; empty_hash_table(old_hash_table); LM_DBG("trusted table reloaded successfully.\n"); return 1; }
int db_mysql_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; }
/* * Used when converting result from a query */ int db_postgres_val2str(const db_con_t* _con, const db_val_t* _v, char* _s, int* _len) { int l, ret; int pgret; char *tmp_s; size_t tmp_len; char* old_s; if ((!_v) || (!_s) || (!_len) || (!*_len)) { LM_ERR("invalid parameter value\n"); return -1; } if (VAL_NULL(_v)) { if ( *_len < (l=(int)sizeof("NULL")-1)) { LM_ERR("buffer too short to print NULL\n"); return -1; } memcpy(_s, "NULL", l); *_len = l; return 0; } switch(VAL_TYPE(_v)) { case DB_INT: if (db_int2str(VAL_INT(_v), _s, _len) < 0) { LM_ERR("failed to convert string to int\n"); return -2; } else { return 0; } break; case DB_BIGINT: if (db_bigint2str(VAL_BIGINT(_v), _s, _len) < 0) { LM_ERR("failed to convert string to big int\n"); return -2; } else { return 0; } break; case DB_BITMAP: if (db_int2str(VAL_BITMAP(_v), _s, _len) < 0) { LM_ERR("failed to convert string to int\n"); return -3; } else { return 0; } break; case DB_DOUBLE: if (db_double2str(VAL_DOUBLE(_v), _s, _len) < 0) { LM_ERR("failed to convert string to double\n"); return -3; } else { return 0; } break; case DB_STRING: l = strlen(VAL_STRING(_v)); if (*_len < (l * 2 + 3)) { LM_ERR("destination STRING buffer too short (have %d, need %d)\n", *_len, l * 2 + 3); return -4; } else { old_s = _s; *_s++ = '\''; ret = PQescapeStringConn(CON_CONNECTION(_con), _s, VAL_STRING(_v), l, &pgret); if(pgret!=0) { LM_ERR("PQescapeStringConn failed\n"); return -4; } LM_DBG("PQescapeStringConn: in: %d chars," " out: %d chars\n", l, ret); _s += ret; *_s++ = '\''; *_s = '\0'; /* FIXME */ *_len = _s - old_s; return 0; } break; case DB_STR: l = VAL_STR(_v).len; if (*_len < (l * 2 + 3)) { LM_ERR("destination STR buffer too short (have %d, need %d)\n", *_len, l * 2 + 3); return -5; } else { old_s = _s; *_s++ = '\''; ret = PQescapeStringConn(CON_CONNECTION(_con), _s, VAL_STRING(_v), l, &pgret); if(pgret!=0) { LM_ERR("PQescapeStringConn failed \n"); return -5; } LM_DBG("PQescapeStringConn: in: %d chars, out: %d chars\n", l, ret); _s += ret; *_s++ = '\''; *_s = '\0'; /* FIXME */ *_len = _s - old_s; return 0; } break; case DB_DATETIME: if (db_time2str(VAL_TIME(_v), _s, _len) < 0) { LM_ERR("failed to convert string to time_t\n"); return -6; } else { return 0; } break; case DB_BLOB: l = VAL_BLOB(_v).len; /* this estimation is not always correct, thus we need to check later again */ if (*_len < (l * 2 + 3)) { LM_ERR("destination BLOB buffer too short (have %d, need %d)\n", *_len, l * 2 + 3); return -7; } else { *_s++ = '\''; tmp_s = (char*)PQescapeByteaConn(CON_CONNECTION(_con), (unsigned char*)VAL_STRING(_v), (size_t)l, (size_t*)&tmp_len); if(tmp_s==NULL) { LM_ERR("PQescapeBytea failed\n"); return -7; } if (tmp_len > *_len) { LM_ERR("escaped result too long\n"); return -7; } memcpy(_s, tmp_s, tmp_len); PQfreemem(tmp_s); tmp_len = strlen(_s); *(_s + tmp_len) = '\''; *(_s + tmp_len + 1) = '\0'; *_len = tmp_len + 2; return 0; } break; default: LM_DBG("unknown data type\n"); return -7; } }
/* * Used when converting result from a query */ int km_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 DB1_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 DB1_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 DB1_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 DB1_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; return 0; } break; case DB1_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 , VAL_STR(_v).len); *_len = VAL_STR(_v).len; return 0; } break; case DB1_DATETIME: if (km_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 DB1_BLOB: l = VAL_BLOB(_v).len; if (*_len < l) { LM_ERR("Destination buffer too short for blob\n"); return -7; } else { LM_DBG("Converting BLOB [%s]\n", _s); _s = VAL_BLOB(_v).s; *_len = 0; return -8; } break; default: LM_DBG("Unknown data type\n"); return -8; } }
/* * Check if domain is local */ int is_domain_local(struct sip_msg *msg, str* _host, char *pvar) { pv_spec_t *pv = (pv_spec_t *)pvar; pv_value_t val; db_val_t *values; if (db_mode == 0) { db_key_t keys[1]; db_val_t vals[1]; db_key_t cols[2]; db_res_t* res = NULL; keys[0] = &domain_col; cols[0] = &domain_col; cols[1] = &domain_attrs_col; if (domain_dbf.use_table(db_handle, &domain_table) < 0) { LM_ERR("Error while trying to use domain table\n"); return -3; } VAL_TYPE(vals) = DB_STR; VAL_NULL(vals) = 0; VAL_STR(vals).s = _host->s; VAL_STR(vals).len = _host->len; if (domain_dbf.query(db_handle, keys, 0, vals, cols, 1, 2, 0, &res) < 0 ) { LM_ERR("Error while querying database\n"); return -3; } if (RES_ROW_N(res) == 0) { LM_DBG("Realm '%.*s' is not local\n", _host->len, ZSW(_host->s)); domain_dbf.free_result(db_handle, res); return -1; } else { LM_DBG("Realm '%.*s' is local\n", _host->len, ZSW(_host->s)); if (pvar) { /* XXX: what shall we do if there are duplicate entries? */ /* we only check the first row - razvanc */ values = ROW_VALUES(RES_ROWS(res)); if (!VAL_NULL(values +1)) { if (VAL_TYPE(values + 1) == DB_STR) { val.rs = VAL_STR(values + 1); } else { val.rs.s = (char *)VAL_STRING(values + 1); val.rs.len = strlen(val.rs.s); } val.flags = PV_VAL_STR; if (pv_set_value(msg, pv, 0, &val) != 0) LM_ERR("Cannot set attributes value\n"); } } domain_dbf.free_result(db_handle, res); return 1; } } else { return hash_table_lookup (msg, _host, pv); } }
/*! * \brief Get all contacts from the database, in partitions if wanted * \see get_all_ucontacts * \param buf target buffer * \param len length of buffer * \param flags contact flags * \param part_idx part index * \param part_max maximal part * \param options options * \return 0 on success, positive if buffer size was not sufficient, negative on failure */ static inline int get_all_db_ucontacts(void *buf, int len, unsigned int flags, unsigned int part_idx, unsigned int part_max, int options) { struct socket_info *sock; unsigned int dbflags; db1_res_t* res = NULL; db_row_t *row; dlist_t *dom; int port, proto; char *p; str addr; str recv; str path; str ruid; str host; unsigned int aorhash; int i; void *cp; int shortage, needed; db_key_t keys1[4]; /* where */ db_val_t vals1[4]; db_op_t ops1[4]; db_key_t keys2[6]; /* select */ int n[2] = {2,6}; /* number of dynamic values used on key1/key2 */ cp = buf; shortage = 0; /* Reserve space for terminating 0000 */ len -= sizeof(addr.len); aorhash = 0; /* select fields */ keys2[0] = &received_col; keys2[1] = &contact_col; keys2[2] = &sock_col; keys2[3] = &cflags_col; keys2[4] = &path_col; keys2[5] = &ruid_col; /* where fields */ keys1[0] = &expires_col; ops1[0] = OP_GT; vals1[0].nul = 0; UL_DB_EXPIRES_SET(&vals1[0], time(0)); keys1[1] = &partition_col; ops1[1] = OP_EQ; vals1[1].type = DB1_INT; vals1[1].nul = 0; if(_ul_max_partition>0) vals1[1].val.int_val = part_idx; else vals1[1].val.int_val = 0; if (flags & nat_bflag) { keys1[n[0]] = &keepalive_col; ops1[n[0]] = OP_EQ; vals1[n[0]].type = DB1_INT; vals1[n[0]].nul = 0; vals1[n[0]].val.int_val = 1; n[0]++; } if(options&GAU_OPT_SERVER_ID) { keys1[n[0]] = &srv_id_col; ops1[n[0]] = OP_EQ; vals1[n[0]].type = DB1_INT; vals1[n[0]].nul = 0; vals1[n[0]].val.int_val = server_id; n[0]++; } /* TODO: use part_idx and part_max on keys1 */ for (dom = root; dom!=NULL ; dom=dom->next) { if (ul_dbf.use_table(ul_dbh, dom->d->name) < 0) { LM_ERR("sql use_table failed\n"); return -1; } if (ul_dbf.query(ul_dbh, keys1, ops1, vals1, keys2, n[0], n[1], NULL, &res) <0 ) { LM_ERR("query error\n"); return -1; } if( RES_ROW_N(res)==0 ) { ul_dbf.free_result(ul_dbh, res); continue; } for(i = 0; i < RES_ROW_N(res); i++) { row = RES_ROWS(res) + i; /* received */ recv.s = (char*)VAL_STRING(ROW_VALUES(row)); if ( VAL_NULL(ROW_VALUES(row)) || recv.s==0 || recv.s[0]==0 ) { recv.s = NULL; recv.len = 0; } else { recv.len = strlen(recv.s); } /* contact */ addr.s = (char*)VAL_STRING(ROW_VALUES(row)+1); if (VAL_NULL(ROW_VALUES(row)+1) || addr.s==0 || addr.s[0]==0) { LM_ERR("empty contact -> skipping\n"); continue; } else { addr.len = strlen(addr.s); } /* path */ path.s = (char*)VAL_STRING(ROW_VALUES(row)+4); if (VAL_NULL(ROW_VALUES(row)+4) || path.s==0 || path.s[0]==0){ path.s = NULL; path.len = 0; } else { path.len = strlen(path.s); } /* ruid */ ruid.s = (char*)VAL_STRING(ROW_VALUES(row)+5); if (VAL_NULL(ROW_VALUES(row)+5) || ruid.s==0 || ruid.s[0]==0){ ruid.s = NULL; ruid.len = 0; } else { ruid.len = strlen(ruid.s); } needed = (int)(sizeof(addr.len) + addr.len + sizeof(recv.len) + recv.len + sizeof(sock) + sizeof(dbflags) + sizeof(path.len) + path.len + sizeof(ruid.len) + ruid.len + sizeof(aorhash)); if (len < needed) { shortage += needed ; continue; } /* write contact */ memcpy(cp, &addr.len, sizeof(addr.len)); cp = (char*)cp + sizeof(addr.len); memcpy(cp, addr.s, addr.len); cp = (char*)cp + addr.len; /* write received */ memcpy(cp, &recv.len, sizeof(recv.len)); cp = (char*)cp + sizeof(recv.len); /* copy received only if exist */ if(recv.len){ memcpy(cp, recv.s, recv.len); cp = (char*)cp + recv.len; } /* sock */ p = (char*)VAL_STRING(ROW_VALUES(row) + 2); if (VAL_NULL(ROW_VALUES(row)+2) || p==0 || p[0]==0){ sock = 0; } else { if (parse_phostport( p, &host.s, &host.len, &port, &proto)!=0) { LM_ERR("bad socket <%s>...set to 0\n", p); sock = 0; } else { sock = grep_sock_info( &host, (unsigned short)port, proto); if (sock==0) { LM_DBG("non-local socket <%s>...set to 0\n", p); } } } /* flags */ dbflags = VAL_BITMAP(ROW_VALUES(row) + 3); /* write sock and flags */ memcpy(cp, &sock, sizeof(sock)); cp = (char*)cp + sizeof(sock); memcpy(cp, &dbflags, sizeof(dbflags)); cp = (char*)cp + sizeof(dbflags); /* write path */ memcpy(cp, &path.len, sizeof(path.len)); cp = (char*)cp + sizeof(path.len); /* copy path only if exist */ if(path.len){ memcpy(cp, path.s, path.len); cp = (char*)cp + path.len; } /* write ruid */ memcpy(cp, &ruid.len, sizeof(ruid.len)); cp = (char*)cp + sizeof(ruid.len); /* copy ruid only if exist */ if(ruid.len){ memcpy(cp, ruid.s, ruid.len); cp = (char*)cp + ruid.len; } /* aorhash not used for db-only records, but it is added * (as 0) to match the struct used for mem records */ memcpy(cp, &aorhash, sizeof(aorhash)); cp = (char*)cp + sizeof(aorhash); len -= needed; } /* row cycle */ ul_dbf.free_result(ul_dbh, res); } /* domain cycle */ /* len < 0 is possible, if size of the buffer < sizeof(c->c.len) */ if (len >= 0) memset(cp, 0, sizeof(addr.len)); /* Shouldn't happen */ if (shortage > 0 && len > shortage) { abort(); } shortage -= len; return shortage > 0 ? shortage : 0; }
/* * Reload domain table to new hash table and when done, make new hash table * current one. */ int reload_domain_table ( void ) { db_key_t cols[2]; db_res_t* res = NULL; db_row_t* row; db_val_t* val; struct domain_list **new_hash_table; int i; str domain, attrs; cols[0] = &domain_col; cols[1] = &domain_attrs_col; if (domain_dbf.use_table(db_handle, &domain_table) < 0) { LM_ERR("Error while trying to use domain table\n"); return -3; } if (domain_dbf.query(db_handle, NULL, 0, NULL, cols, 0, 2, 0, &res) < 0) { LM_ERR("Error while querying database\n"); return -3; } /* 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; } 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++) { val = ROW_VALUES(row + i); if (VAL_TYPE(val) == DB_STRING) { domain.s = (char *)VAL_STRING(val); domain.len = strlen(domain.s); } else if (VAL_TYPE(val) == DB_STR) { domain = VAL_STR(val); } else { LM_ERR("Database problem on domain column\n"); domain_dbf.free_result(db_handle, res); return -3; } if (VAL_NULL(val + 1)) { /* add a marker to determine whether the attributes exist or not */ attrs.len = 0; attrs.s = NULL; } else if (VAL_TYPE(val + 1) == DB_STRING) { attrs.s = (char *)VAL_STRING(val + 1); attrs.len = strlen(attrs.s); } else if (VAL_TYPE(val + 1) == DB_STR) { attrs = VAL_STR(val + 1); } else { LM_ERR("Database problem on attrs column\n"); domain_dbf.free_result(db_handle, res); return -3; } LM_DBG("Value: %s inserted into domain hash table\n",VAL_STRING(val)); if (hash_table_install(new_hash_table, &domain, &attrs)==-1){ LM_ERR("Hash table problem\n"); domain_dbf.free_result(db_handle, res); return -3; } } domain_dbf.free_result(db_handle, res); *hash_table = new_hash_table; return 1; }
/* * Convert a str to a db value, does not copy strings * The postgresql module uses a custom escape function for BLOBs, * so the common db_str2val function from db_ut.h could not used. * If the _s is linked in the db_val result, it will be returned zero */ int pg_str2val(db_type_t _t, db_val_t* _v, char* _s, int _l) { static str dummy_string = {"", 0}; #ifdef PARANOID if (!_v) { LM_ERR("db_val_t parameter cannot be NULL\n"); } #endif 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("failed to convert INT value from string\n"); return -2; } else { VAL_TYPE(_v) = DB_INT; return 0; } break; case DB_BITMAP: LM_DBG("converting BITMAP [%s]\n", _s); if (db_str2int(_s, &VAL_INT(_v)) < 0) { LM_ERR("failed to convert 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("failed to convert 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", _s); VAL_STR(_v).s = (char*)_s; VAL_STR(_v).len = _l; VAL_TYPE(_v) = DB_STR; _s = 0; return 0; case DB_DATETIME: LM_DBG("converting DATETIME [%s]\n", _s); if (db_str2time(_s, &VAL_TIME(_v)) < 0) { LM_ERR("failed to convert datetime\n"); return -5; } else { VAL_TYPE(_v) = DB_DATETIME; return 0; } break; case DB_BLOB: LM_DBG("converting BLOB [%s]\n", _s); /* PQunescapeBytea: Converts a string representation of binary data * into binary data — the reverse of PQescapeBytea. * This is needed when retrieving bytea data in text format, * but not when retrieving it in binary format. */ VAL_BLOB(_v).s = (char*)PQunescapeBytea((unsigned char*)_s, (size_t*)(void*)&(VAL_BLOB(_v).len) ); VAL_TYPE(_v) = DB_BLOB; LM_DBG("got blob len %d\n", _l); return 0; } return -6; }
/** * 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 DB1_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) = DB1_INT; return 0; } break; case DB1_BIGINT: LM_ERR("BIGINT not supported"); return -1; case DB1_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) = DB1_BITMAP; return 0; } break; case DB1_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) = DB1_DOUBLE; return 0; } break; case DB1_STRING: VAL_STRING(_v) = _s; VAL_TYPE(_v) = DB1_STRING; VAL_FREE(_v) = 1; if( strlen(_s)==4 && !strncasecmp(_s, "NULL", 4) ) VAL_NULL(_v) = 1; return 0; case DB1_STR: VAL_STR(_v).s = (char*)_s; VAL_STR(_v).len = _l; VAL_TYPE(_v) = DB1_STR; VAL_FREE(_v) = 1; if( strlen(_s)==4 && !strncasecmp(_s, "NULL", 4) ) VAL_NULL(_v) = 1; return 0; case DB1_DATETIME: if (db_str2time(_s, &VAL_TIME(_v)) < 0) { LM_ERR("Error converting datetime\n"); return -5; } else { VAL_TYPE(_v) = DB1_DATETIME; return 0; } break; case DB1_BLOB: VAL_BLOB(_v).s = _s; VAL_TYPE(_v) = DB1_BLOB; LM_DBG("got blob len %d\n", _l); return 0; } return -6; }
/* * 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 DB1_INT: _m->addr = (int*)&VAL_INT(_v); _m->size = sizeof(VAL_INT(_v)); _m->type = SQLT_INT; break; case DB1_BIGINT: LM_ERR("BIGINT not supported"); return -1; case DB1_BITMAP: _m->addr = (unsigned*)&VAL_BITMAP(_v); _m->size = sizeof(VAL_BITMAP(_v)); _m->type = SQLT_UIN; break; case DB1_DOUBLE: _m->addr = (double*)&VAL_DOUBLE(_v); _m->size = sizeof(VAL_DOUBLE(_v)); _m->type = SQLT_FLT; break; case DB1_STRING: _m->addr = (char*)VAL_STRING(_v); _m->size = strlen(VAL_STRING(_v))+1; _m->type = SQLT_STR; break; case DB1_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 DB1_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 DB1_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; }
/* * Convert a str to a db value, does not copy strings * The postgresql module uses a custom escape function for BLOBs. * If the _s is linked in the db_val result, it will be returned zero */ int db_postgres_str2val(const db_type_t _t, db_val_t* _v, const char* _s, const int _l) { static str dummy_string = {"", 0}; char *x; 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_STR(_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("failed to convert INT value from string\n"); return -2; } else { VAL_TYPE(_v) = DB_INT; return 0; } break; case DB_BIGINT: LM_DBG("converting BIGINT [%s]\n", _s); if (db_str2bigint(_s, &VAL_BIGINT(_v)) < 0) { LM_ERR("failed to convert BIGINT 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("failed to convert 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("failed to convert 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; VAL_FREE(_v) = 1; 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; VAL_FREE(_v) = 1; return 0; case DB_DATETIME: LM_DBG("converting DATETIME [%s]\n", _s); if (db_str2time(_s, &VAL_TIME(_v)) < 0) { LM_ERR("failed to convert datetime\n"); return -5; } else { VAL_TYPE(_v) = DB_DATETIME; return 0; } break; case DB_BLOB: LM_DBG("converting BLOB [%.*s]\n", _l, _s); /* PQunescapeBytea: Converts a string representation of binary data * into binary data - the reverse of PQescapeBytea. * This is needed when retrieving bytea data in text format, * but not when retrieving it in binary format. */ x = (char*)PQunescapeBytea((unsigned char*)_s, (size_t*)(void*)&(VAL_BLOB(_v).len) ); VAL_BLOB(_v).s = pkg_malloc( VAL_BLOB(_v).len+1 ); if (VAL_BLOB(_v).s==NULL) { LM_ERR("failed to allocate pkg for BLOB\n"); return -6; } memcpy( VAL_BLOB(_v).s, x, VAL_BLOB(_v).len); VAL_BLOB(_v).s[VAL_BLOB(_v).len]='\0'; free(x); VAL_TYPE(_v) = DB_BLOB; VAL_FREE(_v) = 1; LM_DBG("got blob len %d\n", _l); return 0; } return -6; }
/* * Matches from uri against patterns returned from database. Returns number * of matches or -1 if none of the patterns match. */ static int match_res(struct sip_msg* msg, int proto, db1_res_t* _r) { int i, tag_avp_type; str uri, ruri; char uri_string[MAX_URI_SIZE+1]; char ruri_string[MAX_URI_SIZE+1]; db_row_t* row; db_val_t* val; regex_t preg; int_str tag_avp, avp_val; int count = 0; if (IS_SIP(msg)) { if (parse_from_header(msg) < 0) return -1; uri = get_from(msg)->uri; if (uri.len > MAX_URI_SIZE) { LM_ERR("message has From URI too large\n"); return -1; } memcpy(uri_string, uri.s, uri.len); uri_string[uri.len] = (char)0; ruri = msg->first_line.u.request.uri; if (ruri.len > MAX_URI_SIZE) { LM_ERR("message has Request URI too large\n"); return -1; } memcpy(ruri_string, ruri.s, ruri.len); ruri_string[ruri.len] = (char)0; } get_tag_avp(&tag_avp, &tag_avp_type); row = RES_ROWS(_r); for(i = 0; i < RES_ROW_N(_r); i++) { val = ROW_VALUES(row + i); if ((ROW_N(row + i) == 4) && (VAL_TYPE(val) == DB1_STRING) && !VAL_NULL(val) && match_proto(VAL_STRING(val), proto) && (VAL_NULL(val + 1) || ((VAL_TYPE(val + 1) == DB1_STRING) && !VAL_NULL(val + 1))) && (VAL_NULL(val + 2) || ((VAL_TYPE(val + 2) == DB1_STRING) && !VAL_NULL(val + 2))) && (VAL_NULL(val + 3) || ((VAL_TYPE(val + 3) == DB1_STRING) && !VAL_NULL(val + 3)))) { if (IS_SIP(msg)) { if (!VAL_NULL(val + 1)) { if (regcomp(&preg, (char *)VAL_STRING(val + 1), REG_NOSUB)) { LM_ERR("invalid regular expression\n"); if (VAL_NULL(val + 2)) { continue; } } if (regexec(&preg, uri_string, 0, (regmatch_t *)0, 0)) { regfree(&preg); continue; } regfree(&preg); } if (!VAL_NULL(val + 2)) { if (regcomp(&preg, (char *)VAL_STRING(val + 2), REG_NOSUB)) { LM_ERR("invalid regular expression\n"); continue; } if (regexec(&preg, ruri_string, 0, (regmatch_t *)0, 0)) { regfree(&preg); continue; } regfree(&preg); } } /* Found a match */ if (tag_avp.n && !VAL_NULL(val + 3)) { avp_val.s.s = (char *)VAL_STRING(val + 3); avp_val.s.len = strlen(avp_val.s.s); if (add_avp(tag_avp_type|AVP_VAL_STR, tag_avp, avp_val) != 0) { LM_ERR("failed to set of tag_avp failed\n"); return -1; } } if (!peer_tag_mode) return 1; count++; } } if (!count) return -1; else return count; }