// Given a filename, find its full path in the upload directory hierarchy
// Return ERR_OPENDIR if dir isn't there (possibly recoverable error),
// ERR_NOT_FOUND if dir is there but not file
//
int get_file_path(
    const char *filename, char* upload_dir, int fanout, char* path
) {
    dir_hier_path(filename, upload_dir, fanout, path, true);
    if (boinc_file_exists(path)) {
        return 0;
    }
    char* p = strrchr(path, '/');
    *p = 0;
    if (boinc_file_exists(path)) {
        return ERR_NOT_FOUND;
    }
    return ERR_OPENDIR;
}
Example #2
0
int CBOINCClientManager::IsBOINCConfiguredAsDaemon() {
    bool bReturnValue = false;
#if   defined(__WXMSW__)
    if (is_daemon_installed()) bReturnValue = 1;
#elif defined(__WXMAC__)
    if ( boinc_file_exists("/Library/LaunchDaemons/edu.berkeley.boinc.plist")) {
        bReturnValue = NewStyleDaemon;                      // New-style daemon uses launchd
    }
    if (boinc_file_exists("/Library/StartupItems/boinc/boinc") ) {
        bReturnValue = OldStyleDaemon;                      // Old-style daemon uses StartupItem
    }
#endif
    return bReturnValue;
}
int CBOINCClientManager::IsBOINCConfiguredAsDaemon() {
    bool bReturnValue = false;
#if   defined(__WXMSW__)
    if (IsBOINCServiceInstalled()) bReturnValue = 1;
#elif defined(__WXMAC__)
    if ( boinc_file_exists("/Library/LaunchDaemons/com.googlecode.synecdoche.plist")) {
        bReturnValue = NewStyleDaemon;                      // New-style daemon uses launchd
    }
    if (boinc_file_exists("/Library/StartupItems/boinc/boinc") ) {
        bReturnValue = OldStyleDaemon;                      // Old-style daemon uses StartupItem
    }
#endif
    return bReturnValue;
}
Example #4
0
int CSkinAdvanced::Parse(MIOFILE& in) {
    char buf[256];
    std::string strBuffer;

    while (in.fgets(buf, 256)) {
        if (match_tag(buf, "</advanced>")) break;
        else if (parse_bool(buf, "is_branded", m_bIsBranded)) continue;
        else if (parse_str(buf, "<application_name>", strBuffer)) {
            m_strApplicationName = wxString(strBuffer.c_str(), wxConvUTF8);
            continue;
        } else if (parse_str(buf, "<application_short_name>", strBuffer)) {
            m_strApplicationShortName = wxString(strBuffer.c_str(), wxConvUTF8);
            continue;
        } else if (match_tag(buf, "<application_icon>")) {
            m_iconApplicationIcon.Parse(in);
            continue;
        } else if (match_tag(buf, "<application_icon32>")) {
            m_iconApplicationIcon32.Parse(in);
            continue;
        } else if (match_tag(buf, "<application_disconnected_icon>")) {
            m_iconApplicationDisconnectedIcon.Parse(in);
            continue;
        } else if (match_tag(buf, "<application_snooze_icon>")) {
            m_iconApplicationSnoozeIcon.Parse(in);
            continue;
        } else if (parse_str(buf, "<application_logo>", strBuffer)) {
            if(strBuffer.length()) {
                wxString str = wxString(
                    wxGetApp().GetSkinManager()->ConstructSkinPath() +
                    wxString(strBuffer.c_str(), wxConvUTF8)
                );
                if (boinc_file_exists(str.c_str())) {
                    m_bitmapApplicationLogo = wxBitmap(wxImage(str.c_str(), wxBITMAP_TYPE_ANY));
                }
            }
            continue;
        } else if (parse_str(buf, "<organization_name>", strBuffer)) {
            m_strOrganizationName = wxString(strBuffer.c_str(), wxConvUTF8);
            continue;
        } else if (parse_str(buf, "<organization_website>", strBuffer)) {
            m_strOrganizationWebsite = wxString(strBuffer.c_str(), wxConvUTF8);
            continue;
        } else if (parse_str(buf, "<organization_help_url>", strBuffer)) {
            m_strOrganizationHelpUrl = wxString(strBuffer.c_str(), wxConvUTF8);
            continue;
        } else if (parse_int(buf, "<open_tab>", m_iDefaultTab)) {
            m_bDefaultTabSpecified = true;
            continue;
        } else if (parse_str(buf, "<exit_message>", strBuffer)) {
            m_strExitMessage = wxString(strBuffer.c_str(), wxConvUTF8);
            continue;
        }
    }

    InitializeDelayedValidation();

    return 0;
}
Example #5
0
void CSimpleTaskPanel::FindSlideShowFiles(TaskSelectionData *selData) {
    RESULT* state_result;
    char urlDirectory[1024];
    char fileName[1024];
    char resolvedFileName[1024];
    int j;
    CMainDocument*      pDoc = wxGetApp().GetDocument();
    wxASSERT(pDoc);
    

    selData->slideShowFileNames.Clear();
    state_result = pDoc->state.lookup_result(selData->result->project_url, selData->result->name);
    if (!state_result) {
        pDoc->ForceCacheUpdate();
        state_result = pDoc->state.lookup_result(selData->result->project_url, selData->result->name);
    }
    if (state_result) {
        url_to_project_dir(state_result->project->master_url, urlDirectory);
        for(j=0; j<99; ++j) {
            sprintf(fileName, "%s/slideshow_%s_%02d", urlDirectory, state_result->app->name, j);
            if(boinc_resolve_filename(fileName, resolvedFileName, sizeof(resolvedFileName)) == 0) {
                if (boinc_file_exists(resolvedFileName)) {
                    selData->slideShowFileNames.Add(wxString(resolvedFileName,wxConvUTF8));
                }
            } else {
                break;
            }
        }

        if ( selData->slideShowFileNames.size() == 0 ) {
            for(j=0; j<99; ++j) {
                sprintf(fileName, "%s/slideshow_%02d", urlDirectory, j);
                if(boinc_resolve_filename(fileName, resolvedFileName, sizeof(resolvedFileName)) == 0) {
                    if (boinc_file_exists(resolvedFileName)) {
                        selData->slideShowFileNames.Add(wxString(resolvedFileName,wxConvUTF8));
                    }
                } else {
                    break;
                }
            }
        }
    }
    selData->lastSlideShown = -1;
}
Example #6
0
bool benchmark_time_to_stop(int which) {
#ifndef _WIN32
    if (getppid() == 1) {
        exit(0);
    }
#endif
    if (boinc_file_exists(file_names[which])) {
        return false;
    }
    return true;
}
Example #7
0
/// Set up a file reference, given a slot dir and project dir.
/// This means:
/// -# copy the file to slot dir, if reference is by copy
/// -# else make a soft link
static int setup_file(
    const PROJECT* project, const FILE_INFO* fip, const FILE_REF& fref,
    const std::string& file_path, const std::string& slot_dir, bool input
) {
    int retval;

    std::string link_path = slot_dir + std::string("/");
    if (strlen(fref.open_name)) {
        link_path += std::string(fref.open_name);
    } else {
        link_path += std::string(fip->name);
    }
    std::string rel_file_path = std::string("../../") + file_path;

    // if anonymous platform, this is called even if not first time,
    // so link may already be there
    //
    if (input && project->anonymous_platform && boinc_file_exists(link_path.c_str())) {
        return 0;
    }

    if (fref.copy_file) {
        if (input) {
            retval = boinc_copy(file_path.c_str(), link_path.c_str());
            if (retval) {
                msg_printf(project, MSG_INTERNAL_ERROR,
                    "Can't copy %s to %s: %s", file_path.c_str(), link_path.c_str(),
                    boincerror(retval)
                );
                return retval;
            }
        }
        return 0;
    }

#ifdef _WIN32
    retval = make_soft_link(project, link_path.c_str(), rel_file_path.c_str());
    if (retval) return retval;
#else
    if (project->use_symlinks) {
        retval = symlink(rel_file_path.c_str(), link_path.c_str());
    } else {
        retval = make_soft_link(project, link_path.c_str(), rel_file_path.c_str());
    }
    if (retval) return retval;
#endif
#ifdef SANDBOX
    return set_to_project_group(link_path.c_str());
#endif
    return 0;
}
Example #8
0
void check_stop_daemons() {
    if (caught_stop_signal) {
        log_messages.printf(MSG_NORMAL, "Quitting due to SIGHUP\n");
        exit(0);
    }
    const char *stop_file = config.project_path(STOP_DAEMONS_FILENAME);
    if (boinc_file_exists(stop_file)) {
        log_messages.printf(MSG_NORMAL,
            "Quitting because trigger file '%s' is present\n",
            stop_file
        );
        exit(0);
    }
}
Example #9
0
void benchmark_wait_to_start(int which) {
    while (1) {
        if (boinc_file_exists(file_names[which])) {
            break;
        }
#ifndef _WIN32
        // UNIX: check if client has died.
        // Not needed on windows, where we run as thread in client process
        //
        if (getppid() == 1) {
            exit(0);
        }
#endif
        boinc_sleep(0.1);
    }
}
Example #10
0
// try and open up the JoyWarrior file descriptor
bool CSensorLinuxUSBJW::detect()
{
   setType();
   setPort();

   const char* strJWEnum[LINUX_JOYSTICK_NUM] = LINUX_JOYSTICK_ARRAY;
   // go through and try potential Linux joystick devices from define.h
   int i;
   for (i = 0; i < LINUX_JOYSTICK_NUM; i++) {
      if (! boinc_file_exists(strJWEnum[i]) ) continue; // first see if file (device) exists
      if ( ( m_fdJoy = open(strJWEnum[i], O_RDONLY)) != -1 && testJoystick() ) {
         fprintf(stdout, "%s detected on joystick device %s\n", m_strJoystick, strJWEnum[i]);
         break;  // found a JW24F8
      }
   }
#ifdef QCN_RAW_DATA
   setSingleSampleDT(true); // set to true in raw mode so we don't get any interpolated/avg points (i.e. just the "integer" value hopefully)
#else
   setSingleSampleDT(false);
#endif
   return (bool)(getTypeEnum() == SENSOR_USB_JW24F8);
}
Example #11
0
void debug_sched(const char *trigger) {
    char tmpfilename[256];
#ifndef _USING_FCGI_
    FILE *fp;
#else
    FCGI_FILE *fp;
#endif

    if (!boinc_file_exists(config.project_path("%s", trigger))) {
        return;
    }

    sprintf(tmpfilename,
        "sched_reply_%06d_%06d", g_request->hostid, g_request->rpc_seqno
    );
    // use _XXXXXX if you want random filenames rather than
    // deterministic mkstemp(tmpfilename);

#ifndef _USING_FCGI_
    fp=fopen(tmpfilename, "w");
#else
    fp=FCGI::fopen(tmpfilename,"w");
#endif

    if (!fp) {
        log_messages.printf(MSG_CRITICAL,
            "Found %s, but can't open %s\n", trigger, tmpfilename
        );
        return;
    }

    log_messages.printf(MSG_DEBUG,
        "Found %s, so writing %s\n", trigger, tmpfilename
    );

    g_reply->write(fp, *g_request);
    fclose(fp);

    sprintf(tmpfilename,
        "sched_request_%06d_%06d", g_request->hostid, g_request->rpc_seqno
    );
#ifndef _USING_FCGI_
    fp=fopen(tmpfilename, "w");
#else
    fp=FCGI::fopen(tmpfilename,"w");
#endif

    if (!fp) {
        log_messages.printf(MSG_CRITICAL,
            "Found %s, but can't open %s\n", trigger, tmpfilename
        );
        return;
    }

    log_messages.printf(MSG_DEBUG,
        "Found %s, so writing %s\n", trigger, tmpfilename
    );

    g_request->write(fp);
    fclose(fp);

    return;
}
Example #12
0
void PrintBacktrace(void) {
    int                         err;
    QCrashReportRef             crRef = NULL;

    char                        nameBuf[256], pathToThisProcess[1024];
    const NXArchInfo            *localArch;
    char                        OSMinorVersion = '?';
    time_t                      t;
    char                        atosPipeBuf[1024], cppfiltPipeBuf[1024];
    char                        outBuf[1024], offsetBuf[32];
    char                        *sourceSymbol, *symbolEnd;
    char                        **symbols = NULL;
    void                        *callstack[CALL_STACK_SIZE];
    int                         frames, i;
    void                        *systemlib = NULL;
    FILE                        *atosPipe = NULL;
    FILE                        *cppfiltPipe = NULL;
    backtraceProc               myBacktraceProc = NULL;
    backtrace_symbolsProc       myBacktrace_symbolsProc = NULL;
    char                        saved_env[128], *env = NULL;
    bool                        atosExists = false, cppfiltExists = false;

#if 0
// To debug backtrace logic:
//  * Enable this block of code.
//  * Set a breakpoint at sleep(1) call, and wherever else you wish.
//  * Launch built development application from Finder.
//  * Get this application's pid from Activity Monitor.
//  * Attach Debugger to this application.
//  * Continue until you reach this breakpoint.
//  * Change wait variable to 0 (false).
// This is necessary because GDB intercepts signals even if you tell it 
// not to, so you must attach GDB after the signal handler is invoked.

    bool wait = true;
    
    while (wait) {
        fprintf(stderr, "waiting\n");
        sleep(1);
    }
#endif

    GetNameOfAndPathToThisProcess(nameBuf, sizeof(nameBuf), pathToThisProcess, sizeof(pathToThisProcess));
    
    if (nameBuf[0]) {
        fprintf(stderr, "\nCrashed executable name: %s\n", nameBuf);
    }
    
#ifdef BOINC_VERSION_STRING
    fprintf(stderr, "built using BOINC library version %s\n", BOINC_VERSION_STRING);
#endif

    localArch = NXGetLocalArchInfo();
    fprintf(stderr, "Machine type %s", localArch->description);
#ifdef __LP64__
    fprintf(stderr, " (64-bit executable)\n");
#else
    fprintf(stderr, " (32-bit executable)\n");
#endif

    PrintOSVersion(&OSMinorVersion);

    time(&t);
    fputs(asctime(localtime(&t)), stderr);
    fputc('\n', stderr);
    
    err = QCRCreateFromSelf(&crRef);

    if (OSMinorVersion == '5') {
#ifdef __ppc__
        fputs("BOINC backtrace under OS 10.5.x only shows exported (global) symbols\n", stderr);
        fputs("and may work poorly on a PowerPC Mac after a crash.  For a better\n", stderr);
        fputs("backtrace, run under OS 10.4.x.\n\n", stderr);
#else
        fputs("BOINC backtrace under OS 10.5.x only shows exported (global) symbols\n", stderr);
        fputs("and may not show the final location which caused a crash.  For a better\n", stderr);
        fputs("backtrace, either run under OS 10.4.x or run under OS 10.6.x or later.\n\n", stderr);
#endif
    }
    
    if (OSMinorVersion >= '5') {
        // Use new backtrace functions if available (only in OS 10.5 and later)
        systemlib = dlopen ("/usr/lib/libSystem.dylib", RTLD_NOW );
        if (systemlib) {
            myBacktraceProc = (backtraceProc)dlsym(systemlib, "backtrace");
         }
        if (! myBacktraceProc) {
            goto skipBackTrace;     // Should never happen
        }
        frames = myBacktraceProc(callstack, CALL_STACK_SIZE);
        myBacktrace_symbolsProc = (backtrace_symbolsProc)dlsym(systemlib, "backtrace_symbols");
        if (myBacktrace_symbolsProc) {
            symbols = myBacktrace_symbolsProc(callstack, frames);
        } else {
            goto skipBackTrace;     // Should never happen
        }
        
        atosExists = boinc_file_exists("/usr/bin/atos");
        cppfiltExists = boinc_file_exists("/usr/bin/atos");
        if (atosExists || cppfiltExists) {
            // The bidirectional popen only works if the NSUnbufferedIO environment 
            // variable is set, so we save and restore its current value.
            env = getenv("NSUnbufferedIO");
            if (env) {
                strlcpy(saved_env, env, sizeof(saved_env));
            }
            setenv("NSUnbufferedIO", "YES", 1);
        }
        
        if (atosExists) {
            // The backtrace_symbols() and backtrace_symbols() APIs are limited to 
            // external symbols only, so we also use the atos command-line utility  
            // which gives us debugging symbols when available.
            //
            // For some reason, using the -p option with the value from getpid() 
            // fails here but the -o option with a path does work.
#ifdef __x86_64__
            snprintf(atosPipeBuf, sizeof(atosPipeBuf), "/usr/bin/atos -o \"%s\" -arch x86_64", pathToThisProcess);
#elif defined (__i386__)
            snprintf(atosPipeBuf, sizeof(atosPipeBuf), "/usr/bin/atos -o \"%s\" -arch i386", pathToThisProcess);
#else
            snprintf(atosPipeBuf, sizeof(atosPipeBuf), "/usr/bin/atos -o \"%s\" -arch ppc", pathToThisProcess);
#endif

            atosPipe = popen(atosPipeBuf, "r+");
            if (atosPipe) {
                setbuf(atosPipe, 0);
            }
        }

        if (cppfiltExists) {
            cppfiltPipe = popen("/usr/bin/c++filt -s gnu-v3 -n", "r+");
            if (cppfiltPipe) {
                setbuf(cppfiltPipe, 0);
            }
        }
        
        for (i=0; i<frames; i++) {
            strlcpy(outBuf, symbols[i], sizeof(outBuf));
            if (cppfiltPipe) {
                sourceSymbol = strstr(outBuf, "0x");
                if (sourceSymbol) {
                    sourceSymbol = strchr(sourceSymbol, (int)'_');
                    if (sourceSymbol) {
                        strlcpy(cppfiltPipeBuf, sourceSymbol, sizeof(cppfiltPipeBuf)-1);
                        *sourceSymbol = '\0';
                        symbolEnd = strchr(cppfiltPipeBuf, (int)' ');
                        if (symbolEnd) {
                            strlcpy(offsetBuf, symbolEnd, sizeof(offsetBuf));
                            *symbolEnd = '\0';
                        }
                        fprintf(cppfiltPipe, "%s\n", cppfiltPipeBuf);
                        BT_PersistentFGets(cppfiltPipeBuf, sizeof(cppfiltPipeBuf), cppfiltPipe);
                        symbolEnd = strchr(cppfiltPipeBuf, (int)'\n');
                        if (symbolEnd) {
                            *symbolEnd = '\0';
                        }
                        strlcat(outBuf, cppfiltPipeBuf, sizeof(outBuf));
                        strlcat(outBuf, offsetBuf, sizeof(outBuf));
                    }
                }
            }
            
            if (atosPipe) {
                fprintf(atosPipe, "%#llx\n", (QTMAddr)callstack[i]);
                BT_PersistentFGets(atosPipeBuf, sizeof(atosPipeBuf), atosPipe);
                sourceSymbol = strstr(atosPipeBuf, "0x");
                if (!sourceSymbol) {        // If atos returned a symbol (not just a hex value)
                    sourceSymbol = strstr(outBuf, "0x");
                    if (sourceSymbol) sourceSymbol = strstr(sourceSymbol, " ");
                    if (sourceSymbol) *++sourceSymbol = '\0'; // Remove questionable symbol from backtrace_symbols()
                    strlcat(outBuf, " ", sizeof(outBuf));
                    strlcat(outBuf, atosPipeBuf, sizeof(outBuf));
                    symbolEnd = strchr(outBuf, (int)'\n');
                    if (symbolEnd) {
                        *symbolEnd = '\0';
                    }
                }
            }
            fprintf(stderr, "%s\n", outBuf);
        }

        if (atosPipe) {
            pclose(atosPipe);
        }
        
        if (cppfiltPipe) {
            pclose(cppfiltPipe);
        }

        if (atosExists || cppfiltExists) {
            if (env) {
                setenv("NSUnbufferedIO", saved_env, 1);
            } else {
                unsetenv("NSUnbufferedIO");
            }
        }
        
skipBackTrace:
        fprintf(stderr, "\n");
    } else {
    // Not OS 10.5.x
        QCRPrintBacktraces(crRef, stderr);
    }

    // make sure this much gets written to file in case future 
    // versions of OS break our crash dump code beyond this point.
    fflush(stderr);
    
    QCRPrintThreadState(crRef, stderr);
    QCRPrintImages(crRef, stderr);
}
Example #13
0
int main(int argc, char *argv[])
{
    char                    pkgPath[MAXPATHLEN];
    char                    postInstallAppPath[MAXPATHLEN];
    char                    temp[MAXPATHLEN], temp2[MAXPATHLEN];
    char                    brand[64], s[256];
    char                    *p;
    OSStatus                err = noErr;
    Boolean                 restartNeeded = true;
    FILE                    *restartNeededFile;
    FILE                    *f;
    long                    oldBrandID;

    if (!check_branding_arrays(temp, sizeof(temp))) {
        ShowMessage((char *)_("Branding array has too few entries: %s"), temp);
        return -1;
    }

    if (Initialize() != noErr) {
        return 0;
    }

    strncpy(loginName, getenv("USER"), sizeof(loginName)-1);
    if (loginName[0] == '\0') {
        ShowMessage((char *)_("Could not get user login name"));
        return 0;
    }

    snprintf(tempDirName, sizeof(tempDirName), "InstallBOINC-%s", loginName);
    
    snprintf(temp, sizeof(temp), "/tmp/%s", tempDirName);
    mkdir(temp, 0777);
    chmod(temp, 0777);  // Needed because mkdir sets permissions restricted by umask (022)

    snprintf(temp, sizeof(temp), "rm -dfR /tmp/%s/BOINC_Installer_Errors", tempDirName);
    err = callPosixSpawn(temp);
    
    snprintf(Catalogs_Dir, sizeof(Catalogs_Dir),
            "/tmp/%s/BOINC_payload/Library/Application Support/BOINC Data/locale/",
            tempDirName);

    // Get the full path to Installer package inside this application's bundle
    getPathToThisApp(pkgPath, sizeof(pkgPath));
    strlcpy(temp, pkgPath, sizeof(temp));

    strlcat(pkgPath, "/Contents/Resources/", sizeof(pkgPath));

    strlcpy(postInstallAppPath, pkgPath, sizeof(postInstallAppPath));
    strlcat(postInstallAppPath, "PostInstall.app", sizeof(postInstallAppPath));

    p = strrchr(temp, '/');         // Point to name of this application (e.g., "BOINC Installer.app")
    if (p == NULL) {
        p = temp - 1;
    } else {
        *p = '\0';
    }
    
    // Delete any old project auto-attach key file from our temp directory
    snprintf(temp2, sizeof(temp2), "rm -dfR \"/tmp/%s/%s\"", tempDirName, ACCOUNT_DATA_FILENAME);
    err = callPosixSpawn(temp2);
    REPORT_ERROR(err);

    // Write a file containing the project auto-attach key into our temp
    // directory because the BOINC Data directory may not yet exist.
    // PostInstall.app will copy it into the BOINC Data directory laer
    snprintf(temp2, sizeof(temp2), "%s/%s", temp, ACCOUNT_DATA_FILENAME);
    if (boinc_file_exists(temp2)) {
        // If the project server put account_data.txt file in the same
        // parent directory as this installer, copy it into our temp directory
        snprintf(temp2, sizeof(temp2), "cp \"%s/%s\" \"/tmp/%s/%s\"", temp, ACCOUNT_DATA_FILENAME, tempDirName, ACCOUNT_DATA_FILENAME);
        err = callPosixSpawn(temp2);
        REPORT_ERROR(err);
    } else {
        // Create an account_data.txt file containing our 
        // installer's filename and put it in our temp directory
        snprintf(temp2, sizeof(temp2), "/tmp/%s/%s", tempDirName, ACCOUNT_DATA_FILENAME);
        f = fopen(temp2, "w");
        fputs(p+1, f);
        fclose(f);
    }

    // Write a temp file to tell our PostInstall.app the previous branding, if any
    oldBrandID = GetOldBrandID();
    snprintf(temp, sizeof(temp), "/tmp/%s/OldBranding", tempDirName);
    f = fopen(temp, "w");
    if (!f) {
        REPORT_ERROR(true);
    } else {
        fprintf(f, "BrandId=%ld\n", oldBrandID);
        fclose(f);
    }

    // To allow for branding, assume name of installer package inside bundle corresponds to name of this application
    strlcpy(brand, p+1, sizeof(brand));
    strlcat(pkgPath, p+1, sizeof(pkgPath));
    p = strrchr(pkgPath, ' ');         // Strip off last space character and everything following
    if (p)
        *p = '\0'; 

    p = strrchr(brand, ' ');         // Strip off last space character and everything following
    if (p)
        *p = '\0'; 
    
    strlcat(pkgPath, ".pkg", sizeof(pkgPath));
    
    // In the unlikely situation that /tmp has files from an earlier attempt to install
    // BOINC by a different user, we won't have permission to delete or overwrite them,
    // so include the current user's name as part of the paths to our temporary files.
    
    // Expand the installer package
    snprintf(temp, sizeof(temp), "rm -dfR /tmp/%s/BOINC.pkg", tempDirName);
    err = callPosixSpawn(temp);
    REPORT_ERROR(err);
    snprintf(temp, sizeof(temp), "rm -dfR /tmp/%s/expanded_BOINC.pkg", tempDirName);
    err = callPosixSpawn(temp);
    REPORT_ERROR(err);
    snprintf(temp, sizeof(temp), "rm -dfR /tmp/%s/PostInstall.app", tempDirName);
    err = callPosixSpawn(temp);
    REPORT_ERROR(err);
    snprintf(temp, sizeof(temp), "rm -f /tmp/%s/BOINC_preferred_languages", tempDirName);
    err = callPosixSpawn(temp);
    REPORT_ERROR(err);
    snprintf(temp, sizeof(temp), "rm -f /tmp/%s/BOINC_restart_flag", tempDirName);
    err = callPosixSpawn(temp);
    REPORT_ERROR(err);
    
    sprintf(temp, "cp -fpR \"%s\" /tmp/%s/PostInstall.app", postInstallAppPath, tempDirName);
    err = callPosixSpawn(temp);
    REPORT_ERROR(err);
    sprintf(temp, "pkgutil --expand \"%s\" /tmp/%s/expanded_BOINC.pkg", pkgPath, tempDirName);
    err = callPosixSpawn(temp);
    REPORT_ERROR(err);
    if (err == noErr) {
        GetPreferredLanguages();
    }
    if (compareOSVersionTo(10, 6) < 0) {
        LoadPreferredLanguages();
        BringAppToFront();
        p = strrchr(brand, ' ');         // Strip off last space character and everything following
        if (p)
            *p = '\0'; 
        ShowMessage((char *)_("Sorry, this version of %s requires system 10.6 or higher."), brand);

        snprintf(temp, sizeof(temp), "rm -dfR /tmp/%s/BOINC_payload", tempDirName);
        err = callPosixSpawn(temp);
        REPORT_ERROR(err);
        return -1;
    }

    snprintf(temp, sizeof(temp), "rm -dfR /tmp/%s/BOINC_payload", tempDirName);
    err = callPosixSpawn(temp);
    REPORT_ERROR(err);

    // Remove previous installer package receipt so we can run installer again
    // (affects only older versions of OS X and fixes a bug in those versions)
    // "rm -rf /Library/Receipts/GridRepublic.pkg"
    sprintf(s, "rm -rf \"/Library/Receipts/%s.pkg\"", brand);
    err = callPosixSpawn (s);
    REPORT_ERROR(err);

    restartNeeded = IsRestartNeeded();
    
    // Write a temp file to tell our PostInstall.app whether restart is needed
    snprintf(temp, sizeof(temp), "/tmp/%s/BOINC_restart_flag", tempDirName);
    restartNeededFile = fopen(temp, "w");
    if (restartNeededFile) {
        fputs(restartNeeded ? "1\n" : "0\n", restartNeededFile);
        fclose(restartNeededFile);
    }
    
    if (restartNeeded) {
        if (err == noErr) {
            // Change onConclusion="none" to onConclusion="RequireRestart"
            snprintf(temp, sizeof(temp), "sed -i \".bak\" s/onConclusion=\"none\"/onConclusion=\"RequireRestart\"/g /tmp/%s/expanded_BOINC.pkg/Distribution", tempDirName);
            err = callPosixSpawn(temp);
            REPORT_ERROR(err);
        }
        if (err == noErr) {
            snprintf(temp, sizeof(temp), "rm -dfR /tmp/%s/expanded_BOINC.pkg/Distribution.bak", tempDirName);
            err = callPosixSpawn(temp);
            REPORT_ERROR(err);
            // Flatten the installer package
            sprintf(temp, "pkgutil --flatten /tmp/%s/expanded_BOINC.pkg /tmp/%s/%s.pkg", tempDirName, tempDirName, brand);
            err = callPosixSpawn(temp);
            REPORT_ERROR(err);
        }

        if (err == noErr) {
            snprintf(temp, sizeof(temp), "rm -dfR /tmp/%s/expanded_BOINC.pkg", tempDirName);
            err = callPosixSpawn(temp);
            REPORT_ERROR(err);
            sprintf(temp, "open \"/tmp/%s/%s.pkg\"", tempDirName, brand);
            err = callPosixSpawn(temp);
            REPORT_ERROR(err);
            return err;
        }
    }

    snprintf(temp, sizeof(temp), "rm -dfR /tmp/%s/expanded_BOINC.pkg", tempDirName);
    err = callPosixSpawn(temp);
    REPORT_ERROR(err);

    sprintf(temp, "open \"%s\"", pkgPath);
    err = callPosixSpawn(temp);
    REPORT_ERROR(err);
    
    return err;
}
Example #14
0
// do an account manager RPC;
// if URL is null, detach from current account manager
//
int ACCT_MGR_OP::do_rpc(ACCT_MGR_INFO& _ami, bool _via_gui) {
    int retval;
    unsigned int i;
    char buf[256];

    ami = _ami;

    error_num = ERR_IN_PROGRESS;
    error_str = "";
    via_gui = _via_gui;
    global_prefs_xml = "";

    // if null URL, detach from current AMS
    //
    if (!strlen(ami.master_url) && strlen(gstate.acct_mgr_info.master_url)) {
        msg_printf(NULL, MSG_INFO, "Removing account manager info");
        gstate.acct_mgr_info.clear();
        boinc_delete_file(ACCT_MGR_URL_FILENAME);
        boinc_delete_file(ACCT_MGR_LOGIN_FILENAME);
        error_num = 0;
        for (i=0; i<gstate.projects.size(); i++) {
            gstate.projects[i]->detach_ams();
        }
        ::rss_feeds.update_feed_list();
        gstate.set_client_state_dirty("detach from AMS");
        return 0;
    }

    canonicalize_master_url(ami.master_url, sizeof(ami.master_url));
    if (!valid_master_url(ami.master_url)) {
        error_num = ERR_INVALID_URL;
        return 0;
    }

    FILE* f = boinc_fopen(ACCT_MGR_REQUEST_FILENAME, "w");
    if (!f) return ERR_FOPEN;
    fprintf(f,
        "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
        "<acct_mgr_request>\n"
    );
    if (strlen(ami.authenticator)) {
        fprintf(f,
            "   <authenticator>%s</authenticator>\n",
            ami.authenticator
        );
    } else {
        fprintf(f,
            "   <name>%s</name>\n"
            "   <password_hash>%s</password_hash>\n",
            ami.login_name, ami.password_hash
        );
    }
    fprintf(f,
        "   <host_cpid>%s</host_cpid>\n"
        "   <domain_name>%s</domain_name>\n"
        "   <client_version>%d.%d.%d</client_version>\n"
        "   <run_mode>%s</run_mode>\n",
        gstate.host_info.host_cpid,
        gstate.host_info.domain_name,
        gstate.core_client_version.major,
        gstate.core_client_version.minor,
        gstate.core_client_version.release,
        run_mode_name[gstate.cpu_run_mode.get_perm()]
    );
    gstate.write_platforms(NULL, f);
    if (strlen(gstate.acct_mgr_info.previous_host_cpid)) {
        fprintf(f,
            "   <previous_host_cpid>%s</previous_host_cpid>\n",
            gstate.acct_mgr_info.previous_host_cpid
        );
    }

    // If the AMS requested it, send GUI RPC port and password.
    // This is for the "farm" account manager so it
    // can know where to send GUI RPC requests to
    // without having to configure each host
    //
    if (gstate.acct_mgr_info.send_gui_rpc_info) {
        if (gstate.cmdline_gui_rpc_port) {
            fprintf(f,"   <gui_rpc_port>%d</gui_rpc_port>\n", gstate.cmdline_gui_rpc_port);
        } else {
            fprintf(f,"   <gui_rpc_port>%d</gui_rpc_port>\n", GUI_RPC_PORT);
        }
        if (boinc_file_exists(GUI_RPC_PASSWD_FILE)) {
            char gui_rpc_password[256];
            safe_strcpy(gui_rpc_password, "");
            FILE* pwdf = fopen(GUI_RPC_PASSWD_FILE, "r");
            if (pwdf) {
                if (fgets(gui_rpc_password, 256, pwdf)) {
                    strip_whitespace(gui_rpc_password);
                }
                fclose(pwdf);
            }
            fprintf(f,
                "   <gui_rpc_password>%s</gui_rpc_password>\n",
                gui_rpc_password
            );
        }
    }
    for (i=0; i<gstate.projects.size(); i++) {
        PROJECT* p = gstate.projects[i];
        double not_started_dur, in_progress_dur;
        p->get_task_durs(not_started_dur, in_progress_dur);
        fprintf(f,
            "   <project>\n"
            "      <url>%s</url>\n"
            "      <project_name>%s</project_name>\n"
            "      <suspended_via_gui>%d</suspended_via_gui>\n"
            "      <hostid>%d</hostid>\n"
            "      <not_started_dur>%f</not_started_dur>\n"
            "      <in_progress_dur>%f</in_progress_dur>\n"
            "      <attached_via_acct_mgr>%d</attached_via_acct_mgr>\n"
            "      <dont_request_more_work>%d</dont_request_more_work>\n"
            "      <detach_when_done>%d</detach_when_done>\n"
            "      <ended>%d</ended>\n"
            "      <resource_share>%f</resource_share>\n"
            "      <disk_usage>%f</disk_usage>\n"
            "      <disk_share>%f</disk_share>\n",
            p->master_url,
            p->project_name,
            p->suspended_via_gui?1:0,
            p->hostid,
            not_started_dur,
            in_progress_dur,
            p->attached_via_acct_mgr?1:0,
            p->dont_request_more_work?1:0,
            p->detach_when_done?1:0,
            p->ended?1:0,
            p->resource_share,
            p->disk_usage,
            p->disk_share
        );
        
        // send work and starvation-related info
        //
        if (ami.dynamic) {
            fprintf(f,
                "      <nrpc_failures>%d</nrpc_failures>\n"
                "      <cpu_ec>%f</cpu_ec>\n"
                "      <cpu_time>%f</cpu_time>\n"
                "      <gpu_ec>%f</gpu_ec>\n"
                "      <gpu_time>%f</gpu_time>\n"
                "      <njobs_success>%d</njobs_success>\n"
                "      <njobs_error>%d</njobs_error>\n",
                p->nrpc_failures,
                p->cpu_ec,
                p->cpu_time,
                p->gpu_ec,
                p->gpu_time,
                p->njobs_success,
                p->njobs_error
            );
            for (int j=0; j<coprocs.n_rsc; j++) {
                if (p->sched_req_no_work[j]) {
                    fprintf(f,
                        "    <sched_req_no_work>%s</sched_req_no_work>\n",
                        coprocs.coprocs[j].type
                    );
                }
            }
        }

        if (p->attached_via_acct_mgr) {
            fprintf(f,
                "      <account_key>%s</account_key>\n",
                p->authenticator
            );
        }
        fprintf(f,
            "   </project>\n"
        );
    }
    MIOFILE mf;
    mf.init_file(f);

    // send working prefs
    //
    fprintf(f, "<working_global_preferences>\n");
    gstate.global_prefs.write(mf);
    fprintf(f, "</working_global_preferences>\n");

    if (boinc_file_exists(GLOBAL_PREFS_FILE_NAME)) {
        FILE* fprefs = fopen(GLOBAL_PREFS_FILE_NAME, "r");
        if (fprefs) {
            copy_stream(fprefs, f);
            fclose(fprefs);
        }
    }
    gstate.host_info.write(mf, !cc_config.suppress_net_info, true);
    if (strlen(gstate.acct_mgr_info.opaque)) {
        fprintf(f,
            "   <opaque>\n%s\n"
            "   </opaque>\n",
            gstate.acct_mgr_info.opaque
        );
    }
    gstate.time_stats.write(mf, true);
    gstate.net_stats.write(mf);
    fprintf(f, "</acct_mgr_request>\n");
    fclose(f);
    snprintf(buf, sizeof(buf), "%srpc.php", ami.master_url);
    retval = gui_http->do_rpc_post(
        this, buf, ACCT_MGR_REQUEST_FILENAME, ACCT_MGR_REPLY_FILENAME, true
    );
    if (retval) {
        error_num = retval;
        return retval;
    }
    msg_printf(NULL, MSG_INFO, "Contacting account manager at %s", ami.master_url);

    return 0;
}
Example #15
0
// determine the list of supported platforms.
//
void CLIENT_STATE::detect_platforms() {

#if defined(_WIN32) && !defined(__CYGWIN32__)
#if defined(_WIN64) && defined(_M_X64)
    add_platform("windows_x86_64");
    add_platform("windows_intelx86");
#else
    // see if 32-bit client is running on 64-bit machine
    //
    BOOL bIsWow64 = FALSE;
    fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(
        GetModuleHandle(TEXT("kernel32")),"IsWow64Process"
    );
    if (fnIsWow64Process) {
        if (fnIsWow64Process(GetCurrentProcess(), &bIsWow64)) {
            if (bIsWow64) {
                add_platform("windows_x86_64");
            }
        }
    }
    add_platform("windows_intelx86");
#endif

#elif defined(__APPLE__)

#if defined(__i386__) || defined(__x86_64__)
    OSStatus err = noErr;
    SInt32 version = 0;
    int response = 0;
    int retval = 0;
    size_t len = sizeof(response);

    err = Gestalt(gestaltSystemVersion, &version);
    retval = sysctlbyname("hw.optional.x86_64", &response, &len, NULL, 0);
    if ((err == noErr) && (version >= 0x1050) && response && (!retval)) {
        HOSTTYPE = "x86_64-apple-darwin";
        add_platform("x86_64-apple-darwin");
    } else {
        HOSTTYPE = "i686-apple-darwin";
    }

    // Supported on both Mac Intel architectures    
    add_platform("i686-apple-darwin");
#endif
    // Supported on all 3 Mac architectures
    add_platform("powerpc-apple-darwin");

#elif defined(__linux__) && ( defined(__i386__) || defined(__x86_64__) )
    // Let's try to support both 32 and 64 bit applications in one client
    // regardless of whether it is a 32 or 64 bit client
    const char *uname[]={"/bin/uname","/usr/bin/uname",0};
    int eno=0, support64=0, support32=0;
    FILE *f;
    char cmdline[256];
    cmdline[0]=0;

    // find the 'uname' executable
    do {
        if (boinc_file_exists(uname[eno])) break; 
    } while (uname[++eno] != 0);

    // run it and check the kernel machine architecture.
    if ( uname[eno] != 0 ) {
        strlcpy(cmdline,uname[eno],256);
        strlcat(cmdline," -m",256);
        if ((f=popen(cmdline,"r"))) {
            while (!std::feof(f)) {
                fgets(cmdline,256,f);
                if (strstr(cmdline,"x86_64")) support64=1;
            }
            pclose(f);
        }

        if (!support64) {
	        // we're running on a 32 bit kernel, so we will assume
	        // we are i686-pc-linux-gnu only.
	        support32=1;
	    } else {
	        // we're running on a 64 bit kernel.
	        // Now comes the hard part.  How to tell whether we can run
	        // 32-bit binaries.
#if defined(__i386__) && !defined(__x86_64__)
            // If we're a 32 bit binary, then we obviously can.
	        support32=1;
#else
            // If we're a 64 bit binary, the check is a bit harder.
	        // We'll use the file command to check installation of
	        // 32 bit libraries or executables.
	        const char *file[]={"/usr/bin/file","/bin/file",0};
	        const char *libdir[]={"/lib","/lib32","/lib/32","/usr/lib","/usr/lib32","/usr/lib/32"};
	        const int nlibdirs=sizeof(libdir)/sizeof(char *);
    	    
            // find 'file'
            eno=0;
            do {
                if (boinc_file_exists(file[eno])) break; 
            } while (file[++eno] != 0);
    	    
            // now try to find a 32-bit C library.
	        if (file[eno] != 0) {
	            int i;
	            for (i=0; i < nlibdirs; i++) {
	                struct dirent *entry;
	                DIR *a = opendir(libdir[i]);
                    // if dir doesn't exist, do to the next one
                    if (a == 0) continue;
                    // dir exists. read each entry until you find a 32bit lib
                    while ((support32 == 0) && ((entry=readdir(a)) != 0)) {
                        strlcpy(cmdline, file[eno], 256);
                        strlcat(cmdline, " -L ", 256);
                        strlcat(cmdline, libdir[i], 256);
                        strlcat(cmdline, "/", 256);
                        strlcat(cmdline, entry->d_name, 256);
                        f = popen(cmdline, "r");
                        if (f) {
                            while (!std::feof(f)) {
	                            fgets(cmdline,256,f);
                                // If the library is 32-bit ELF, then we're
                                // golden.
		                        if (strstr(cmdline, "ELF") && strstr(cmdline, "32-bit")) support32=1;
	                        }
			                pclose(f);
                        }  
                    }
                    closedir(a);
                    if (support32) break;
                }
	        }
#endif
        }
    }

    if (support64) {
        add_platform("x86_64-pc-linux-gnu");
    }
    if (support32) {
        add_platform("i686-pc-linux-gnu");
    }

    if (!(support64 || support32)) {
        // Something went wrong. Assume HOSTTYPE and HOSTTYPEALT
        // are correct
        add_platform(HOSTTYPE);
#ifdef HOSTTYPEALT
        add_platform(HOSTTYPEALT);
#endif
    }

#elif defined(sun)
    // Check if we can run 64-bit binaries...
    // this assumes there isn't a 64-bit only solaris.  (Every 64-bit solaris can run 32 bit binaries)

#if defined(__sparc) || defined(sparc)
    char *exe64=const_cast<char *>("/usr/bin/sparcv9/ls");
    char *platform64=const_cast<char *>("sparc64-sun-solaris");
    char *platform32=const_cast<char *>("sparc-sun-solaris");
#elif defined(__i386) || defined(i386) || defined(__amd64) || defined(__x86_64__)
    char *exe64=const_cast<char *>("/usr/bin/amd64/ls");
    char *platform64=const_cast<char *>("x86_64-pc-solaris");
    char *platform32=const_cast<char *>("i686-pc-solaris");
#else
#define UNKNOWN_SOLARIS_PROCESSOR
#endif

#ifndef UNKNOWN_SOLARIS_PROCESSOR
    FILE *f=fopen(exe64,"r"); 
    char *argv[3];
    pid_t pid;
    int rv=0;
    argv[0]=exe64;
    argv[1]=argv[0];
    argv[2]=NULL;
    if (f) {
        fclose(f);
        if (0==(pid=fork())) {
            // we are in child process
            freopen("/dev/null","a",stderr);
            freopen("/dev/null","a",stdout);
            rv=execv(argv[0],argv);
            exit(rv);
        } else {
            // we are in the parent process.
            time_t start=time(0);
            int done;
            // wait 5 seconds or until the process exits.
            do {
                done=waitpid(pid,&rv,WNOHANG);
                sleep(1);
            } while (!done && ((time(0)-start)<5));
            // if we timed out, kill the process	
            if ((time(0)-start)>=5) {
                kill(pid,SIGKILL); 
                done=-1;
            }
            // if we exited with success add the 64 bit platform
            if ((done == pid) && (rv == 0)) {
               add_platform(platform64);
            }
        }
    }
    add_platform(platform32);
    // the following platform is obsolete, but we'll add it anyway.
#if defined(__sparc) || defined(sparc) 
    add_platform("sparc-sun-solaris2.7");
#endif
#else  // !defined(UNKNOWN_SOLARIS_PROCESSOR)

    add_platform(HOSTTYPE);
#ifdef HOSTTYPEALT
    add_platform(HOSTTYPEALT);
#endif

#endif  // !defined(UNKNOWN_SOLARIS_PROCESSOR)

#else                   

    // Any other platform, fall back to the previous method
    add_platform(HOSTTYPE);
#ifdef HOSTTYPEALT
    add_platform(HOSTTYPEALT);
#endif

#endif

    if (config.no_alt_platform) {
        PLATFORM p = platforms[0];
        platforms.clear();
        platforms.push_back(p);
    }

    // add platforms listed in cc_config.xml AFTER the above.
    //
    for (unsigned int i=0; i<config.alt_platforms.size(); i++) {
        add_platform(config.alt_platforms[i].c_str());
    }
}
Example #16
0
void do_client_simulation() {
    char buf[256], buf2[256];
    int retval;
    FILE* f;

    sprintf(buf, "%s%s", infile_prefix, CONFIG_FILE);
    cc_config.defaults();
    read_config_file(true, buf);

    log_flags.init();
    sprintf(buf, "%s%s", outfile_prefix, "log_flags.xml");
    f = fopen(buf, "r");
    if (f) {
        MIOFILE mf;
        mf.init_file(f);
        XML_PARSER xp(&mf);
        xp.get_tag();   // skip open tag
        log_flags.parse(xp);
        fclose(f);
    }

    gstate.add_platform("client simulator");
    sprintf(buf, "%s%s", infile_prefix, STATE_FILE_NAME);
    if (!boinc_file_exists(buf)) {
        fprintf(stderr, "No client state file\n");
        exit(1);
    }
    retval = gstate.parse_state_file_aux(buf);
    if (retval) {
        fprintf(stderr, "state file parse error %d\n", retval);
        exit(1);
    }

    // if tasks have pending transfers, mark as completed
    //
    for (unsigned int i=0; i<gstate.results.size(); i++) {
        RESULT* rp = gstate.results[i];
        if (rp->state() < RESULT_FILES_DOWNLOADED) {
            rp->set_state(RESULT_FILES_DOWNLOADED, "init");
        } else if (rp->state() == RESULT_FILES_UPLOADING) {
            rp->set_state(RESULT_FILES_UPLOADED, "init");
        }
    }

    check_app_config(infile_prefix);
    show_app_config();
    cc_config.show();
    log_flags.show();

    sprintf(buf, "%s%s", infile_prefix, GLOBAL_PREFS_FILE_NAME);
    sprintf(buf2, "%s%s", infile_prefix, GLOBAL_PREFS_OVERRIDE_FILE);
    gstate.read_global_prefs(buf, buf2);
    fprintf(index_file,
        "<h3>Output files</h3>\n"
        "<a href=%s>Summary</a>\n"
        "<br><a href=%s>Log file</a>\n",
        SUMMARY_FNAME, LOG_FNAME
    );

    // fill in GPU device nums and OpenCL flags
    //
    for (int i=0; i<coprocs.n_rsc; i++) {
        COPROC& cp = coprocs.coprocs[i];
        for (int j=0; j<cp.count; j++) {
            cp.device_nums[j] = j;
            if (cp.have_opencl) {
                cp.instance_has_opencl[j] = true;
            }
        }
    }
    set_no_rsc_config();
    process_gpu_exclusions();

    get_app_params();
    if (!include_empty_projects) {
        cull_projects();
    }
    fprintf(summary_file, "--------------------------\n");

    int j=0;
    for (unsigned int i=0; i<gstate.projects.size(); i++) {
        gstate.projects[i]->index = j++;
    }

    clear_backoff();

    gstate.log_show_projects();
    gstate.set_ncpus();
    work_fetch.init();

    //set_initial_rec();

    rec_adjust_period = delta;

    gstate.request_work_fetch("init");
    simulate();

    sim_results.compute_figures_of_merit();

    sprintf(buf, "%s%s", outfile_prefix, RESULTS_DAT_FNAME);
    f = fopen(buf, "w");
    sim_results.print(f);
    fclose(f);
    sprintf(buf, "%s%s", outfile_prefix, RESULTS_TXT_FNAME);
    f = fopen(buf, "w");
    sim_results.print(f, true);
    fclose(f);

    fprintf(summary_file,
        "Simulation done.\n"
        "-------------------------\n"
        "Figures of merit:\n"
    );

    sim_results.print(summary_file, true);

    double cpu_time;
    boinc_calling_thread_cpu_time(cpu_time);
    fprintf(summary_file,
        "-------------------------\n"
        "Simulator CPU time: %f secs\n"
        "-------------------------\n"
        "Peak FLOPS: CPU %.2fG GPU %.2fG\n",
        cpu_time,
        cpu_peak_flops()/1e9,
        gpu_peak_flops()/1e9
    );
    print_project_results(summary_file);

    fclose(rec_file);
    make_graph("REC", "rec", 0);
}
// assimilate_handler() is called by BOINC code and is passed the canonical 
// result for a workunit.  assimilate_handler() reads the referenced result
// file and inserts the result and its signals into the master science DB.
// BOINC also passes the workunit (as it appears in the BOINC DB) and a vector
// containing all results (including the canonical one) for that workunit.
// We use the workunit to determine if there is an error condition.
int assimilate_handler(
    WORKUNIT& boinc_wu, vector<RESULT>& boinc_results, RESULT& boinc_canonical_result
) {
    int retval=0;
    int spike_count=0, spike_inserted_count=0, gaussian_count=0, gaussian_inserted_count=0, pulse_count=0, pulse_inserted_count=0, triplet_count=0, triplet_inserted_count=0;
    static receiver_config receiver_cfg;
    static analysis_config analysis_cfg;
    workunit s_wu;
    workunit_grp s_wu_grp;
    result sah_result;
    spike sah_spike;
    gaussian sah_gaussian;
    pulse sah_pulse;
    triplet sah_triplet;
    char filename[256];
    char * path;
    std::string path_str;
    long sah_result_id;
    sqlint8_t sah_spike_id, sah_gaussian_id, sah_pulse_id, sah_triplet_id;
    static bool first_time = true;
    int sql_error_code;
    long long seti_wu_id;
    time_t now;
    int hotpix_update_count;
    int hotpix_insert_count;

    APP_CONFIG sah_config;

    hotpix hotpix;
    list<long> qpixlist;            // will be a unique list of qpixes for
                                    // updating the hotpix table
    list<long>::iterator qpix_i;

    nanotime.tv_sec = 0;
    nanotime.tv_nsec = 1000000;


    // app specific configuration
    if (first_time) {
	first_time = false;
	receiver_cfg.id = 0;
	analysis_cfg.id   = 0;
    	retval = sah_config.parse_file("..");
    	if (retval) {
      		log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,
       	     	"First entrance to handler : can't parse config file. Exiting.\n"
      		);
  		return(retval);
	} else {
		retval = db_change(sah_config.scidb_name); 
		if (!retval) {
      			log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,
       	     		"First entrance to handler : could not open science DB %s. Exiting.\n",
			sah_config.scidb_name
      			);
  			return(retval);
		} else {
      			log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,
       	     		"First entrance to handler : using science DB %s\n",
			sah_config.scidb_name
      			);
		}
	}
    	// Sometimes we want to perform all assimilation functions
    	// *except* insertion into the science master DB.
    	if (noinsert) {
      		log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,
      		"[%s] assimilator is in noinsert mode.\n",
      		boinc_wu.name
      		);
    	}
    } else {
/*
	retval = db_change(sah_config.scidb_name);
        if (!retval) {
              log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,
                  "First entrance to handler : could not open science DB %s. Exiting.\n",
                  sah_config.scidb_name
              );
              return(retval);
        } else {
              log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,
                  "First entrance to handler : using science DB %s\n",
                  sah_config.scidb_name
              );
        }
*/
   }
   if (noinsert) return 0;   	// Note that this will result in the WU being marked as assimilated - 
				// we will not see it again.

    // translate seti wuid for thos wus that changed ids during the DB merge
    seti_wu_id = new_wu_id((long long)boinc_wu.opaque);
   log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,
         	"[%s] old seti WU id is : %lld  new seti WU id is : %lld\n", 
            boinc_wu.name, (long long)boinc_wu.opaque, seti_wu_id
   );

    if (boinc_wu.canonical_resultid) {
      log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,
            "[%s] Canonical result is %d.  SETI workunit ID is %lld.\n", 
	    boinc_wu.name,  boinc_wu.canonical_resultid, seti_wu_id
      );
    } else {
      log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,
            "[%s] No canonical result\n", boinc_wu.name
      );
    }

    if (!boinc_wu.canonical_resultid) {
	return 0;		// Note that this will result in the WU being marked as assimilated - 
                                // we will not see it again.  No canonical result means that
				// too many results were returned with no concensus. 

    }

    // Obtain and check the full path to the boinc result file.
    retval = get_output_file_path(boinc_canonical_result, path_str);
    if (retval) {
	if (retval == ERR_XML_PARSE) {
		log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,
			"[%s] Cannot extract filename from canonical result %ld.\n",
            		boinc_wu.name,  boinc_wu.canonical_resultid);
        	return(retval);
	} else {
		log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,
                        "[%s] unknown error from get_output_file_path() for result %ld.\n",
                        boinc_wu.name,  boinc_wu.canonical_resultid);
                return(retval);
   	}
     } else {
     	path = (char *)path_str.c_str();
     	if (!boinc_file_exists(path)) {
		log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,
        		"[%s] Output file %s does not exist for result %ld.\n",
               	  	boinc_wu.name, path,  boinc_wu.canonical_resultid);
        	return(-1);
     	} else {
		log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,
                        "[%s] Result %ld : using upload file %s\n",
               	  	boinc_wu.name, boinc_wu.canonical_resultid, path);
	}
    }

    // Open it.
    std::ifstream result_file(path, ios_base::in);
    if (!result_file.is_open()) {
      log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,
           "[%s] open error for result file %s : errno %d\n", 
           boinc_wu.name, path, errno
      );
      return -1;
    }

    retval = get_science_configs(boinc_wu, seti_wu_id, receiver_cfg, analysis_cfg);
    if (retval) {
	if (retval == 100) {
		return (0);
	} else {
		return (-1);
 	}
    }
    log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,
                        "[%s] Result %ld : using receiver_cfg %d and analysis_cfg %d\n",
               	  	boinc_wu.name, boinc_wu.canonical_resultid, receiver_cfg.id, analysis_cfg.id);

    // Insert a sah result
    retval = populate_seti_result(sah_result, boinc_canonical_result, boinc_wu, seti_wu_id);
    sah_result_id = sah_result.insert();
    if (sah_result_id) {
    	log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,
         		"[%s] Inserted result.  Boinc result id is %d.  Sah result id is %lld.\n", 
	 		boinc_wu.name, boinc_canonical_result.id, 
			(long long)sah_result_id
   	);
    } else {
	if (sql_last_error_code() == -239 || sql_last_error_code() == -268) {
		log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,
                        "[%s] Could not insert duplicate result.  SQLCODE is %ld.  SQLMSG is %s.\n",
                        boinc_wu.name, sql_last_error_code(), sql_error_message()
        	);
		return 0; 	// non-fatal - we will never see this result again
	} else {
		log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,
                        "[%s] Could not insert result.  SQLCODE is %ld.  SQLMSG is %s.\n",
                        boinc_wu.name, sql_last_error_code(), sql_error_message()
        	);
        	return -1;	// fatal - non-dup error
	}
    }

    // Insert all sah signals in turn
    insert_signals( sah_spike, 
                    "spike", 
                    boinc_wu.name, 
                    sah_result_id,
                    result_file, 
                    receiver_cfg, 
                    boinc_canonical_result.appid, 
                    analysis_cfg.max_spikes,
                    qpixlist);

    insert_signals( sah_gaussian, 
                    "gaussian", 
                    boinc_wu.name, 
                    sah_result_id,
                    result_file, 
                    receiver_cfg, 
                    boinc_canonical_result.appid, 
                    analysis_cfg.max_gaussians,
                    qpixlist);

    insert_signals( sah_pulse, 
                    "pulse", 
                    boinc_wu.name, 
                    sah_result_id,
                    result_file, 
                    receiver_cfg, 
                    boinc_canonical_result.appid, 
                    analysis_cfg.max_pulses,
                    qpixlist);

    insert_signals( sah_triplet, 
                    "triplet", 
                    boinc_wu.name, 
                    sah_result_id,
                    result_file, 
                    receiver_cfg, 
                    boinc_canonical_result.appid, 
                    analysis_cfg.max_triplets,
                    qpixlist);

    // update last hit time to now for each qpix hit
    qpixlist.unique();
    hotpix_update_count = 0;
    hotpix_insert_count = 0;
    time(&now); 
    for(qpix_i = qpixlist.begin(); qpix_i != qpixlist.end(); qpix_i++) {
        if (hotpix.fetch(*qpix_i)) {
            hotpix.last_hit_time = now;
            hotpix.update();
            hotpix_update_count++;
        } else {
            hotpix.id = *qpix_i;
            hotpix.last_hit_time = now;
            hotpix.insert(*qpix_i);
            hotpix_insert_count++;
        }
    }
    log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,
             "[%s] Updated %d rows and inserted %d rows in the hotpix table\n",
             boinc_wu.name, hotpix_update_count, hotpix_insert_count
    );

    

    return 0;   // the successful assimilation of one WU
}
Example #18
0
int CSkinAdvanced::Parse(MIOFILE& in) {
    char buf[256];
    std::string strBuffer;

    while (in.fgets(buf, 256)) {
        if (match_tag(buf, "</advanced>")) break;
        else if (parse_bool(buf, "is_branded", m_bIsBranded)) continue;
        else if (parse_str(buf, "<application_name>", strBuffer)) {
            m_strApplicationName = wxString(strBuffer.c_str(), wxConvUTF8);
            continue;
        } else if (parse_str(buf, "<application_short_name>", strBuffer)) {
            m_strApplicationShortName = wxString(strBuffer.c_str(), wxConvUTF8);
            continue;
        } else if (match_tag(buf, "<application_icon>")) {
            m_iconApplicationIcon.Parse(in);
            continue;
        } else if (match_tag(buf, "<application_icon32>")) {
            m_iconApplicationIcon.Parse32(in);
            continue;
        } else if (match_tag(buf, "<application_disconnected_icon>")) {
            m_iconApplicationDisconnectedIcon.Parse(in);
            continue;
        } else if (match_tag(buf, "<application_snooze_icon>")) {
            m_iconApplicationSnoozeIcon.Parse(in);
            continue;
        } else if (parse_str(buf, "<application_logo>", strBuffer)) {
            if(strBuffer.length()) {
                wxString str = wxString(
                    wxGetApp().GetSkinManager()->ConstructSkinPath() +
                    wxString(strBuffer.c_str(), wxConvUTF8)
                );
                if (boinc_file_exists(str.c_str())) {
                    wxImage img = wxImage(str.c_str(), wxBITMAP_TYPE_ANY);
                    if (img.IsOk()) {
#ifdef __WXMSW__
// TODO: Choose from multiple size images if provided, else resize the closest one
                        if ((GetXDPIScaling() > 1.05) || (GetYDPIScaling() > 1.05)) {
                            img.Rescale((int) (img.GetWidth()*GetXDPIScaling()), 
                                        (int) (img.GetHeight()*GetYDPIScaling()), 
                                        wxIMAGE_QUALITY_BILINEAR
                                    );
                        }
#endif
                        m_bitmapApplicationLogo = wxBitmap(img);
                    }
                }
            }
            continue;
        } else if (parse_str(buf, "<organization_name>", strBuffer)) {
            m_strOrganizationName = wxString(strBuffer.c_str(), wxConvUTF8);
            continue;
        } else if (parse_str(buf, "<organization_website>", strBuffer)) {
            m_strOrganizationWebsite = wxString(strBuffer.c_str(), wxConvUTF8);
            continue;
        } else if (parse_str(buf, "<organization_help_url>", strBuffer)) {
            m_strOrganizationHelpUrl = wxString(strBuffer.c_str(), wxConvUTF8);
            continue;
        } else if (parse_int(buf, "<open_tab>", m_iDefaultTab)) {
            m_bDefaultTabSpecified = true;
            continue;
        } else if (parse_str(buf, "<exit_message>", strBuffer)) {
            m_strExitMessage = wxString(strBuffer.c_str(), wxConvUTF8);
            continue;
        }
    }

    InitializeDelayedValidation();

    return 0;
}
Example #19
0
bool check_stop_sched() {
    return boinc_file_exists(config.project_path(STOP_SCHED_FILENAME));
}
Example #20
0
// do an account manager RPC;
// if URL is null, detach from current account manager
//
int ACCT_MGR_OP::do_rpc(
    std::string _url, std::string name, std::string password_hash,
    bool _via_gui
) {
    int retval;
    unsigned int i;
    char url[256], password[256], buf[256];
    FILE *pwdf;

    strlcpy(url, _url.c_str(), sizeof(url));

    error_num = ERR_IN_PROGRESS;
    via_gui = _via_gui;
    if (global_prefs_xml) {
        free(global_prefs_xml);
        global_prefs_xml = 0;
    }

    // if null URL, detach from current AMS
    //
    if (!strlen(url) && strlen(gstate.acct_mgr_info.acct_mgr_url)) {
        msg_printf(NULL, MSG_INFO, "Removing account manager info");
        gstate.acct_mgr_info.clear();
        boinc_delete_file(ACCT_MGR_URL_FILENAME);
        boinc_delete_file(ACCT_MGR_LOGIN_FILENAME);
        error_num = 0;
        for (i=0; i<gstate.projects.size(); i++) {
            PROJECT* p = gstate.projects[i];
            p->attached_via_acct_mgr = false;
            p->ams_resource_share = -1;
        }
        return 0;
    }

    canonicalize_master_url(url);
    if (!valid_master_url(url)) {
        error_num = ERR_INVALID_URL;
        return 0;
    }

    strlcpy(ami.acct_mgr_url, url, sizeof(ami.acct_mgr_url));
    strlcpy(ami.acct_mgr_name, "", sizeof(ami.acct_mgr_name));
    strlcpy(ami.login_name, name.c_str(), sizeof(ami.login_name));
    strlcpy(ami.password_hash, password_hash.c_str(), sizeof(ami.password_hash));

    FILE* f = boinc_fopen(ACCT_MGR_REQUEST_FILENAME, "w");
    if (!f) return ERR_FOPEN;
    fprintf(f,
        "<acct_mgr_request>\n"
        "   <name>%s</name>\n"
        "   <password_hash>%s</password_hash>\n"
        "   <host_cpid>%s</host_cpid>\n"
        "   <domain_name>%s</domain_name>\n"
        "   <client_version>%d.%d.%d</client_version>\n"
        "   <run_mode>%s</run_mode>\n",
        name.c_str(), password_hash.c_str(),
        gstate.host_info.host_cpid,
        gstate.host_info.domain_name,
        gstate.core_client_version.major,
        gstate.core_client_version.minor,
        gstate.core_client_version.release,
        run_mode_name[gstate.run_mode.get_perm()]
    );
    if (strlen(gstate.acct_mgr_info.previous_host_cpid)) {
        fprintf(f,
            "   <previous_host_cpid>%s</previous_host_cpid>\n",
            gstate.acct_mgr_info.previous_host_cpid
        );
    }

    // If the AMS requested it, send GUI RPC port and password hash.
    // This is for the "farm" account manager so it
    // can know where to send GUI RPC requests to
    // without having to configure each host
    //
    if (gstate.acct_mgr_info.send_gui_rpc_info) {
        if (gstate.cmdline_gui_rpc_port) {
            fprintf(f,"   <gui_rpc_port>%d</gui_rpc_port>\n", gstate.cmdline_gui_rpc_port);
        } else {
            fprintf(f,"   <gui_rpc_port>%d</gui_rpc_port>\n", GUI_RPC_PORT);
        }
        if (boinc_file_exists(GUI_RPC_PASSWD_FILE)) {
            strcpy(password, "");
            pwdf = fopen(GUI_RPC_PASSWD_FILE, "r");
            if (pwdf) {
                if (fgets(password, 256, pwdf)) {
                    strip_whitespace(password);
                }
                fclose(pwdf);
            }
            fprintf(f,"   <gui_rpc_password>%s</gui_rpc_password>\n", password);
        }
    }
    for (i=0; i<gstate.projects.size(); i++) {
        PROJECT* p = gstate.projects[i];
        fprintf(f,
            "   <project>\n"
            "      <url>%s</url>\n"
            "      <project_name>%s</project_name>\n"
            "      <suspended_via_gui>%d</suspended_via_gui>\n"
            "      <account_key>%s</account_key>\n"
            "      <hostid>%d</hostid>\n"
            "%s"
            "   </project>\n",
            p->master_url,
            p->project_name,
            p->suspended_via_gui,
            p->authenticator,
            p->hostid,
            p->attached_via_acct_mgr?"      <attached_via_acct_mgr/>\n":""
        );
    }
    if (boinc_file_exists(GLOBAL_PREFS_FILE_NAME)) {
        FILE* fprefs = fopen(GLOBAL_PREFS_FILE_NAME, "r");
        if (fprefs) {
            copy_stream(fprefs, f);
            fclose(fprefs);
        }
    }
	if (strlen(gstate.acct_mgr_info.opaque)) {
		fprintf(f,
			"   <opaque>\n%s\n"
			"   </opaque>\n",
			gstate.acct_mgr_info.opaque
		);
	}
    fprintf(f, "</acct_mgr_request>\n");
    fclose(f);
    sprintf(buf, "%srpc.php", url);
    retval = gstate.gui_http.do_rpc_post(
        this, buf, ACCT_MGR_REQUEST_FILENAME, ACCT_MGR_REPLY_FILENAME
    );
    if (retval) {
        error_num = retval;
        return retval;
    }
    msg_printf(NULL, MSG_INFO, "Contacting account manager at %s", url);

    return 0;
}
Example #21
0
bool CBOINCClientManager::IsBOINCCoreRunning() {
    wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::IsBOINCCoreRunning - Function Begin"));
    bool running = false;

#ifdef __WXMSW__
    char buf[MAX_PATH] = "";
    
    if (is_daemon_installed()) {
        running = (FALSE != is_daemon_starting()) || (FALSE != is_daemon_running());
    } else {
        // Global mutex on Win2k and later
        //
        safe_strcpy(buf, "Global\\");
        strcat( buf, RUN_MUTEX);

        HANDLE h = CreateMutexA(NULL, true, buf);
        DWORD err = GetLastError();
        if ((h==0) || (err == ERROR_ALREADY_EXISTS)) {
            running = true;
        }
        if (h) {
            CloseHandle(h);
        }
    }
#elif defined(__WXMAC__)
    char path[1024];
    static FILE_LOCK file_lock;
    
    sprintf(path, "%s/%s", (const char *)wxGetApp().GetDataDirectory().mb_str(), LOCK_FILE_NAME);
    if (boinc_file_exists(path)) {   // If there is no lock file, core is not running
        if (file_lock.lock(path)) {
            running = true;
        } else {
            file_lock.unlock(path);
        }
    }
#else
    PROC_MAP pm;
    int retval;

    if (m_lBOINCCoreProcessId) {
        // Prevent client from being a zombie
        if (waitpid(m_lBOINCCoreProcessId, 0, WNOHANG) == m_lBOINCCoreProcessId) {
            m_lBOINCCoreProcessId = 0;
        }
    }

    // Look for BOINC Client in list of all running processes
    retval = procinfo_setup(pm);
    if (retval) return false;     // Should never happen
    
    PROC_MAP::iterator i;
    for (i=pm.begin(); i!=pm.end(); i++) {
        PROCINFO& pi = i->second;
        if (!strcmp(pi.command, "boinc")) {
            running = true;
            break;
        }
        if (!strcmp(pi.command, "boinc_client")) {
            running = true;
            break;
        }
    }
#endif
    wxLogTrace(wxT("Function Status"), wxT("CBOINCClientManager::IsBOINCCoreRunning - Returning '%d'"), (int)running);
    wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::IsBOINCCoreRunning - Function End"));
    return running;
}
Example #22
0
void chdir_to_data_dir() {
    LONG    lReturnValue;
    HKEY    hkSetupHive;
    char    szPath[MAX_PATH];
    LPSTR   lpszValue = NULL;
    LPSTR   lpszExpandedValue = NULL;
    DWORD   dwValueType = REG_EXPAND_SZ;
    DWORD   dwSize = 0;

    // change the current directory to the boinc data directory if it exists
    lReturnValue = RegOpenKeyExA(
        HKEY_LOCAL_MACHINE, 
        "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?
        lReturnValue = RegQueryValueExA(
            hkSetupHive,
            "DATADIR",
            NULL,
            &dwValueType,
            NULL,
            &dwSize
        );
        if (lReturnValue != ERROR_FILE_NOT_FOUND) {
            // Allocate the buffer space.
            lpszValue = (LPSTR) malloc(dwSize);
            (*lpszValue) = NULL;

            // Now get the data
            lReturnValue = RegQueryValueExA( 
                hkSetupHive,
                "DATADIR",
                NULL,
                &dwValueType,
                (LPBYTE)lpszValue,
                &dwSize
            );

            // Expand the Strings
            // We need to get the size of the buffer needed
            dwSize = 0;
            lReturnValue = ExpandEnvironmentStringsA(lpszValue, NULL, dwSize);
   
            if (lReturnValue) {
                // Make the buffer big enough for the expanded string
                lpszExpandedValue = (LPSTR) malloc(lReturnValue);
                (*lpszExpandedValue) = NULL;
                dwSize = lReturnValue;
   
                ExpandEnvironmentStringsA(lpszValue, lpszExpandedValue, dwSize);

                SetCurrentDirectoryA(lpszExpandedValue);
            }
        }
    } else {
        if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_COMMON_APPDATA|CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, szPath))) {
            strncat(szPath, "\\boinc", (sizeof(szPath) - strlen(szPath)));
            if (boinc_file_exists(szPath)) {
                SetCurrentDirectoryA(szPath);
            }
        }
    }

    if (hkSetupHive) RegCloseKey(hkSetupHive);
    if (lpszValue) free(lpszValue);
    if (lpszExpandedValue) free(lpszExpandedValue);
}
Example #23
0
/// Start a task in a slot directory.
/// This includes setting up soft links,
/// passing preferences, and starting the process.
///
/// Current dir is top-level Synecdoche dir.
///
/// \post
/// - If any error occurs
///   - #task_state is #PROCESS_COULDNT_START
///   - CLIENT_STATE::report_result_error() is called
/// - else
///   - #task_state is #PROCESS_EXECUTING
///
/// \return 0 on success, nonzero otherwise.
int ACTIVE_TASK::start() {
    char exec_name[256], exec_path[256];
    unsigned int i;
    FILE_REF fref;
    int retval;
    // F*** goto, need to define some variables here instead of where they are used!
    std::ostringstream err_stream;
#ifdef _WIN32
    std::string cmd_line;
    std::string slotdirpath;
#else
    // Needs to be defined here because those gotos would skip the
    // initialization of 'cmdline' and 'argv' if it would be defined later.
    std::ostringstream cmdline;
    std::list<std::string> argv;
#endif
    if ((!full_init_done) && (log_flags.task)) {
        msg_printf(wup->project, MSG_INFO,
            "Starting %s", result->name
        );
    }
    if (log_flags.cpu_sched) {
        msg_printf(wup->project, MSG_INFO,
            "[cpu_sched] Starting %s%s", result->name, (full_init_done) ? " (resume)" : " (initial)"
        );
    }

    // Always check if all required files are present. If not, trigger
    // re-downloads and don't start the science application.
    FILE_INFO_PSET missing_file_infos;
    retval = gstate.input_files_available(result, true, &missing_file_infos);
    if (retval) {
        for (FILE_INFO_PSET::iterator it = missing_file_infos.begin(); it != missing_file_infos.end(); ++it) {
            FILE_INFO* fip = *it;
            if (fip) {
                err_stream << "Input file " << fip->name
                           << " missing or invalid: " << retval;
            } else {
                err_stream << "Input file missing or invalid";
                // We can't trigger a new download if we don't have
                // any file information. Just fail here as before.
                goto error;
            }
            fip->status = FILE_NOT_PRESENT;
        }
    }
    if (!missing_file_infos.empty()) {
        // Some files are missing and are set for re-transfer.
        // Update status and return without error.
        result->set_state(RESULT_FILES_DOWNLOADING, "start");
        set_task_state(PROCESS_UNINITIALIZED, "start");
        next_scheduler_state = PROCESS_UNINITIALIZED;
        return 0;
    }

    if (!full_init_done) {
        checkpoint_cpu_time = 0;
        checkpoint_wall_time = gstate.now;
    }
    current_cpu_time = checkpoint_cpu_time;
    episode_start_cpu_time = checkpoint_cpu_time;
    debt_interval_start_cpu_time = checkpoint_cpu_time;

    graphics_request_queue.init(result->name);        // reset message queues
    process_control_queue.init(result->name);

    if (!app_client_shm.shm) {
        retval = get_shmem_seg_name();
        if (retval) {
            err_stream << "Can't get shared memory segment name: " << boincerror(retval);
            goto error;
        }
    }

    // this must go AFTER creating shmem name,
    // since the shmem name is part of the file
    //
    retval = write_app_init_file();
    if (retval) {
        err_stream << "Can't write init file: " << retval;
        goto error;
    }

    // set up applications files
    //
    strcpy(exec_name, "");
    for (i=0; i<app_version->app_files.size(); i++) {
        fref = app_version->app_files[i];
        FILE_INFO* fip = fref.file_info;
        std::string file_path = get_pathname(fip);
        if (fref.main_program) {
            if (is_image_file(fip->name)) {
                err_stream << "Main program " << fip->name << " is an image file";
                retval = ERR_NO_SIGNATURE;
                goto error;
            }
            if (!fip->executable && !wup->project->anonymous_platform) {
                err_stream << "Main program " << fip->name << " is not executable";
                retval = ERR_NO_SIGNATURE;
                goto error;
            }
            safe_strcpy(exec_name, fip->name.c_str());
            safe_strcpy(exec_path, file_path.c_str());
        }
        // anonymous platform may use different files than
        // when the result was started, so link files even if not first time
        if ((!full_init_done) || (wup->project->anonymous_platform)) {
            retval = setup_file(result->project, fip, fref, file_path, slot_dir, true);
            if (retval) {
                err_stream << "Can't link input file";
                goto error;
            }
        }
    }
    if (!strlen(exec_name)) {
        err_stream << "No main program specified";
        retval = ERR_NOT_FOUND;
        goto error;
    }

    // set up input, output files
    if (!full_init_done) {
        for (i=0; i<wup->input_files.size(); i++) {
            fref = wup->input_files[i];
            const FILE_INFO* fip = fref.file_info;
            std::string file_path = get_pathname(fref.file_info);
            retval = setup_file(result->project, fip, fref, file_path, slot_dir, true);
            if (retval) {
                err_stream << "Can't link input file";
                goto error;
            }
        }
        for (i=0; i<result->output_files.size(); i++) {
            fref = result->output_files[i];
            if (fref.copy_file) continue;
            const FILE_INFO* fip = fref.file_info;
            std::string file_path = get_pathname(fref.file_info);
            retval = setup_file(result->project, fip, fref, file_path, slot_dir, false);
            if (retval) {
                err_stream << "Can't link output file";
                goto error;
            }
        }
        full_init_done = true;
    }

    link_user_files();

    if (gstate.exit_before_start) {
        exit(0);
    }

#ifdef _WIN32
    PROCESS_INFORMATION process_info;
    STARTUPINFO startup_info;
    LPVOID environment_block = NULL;
    char error_msg[1024];
    char error_msg2[1024];

    memset(&process_info, 0, sizeof(process_info));
    memset(&startup_info, 0, sizeof(startup_info));
    startup_info.cb = sizeof(startup_info);

    // suppress 2-sec rotating hourglass cursor on startup
    //
    startup_info.dwFlags = STARTF_FORCEOFFFEEDBACK;

    app_client_shm.reset_msgs();

    if (config.run_apps_manually) {
        // fill in core client's PID so we won't think app has exited
        pid = GetCurrentProcessId();
        pid_handle = GetCurrentProcess();
        set_task_state(PROCESS_EXECUTING, "start");
        return 0;
    }
    // NOTE: in Windows, stderr is redirected in boinc_init_diagnostics();

    cmd_line = exec_path + std::string(" ") + wup->command_line;
    if (strlen(app_version->cmdline)) {
        cmd_line += std::string(" ") + app_version->cmdline;
    }
    slotdirpath = relative_to_absolute(slot_dir);
    bool success = false;

    for (i=0; i<5; i++) {
        if (sandbox_account_service_token != NULL) {
            // Find CreateEnvironmentBlock/DestroyEnvironmentBlock pointers
            tCEB    pCEB = NULL;
            tDEB    pDEB = NULL;
            HMODULE hUserEnvLib = NULL;

            hUserEnvLib = LoadLibrary("userenv.dll");
            if (hUserEnvLib) {
                pCEB = (tCEB) GetProcAddress(hUserEnvLib, "CreateEnvironmentBlock");
                pDEB = (tDEB) GetProcAddress(hUserEnvLib, "DestroyEnvironmentBlock");
            }

            if (!pCEB(&environment_block, sandbox_account_service_token, FALSE)) {
                if (log_flags.task) {
                    windows_error_string(error_msg, sizeof(error_msg));
                    msg_printf(wup->project, MSG_INFO,
                        "Process environment block creation failed: %s", error_msg
                    );
                }
            }

            if (CreateProcessAsUser(
                sandbox_account_service_token,
                exec_path,
                (LPSTR)cmd_line.c_str(),
                NULL,
                NULL,
                FALSE,
                CREATE_NEW_PROCESS_GROUP|CREATE_NO_WINDOW|IDLE_PRIORITY_CLASS|CREATE_UNICODE_ENVIRONMENT,
                environment_block,
                slotdirpath.c_str(),
                &startup_info,
                &process_info
            )) {
                success = true;
                break;
            } else {
                windows_error_string(error_msg, sizeof(error_msg));
                msg_printf(wup->project, MSG_INTERNAL_ERROR,
                    "Process creation failed: %s", error_msg
                );
            }

            if (!pDEB(environment_block)) {
                if (log_flags.task) {
                    windows_error_string(error_msg, sizeof(error_msg2));
                    msg_printf(wup->project, MSG_INFO,
                        "Process environment block cleanup failed: %s",
                        error_msg2
                    );
                }
            }

            if (hUserEnvLib) {
                pCEB = NULL;
                pDEB = NULL;
                FreeLibrary(hUserEnvLib);
            }

        } else {
            if (CreateProcess(
                exec_path,
                (LPSTR)cmd_line.c_str(),
                NULL,
                NULL,
                FALSE,
                CREATE_NEW_PROCESS_GROUP|CREATE_NO_WINDOW|IDLE_PRIORITY_CLASS,
                NULL,
                slotdirpath.c_str(),
                &startup_info,
                &process_info
            )) {
                success = true;
                break;
            } else {
                windows_error_string(error_msg, sizeof(error_msg));
                msg_printf(wup->project, MSG_INTERNAL_ERROR,
                    "Process creation failed: %s", error_msg
                );
            }
        }
        boinc_sleep(drand());
    }

    if (!success) {
        err_stream << "CreateProcess() failed - " << error_msg;
        retval = ERR_EXEC;
        goto error;
    }
    pid = process_info.dwProcessId;
    pid_handle = process_info.hProcess;
    CloseHandle(process_info.hThread);  // thread handle is not used
#else
    // Unix/Linux/Mac case

    // Set up core/app shared memory seg if needed
    //
    if (!app_client_shm.shm) {
        if (app_version->api_major_version() >= 6) {
            // Use mmap() shared memory
            std::string buf = slot_dir + std::string("/") + std::string(MMAPPED_FILE_NAME);
            if (g_use_sandbox) {
                if (!boinc_file_exists(buf.c_str())) {
                    int fd = open(buf.c_str(), O_RDWR | O_CREAT, 0660);
                    if (fd >= 0) {
                        close (fd);
#ifdef SANDBOX
                        set_to_project_group(buf.c_str());
#endif
                    }
                }
            }
            retval = create_shmem_mmap(
                buf.c_str(), sizeof(SHARED_MEM), (void**)&app_client_shm.shm
            );
        } else {
            // Use shmget() shared memory
            retval = create_shmem(
                shmem_seg_name, sizeof(SHARED_MEM), gstate.boinc_project_gid,
                (void**)&app_client_shm.shm
            );

            if (retval) {
                needs_shmem = true;
                destroy_shmem(shmem_seg_name);
                return retval;
            }
        }
        needs_shmem = false;
    }
    app_client_shm.reset_msgs();

#if (defined (__APPLE__) && (defined(__i386__) || defined(__x86_64__)))
    // PowerPC apps emulated on i386 Macs crash if running graphics
    powerpc_emulated_on_i386 = ! is_native_i386_app(exec_path);
#endif
    if (config.run_apps_manually) {
        pid = getpid();     // use the client's PID
        set_task_state(PROCESS_EXECUTING, "start");
        return 0;
    }

    // Prepare command line for the science app:
    cmdline << wup->command_line;
    if (strlen(app_version->cmdline)) {
        cmdline << ' ' << app_version->cmdline;
    }
    argv = parse_command_line(cmdline.str().c_str());
    if (log_flags.task_debug) {
        debug_print_argv(argv);
    }

    pid = fork();
    if (pid == -1) {
        err_stream << "fork() failed: " << strerror(errno);
        retval = ERR_FORK;
        goto error;
    }
    if (pid == 0) {
        // from here on we're running in a new process.
        // If an error happens,
        // exit nonzero so that the core client knows there was a problem.

        // don't pass stdout to the app
        //
        int fd = open("/dev/null", O_RDWR);
        dup2(fd, STDOUT_FILENO);
        close(fd);

        // add to library path:
        // - the project dir (../../projects/X)
        // - the slot dir (.)
        // - the Synecdoche dir (../..)
        // We use relative paths in case higher-level dirs
        // are not readable to the account under which app runs
        //
        std::string pdir = get_project_dir(wup->project);

        std::ostringstream libpath;
        const char* env_lib_path = getenv("LD_LIBRARY_PATH");
        if (env_lib_path) {
            libpath << env_lib_path << ':';
        }
        libpath << "../../" << pdir << ":.:../..";
        setenv("LD_LIBRARY_PATH", libpath.str().c_str(), 1);

        retval = chdir(slot_dir.c_str());
        if (retval) {
            perror("chdir");
            fflush(NULL);
            _exit(errno);
        }

#if 0
        // set stack size limit to the max.
        // Some BOINC apps have reported problems with exceeding
        // small stack limits (e.g. 8 MB)
        // and it seems like the best thing to raise it as high as possible
        //
        struct rlimit rlim;
#define MIN_STACK_LIMIT 64000000
        getrlimit(RLIMIT_STACK, &rlim);
        if (rlim.rlim_cur != RLIM_INFINITY && rlim.rlim_cur <= MIN_STACK_LIMIT) {
            if (rlim.rlim_max == RLIM_INFINITY || rlim.rlim_max > MIN_STACK_LIMIT) {
                rlim.rlim_cur = MIN_STACK_LIMIT;
            } else {
                rlim.rlim_cur = rlim.rlim_max;
            }
            setrlimit(RLIMIT_STACK, &rlim);
        }
#endif

        // hook up stderr to a specially-named file
        //
        freopen(STDERR_FILE, "a", stderr);

        // set idle process priority
#ifdef HAVE_SETPRIORITY
        if (setpriority(PRIO_PROCESS, 0, PROCESS_IDLE_PRIORITY)) {
            perror("setpriority");
        }
#endif
        std::string path = std::string("../../") + std::string(exec_path);
        if (g_use_sandbox) {
            std::ostringstream switcher_path;
            switcher_path << "../../" << SWITCHER_DIR << '/' << SWITCHER_FILE_NAME;
            argv.push_front(exec_name);
            argv.push_front(path);
            argv.push_front(SWITCHER_FILE_NAME);
            // Files written by projects have user boinc_project and group boinc_project,
            // so they must be world-readable so Synecdoche can read them.
            umask(2);
            retval = do_execv(switcher_path.str(), argv);
        } else {
            argv.push_front(exec_name);
            retval = do_execv(path, argv);
        }
        msg_printf(wup->project, MSG_INTERNAL_ERROR,
            "Process creation (%s) failed: %s, errno=%d\n", path.c_str(), boincerror(retval), errno
        );
        perror("execv");
        fflush(NULL);
        _exit(errno);
    }

    if (log_flags.task_debug) {
        msg_printf(wup->project, MSG_INFO,
            "[task_debug] ACTIVE_TASK::start(): forked process: pid %d\n", pid
        );
    }

#endif
    set_task_state(PROCESS_EXECUTING, "start");
    return 0;

    // go here on error; "error_msg" contains error message, "retval" is nonzero
    //
error:
    // if something failed, it's possible that the executable was munged.
    // Verify it to trigger another download.
    //
    gstate.input_files_available(result, true);
    gstate.report_result_error(*result, "%s", err_stream.str().c_str());
    set_task_state(PROCESS_COULDNT_START, "start");
    return retval;
}
Example #24
0
DataMgmtProcType CScreensaver::DataManagementProc() {
    int             retval                      = 0;
    int             suspend_reason              = 0;
    RESULT*         theResult                   = NULL;
    RESULT*         graphics_app_result_ptr     = NULL;
    RESULT          previous_result;
    // previous_result_ptr = &previous_result when previous_result is valid, else NULL
    RESULT*         previous_result_ptr         = NULL;
    int             iResultCount                = 0;
    int             iIndex                      = 0;
    double          default_phase_start_time    = 0.0;
    double          science_phase_start_time    = 0.0;
    double          last_change_time            = 0.0;
    // If we run default screensaver during science phase because no science graphics 
    // are available, then shorten next default graphics phase by that much time.
    double          default_saver_start_time_in_science_phase    = 0.0;
    double          default_saver_duration_in_science_phase      = 0.0;

    SS_PHASE        ss_phase                    = DEFAULT_SS_PHASE;
    bool            switch_to_default_gfx       = false;
    bool            killing_default_gfx         = false;
    int             exit_status                 = 0;
    
    char*           default_ss_dir_path         = NULL;
    char            full_path[1024];

    BOINCTRACE(_T("CScreensaver::DataManagementProc - Display screen saver loading message\n"));
    SetError(TRUE, SCRAPPERR_BOINCSCREENSAVERLOADING);  // No GFX App is running: show moving BOINC logo
#ifdef _WIN32
    m_tThreadCreateTime = time(0);

    // Set the starting point for iterating through the results
    m_iLastResultShown = 0;
    m_tLastResultChangeTime = 0;
#endif

    m_bDefault_ss_exists = false;
    m_bScience_gfx_running = false;
    m_bDefault_gfx_running = false;
    m_bShow_default_ss_first = false;

#ifdef __APPLE__
    m_vIncompatibleGfxApps.clear();
    default_ss_dir_path = "/Library/Application Support/BOINC Data";
#else
    default_ss_dir_path = (char*)m_strBOINCInstallDirectory.c_str();
#endif

    strlcpy(full_path, default_ss_dir_path, sizeof(full_path));
    strlcat(full_path, PATH_SEPARATOR, sizeof(full_path));
    strlcat(full_path, THE_DEFAULT_SS_EXECUTABLE, sizeof(full_path));
        
    if (boinc_file_exists(full_path)) {
        m_bDefault_ss_exists = true;
    } else {
        SetError(TRUE, SCRAPPERR_CANTLAUNCHDEFAULTGFXAPP);  // No GFX App is running: show moving BOINC logo
    }
    
    if (m_bDefault_ss_exists && m_bShow_default_ss_first) {
        ss_phase = DEFAULT_SS_PHASE;
        default_phase_start_time = dtime();
        science_phase_start_time = 0;
        switch_to_default_gfx = true;
    } else {
        ss_phase = SCIENCE_SS_PHASE;
        default_phase_start_time = 0;
        science_phase_start_time = dtime();
    }

    while (true) {
        for (int i = 0; i < 4; i++) {
            // ***
            // *** Things that should be run frequently.
            // ***   4 times per second.
            // ***

            // Are we supposed to exit the screensaver?
            if (m_bQuitDataManagementProc) {     // If main thread has requested we exit
                BOINCTRACE(_T("CScreensaver::DataManagementProc - Thread told to stop\n"));
                if (m_hGraphicsApplication || graphics_app_result_ptr) {
                    if (m_bDefault_gfx_running) {
                        BOINCTRACE(_T("CScreensaver::DataManagementProc - Terminating default screensaver\n"));
                        terminate_default_screensaver(m_hGraphicsApplication);
                    } else {
                        BOINCTRACE(_T("CScreensaver::DataManagementProc - Terminating screensaver\n"));
                        terminate_screensaver(m_hGraphicsApplication, graphics_app_result_ptr);
                    }
                    graphics_app_result_ptr = NULL;
                    previous_result_ptr = NULL;
                    m_hGraphicsApplication = 0;
                }
                BOINCTRACE(_T("CScreensaver::DataManagementProc - Stopping...\n"));
                m_bDataManagementProcStopped = true; // Tell main thread that we exited
                return 0;                       // Exit the thread
            }
            boinc_sleep(0.25);
        }

        // ***
        // *** Things that should be run less frequently.
        // *** 1 time per second.
        // ***

        // Blank screen saver?
        if ((m_dwBlankScreen) && (time(0) > m_dwBlankTime) && (m_dwBlankTime > 0)) {
            BOINCTRACE(_T("CScreensaver::DataManagementProc - Time to blank\n"));
            SetError(FALSE, SCRAPPERR_SCREENSAVERBLANKED);    // Blanked - hide moving BOINC logo
            m_bQuitDataManagementProc = true;
            continue;       // Code above will exit the thread
        }

        BOINCTRACE(_T("CScreensaver::DataManagementProc - ErrorMode = '%d', ErrorCode = '%x'\n"), m_bErrorMode, m_hrError);

        if (!m_bConnected) {
            HandleRPCError();
        }
        
        if (m_bConnected) {
            // Do we need to get the core client state?
            if (m_bResetCoreState) {
                // Try and get the current state of the CC
                retval = rpc->get_state(state);
                if (retval) {
                    // CC may not yet be running
                    HandleRPCError();
                    continue;
                } else {
                    m_bResetCoreState = false;
                }
            }
    
            // Update our task list
            retval = rpc->get_screensaver_tasks(suspend_reason, results);
            if (retval) {
                // rpc call returned error
                HandleRPCError();
                m_bResetCoreState = true;
                continue;
            }
        } else {
            results.clear();
        }
        
        // Time to switch to default graphics phase?
        if (m_bDefault_ss_exists && (ss_phase == SCIENCE_SS_PHASE) && (m_fGFXDefaultPeriod > 0)) {
            if (science_phase_start_time && ((dtime() - science_phase_start_time) > m_fGFXSciencePeriod)) {
                if (!m_bDefault_gfx_running) {
                    switch_to_default_gfx = true;
                }
                ss_phase = DEFAULT_SS_PHASE;
                default_phase_start_time = dtime();
                science_phase_start_time = 0;
                if (m_bDefault_gfx_running && default_saver_start_time_in_science_phase) {
                    // Remember how long default graphics ran during science phase
                    default_saver_duration_in_science_phase += (dtime() - default_saver_start_time_in_science_phase); 
                }
                default_saver_start_time_in_science_phase = 0;
            }
        }
        
        // Time to switch to science graphics phase?
        if ((ss_phase == DEFAULT_SS_PHASE) && m_bConnected && (m_fGFXSciencePeriod > 0)) {
            if (default_phase_start_time && 
                    ((dtime() - default_phase_start_time + default_saver_duration_in_science_phase) 
                    > m_fGFXDefaultPeriod)) {
                // BOINCTRACE(_T("CScreensaver::Ending Default phase: now=%f, default_phase_start_time=%f, default_saver_duration_in_science_phase=%f\n"),
                // dtime(), default_phase_start_time, default_saver_duration_in_science_phase);
                ss_phase = SCIENCE_SS_PHASE;
                default_phase_start_time = 0;
                default_saver_duration_in_science_phase = 0;
                science_phase_start_time = dtime();
                if (m_bDefault_gfx_running) {
                    default_saver_start_time_in_science_phase = science_phase_start_time;
                }
                switch_to_default_gfx = false;
            }
        }

        // Core client suspended?
        // We ignore SUSPEND_REASON_CPU_USAGE in SS coordinator, so it won't kill graphics apps for
        // short-term CPU usage spikes (such as anti-virus.)  Added 9 April 2010
        if (suspend_reason && !(suspend_reason & (SUSPEND_REASON_CPU_THROTTLE | SUSPEND_REASON_CPU_USAGE))) {
            if (!m_bDefault_gfx_running) {
                SetError(TRUE, m_hrError);          // No GFX App is running: show moving BOINC logo
                if (m_bDefault_ss_exists) {
                    switch_to_default_gfx = true;
                }
            }
        }
        
        if (switch_to_default_gfx) {
            if (m_bScience_gfx_running) {
                if (m_hGraphicsApplication || previous_result_ptr) {
                    // use previous_result_ptr because graphics_app_result_ptr may no longer be valid
                    terminate_screensaver(m_hGraphicsApplication, previous_result_ptr);
                    if (m_hGraphicsApplication == 0) {
                        graphics_app_result_ptr = NULL;
                        m_bScience_gfx_running = false;
                    } else {
                        // HasProcessExited() test will clear m_hGraphicsApplication and graphics_app_result_ptr
                    }
                    previous_result_ptr = NULL;
                }
            } else {
                if (!m_bDefault_gfx_running) {
                    switch_to_default_gfx = false;
                    retval = launch_default_screensaver(default_ss_dir_path, m_hGraphicsApplication);
                    if (retval) {
                        m_hGraphicsApplication = 0;
                        previous_result_ptr = NULL;
                        graphics_app_result_ptr = NULL;
                        m_bDefault_gfx_running = false;
                        SetError(TRUE, SCRAPPERR_CANTLAUNCHDEFAULTGFXAPP);  // No GFX App is running: show moving BOINC logo
                   } else {
                        m_bDefault_gfx_running = true;
                        if (ss_phase == SCIENCE_SS_PHASE) {
                            default_saver_start_time_in_science_phase = dtime();
                        }
                        SetError(FALSE, SCRAPPERR_BOINCSCREENSAVERLOADING);    // A GFX App is running: hide moving BOINC logo
                    }
                }
            }
        }

        if ((ss_phase == SCIENCE_SS_PHASE) && !switch_to_default_gfx) {
        
#if SIMULATE_NO_GRAPHICS /* FOR TESTING */

            if (!m_bDefault_gfx_running) {
                SetError(TRUE, m_hrError);          // No GFX App is running: show moving BOINC logo
                if (m_bDefault_ss_exists) {
                    switch_to_default_gfx = true;
                }
            }

#else                   /* NORMAL OPERATION */

            if (m_bScience_gfx_running) {
                // Is the current graphics app's associated task still running?
                
                if ((m_hGraphicsApplication) || (graphics_app_result_ptr)) {
                    iResultCount = (int)results.results.size();
                    graphics_app_result_ptr = NULL;

                    // Find the current task in the new results vector (if it still exists)
                    for (iIndex = 0; iIndex < iResultCount; iIndex++) {
                        theResult = results.results.at(iIndex);

                        if (is_same_task(theResult, previous_result_ptr)) {
                            graphics_app_result_ptr = theResult;
                            previous_result = *theResult;
                            previous_result_ptr = &previous_result;
                            break;
                        }
                    }

                    // V6 graphics only: if worker application has stopped running, terminate_screensaver
                    if ((graphics_app_result_ptr == NULL) && (m_hGraphicsApplication != 0)) {
                        if (previous_result_ptr) {
                            BOINCTRACE(_T("CScreensaver::DataManagementProc - %s finished\n"), 
                                previous_result.graphics_exec_path
                            );
                        }
                        terminate_screensaver(m_hGraphicsApplication, previous_result_ptr);
                        previous_result_ptr = NULL;
                        if (m_hGraphicsApplication == 0) {
                            graphics_app_result_ptr = NULL;
                            m_bScience_gfx_running = false;
                            // Save previous_result and previous_result_ptr for get_random_graphics_app() call
                        } else {
                            // HasProcessExited() test will clear m_hGraphicsApplication and graphics_app_result_ptr
                        }
                    }

                     if (last_change_time && (m_fGFXChangePeriod > 0) && ((dtime() - last_change_time) > m_fGFXChangePeriod) ) {
                        if (count_active_graphic_apps(results, previous_result_ptr) > 0) {
                            if (previous_result_ptr) {
                                BOINCTRACE(_T("CScreensaver::DataManagementProc - time to change: %s / %s\n"), 
                                    previous_result.name, previous_result.graphics_exec_path
                                );
                            }
                            terminate_screensaver(m_hGraphicsApplication, graphics_app_result_ptr);
                            if (m_hGraphicsApplication == 0) {
                                graphics_app_result_ptr = NULL;
                                m_bScience_gfx_running = false;
                                // Save previous_result and previous_result_ptr for get_random_graphics_app() call
                            } else {
                                // HasProcessExited() test will clear m_hGraphicsApplication and graphics_app_result_ptr
                            }
                        }
                        last_change_time = dtime();
                    }
                }
            }       // End if (m_bScience_gfx_running)
        
            // If no current graphics app, pick an active task at random
            // and launch its graphics app
            //
            if ((m_bDefault_gfx_running || (m_hGraphicsApplication == 0)) && (graphics_app_result_ptr == NULL)) {
                if (suspend_reason && !(suspend_reason & (SUSPEND_REASON_CPU_THROTTLE | SUSPEND_REASON_CPU_USAGE))) {
                    graphics_app_result_ptr = NULL;
                } else {
                    graphics_app_result_ptr = get_random_graphics_app(results, previous_result_ptr);
                    previous_result_ptr = NULL;
                }
                
                if (graphics_app_result_ptr) {
                    if (m_bDefault_gfx_running) {
                        terminate_default_screensaver(m_hGraphicsApplication);
                        killing_default_gfx = true;
                        // Remember how long default graphics ran during science phase
                        if (default_saver_start_time_in_science_phase) {
                            default_saver_duration_in_science_phase += (dtime() - default_saver_start_time_in_science_phase); 
                            //BOINCTRACE(_T("CScreensaver::During Science phase: now=%f, default_saver_start_time=%f, default_saver_duration=%f\n"),
                            //    dtime(), default_saver_start_time_in_science_phase, default_saver_duration_in_science_phase);
                        }
                        default_saver_start_time_in_science_phase = 0;
                        // HasProcessExited() test will clear
                        // m_hGraphicsApplication and graphics_app_result_ptr
                     } else {
                        retval = launch_screensaver(graphics_app_result_ptr, m_hGraphicsApplication);
                        if (retval) {
                            m_hGraphicsApplication = 0;
                            previous_result_ptr = NULL;
                            graphics_app_result_ptr = NULL;
                            m_bScience_gfx_running = false;
                        } else {
                            // A GFX App is running: hide moving BOINC logo
                            //
                            SetError(FALSE, SCRAPPERR_BOINCSCREENSAVERLOADING);
                            last_change_time = dtime();
                            m_bScience_gfx_running = true;
                            // Make a local copy of current result, since original pointer 
                            // may have been freed by the time we perform later tests
                            previous_result = *graphics_app_result_ptr;
                            previous_result_ptr = &previous_result;
                            if (previous_result_ptr) {
                                BOINCTRACE(_T("CScreensaver::DataManagementProc - launching %s\n"), 
                                    previous_result.graphics_exec_path
                                );
                            }
                        }
                    }
                } else {
                    if (!m_bDefault_gfx_running) {
                        // We can't run a science graphics app, so run the default graphics if available
                        SetError(TRUE, m_hrError); 
                        if (m_bDefault_ss_exists) {
                            switch_to_default_gfx = true;
                        }
                    }

                }   // End if no science graphics available
            }      // End if no current science graphics app is running

#endif      // ! SIMULATE_NO_GRAPHICS

            if (switch_to_default_gfx) {
                switch_to_default_gfx = false;
                if (!m_bDefault_gfx_running) {
                    retval = launch_default_screensaver(default_ss_dir_path, m_hGraphicsApplication);
                    if (retval) {
                        m_hGraphicsApplication = 0;
                        previous_result_ptr = NULL;
                        graphics_app_result_ptr = NULL;
                        m_bDefault_gfx_running = false;
                        SetError(TRUE, SCRAPPERR_CANTLAUNCHDEFAULTGFXAPP);
                        // No GFX App is running: show BOINC logo
                    } else {
                        m_bDefault_gfx_running = true;
                        default_saver_start_time_in_science_phase = dtime();
                        SetError(FALSE, SCRAPPERR_BOINCSCREENSAVERLOADING);
                        // Default GFX App is running: hide moving BOINC logo
                    }
                }
            }
        }   // End if ((ss_phase == SCIENCE_SS_PHASE) && !switch_to_default_gfx)
        
        
        
        // Is the graphics app still running?
        if (m_hGraphicsApplication) {
            if (HasProcessExited(m_hGraphicsApplication, exit_status)) {
                // Something has happened to the previously selected screensaver
                //   application. Start a different one.
                BOINCTRACE(_T("CScreensaver::DataManagementProc - Graphics application isn't running, start a new one.\n"));
                if (m_bDefault_gfx_running) {
                    // If we were able to connect to core client
                    // but gfx app can't, don't use it. 
                    //
                    BOINCTRACE(_T("CScreensaver::DataManagementProc - Default graphics application exited with code %d.\n"), exit_status);
                    if (!killing_default_gfx) {     // If this is an unexpected exit
                        if (exit_status == DEFAULT_GFX_CANT_CONNECT) {
                            SetError(TRUE, SCRAPPERR_DEFAULTGFXAPPCANTCONNECT);
                            // No GFX App is running: show moving BOINC logo
                        } else {
                            SetError(TRUE, SCRAPPERR_DEFAULTGFXAPPCRASHED);
                            // No GFX App is running: show moving BOINC logo
                        }
                        m_bDefault_ss_exists = false;
                        ss_phase = SCIENCE_SS_PHASE;
                    }
                    killing_default_gfx = false;
                }
                SetError(TRUE, SCRAPPERR_BOINCNOGRAPHICSAPPSEXECUTING);
                // No GFX App is running: show moving BOINC logo
                m_hGraphicsApplication = 0;
                graphics_app_result_ptr = NULL;
                m_bDefault_gfx_running = false;
                m_bScience_gfx_running = false;
#ifdef __APPLE__
                launchedGfxApp("", 0, -1);
#endif
                continue;
            }
        }
    }   // end while(true)
}
Example #25
0
OSStatus CScreensaver::initBOINCApp() {
    char boincPath[2048];
    pid_t myPid;
    int status;
    OSStatus err;
    long brandId = 0;

    saverState = SaverState_CantLaunchCoreClient;
    
    brandId = GetBrandID();
    switch(brandId) {
    case 1:
        m_BrandText = "GridRepublic Desktop";
         break;
    case 2:
        m_BrandText = "Progress Thru Processors Desktop";
         break;
    case 3:
        m_BrandText = "Charity Engine Desktop";
         break;
    default:
        m_BrandText = "BOINC";
        break;
    }

    m_CoreClientPID = FindProcessPID("boinc", 0);
    if (m_CoreClientPID) {
        m_wasAlreadyRunning = true;
        saverState = SaverState_LaunchingCoreClient;
        retryCount = 0;
        return noErr;
    }
    
    m_wasAlreadyRunning = false;
    
    if (++retryCount > 3)   // Limit to 3 relaunches to prevent thrashing
        return -1;

    // Find boinc client within BOINCManager.app
    // First, try default path
    strcpy(boincPath, "/Applications/");
    if (brandId) {
        strcat(boincPath, m_BrandText);
    } else {
        strcat(boincPath, "BOINCManager");
    }
    strcat(boincPath, ".app/Contents/Resources/boinc");

    // If not at default path, search for it by creator code and bundle identifier
    if (!boinc_file_exists(boincPath)) {
        err = GetpathToBOINCManagerApp(boincPath, sizeof(boincPath));
        if (err) {
            saverState = SaverState_CantLaunchCoreClient;
            return err;
        } else {
            strcat(boincPath, "/Contents/Resources/boinc");
        }
    }

    if ( (myPid = fork()) < 0)
        return -1;
    else if (myPid == 0)			// child
    {
      // We don't customize BOINC Data directory name for branding
#if 0   // Code for separate data in each user's private directory
        char buf[256];
        safe_strcpy(buf, getenv("HOME"));
        safe_strcat(buf, "/Library/Application Support/BOINC Data");
        status = chdir(buf);
#else   // All users share the same data
        status = chdir("/Library/Application Support/BOINC Data");
#endif
        if (status) {
            perror("chdir");
            fflush(NULL);
            _exit(status);
        }

        status = execl(boincPath, boincPath, "-redirectio", "-saver", (char *) 0);
        fflush(NULL);
        _exit(127);         // execl error (execl should never return)
    } else {
        m_CoreClientPID = myPid;		// make this available globally
        saverState = SaverState_LaunchingCoreClient;
    }

    return noErr;
}
Example #26
0
int main(int argc, char *argv[]) {
    int retval;
    R_RSA_PUBLIC_KEY key;
    char log_path[MAXPATHLEN];
#ifdef _USING_FCGI_
    unsigned int counter=0;
#endif

    for(int c = 1; c < argc; c++) {
        std::string option(argv[c]);
        if(option == "-v" || option == "--version") {
            printf("%s\n", SVN_VERSION);
            exit(0);
        } else if(option == "-h" || option == "--help") {
            usage(argv[0]);
            exit(0);
        } else if (option.length()){
            fprintf(stderr, "unknown command line argument: %s\n\n", argv[c]);
            usage(argv[0]);
            exit(1);
        }
    }

    installer();

    get_log_path(log_path, "file_upload_handler.log");
#ifndef _USING_FCGI_
    if (!freopen(log_path, "a", stderr)) {
        fprintf(stderr, "Can't open log file '%s' (errno: %d)\n",
            log_path, errno
        );
        return_error(ERR_TRANSIENT, "can't open log file '%s' (errno: %d)",
            log_path, errno
        );
        exit(1);
    }
#else
    FCGI_FILE *f = FCGI::fopen(log_path, "a");
    if (f) {
       log_messages.redirect(f);
    } else {
        fprintf(stderr, "Can't redirect FCGI log messages\n");
        return_error(ERR_TRANSIENT, "can't open log file (FCGI)");
        exit(1);
    }
#endif

    retval = config.parse_file();
    if (retval) {
        fprintf(stderr, "Can't parse config.xml: %s\n", boincerror(retval));
        return_error(ERR_TRANSIENT,
            "can't parse config file", log_path, errno
        );
        exit(1);
    }

    log_messages.pid = getpid();
    log_messages.set_debug_level(config.fuh_debug_level);

    if (boinc_file_exists(config.project_path("stop_upload"))) {
        return_error(ERR_TRANSIENT, "Maintenance underway: file uploads are temporarily disabled.");
        exit(1);
    }

    if (!config.ignore_upload_certificates) {
        retval = get_key(key);
        if (retval) {
            return_error(ERR_TRANSIENT, "can't read key file");
            exit(1);
        }
    }

#ifdef _USING_FCGI_
    while(FCGI_Accept() >= 0) {
        counter++;
        //fprintf(stderr, "file_upload_handler (FCGI): counter: %d\n", counter);
        log_messages.set_indent_level(0);
#endif
        handle_request(stdin, key);
#ifdef _USING_FCGI_
        // flush log for FCGI, otherwise it just buffers a lot
        log_messages.flush();
    }
    // when exiting, write headers back to apache so it won't complain
    // about "incomplete headers"
    fprintf(stdout,"Content-type: text/plain\n\n");
#endif
    return 0;
}
Example #27
0
// Write the client_state.xml file
//
int CLIENT_STATE::write_state_file() {
    MFILE mf;
    int retval, ret1, ret2, attempt;
#ifdef _WIN32
    char win_error_msg[4096];
#endif

    for (attempt=1; attempt<=MAX_STATE_FILE_WRITE_ATTEMPTS; attempt++) {
        if (attempt > 1) boinc_sleep(1.0);
            
        if (log_flags.statefile_debug) {
            msg_printf(0, MSG_INFO,
                "[statefile] Writing state file"
            );
        }
#ifdef _WIN32
        retval = mf.open(STATE_FILE_NEXT, "wc");
#else
        retval = mf.open(STATE_FILE_NEXT, "w");
#endif
        if (retval) {
            if ((attempt == MAX_STATE_FILE_WRITE_ATTEMPTS) || log_flags.statefile_debug) {
                msg_printf(0, MSG_INTERNAL_ERROR,
                    "Can't open %s: %s",
                    STATE_FILE_NEXT, boincerror(retval)
                );
            }
            if (attempt < MAX_STATE_FILE_WRITE_ATTEMPTS) continue;
            return ERR_FOPEN;
        }
        MIOFILE miof;
        miof.init_mfile(&mf);
        ret1 = write_state(miof);
        ret2 = mf.close();
        if (ret1) {
            if ((attempt == MAX_STATE_FILE_WRITE_ATTEMPTS) || log_flags.statefile_debug) {
                msg_printf(NULL, MSG_INTERNAL_ERROR,
                    "Couldn't write state file: %s", boincerror(retval)
                );
            }
            if (attempt < MAX_STATE_FILE_WRITE_ATTEMPTS) continue;
            return ret1;
        }
        if (ret2) {
            if (attempt < MAX_STATE_FILE_WRITE_ATTEMPTS) continue;
            return ret2;
        }

        // only attempt to rename the current state file if it exists.
        //
        if (boinc_file_exists(STATE_FILE_NAME)) {
            if (boinc_file_exists(STATE_FILE_PREV)) {
                retval = boinc_delete_file(STATE_FILE_PREV);
                if (retval) {
                    if ((attempt == MAX_STATE_FILE_WRITE_ATTEMPTS) || log_flags.statefile_debug) {
#ifdef _WIN32
                        msg_printf(0, MSG_INFO,
                            "Can't delete previous state file; %s",
                            windows_format_error_string(GetLastError(), win_error_msg, sizeof(win_error_msg))
                        );
#else
                        msg_printf(0, MSG_INFO,
                            "Can't delete previous state file: %s",
                            strerror(errno)
                        );
#endif
                    }
                    if (attempt < MAX_STATE_FILE_WRITE_ATTEMPTS) continue;
                }
            }
            
            retval = boinc_rename(STATE_FILE_NAME, STATE_FILE_PREV);
            if (retval) {
                if ((attempt == MAX_STATE_FILE_WRITE_ATTEMPTS) || log_flags.statefile_debug) {
#ifdef _WIN32
                    msg_printf(0, MSG_INFO,
                        "Can't rename current state file to previous state file; %s",
                        windows_format_error_string(GetLastError(), win_error_msg, sizeof(win_error_msg))
                    );
#else
                    msg_printf(0, MSG_INFO, 
                        "Can't rename current state file to previous state file: %s", 
                        strerror(errno)
                    );
#endif
                }
                if (attempt < MAX_STATE_FILE_WRITE_ATTEMPTS) continue;
            }
        }

        retval = boinc_rename(STATE_FILE_NEXT, STATE_FILE_NAME);
        if (log_flags.statefile_debug) {
            msg_printf(0, MSG_INFO,
                "[statefile] Done writing state file"
            );
        }
        if (!retval) break;     // Success!
        
        if ((attempt == MAX_STATE_FILE_WRITE_ATTEMPTS) || log_flags.statefile_debug) {
#ifdef _WIN32
            msg_printf(0, MSG_INFO,
                "rename error: %s",
                windows_format_error_string(GetLastError(), win_error_msg, sizeof(win_error_msg))
            );
#elif defined (__APPLE__)
            if (log_flags.statefile_debug) {
                system("ls -al /Library/Application\\ Support/BOINC\\ Data/client*.*");
            }
#endif
        }
        if (attempt < MAX_STATE_FILE_WRITE_ATTEMPTS) continue;
        return ERR_RENAME;
    }
    return 0;
}
Example #28
0
// parse a project's app_info.xml (anonymous platform) file
//
int CLIENT_STATE::parse_app_info(PROJECT* p, FILE* in) {
    char buf[256], path[MAXPATHLEN];
    MIOFILE mf;
    mf.init_file(in);
    XML_PARSER xp(&mf);

    while (!xp.get_tag()) {
        if (xp.match_tag("app_info")) continue;
        if (xp.match_tag("/app_info")) {
            notices.remove_notices(p, REMOVE_APP_INFO_MSG);
            return 0;
        }
        if (xp.match_tag("file_info") || xp.match_tag("file")) {
            FILE_INFO* fip = new FILE_INFO;
            if (fip->parse(xp)) {
                delete fip;
                continue;
            }
            if (!fip->download_urls.empty() || !fip->upload_urls.empty()) {
                msg_printf(p, MSG_INFO,
                    "Can't specify URLs in app_info.xml"
                );
                delete fip;
                continue;
            }
            if (link_file_info(p, fip)) {
                delete fip;
                continue;
            }
            // check that the file is actually there
            //
            get_pathname(fip, path, sizeof(path));
            if (!boinc_file_exists(path)) {
                safe_strcpy(buf,
                    _("File referenced in app_info.xml does not exist: ")
                );
                strcat(buf, fip->name);
                msg_printf(p, MSG_USER_ALERT, "%s", buf);
                delete fip;
                continue;
            }
            fip->status = FILE_PRESENT;
            fip->anonymous_platform_file = true;
            file_infos.push_back(fip);
            continue;
        }
        if (xp.match_tag("app")) {
            APP* app = new APP;
            if (app->parse(xp)) {
                delete app;
                continue;
            }
            if (lookup_app(p, app->name)) {
                delete app;
                continue;
            }
            link_app(p, app);
            apps.push_back(app);
            continue;
        }
        if (xp.match_tag("app_version")) {
            APP_VERSION* avp = new APP_VERSION;
            if (avp->parse(xp)) {
                delete avp;
                continue;
            }
            if (cc_config.dont_use_vbox && strstr(avp->plan_class, "vbox")) {
                msg_printf(p, MSG_INFO,
                    "skipping vbox app in app_info.xml; vbox disabled in cc_config.xml"
                );
                delete avp;
                continue;
            }
            if (strlen(avp->platform) == 0) {
                safe_strcpy(avp->platform, get_primary_platform());
            }
            if (link_app_version(p, avp)) {
                delete avp;
                continue;
            }
            app_versions.push_back(avp);
            continue;
        }
        if (log_flags.unparsed_xml) {
            msg_printf(p, MSG_INFO,
                "Unparsed line in app_info.xml: %s",
                xp.parsed_tag
            );
        }
    }
    return ERR_XML_PARSE;
}
// returns true if the work generator can not make more work for this
// file, false if it can.
//
static bool work_generation_over(char *filename) {
    return boinc_file_exists(config.project_path("locality_scheduling/no_work_available/%s", filename));
}