Beispiel #1
0
int callPosixSpawn(const char *cmdline) {
    char command[1024];
    char progName[1024];
    char progPath[MAXPATHLEN];
    char* argv[100];
    int argc = 0;
    char *p;
    pid_t thePid = 0;
    int result = 0;
    int status = 0;
    extern char **environ;

    // Make a copy of cmdline because parse_posix_spawn_command_line modifies it
    strlcpy(command, cmdline, sizeof(command));
    argc = parse_posic_spawn_command_line(const_cast<char*>(command), argv);
    strlcpy(progPath, argv[0], sizeof(progPath));
    strlcpy(progName, argv[0], sizeof(progName));
    p = strrchr(progName, '/');
    if (p) {
        argv[0] = p+1;
    } else {
        argv[0] = progName;
    }
    
#if VERBOSE_TEST
    print_to_log_file("***********");
    for (int i=0; i<argc; ++i) {
        print_to_log_file("argv[%d]=%s", i, argv[i]);
    }
    print_to_log_file("***********\n");
#endif

    errno = 0;

    result = posix_spawnp(&thePid, progPath, NULL, NULL, argv, environ);
#if VERBOSE_TEST
    print_to_log_file("callPosixSpawn command: %s", cmdline);
    print_to_log_file("callPosixSpawn: posix_spawnp returned %d: %s", result, strerror(result));
#endif
    if (result) {
        return result;
    }
// CAF    int val =
    waitpid(thePid, &status, WUNTRACED);
// CAF        if (val < 0) printf("first waitpid returned %d\n", val);
    if (status != 0) {
#if VERBOSE_TEST
        print_to_log_file("waitpid() returned status=%d", status);
#endif
        result = status;
    } else {
        if (WIFEXITED(status)) {
            result = WEXITSTATUS(status);
            if (result == 1) {
#if VERBOSE_TEST
                print_to_log_file("WEXITSTATUS(status) returned 1, errno=%d: %s", errno, strerror(errno));
#endif
                result = errno;
            }
#if VERBOSE_TEST
            else if (result) {
                print_to_log_file("WEXITSTATUS(status) returned %d", result);
            }
#endif
        }   // end if (WIFEXITED(status)) else
    }       // end if waitpid returned 0 sstaus else
    
    return result;
}
Beispiel #2
0
int main(int argc, char** argv) {
    passwd      *pw;
    group       *grp;
    char        user_name[256], group_name[256];
    char	gfx_app_path[MAXPATHLEN], resolved_path[MAXPATHLEN];
    char        *BOINCDatSlotsPath = "/Library/Application Support/BOINC Data/slots/";
    int         retval;
    int         pid;

    if (argc < 2) return EINVAL;

    strlcpy(user_name, "boinc_project", sizeof(user_name));
    strlcpy(group_name, user_name, sizeof(group_name));

#if 0       // For debugging only
    // Allow debugging without running as user or group boinc_project
    pw = getpwuid(getuid());
    if (pw) strlcpy(user_name, pw->pw_name, sizeof(user_name));
    grp = getgrgid(getgid());
    if (grp) strlcpy(group_name, grp->gr_gid, sizeof(group_name));

#endif

    // We are running setuid root, so setgid() sets real group ID, 
    // effective group ID and saved set_group-ID for this process
    grp = getgrnam(group_name);
    if (grp) setgid(grp->gr_gid);

    // We are running setuid root, so setuid() sets real user ID, 
    // effective user ID and saved set_user-ID for this process
    pw = getpwnam(user_name);
    if (pw) setuid(pw->pw_uid);

    // NOTE: call print_to_log_file only after switching user and group
#if 0           // For debugging only
    char	current_dir[MAXPATHLEN];

    getcwd( current_dir, sizeof(current_dir));
    print_to_log_file( "current directory = %s", current_dir);
    
    for (int i=0; i<argc; i++) {
         print_to_log_file("switcher arg %d: %s", i, argv[i]);
    }
#endif

    if (strcmp(argv[1], "-default_gfx") == 0) {
        strlcpy(resolved_path, "/Library/Application Support/BOINC Data/boincscr", sizeof(resolved_path));
        argv[2] = resolved_path;
        
#if 0           // For debugging only
    for (int i=2; i<argc; i++) {
         print_to_log_file("calling execv with arg %d: %s", i-2, argv[i]);
    }
#endif

        // For unknown reasons, the graphics application exits with 
        // "RegisterProcess failed (error = -50)" unless we pass its 
        // full path twice in the argument list to execv.
        execv(resolved_path, argv+2);
        // If we got here execv failed
        fprintf(stderr, "Process creation (%s) failed: errno=%d\n", resolved_path, errno);
        return errno;
    }
    
    if (strcmp(argv[1], "-launch_gfx") == 0) {
        strlcpy(gfx_app_path, BOINCDatSlotsPath, sizeof(gfx_app_path));
        strlcat(gfx_app_path, argv[2], sizeof(gfx_app_path));
        strlcat(gfx_app_path, "/", sizeof(gfx_app_path));
        strlcat(gfx_app_path, GRAPHICS_APP_FILENAME, sizeof(gfx_app_path));
        retval = boinc_resolve_filename(gfx_app_path, resolved_path, sizeof(resolved_path));
        if (retval) return retval;
        
        argv[2] = resolved_path;
        
#if 0           // For debugging only
    for (int i=2; i<argc; i++) {
         print_to_log_file("calling execv with arg %d: %s", i-2, argv[i]);
    }
#endif

        // For unknown reasons, the graphics application exits with 
        // "RegisterProcess failed (error = -50)" unless we pass its 
        // full path twice in the argument list to execv.
        execv(resolved_path, argv+2);
        // If we got here execv failed
        fprintf(stderr, "Process creation (%s) failed: errno=%d\n", resolved_path, errno);
        return errno;
    }

    if (strcmp(argv[1], "-kill_gfx") == 0) {
        pid = atoi(argv[2]);
        if (! pid) return EINVAL;
        if ( kill(pid, SIGKILL)) {
#if 0           // For debugging only
     print_to_log_file("kill(%d, SIGKILL) returned error %d", pid, errno);
#endif
            return errno;
        }
        return 0;
    }
    
    return EINVAL;  // Unknown command
}
Beispiel #3
0
// Because language preferences are set on a per-user basis, we
// must get the preferred languages while set to the current 
// user, before the Apple Installer switches us to root.
// So we get the preferred languages here and write them to a
// temporary file to be retrieved by our PostInstall app.
static void GetPreferredLanguages() {
    DIR *dirp;
    struct dirent *dp;
    char temp[MAXPATHLEN];
    char searchPath[MAXPATHLEN];
    char savedWD[MAXPATHLEN];
    struct stat sbuf;
    CFMutableArrayRef supportedLanguages;
    CFStringRef aLanguage;
    char shortLanguage[32];
    CFArrayRef preferredLanguages;
    int i, j, k;
    char * language;
    char *uscore;
    FILE *f;

    getcwd(savedWD, sizeof(savedWD));
    snprintf(temp, sizeof(temp), "rm -dfR /tmp/%s/BOINC_payload", tempDirName);
    callPosixSpawn(temp);
    snprintf(temp, sizeof(temp), "/tmp/%s/BOINC_payload", tempDirName);
    mkdir(temp, 0777);
    chmod(temp, 0777);  // Needed because mkdir sets permissions restricted by umask (022)
    chdir(temp);
    snprintf(temp, sizeof(temp), "cpio -i -I /tmp/%s/expanded_BOINC.pkg/BOINC.pkg/Payload", tempDirName);
    callPosixSpawn(temp);
    chdir(savedWD);

    // Create an array of all our supported languages
    supportedLanguages = CFArrayCreateMutable(kCFAllocatorDefault, 100, &kCFTypeArrayCallBacks);
    
    aLanguage = CFStringCreateWithCString(NULL, "en", kCFStringEncodingMacRoman);
    CFArrayAppendValue(supportedLanguages, aLanguage);
    CFRelease(aLanguage);
    aLanguage = NULL;

    dirp = opendir(Catalogs_Dir);
    if (!dirp) {
        REPORT_ERROR(true);
        goto cleanup;
    }
    while (true) {
        dp = readdir(dirp);
        if (dp == NULL)
            break;                  // End of list

        if (dp->d_name[0] == '.')
            continue;               // Ignore names beginning with '.'

        strlcpy(searchPath, Catalogs_Dir, sizeof(searchPath));
        strlcat(searchPath, dp->d_name, sizeof(searchPath));
        strlcat(searchPath, "/", sizeof(searchPath));
        strlcat(searchPath, Catalog_Name, sizeof(searchPath));
        strlcat(searchPath, ".mo", sizeof(searchPath));
        if (stat(searchPath, &sbuf) != 0) continue;
//        printf("Adding %s to supportedLanguages array\n", dp->d_name);
        aLanguage = CFStringCreateWithCString(NULL, dp->d_name, kCFStringEncodingMacRoman);
        CFArrayAppendValue(supportedLanguages, aLanguage);
        CFRelease(aLanguage);
        aLanguage = NULL;
        
        // If it has a region code ("it_IT") also try without region code ("it")
        // TODO: Find a more general solution
        strlcpy(shortLanguage, dp->d_name, sizeof(shortLanguage));
        uscore = strchr(shortLanguage, '_');
        if (uscore) {
            *uscore = '\0';
            aLanguage = CFStringCreateWithCString(NULL, shortLanguage, kCFStringEncodingMacRoman);
            CFArrayAppendValue(supportedLanguages, aLanguage);
            CFRelease(aLanguage);
            aLanguage = NULL;
        }
    }
    
    closedir(dirp);

    // Write a temp file to tell our PostInstall.app our preferred languages
    snprintf(temp, sizeof(temp), "/tmp/%s/BOINC_preferred_languages", tempDirName);
    f = fopen(temp, "w");
    if (!f) {
        REPORT_ERROR(true);
        goto cleanup;
    }

    for (i=0; i<MAX_LANGUAGES_TO_TRY; ++i) {
    
        preferredLanguages = CFBundleCopyLocalizationsForPreferences(supportedLanguages, NULL );
        
#if 0   // For testing
        int c = CFArrayGetCount(preferredLanguages);
        for (k=0; k<c; ++k) {
        CFStringRef s = (CFStringRef)CFArrayGetValueAtIndex(preferredLanguages, k);
            printf("Preferred language %u is %s\n", k, CFStringGetCStringPtr(s, kCFStringEncodingMacRoman));
        }

#endif

        for (j=0; j<CFArrayGetCount(preferredLanguages); ++j) {
            aLanguage = (CFStringRef)CFArrayGetValueAtIndex(preferredLanguages, j);
            language = (char *)CFStringGetCStringPtr(aLanguage, kCFStringEncodingMacRoman);
            if (language == NULL) {
                if (CFStringGetCString(aLanguage, shortLanguage, sizeof(shortLanguage), kCFStringEncodingMacRoman)) {
                    language = shortLanguage;
                }
            }
            if (f && language) {
                fprintf(f, "%s\n", language);
#if CREATE_LOG
                print_to_log_file("Adding language: %s\n", language);
#endif
            }
            // Remove all copies of this language from our list of supported languages
            // so we can get the next preferred language in order of priority
            for (k=CFArrayGetCount(supportedLanguages)-1; k>=0; --k) {
                if (CFStringCompare(aLanguage, (CFStringRef)CFArrayGetValueAtIndex(supportedLanguages, k), 0) == kCFCompareEqualTo) {
                    CFArrayRemoveValueAtIndex(supportedLanguages, k);
                }
            }

            // Since the original strings are English, no 
            // further translation is needed for language en.
            if (language) {
                if (!strcmp(language, "en")) {
                    fclose(f);
                    CFRelease(preferredLanguages);
                    preferredLanguages = NULL;
                    goto cleanup;
                }
            }
        }
        
        CFRelease(preferredLanguages);
        preferredLanguages = NULL;

    }

    if (f) {
        fprintf(f, "en\n");
        fclose(f);
    }

cleanup:
    CFArrayRemoveAllValues(supportedLanguages);
    CFRelease(supportedLanguages);
    supportedLanguages = NULL;
#if CREATE_LOG
    print_to_log_file("Exiting GetPreferredLanguages");
#endif
}