| #include "xml_ubus.h" |
| |
| static struct blob_buf buf; |
| static struct ubus_context *ctx; |
| static char *g_xml_res = NULL; |
| formvars *start; |
| static struct upload_ctx upload_obj; |
| |
| void blobmsg_add_xml_leaf_node(struct blob_buf *b, mxml_node_t * node); |
| void blobmsg_add_xml_tree(struct blob_buf *b, mxml_node_t * node); |
| void cgi_init_http_headers(int content_length, char *content_disposition, struct mime_vec *mime); |
| void cgi_init_xml_headers(int content_length, char *content_disposition); |
| int send_xml_response(char *xml_res); |
| int xml_duster_parse(char *filepost); |
| int get_request_len(char *buf, int buflen); |
| int comm_ota_init(struct upload_ctx *ota_ctx, int fbf_size, int segment_size); |
| int send_prepare_msg_ota(struct upload_ctx *ota_ctx); |
| int connect_to_ota(struct upload_ctx *ota_ctx); |
| int send_fbf_segment_ota(struct upload_ctx *ota_ctx, char *data, int len); |
| int upload_fw_fs_init(struct upload_ctx *obj, int file_size); |
| int upload_fw_fs_write(struct upload_ctx *obj, char *data, int len); |
| int upload_fw_fs_done(struct upload_ctx *obj); |
| int upload_fw_ota_init(struct upload_ctx *obj, int file_size, int segmnet_size); |
| int upload_fw_ota_write(struct upload_ctx *obj, char *data, int len); |
| int process_upload_request(struct upload_forward_ops *ops); |
| int download_config_file_init(); |
| int response_download_config_file(); |
| int process_download_request(struct download_ops *ops); |
| |
| void blobmsg_add_xml_leaf_node(struct blob_buf *b, mxml_node_t * node) |
| { |
| mxml_node_t *cur; |
| char *node_key; |
| char *node_val; |
| void *t; |
| |
| if (node->child && node->child->type != MXML_ELEMENT && node->child->child == NULL && node->child->next == NULL) { |
| /*This is a leaf node with value */ |
| node_key = node->value.element.name; |
| node_val = node->child->value.opaque; |
| blobmsg_add_string(b, node_key, node_val); |
| return; |
| } else if (node->type == MXML_ELEMENT && node->child == NULL) { |
| /*leaf node with no value, do not need to add to blob */ |
| CGI_LOGI("blobmsg_add_xml_leaf_node, leaf node with no value\n"); |
| } else { |
| /* Not a leaf node |
| * Proceed further*/ |
| t = blobmsg_open_table(b, node->value.element.name); |
| for (cur = node->child; cur != NULL; cur = cur->next) { |
| if (cur->type != MXML_ELEMENT) { |
| continue; |
| } |
| blobmsg_add_xml_leaf_node(b, cur); |
| } |
| blobmsg_close_table(b, t); |
| } |
| } |
| |
| void blobmsg_add_xml_tree(struct blob_buf *b, mxml_node_t * node) |
| { |
| mxml_node_t *child; |
| |
| for (child = node->child; child != NULL; child = child->next) { |
| if (child->type != MXML_ELEMENT) { |
| continue; |
| } |
| blobmsg_add_xml_leaf_node(b, child); |
| } |
| |
| return; |
| } |
| |
| static int cgi_ubus_init(void) |
| { |
| const char *ubus_socket = NULL; |
| |
| ctx = ubus_connect(ubus_socket); |
| if (!ctx) { |
| fprintf(stderr, "Failed to connect to ubus\n"); |
| return -1; |
| } |
| return 0; |
| } |
| |
| static void cgi_ubus_end(void) |
| { |
| ubus_free(ctx); |
| } |
| |
| static void cgi_receive_ubus_result_data(struct ubus_request *req, int type, struct blob_attr *msg) |
| { |
| mxml_node_t *xml; |
| mxml_node_t *rgw; |
| mxml_node_t *cur; |
| FILE *fp = NULL; |
| bool array; |
| |
| if (!msg) { |
| system("echo \"no msg return\" >> /tmp/my_debug"); |
| return; |
| } |
| array = blob_is_extended(msg) && blobmsg_type(msg) == BLOBMSG_TYPE_ARRAY; |
| |
| xml = mxmlNewXML("1.0"); |
| rgw = mxmlNewElement(xml, "RGW"); |
| cur = rgw; |
| |
| CGI_LOGI("blob_data(msg) %p, blob_len(msg) %d array %d\n", blob_data(msg), blob_len(msg), array); |
| blobmsg_format_xml_tree(cur, blob_data(msg), blob_len(msg), array); |
| |
| fp = fopen(g_xml_res, "wb"); |
| if(!fp) |
| { |
| CGI_LOGI("open g_xml_res fail\n"); |
| return; |
| } |
| mxmlSaveFile(xml, fp, NULL); |
| fclose(fp); |
| mxmlDelete(xml); |
| } |
| |
| static void cgi_prepare_response(char *module_name, e_error_cause error_cause, e_error_cause_format format) |
| { |
| #define TMP_BUFF_SIZ 256 |
| char buff[TMP_BUFF_SIZ] = { 0 }; |
| FILE *fp = NULL; |
| int size = 0; |
| |
| if (!module_name) { |
| goto END; |
| } |
| |
| if (format == ERR_STRING) { |
| snprintf(buff, TMP_BUFF_SIZ, "<?xml version=\"1.0\" encoding=\"US-ASCII\" ?><RGW><%s>%s</%s></RGW>", |
| module_name, error_cause_msg[error_cause], module_name); |
| } else if (format == ERR_NUMBER) { |
| snprintf(buff, TMP_BUFF_SIZ, "<?xml version=\"1.0\" encoding=\"US-ASCII\" ?><RGW><%s>%d</%s></RGW>", |
| module_name, (int)error_cause, module_name); |
| } else |
| goto END; |
| |
| fp = fopen(g_xml_res, "wb"); |
| if (!fp) { |
| goto END; |
| } |
| if (strlen(buff) >= TMP_BUFF_SIZ) { |
| goto END; |
| } |
| |
| size = fwrite(buff, strlen(buff), sizeof(char), fp); |
| if (size != strlen(buff)) { |
| goto END; |
| } |
| END: |
| if (fp != NULL) |
| fclose(fp); |
| |
| } |
| |
| static void cgi_ubus_send_request(int obj, char *func, const char *sid, struct blob_attr *args, int timeout) |
| { |
| struct blob_attr *cur; |
| static struct blob_buf req; |
| int rem; |
| |
| blob_buf_init(&req, 0); |
| |
| blobmsg_for_each_attr(cur, args, rem) { |
| if (!strcmp(blobmsg_name(cur), "ubus_rpc_session")) { |
| //return ubus_error(cl, ERROR_PARAMS); |
| } |
| blobmsg_add_blob(&req, cur); |
| } |
| blobmsg_add_string(&req, "ubus_rpc_session", sid); |
| |
| CGI_LOGI("ctx %p, obj %u, func %s, req.head %p\n", ctx, obj, func, req.head); |
| if (ubus_invoke(ctx, obj, func, req.head, cgi_receive_ubus_result_data, 0, timeout) == UBUS_STATUS_TIMEOUT) |
| { |
| cgi_prepare_response(ERROR_CAUSE_TAG, ERR_CGI_FILE, ERR_NUMBER); |
| } |
| blob_buf_free(&req); |
| } |
| |
| static void cgi_ubus_create_pdp(int obj, char *func, int timeout) |
| { |
| struct blob_attr *cur; |
| static struct blob_buf req; |
| int status; |
| |
| blob_buf_init(&req, 0); |
| |
| CGI_LOGI("ctx %p, obj %u, func %s, req.head %p\n", ctx, obj, func, req.head); |
| if (status = ubus_invoke(ctx, obj, func, req.head, NULL, 0, timeout)) |
| { |
| CGI_LOGE("cgi_ubus_create_pdp failed, status %d\n", status); |
| } |
| blob_buf_free(&req); |
| } |
| |
| static void cgi_ubus_destroy_pdp(int obj, char *func, int timeout, int connection_num, int delete_all) |
| { |
| struct blob_attr *cur; |
| static struct blob_buf req; |
| int status; |
| |
| blob_buf_init(&req, 0); |
| |
| blobmsg_add_u32(&req, "connectionNum", connection_num); |
| blobmsg_add_u32(&req, "deleteall", delete_all); |
| |
| CGI_LOGI("ctx %p, obj %u, func %s, req.head %p\n", ctx, obj, func, req.head); |
| if (status = ubus_invoke(ctx, obj, func, req.head, NULL, 0, timeout)) |
| { |
| CGI_LOGE("cgi_ubus_destroy_pdp failed, status %d\n", status); |
| } |
| blob_buf_free(&req); |
| } |
| |
| void cgi_init_http_headers(int content_length, char *content_disposition, struct mime_vec *mime) |
| { |
| printf("Content-Type: %s\r\n", mime->str); |
| printf("Pragma: No-Cache\r\n"); |
| printf("Cache-Control: no-cache,no-store,max-age=0\r\n"); |
| if (content_disposition != NULL) |
| printf("Content-Disposition: %s\r\n", content_disposition); |
| printf("Content-Length: %d\r\n", content_length); |
| printf("\r\n"); |
| } |
| |
| void cgi_init_xml_headers(int content_length, char *content_disposition) |
| { |
| printf("Content-type: text/xml\r\n"); |
| printf("Charset: utf-8\r\n"); |
| printf("Pragma: No-Cache\r\n"); |
| printf("Cache-Control: no-cache,no-store,max-age=0\r\n"); |
| if (content_disposition != NULL) |
| printf("Content-disposition: %s\r\n", content_disposition); |
| printf("Content-length: %d\r\n\r\n", content_length); |
| |
| } |
| |
| int send_xml_response(char *xml_res) |
| { |
| struct stat file_stat; |
| char *buffer = NULL; |
| int fd = -1, size = 0; |
| int ret = 0; |
| |
| buffer = malloc(XML_GET_BUF_SIZE); |
| if (!buffer) { |
| return -1; |
| } |
| memset(buffer, 0, XML_GET_BUF_SIZE); |
| |
| /* init the repsonse header and body */ |
| stat(xml_res, &file_stat); |
| fd = open(xml_res, O_RDONLY); |
| if (fd < 0) { |
| system("echo \"Open xml_res failed\" >> /tmp/my_debug"); |
| ret = -1; |
| goto end; |
| } |
| system("echo \"Prepare to init xml_headers\" >> /tmp/my_debug"); |
| |
| memset(buffer, 0, XML_GET_BUF_SIZE); |
| cgi_init_xml_headers(file_stat.st_size, NULL); |
| while ((size = read(fd, buffer, XML_GET_BUF_SIZE)) > 0) { |
| buffer[size] = '\0'; |
| //Pirnt the buffer to stdout, the stdout now redirect to pipi_wr, connect to parent process(Web Server) |
| printf("%s", buffer); |
| } |
| ret = 0; |
| |
| end: |
| if (fd >= 0) |
| close(fd); |
| |
| if (buffer) |
| free(buffer); |
| |
| return ret; |
| } |
| |
| int xml_duster_parse(char *filepost) |
| { |
| #define UBUS_PARAM_NUM 4 |
| #define PARAM_LEN 32 |
| #define ERROR_CAUSE_TAG "error_cause" |
| mxml_node_t *root = NULL; |
| mxml_node_t *cur = NULL; |
| mxml_node_t *param_node = NULL; |
| char param[UBUS_PARAM_NUM][PARAM_LEN]; |
| unsigned int obj_id, cm_obj_id; |
| int i = 0; |
| FILE *fp = NULL; |
| int ret = 0; |
| int timeout = 0; |
| |
| blob_buf_init(&buf, 0); |
| fp = fopen(filepost, "r"); |
| if (fp == NULL) { |
| perror("Couldn't read file"); |
| ret = -1; |
| cgi_prepare_response(ERROR_CAUSE_TAG, ERR_CGI_FILE, ERR_NUMBER); |
| goto END; |
| } |
| CGI_LOGI("ctx %p, xml_duster_parse enter\n", ctx); |
| root = mxmlLoadFile(NULL, fp, MXML_OPAQUE_CALLBACK); |
| fclose(fp); |
| |
| CGI_LOGI("ctx %p, mxmlLoadFile success\n", ctx); |
| |
| cur = mxmlFindElement(root, root, "RGW", NULL, NULL, MXML_DESCEND_FIRST); |
| if (cur == NULL) { |
| cgi_prepare_response(ERROR_CAUSE_TAG, ERR_CGI_FORMAT, ERR_NUMBER); |
| ret = -1; |
| goto END; |
| } |
| cur = cur->child; |
| for (; cur != NULL; cur = cur->next) { |
| if (cur->type != MXML_ELEMENT) { |
| continue; |
| } |
| if (!strcmp(cur->value.element.name, "param")) { |
| param_node = cur->child; |
| i = 0; |
| for (; param_node != NULL; param_node = param_node->next) { |
| if (param_node->type != MXML_ELEMENT) { |
| continue; |
| } |
| if (param_node->child && param_node->child->type != MXML_ELEMENT && |
| param_node->child->child == NULL && param_node->child->next == NULL) { |
| if (param_node->child->value.opaque){ |
| if(i >= UBUS_PARAM_NUM || strlen(param_node->child->value.opaque) > PARAM_LEN){ |
| CGI_LOGE("xml_duster_parse failed i[%d],opaque len[%d]\n", i, strlen(param_node->child->value.opaque)); |
| cgi_prepare_response(ERROR_CAUSE_TAG, ERR_PARAM_INVALID, ERR_NUMBER); |
| ret = -1; |
| goto END; |
| |
| }else{ |
| strcpy(param[i++], param_node->child->value.opaque); |
| } |
| } |
| } |
| } |
| } else { |
| blobmsg_add_xml_tree(&buf, cur); |
| } |
| |
| } |
| |
| if (!strcmp(param[RPC_METHOD], "call")) { |
| if (strlen(param[RPC_SESSIONID]) == 0 || strlen(param[RPC_OBJPATH]) == 0 ||strlen(param[PRC_OBJMETHOD]) == 0) { |
| cgi_prepare_response(ERROR_CAUSE_TAG, ERR_PARAM_INVALID, ERR_NUMBER); |
| ret = -1; |
| goto END; |
| } |
| CGI_LOGI("ctx %p, param[RPC_OBJPATH] %s\n", ctx, param[RPC_OBJPATH]); |
| if (ubus_lookup_id(ctx, param[RPC_OBJPATH], &obj_id)) { |
| cgi_prepare_response(ERROR_CAUSE_TAG, ERR_SERVICE_NOT_FOUND, ERR_NUMBER); |
| ret = -1; |
| goto END; |
| } |
| |
| if (strcmp(param[PRC_OBJMETHOD], "search_network") == 0) |
| { |
| timeout = 360*1000; |
| } |
| else if (strcmp(param[RPC_OBJPATH], "wireless") == 0) |
| { |
| timeout = 60*1000; |
| } |
| else if (strcmp(param[RPC_OBJPATH], "cm") == 0) |
| { |
| timeout = 120*1000; |
| } |
| else |
| timeout = 30*1000; |
| |
| CGI_LOGI("ctx %p, obj_id %u, obj_method %s, buf.head %p, invoke timeout %d ms\n", ctx, obj_id, param[PRC_OBJMETHOD], |
| buf.head, timeout); |
| |
| if (strcmp(param[PRC_OBJMETHOD], "search_network") == 0) |
| { |
| if (ubus_lookup_id(ctx, "cm", &cm_obj_id)) { |
| cgi_prepare_response(ERROR_CAUSE_TAG, ERR_SERVICE_NOT_FOUND, ERR_NUMBER); |
| ret = -1; |
| goto END; |
| } |
| cgi_ubus_destroy_pdp(cm_obj_id, "destroy_pdp", 30000, 0, 1); |
| cgi_ubus_send_request(obj_id, param[PRC_OBJMETHOD], param[RPC_SESSIONID], buf.head, timeout); |
| cgi_ubus_create_pdp(cm_obj_id, "create_pdp", 30000); |
| } else { |
| cgi_ubus_send_request(obj_id, param[PRC_OBJMETHOD], param[RPC_SESSIONID], buf.head, timeout); |
| } |
| } else if (!strcmp(param[RPC_METHOD], "list")) { |
| /*not support yet*/ |
| cgi_prepare_response(ERROR_CAUSE_TAG, ERR_METHOD_NOT_SUPPORT, ERR_NUMBER); |
| ret = -1; |
| goto END; |
| } |
| END: |
| if (root) |
| mxmlDelete(root); |
| |
| blob_buf_free(&buf); |
| return ret; |
| } |
| |
| int get_request_len(char *buf, int buflen) |
| { |
| const char *s, *e; |
| int len = 0; |
| for (s = buf, e = s + buflen - 1; len <= 0 && s < e; s++) { |
| if (!isprint(*(const unsigned char *)s && *s != '\r' && *s != '\n') && |
| (*(const unsigned char *)s < 128)) { |
| len = -1; |
| } else if (s[0] == '\n' && s[1] == '\n') { |
| len = (int)(s - buf) + 2; |
| } else if (s[0] == '\n' && &s[1] < e && s[1] == '\r' && s[2] == '\n') { |
| len = (int)(s - buf) + 3; |
| } |
| } |
| return len; |
| } |
| |
| int comm_ota_init(struct upload_ctx *ota_ctx, int fbf_size, int segment_size) |
| { |
| int ret; |
| ret = ubus_lookup_id(ctx, "ota", &(ota_ctx->id)); |
| if (ret != NO_ERR) { |
| CGI_LOGE("%s: lookup object ota failed\n", __func__); |
| ret = ERR_PARAM_INVALID; |
| goto end; |
| } |
| ota_ctx->n_file_total = fbf_size; |
| ota_ctx->n_file_segmnet = segment_size; |
| |
| end: |
| return ret; |
| } |
| |
| static void receive_msg_ota_cb(struct ubus_request *req, int type, struct blob_attr *msg) |
| { |
| CGI_LOGE("enter %s\n", __func__); |
| return; |
| } |
| |
| int send_prepare_msg_ota(struct upload_ctx *ota_ctx) |
| { |
| blob_buf_init(&buf, 0); |
| blobmsg_add_string(&buf, "url", OTA_UNIX_PATH); |
| blobmsg_add_u32(&buf, "type", 1); |
| blobmsg_add_u32(&buf, "size", ota_ctx->n_file_total); |
| blobmsg_add_u32(&buf, "segment_size", ota_ctx->n_file_segmnet); |
| |
| ubus_invoke(ctx, ota_ctx->id, "download", buf.head, receive_msg_ota_cb, 0, 5000); |
| |
| CGI_LOGI("%s: send size %d, segment_size %d\n", __func__, ota_ctx->n_file_total, ota_ctx->n_file_segmnet); |
| return NO_ERR; |
| } |
| |
| enum { |
| QUERY_RESPONSE, |
| QUERY_RESPONSE_MAX, |
| }; |
| |
| const struct blobmsg_policy query_response_policy[QUERY_RESPONSE_MAX] ={ |
| [QUERY_RESPONSE] = { .name = "response", .type = BLOBMSG_TYPE_STRING }, |
| }; |
| |
| static void query_status_msg_ota_cb(struct ubus_request *req, int type, struct blob_attr *msg) |
| { |
| UNUSEDPARAM(type); |
| struct blob_attr *tb[QUERY_RESPONSE_MAX]; |
| int rc; |
| char *query_response = NULL; |
| struct upload_ctx *ota_ctx = (struct upload_ctx *)req->priv; |
| |
| rc = blobmsg_parse(query_response_policy, ARRAY_SIZE(query_response_policy), tb, blob_data(msg), blob_len(msg)); |
| if (rc < 0 || !tb[QUERY_RESPONSE]) { |
| CGI_LOGE("%s: parse msg failed\n", __func__); |
| return; |
| } |
| |
| query_response = blobmsg_get_string(tb[QUERY_RESPONSE]); |
| if (!query_response) { |
| CGI_LOGE("%s: query_response is null \n", __func__); |
| return; |
| } |
| |
| CGI_LOGE("%s: query_response %s \n", __func__, query_response); |
| |
| if (strstr(query_response, "fail")) |
| ota_ctx->upload_status = ERR_UPLOAD_FAILED; |
| |
| return; |
| } |
| |
| int query_upgrade_status_msg_ota(struct upload_ctx *ota_ctx) |
| { |
| blob_buf_init(&buf, 0); |
| blobmsg_add_string(&buf, "type", "1"); |
| ubus_invoke(ctx, ota_ctx->id, "query", buf.head, query_status_msg_ota_cb, ota_ctx, 5000); |
| |
| CGI_LOGI("%s: done\n", __func__); |
| return NO_ERR; |
| } |
| |
| int connect_to_ota(struct upload_ctx *ota_ctx) |
| { |
| int waitSeconds = 10, i = 0; |
| |
| //sleep(1); |
| while (i++ < waitSeconds) { |
| ota_ctx->fd = usock(USOCK_UNIX, OTA_UNIX_PATH, NULL); |
| if (ota_ctx->fd < 0) { |
| sleep(1); |
| } |
| else { |
| CGI_LOGI("%s: client fd %d", __func__, ota_ctx->fd); |
| return NO_ERR; |
| } |
| } |
| |
| CGI_LOGE("%s: Failed to connect to server(%s)\n", __func__, strerror(errno)); |
| return ERR_PARAM_INVALID; |
| } |
| |
| int send_fbf_segment_ota(struct upload_ctx *ota_ctx, char *data, int len) |
| { |
| int n_send; |
| n_send = write(ota_ctx->fd, data, len); |
| if (n_send != len) { |
| CGI_LOGE("%s: size %d actual send %d\n", __func__, len, n_send); |
| return ERR_PARAM_INVALID; |
| } |
| ota_ctx->n_send += n_send; |
| return NO_ERR; |
| } |
| |
| int upload_fw_fs_init(struct upload_ctx *obj, int file_size) |
| { |
| char *file_tmp = NULL; |
| int fd_tmp = 0; |
| int ret = NO_ERR; |
| |
| CGI_LOGI("%s: enter\n", __func__); |
| file_tmp = strdup("/tmp/config.XXXXXX"); |
| if ((fd_tmp = mkstemp(file_tmp)) < 0) { |
| ret = ERR_PARAM_INVALID; |
| goto end; |
| } |
| close(fd_tmp); |
| fd_tmp = open(file_tmp, O_WRONLY | O_TRUNC | O_CREAT | O_APPEND, 0); |
| if (fd_tmp == -1) { |
| ret = ERR_PARAM_INVALID; |
| goto end; |
| } |
| strncpy(obj->f_name, file_tmp, 31); |
| obj->fd = fd_tmp; |
| CGI_LOGI("%s: temp file %s\n", __func__, obj->f_name); |
| end: |
| //coverity[check_after_deref:SUPPRESS] |
| if (file_tmp) { |
| free(file_tmp); |
| } |
| CGI_LOGI("%s: leave\n", __func__); |
| return ret; |
| } |
| |
| int upload_fw_fs_write(struct upload_ctx *obj, char *data, int len) |
| { |
| int n_send; |
| n_send = write(obj->fd, data, len); |
| if (n_send != len) { |
| CGI_LOGE("%s: size %d actual send %d\n", __func__, len, n_send); |
| return ERR_PARAM_INVALID; |
| } |
| obj->n_send += n_send; |
| return NO_ERR; |
| } |
| |
| int upload_fw_fs_done(struct upload_ctx *obj) |
| { |
| char exec_str[128] = { 0 }; |
| int ret = ERR_PARAM_INVALID; |
| CGI_LOGI("%s: enter\n", __func__); |
| |
| if (obj->fd > 0) |
| close(obj->fd); |
| |
| if (strlen(obj->f_name) > 0) { |
| snprintf(exec_str, 127, "tar xzvf %s -C / >/dev/null", obj->f_name); |
| CGI_LOGI("%s: exec command:%s\n", __func__, exec_str); |
| ret = system(exec_str); |
| if (ret < 0) |
| ret = ERR_PARAM_INVALID; |
| else |
| ret = NO_ERR; |
| } |
| CGI_LOGI("%s: leave %d\n", __func__, ret); |
| return ret; |
| } |
| |
| int upload_fw_ota_init(struct upload_ctx *obj, int file_size, int segmnet_size) |
| { |
| int ret; |
| |
| ret = comm_ota_init(obj, file_size, segmnet_size); |
| if (ret != NO_ERR) { |
| CGI_LOGE("%s: comm_ota_init Failed\n", __func__); |
| goto end; |
| } |
| |
| query_upgrade_status_msg_ota(obj); |
| if (obj->upload_status == ERR_UPLOAD_FAILED) |
| { |
| ret = ERR_PARAM_INVALID; |
| goto end; |
| } |
| |
| ret = send_prepare_msg_ota(obj); |
| if (ret != NO_ERR) { |
| CGI_LOGE("%s: send_prepare_msg_ota Failed\n", __func__); |
| goto end; |
| } |
| ret = connect_to_ota(obj); |
| if (ret != NO_ERR) { |
| CGI_LOGE("%s: connect_to_ota Failed\n", __func__); |
| goto end; |
| } |
| end: |
| CGI_LOGI("%s: done with ret %d\n", __func__, ret); |
| return ret; |
| } |
| |
| int upload_fw_ota_write(struct upload_ctx *obj, char *data, int len) |
| { |
| return send_fbf_segment_ota(obj, data, len); |
| } |
| |
| int upload_fw_ota_done(struct upload_ctx *obj) |
| { |
| int ret = ERR_PARAM_INVALID; |
| |
| if (obj->fd > 0) |
| ret = close(obj->fd); |
| |
| CGI_LOGI("%s: leave with %d\n", __func__, ret); |
| return ret; |
| } |
| |
| #define CONTENET_TYPE_OCTECT "application/octet-stream" |
| int process_upload_request(struct upload_forward_ops *ops) |
| { |
| #define MAX_HEADER_OPTION_LEN 256 |
| #define MAX_TCP_BUF_SIZE 1460 |
| #define FORM_HEAD_MAX_SIZE 256 |
| |
| char content_type_buf[MAX_HEADER_OPTION_LEN] = { 0 }; |
| char boundary_buf[MAX_HEADER_OPTION_LEN] = { 0 }; |
| char media_type[MAX_HEADER_OPTION_LEN] = { 0 }; |
| char *env_content_type = getenv("CONTENT_TYPE"); |
| char *env_content_len = getenv("CONTENT_LENGTH"); |
| char *p = NULL, *p1 = NULL; |
| char buf[2 * MAX_TCP_BUF_SIZE]; |
| char fbf_buf[2 * MAX_TCP_BUF_SIZE]; |
| int n_boundary = 0, n_consumed = 0, content_len = 0, len = 0; |
| int n_form_head = 0, n_form_tail = 0, n_fbf = 0, n_fbf_total = 0, n_file_size = 0; |
| int n_read, to_read; |
| int ret = NO_ERR; |
| bool boundary_found = true; |
| |
| CGI_LOGI("%s: enter\n", __func__); |
| if (!env_content_type) { |
| /*not found content_type */ |
| CGI_LOGI("%s: no Content-Type in request\n", __func__); |
| |
| ret = ERR_PARAM_INVALID; |
| goto end; |
| } |
| |
| if (!env_content_len) { |
| /*not found content_length */ |
| CGI_LOGI("%s: no Content-Length in request\n", __func__); |
| ret = ERR_PARAM_INVALID; |
| goto end; |
| } |
| |
| if (env_content_type) { |
| strncpy(content_type_buf, env_content_type, MAX_HEADER_OPTION_LEN - 1); |
| } |
| |
| CGI_LOGI("%s: content_type_buf %s\n", __func__, content_type_buf); |
| p = strstr(content_type_buf, CONTENET_TYPE_OCTECT); |
| if (!p) { |
| p = strstr(content_type_buf, "boundary="); |
| } |
| else |
| boundary_found = false; |
| |
| if (!p) { |
| /*not found connect type */ |
| CGI_LOGI("%s: content type %s in request is not valid\n", __func__, content_type_buf); |
| ret = ERR_PARAM_INVALID; |
| goto end; |
| } |
| |
| /*fbf segment size */ |
| content_len = atoi(env_content_len); |
| CGI_LOGI("%s: content length %d\n", __func__, content_len); |
| if (boundary_found) { |
| p += strlen("boundary="); |
| strncpy(boundary_buf, p, sizeof(boundary_buf) - 1); |
| CGI_LOGI("%s: boundary=%s\n", __func__, boundary_buf); |
| n_boundary = strlen("\r\n--") + strlen(boundary_buf); |
| } |
| else { |
| p += strlen(CONTENET_TYPE_OCTECT); |
| /* find ',' */ |
| if (*p == ',') |
| { |
| /* skip ',' and ' ' */ |
| p += 2; |
| strncpy(boundary_buf, p, sizeof(boundary_buf) - 1); |
| CGI_LOGI("%s: fbf file size %s, %d\n", __func__, boundary_buf, atoi(boundary_buf)); |
| |
| /*fbf total size */ |
| n_file_size = atoi(boundary_buf); |
| if (n_file_size == 0) |
| goto end; |
| } |
| } |
| |
| if (boundary_found) { |
| /*read first boundary */ |
| if ((n_read = read(0, buf, MAX_TCP_BUF_SIZE)) > 0) { |
| CGI_LOGI("%s: read size %d n_boundary %d\n", __func__, n_read, n_boundary); |
| n_form_head = get_request_len(buf + n_boundary, FORM_HEAD_MAX_SIZE); |
| if (n_form_head > 0) { |
| n_form_head += n_boundary; |
| n_fbf = n_read - n_form_head; |
| memcpy(fbf_buf, buf + n_form_head, n_fbf); |
| n_fbf_total += n_fbf; |
| } else { |
| /*not get full form head */ |
| CGI_LOGI("%s: not get full form head\n", __func__); |
| buf[n_read] = '\0'; |
| |
| p = strstr(buf, "Content-Type:"); |
| if (!p) { |
| goto end; |
| } |
| |
| p1 = strstr(buf, "\r\n\r\n"); |
| if (!p1) { |
| goto end; |
| } |
| |
| if (p > p1) { |
| goto end; |
| } |
| len = p1 + strlen("\r\n\r\n") - p - strlen("Content-Type:"); |
| if (len < 0) { |
| goto end; |
| } |
| memcpy(media_type, p + strlen("Content-Type:"), len); |
| media_type[len] = '\0'; |
| |
| CGI_LOGI("%s: len %d media_type %s\n", __func__, len, media_type); |
| |
| p = strstr(buf, media_type); |
| if (!p) { |
| goto end; |
| } |
| n_form_head = p - buf + strlen(media_type); |
| CGI_LOGI("%s: n_form_head %d\n", __func__, n_form_head); |
| if (n_form_head > n_read) |
| goto end; |
| n_fbf = n_read - n_form_head; |
| memcpy(fbf_buf, buf + n_form_head, n_fbf); |
| n_fbf_total += n_fbf; |
| |
| n_file_size = content_len - n_form_head - n_boundary - strlen("\r\n--"); |
| CGI_LOGI("%s: fbf size %d\n", __func__, n_file_size); |
| } |
| /**here we should send fbf to OTA service**/ |
| CGI_LOGI("%s: forward file segment, length %d, total length %d\n", __func__, n_fbf, n_fbf_total); |
| #ifdef TMP_STORE_FBF |
| fbf_tmp = strdup("/tmp/fbf.XXXXXX"); |
| if ((fd_tmp = mkstemp(fbf_tmp)) < 0) |
| goto end; |
| close(fd_tmp); |
| fd_tmp = open(fbf_tmp, O_WRONLY | O_TRUNC | O_CREAT | O_APPEND, 0); |
| if (fd_tmp == -1) |
| goto end; |
| write(fd_tmp, fbf_buf, n_fbf); |
| #else |
| if (!ops->upload_fw_init_cb) { |
| CGI_LOGE("%s: upload forward init not registered\n", __func__); |
| goto end; |
| } |
| ret = ops->upload_fw_init_cb(&upload_obj, n_file_size, 0); |
| if (ret != NO_ERR) { |
| CGI_LOGE("%s: upload forward init Failed\n", __func__); |
| goto end; |
| } |
| |
| if (!ops->upload_fw_write_cb) { |
| CGI_LOGE("%s: upload forward write not registered \n", __func__); |
| goto end; |
| } |
| ret = ops->upload_fw_write_cb(&upload_obj, fbf_buf, n_fbf); |
| if (ret != NO_ERR) { |
| CGI_LOGE("%s: upload forward write Failed\n", __func__); |
| goto end; |
| } |
| #endif |
| } |
| n_consumed += n_read; |
| CGI_LOGI("%s: after first boundary get file len %d\n", __func__, n_fbf_total); |
| } |
| else { |
| if (!ops->upload_fw_init_cb) { |
| CGI_LOGE("%s: upload forward init not registered\n", __func__); |
| goto end; |
| } |
| |
| if (!ops->upload_fw_write_cb) { |
| CGI_LOGE("%s: upload forward write not registered \n", __func__); |
| goto end; |
| } |
| |
| ret = ops->upload_fw_init_cb(&upload_obj, n_file_size, content_len); |
| if (ret != NO_ERR) { |
| CGI_LOGE("%s: upload forward init Failed\n", __func__); |
| goto end; |
| } |
| } |
| |
| /*read fbf until done */ |
| //coverity[tainted_data:SUPPRESS] |
| while (n_consumed < content_len) { |
| to_read = MAX_TCP_BUF_SIZE; |
| if (to_read > content_len - n_consumed) { |
| to_read = content_len - n_consumed; |
| } |
| n_read = read(0, buf, to_read); |
| if (n_read <= 0) { |
| /**read failed**/ |
| CGI_LOGE("%s: read failed or read end %d\n", __func__, n_read); |
| goto end; |
| } |
| |
| n_consumed += n_read; |
| CGI_LOGI("%s: read size %d\n", __func__, n_consumed); |
| |
| if (boundary_found) { |
| if (content_len - n_consumed < n_boundary) { |
| /*get tail boundary in this read, should remove it */ |
| CGI_LOGI("%s: tali boundary, %d %d \n", __func__, n_consumed, content_len); |
| if (n_consumed >= content_len) { |
| /*get all content done */ |
| CGI_LOGE("%s: get all content done\n", __func__); |
| memcpy(fbf_buf, buf, n_read); |
| n_fbf = n_read; |
| } else { |
| memcpy(fbf_buf, buf, n_read); |
| n_fbf = n_read; |
| /*check until get all content done */ |
| while (n_consumed < content_len) { |
| to_read = content_len - n_consumed; |
| n_read = read(0, buf, to_read); |
| if (n_read <= 0) { |
| /**read failed**/ |
| CGI_LOGE("%s: read %d failed or read end %d\n", __func__, to_read, |
| n_read); |
| goto end; |
| } |
| n_consumed += n_read; |
| n_fbf += n_read; |
| memcpy(fbf_buf + n_fbf, buf, n_read); |
| } |
| /*here we should get all connted done */ |
| } |
| |
| /** remove last boundary |
| * "--\r\n" append the tail of boundary |
| * remove it **/ |
| n_boundary += strlen("--\r\n"); |
| n_form_tail = n_fbf - n_boundary; |
| n_fbf = n_form_tail; |
| |
| /*remove '-' '\r''\n' in tail of fbf, if need */ |
| while (1) { |
| if (fbf_buf[n_fbf - 1] == '-' || fbf_buf[n_fbf - 1] == '\r' |
| || fbf_buf[n_fbf - 1] == '\n') |
| n_fbf--; |
| else |
| break; |
| } |
| n_fbf_total += n_fbf; |
| CGI_LOGI("%s: forward file segment, length %d, total length %d\n", __func__, n_fbf, |
| n_fbf_total); |
| /** Here should send fbf segment to OTA service |
| * TODO |
| **/ |
| #ifdef TMP_STORE_FBF |
| write(fd_tmp, fbf_buf, n_fbf); |
| #else |
| ret = ops->upload_fw_write_cb(&upload_obj, fbf_buf, n_fbf); |
| if (ret != NO_ERR) { |
| CGI_LOGE("%s: upload forward write Failed\n", __func__); |
| goto end; |
| } |
| #endif |
| } else { |
| n_fbf_total += n_read; |
| CGI_LOGI("%s: forward file segment, length %d, total length %d\n", __func__, n_read, |
| n_fbf_total); |
| /** Here should send fbf segment to OTA service |
| * TODO |
| **/ |
| #ifdef TMP_STORE_FBF |
| write(fd_tmp, buf, n_read); |
| #else |
| ret = ops->upload_fw_write_cb(&upload_obj, buf, n_read); |
| if (ret != NO_ERR) { |
| CGI_LOGE("%s: upload forward write Failed\n", __func__); |
| goto end; |
| } |
| #endif |
| } |
| } |
| else { |
| ret = ops->upload_fw_write_cb(&upload_obj, buf, n_read); |
| if (ret != NO_ERR) { |
| CGI_LOGE("%s: upload forward write Failed\n", __func__); |
| goto end; |
| } |
| } |
| } |
| |
| end: |
| |
| if (ops->upload_fw_done_cb) |
| ops->upload_fw_done_cb(&upload_obj); |
| |
| if (ret == NO_ERR) |
| { |
| upload_obj.upload_status = UPLOAD_OK; |
| } else { |
| upload_obj.upload_status = ERR_UPLOAD_FAILED; |
| } |
| |
| if (ops->upload_response_cb) { |
| if (ops->upload_response_cb(&upload_obj) != NO_ERR) |
| CGI_LOGE("%s: upload response Failed\n", __func__); |
| } |
| |
| CGI_LOGI("%s: leave with ret %d\n", __func__, ret); |
| return ret; |
| } |
| |
| int download_config_file_init() |
| { |
| int ret = ERR_PARAM_INVALID; |
| char exec_str[128] = { 0 }; |
| |
| CGI_LOGI("%s: enter\n", __func__); |
| snprintf(exec_str, 127, "tar czvf /tmp/pxa1826_cfg.tar.gz /etc/config/ > /dev/null"); |
| ret = system(exec_str); |
| if (ret < 0) |
| ret = ERR_PARAM_INVALID; |
| else |
| ret = NO_ERR; |
| |
| CGI_LOGI("%s: leave %d \n", __func__, ret); |
| return ret; |
| } |
| |
| int response_restore_status(struct upload_ctx *obj) |
| { |
| #define CONF_MGR_TAG "configure_management" |
| #define RESTORE_STATUS_TAG "restore_status" |
| int ret = NO_ERR; |
| int text_size; |
| char *buffer = NULL; |
| struct mime_vec mime; |
| |
| CGI_LOGI("%s: enter\n", __func__); |
| buffer = malloc(XML_GET_BUF_SIZE); |
| if (!buffer) { |
| ret = ERR_PARAM_INVALID; |
| goto end; |
| } |
| memset(buffer, 0, XML_GET_BUF_SIZE); |
| mime.str = "text/xml"; |
| mime.len = strlen("text/xml"); |
| text_size = snprintf(buffer, XML_GET_BUF_SIZE, "<?xml version=\"1.0\" encoding=\"US-ASCII\" ?><RGW><%s><%s>%d</%s></%s></RGW>", |
| CONF_MGR_TAG, RESTORE_STATUS_TAG, (int)obj->upload_status, RESTORE_STATUS_TAG, CONF_MGR_TAG); |
| |
| cgi_init_http_headers(text_size, NULL, &mime); |
| printf("%s",buffer); |
| |
| end: |
| if (buffer) |
| free(buffer); |
| return ret; |
| } |
| |
| int response_firmware_upload(struct upload_ctx *obj) |
| { |
| #define FIRMWARE_TAG "firmware" |
| #define UPLOAD_STATUS_TAG "upload_status" |
| int ret = NO_ERR; |
| int text_size; |
| char *buffer = NULL; |
| struct mime_vec mime; |
| |
| CGI_LOGI("%s: enter\n", __func__); |
| buffer = malloc(XML_GET_BUF_SIZE); |
| if (!buffer) { |
| ret = ERR_PARAM_INVALID; |
| goto end; |
| } |
| memset(buffer, 0, XML_GET_BUF_SIZE); |
| mime.str = "text/xml"; |
| mime.len = strlen("text/xml"); |
| text_size = snprintf(buffer, XML_GET_BUF_SIZE, "<?xml version=\"1.0\" encoding=\"US-ASCII\" ?><RGW><%s><%s>%d</%s></%s></RGW>", |
| FIRMWARE_TAG, UPLOAD_STATUS_TAG, (int)obj->upload_status, UPLOAD_STATUS_TAG, FIRMWARE_TAG); |
| |
| cgi_init_http_headers(text_size, NULL, &mime); |
| printf("%s",buffer); |
| |
| end: |
| if (buffer) |
| free(buffer); |
| return ret; |
| } |
| |
| int response_download_config_file() |
| { |
| struct stat file_stat; |
| char *buffer = NULL; |
| int fd = -1, size = 0, n_write = 0; |
| char file_name[128] = "/tmp/pxa1826_cfg.tar.gz"; |
| int ret = NO_ERR; |
| struct mime_vec mime; |
| char disposition[128] = { 0 }; |
| |
| CGI_LOGI("%s: enter\n", __func__); |
| |
| mime.str = "application/octet-stream"; |
| mime.len = strlen("application/octet-stream"); |
| stat(file_name, &file_stat); |
| if (file_stat.st_size <= 0) { |
| CGI_LOGE("%s: file size %d invalid\n", __func__, file_stat.st_size); |
| ret = ERR_PARAM_INVALID; |
| goto end; |
| } |
| |
| buffer = malloc(XML_GET_BUF_SIZE); |
| if (!buffer) { |
| ret = ERR_PARAM_INVALID; |
| goto end; |
| } |
| memset(buffer, 0, XML_GET_BUF_SIZE); |
| |
| /* init the repsonse header and body */ |
| fd = open(file_name, O_RDONLY); |
| if (fd < 0) { |
| system("echo \"Open xml_res failed\" >> /tmp/my_debug"); |
| ret = ERR_PARAM_INVALID; |
| goto end; |
| } |
| |
| snprintf(disposition, 127, "attachment; filename=%s", CONFIG_FILE_NAME); |
| CGI_LOGI("%s: file size %d\n", __func__, file_stat.st_size); |
| cgi_init_http_headers(file_stat.st_size, disposition, &mime); |
| while ((size = read(fd, buffer, XML_GET_BUF_SIZE)) > 0) { |
| CGI_LOGI("%s: read size %d\n", __func__, size); |
| /*Pirnt the buffer to stdout, the stdout now redirect to pipi_wr, connect to parent process(Web Server) */ |
| fwrite(buffer, size, 1, stdout); |
| if (n_write == size) { |
| CGI_LOGI("%s: write size %d done\n", __func__, size); |
| } |
| } |
| |
| end: |
| CGI_LOGI("%s: leave %d\n", __func__, ret); |
| if (fd >= 0) |
| close(fd); |
| if (buffer) |
| free(buffer); |
| return ret; |
| } |
| |
| int process_download_request(struct download_ops *ops) |
| { |
| int ret = ERR_PARAM_INVALID; |
| |
| CGI_LOGI("%s: enter\n", __func__); |
| |
| if (ops->download_init_cb) { |
| ret = ops->download_init_cb(); |
| if (ret != NO_ERR) |
| goto end; |
| } |
| if (ops->download_response_cb) { |
| ret = ops->download_response_cb(); |
| if (ret != NO_ERR) |
| goto end; |
| } |
| end: |
| CGI_LOGI("%s: leave %d\n", __func__, ret); |
| return ret; |
| } |
| |
| |
| int check_rpc_method_no_auth(char *filepost) |
| { |
| #define UBUS_PARAM_NUM 4 |
| #define PARAM_LEN 32 |
| #define ERROR_CAUSE_TAG "error_cause" |
| mxml_node_t *root = NULL; |
| mxml_node_t *cur = NULL; |
| mxml_node_t *param_node = NULL; |
| char param[UBUS_PARAM_NUM][PARAM_LEN]; |
| unsigned int obj_id; |
| int i = 0; |
| FILE *fp = NULL; |
| int ret = -1; |
| |
| fp = fopen(filepost, "r"); |
| if (fp == NULL) { |
| CGI_LOGE("%s Couldn't read file\n", __func__); |
| ret = -1; |
| goto END; |
| } |
| |
| root = mxmlLoadFile(NULL, fp, MXML_OPAQUE_CALLBACK); |
| fclose(fp); |
| CGI_LOGI("mxmlLoadFile success\n"); |
| |
| cur = mxmlFindElement(root, root, "RGW", NULL, NULL, MXML_DESCEND_FIRST); |
| if (cur == NULL) { |
| CGI_LOGE("%s mxmlFindElement failed\n", __func__); |
| ret = -1; |
| goto END; |
| } |
| cur = cur->child; |
| for (; cur != NULL; cur = cur->next) { |
| if (cur->type != MXML_ELEMENT) { |
| continue; |
| } |
| if (!strcmp(cur->value.element.name, "param")) { |
| param_node = cur->child; |
| i = 0; |
| for (; param_node != NULL; param_node = param_node->next) { |
| if (param_node->type != MXML_ELEMENT) { |
| continue; |
| } |
| if (param_node->child && param_node->child->type != MXML_ELEMENT && |
| param_node->child->child == NULL && param_node->child->next == NULL) { |
| if (param_node->child->value.opaque){ |
| if(i >= UBUS_PARAM_NUM || strlen(param_node->child->value.opaque) > PARAM_LEN){ |
| CGI_LOGE("check_rpc_method_no_auth failed i[%d],opaque len[%d]\n", i, strlen(param_node->child->value.opaque)); |
| ret = -1; |
| goto END; |
| |
| }else{ |
| strcpy(param[i++], param_node->child->value.opaque); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| if (!strcmp(param[RPC_METHOD], "call")){ |
| if(!strcmp(param[PRC_OBJMETHOD],"webdav_get_path_info")){ |
| ret = 0; |
| } |
| } |
| END: |
| if (root) |
| mxmlDelete(root); |
| |
| CGI_LOGI("check_rpc_method_no_auth: ret %d\n", ret); |
| return ret; |
| } |
| |
| int main(int argc, char *argv[]) |
| { |
| char *buffer = NULL; |
| int size; |
| int fd1, fd2; |
| char *xml_set = NULL, *xml_res = NULL; |
| int save_fd; |
| int ret = NO_ERR; |
| int res = NO_ERR; |
| struct upload_forward_ops ul_ops = { 0 }; |
| struct download_ops dl_ops = { 0 }; |
| |
| set_service_log_tag("XML_ACTION"); |
| prctl(PR_SET_NAME, "xml_action"); |
| cgi_init(); |
| if (cgi_ubus_init() != 0) { |
| CGI_LOGE("connect to ubus failed\n"); |
| exit(0); |
| } |
| |
| system("echo xml_action.lock > /sys/power/wake_lock"); |
| |
| start = cgi_process_form(); |
| |
| #if 0 |
| if (access("/tmp/xml_lock", F_OK) < 0) |
| { |
| lock_fd = open("/tmp/xml_lock", O_RDWR|O_CREAT, 0); |
| if (lock_fd < 0) |
| { |
| /* create file failed */ |
| cgi_prepare_response(ERROR_CAUSE_TAG, ERR_CGI_FILE, ERR_NUMBER); |
| goto cgi_cleanup; |
| } |
| } |
| else |
| { |
| /* lock file exist, not allow current request */ |
| cgi_prepare_response(ERROR_CAUSE_TAG, ERR_CGI_FILE, ERR_NUMBER); |
| goto cgi_cleanup; |
| } |
| #endif |
| |
| /*Generate temp unique get-result files for all request */ |
| xml_set = strdup("/tmp/xml_set.XXXXXX"); |
| xml_res = strdup("/tmp/xml_res.XXXXXX"); |
| |
| if ((fd1 = mkstemp(xml_set)) < 0) |
| goto cgi_cleanup; |
| |
| if ((fd2 = mkstemp(xml_res)) < 0) |
| goto cgi_cleanup; |
| |
| close(fd1); |
| close(fd2); |
| |
| /*re-pointer to xml result temp file*/ |
| g_xml_res = xml_res; |
| |
| if (cgi_param(ARG_METHOD)) { |
| /*Open a temporary file in which the body of |
| *POST request will be stored*/ |
| save_fd = open(xml_set, O_WRONLY | O_TRUNC | O_CREAT, 0); |
| if (save_fd == -1) |
| goto cgi_cleanup; |
| |
| if (!buffer) { |
| buffer = malloc(XML_GET_BUF_SIZE); |
| memset(buffer, 0, XML_GET_BUF_SIZE); |
| } |
| /*Read the body of the POST request for stdin which has been redirect to pipe_rd*/ |
| if ((size = read(0, buffer, XML_GET_BUF_SIZE)) > 0) |
| write(save_fd, buffer, size); |
| close(save_fd); |
| |
| res=check_rpc_method_no_auth(xml_set); |
| ret = cgi_session_check(); |
| CGI_LOGE("cgi_session_check ret %d\n", ret); |
| if (ret != SESS_VALID && res!=0) { |
| CGI_LOGE("invalid session!\n"); |
| cgi_prepare_response(ERROR_CAUSE_TAG, ERR_SESSION_INVALID, ERR_NUMBER); |
| } else { |
| xml_duster_parse(xml_set); |
| } |
| send_xml_response(xml_res); |
| CGI_LOGI("send response done!\n"); |
| } |
| if (cgi_param(ARG_ACTION)) { |
| if (cgi_session_check() != SESS_VALID) { |
| cgi_prepare_response(ERROR_CAUSE_TAG, ERR_SESSION_INVALID, ERR_NUMBER); |
| goto cgi_cleanup; |
| } |
| |
| if (!strcmp(cgi_param(ARG_ACTION), "logout")) { |
| cgi_session_destroy(); |
| cgi_prepare_response(RESPONSE_TAG, NO_ERR, ERR_STRING); |
| send_xml_response(xml_res); |
| } else if (!strcmp(cgi_param(ARG_ACTION), "Upload")) { |
| if (!strcmp(cgi_param(ARG_FILE), "upgrade")) { |
| CGI_LOGI("software upgrade!\n"); |
| ul_ops.upload_fw_init_cb = upload_fw_ota_init; |
| ul_ops.upload_fw_write_cb = upload_fw_ota_write; |
| ul_ops.upload_fw_done_cb = upload_fw_ota_done; |
| ul_ops.upload_response_cb = response_firmware_upload; |
| ret = process_upload_request(&ul_ops); |
| if (ret != NO_ERR) |
| { |
| if (upload_obj.upload_status == ERR_UPLOAD_FAILED) |
| system("reboot > /dev/null"); |
| else |
| goto cgi_cleanup; |
| } |
| } else if (!strcmp(cgi_param(ARG_FILE), "restore_config")) { |
| if (cgi_param(ARG_COMMAND)) { |
| if (!strcmp(cgi_param(ARG_COMMAND), "query_status")) { |
| CGI_LOGI("query restore config status!\n"); |
| ul_ops.upload_response_cb = response_restore_status; |
| ul_ops.upload_response_cb(&upload_obj); |
| if (upload_obj.upload_status == UPLOAD_OK) { |
| /*reboot here*/ |
| system("reboot > /dev/null"); |
| } |
| } |
| goto cgi_cleanup; |
| } |
| |
| CGI_LOGI("restore config!\n"); |
| ul_ops.upload_fw_init_cb = upload_fw_fs_init; |
| ul_ops.upload_fw_write_cb = upload_fw_fs_write; |
| ul_ops.upload_fw_done_cb = upload_fw_fs_done; |
| ret = process_upload_request(&ul_ops); |
| if (ret != NO_ERR) { |
| upload_obj.upload_status = ERR_UPLOAD_FAILED; |
| } else |
| upload_obj.upload_status = UPLOAD_OK; |
| |
| goto cgi_cleanup; |
| } |
| } else if (!strcmp(cgi_param(ARG_ACTION), "Download")) { |
| if (!strcmp(cgi_param(ARG_FILE), "backup_config")) { |
| CGI_LOGI("backup config!\n"); |
| dl_ops.download_init_cb = download_config_file_init; |
| dl_ops.download_response_cb = response_download_config_file; |
| ret = process_download_request(&dl_ops); |
| if (ret != NO_ERR) |
| goto cgi_cleanup; |
| } |
| } |
| } |
| |
| cgi_cleanup: |
| cgi_ubus_end(); |
| cgi_end(); |
| if (xml_res) |
| { |
| remove(xml_res); |
| free(xml_res); |
| } |
| //coverity[check_after_deref:SUPPRESS] |
| if (xml_set) |
| { |
| remove(xml_set); |
| free(xml_set); |
| } |
| if (buffer) { |
| free(buffer); |
| buffer = NULL; |
| } |
| |
| #if 0 |
| if (lock_fd != -1) |
| { |
| unlink("/tmp/xml_lock"); |
| } |
| #endif |
| |
| system("echo xml_action.lock > /sys/power/wake_unlock"); |
| CGI_LOGI("%s: exit\n", __func__); |
| exit(0); |
| } |