mirror of https://github.com/BOINC/boinc.git
Mac: make uninstaller work even if user deleted BOINC Data directory
This commit is contained in:
parent
64d6df402e
commit
ae5e68b2d7
|
@ -1,6 +1,6 @@
|
|||
// This file is part of BOINC.
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2022 University of California
|
||||
// Copyright (C) 2023 University of California
|
||||
//
|
||||
// BOINC is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License
|
||||
|
@ -202,7 +202,6 @@ int main(int argc, char *argv[])
|
|||
OSStatus err;
|
||||
FILE *f;
|
||||
char s[2048];
|
||||
char path[MAXPATHLEN];
|
||||
|
||||
#ifndef SANDBOX
|
||||
group *grp;
|
||||
|
@ -298,10 +297,13 @@ int main(int argc, char *argv[])
|
|||
err = callPosixSpawn (s);
|
||||
REPORT_ERROR(err);
|
||||
|
||||
// We don't customize BOINC Data directory name for branding
|
||||
err = callPosixSpawn ("rm -rf \"/Library/Application Support/BOINC Data\"");
|
||||
REPORT_ERROR(err);
|
||||
|
||||
// Don't remove BOINC Data directory if previously present
|
||||
if (!boinc_file_exists("/Library/Application Support/BOINC Data/stdoutdae.txt")){
|
||||
// We don't customize BOINC Data directory name for branding
|
||||
err = callPosixSpawn ("rm -rf \"/Library/Application Support/BOINC Data\"");
|
||||
REPORT_ERROR(err);
|
||||
}
|
||||
|
||||
err = kill(installerPID, SIGKILL);
|
||||
|
||||
return 0;
|
||||
|
@ -472,28 +474,6 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
}
|
||||
|
||||
if (compareOSVersionTo(10, 13) >= 0) {
|
||||
getPathToThisApp(path, sizeof(path));
|
||||
strncat(path, "/Contents/Resources/boinc_Finish_Install", sizeof(path)-1);
|
||||
snprintf(s, sizeof(s), "cp -f \"%s\" \"/Library/Application Support/BOINC Data/%s_Finish_Install\"", path, appName[brandID]);
|
||||
err = callPosixSpawn(s);
|
||||
REPORT_ERROR(err);
|
||||
if (err) {
|
||||
printf("Command %s returned error %d\n", s, err);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
snprintf(s, sizeof(s), "/Library/Application Support/BOINC Data/%s_Finish_Install\"</string>\n", appName[brandID]);
|
||||
chmod(s, 0755);
|
||||
#ifdef SANDBOX
|
||||
group *bmgrp = getgrnam(boinc_master_group_name);
|
||||
passwd *bmpw = getpwnam(boinc_master_user_name);
|
||||
if (bmgrp && bmpw) {
|
||||
chown(s, bmpw->pw_uid, bmgrp->gr_gid);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
err = UpdateAllVisibleUsers(brandID, oldBrandID);
|
||||
if (err != noErr) {
|
||||
REPORT_ERROR(true);
|
||||
|
@ -1129,7 +1109,7 @@ Boolean SetLoginItemLaunchAgent(long brandID, long oldBrandID, Boolean deleteLog
|
|||
fprintf(f, "\t<string>edu.berkeley.fix_login_items</string>\n");
|
||||
fprintf(f, "\t<key>ProgramArguments</key>\n");
|
||||
fprintf(f, "\t<array>\n");
|
||||
fprintf(f, "\t\t<string>/Library/Application Support/BOINC Data/%s_Finish_Install</string>\n", appName[brandID]);
|
||||
fprintf(f, "\t\t<string>/Users/%s/Library/Application Support/BOINC/%s_Finish_Install</string>\n", pw->pw_name, appName[brandID]);
|
||||
if (deleteLogInItem || (brandID != oldBrandID)) {
|
||||
// If this user was previously authorized to run the Manager, there
|
||||
// may still be a Login Item for this user, and the Login Item may
|
||||
|
@ -1138,11 +1118,10 @@ Boolean SetLoginItemLaunchAgent(long brandID, long oldBrandID, Boolean deleteLog
|
|||
// (for this user only) if it is running.
|
||||
//
|
||||
fprintf(f, "\t\t<string>-d</string>\n");
|
||||
fprintf(f, "\t\t<string>%s</string>\n", appName[oldBrandID]);
|
||||
}
|
||||
if (!deleteLogInItem) {
|
||||
fprintf(f, "\t\t<string>%d</string>\n", (int)oldBrandID);
|
||||
} else {
|
||||
fprintf(f, "\t\t<string>-a</string>\n");
|
||||
fprintf(f, "\t\t<string>%s</string>\n", appName[brandID]);
|
||||
fprintf(f, "\t\t<string>%d</string>\n", (int)brandID);
|
||||
}
|
||||
fprintf(f, "\t</array>\n");
|
||||
fprintf(f, "\t<key>RunAtLoad</key>\n");
|
||||
|
@ -1565,7 +1544,7 @@ OSErr UpdateAllVisibleUsers(long brandID, long oldBrandID)
|
|||
uid_t saved_uid;
|
||||
Boolean deleteLoginItem;
|
||||
char human_user_name[256];
|
||||
char s[256];
|
||||
char s[2*MAXPATHLEN];
|
||||
Boolean saverAlreadySetForAll = true;
|
||||
Boolean setSaverForAllUsers = false;
|
||||
Boolean allNonAdminUsersAreSet = true;
|
||||
|
@ -1573,12 +1552,13 @@ OSErr UpdateAllVisibleUsers(long brandID, long oldBrandID)
|
|||
int err;
|
||||
Boolean isAdminGroupMember, isBMGroupMember;
|
||||
struct stat sbuf;
|
||||
char cmd[256];
|
||||
char cmd[2*MAXPATHLEN];
|
||||
#ifdef SANDBOX
|
||||
int BMGroupMembershipCount, BPGroupMembershipCount;
|
||||
int i;
|
||||
#endif
|
||||
int i;
|
||||
int userIndex;
|
||||
char path[MAXPATHLEN];
|
||||
|
||||
// char nameOfSkin[256];
|
||||
// FindSkinName(nameOfSkin, sizeof(nameOfSkin));
|
||||
|
@ -1811,21 +1791,78 @@ OSErr UpdateAllVisibleUsers(long brandID, long oldBrandID)
|
|||
if (useOSASript) {
|
||||
snprintf(s, sizeof(s), "/Users/%s/Library/LaunchAgents/edu.berkeley.boinc.plist", pw->pw_name);
|
||||
boinc_delete_file(s);
|
||||
|
||||
for (i=0; i< NUMBRANDS; i++) {
|
||||
snprintf(s, sizeof(s), "rm -f \"/Users/%s/Library/Application Support/BOINC/%s_Finish_Install\"", pw->pw_name, appName[i]);
|
||||
err = callPosixSpawn(s);
|
||||
REPORT_ERROR(err);
|
||||
if (err) {
|
||||
printf("Command %s returned error %d\n", s, err);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
snprintf(s, sizeof(s), "rm -f \"/Users/%s/Library/Application Support/BOINC/%s_Finish_Uninstall\"", pw->pw_name, appName[i]);
|
||||
err = callPosixSpawn(s);
|
||||
REPORT_ERROR(err);
|
||||
if (err) {
|
||||
printf("Command %s returned error %d\n", s, err);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
printf("[2] calling SetLoginItemOSAScript for user %s, euid = %d, deleteLoginItem = %d\n",
|
||||
pw->pw_name, geteuid(), deleteLoginItem);
|
||||
fflush(stdout);
|
||||
SetLoginItemOSAScript(brandID, deleteLoginItem, pw->pw_name);
|
||||
|
||||
printf("[2] calling FixLaunchServicesDataBase for user %s\n", pw->pw_name);
|
||||
fflush(stdout);
|
||||
FixLaunchServicesDataBase(pw->pw_uid, brandID);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "mkdir -p \"/Users/%s/Library/Application Support/BOINC/\"", pw->pw_name);
|
||||
err = callPosixSpawn(s);
|
||||
REPORT_ERROR(err);
|
||||
if (err) {
|
||||
printf("Command %s returned error %d\n", s, err);
|
||||
fflush(stdout);
|
||||
}
|
||||
snprintf(s, sizeof(s), "/Users/%s/Library/Application Support/BOINC/", pw->pw_name);
|
||||
chmod(s, 0771);
|
||||
chown(s, pw->pw_uid, pw->pw_gid);
|
||||
|
||||
getPathToThisApp(path, sizeof(path));
|
||||
strncat(path, "/Contents/Resources/boinc_finish_install", sizeof(path)-1);
|
||||
snprintf(s, sizeof(s), "cp -f \"%s\" \"/Users/%s/Library/Application Support/BOINC/%s_Finish_Install\"", path, pw->pw_name, appName[brandID]);
|
||||
err = callPosixSpawn(s);
|
||||
REPORT_ERROR(err);
|
||||
if (err) {
|
||||
printf("Command %s returned error %d\n", s, err);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
snprintf(s, sizeof(s), "/Users/%s/Library/Application Support/BOINC/%s_Finish_Install", pw->pw_name, appName[brandID]);
|
||||
chmod(s, 0755);
|
||||
chown(s, pw->pw_uid, pw->pw_gid);
|
||||
|
||||
for (i=0; i< NUMBRANDS; i++) {
|
||||
// If we previously ran the uninstaller but did not log in to this user,
|
||||
// remove the user's unused BOINC_Manager_Finish_Uninstall file.
|
||||
snprintf(s, sizeof(s), "rm -f \"/Users/%s/Library/Application Support/BOINC/%s_Finish_Uninstall\"", pw->pw_name, appName[i]);
|
||||
err = callPosixSpawn(s);
|
||||
REPORT_ERROR(err);
|
||||
if (err) {
|
||||
printf("Command %s returned error %d\n", s, err);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
printf("[2] calling SetLoginItemLaunchAgent for user %s, euid = %d, deleteLoginItem = %d\n",
|
||||
pw->pw_name, geteuid(), deleteLoginItem);
|
||||
fflush(stdout);
|
||||
// SetLoginItemLaunchAgent will run helper app which will call FixLaunchServicesDataBase()
|
||||
SetLoginItemLaunchAgent(brandID, oldBrandID, deleteLoginItem, pw);
|
||||
}
|
||||
|
||||
printf("[2] calling FixLaunchServicesDataBase for user %s\n", pw->pw_name);
|
||||
fflush(stdout);
|
||||
FixLaunchServicesDataBase(pw->pw_uid, brandID);
|
||||
|
||||
if (isBMGroupMember) {
|
||||
// For some reason we need to call getpwnam again on OS 10.5
|
||||
pw = getpwnam(human_user_name);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This file is part of BOINC.
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2022 University of California
|
||||
// Copyright (C) 2023 University of California
|
||||
//
|
||||
// BOINC is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License
|
||||
|
@ -56,8 +56,7 @@
|
|||
#include "mac_branding.h"
|
||||
|
||||
int callPosixSpawn(const char *cmd);
|
||||
long GetBrandID(char *path);
|
||||
static void FixLaunchServicesDataBase(void);
|
||||
static void FixLaunchServicesDataBase(int brandId, bool isUninstall);
|
||||
static Boolean IsUserActive(const char *userName);
|
||||
static char * PersistentFGets(char *buf, size_t buflen, FILE *f);
|
||||
void print_to_log_file(const char *format, ...);
|
||||
|
@ -66,8 +65,11 @@ void strip_cr(char *buf);
|
|||
int main(int argc, const char * argv[]) {
|
||||
int i, err;
|
||||
char cmd[2048];
|
||||
char scriptName[1024];
|
||||
char *userName;
|
||||
passwd *pw;
|
||||
bool isUninstall = false;
|
||||
int iBrandId = 0;
|
||||
|
||||
// Wait until we are the active login (in case of fast user switching)
|
||||
userName = getenv("USER");
|
||||
|
@ -85,67 +87,72 @@ int main(int argc, const char * argv[]) {
|
|||
}
|
||||
}
|
||||
|
||||
FixLaunchServicesDataBase();
|
||||
|
||||
for (i=1; i<argc; i+=2) {
|
||||
if (strcmp(argv[i], "-d") == 0) {
|
||||
// If this user was previously authorized to run the Manager, the Login Item
|
||||
// may have launched the Manager before this app deleted that Login Item. To
|
||||
// guard against this, we kill the Manager (for this user only) if it is running.
|
||||
//
|
||||
snprintf(cmd, sizeof(cmd), "killall -u %d -9 \"%s\"", getuid(), argv[i+1]);
|
||||
err = callPosixSpawn(cmd);
|
||||
if (err) {
|
||||
fprintf(stderr, "Command: %s\n", cmd);
|
||||
fprintf(stderr, "killall %s returned error %d\n", argv[i+1], err);
|
||||
fflush(stderr);
|
||||
}
|
||||
} else if (strcmp(argv[i], "-a") == 0) {
|
||||
snprintf(cmd, sizeof(cmd), "osascript -e 'tell application \"System Events\" to make new login item at end with properties {path:\"/Applications/%s.app\", hidden:true, name:\"%s\"}'", argv[i+1], argv[i+1]);
|
||||
err = callPosixSpawn(cmd);
|
||||
if (err) {
|
||||
fprintf(stderr, "Command: %s\n", cmd);
|
||||
fprintf(stderr, "Make new login item for %s returned error %d\n", argv[i+1], err);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
snprintf(cmd, sizeof(cmd), "open -jg \"/Applications/%s.app\"", argv[i+1]);
|
||||
err = callPosixSpawn(cmd);
|
||||
if (err) {
|
||||
fprintf(stderr, "Command: %s\n", cmd);
|
||||
fprintf(stderr, "Make login item for %s returned error %d\n", argv[i+1], err);
|
||||
fflush(stderr);
|
||||
}
|
||||
} // end if (strcmp(argv[i], "-a") == 0)
|
||||
isUninstall = true;
|
||||
} else if (strcmp(argv[i], "-a") != 0) {
|
||||
iBrandId = atoi(argv[i]);
|
||||
}
|
||||
} // end for (i=i; i<argc; i+=2)
|
||||
|
||||
if (isUninstall) {
|
||||
// If this user was previously authorized to run the Manager, the Login Item
|
||||
// may have launched the Manager before this app deleted that Login Item. To
|
||||
// guard against this, we kill the Manager (for this user only) if it is running.
|
||||
//
|
||||
snprintf(cmd, sizeof(cmd), "killall -u %d -9 \"%s\"", getuid(), appName[iBrandId]);
|
||||
err = callPosixSpawn(cmd);
|
||||
if (err) {
|
||||
fprintf(stderr, "Command: %s\n", cmd);
|
||||
fprintf(stderr, "killall %s returned error %d\n", appName[iBrandId], err);
|
||||
fflush(stderr);
|
||||
}
|
||||
} else {
|
||||
snprintf(cmd, sizeof(cmd), "osascript -e 'tell application \"System Events\" to make new login item at end with properties {path:\"/Applications/%s.app\", hidden:true, name:\"%s\"}'", appName[iBrandId], appName[iBrandId]);
|
||||
err = callPosixSpawn(cmd);
|
||||
if (err) {
|
||||
fprintf(stderr, "Command: %s\n", cmd);
|
||||
fprintf(stderr, "Make new login item for %s returned error %d\n", appName[iBrandId], err);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
snprintf(cmd, sizeof(cmd), "open -jg \"/Applications/%s.app\"", appName[iBrandId]);
|
||||
err = callPosixSpawn(cmd);
|
||||
if (err) {
|
||||
fprintf(stderr, "Command: %s\n", cmd);
|
||||
fprintf(stderr, "\"open -jg \"/Applications/%s.app\" returned error %d\n", appName[iBrandId], err);
|
||||
fflush(stderr);
|
||||
}
|
||||
}
|
||||
|
||||
FixLaunchServicesDataBase(iBrandId, isUninstall);
|
||||
|
||||
pw = getpwuid(getuid());
|
||||
|
||||
snprintf(cmd, sizeof(cmd), "rm -f \"/Users/%s/Library/LaunchAgents/edu.berkeley.boinc.plist\"", pw->pw_name);
|
||||
callPosixSpawn(cmd);
|
||||
|
||||
// We can't delete ourselves while we are running,
|
||||
// so launch a shell script to do it after we exit.
|
||||
sprintf(scriptName, "/tmp/%s_Finish_%s_%s", appName[iBrandId], isUninstall ? "Uninstall" : "Install", pw->pw_name);
|
||||
FILE* f = fopen(scriptName, "w");
|
||||
fprintf(f, "#!/bin/bash\n\n");
|
||||
fprintf(f, "sleep 3\n");
|
||||
if (isUninstall) {
|
||||
// Delete per-user BOINC Manager and screensaver files, including this executable
|
||||
fprintf(f, "rm -fR \"/Users/%s/Library/Application Support/BOINC\"\n", pw->pw_name);
|
||||
} else {
|
||||
// Delete only this executable
|
||||
fprintf(f, "rm -f \"/Users/%s/Library/Application Support/BOINC/%s_Finish_Install\"", pw->pw_name, appName[iBrandId]);
|
||||
}
|
||||
fclose(f);
|
||||
sprintf(cmd, "sh %s", scriptName);
|
||||
callPosixSpawn (cmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long GetBrandID(char *path)
|
||||
{
|
||||
long iBrandId;
|
||||
|
||||
iBrandId = 0; // Default value
|
||||
|
||||
FILE *f = fopen(path, "r");
|
||||
if (f) {
|
||||
fscanf(f, "BrandId=%ld\n", &iBrandId);
|
||||
fclose(f);
|
||||
}
|
||||
if ((iBrandId < 0) || (iBrandId > (NUMBRANDS-1))) {
|
||||
iBrandId = 0;
|
||||
}
|
||||
return iBrandId;
|
||||
}
|
||||
|
||||
|
||||
// If there are other copies of BOINC Manager with different branding
|
||||
// on the system, Notifications may display the icon for the wrong
|
||||
// branding, due to the Launch Services database having one of the
|
||||
|
@ -155,27 +162,24 @@ long GetBrandID(char *path)
|
|||
//
|
||||
// This probably will happen only on BOINC development systems where
|
||||
// Xcode has generated copies of BOINC Manager.
|
||||
static void FixLaunchServicesDataBase() {
|
||||
long brandID = 0;
|
||||
static void FixLaunchServicesDataBase(int brandID, bool isUninstall) {
|
||||
char boincPath[MAXPATHLEN];
|
||||
char cmd[MAXPATHLEN+250];
|
||||
long i, n;
|
||||
CFArrayRef appRefs = NULL;
|
||||
OSStatus err;
|
||||
|
||||
brandID = GetBrandID("/Library/Application Support/BOINC Data/Branding");
|
||||
|
||||
CFStringRef bundleID = CFSTR("edu.berkeley.boinc");
|
||||
|
||||
// LSCopyApplicationURLsForBundleIdentifier is not available before OS 10.10,
|
||||
// but this app is used only for OS 10.13 and later
|
||||
appRefs = LSCopyApplicationURLsForBundleIdentifier(bundleID, NULL);
|
||||
if (appRefs == NULL) {
|
||||
print_to_log_file("Call to LSCopyApplicationURLsForBundleIdentifier returned NULL");
|
||||
goto registerOurApp;
|
||||
}
|
||||
n = CFArrayGetCount(appRefs); // Returns all results at once, in database order
|
||||
print_to_log_file("LSCopyApplicationURLsForBundleIdentifier returned %ld results", n);
|
||||
appRefs = LSCopyApplicationURLsForBundleIdentifier(bundleID, NULL);
|
||||
if (appRefs == NULL) {
|
||||
print_to_log_file("Call to LSCopyApplicationURLsForBundleIdentifier returned NULL");
|
||||
goto registerOurApp;
|
||||
}
|
||||
n = CFArrayGetCount(appRefs); // Returns all results at once, in database order
|
||||
print_to_log_file("LSCopyApplicationURLsForBundleIdentifier returned %ld results", n);
|
||||
|
||||
for (i=0; i<n; ++i) { // Prevent infinite loop
|
||||
CFURLRef appURL = (CFURLRef)CFArrayGetValueAtIndex(appRefs, i);
|
||||
|
@ -188,10 +192,12 @@ static void FixLaunchServicesDataBase() {
|
|||
CFRelease(appURL);
|
||||
appURL = NULL;
|
||||
}
|
||||
if (strncmp(boincPath, appPath[brandID], sizeof(boincPath)) == 0) {
|
||||
print_to_log_file("**** Keeping %s", boincPath);
|
||||
if (appRefs) CFRelease(appRefs);
|
||||
return; // Our (possibly branded) BOINC Manager app is now at top of database
|
||||
if (! isUninstall) {
|
||||
if (strncmp(boincPath, appPath[brandID], sizeof(boincPath)) == 0) {
|
||||
print_to_log_file("**** Keeping %s", boincPath);
|
||||
if (appRefs) CFRelease(appRefs);
|
||||
return; // Our (possibly branded) BOINC Manager app is now at top of database
|
||||
}
|
||||
}
|
||||
print_to_log_file("Unregistering %3ld: %s", i, boincPath);
|
||||
// Remove this entry from the Launch Services database
|
||||
|
@ -205,6 +211,8 @@ static void FixLaunchServicesDataBase() {
|
|||
registerOurApp:
|
||||
if (appRefs) CFRelease(appRefs);
|
||||
|
||||
if (isUninstall) return;
|
||||
|
||||
// We have exhausted the Launch Services database without finding our
|
||||
// (possibly branded) BOINC Manager app, so add it to the dataabase
|
||||
print_to_log_file("%s was not found in Launch Services database; registering it now", appPath[brandID]);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This file is part of BOINC.
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2022 University of California
|
||||
// Copyright (C) 2023 University of California
|
||||
//
|
||||
// BOINC is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License
|
||||
|
@ -625,12 +625,13 @@ static OSStatus CleanupAllVisibleUsers(void)
|
|||
int userIndex;
|
||||
int flag;
|
||||
char buf[256];
|
||||
char s[1024];
|
||||
char s[2*MAXPATHLEN];
|
||||
FILE *f;
|
||||
char *p;
|
||||
int id;
|
||||
OSStatus err;
|
||||
Boolean changeSaver;
|
||||
Boolean isCatalinaOrLater = (compareOSVersionTo(10, 15) >= 0);
|
||||
|
||||
// saved_uid = getuid();
|
||||
saved_euid = geteuid();
|
||||
|
@ -749,6 +750,14 @@ static OSStatus CleanupAllVisibleUsers(void)
|
|||
pw->pw_name, geteuid());
|
||||
#endif
|
||||
DeleteLoginItemOSAScript(pw->pw_name);
|
||||
|
||||
// Under OS 10.13 High Sierra or later, this code deletes the per-user BOINC
|
||||
// Manager files only for the user running this app. For each user other than
|
||||
// one running this app, we put BOINCManager_Finish_Uninstall in its per-user
|
||||
// BOINC directory, so we can't delete it now. BOINCManager_Finish_Uninstall
|
||||
// will delete that user's per-user BOINC directory as its final task.
|
||||
sprintf(s, "rm -fR \"/Users/%s/Library/Application Support/BOINC\"", pw->pw_name);
|
||||
callPosixSpawn (s);
|
||||
} else {
|
||||
#if TESTING
|
||||
showDebugMsg("calling DeleteLoginItemLaunchAgent for user %s, euid = %d\n",
|
||||
|
@ -767,14 +776,18 @@ static OSStatus CleanupAllVisibleUsers(void)
|
|||
// sprintf(s, "rm -f \"/Users/%s/Library/Preferences/BOINC Manager Preferences\"", human_user_name);
|
||||
// callPosixSpawn (s);
|
||||
|
||||
// Delete per-user BOINC Manager and screensaver files
|
||||
sprintf(s, "rm -fR \"/Users/%s/Library/Application Support/BOINC\"", human_user_name);
|
||||
callPosixSpawn (s);
|
||||
|
||||
// Set screensaver to "Flurry" screensaver only
|
||||
// if it was BOINC unbranded or branded screensaver.
|
||||
changeSaver = false;
|
||||
|
||||
if (isCatalinaOrLater) {
|
||||
// As of Catalina, Screensaver output files are put in the user's Containers
|
||||
// directory.
|
||||
snprintf(s, sizeof(s), "rm -fR \"/Users/%s/Library/Containers/com.apple.ScreenSaver.Engine.legacyScreenSaver/Data/Library/Application Support/BOINC\"",
|
||||
pw->pw_name);
|
||||
callPosixSpawn(s);
|
||||
}
|
||||
|
||||
err = GetCurrentScreenSaverSelection(pw, s, sizeof(s) -1);
|
||||
if (err == noErr) {
|
||||
for (i=0; i<NUMBRANDS; ++i) {
|
||||
|
@ -953,7 +966,7 @@ cleanupSystemEvents:
|
|||
}
|
||||
|
||||
|
||||
// Under OS 10.13 High Sierra, telling System Events to modify Login Items for
|
||||
// As of OS 10.13 High Sierra, telling System Events to modify Login Items for
|
||||
// users who are not currently logged in no longer works, even when System Events
|
||||
// is running as that user.
|
||||
// So we create a LaunchAgent for that user. The next time that user logs in, the
|
||||
|
@ -969,28 +982,34 @@ cleanupSystemEvents:
|
|||
//
|
||||
Boolean DeleteLoginItemLaunchAgent(long brandID, passwd *pw)
|
||||
{
|
||||
static bool alreadyCopied = false;
|
||||
struct stat sbuf;
|
||||
char path[MAXPATHLEN];
|
||||
char s[2048];
|
||||
char s[2*MAXPATHLEN];
|
||||
OSErr err;
|
||||
|
||||
if (!alreadyCopied) {
|
||||
getPathToThisApp(path, sizeof(path));
|
||||
strncat(path, "/Contents/Resources/boinc_finish_install", sizeof(path)-1);
|
||||
snprintf(s, sizeof(s), "cp -f \"%s\" \"/Library/Application Support/BOINC Data/%s_Finish_Uninstall\"", path, appName[brandID]);
|
||||
err = callPosixSpawn(s);
|
||||
if (err) {
|
||||
printf("[2] Command %s returned error %d\n", s, err);
|
||||
fflush(stdout);
|
||||
} else {
|
||||
alreadyCopied = true;
|
||||
}
|
||||
|
||||
snprintf(s, sizeof(s), "/Library/Application Support/BOINC Data/%s_Finish_Install\"</string>\n", appName[brandID]);
|
||||
chmod(s, 0755);
|
||||
chown(s, pw->pw_uid, pw->pw_gid);
|
||||
snprintf(s, sizeof(s), "mkdir -p \"/Users/%s/Library/Application Support/BOINC/\"", pw->pw_name);
|
||||
err = callPosixSpawn(s);
|
||||
if (err) {
|
||||
printf("[2] Command %s returned error %d\n", s, err);
|
||||
fflush(stdout);
|
||||
}
|
||||
snprintf(s, sizeof(s), "/Users/%s/Library/Application Support/BOINC/", pw->pw_name);
|
||||
chmod(s, 0771);
|
||||
chown(s, pw->pw_uid, pw->pw_gid);
|
||||
|
||||
getPathToThisApp(path, sizeof(path));
|
||||
strncat(path, "/Contents/Resources/boinc_finish_install", sizeof(path)-1);
|
||||
snprintf(s, sizeof(s), "cp -f \"%s\" \"/Users/%s/Library/Application Support/BOINC/%s_Finish_Uninstall\"",
|
||||
path, pw->pw_name, appName[brandID]);
|
||||
err = callPosixSpawn(s);
|
||||
if (err) {
|
||||
printf("[2] Command %s returned error %d\n", s, err);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
snprintf(s, sizeof(s), "/Users/%s/Library/Application Support/BOINC/%s_Finish_Uninstall", pw->pw_name, appName[brandID]);
|
||||
chmod(s, 0755);
|
||||
chown(s, pw->pw_uid, pw->pw_gid);
|
||||
|
||||
// Create a LaunchAgent for the specified user, replacing any LaunchAgent created
|
||||
// previously (such as by Installer or by installing a differently branded BOINC.)
|
||||
|
@ -1013,7 +1032,7 @@ Boolean DeleteLoginItemLaunchAgent(long brandID, passwd *pw)
|
|||
fprintf(f, "\t<string>edu.berkeley.fix_login_items</string>\n");
|
||||
fprintf(f, "\t<key>ProgramArguments</key>\n");
|
||||
fprintf(f, "\t<array>\n");
|
||||
fprintf(f, "\t\t<string>/Library/Application Support/BOINC Data/%s_Finish_Uninstall</string>\n", appName[brandID]);
|
||||
fprintf(f, "\t\t<string>/Users/%s/Library/Application Support/BOINC/%s_Finish_Uninstall</string>\n", pw->pw_name, appName[brandID]);
|
||||
// If this user was previously authorized to run the Manager, there
|
||||
// may still be a Login Item for this user, and the Login Item may
|
||||
// launch the Manager before the LaunchAgent deletes the Login Item.
|
||||
|
@ -1024,7 +1043,7 @@ Boolean DeleteLoginItemLaunchAgent(long brandID, passwd *pw)
|
|||
// that could happen, so this step is probably unnecessary.
|
||||
//
|
||||
fprintf(f, "\t\t<string>-d</string>\n");
|
||||
fprintf(f, "\t\t<string>%s</string>\n", appName[brandID]);
|
||||
fprintf(f, "\t\t<string>%d</string>\n", (int)brandID);
|
||||
fprintf(f, "\t</array>\n");
|
||||
fprintf(f, "\t<key>RunAtLoad</key>\n");
|
||||
fprintf(f, "\t<true/>\n");
|
||||
|
|
Loading…
Reference in New Issue