/** * "pdt_add" syntax : * sdomain * prefix * domain */ struct mi_root* pdt_mi_add(struct mi_root* cmd_tree, void* param) { db_key_t db_keys[NR_KEYS] = {&sdomain_column, &prefix_column, &domain_column}; db_val_t db_vals[NR_KEYS]; db_op_t db_ops[NR_KEYS] = {OP_EQ, OP_EQ}; int i= 0; str sd, sp, sdomain; struct mi_node* node= NULL; if(_ptree==NULL) { LM_ERR("strange situation\n"); return init_mi_tree( 500, MI_INTERNAL_ERR_S, MI_INTERNAL_ERR_LEN); } /* read sdomain */ node = cmd_tree->node.kids; if(node == NULL) goto error1; sdomain = node->value; if(sdomain.s == NULL || sdomain.len== 0) return init_mi_tree( 404, "domain not found", 16); if(*sdomain.s=='.' ) return init_mi_tree( 400, "empty param",11); /* read prefix */ node = node->next; if(node == NULL) goto error1; sp= node->value; if(sp.s== NULL || sp.len==0) { LM_ERR("could not read prefix\n"); return init_mi_tree( 404, "prefix not found", 16); } if(*sp.s=='.') return init_mi_tree(400, "empty param", 11); while(i< sp.len) { if(strpos(pdt_char_list.s,sp.s[i]) < 0) return init_mi_tree(400, "bad prefix", 10); i++; } /* read domain */ node= node->next; if(node == NULL || node->next!=NULL) goto error1; sd= node->value; if(sd.s== NULL || sd.len==0) { LM_ERR("could not read domain\n"); return init_mi_tree( 400, "domain not found", 16); } if(*sd.s=='.') return init_mi_tree(400, "empty param", 11); if(pdt_check_domain!=0 && *_ptree!=NULL && pdt_check_pd(*_ptree, &sdomain, &sp, &sd)==1) { LM_ERR("(sdomain,prefix,domain) exists\n"); return init_mi_tree(400, "(sdomain,prefix,domain) exists already", 38); } db_vals[0].type = DB_STR; db_vals[0].nul = 0; db_vals[0].val.str_val.s = sdomain.s; db_vals[0].val.str_val.len = sdomain.len; db_vals[1].type = DB_STR; db_vals[1].nul = 0; db_vals[1].val.str_val.s = sp.s; db_vals[1].val.str_val.len = sp.len; db_vals[2].type = DB_STR; db_vals[2].nul = 0; db_vals[2].val.str_val.s = sd.s; db_vals[2].val.str_val.len = sd.len; /* insert a new domain into database */ if(pdt_dbf.insert(db_con, db_keys, db_vals, NR_KEYS)<0) { LM_ERR("failed to store new prefix/domain\n"); return init_mi_tree( 500,"Cannot store prefix/domain", 26); } /* re-loading all information from database */ if(pdt_load_db()!=0) { LM_ERR("cannot re-load info from database\n"); goto error; } LM_DBG("new prefix added %.*s-%.*s => %.*s\n", sdomain.len, sdomain.s, sp.len, sp.s, sd.len, sd.s); return init_mi_tree( 200, MI_OK_S, MI_OK_LEN); error: if(pdt_dbf.delete(db_con, db_keys, db_ops, db_vals, NR_KEYS)<0) LM_ERR("database/cache are inconsistent\n"); return init_mi_tree( 500, "could not add to cache", 23 ); error1: return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); }
static void rpc_add(rpc_t* rpc, void* c) { db_key_t db_keys[NR_KEYS] = {prefix_column, domain_column}; db_val_t db_vals[NR_KEYS]; db_op_t db_ops[NR_KEYS] = {OP_EQ, OP_EQ}; pd_t* cell; pd_op_t *ito, *tmp; str sd, sp; char* t; if(_dhash==NULL) { LOG(L_ERR, "PDT:pdt_fifo_add: strange situation\n"); rpc->fault(c, 500, "Server Error"); return; } /* Use 's' to make sure strings are zero terminated */ if (rpc->scan(c, "ss", &sp.s, &sd.s) < 2) { rpc->fault(c, 400, "Invalid Parameter Value"); return; } sp.len = strlen(sp.s); sd.len = strlen(sd.s); t = sp.s; while(t!=NULL && *t!='\0') { if(*t < '0' || *t > '9') { LOG(L_ERR, "PDT:pdt_fifo_add: bad prefix [%s]\n", sp.s); rpc->fault(c, 400, "Bad Prefix"); return; } t++; } if(pdt_check_pd(_dhash, &sp, &sd)!=0) { LOG(L_ERR, "PDT:pdt_fifo_add: prefix or domain exists\n"); rpc->fault(c, 400, "Prefix Or Domain Exists"); return; } db_vals[0].type = DB_STR; db_vals[0].nul = 0; db_vals[0].val.str_val = sp; db_vals[1].type = DB_STR; db_vals[1].nul = 0; db_vals[1].val.str_val= sd; DBG("PDT:pdt_fifo_add: [%.*s] <%.*s>\n", sp.len, sp.s, sd.len, sd.s); /* insert a new domain into database */ if(pdt_dbf.insert(db_con, db_keys, db_vals, NR_KEYS)<0) { LOG(L_ERR, "PDT:pdt_fifo_add: error storing new prefix/domain\n"); rpc->fault(c, 430, "Cannot Store Prefix/domain"); return; } /* insert the new domain into hashtables, too */ cell = new_cell(&sp, &sd); if(cell==NULL) { LOG(L_ERR, "PDT:pdt_fifo_add: no more shm\n"); rpc->fault(c, 431, "Out Of Shared Memory"); goto error1; } tmp = new_pd_op(cell, 0, PDT_ADD); if(tmp==NULL) { LOG(L_ERR, "PDT:pdt_fifo_add: no more shm!\n"); rpc->fault(c, 431, "Out Of Shared Memory"); goto error2; } lock_get(&_dhash->diff_lock); if(pdt_add_to_hash(_dhash, &sp, &sd)!=0) { LOG(L_ERR, "PDT:pdt_fifo_add: could not add to cache\n"); rpc->fault(c, 431, "Could Not Add To Cache"); goto error3; } _dhash->max_id++; tmp->id = _dhash->max_id; if(_dhash->diff==NULL) { _dhash->diff = tmp; goto done; } ito = _dhash->diff; while(ito->n!=NULL) ito = ito->n; ito->n = tmp; tmp->p = ito; done: DBG("PDT:pdt_fifo_add: op[%d]=%d...\n", tmp->id, tmp->op); lock_release(&_dhash->diff_lock); return; error3: lock_release(&_dhash->diff_lock); free_pd_op(tmp); error2: free_cell(cell); error1: if(pdt_dbf.delete(db_con, db_keys, db_ops, db_vals, NR_KEYS)<0) LOG(L_ERR,"PDT:pdt_fifo_add: database/cache are inconsistent\n"); }
static int pdt_load_db(void) { db_key_t db_cols[3] = {&sdomain_column, &prefix_column, &domain_column}; str p, d, sdomain; db_res_t* db_res = NULL; int i, ret; pdt_tree_t *_ptree_new = NULL; pdt_tree_t *old_tree = NULL; int no_rows = 10; if(db_con==NULL) { LM_ERR("no db connection\n"); return -1; } if (pdt_dbf.use_table(db_con, &db_table) < 0) { LM_ERR("failed to use_table\n"); return -1; } if (DB_CAPABILITY(pdt_dbf, DB_CAP_FETCH)) { if(pdt_dbf.query(db_con,0,0,0,db_cols,0,3,&sdomain_column,0) < 0) { LM_ERR("Error while querying db\n"); return -1; } no_rows = estimate_available_rows( 64+16+64, 3); if (no_rows==0) no_rows = 10; if(pdt_dbf.fetch_result(db_con, &db_res, no_rows)<0) { LM_ERR("Error while fetching result\n"); if (db_res) pdt_dbf.free_result(db_con, db_res); goto error; } else { if(RES_ROW_N(db_res)==0) { return 0; } } } else { if((ret=pdt_dbf.query(db_con, NULL, NULL, NULL, db_cols, 0, 3, &sdomain_column, &db_res))!=0 || RES_ROW_N(db_res)<=0 ) { pdt_dbf.free_result(db_con, db_res); if( ret==0) { return 0; } else { goto error; } } } do { for(i=0; i<RES_ROW_N(db_res); i++) { /* check for NULL values ?!?! */ sdomain.s = (char*)(RES_ROWS(db_res)[i].values[0].val.string_val); sdomain.len = strlen(sdomain.s); p.s = (char*)(RES_ROWS(db_res)[i].values[1].val.string_val); p.len = strlen(p.s); d.s = (char*)(RES_ROWS(db_res)[i].values[2].val.string_val); d.len = strlen(d.s); if(p.s==NULL || d.s==NULL || sdomain.s==NULL || p.len<=0 || d.len<=0 || sdomain.len<=0) { LM_ERR("Error - bad values in db\n"); continue; } if(pdt_check_domain!=0 && _ptree_new!=NULL && pdt_check_pd(_ptree_new, &sdomain, &p, &d)==1) { LM_ERR("sdomain [%.*s]: prefix [%.*s] or domain <%.*s> " "duplicated\n", sdomain.len, sdomain.s, p.len, p.s, d.len, d.s); continue; } if(pdt_add_to_tree(&_ptree_new, &sdomain, &p, &d)<0) { LM_ERR("Error adding info to tree\n"); goto error; } } if (DB_CAPABILITY(pdt_dbf, DB_CAP_FETCH)) { if(pdt_dbf.fetch_result(db_con, &db_res, no_rows)<0) { LM_ERR("Error while fetching!\n"); if (db_res) pdt_dbf.free_result(db_con, db_res); goto error; } } else { break; } } while(RES_ROW_N(db_res)>0); pdt_dbf.free_result(db_con, db_res); /* block all readers */ lock_start_write( pdt_lock ); old_tree = *_ptree; *_ptree = _ptree_new; lock_stop_write( pdt_lock ); /* free old data */ if (old_tree!=NULL) pdt_free_tree(old_tree); return 0; error: pdt_dbf.free_result(db_con, db_res); if (_ptree_new!=NULL) pdt_free_tree(_ptree_new); return -1; }
int pdt_load_db() { db_key_t db_cols[] = {prefix_column, domain_column}; str p, d; db_res_t* db_res = NULL; int i; if(db_con==NULL) { LOG(L_ERR, "PDT:pdt_load_db: no db connection\n"); return -1; } if (pdt_dbf.use_table(db_con, db_table) < 0) { LOG(L_ERR, "PDT:pdt_load_db: Error in use_table\n"); return -1; } if(pdt_dbf.query(db_con, NULL, NULL, NULL, db_cols, 0, 2, prefix_column, &db_res)==0) { for(i=0; i<RES_ROW_N(db_res); i++) { /* check for NULL values ?!?! */ p.s = (char*)(RES_ROWS(db_res)[i].values[0].val.string_val); p.len = strlen(p.s); d.s = (char*)(RES_ROWS(db_res)[i].values[1].val.string_val); d.len = strlen(d.s); if(p.s==NULL || d.s==NULL || p.len<=0 || d.len<=0) { LOG(L_ERR, "PDT:pdt_load_db: Error - bad values in db\n"); goto error; } if(pdt_check_pd(_dhash, &p, &d)!=0) { LOG(L_ERR, "PDT:pdt_load_db: prefix [%.*s] or domain <%.*s> duplicated\n", p.len, p.s, d.len, d.s); goto error;; } if(pdt_add_to_tree(_ptree, &p, &d)!=0) { LOG(L_ERR, "PDT:pdt_load_db: Error adding info in tree\n"); goto error; } if(pdt_add_to_hash(_dhash, &p, &d)!=0) { LOG(L_ERR, "PDT:pdt_load_db: Error adding info in hash\n"); goto error; } } } pdt_dbf.free_result(db_con, db_res); return 0; error: pdt_dbf.free_result(db_con, db_res); return -1; }