Fix Mac installer & uninstaller to properly handle branded BOINC screensavers on OS 10.15 Catalina

This commit is contained in:
Charlie Fenton 2019-12-06 05:32:28 -08:00
parent 3fdf87d0ba
commit ba67414df6
2 changed files with 94 additions and 53 deletions

View File

@ -115,7 +115,7 @@ Boolean IsRestartNeeded();
void CheckUserAndGroupConflicts();
Boolean SetLoginItemOSAScript(long brandID, Boolean deleteLogInItem, char *userName);
Boolean SetLoginItemLaunchAgent(long brandID, long oldBrandID, Boolean deleteLogInItem, passwd *pw);
Boolean SetScreenSaverLaunchAgent(passwd *pw);
Boolean SetScreenSaverLaunchAgent(passwd *pw, char *theSaverName);
OSErr GetCurrentScreenSaverSelection(passwd *pw, char *moduleName, size_t maxLen);
OSErr SetScreenSaverSelection(char *moduleName, char *modulePath, int type);
void SetSkinInUserPrefs(char *userName, char *nameOfSkin);
@ -1164,11 +1164,17 @@ Boolean SetLoginItemLaunchAgent(long brandID, long oldBrandID, Boolean deleteLog
chmod(s, 0644);
chown(s, pw->pw_uid, pw->pw_gid);
if (IsUserLoggedIn(pw->pw_name)) {
sprintf(s, "su -l \"%s\" -c 'launchctl unload /Users/%s/Library/LaunchAgents/edu.berkeley.boinc.plist'", pw->pw_name, pw->pw_name);
callPosixSpawn(s);
sprintf(s, "su -l \"%s\" -c 'launchctl load /Users/%s/Library/LaunchAgents/edu.berkeley.boinc.plist'", pw->pw_name, pw->pw_name);
callPosixSpawn(s);
}
return true;
}
Boolean SetScreenSaverLaunchAgent(passwd *pw)
Boolean SetScreenSaverLaunchAgent(passwd *pw, char *theSaverName)
{
struct stat sbuf;
char s[2048];
@ -1183,12 +1189,17 @@ Boolean SetScreenSaverLaunchAgent(passwd *pw)
//
// Create LaunchAgents directory for this user if it does not yet exist
snprintf(s, sizeof(s), "/Users/%s/Library/LaunchAgents", pw->pw_name);
if (stat(s, &sbuf) != 0) {
if (stat(s, &sbuf) != 0) { // stat() returns zero on success
mkdir(s, 0755);
chown(s, pw->pw_uid, pw->pw_gid);
}
snprintf(s, sizeof(s), "/Users/%s/Library/LaunchAgents/edu.berkeley.boinc-sshelper.plist", pw->pw_name);
if (stat(s, &sbuf) == 0) {
sprintf(s, "su -l \"%s\" -c 'launchctl unload /Users/%s/Library/LaunchAgents/edu.berkeley.boinc-sshelper.plist'", pw->pw_name, pw->pw_name);
callPosixSpawn(s);
}
FILE* f = fopen(s, "w");
if (!f) return false;
fprintf(f, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
@ -1199,7 +1210,7 @@ Boolean SetScreenSaverLaunchAgent(passwd *pw)
fprintf(f, "\t<string>edu.berkeley.boinc-sshelper</string>\n");
fprintf(f, "\t<key>ProgramArguments</key>\n");
fprintf(f, "\t<array>\n");
fprintf(f, "\t\t<string>/Library/Screen Savers/BOINCSaver.saver/Contents/Resources/gfx_switcher</string>\n");
fprintf(f, "\t\t<string>/Library/Screen Savers/%s.saver/Contents/Resources/gfx_switcher</string>\n", theSaverName);
fprintf(f, "\t</array>\n");
fprintf(f, "\t<key>WatchPaths</key>\n");
fprintf(f, "\t<array>\n");
@ -1217,6 +1228,11 @@ Boolean SetScreenSaverLaunchAgent(passwd *pw)
chmod(s, 0644);
chown(s, pw->pw_uid, pw->pw_gid);
if (IsUserLoggedIn(pw->pw_name)) {
sprintf(s, "su -l \"%s\" -c 'launchctl load /Users/%s/Library/LaunchAgents/edu.berkeley.boinc-sshelper.plist'", pw->pw_name, pw->pw_name);
callPosixSpawn(s);
}
return true;
}
@ -1882,6 +1898,9 @@ OSErr UpdateAllVisibleUsers(long brandID, long oldBrandID)
// callPosixSpawn(s);
}
// Set the screensaver launch agent even if they have not selected the
// BOINC screensaver now, so BOINC screensaver will work if selected later
// via System Preferences.
if (useScreenSaverLaunchAgent) {
printf("[2] calling SetScreenSaverLaunchAgent for user %s, euid = %d\n",
pw->pw_name, geteuid());
@ -1891,26 +1910,25 @@ OSErr UpdateAllVisibleUsers(long brandID, long oldBrandID)
// that file and writes a file /Users/Shared/BOINCGfxPid.txt with the new pid if it
// succesfully launched a gfx app.
//
SetScreenSaverLaunchAgent(pw);
}
SetScreenSaverLaunchAgent(pw, saverName[brandID]);
if (compareOSVersionTo(10, 15) >= 0) {
// Under Catalina, Screensaver output files are put in the user's Containers
// directory. Create the directory if it doesn't exist and create a symbolic
// link to it in the normal per-user BOINC directory
snprintf(s, sizeof(s),
"/Users/%s/Library/Application Support/BOINC", pw->pw_name);
if (stat(s, &sbuf) != 0) {
snprintf(cmd, sizeof(cmd), "sudo -u \"%s\" mkdir -p -m 0775 \"/Users/%s/Library/Application Support/BOINC\"",
pw->pw_name, pw->pw_name);
err = callPosixSpawn(cmd);
REPORT_ERROR(err);
printf("[2] %s returned %d\n", cmd, err);
fflush(stdout);
}
snprintf(s, sizeof(s), "/Users/%s/Library/Containers/com.apple.ScreenSaver.Engine.legacyScreenSaver/Data/Library/Application Support/BOINC",
pw->pw_name);
if (compareOSVersionTo(10, 15) >= 0) {
// Under Catalina, Screensaver output files are put in the user's Containers
// directory. Create the directory if it doesn't exist and create a symbolic
// link to it in the normal per-user BOINC directory
snprintf(s, sizeof(s),
"/Users/%s/Library/Application Support/BOINC", pw->pw_name);
if (stat(s, &sbuf) != 0) {
snprintf(cmd, sizeof(cmd), "sudo -u \"%s\" mkdir -p -m 0775 \"/Users/%s/Library/Application Support/BOINC\"",
pw->pw_name, pw->pw_name);
err = callPosixSpawn(cmd);
REPORT_ERROR(err);
printf("[2] %s returned %d\n", cmd, err);
fflush(stdout);
}
snprintf(s, sizeof(s), "/Users/%s/Library/Containers/com.apple.ScreenSaver.Engine.legacyScreenSaver/Data/Library/Application Support/BOINC",
pw->pw_name);
if (stat(s, &sbuf) != 0) {
// mkdir -p creates intermediate directories as required
snprintf(cmd, sizeof(cmd), "sudo -u \"%s\" mkdir -p -m 0700 \"/Users/%s/Library/Containers/com.apple.ScreenSaver.Engine.legacyScreenSaver/Data/Library/Application Support\"",
@ -1920,22 +1938,23 @@ OSErr UpdateAllVisibleUsers(long brandID, long oldBrandID)
printf("[2] %s returned %d\n", cmd, err);
fflush(stdout);
snprintf(cmd, sizeof(cmd), "sudo -u \"%s\" mkdir -m 0775 \"/Users/%s/Library/Containers/com.apple.ScreenSaver.Engine.legacyScreenSaver/Data/Library/Application Support/BOINC\"",
pw->pw_name, pw->pw_name);
err = callPosixSpawn(cmd);
REPORT_ERROR(err);
printf("[2] %s returned %d\n", cmd, err);
fflush(stdout);
}
snprintf(s, sizeof(s),
"/Users/%s/Library/Application Support/BOINC/ScreenSaver Logs",
pw->pw_name);
if (lstat(s, &sbuf) != 0) {
snprintf(cmd, sizeof(cmd), "sudo -u \"%s\" ln -s \"/Users/%s/Library/Containers/com.apple.ScreenSaver.Engine.legacyScreenSaver/Data/Library/Application Support/BOINC\" \"/Users/%s/Library/Application Support/BOINC/ScreenSaver Logs\"", pw->pw_name, pw->pw_name, pw->pw_name);
err = callPosixSpawn(cmd);
REPORT_ERROR(err);
printf("[2] %s returned %d\n", cmd, err);
fflush(stdout);
snprintf(cmd, sizeof(cmd), "sudo -u \"%s\" mkdir -m 0775 \"/Users/%s/Library/Containers/com.apple.ScreenSaver.Engine.legacyScreenSaver/Data/Library/Application Support/BOINC\"",
pw->pw_name, pw->pw_name);
err = callPosixSpawn(cmd);
REPORT_ERROR(err);
printf("[2] %s returned %d\n", cmd, err);
fflush(stdout);
}
snprintf(s, sizeof(s),
"/Users/%s/Library/Application Support/BOINC/ScreenSaver Logs",
pw->pw_name);
if (lstat(s, &sbuf) != 0) {
snprintf(cmd, sizeof(cmd), "sudo -u \"%s\" ln -s \"/Users/%s/Library/Containers/com.apple.ScreenSaver.Engine.legacyScreenSaver/Data/Library/Application Support/BOINC\" \"/Users/%s/Library/Application Support/BOINC/ScreenSaver Logs\"", pw->pw_name, pw->pw_name, pw->pw_name);
err = callPosixSpawn(cmd);
REPORT_ERROR(err);
printf("[2] %s returned %d\n", cmd, err);
fflush(stdout);
}
}
}
}

View File

@ -62,6 +62,7 @@ static void DeleteLoginItemOSAScript(char *userName);
static Boolean DeleteLoginItemLaunchAgent(long brandID, passwd *pw);
static void DeleteScreenSaverLaunchAgent(passwd *pw);
long GetBrandID(char *path);
static Boolean IsUserLoggedIn(const char *userName);
static char * PersistentFGets(char *buf, size_t buflen, FILE *f);
OSErr GetCurrentScreenSaverSelection(passwd *pw, char *moduleName, size_t maxLen);
OSErr SetScreenSaverSelection(char *moduleName, char *modulePath, int type);
@ -81,7 +82,6 @@ static char gBrandName[256];
static char gCatalogsDir[MAXPATHLEN];
static char * gCatalog_Name = (char *)"BOINC-Setup";
static char loginName[256];
static Boolean usedScreenSaverLaunchAgent = false;
/* BEGIN TEMPORARY ITEMS TO ALLOW TRANSLATORS TO START WORK */
@ -101,9 +101,6 @@ int main(int argc, char *argv[])
FILE *f;
OSStatus err = noErr;
// MIN_OS_TO_USE_SCREENSAVER_LAUNCH_AGENT is defined in mac_util.h
usedScreenSaverLaunchAgent = (compareOSVersionTo(10, MIN_OS_TO_USE_SCREENSAVER_LAUNCH_AGENT) >= 0);
pathToSelf[0] = '\0';
// Get the full path to our executable inside this application's bundle
getPathToThisApp(pathToSelf, sizeof(pathToSelf));
@ -759,13 +756,11 @@ static OSStatus CleanupAllVisibleUsers(void)
DeleteLoginItemLaunchAgent(brandID, pw);
}
if (usedScreenSaverLaunchAgent) {
#if TESTING
showDebugMsg("calling DeleteScreenSaverLaunchAgent for user %s, euid = %d\n",
showDebugMsg("calling DeleteScreenSaverLaunchAgent for user %s, euid = %d\n",
pw->pw_name);
#endif
DeleteScreenSaverLaunchAgent(pw);
}
DeleteScreenSaverLaunchAgent(pw);
// We don't delete the user's BOINC Manager preferences
// sprintf(s, "rm -f \"/Users/%s/Library/Preferences/BOINC Manager Preferences\"", human_user_name);
@ -1039,19 +1034,29 @@ Boolean DeleteLoginItemLaunchAgent(long brandID, passwd *pw)
chmod(s, 0644);
chown(s, pw->pw_uid, pw->pw_gid);
if (IsUserLoggedIn(pw->pw_name)) {
sprintf(s, "su -l \"%s\" -c 'launchctl unload /Users/%s/Library/LaunchAgents/edu.berkeley.boinc.plist'", pw->pw_name, pw->pw_name);
callPosixSpawn(s);
sprintf(s, "su -l \"%s\" -c 'launchctl load /Users/%s/Library/LaunchAgents/edu.berkeley.boinc.plist'", pw->pw_name, pw->pw_name);
callPosixSpawn(s);
}
return true;
}
void DeleteScreenSaverLaunchAgent(passwd *pw) {
char cmd[MAXPATHLEN];
sprintf(cmd, "sudo -u \"%s\" -b launchctl unload /Users/%s/Library/LaunchAgents/edu.berkeley.boinc-sshelper.plist", pw->pw_name, pw->pw_name);
callPosixSpawn(cmd);
sprintf(cmd, "/Users/%s/Library/LaunchAgents/edu.berkeley.boinc-sshelper.plist", pw->pw_name);
if (boinc_file_exists(cmd)) {
sprintf(cmd, "su -l \"%s\" -c 'launchctl unload /Users/%s/Library/LaunchAgents/edu.berkeley.boinc-sshelper.plist'", pw->pw_name, pw->pw_name);
callPosixSpawn(cmd);
snprintf(cmd, sizeof(cmd),
"/Users/%s/Library/LaunchAgents/edu.berkeley.boinc-sshelper.plist",
pw->pw_name);
boinc_delete_file(cmd);
snprintf(cmd, sizeof(cmd),
"/Users/%s/Library/LaunchAgents/edu.berkeley.boinc-sshelper.plist",
pw->pw_name);
boinc_delete_file(cmd);
}
}
@ -1074,6 +1079,23 @@ long GetBrandID(char *path)
}
static Boolean IsUserLoggedIn(const char *userName){
char s[1024];
sprintf(s, "w -h \"%s\"", userName);
FILE *f = popen(s, "r");
if (f) {
if (PersistentFGets(s, sizeof(s), f) != NULL) {
pclose (f);
printf("User %s is currently logged in\n", userName);
return true; // this user is logged in (perhaps via fast user switching)
}
pclose (f);
}
return false;
}
static char * PersistentFGets(char *buf, size_t buflen, FILE *f) {
char *p = buf;
size_t len = buflen;