// The host has been authenticated, so write the stats. // Use a directory hierarchy since there may be many hosts // void write_time_stats_log() { char filename[256]; const char *dirname; int hostid = g_reply->host.id; int dirnum = hostid % 1000; dirname = config.project_path("time_stats_log/%d", dirnum); if (!is_dir(dirname)) { int retval = boinc_mkdir(dirname); if (retval) { log_messages.printf(MSG_CRITICAL, "Can't make time stats log dir %s: %s\n", dirname, boincerror(retval) ); std::perror("mkdir"); return; } } sprintf(filename, "%s/%d", dirname, hostid); #ifndef _USING_FCGI_ FILE* f = fopen(filename, "w"); #else FCGI_FILE *f = FCGI::fopen(filename, "w"); #endif if (!f) { log_messages.printf(MSG_CRITICAL, "Can't create time stats file %s\n", filename ); return; } fputs(stats_buf, f); fclose(f); free(stats_buf); stats_buf = 0; }
// given a filename, compute its path in a directory hierarchy // If create is true, create the directory if needed // int dir_hier_path( const char* filename, const char* root, int fanout, char* path, bool create ) { char dir[256], dirpath[MAXPATHLEN]; int retval; if (fanout==0) { sprintf(path, "%s/%s", root, filename); return 0; } filename_hash(filename, fanout, dir); sprintf(dirpath, "%s/%s", root, dir); if (create) { retval = boinc_mkdir(dirpath); if (retval && (errno != EEXIST)) { fprintf(stderr, "boinc_mkdir(%s): %s: errno %d\n", dirpath, boincerror(retval), errno ); return ERR_MKDIR; } } sprintf(path, "%s/%s", dirpath, filename); return 0; }
int assimilate_handler( WORKUNIT& wu, std::vector<RESULT>& /*results*/, RESULT& canonical_result) { int retval; char buf[1024]; MapReduceTask* mrt = NULL; // First time initialization (loads jobtracker state). // This information is loaded into memory but we only need the output paths // and wu names. We are not updating the file here. if(jobtracker_file == NULL) { // Open jobtracker state file. jobtracker_file = fopen(jobtracker_file_path, "r+"); if (!jobtracker_file){ sprintf(buf, "Can't jobtracker file (%s).\n", jobtracker_file_path); return write_error(buf); } // Parse jobtracker state file. retval = parse_jobtracker(jobtracker_file, jobs); if(retval) { sprintf(buf, "Error parsing jobtracker file\n"); return write_error(buf); } } retval = boinc_mkdir(config.project_path("sample_results")); if (retval) return retval; if (wu.canonical_resultid) { std::vector<OUTPUT_FILE_INFO> output_files; const char *copy_path; get_output_file_infos(canonical_result, output_files); bool file_copied = false; // Get the task identified by the work unit name. mrt = get_task_by_name(jobs, wu.name); if (mrt == NULL) { sprintf(buf, "Can't find MapRedureTask %s\n", wu.name); return write_error(buf); } // FIXME - if wu.name contains reduce, also copy to bt new. -> put mrt output task = bt new retval = boinc_copy(output_files[0].path.c_str() , mrt->getOutputPath().c_str()); if (!retval) { file_copied = true; } if (!file_copied) { copy_path = config.project_path("sample_results/%s_%s", wu.name, "no_output_files"); FILE* f = fopen(copy_path, "w"); fclose(f); } } else { sprintf(buf, "%s: 0x%x\n", wu.name, wu.error_mask); return write_error(buf); } return 0; }
// Create the slot directory for the specified slot # // int make_slot_dir(int slot) { char buf[1024]; if (slot<0) { msg_printf(NULL, MSG_INTERNAL_ERROR, "Bad slot number %d", slot); return ERR_NEG; } boinc_mkdir(SLOTS_DIR); #ifndef _WIN32 mode_t old_mask; if (g_use_sandbox) { old_mask = umask(2); // Allow writing by group chmod(SLOTS_DIR, S_IRUSR|S_IWUSR|S_IXUSR |S_IRGRP|S_IWGRP|S_IXGRP ); umask(old_mask); // Only user boinc_master and group boinc_project can // access slot directories, to keep authenticators private set_to_project_group(SLOTS_DIR); } #endif get_slot_dir(slot, buf, sizeof(buf)); int retval = boinc_mkdir(buf); #ifndef _WIN32 if (g_use_sandbox) { old_mask = umask(2); // Contents of slots directory must be world-readable so BOINC Client can read // files written by projects which have user boinc_project and group boinc_project chmod(buf, S_IRUSR|S_IWUSR|S_IXUSR |S_IRGRP|S_IWGRP|S_IXGRP |S_IROTH|S_IXOTH ); umask(old_mask); set_to_project_group(buf); } #endif return retval; }
// Create the directory for the project p // int make_project_dir(PROJECT& p) { char buf[1024]; int retval; boinc_mkdir(PROJECTS_DIR); #ifndef _WIN32 mode_t old_mask; if (g_use_sandbox) { old_mask = umask(2); // Allow writing by group chmod(PROJECTS_DIR, S_IRUSR|S_IWUSR|S_IXUSR |S_IRGRP|S_IWGRP|S_IXGRP ); umask(old_mask); // Only user boinc_master and group boinc_project can access // project directories, to keep authenticators private set_to_project_group(PROJECTS_DIR); } #endif get_project_dir(&p, buf, sizeof(buf)); retval = boinc_mkdir(buf); #ifndef _WIN32 if (g_use_sandbox) { old_mask = umask(2); // Contents of projects directory must be world-readable so BOINC Client can read // files written by projects which have user boinc_project and group boinc_project chmod(buf, S_IRUSR|S_IWUSR|S_IXUSR |S_IRGRP|S_IWGRP|S_IXGRP |S_IROTH|S_IXOTH ); umask(old_mask); set_to_project_group(buf); } #endif return retval; }
// initialize the diagnostics environment. // int diagnostics_init( int _flags, const char* stdout_prefix, const char* stderr_prefix ) { // Check to see if we have already been called // if (diagnostics_initialized) { return ERR_INVALID_PARAM; } diagnostics_initialized = true; // Setup initial values // flags = _flags; strcpy(stdout_log, ""); strcpy(stdout_archive, ""); strcpy(stderr_log, ""); strcpy(stderr_archive, ""); strcpy(boinc_dir, ""); strcpy(boinc_install_dir, ""); boinc_proxy_enabled = 0; strcpy(boinc_proxy, ""); strcpy(symstore, ""); // Check for invalid parameter combinations // if ((flags & BOINC_DIAG_REDIRECTSTDERR) && (flags & BOINC_DIAG_REDIRECTSTDERROVERWRITE)) { return ERR_INVALID_PARAM; } if ((flags & BOINC_DIAG_REDIRECTSTDOUT) && (flags & BOINC_DIAG_REDIRECTSTDOUTOVERWRITE)) { return ERR_INVALID_PARAM; } // Determine where the log files are to be stored // if (flags & BOINC_DIAG_PERUSERLOGFILES) { char user_dir[MAXPATHLEN]; #if defined(_WIN32) snprintf(user_dir, sizeof(user_dir), "%s", getenv("APPDATA")); strncat(user_dir, "/BOINC", sizeof(user_dir) - strlen(user_dir)-1); #elif defined(__APPLE__) snprintf(user_dir, sizeof(user_dir), "%s", getenv("HOME")); strncat(user_dir, "/Library/Application Support/BOINC", sizeof(user_dir) - strlen(user_dir)-1); #else snprintf(user_dir, sizeof(user_dir), "%s", getenv("HOME")); strncat(user_dir, "/.BOINC", sizeof(user_dir) - strlen(user_dir)-1); #endif // Check to see if the directory exists if (!is_dir(user_dir)) { boinc_mkdir(user_dir); } snprintf(stdout_log, sizeof(stdout_log), "%s/%s.txt", user_dir, stdout_prefix); snprintf(stdout_archive, sizeof(stdout_archive), "%s/%s.old", user_dir, stdout_prefix); snprintf(stderr_log, sizeof(stderr_log), "%s/%s.txt", user_dir, stderr_prefix); snprintf(stderr_archive, sizeof(stderr_archive), "%s/%s.old", user_dir, stderr_prefix); } else { snprintf(stdout_log, sizeof(stdout_log), "%s.txt", stdout_prefix); snprintf(stdout_archive, sizeof(stdout_archive), "%s.old", stdout_prefix); snprintf(stderr_log, sizeof(stderr_log), "%s.txt", stderr_prefix); snprintf(stderr_archive, sizeof(stderr_archive), "%s.old", stderr_prefix); } // Archive any old stderr.txt and stdout.txt files, if requested // if (flags & BOINC_DIAG_ARCHIVESTDERR) { boinc_copy(stderr_log, stderr_archive); } if (flags & BOINC_DIAG_ARCHIVESTDOUT) { boinc_copy(stdout_log, stdout_archive); } // Redirect stderr and/or stdout, if requested // if (flags & BOINC_DIAG_REDIRECTSTDERR) { file_size(stderr_log, stderr_file_size); stderr_file = freopen(stderr_log, "a", stderr); if (!stderr_file) { return ERR_FOPEN; } setbuf(stderr_file, 0); } if (flags & BOINC_DIAG_REDIRECTSTDERROVERWRITE) { stderr_file = freopen(stderr_log, "w", stderr); if (!stderr_file) { return ERR_FOPEN; } setbuf(stderr_file, 0); } if (flags & BOINC_DIAG_REDIRECTSTDOUT) { file_size(stdout_log, stdout_file_size); stdout_file = freopen(stdout_log, "a", stdout); if (!stdout_file) { return ERR_FOPEN; } } if (flags & BOINC_DIAG_REDIRECTSTDOUTOVERWRITE) { stdout_file = freopen(stdout_log, "w", stdout); if (!stdout_file) { return ERR_FOPEN; } } #if defined(_WIN32) #if defined(_DEBUG) _CrtSetReportHook(boinc_message_reporting); if (flags & BOINC_DIAG_MEMORYLEAKCHECKENABLED) { SET_CRT_DEBUG_FIELD(_CRTDBG_LEAK_CHECK_DF); } if (flags & BOINC_DIAG_HEAPCHECKENABLED) { if (flags & BOINC_DIAG_HEAPCHECKEVERYALLOC) { SET_CRT_DEBUG_FIELD(_CRTDBG_CHECK_ALWAYS_DF); } else { SET_CRT_DEBUG_FIELD(_CRTDBG_CHECK_EVERY_1024_DF); } } if (flags & BOINC_DIAG_BOINCAPPLICATION) { if (flags & BOINC_DIAG_MEMORYLEAKCHECKENABLED) { _CrtMemCheckpoint(&start_snapshot); } } #endif // defined(_DEBUG) // Initialize the thread list structure // The data for this structure should be set by // boinc_init or boinc_init_graphics. diagnostics_init_thread_list(); diagnostics_init_unhandled_exception_monitor(); diagnostics_init_message_monitor(); #endif // defined(_WIN32) #ifdef ANDROID #define resolve_func(l,x) \ x=(x##_t)dlsym(l,#x); \ if (!x) {\ fprintf(stderr,"Unable to resolve function %s\n",#x); \ unwind_backtrace_signal_arch=NULL; \ } if ((libhandle=dlopen("libcorkscrew.so",RTLD_NOW|RTLD_GLOBAL))) { resolve_func(libhandle,unwind_backtrace_signal_arch); resolve_func(libhandle,acquire_my_map_info_list); resolve_func(libhandle,release_my_map_info_list); resolve_func(libhandle,get_backtrace_symbols); resolve_func(libhandle,free_backtrace_symbols); resolve_func(libhandle,format_backtrace_line); resolve_func(libhandle,load_symbol_table); resolve_func(libhandle,free_symbol_table); resolve_func(libhandle,find_symbol); } else { fprintf(stderr,"stackdumps unavailable\n"); } #endif // ANDROID // Install unhandled exception filters and signal traps. if (BOINC_SUCCESS != boinc_install_signal_handlers()) { return ERR_SIGNAL_OP; } // Store various pieces of inforation for future use. if (flags & BOINC_DIAG_BOINCAPPLICATION) { char buf[256]; char proxy_address[256]; int proxy_port; MIOFILE mf; FILE* p; #ifdef _WIN32 LONG lReturnValue; HKEY hkSetupHive; DWORD dwSize = 0; #endif strcpy(buf, ""); strcpy(proxy_address, ""); proxy_port = 0; #ifndef _USING_FCGI_ p = fopen(INIT_DATA_FILE, "r"); #else p = FCGI::fopen(INIT_DATA_FILE, "r"); #endif if (p) { mf.init_file(p); while(mf.fgets(buf, sizeof(buf))) { if (match_tag(buf, "</app_init_data>")) break; else if (parse_str(buf, "<boinc_dir>", boinc_dir, sizeof(boinc_dir))) continue; else if (parse_str(buf, "<symstore>", symstore, sizeof(symstore))) ; else if (match_tag(buf, "<use_http_proxy/>")) { boinc_proxy_enabled = true; continue; } else if (parse_str(buf, "<http_server_name>", proxy_address, sizeof(proxy_address))) continue; else if (parse_int(buf, "<http_server_port>", proxy_port)) continue; } fclose(p); } if (boinc_proxy_enabled) { int buffer_used = snprintf(boinc_proxy, sizeof(boinc_proxy), "%s:%d", proxy_address, proxy_port); if ((sizeof(boinc_proxy) == buffer_used) || (-1 == buffer_used)) { boinc_proxy[sizeof(boinc_proxy)-1] = '\0'; } } #ifdef _WIN32 // Lookup the location of where BOINC was installed to and store // that for future use. lReturnValue = RegOpenKeyEx( HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Space Sciences Laboratory, U.C. Berkeley\\BOINC Setup"), 0, KEY_READ, &hkSetupHive ); if (lReturnValue == ERROR_SUCCESS) { // How large does our buffer need to be? dwSize = sizeof(boinc_install_dir); lReturnValue = RegQueryValueEx( hkSetupHive, _T("INSTALLDIR"), NULL, NULL, (LPBYTE)&boinc_install_dir, &dwSize ); } if (hkSetupHive) RegCloseKey(hkSetupHive); #endif } return BOINC_SUCCESS; }
int main(int argc, char** argv) { int retval; bool one_pass = false; int i; int sleep_sec = 600; check_stop_daemons(); for (i=1; i<argc; i++) { if (is_arg(argv[i], "one_pass")) { one_pass = true; } else if (is_arg(argv[i], "dont_delete")) { dont_delete = true; } else if (is_arg(argv[i], "d") || is_arg(argv[i], "debug_level")) { if (!argv[++i]) { log_messages.printf(MSG_CRITICAL, "%s requires an argument\n\n", argv[--i]); usage(argv[0]); exit(1); } int dl = atoi(argv[i]); log_messages.set_debug_level(dl); if (dl == 4) g_print_queries = true; } else if (is_arg(argv[i], "min_age_days")) { if (!argv[++i]) { log_messages.printf(MSG_CRITICAL, "%s requires an argument\n\n", argv[--i]); usage(argv[0]); exit(1); } min_age_days = atof(argv[i]); } else if (is_arg(argv[i], "max")) { if (!argv[++i]) { log_messages.printf(MSG_CRITICAL, "%s requires an argument\n\n", argv[--i]); usage(argv[0]); exit(1); } max_number_workunits_to_purge= atoi(argv[i]); } else if (is_arg(argv[i], "daily_dir")) { daily_dir=true; } else if (is_arg(argv[i], "zip")) { compression_type=COMPRESSION_ZIP; } else if (is_arg(argv[i], "gzip")) { compression_type=COMPRESSION_GZIP; } else if (is_arg(argv[i], "max_wu_per_file")) { if(!argv[++i]) { log_messages.printf(MSG_CRITICAL, "%s requires an argument\n\n", argv[--i]); usage(argv[0]); exit(1); } max_wu_per_file = atoi(argv[i]); } else if (is_arg(argv[i], "no_archive")) { no_archive = true; } else if (is_arg(argv[i], "-sleep")) { if(!argv[++i]) { log_messages.printf(MSG_CRITICAL, "%s requires an argument\n\n", argv[--i]); usage(argv[0]); exit(1); } sleep_sec = atoi(argv[i]); if (sleep_sec < 1 || sleep_sec > 86400) { log_messages.printf(MSG_CRITICAL, "Unreasonable value of sleep interval: %d seconds\n", sleep_sec ); usage(argv[0]); exit(1); } } else if (is_arg(argv[i], "--help") || is_arg(argv[i], "-help") || is_arg(argv[i], "-h")) { usage(argv[0]); return 0; } else if (is_arg(argv[i], "--version") || is_arg(argv[i], "-version")) { printf("%s\n", SVN_VERSION); exit(0); } else { log_messages.printf(MSG_CRITICAL, "unknown command line argument: %s\n\n", argv[i] ); usage(argv[0]); exit(1); } } retval = config.parse_file(); if (retval) { log_messages.printf(MSG_CRITICAL, "Can't parse config.xml: %s\n", boincerror(retval) ); exit(1); } log_messages.printf(MSG_NORMAL, "Starting\n"); retval = boinc_db.open( config.db_name, config.db_host, config.db_user, config.db_passwd ); if (retval) { log_messages.printf(MSG_CRITICAL, "Can't open DB\n"); exit(2); } install_stop_signal_handler(); boinc_mkdir(config.project_path("archives")); // on exit, either via the check_stop_daemons signal handler, or // through a regular call to exit, these functions will be called // in the opposite order of registration. // atexit(close_db_exit_handler); atexit(close_all_archives); while (1) { if (time_to_quit()) { break; } if (!do_pass() && !one_pass) { log_messages.printf(MSG_NORMAL, "Sleeping....\n"); sleep(sleep_sec); } if (one_pass) { break; } } // files and database are closed by exit handler exit(0); }