void mi_datagram_server(int rx_sock, int tx_sock) { struct mi_root *mi_cmd; struct mi_root *mi_rpl; struct mi_handler *hdl; struct mi_cmd * f; datagram_stream dtgram; int ret, len; ret = 0; f = 0; while(1){/*read the datagram*/ memset(mi_buf, 0, DATAGRAM_SOCK_BUF_SIZE); reply_addr_len = sizeof(reply_addr); /* get the client's address */ ret = recvfrom(rx_sock, mi_buf, DATAGRAM_SOCK_BUF_SIZE, 0, (struct sockaddr*)&reply_addr, &reply_addr_len); if (ret == -1) { LM_ERR("recvfrom: (%d) %s\n", errno, strerror(errno)); if ((errno == EINTR) || (errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == ECONNREFUSED)) { LM_DBG("got %d (%s), going on\n", errno, strerror(errno)); continue; } LM_DBG("error in recvfrom\n"); continue; } if(ret == 0) continue; LM_DBG("received %.*s\n", ret, mi_buf); if(ret> DATAGRAM_SOCK_BUF_SIZE){ LM_ERR("buffer overflow\n"); continue; } LM_DBG("mi_buf is %s and we have received %i bytes\n",mi_buf, ret); dtgram.start = mi_buf; dtgram.len = ret; dtgram.current = dtgram.start; ret = identify_command(&dtgram, &f); /*analyze the command--from the first line*/ if(ret != 0) { LM_ERR("command not available\n"); mi_send_dgram(tx_sock, MI_COMMAND_NOT_AVAILABLE, MI_COMMAND_AVAILABLE_LEN, (struct sockaddr* )&reply_addr, reply_addr_len, mi_socket_timeout); continue; } LM_DBG("we have a valid command \n"); /* if asyncron cmd, build the async handler */ if (f->flags&MI_ASYNC_RPL_FLAG) { hdl = build_async_handler(mi_socket_domain, &reply_addr, reply_addr_len, tx_sock); if (hdl==0) { LM_ERR("failed to build async handler\n"); mi_send_dgram(tx_sock, MI_INTERNAL_ERROR, MI_INTERNAL_ERROR_LEN,(struct sockaddr* )&reply_addr, reply_addr_len, mi_socket_timeout); continue; } } else{ hdl = 0; } LM_DBG("after identifing the command, the received datagram is %s\n", dtgram.current); /*if no params required*/ if (f->flags&MI_NO_INPUT_FLAG) { LM_DBG("the command has no params\n"); mi_cmd = 0; } else { LM_DBG("parsing the command's params\n"); mi_cmd = mi_datagram_parse_tree(&dtgram); if (mi_cmd==NULL){ LM_ERR("failed to parse the MI tree\n"); mi_send_dgram(tx_sock, MI_PARSE_ERROR, MI_PARSE_ERROR_LEN, (struct sockaddr* )&reply_addr, reply_addr_len, mi_socket_timeout); free_async_handler(hdl); continue; } mi_cmd->async_hdl = hdl; } LM_DBG("done parsing the mi tree\n"); if ( (mi_rpl=run_mi_cmd(f, mi_cmd, (mi_flush_f *)mi_datagram_flush_tree, &dtgram))==0 ) { /*error while running the command*/ LM_ERR("failed to process the command\n"); mi_send_dgram(tx_sock, MI_COMMAND_FAILED, MI_COMMAND_FAILED_LEN, (struct sockaddr* )&reply_addr, reply_addr_len, mi_socket_timeout); goto failure; } /*the command exited well*/ LM_DBG("command process (%s)succeded\n",f->name.s); if (mi_rpl!=MI_ROOT_ASYNC_RPL) { if(mi_datagram_write_tree(&dtgram , mi_rpl) != 0){ LM_ERR("failed to build the response \n"); goto failure; } len = dtgram.current - dtgram.start; ret = mi_send_dgram(tx_sock, dtgram.start,len, (struct sockaddr* )&reply_addr, reply_addr_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: %s (%d)\n", strerror(errno), errno); } free_mi_tree( mi_rpl ); free_async_handler(hdl); if (mi_cmd) free_mi_tree( mi_cmd ); }else { if (mi_cmd) free_mi_tree( mi_cmd ); } continue; failure: free_async_handler(hdl); /* destroy request tree */ if (mi_cmd) free_mi_tree( mi_cmd ); /* destroy the reply tree */ if (mi_rpl) free_mi_tree(mi_rpl); continue; } }
void mi_fifo_server(FILE *fifo_stream) { struct mi_root *mi_cmd; struct mi_root *mi_rpl; struct mi_handler *hdl; int line_len; char *file_sep, *command, *file; struct mi_cmd *f; FILE *reply_stream; while(1) { reply_stream = NULL; /* commands must look this way ':<command>:[filename]' */ if (mi_read_line(mi_buf,MAX_MI_FIFO_BUFFER,fifo_stream, &line_len)) { LM_ERR("failed to read command\n"); continue; } /* trim from right */ while(line_len) { if(mi_buf[line_len-1]=='\n' || mi_buf[line_len-1]=='\r' || mi_buf[line_len-1]==' ' || mi_buf[line_len-1]=='\t' ) { line_len--; mi_buf[line_len]=0; } else break; } if (line_len==0) { LM_DBG("command empty\n"); continue; } if (line_len<3) { LM_ERR("command must have at least 3 chars\n"); continue; } if (*mi_buf!=MI_CMD_SEPARATOR) { LM_ERR("command must begin with %c: %.*s\n", MI_CMD_SEPARATOR, line_len, mi_buf ); goto consume1; } command = mi_buf+1; file_sep=strchr(command, MI_CMD_SEPARATOR ); if (file_sep==NULL) { LM_ERR("file separator missing\n"); goto consume1; } if (file_sep==command) { LM_ERR("empty command\n"); goto consume1; } if (*(file_sep+1)==0) { file = NULL; } else { file = file_sep+1; file = get_reply_filename(file, mi_buf+line_len-file); if (file==NULL) { LM_ERR("trimming filename\n"); goto consume1; } } /* make command zero-terminated */ *file_sep=0; f=lookup_mi_cmd( command, strlen(command) ); if (f==0) { LM_ERR("command %s is not available\n", command); mi_open_reply( file, reply_stream, consume1); mi_fifo_reply( reply_stream, "500 command '%s' not available\n", command); goto consume2; } /* if asyncron cmd, build the async handler */ if (f->flags&MI_ASYNC_RPL_FLAG) { hdl = build_async_handler( file, strlen(file) ); if (hdl==0) { LM_ERR("failed to build async handler\n"); mi_open_reply( file, reply_stream, consume1); mi_fifo_reply( reply_stream, "500 Internal server error\n"); goto consume2; } } else { hdl = 0; mi_open_reply( file, reply_stream, consume1); } if (f->flags&MI_NO_INPUT_FLAG) { mi_cmd = 0; mi_do_consume(); } else { mi_cmd = mi_parse_tree(fifo_stream); if (mi_cmd==NULL) { LM_ERR("error parsing MI tree\n"); if (!reply_stream) mi_open_reply( file, reply_stream, consume3); mi_fifo_reply( reply_stream, "400 parse error in " "command '%s'\n", command); goto consume3; } mi_cmd->async_hdl = hdl; } LM_DBG("done parsing the mi tree\n"); if ( (mi_rpl=run_mi_cmd(f, mi_cmd, (mi_flush_f *)mi_flush_tree, reply_stream))==0 ) { if (!reply_stream) mi_open_reply( file, reply_stream, failure); mi_fifo_reply(reply_stream, "500 command '%s' failed\n", command); LM_ERR("command (%s) processing failed\n", command ); } else if (mi_rpl!=MI_ROOT_ASYNC_RPL) { if (!reply_stream) mi_open_reply( file, reply_stream, failure); mi_write_tree( reply_stream, mi_rpl); free_mi_tree( mi_rpl ); } else { if (mi_cmd) free_mi_tree( mi_cmd ); continue; } free_async_handler(hdl); /* close reply fifo */ fclose(reply_stream); /* destroy request tree */ if (mi_cmd) free_mi_tree( mi_cmd ); continue; failure: free_async_handler(hdl); /* destroy request tree */ if (mi_cmd) free_mi_tree( mi_cmd ); /* destroy the reply tree */ if (mi_rpl) free_mi_tree(mi_rpl); continue; consume3: free_async_handler(hdl); if (reply_stream) consume2: fclose(reply_stream); consume1: mi_do_consume(); } }
xmlrpc_value* default_method (xmlrpc_env* env, const char* host, const char* methodName, xmlrpc_value* paramArray, void* serverInfo) #endif { xmlrpc_value* ret = NULL; struct mi_root* mi_cmd = NULL; struct mi_root* mi_rpl = NULL; struct mi_handler *hdl = NULL; struct mi_cmd* f; char* response = 0; int is_shm = 0; LM_DBG("starting up.....\n"); f = lookup_mi_cmd((char*)methodName, strlen(methodName)); if ( f == 0 ) { LM_ERR("command %s is not available!\n", methodName); xmlrpc_env_set_fault_formatted(env, XMLRPC_NO_SUCH_METHOD_ERROR, "Requested command (%s) is not available!", methodName); goto error; } LM_DBG("done looking the mi command.\n"); /* if asyncron cmd, build the async handler */ if (f->flags&MI_ASYNC_RPL_FLAG) { hdl = build_async_handler( ); if (hdl==0) { LM_ERR("failed to build async handler\n"); if ( !env->fault_occurred ) xmlrpc_env_set_fault(env, XMLRPC_INTERNAL_ERROR, "Internal server error while processing request"); goto error; } } else { hdl = NULL; } if (f->flags&MI_NO_INPUT_FLAG) { mi_cmd = 0; } else { mi_cmd = xr_parse_tree(env, paramArray); if ( mi_cmd == NULL ){ LM_ERR("failed to parse MI tree\n"); if ( !env->fault_occurred ) xmlrpc_env_set_fault(env, XMLRPC_INTERNAL_ERROR, "The xmlrpc request could not be parsed into a MI tree!"); goto error; } mi_cmd->async_hdl = hdl; } LM_DBG("done parsing the mi tree.\n"); if ( ( mi_rpl = run_mi_cmd(f, mi_cmd) ) == 0 ){ LM_ERR("command (%s) processing failed.\n", methodName); xmlrpc_env_set_fault_formatted(env, XMLRPC_INTERNAL_ERROR, "Command (%s) processing failed.\n", methodName); goto error; } else if (mi_rpl==MI_ROOT_ASYNC_RPL) { mi_rpl = wait_async_reply(hdl); hdl = 0; if (mi_rpl==0) { xmlrpc_env_set_fault_formatted(env, XMLRPC_INTERNAL_ERROR, "Command (%s) processing failed (async).\n", methodName); goto error; } is_shm = 1; } LM_DBG("done running the mi command.\n"); if ( rpl_opt == 1 ) { if ( xr_build_response_array( env, mi_rpl ) != 0 ){ if ( !env->fault_occurred ) { LM_ERR("failed parsing the xmlrpc response from the mi tree\n"); xmlrpc_env_set_fault(env, XMLRPC_INTERNAL_ERROR, "Failed to parse the xmlrpc response from the mi tree."); } goto error; } LM_DBG("done building response array.\n"); ret = xr_response; } else { if ( (response = xr_build_response( env, mi_rpl )) == 0 ){ if ( !env->fault_occurred ) { LM_ERR("failed parsing the xmlrpc response from the mi tree\n"); xmlrpc_env_set_fault_formatted(env, XMLRPC_INTERNAL_ERROR, "Failed to parse the xmlrpc response from the mi tree."); } goto error; } LM_DBG("done building response.\n"); ret = xmlrpc_build_value(env, "s", response); } error: free_async_handler(hdl); if ( mi_cmd ) free_mi_tree( mi_cmd ); if ( mi_rpl ) { is_shm?free_shm_mi_tree(mi_rpl):free_mi_tree(mi_rpl);} return ret; }