int8_t http_send_message(char *msg_out, char **msg_in) { CURLcode res; curl_easy_setopt(curl, CURLOPT_POSTFIELDS, msg_out); http_c.header_list = NULL; http_c.header_list = curl_slist_append(http_c.header_list, "Accept:"); if (!http_c.header_list) return -1; http_c.header_list = curl_slist_append(http_c.header_list, "User-Agent: easycwmp"); if (!http_c.header_list) return -1; http_c.header_list = curl_slist_append(http_c.header_list, "Content-Type: text/xml; charset=\"utf-8\""); if (!http_c.header_list) return -1; if (config->acs->http100continue_disable) { http_c.header_list = curl_slist_append(http_c.header_list, "Expect:"); if (!http_c.header_list) return -1; } if (msg_out) { DDF("+++ SEND HTTP REQUEST +++\n"); DDF("%s", msg_out); DDF("--- SEND HTTP REQUEST ---\n"); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long) strlen(msg_out)); http_c.header_list = curl_slist_append(http_c.header_list, "SOAPAction;"); if (!http_c.header_list) return -1; } else { DDF("+++ SEND EMPTY HTTP REQUEST +++\n"); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 0); } curl_easy_setopt(curl, CURLOPT_HTTPHEADER, http_c.header_list); curl_easy_setopt(curl, CURLOPT_WRITEDATA, msg_in); *msg_in = (char *) calloc (1, sizeof(char)); res = curl_easy_perform(curl); if (http_c.header_list) { curl_slist_free_all(http_c.header_list); http_c.header_list = NULL; } if (!strlen(*msg_in)) { FREE(*msg_in); } long httpCode = 0; curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode); if (httpCode == 302 || httpCode == 307) { curl_easy_getinfo(curl, CURLINFO_REDIRECT_URL, &http_redirect_url); if ((http_redirect_url = strdup(http_redirect_url)) == NULL) return -1; http_client_exit(); if (http_client_init()) { D("receiving http redirect: re-initializing http client failed\n"); FREE(http_redirect_url); return -1; } FREE(http_redirect_url); FREE(*msg_in); int redirect = http_send_message(msg_out, msg_in); return redirect; } if (res || (httpCode != 200 && httpCode != 204)) { log_message(NAME, L_NOTICE, "sending http message failed\n"); return -1; } if (*msg_in) { DDF("+++ RECEIVED HTTP RESPONSE +++\n"); DDF("%s", *msg_in); DDF("--- RECEIVED HTTP RESPONSE ---\n"); } else { DDF("+++ RECEIVED EMPTY HTTP RESPONSE +++\n"); } return 0; }
int main (int argc, char **argv) { int c; int start_event = 0; bool foreground = false; while (1) { c = getopt_long(argc, argv, "fhbgv", long_opts, NULL); if (c == EOF) break; switch (c) { case 'b': start_event |= START_BOOT; break; case 'f': foreground = true; break; case 'g': start_event |= START_GET_RPC_METHOD; break; case 'h': print_help(); exit(EXIT_SUCCESS); case 'v': print_version(); exit(EXIT_SUCCESS); default: print_help(); exit(EXIT_FAILURE); } } log_message(NAME, L_DEBUG, "daemon started\n"); setlocale(LC_CTYPE, ""); umask(0037); if (getuid() != 0) { D("run %s as root\n", NAME); exit(EXIT_FAILURE); } /* run early cwmp initialization */ cwmp = calloc(1, sizeof(struct cwmp_internal)); if (!cwmp) return -1; INIT_LIST_HEAD(&cwmp->events); INIT_LIST_HEAD(&cwmp->notifications); INIT_LIST_HEAD(&cwmp->downloads); INIT_LIST_HEAD(&cwmp->scheduled_informs); uloop_init(); backup_init(); config_load(); cwmp_init_deviceid(); if (start_event & START_BOOT) { cwmp_add_event(EVENT_BOOT, NULL, 0, EVENT_BACKUP); cwmp_add_inform_timer(); } if (start_event & START_GET_RPC_METHOD) { cwmp->get_rpc_methods = true; cwmp_add_event(EVENT_PERIODIC, NULL, 0, EVENT_BACKUP); cwmp_add_inform_timer(); } if (netlink_init()) { D("netlink initialization failed\n"); exit(EXIT_FAILURE); } if (ubus_init()) D("ubus initialization failed\n"); http_server_init(); pid_t pid, sid; if (!foreground) { pid = fork(); if (pid < 0) exit(EXIT_FAILURE); if (pid > 0) exit(EXIT_SUCCESS); sid = setsid(); if (sid < 0) { D("setsid() returned error\n"); exit(EXIT_FAILURE); } char *directory = "/"; if ((chdir(directory)) < 0) { D("chdir() returned error\n"); exit(EXIT_FAILURE); } } log_message(NAME, L_DEBUG, "entering main loop\n"); uloop_run(); ubus_exit(); uloop_done(); http_client_exit(); xml_exit(); config_exit(); cwmp_free_deviceid(); free(cwmp); closelog(); log_message(NAME, L_DEBUG, "exiting\n"); return 0; }