// 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 . // BOINC GAHP (Grid ASCII Helper Protocol) daemon #include #include #include #include #include #include #include #include #include using std::map; using std::pair; using std::set; using std::string; using std::vector; bool async_mode = true; // represents a command. // if out is NULL the command is in progress; // otherwise it's the output // struct COMMAND { char* in; char* out; }; typedef map COMMANDS; COMMANDS commands; struct INFILE { char src_path[256]; char dst_path[256]; }; struct JOB { char job_name[256]; vector args; vector infiles; bool all_output_files; vector outfiles; }; struct SUBMIT_REQ { char batch_name[256]; char app_name[256]; vector jobs; }; void compute_md5(string& path) { } // Get a list of the input files used by the batch. // Get their MD5s. // See if they're already on the server. // If not, upload them. // int process_input_files(SUBMIT_REQ& req) { unsigned int i, j; // get the set of source paths w/o dups // set files; for (i=0; i md5s; set::iterator iter = files.begin(); while (iter != files.end()) { string s = *iter; compute_md5(s); iter++; } } int parse_boinc_submit(COMMAND& c, char* p, SUBMIT_REQ& req) { strcpy(req.batch_name, strtok_r(NULL, " ", &p)); strcpy(req.app_name, strtok_r(NULL, " ", &p)); int njobs = atoi(strtok_r(NULL, " ", &p)); for (int i=0; isecond; if (c2->out) { printf("command %d result: %s\n", id, c2->out); free(c2->out); free(c2->in); free(c2); commands.erase(i); } else { printf("command %d not finished\n", id); } return 0; } else { // Handle asynchronous commands // int n = sscanf(c.in, "%s %d", cmd, &id); if (n != 2) { fprintf(stderr, "invalid command: %s\n", c.in); return -1; } COMMAND *cp = new COMMAND; cp->in = c.in; cp->out = NULL; printf("inserting cmd %d\n", id); commands.insert(pair(id, cp)); if (async_mode) { pthread_t thread_handle; pthread_attr_t thread_attrs; pthread_attr_init(&thread_attrs); pthread_attr_setstacksize(&thread_attrs, 32768); int retval = pthread_create( &thread_handle, &thread_attrs, &handle_command_aux, cp ); if (retval) { fprintf(stderr, "can't create thread\n"); return -1; } } else { handle_command_aux(cp); } } return 0; } // read a line from stdin (possibly very long). // Return it in a malloc'd buffer // char* get_cmd() { static const int buf_inc = 16384; char* p = (char*)malloc(buf_inc); if (!p) return NULL; int len = 0; int buf_size = buf_inc; while (1) { char c = fgetc(stdin); if (c == EOF) { return NULL; } if (c == '\n') { p[len] = 0; return p; } p[len++] = c; if (len == buf_size) { p = (char*)realloc(p, len+buf_inc); buf_size += buf_inc; } } } int main() { char* p; int retval; while (1) { p = get_cmd(); if (p == NULL) break; COMMAND c; c.in = p; retval = handle_command(c); if (retval) break; } }