// This file is part of BOINC. // http://boinc.berkeley.edu // Copyright (C) 2012 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License // as published by the Free Software Foundation, // either version 3 of the License, or (at your option) any later version. // // BOINC is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with BOINC. If not, see . #include #include #include #include #include #include "parse.h" #include "job_rpc.h" using std::vector; using std::string; // do an HTTP GET request. // static int do_http_get( const char* url, const char* dst_path ) { FILE* reply = fopen(dst_path, "w"); if (!reply) return -1; CURL *curl = curl_easy_init(); if (!curl) { return -1; } curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_USERAGENT, "BOINC Condor adapter"); curl_easy_setopt(curl, CURLOPT_WRITEDATA, reply); CURLcode res = curl_easy_perform(curl); if (res != CURLE_OK) { fprintf(stderr, "CURL error: %s\n", curl_easy_strerror(res)); } curl_easy_cleanup(curl); return 0; } // send an HTTP POST request, // with an optional set of multi-part file attachments // static int do_http_post( const char* url, const char* request, FILE* reply, vector send_files ) { CURL *curl; CURLcode res; char buf[256]; curl = curl_easy_init(); if (!curl) { return -1; } struct curl_httppost *formpost=NULL; struct curl_httppost *lastptr=NULL; struct curl_slist *headerlist=NULL; curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "request", CURLFORM_COPYCONTENTS, request, CURLFORM_END ); for (unsigned int i=0; i &paths, vector &md5s, int batch_id, vector &absent_files ) { string req_msg; char buf[256]; req_msg = "\n"; sprintf(buf, "%s\n", authenticator); req_msg += string(buf); if (batch_id) { sprintf(buf, "%d\n", batch_id); req_msg += string(buf); } for (unsigned int i=0; i%s\n", md5s[i].c_str()); req_msg += string(buf); } req_msg += "\n"; FILE* reply = tmpfile(); char url[256]; sprintf(url, "%sjob_file.php", project_url); int retval = do_http_post(url, req_msg.c_str(), reply, paths); if (retval) { fclose(reply); return retval; } fseek(reply, 0, SEEK_SET); int x; while (fgets(buf, 256, reply)) { printf("reply: %s", buf); if (strstr(buf, "error")) { retval = -1; } if (parse_int(buf, "", x)) { absent_files.push_back(x); continue; } } fclose(reply); return retval; } int upload_files ( const char* project_url, const char* authenticator, vector &paths, vector &md5s, int batch_id ) { char buf[1024]; string req_msg = "\n"; sprintf(buf, "%s\n", authenticator); req_msg += string(buf); if (batch_id) { sprintf(buf, "%d\n", batch_id); req_msg += string(buf); } for (unsigned int i=0; i%s\n", md5s[i].c_str()); req_msg += string(buf); } req_msg += "\n"; FILE* reply = tmpfile(); char url[256]; sprintf(url, "%sjob_file.php", project_url); int retval = do_http_post(url, req_msg.c_str(), reply, paths); if (retval) { fclose(reply); return retval; } fseek(reply, 0, SEEK_SET); bool success = false; while (fgets(buf, 256, reply)) { printf("upload_files reply: %s", buf); if (strstr(buf, "success")) { success = true; break; } } fclose(reply); if (!success) return -1; return 0; } int create_batch( const char* project_url, const char* authenticator, const char* batch_name, const char* app_name, int& batch_id ) { char request[1024]; char url[1024]; sprintf(request, "\n" " %s\n" " \n" " %s\n" " %s\n" " \n" "\n", authenticator, batch_name, app_name ); sprintf(url, "%ssubmit_rpc_handler.php", project_url); FILE* reply = tmpfile(); vector x; int retval = do_http_post(url, request, reply, x); if (retval) { fclose(reply); return retval; } char buf[256]; batch_id = 0; fseek(reply, 0, SEEK_SET); while (fgets(buf, 256, reply)) { printf("create_batch reply: %s", buf); if (parse_int(buf, "", batch_id)) break; } fclose(reply); if (batch_id == 0) { return -1; } return 0; } int submit_jobs( const char* project_url, const char* authenticator, SUBMIT_REQ &req ) { char buf[1024], url[1024]; sprintf(buf, "\n" "%s\n" "\n" " %d\n" " %s\n", authenticator, req.batch_id, req.app_name ); string request = buf; for (unsigned int i=0; i\n"; } for (unsigned int j=0; j::iterator iter = req.local_files.find(infile.src_path); if (iter == req.local_files.end()) { fprintf(stderr, "file %s not in map\n", infile.src_path); exit(1); } LOCAL_FILE& lf = iter->second; sprintf(buf, "\n" "local_staged\n" "jf_%s\n" "\n", lf.md5 ); request += buf; } request += "\n"; } request += "\n\n"; sprintf(url, "%ssubmit_rpc_handler.php", project_url); FILE* reply = tmpfile(); vector x; int retval = do_http_post(url, request.c_str(), reply, x); if (retval) { fclose(reply); return retval; } fseek(reply, 0, SEEK_SET); retval = 0; while (fgets(buf, 256, reply)) { printf("submit_batch reply: %s", buf); if (strstr(buf, "error")) { retval = -1; } } fclose(reply); return retval; } int query_batch( const char* project_url, const char* authenticator, int batch_id, QUERY_BATCH_REPLY& qb_reply ) { string request; char url[1024], buf[256]; request = "\n"; sprintf(buf, "%d\n", batch_id); request += string(buf); sprintf(buf, "%s\n", authenticator); request += string(buf); request += "\n"; sprintf(url, "%ssubmit_rpc_handler.php", project_url); FILE* reply = tmpfile(); vector x; int retval = do_http_post(url, request.c_str(), reply, x); if (retval) { fclose(reply); return retval; } fseek(reply, 0, SEEK_SET); retval = 0; while (fgets(buf, 256, reply)) { printf("query_batch reply: %s", buf); if (strstr(buf, "error")) { retval = -1; } if (strstr(buf, "")) { QUERY_BATCH_JOB qbj; while (fgets(buf, 256, reply)) { if (strstr(buf, "")) { qb_reply.jobs.push_back(qbj); } if (parse_str(buf, "job_name", qbj.job_name)) continue; if (parse_str(buf, "status", qbj.status)) continue; } } } fclose(reply); return retval; } int get_output_file( const char* project_url, const char* authenticator, const char* job_name, int file_num, const char* dst_path ) { char url[1024]; sprintf(url, "%sget_output.php?cmd=workunit_file&auth_str=%s&wu_name=%s&file_num=%d", project_url, authenticator, job_name, file_num ); printf("fetching %s to %s\n", url, dst_path); return do_http_get(url, dst_path); }