Пример #1
0
// 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;
}
Пример #2
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;
}
Пример #4
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;
}
Пример #5
0
// 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;
}
Пример #6
0
// 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;
}
Пример #7
0
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);
}