static struct mi_root *mi_reset_stats(struct mi_root *cmd, void *param) { struct mi_root *rpl_tree; struct mi_node *arg; stat_var *stat; int found; if (cmd->node.kids==NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if (rpl_tree==0) return 0; found = 0; for( arg=cmd->node.kids ; arg ; arg=arg->next) { if (arg->value.len==0) continue; stat = get_stat( &arg->value ); if (stat==0) continue; reset_stat( stat ); found = 1; } if (!found) { free_mi_tree(rpl_tree); return init_mi_tree( 404, "Statistics Not Found", 20); } return rpl_tree; }
static struct mi_root *mi_dump_secrets(struct mi_root *cmd, void *param) { int pos = 0; struct secret *secret_struct = secret_list; struct mi_root *rpl_tree; if (cmd->node.kids != NULL) { LM_WARN("too many parameters\n"); return init_mi_tree(400, str_status_too_many_params.s, str_status_too_many_params.len); } rpl_tree = init_mi_tree(200, MI_OK_S, MI_OK_LEN); if (rpl_tree == NULL) return 0; SECRET_LOCK; while (secret_struct != NULL) { if (addf_mi_node_child(&rpl_tree->node, 0, 0, 0, "ID %d: %.*s", pos++, secret_struct->secret_key.len, secret_struct->secret_key.s) == 0) { free_mi_tree(rpl_tree); SECRET_UNLOCK; return 0; } secret_struct = secret_struct->next; } SECRET_UNLOCK; return rpl_tree; }
/* lists all domains */ static struct mi_root * tls_list(struct mi_root *cmd_tree, void *param) { struct mi_node *root = NULL; struct mi_root *rpl_tree = NULL; rpl_tree = init_mi_tree(200, MI_OK_S, MI_OK_LEN); if (rpl_tree == NULL) { return NULL; } lock_start_read(dom_lock); root = &rpl_tree->node; if (list_domain(root, tls_client_domains) < 0) goto error; if (list_domain(root, tls_server_domains) < 0) goto error; lock_stop_read(dom_lock); return rpl_tree; error: lock_stop_read(dom_lock); if (rpl_tree) free_mi_tree(rpl_tree); return NULL; }
struct mi_root* mi_get_pid(struct mi_root* cmd_tree, void* param) { struct mi_root *rpl_tree; struct mi_node *node=NULL, *rpl=NULL; struct mi_attr* attr; rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if (rpl_tree==0) return 0; rpl = &rpl_tree->node; node = add_mi_node_child(rpl, 0, "PID", 3, 0, 0); if(node == NULL) goto error; rpl_pipe_lock(0); attr= addf_mi_attr(node, 0, "ki", 2, "%0.3f", *pid_ki); if(attr == NULL) goto error; attr= addf_mi_attr(node, 0, "kp", 2, "%0.3f", *pid_kp); if(attr == NULL) goto error; attr= addf_mi_attr(node, 0, "kd", 2, "%0.3f", *pid_kd); rpl_pipe_release(0); if(attr == NULL) goto error; return rpl_tree; error: rpl_pipe_release(0); LM_ERR("Unable to create reply\n"); free_mi_tree(rpl_tree); return 0; }
/* used to list all the registered events */ struct mi_root * mi_events_list(struct mi_root *cmd_tree, void *param) { struct mi_root *rpl_tree; struct mi_node *node=NULL, *rpl=NULL; unsigned i; rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if (rpl_tree==0) return 0; rpl = &rpl_tree->node; for (i = 0; i < events_no; i++) { node = add_mi_node_child(rpl, 0, "Event", 5, events[i].name.s, events[i].name.len); if(node == NULL) goto error; if (!addf_mi_attr(node, 0, "id", 2, "%d", events[i].id)) goto error; if ((i + 1) % 50 == 0) { flush_mi_tree(rpl_tree); } } return rpl_tree; error: free_mi_tree(rpl_tree); return 0; }
/*! * \brief Print a dialog context via the MI interface * \param cmd_tree MI command tree * \param param unused * \return mi node with the dialog information, or NULL on failure */ struct mi_root * mi_print_dlgs_ctx(struct mi_root *cmd_tree, void *param ) { struct mi_root* rpl_tree= NULL; struct mi_node* rpl = NULL; struct dlg_cell* dlg = NULL; rpl_tree = process_mi_params( cmd_tree, &dlg); if (rpl_tree) /* param error */ return rpl_tree; rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK)); if (rpl_tree==0) return 0; rpl = &rpl_tree->node; if (dlg==NULL) { if ( internal_mi_print_dlgs(rpl,1)!=0 ) goto error; } else { if ( internal_mi_print_dlg(rpl,dlg,1)!=0 ) goto error; } return rpl_tree; error: free_mi_tree(rpl_tree); return NULL; }
static struct mi_root *mi_which(struct mi_root *cmd, void *param) { struct mi_root *rpl_tree; struct mi_cmd *cmds; struct mi_node *rpl; struct mi_node *node; int size; int i; rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK)); if (rpl_tree==0) return 0; rpl = &rpl_tree->node; get_mi_cmds( &cmds, &size); for ( i=0 ; i<size ; i++ ) { node = add_mi_node_child( rpl, 0, 0, 0, cmds[i].name.s, cmds[i].name.len); if (node==0) { LM_ERR("failed to add node\n"); free_mi_tree(rpl_tree); return 0; } } return rpl_tree; }
struct mi_root * mi_print_dlgs_ctx(struct mi_root *cmd_tree, void *param ) { struct mi_root* rpl_tree= NULL; struct mi_node* rpl = NULL; struct dlg_cell* dlg = NULL; unsigned int idx,cnt; rpl_tree = process_mi_params( cmd_tree, &dlg, &idx, &cnt); if (rpl_tree) /* param error */ return rpl_tree; rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK)); if (rpl_tree==0) goto error; rpl = &rpl_tree->node; if (dlg==NULL) { if ( internal_mi_print_dlgs(rpl_tree, rpl, 1, idx, cnt)!=0 ) goto error; } else { if ( internal_mi_print_dlg(rpl,dlg,1)!=0 ) goto error; /* done with the dialog -> unlock it */ dlg_unlock_dlg(dlg); } return rpl_tree; error: /* if a dialog ref was returned, unlock it now */ if (dlg) dlg_unlock_dlg(dlg); /* trash everything that was built so far */ if (rpl_tree) free_mi_tree(rpl_tree); return NULL; }
static struct mi_root* mi_list_root_path(struct mi_root* cmd, void* param) { struct mi_root *rpl_tree; struct mi_node *node, *rpl; struct mi_attr* attr; struct httpd_cb *cb = httpd_cb_list; rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if (rpl_tree==NULL) return NULL; rpl = &rpl_tree->node; rpl->flags |= MI_IS_ARRAY; while(cb) { node = add_mi_node_child(rpl, 0, "http_root", 9, cb->http_root->s, cb->http_root->len); if(node == NULL) goto error; attr = add_mi_attr(node, 0, "module", 6, (char*)cb->module, strlen(cb->module)); if(attr == NULL) goto error; cb = cb->next; } return rpl_tree; error: LM_ERR("Unable to create reply\n"); free_mi_tree(rpl_tree); return NULL; }
/*! * \brief fifo command for listing configuration * \return pointer to the mi_root on success, 0 otherwise */ static struct mi_root* forward_fifo_list(struct mi_root* cmd_tree, void *param) { struct mi_node *node = NULL; struct mi_root * ret = init_mi_tree(200, MI_OK_S, MI_OK_LEN); if(ret == NULL) return 0; node = addf_mi_node_child( &ret->node, 0, 0, 0, "Printing forwarding information:"); if(node == NULL) goto error; // critical section start: // avoids dirty reads when updating configuration. lock_get(conf_lock); conf_show(ret); // critical section end lock_release(conf_lock); return ret; error: free_mi_tree(ret); return 0; }
struct mi_root* mt_mi_summary(struct mi_root* cmd_tree, void* param) { m_tree_t *pt; struct mi_root* rpl_tree = NULL; struct mi_node* node = NULL; struct mi_attr* attr= NULL; str val; if(!mt_defined_trees()) { LM_ERR("empty tree list\n"); return init_mi_tree( 500, "No trees", 8); } rpl_tree = init_mi_tree(200, MI_OK_S, MI_OK_LEN); if(rpl_tree == NULL) return 0; pt = mt_get_first_tree(); while(pt!=NULL) { node = add_mi_node_child(&rpl_tree->node, 0, "MT", 2, 0, 0); if(node == NULL) goto error; attr = add_mi_attr(node, MI_DUP_VALUE, "TNAME", 5, pt->tname.s, pt->tname.len); if(attr == NULL) goto error; val.s = int2str(pt->type, &val.len); attr = add_mi_attr(node, MI_DUP_VALUE, "TTYPE", 5, val.s, val.len); if(attr == NULL) goto error; val.s = int2str(pt->memsize, &val.len); attr = add_mi_attr(node, MI_DUP_VALUE, "MEMSIZE", 7, val.s, val.len); if(attr == NULL) goto error; val.s = int2str(pt->nrnodes, &val.len); attr = add_mi_attr(node, MI_DUP_VALUE, "NRNODES", 7, val.s, val.len); if(attr == NULL) goto error; val.s = int2str(pt->nritems, &val.len); attr = add_mi_attr(node, MI_DUP_VALUE, "NRITEMS", 7, val.s, val.len); if(attr == NULL) goto error; pt = pt->next; } return rpl_tree; error: free_mi_tree(rpl_tree); return 0; }
struct mi_root *run_rcv_mi_cmd(str *cmd_name, str *cmd_params, int nr_params) { struct mi_cmd *f; struct mi_root *cmd_root = NULL, *cmd_rpl; int i; f = lookup_mi_cmd(cmd_name->s, cmd_name->len); if (!f) { LM_ERR("MI command to be run not found\n"); return NULL; } if (f->flags & MI_NO_INPUT_FLAG && nr_params) { LM_ERR("MI command should not have parameters\n"); return NULL; } if (!(f->flags & MI_NO_INPUT_FLAG)) { cmd_root = init_mi_tree(0,0,0); if (!cmd_root) { LM_ERR("the MI tree for the command to be run cannot be initialized!\n"); return NULL; } } for (i = 0; i < nr_params; i++) if (!add_mi_node_child(&cmd_root->node, 0, 0, 0, cmd_params[i].s, cmd_params[i].len)) { free_mi_tree(cmd_root); LM_ERR("cannot add child node to the tree of the MI command to be run\n"); return NULL; } if ((cmd_rpl = run_mi_cmd(f, cmd_root, 0, 0)) == NULL) { if (cmd_root) free_mi_tree(cmd_root); return NULL; } if (cmd_root) free_mi_tree(cmd_root); return cmd_rpl; }
struct mi_root* mt_mi_list(struct mi_root* cmd_tree, void* param) { str tname = {0, 0}; m_tree_t *pt; struct mi_node* node = NULL; struct mi_root* rpl_tree = NULL; struct mi_node* rpl = NULL; static char code_buf[MT_MAX_DEPTH+1]; int len; if(!mt_defined_trees()) { LM_ERR("empty tree list\n"); return init_mi_tree( 500, MI_INTERNAL_ERR_S, MI_INTERNAL_ERR_LEN); } /* read tree name */ node = cmd_tree->node.kids; if(node != NULL) { tname = node->value; if(tname.s == NULL || tname.len== 0) return init_mi_tree( 404, "domain not found", 16); if(*tname.s=='.') { tname.s = 0; tname.len = 0; } } rpl_tree = init_mi_tree(200, MI_OK_S, MI_OK_LEN); if(rpl_tree == NULL) return 0; rpl = &rpl_tree->node; pt = mt_get_first_tree(); while(pt!=NULL) { if(tname.s==NULL || (tname.s!=NULL && pt->tname.len>=tname.len && strncmp(pt->tname.s, tname.s, tname.len)==0)) { len = 0; if(mt_print_mi_node(pt, pt->head, rpl, code_buf, len)<0) goto error; } pt = pt->next; } return rpl_tree; error: free_mi_tree(rpl_tree); return 0; }
int mi_xmlrpc_http_answer_to_connection (void *cls, void *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls, str *buffer, str *page) { str arg = {NULL, 0}; struct mi_root *tree = NULL; struct mi_handler *async_hdl; int ret_code = MI_XMLRPC_OK; LM_DBG("START *** cls=%p, connection=%p, url=%s, method=%s, " "versio=%s, upload_data[%d]=%p, *con_cls=%p\n", cls, connection, url, method, version, (int)*upload_data_size, upload_data, *con_cls); if (strncmp(method, "POST", 4)==0) { httpd_api.lookup_arg(connection, "1", *con_cls, &arg); if (arg.s) { tree = mi_xmlrpc_http_run_mi_cmd(&arg, page, buffer, &async_hdl); if (tree == NULL) { LM_ERR("no reply\n"); *page = MI_XMLRPC_U_ERROR; ret_code = MI_XMLRPC_INTERNAL_ERROR; } else if (tree == MI_ROOT_ASYNC_RPL) { LM_DBG("got an async reply\n"); tree = NULL; } else { LM_DBG("building on page [%p:%d]\n", page->s, page->len); if(0!=mi_xmlrpc_http_build_page(page, buffer->len, tree)){ LM_ERR("unable to build response\n"); *page = MI_XMLRPC_U_ERROR; ret_code = MI_XMLRPC_INTERNAL_ERROR; } else { ret_code = tree->code; } } } else { page->s = buffer->s; LM_ERR("unable to build response for empty request\n"); *page = MI_XMLRPC_U_ERROR; ret_code = MI_XMLRPC_INTERNAL_ERROR; } if (tree) { free_mi_tree(tree); tree = NULL; } } else { LM_ERR("unexpected method [%s]\n", method); *page = MI_XMLRPC_U_METHOD; return MI_XMLRPC_NOT_ACCEPTABLE; } return ret_code; }
static void datagram_close_async(struct mi_root *mi_rpl,struct mi_handler *hdl, int done) { datagram_stream dtgram; int ret; my_socket_address *p; int reply_sock, flags; p = (my_socket_address *)hdl->param; LM_DBG("the socket domain is %i and af_local is %i\n", p->domain, AF_LOCAL); memset(&dtgram, 0, sizeof(dtgram)); mi_create_dtgram_replysocket(reply_sock, p->domain, err); if (mi_rpl!=0) { /*allocate the response datagram*/ dtgram.start = pkg_malloc(DATAGRAM_SOCK_BUF_SIZE); if(!dtgram.start) { LM_ERR("no more pkg memory\n"); goto err; } /*build the response*/ if(mi_datagram_write_tree(&dtgram , mi_rpl) != 0) { LM_ERR("failed to build the response \n"); goto err; } LM_DBG("the response is %s", dtgram.start); /*send the response*/ ret = mi_send_dgram(reply_sock, dtgram.start, dtgram.current - dtgram.start, (struct sockaddr *)&p->address, p->address_len, mi_socket_timeout); if (ret>0) { LM_DBG("the response: %s has been sent in %i octets\n", dtgram.start, ret); } else { LM_ERR("failed to send the response, ret is %i\n",ret); } free_mi_tree(mi_rpl); pkg_free(dtgram.start); if (done) free_async_handler( hdl ); } else if (done) { mi_send_dgram(reply_sock, MI_COMMAND_FAILED, MI_COMMAND_FAILED_LEN, (struct sockaddr*)&reply_addr, reply_addr_len, mi_socket_timeout); free_async_handler( hdl ); } close(reply_sock); return; err: if(dtgram.start) pkg_free(dtgram.start); close(reply_sock); if (done) free_async_handler( hdl ); return; }
static void datagram_close_async(struct mi_root *mi_rpl,struct mi_handler *hdl, int done) { datagram_stream dtgram; int ret; my_socket_address *p; p = (my_socket_address *)hdl->param; if ( mi_rpl!=0 || done ) { if (mi_rpl!=0) { /*allocate the response datagram*/ dtgram.start = pkg_malloc(DATAGRAM_SOCK_BUF_SIZE); if(!dtgram.start){ LM_ERR("no more pkg memory\n"); goto err; } /*build the response*/ if(mi_datagram_write_tree(&dtgram , mi_rpl) != 0){ LM_ERR("failed to build the response \n"); goto err1; } LM_DBG("the response is %s", dtgram.start); /*send the response*/ ret = mi_send_dgram(p->tx_sock, dtgram.start, dtgram.current - dtgram.start, (struct sockaddr *)&p->address, p->address_len, mi_socket_timeout); if (ret>0){ LM_DBG("the response: %s has been sent in %i octets\n", dtgram.start, ret); }else{ LM_ERR("failed to send the response, ret is %i\n",ret); } free_mi_tree( mi_rpl ); pkg_free(dtgram.start); } else { mi_send_dgram(p->tx_sock, MI_COMMAND_FAILED, MI_COMMAND_FAILED_LEN, (struct sockaddr*)&reply_addr, reply_addr_len, mi_socket_timeout); } } if (done) free_async_handler( hdl ); return; err1: pkg_free(dtgram.start); err: return; }
struct mi_root *mi_help(struct mi_root *root, void *param) { struct mi_root *rpl_tree = 0; struct mi_node *node; struct mi_node *rpl; struct mi_cmd *cmd; if (!root) { LM_ERR("invalid MI command\n"); return 0; } node = root->node.kids; if (!node || !node->value.len || !node->value.s) { rpl_tree = init_mi_tree(200, MI_SSTR(MI_OK)); if (!rpl_tree) { LM_ERR("cannot init mi tree\n"); return 0; } rpl = &rpl_tree->node; if (!add_mi_node_child(rpl, 0, "Usage", 5, MI_SSTR(MI_HELP_STR))) { LM_ERR("cannot add new child\n"); goto error; } } else { /* search the command */ cmd = lookup_mi_cmd(node->value.s, node->value.len); if (!cmd) return init_mi_tree(404, MI_SSTR(MI_UNKNOWN_CMD)); rpl_tree = init_mi_tree(200, MI_SSTR(MI_OK)); if (!rpl_tree) { LM_ERR("cannot init mi tree\n"); return 0; } rpl = &rpl_tree->node; if (!addf_mi_node_child(rpl, 0, "Help", 4, "%s", cmd->help.s ? cmd->help.s : MI_NO_HELP)) { LM_ERR("cannot add new child\n"); goto error; } if (cmd->module.len && cmd->module.s && !add_mi_node_child(rpl, 0, "Exported by", 11, cmd->module.s, cmd->module.len)) { LM_ERR("cannot add new child\n"); goto error; } } return rpl_tree; error: if (rpl_tree) free_mi_tree(rpl_tree); return 0; }
/************************* MI ***********************/ static struct mi_root* imc_mi_list_rooms(struct mi_root* cmd_tree, void* param) { int i, len; struct mi_root* rpl_tree= NULL; struct mi_node* rpl= NULL; struct mi_node* node= NULL; struct mi_attr* attr= NULL; imc_room_p irp = NULL; char* p = NULL; rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if(rpl_tree == NULL) return 0; rpl = &rpl_tree->node; rpl->flags |= MI_IS_ARRAY; for(i=0; i<imc_hash_size; i++) { lock_get(&_imc_htable[i].lock); irp = _imc_htable[i].rooms; while(irp){ node = add_mi_node_child(rpl, 0, "ROOM", 4, 0, 0); if( node == NULL) goto error; attr= add_mi_attr(node, MI_DUP_VALUE, "URI", 3, irp->uri.s, irp->uri.len); if(attr == NULL) goto error; p = int2str(irp->nr_of_members, &len); attr= add_mi_attr(node, 0, "MEMBERS", 7,p, len ); if(attr == NULL) goto error; attr= add_mi_attr(node, MI_DUP_VALUE, "OWNER", 5, irp->members->uri.s, irp->members->uri.len); if(attr == NULL) goto error; irp = irp->next; } lock_release(&_imc_htable[i].lock); } return rpl_tree; error: lock_release(&_imc_htable[i].lock); free_mi_tree(rpl_tree); return 0; }
struct mi_root* mi_get_pipes(struct mi_root* cmd_tree, void* param) { struct mi_root *rpl_tree; struct mi_node *node=NULL, *rpl=NULL; struct mi_attr* attr; str algo; char* p; int i, len; rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if (rpl_tree==0) return 0; rpl = &rpl_tree->node; LOCK_GET(rl_lock); for (i=0; i<MAX_PIPES; i++) { if (*pipes[i].algo != PIPE_ALGO_NOP) { node = add_mi_node_child(rpl, 0, "PIPE", 4, 0, 0); if(node == NULL) goto error; p = int2str((unsigned long)(i), &len); attr = add_mi_attr(node, MI_DUP_VALUE, "id" , 2, p, len); if(attr == NULL) goto error; p = int2str((unsigned long)(*pipes[i].algo), &len); if (str_map_int(algo_names, *pipes[i].algo, &algo)) goto error; attr = add_mi_attr(node, 0, "algorithm", 9, algo.s, algo.len); if(attr == NULL) goto error; p = int2str((unsigned long)(*pipes[i].limit), &len); attr = add_mi_attr(node, MI_DUP_VALUE, "limit", 5, p, len); if(attr == NULL) goto error; p = int2str((unsigned long)(*pipes[i].counter), &len); attr = add_mi_attr(node, MI_DUP_VALUE, "counter", 7, p, len); if(attr == NULL) goto error; } } LOCK_RELEASE(rl_lock); return rpl_tree; error: LOCK_RELEASE(rl_lock); LM_ERR("Unable to create reply\n"); free_mi_tree(rpl_tree); return 0; }
/* * MI function to print subnets from current subnet table */ struct mi_root* mi_subnet_dump(struct mi_root *cmd_tree, void *param) { struct mi_root* rpl_tree; struct mi_node *node = NULL; struct pm_part_struct *it, *ps; if (cmd_tree) node = cmd_tree->node.kids; rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK)); if (node == NULL) { /* dump all subnets */ for (it=get_part_structs(); it; it = it->next) { if (it->subnet_table == NULL) continue; if (subnet_table_mi_print(*it->subnet_table, &rpl_tree->node, it) < 0) { LM_ERR("failed to add a node\n"); free_mi_tree(rpl_tree); return 0; } } } else { ps = get_part_struct(&node->value); if (ps == NULL) return init_mi_tree(404, MI_SSTR("No such partition")); if (ps->subnet_table == NULL) return init_mi_tree( 200, MI_SSTR(MI_OK)); /* dump requested subnet*/ if (subnet_table_mi_print(*ps->subnet_table, &rpl_tree->node, ps) < 0) { LM_ERR("failed to add a node\n"); free_mi_tree(rpl_tree); return 0; } } return rpl_tree; }
struct mi_root *mi_rpc_read_params(rpc_t *rpc, void *ctx) { struct mi_root *root; struct mi_node *node; str name; str value; root = init_mi_tree(0,0,0); if (!root) { LM_ERR("the MI tree cannot be initialized!\n"); goto error; } node = &root->node; while (rpc->scan(ctx, "*.S", &value) == 1) { name.s = 0; name.len = 0; if(value.len>=2 && value.s[0]=='-' && value.s[1]=='-') { /* name */ if(value.len>2) { name.s = value.s + 2; name.len = value.len - 2; } /* value */ if(rpc->scan(ctx, "*.S", &value) != 1) { LM_ERR("value expected\n"); goto error; } } if(!add_mi_node_child(node, 0, name.s, name.len, value.s, value.len)) { LM_ERR("cannot add the child node to the MI tree\n"); goto error; } } return root; error: if (root) free_mi_tree(root); return 0; }
static struct mi_root* mi_reg_reload(struct mi_root* cmd, void* param) { struct mi_root *rpl_tree; int i; int err = 0; rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if (rpl_tree==NULL) return NULL; for(i=0; i<reg_hsize; i++) { lock_get(®_htable[i].lock); if (reg_htable[i].s_list!=NULL) { LM_ERR("Found non NULL s_list\n"); slinkedl_list_destroy(reg_htable[i].s_list); reg_htable[i].s_list = NULL; } reg_htable[i].s_list = slinkedl_init(®_alloc, ®_free); if (reg_htable[i].p_list == NULL) { LM_ERR("oom while allocating list\n"); err = 1; } lock_release(®_htable[i].lock); if (err) goto error; } /* Load registrants into the secondary list */ if(load_reg_info_from_db(1) !=0){ LM_ERR("unable to reload the registrant data\n"); free_mi_tree(rpl_tree); goto error; } /* Swap the lists: secondary will become primary */ for(i=0; i<reg_hsize; i++) { lock_get(®_htable[i].lock); slinkedl_list_destroy(reg_htable[i].p_list); reg_htable[i].p_list = reg_htable[i].s_list; reg_htable[i].s_list = NULL; lock_release(®_htable[i].lock); } return rpl_tree; error: for(i=0; i<reg_hsize; i++) { lock_get(®_htable[i].lock); if (reg_htable[i].s_list) slinkedl_list_destroy(reg_htable[i].s_list); reg_htable[i].s_list = NULL; lock_release(®_htable[i].lock); } return NULL; }
static struct mi_root * clusterer_list_cap(struct mi_root *cmd_tree, void *param) { cluster_info_t *cl; struct local_cap *cap; struct mi_root *rpl_tree = NULL; struct mi_node *node = NULL; struct mi_node *node_s = NULL; struct mi_attr* attr; str val; static str str_ok = str_init("Ok"); static str str_not_synced = str_init("not synced"); rpl_tree = init_mi_tree(200, MI_OK_S, MI_OK_LEN); if (!rpl_tree) return NULL; rpl_tree->node.flags |= MI_IS_ARRAY; lock_start_read(cl_list_lock); for (cl = *cluster_list; cl; cl = cl->next) { val.s = int2str(cl->cluster_id, &val.len); node = add_mi_node_child(&rpl_tree->node, MI_DUP_VALUE|MI_IS_ARRAY, MI_SSTR("Cluster"), val.s, val.len); if (!node) goto error; for (cap = cl->capabilities; cap; cap = cap->next) { val.s = cap->reg.name.s; val.len = cap->reg.name.len; node_s = add_mi_node_child(node, MI_DUP_VALUE|MI_IS_ARRAY, MI_SSTR("Capability"), val.s, val.len); if (!node_s) goto error; lock_get(cl->lock); val.s = int2str((cap->flags & CAP_STATE_OK) ? 1 : 0, &val.len); lock_release(cl->lock); attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("State"), (cap->flags & CAP_STATE_OK) ? str_ok.s : str_not_synced.s, (cap->flags & CAP_STATE_OK) ? str_ok.len : str_not_synced.len); if (!attr) goto error; } } lock_stop_read(cl_list_lock); return rpl_tree; error: lock_stop_read(cl_list_lock); if (rpl_tree) free_mi_tree(rpl_tree); return NULL; }
static struct mi_root *run_mi_cmd_local(struct mi_cmd *f, str *cmd_params, int nr_params, struct mi_handler *async_hdl) { struct mi_root *cmd_root = NULL, *cmd_rpl; int i; if (f->flags & MI_NO_INPUT_FLAG && nr_params) return init_mi_tree(400, MI_SSTR(MI_MISSING_PARM_S)); if (!(f->flags & MI_NO_INPUT_FLAG)) { cmd_root = init_mi_tree(0,0,0); if (!cmd_root) { LM_ERR("the MI tree for the command to be run cannot be initialized!\n"); return init_mi_tree(400, MI_SSTR(MI_INTERNAL_ERR)); } cmd_root->async_hdl = async_hdl; } for (i = 0; i < nr_params; i++) if (!add_mi_node_child(&cmd_root->node, 0, 0, 0, cmd_params[i].s, cmd_params[i].len)) { LM_ERR("cannot add child node to the tree of the MI command to be run\n"); free_mi_tree(cmd_root); return init_mi_tree(400, MI_SSTR(MI_INTERNAL_ERR)); } if ((cmd_rpl = run_mi_cmd(f, cmd_root, 0, 0)) == NULL) { if (cmd_root) free_mi_tree(cmd_root); return init_mi_tree(400, MI_SSTR("MI command to be run failed")); } if (cmd_root) free_mi_tree(cmd_root); return cmd_rpl; }
/*! \brief parsing the datagram buffer*/ struct mi_root * mi_datagram_parse_tree(datagram_stream * datagram) { struct mi_root *root; struct mi_node *node; str name; str value; int ret; root = init_mi_tree(0,0,0); if (!root) { LM_ERR("the MI tree cannot be initialized!\n"); goto error; } if(!datagram || datagram->current[0] == '\0') { LM_DBG("no data in the datagram\n"); return root; } node = &root->node; name.s = value.s = 0; name.len = value.len = 0; /* every tree for a command ends with a \n that is alone on its line */ while ((ret=mi_datagram_parse_node(datagram, &name, &value))>=0 ) { if(ret == 1) return root; LM_DBG("adding node <%.*s> ; val <%.*s>\n", name.len,name.s, value.len,value.s); if(!add_mi_node_child(node,0,name.s,name.len,value.s,value.len)){ LM_ERR("cannot add the child node to the tree\n"); goto error; } LM_DBG("the remaining datagram has %i bytes\n",datagram->len); /*end condition*/ if(datagram->len == 0) { LM_DBG("found end of input\n"); return root; } } LM_ERR("parse error!\n"); error: if (root) free_mi_tree(root); return 0; }
/* * MI function to print domain name table */ struct mi_root* mi_domain_name_dump(struct mi_root *cmd_tree, void *param) { struct mi_root* rpl_tree; rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK)); if (rpl_tree==NULL) return 0; if(domain_list_table && domain_name_table_mi_print(*domain_list_table, &rpl_tree->node) < 0) { LM_ERR("failed to add a node\n"); free_mi_tree(rpl_tree); return 0; } return rpl_tree; }
/* * MI function to print address entries from current hash table */ struct mi_root* mi_address_dump(struct mi_root *cmd_tree, void *param) { struct mi_root* rpl_tree; rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK)); if (rpl_tree==NULL) return 0; if(addr_hash_table_mi_print(*addr_hash_table, &rpl_tree->node) < 0) { LM_ERR("failed to add a node\n"); free_mi_tree(rpl_tree); return 0; } return rpl_tree; }
/** * prints the routing data * * @param cmd_tree the MI command tree * @param param the parameter * * @return code 200 on success, code 400 or 500 on failure */ struct mi_root* dump_fifo (struct mi_root* cmd_tree, void *param) { struct route_data_t * rd; str *tmp_str; str empty_str = str_init("<empty>"); if((rd = get_data ()) == NULL) { LM_ERR("error during retrieve data\n"); return init_mi_tree(500, "error during command processing", 31); } struct mi_root* rpl_tree; struct mi_node* node = NULL; rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if(rpl_tree == NULL) goto error2; node = addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "Printing routing information:"); if(node == NULL) goto error; LM_DBG("start processing of data\n"); int i, j; for (i = 0; i < rd->carrier_num; i++) { if (rd->carriers[i]) { tmp_str = (rd->carriers[i] ? rd->carriers[i]->name : &empty_str); node = addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "Printing tree for carrier '%.*s' (%i)\n", tmp_str->len, tmp_str->s, rd->carriers[i] ? rd->carriers[i]->id : 0); if(node == NULL) goto error; for (j=0; j<rd->carriers[i]->domain_num; j++) { if (rd->carriers[i]->domains[j] && rd->carriers[i]->domains[j]->tree) { tmp_str = (rd->carriers[i]->domains[j] ? rd->carriers[i]->domains[j]->name : &empty_str); node = addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "Printing tree for domain '%.*s' (%i)\n", tmp_str->len, tmp_str->s, rd->carriers[i]->domains[j]->id); if(node == NULL) goto error; if (dump_tree_recursor (&rpl_tree->node, rd->carriers[i]->domains[j]->tree, "") < 0) goto error; } } } } release_data (rd); return rpl_tree; error: free_mi_tree(rpl_tree); error2: release_data (rd); return 0; }
/* mi function implementations */ struct mi_root* mi_stats(struct mi_root* cmd_tree, void* param) { struct mi_root *rpl_tree; struct mi_node *node=NULL, *rpl=NULL; struct mi_attr* attr; char* p; int i, len; rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if (rpl_tree==0) return 0; rpl = &rpl_tree->node; LOCK_GET(rl_lock); for (i=0; i<MAX_PIPES; i++) { if (*pipes[i].algo != PIPE_ALGO_NOP) { node = add_mi_node_child(rpl, 0, "PIPE", 4, 0, 0); if(node == NULL) goto error; p = int2str((unsigned long)(i), &len); attr = add_mi_attr(node, MI_DUP_VALUE, "id", 2, p, len); if(attr == NULL) goto error; p = int2str((unsigned long)(*pipes[i].load), &len); attr = add_mi_attr(node, MI_DUP_VALUE, "load", 4, p, len); if(attr == NULL) goto error; p = int2str((unsigned long)(*pipes[i].last_counter), &len); attr = add_mi_attr(node, MI_DUP_VALUE, "counter", 7, p, len); if(attr == NULL) goto error; } } p = int2str((unsigned long)(*drop_rate), &len); node = add_mi_node_child(rpl, MI_DUP_VALUE, "DROP_RATE", 9, p, len); LOCK_RELEASE(rl_lock); return rpl_tree; error: LOCK_RELEASE(rl_lock); LM_ERR("Unable to create reply\n"); free_mi_tree(rpl_tree); return 0; }
static struct mi_root * mi_show_partition(struct mi_root *cmd_tree, void *param) { struct mi_node *node = NULL; struct mi_root *rpl_tree = NULL; struct mi_node* root= NULL; struct mi_attr* attr; dp_connection_list_t *el; rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if (rpl_tree==NULL) return NULL; if (cmd_tree) node = cmd_tree->node.kids; if (node == NULL) { el = dp_get_connections(); root = &rpl_tree->node; while (el) { node = add_mi_node_child(root, 0, "Partition", 9, el->partition.s, el->partition.len); if( node == NULL) goto error; attr = add_mi_attr(node, 0, "table", 5, el->table_name.s, el->table_name.len); if(attr == NULL) goto error; db_get_url(&el->db_url); if(database_url.len == 0) goto error; attr = add_mi_attr(node, MI_DUP_VALUE, "db_url", 6, database_url.s, database_url.len); if(attr == NULL) goto error; el = el->next; } } else { el = dp_get_connection(&node->value); if (!el) goto error; root = &rpl_tree->node; node = add_mi_node_child(root, 0, "Partition", 9, el->partition.s, el->partition.len); if( node == NULL) goto error; attr = add_mi_attr(node, 0, "table", 5, el->table_name.s, el->table_name.len); if(attr == NULL) goto error; db_get_url(&el->db_url); if(database_url.len == 0) goto error; attr = add_mi_attr(node, MI_DUP_VALUE, "db_url", 6, database_url.s, database_url.len); if(attr == NULL) goto error; } return rpl_tree; error: if(rpl_tree) free_mi_tree(rpl_tree); return NULL; }