コード例 #1
0
ファイル: Installer.cpp プロジェクト: UweBeckert/boinc
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;
}
コード例 #2
0
ファイル: Installer.cpp プロジェクト: justinlynn/boinc-v2
int main(int argc, char *argv[])
{
    char                    pkgPath[MAXPATHLEN];
    char                    temp[MAXPATHLEN];
    char                    brand[64], s[256];
    char                    *p;
    ProcessSerialNumber     ourPSN;
    FSRef                   ourFSRef;
    OSStatus                err = noErr;
    Boolean                 restartNeeded = true;
    FILE                    *restartNeededFile;

    Initialize();

    // Get the full path to Installer package inside this application's bundle
    err = GetCurrentProcess (&ourPSN);
    if (err == noErr)
        err = GetProcessBundleLocation(&ourPSN, &ourFSRef);

    if (err == noErr)
        err = FSRefMakePath (&ourFSRef, (UInt8*)pkgPath, sizeof(pkgPath));

    strlcpy(temp, pkgPath, sizeof(temp));

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

   // To allow for branding, assume name of installer package inside bundle corresponds to name of this application
    p = strrchr(temp, '/');         // Point to name of this application (e.g., "BOINC Installer.app")
    if (p == NULL)
        p = temp - 1;
    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 = strstr(brand, " Installer.app");  // Strip off trailing " Installer.app"
    if (p)
        *p = '\0'; 
    
    strlcat(pkgPath, ".pkg", sizeof(pkgPath));
    // Expand the installer package
    system("rm -dfR /tmp/BOINC.pkg");
    system("rm -dfR /tmp/expanded_BOINC.pkg");
    sprintf(temp, "pkgutil --expand \"%s\" /tmp/expanded_BOINC.pkg", pkgPath);
    err = system(temp);

    if (err == noErr) {
        GetPreferredLanguages();
    }
    if (compareOSVersionTo(10, 5) < 0) {
        LoadPreferredLanguages();
        ::SetFrontProcess(&ourPSN);
        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.5 or higher."), brand);

        system("rm -dfR /tmp/BOINC_payload");
        return -1;
    }

    system("rm -dfR /tmp/BOINC_payload");

    // 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);
    system (s);

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

        if (err == noErr) {
            sprintf(temp, "open \"/tmp/%s.pkg\" &", brand);
            system(temp);
            return 0;
        }
    }

    sprintf(temp, "open \"%s\" &", pkgPath);
    system(temp);
    
    return err;
}