smcp_status_t plugtest_test_handler(smcp_node_t node) { smcp_status_t ret = SMCP_STATUS_NOT_ALLOWED; char* content = NULL; coap_size_t max_len = 0; smcp_method_t method = smcp_inbound_get_code(); if(method==COAP_METHOD_GET) { ret = smcp_outbound_begin_response(COAP_RESULT_205_CONTENT); } else if(method==COAP_METHOD_POST) { ret = smcp_outbound_begin_response(COAP_RESULT_201_CREATED); } else if(method==COAP_METHOD_PUT) { ret = smcp_outbound_begin_response(COAP_RESULT_204_CHANGED); } else if(method==COAP_METHOD_DELETE) { ret = smcp_outbound_begin_response(COAP_RESULT_202_DELETED); } if(ret) goto bail; smcp_outbound_add_option_uint(COAP_OPTION_CONTENT_TYPE, COAP_CONTENT_TYPE_TEXT_PLAIN); content = smcp_outbound_get_content_ptr(&max_len); if(!content) { ret = SMCP_STATUS_FAILURE; goto bail; } smcp_inbound_get_path(content, SMCP_GET_PATH_LEADING_SLASH|SMCP_GET_PATH_INCLUDE_QUERY); strlcat(content,"\nPlugtest!\nMethod = ",max_len); strlcat(content,coap_code_to_cstr(method),max_len); strlcat(content,"\n",max_len); { const uint8_t* value; coap_size_t value_len; coap_option_key_t key; while((key=smcp_inbound_next_option(&value, &value_len))!=COAP_OPTION_INVALID) { strlcat(content,coap_option_key_to_cstr(key,1),max_len); strlcat(content,": ",max_len); if(coap_option_value_is_string(key)) { int argh = strlen(content)+value_len; strlcat(content,(char*)value,MIN(max_len,argh+1)); content[argh] = 0; } else { strlcat(content,"<binary>",max_len); } strlcat(content,"\n",max_len); } } smcp_outbound_set_content_len((coap_size_t)strlen(content)); ret = smcp_outbound_send(); bail: return ret; }
static smcp_status_t request_handler(void* context) { smcp_status_t ret = SMCP_STATUS_OK; char* content = (char*)smcp_inbound_get_content_ptr(); size_t content_length = smcp_inbound_get_content_len(); char *path = NULL; FILE * pFile; path = smcp_inbound_get_path(NULL,0); // path must be free()'d after this! //require_action_string(path && path[0], (free((void*)path),ret = SMCP_STATUS_INVALID_ARGUMENT)); if(smcp_inbound_get_code() != COAP_METHOD_POST) { return SMCP_STATUS_NOT_IMPLEMENTED; } // Skip to the URI path option while(smcp_inbound_peek_option(NULL, NULL) != COAP_OPTION_URI_PATH) if(smcp_inbound_next_option(NULL, NULL) == COAP_OPTION_INVALID) break; smcp_outbound_begin_response(COAP_RESULT_205_CONTENT); smcp_outbound_add_option_uint( COAP_OPTION_CONTENT_TYPE, COAP_CONTENT_TYPE_TEXT_PLAIN); if(content && content_length) { // if content exist then print and write on .txt file with "a" being append feature. pFile = fopen ("data-collect.txt","a"); printf("%s", content); if (pFile!=NULL) { fputs (content,pFile); fclose (pFile); } /* Only print a newline if the content doesn't already print one. */ if((content[content_length - 1] != '\n')) printf("\n"); } ret = smcp_outbound_send(); free((void*)path); bail: return ret; }
cgi_node_request_t cgi_node_create_request(cgi_node_t node) { cgi_node_request_t ret = NULL; int i; int pipe_cmd_stdin[2]; int pipe_cmd_stdout[2]; for (i=0; i < CGI_NODE_MAX_REQUESTS; i++) { if (node->requests[i].state <= CGI_NODE_STATE_FINISHED) { ret = &node->requests[i]; if (node->requests[i].state == CGI_NODE_STATE_INACTIVE) { break; } } } require(ret,bail); ret->is_active = 1; ret->state = CGI_NODE_STATE_ACTIVE_BLOCK1_WAIT_REQ; if(ret->pid != 0 && ret->pid != -1) { int status; kill(ret->pid,SIGKILL); waitpid(ret->pid, &status, 0); } if(ret->fd_cmd_stdin>=0) { close(ret->fd_cmd_stdin); } if(ret->fd_cmd_stdout>=0) { close(ret->fd_cmd_stdout); } ret->pid = 0; ret->fd_cmd_stdin = -1; ret->fd_cmd_stdout = -1; ret->block1 = BLOCK_OPTION_UNSPECIFIED; ret->block2 = BLOCK_OPTION_DEFAULT; // Default value, overwrite with actual block ret->stdin_buffer_len = 0; ret->stdout_buffer_len = 0; ret->expiration = smcp_plat_cms_to_timestamp(30 * MSEC_PER_SEC); free(ret->stdin_buffer); ret->stdin_buffer = NULL; free(ret->stdout_buffer); ret->stdout_buffer = NULL; smcp_start_async_response(&ret->async_response, SMCP_ASYNC_RESPONSE_FLAG_DONT_ACK); pipe(pipe_cmd_stdin); pipe(pipe_cmd_stdout); if(!(ret->pid=fork())) { // We are the child! char path[2048]; // todo: this max should be a preprocessor macro // Update stdin and stdout. dup2(pipe_cmd_stdin[0],STDIN_FILENO); dup2(pipe_cmd_stdout[1],STDOUT_FILENO); close(pipe_cmd_stdin[0]); close(pipe_cmd_stdin[1]); close(pipe_cmd_stdout[0]); close(pipe_cmd_stdout[1]); path[0] = 0; smcp_node_get_path(&node->node,path,sizeof(path)); setenv("SCRIPT_NAME",path,1); setenv("SERVER_SOFTWARE","smcpd/"PACKAGE_VERSION,1); setenv("REQUEST_METHOD",coap_code_to_cstr(smcp_inbound_get_packet()->code),1); setenv("REQUEST_URI",smcp_inbound_get_path(path,2),1); setenv("GATEWAY_INTERFACE","CGI/1.1",1); setenv("SERVER_PROTOCOL","CoAP/1.0",1); setenv("REMOTE_ADDR","",1); setenv("REMOTE_PORT","",1); setenv("SERVER_NAME","",1); setenv("SERVER_ADDR","",1); setenv("SERVER_PORT","",1); if (0 == strncmp(path,getenv("SCRIPT_NAME"),strlen(getenv("SCRIPT_NAME")))) { setenv("PATH_INFO",path+strlen(getenv("SCRIPT_NAME")),1); } syslog(LOG_DEBUG, "cgi-node: About to execute \"%s\" using shell \"%s\"", node->cmd, node->shell); execl(node->shell,node->shell,"-c",node->cmd,NULL); syslog(LOG_ERR, "cgi-node: Failed to execute \"%s\" using shell \"%s\"", node->cmd, node->shell); // We should never get here... abort(); } if (ret->pid < 0) { // Oh hell. syslog(LOG_ERR,"Unable to fork!"); close(pipe_cmd_stdin[0]); close(pipe_cmd_stdin[1]); close(pipe_cmd_stdout[0]); close(pipe_cmd_stdout[1]); ret->is_active = 0; ret->state = CGI_NODE_STATE_INACTIVE; ret = NULL; goto bail; } ret->fd_cmd_stdin = pipe_cmd_stdin[1]; ret->fd_cmd_stdout = pipe_cmd_stdout[0]; close(pipe_cmd_stdin[0]); close(pipe_cmd_stdout[1]); bail: return ret; }