mirror of https://github.com/BOINC/boinc.git
Mac: Fix automatic launch on login under MacOS 13.3.1
This commit is contained in:
parent
86aef84d55
commit
49fecc6d71
|
@ -216,12 +216,6 @@ int main(int argc, char *argv[])
|
|||
sprintf(s, "dscl . -delete /Groups/boinc_project GroupMembership %s", pw->pw_name);
|
||||
callPosixSpawn(s);
|
||||
}
|
||||
|
||||
if (!AddUsers) {
|
||||
// Delete per-user BOINC Manager and screensaver files
|
||||
sprintf(s, "rm -fR \"/Users/%s/Library/Application Support/BOINC\"", pw->pw_name);
|
||||
callPosixSpawn (s);
|
||||
}
|
||||
|
||||
// Set or remove login item for this user
|
||||
bool useOSASript = false;
|
||||
|
@ -237,6 +231,12 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
#endif
|
||||
if (useOSASript) {
|
||||
if (!AddUsers) {
|
||||
// Delete per-user BOINC Manager and screensaver files
|
||||
sprintf(s, "rm -fR \"/Users/%s/Library/Application Support/BOINC\"", pw->pw_name);
|
||||
callPosixSpawn (s);
|
||||
}
|
||||
|
||||
snprintf(s, sizeof(s), "/Users/%s/Library/LaunchAgents/edu.berkeley.boinc.plist", pw->pw_name);
|
||||
boinc_delete_file(s);
|
||||
SetLoginItemOSAScript(brandID, !AddUsers, pw->pw_name);
|
||||
|
@ -535,6 +535,35 @@ Boolean SetLoginItemLaunchAgent(long brandID, Boolean deleteLogInItem, passwd *p
|
|||
if (stat(s, &sbuf) != 0) {
|
||||
return SetLoginItemLaunchAgentShellScript(brandID, deleteLogInItem, pw);
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "/Users/%s/Library/Application Support/BOINC", pw->pw_name);
|
||||
if (stat(s, &sbuf) != 0) {
|
||||
snprintf(s, sizeof(s), "sudo -u \"%s\" mkdir -p -m 0775 \"/Users/%s/Library/Application Support/BOINC\"",
|
||||
pw->pw_name, pw->pw_name);
|
||||
err = callPosixSpawn(s);
|
||||
if (err) {
|
||||
fprintf(stderr, "Command: %s returned error %d\n", s, (int) err);
|
||||
fflush(stderr);
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(s, sizeof(s), "cp -fR \"/Library/Application Support/BOINC Data/%s_Finish_Install.app\" \"/Users/%s/Library/Application Support/BOINC/%s_Finish_Install.app\"", brandName[brandID], pw->pw_name, brandName[brandID]);
|
||||
err = callPosixSpawn(s);
|
||||
if (err) {
|
||||
fprintf(stderr, "Command: %s returned error %d\n", s, (int) err);
|
||||
fflush(stderr);
|
||||
}
|
||||
snprintf(s, sizeof(s), "chown -R %d:%d \"/Users/%s/Library/Application Support/BOINC/%s_Finish_Install.app\"", pw->pw_uid, pw->pw_gid, pw->pw_name, brandName[brandID]);
|
||||
err = callPosixSpawn(s);
|
||||
if (err) {
|
||||
fprintf(stderr, "Command: %s returned error %d\n", s, (int) err);
|
||||
fflush(stderr);
|
||||
}
|
||||
snprintf(s, sizeof(s), "chmod -R a+rw \"/Users/%s/Library/Application Support/BOINC/%s_Finish_Install.app\"", pw->pw_name, brandName[brandID]);
|
||||
if (err) {
|
||||
fprintf(stderr, "Command: %s returned error %d\n", s, (int) err);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
return SetLoginItemLaunchAgentFinishInstallApp(brandID, deleteLogInItem, pw);
|
||||
}
|
||||
}
|
||||
|
@ -599,8 +628,8 @@ Boolean SetLoginItemLaunchAgentFinishInstallApp(long brandID, Boolean deleteLogI
|
|||
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.app/Contents/MacOS/%s_Finish_Install</string>\n", brandName[brandID], brandName[brandID]);
|
||||
if (deleteLogInItem) {
|
||||
fprintf(f, "\t\t<string>/Users/%s/Library/Application Support/BOINC/%s_Finish_Install.app/Contents/MacOS/%s_Finish_Install</string>\n", pw->pw_name, brandName[brandID], brandName[brandID]);
|
||||
if (deleteLogInItem) {
|
||||
// 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.
|
||||
|
|
|
@ -1087,8 +1087,8 @@ Boolean SetLoginItemLaunchAgent(long brandID, long oldBrandID, Boolean deleteLog
|
|||
struct stat sbuf;
|
||||
char s[2048];
|
||||
|
||||
// Create a LaunchAgent for the specified user, replacing any LaunchAgent created
|
||||
// previously (such as by Uninstaller or by installing a differently branded BOINC.)
|
||||
// Create a LaunchAgent to finish installation for the specified user, replacing any LaunchAgent
|
||||
// created previously (such as by Uninstaller or by installing a differently branded BOINC.)
|
||||
|
||||
// Create LaunchAgents directory for this user if it does not yet exist
|
||||
snprintf(s, sizeof(s), "/Users/%s/Library/LaunchAgents", pw->pw_name);
|
||||
|
@ -1823,11 +1823,22 @@ OSErr UpdateAllVisibleUsers(long brandID, long oldBrandID)
|
|||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
if (compareOSVersionTo(13, 0) >= 0) {
|
||||
deleteLoginItem = true; // Use LaunchAgent to autostart BOINC Manager
|
||||
snprintf(s, sizeof(s), "open \"/Library/Application Support/BOINC Data/%s_Finish_Install.app\"", brandName[brandID]);
|
||||
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);
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
printf("[2] calling FixLaunchServicesDataBase for Finish_Install for user %s\n", pw->pw_name);
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <sys/wait.h> // waitpid
|
||||
#include <sys/param.h> // for MAXPATHLEN
|
||||
#include <sys/stat.h> // for chmod
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <cerrno>
|
||||
|
@ -55,12 +56,13 @@
|
|||
|
||||
#include "mac_branding.h"
|
||||
|
||||
int callPosixSpawn(const char *cmd);
|
||||
static int callPosixSpawn(const char *cmd);
|
||||
static Boolean MakeLaunchManagerLaunchAgent(long brandID, passwd *pw);
|
||||
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, ...);
|
||||
void strip_cr(char *buf);
|
||||
static int compareOSVersionTo(int toMajor, int toMinor);
|
||||
static void print_to_log_file(const char *format, ...);
|
||||
|
||||
int main(int argc, const char * argv[]) {
|
||||
int i, err;
|
||||
|
@ -76,14 +78,16 @@ int main(int argc, const char * argv[]) {
|
|||
while (!IsUserActive(userName)) {
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
pw = getpwuid(getuid());
|
||||
|
||||
|
||||
for (i=0; i<NUMBRANDS; i++) {
|
||||
snprintf(cmd, sizeof(cmd), "osascript -e 'tell application \"System Events\" to delete login item \"%s\"'", appName[i]);
|
||||
err = callPosixSpawn(cmd);
|
||||
if (err) {
|
||||
fprintf(stderr, "Command: %s\n", cmd);
|
||||
fprintf(stderr, "Delete login item containing %s returned error %d\n", appName[i], err);
|
||||
fflush(stderr);
|
||||
print_to_log_file("Command: %s\n", cmd);
|
||||
print_to_log_file("Delete login item containing %s returned error %d\n", appName[i], err);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,32 +107,67 @@ int main(int argc, const char * argv[]) {
|
|||
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);
|
||||
print_to_log_file("Command: %s\n", cmd);
|
||||
print_to_log_file("killall %s returned error %d\n", appName[iBrandId], err);
|
||||
}
|
||||
|
||||
if (compareOSVersionTo(13, 0) >= 0) {
|
||||
snprintf(cmd, sizeof(cmd), "launchctl unload \"/Users/%s/Library/LaunchAgents/edu.berkeley.launchboincmanager.plist\"", pw->pw_name);
|
||||
err = callPosixSpawn(cmd);
|
||||
if (err) {
|
||||
print_to_log_file("Command: %s\n", cmd);
|
||||
print_to_log_file("returned error %d\n", err);
|
||||
}
|
||||
sprintf(cmd, "rm -f \"/Users/%s/Library/LaunchAgents/edu.berkeley.launchboincmanager.plist\"", pw->pw_name);
|
||||
callPosixSpawn (cmd);
|
||||
if (err) {
|
||||
print_to_log_file("Command: %s\n", cmd);
|
||||
print_to_log_file("returned error %d\n", err);
|
||||
}
|
||||
}
|
||||
|
||||
} 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[i], err);
|
||||
fflush(stderr);
|
||||
if (compareOSVersionTo(13, 0) >= 0) {
|
||||
bool success = MakeLaunchManagerLaunchAgent(iBrandId, pw);
|
||||
if (!success) {
|
||||
print_to_log_file("Command: %s\n", cmd);
|
||||
print_to_log_file("MakeLaunchManagerLaunchAgent for %s failed\n", appName[iBrandId]);
|
||||
}
|
||||
} else {
|
||||
snprintf(cmd, sizeof(cmd), "osascript -e 'tell application \"System Events\" to make new login item at end with properties {path:\"%s\", hidden:true, name:\"%s\"}'", appPath[iBrandId], appName[iBrandId]);
|
||||
err = callPosixSpawn(cmd);
|
||||
if (err) {
|
||||
print_to_log_file("Command: %s\n", cmd);
|
||||
print_to_log_file("Make new login item for %s returned error %d\n", appName[iBrandId], err);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (compareOSVersionTo(13, 0) >= 0) {
|
||||
snprintf(cmd, sizeof(cmd), "launchctl unload \"/Users/%s/Library/LaunchAgents/edu.berkeley.launchboincmanager.plist\"", pw->pw_name);
|
||||
err = callPosixSpawn(cmd);
|
||||
if (err) {
|
||||
print_to_log_file("Command: %s\n", cmd);
|
||||
print_to_log_file("returned error %d\n", err);
|
||||
}
|
||||
|
||||
snprintf(cmd, sizeof(cmd), "launchctl load \"/Users/%s/Library/LaunchAgents/edu.berkeley.launchboincmanager.plist\"", pw->pw_name);
|
||||
err = callPosixSpawn(cmd);
|
||||
if (err) {
|
||||
print_to_log_file("Command: %s\n", cmd);
|
||||
print_to_log_file("returned error %d\n", err);
|
||||
}
|
||||
} else {
|
||||
snprintf(cmd, sizeof(cmd), "open -jg \"%s\"", appPath[iBrandId]);
|
||||
err = callPosixSpawn(cmd);
|
||||
if (err) {
|
||||
print_to_log_file("Command: %s\n", cmd);
|
||||
print_to_log_file("\"open -jg \"%s\" returned error %d\n", appPath[iBrandId], err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
@ -153,6 +192,51 @@ int main(int argc, const char * argv[]) {
|
|||
}
|
||||
|
||||
|
||||
static Boolean MakeLaunchManagerLaunchAgent(long brandID, passwd *pw)
|
||||
{
|
||||
struct stat sbuf;
|
||||
char s[2048];
|
||||
|
||||
// Create a LaunchAgent for the specified user to autostart BOINC Manager on login, replacing
|
||||
// any LaunchAgent created previously (such as by installing a differently branded BOINC.)
|
||||
|
||||
// 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) {
|
||||
mkdir(s, 0755);
|
||||
chown(s, pw->pw_uid, pw->pw_gid);
|
||||
}
|
||||
|
||||
snprintf(s, sizeof(s), "/Users/%s/Library/LaunchAgents/edu.berkeley.launchboincmanager.plist", pw->pw_name);
|
||||
FILE* f = fopen(s, "w");
|
||||
if (!f) return false;
|
||||
fprintf(f, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
|
||||
fprintf(f, "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n");
|
||||
fprintf(f, "<plist version=\"1.0\">\n");
|
||||
fprintf(f, "<dict>\n");
|
||||
fprintf(f, "\t<key>Label</key>\n");
|
||||
fprintf(f, "\t<string>edu.berkeley.launchBOINCManager</string>\n");
|
||||
fprintf(f, "\t<key>ProgramArguments</key>\n");
|
||||
fprintf(f, "\t<array>\n");
|
||||
fprintf(f, "\t\t<string>%s/Contents/MacOS/%s</string>\n", appPath[brandID], appName[brandID]);
|
||||
fprintf(f, "\t\t<string>--autostart</string>\n");
|
||||
fprintf(f, "\t</array>\n");
|
||||
if (compareOSVersionTo(13, 0) >= 0) {
|
||||
fprintf(f, "\t<key>AssociatedBundleIdentifiers</key>\n");
|
||||
fprintf(f, "\t<string>edu.berkeley.boinc</string>\n");
|
||||
}
|
||||
fprintf(f, "\t<key>RunAtLoad</key>\n");
|
||||
fprintf(f, "\t<true/>\n");
|
||||
fprintf(f, "</dict>\n");
|
||||
fprintf(f, "</plist>\n");
|
||||
fclose(f);
|
||||
|
||||
chmod(s, 0644);
|
||||
chown(s, pw->pw_uid, pw->pw_gid);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 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
|
||||
|
@ -260,6 +344,44 @@ static Boolean IsUserActive(const char *userName){
|
|||
}
|
||||
|
||||
|
||||
// Test OS version number on all versions of OS X without using deprecated Gestalt
|
||||
// compareOSVersionTo(x, y) returns:
|
||||
// -1 if the OS version we are running on is less than x.y
|
||||
// 0 if the OS version we are running on is equal to x.y
|
||||
// +1 if the OS version we are running on is lgreater than x.y
|
||||
static int compareOSVersionTo(int toMajor, int toMinor) {
|
||||
static SInt32 major = -1;
|
||||
static SInt32 minor = -1;
|
||||
|
||||
if (major < 0) {
|
||||
char vers[100], *p1 = NULL;
|
||||
FILE *f;
|
||||
vers[0] = '\0';
|
||||
f = popen("sw_vers -productVersion", "r");
|
||||
if (f) {
|
||||
fscanf(f, "%s", vers);
|
||||
pclose(f);
|
||||
}
|
||||
if (vers[0] == '\0') {
|
||||
print_to_log_file("popen(\"sw_vers -productVersion\" failed\n");
|
||||
return 0;
|
||||
}
|
||||
// Extract the major system version number
|
||||
major = atoi(vers);
|
||||
// Extract the minor system version number
|
||||
p1 = strchr(vers, '.');
|
||||
minor = atoi(p1+1);
|
||||
}
|
||||
|
||||
if (major < toMajor) return -1;
|
||||
if (major > toMajor) return 1;
|
||||
// if (major == toMajor) compare minor version numbers
|
||||
if (minor < toMinor) return -1;
|
||||
if (minor > toMinor) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#define NOT_IN_TOKEN 0
|
||||
#define IN_SINGLE_QUOTED_TOKEN 1
|
||||
#define IN_DOUBLE_QUOTED_TOKEN 2
|
||||
|
@ -316,7 +438,7 @@ static int parse_posix_spawn_command_line(char* p, char** argv) {
|
|||
}
|
||||
|
||||
|
||||
int callPosixSpawn(const char *cmdline) {
|
||||
static int callPosixSpawn(const char *cmdline) {
|
||||
char command[1024];
|
||||
char progName[1024];
|
||||
char progPath[MAXPATHLEN];
|
||||
|
@ -386,8 +508,21 @@ int callPosixSpawn(const char *cmdline) {
|
|||
return result;
|
||||
}
|
||||
|
||||
#if CREATE_LOG
|
||||
void strip_cr(char *buf)
|
||||
{
|
||||
char *theCR;
|
||||
|
||||
void print_to_log_file(const char *format, ...) {
|
||||
theCR = strrchr(buf, '\n');
|
||||
if (theCR)
|
||||
*theCR = '\0';
|
||||
theCR = strrchr(buf, '\r');
|
||||
if (theCR)
|
||||
*theCR = '\0';
|
||||
}
|
||||
#endif // CREATE_LOG
|
||||
|
||||
static void print_to_log_file(const char *format, ...) {
|
||||
#if CREATE_LOG
|
||||
va_list args;
|
||||
char buf[256];
|
||||
|
@ -423,17 +558,3 @@ void print_to_log_file(const char *format, ...) {
|
|||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CREATE_LOG
|
||||
void strip_cr(char *buf)
|
||||
{
|
||||
char *theCR;
|
||||
|
||||
theCR = strrchr(buf, '\n');
|
||||
if (theCR)
|
||||
*theCR = '\0';
|
||||
theCR = strrchr(buf, '\r');
|
||||
if (theCR)
|
||||
*theCR = '\0';
|
||||
}
|
||||
#endif // CREATE_LOG
|
||||
|
|
|
@ -773,6 +773,11 @@ static OSStatus CleanupAllVisibleUsers(void)
|
|||
#endif
|
||||
DeleteLoginItemLaunchAgent(brandID, pw);
|
||||
}
|
||||
|
||||
if (compareOSVersionTo(13, 0) >= 0) {
|
||||
sprintf(s, "rm -f \"/Users/%s/Library/LaunchAgents/edu.berkeley.launchboincmanager.plist\"", pw->pw_name);
|
||||
callPosixSpawn (s);
|
||||
}
|
||||
|
||||
#if TESTING
|
||||
showDebugMsg("calling DeleteScreenSaverLaunchAgent for user %s, euid = %d\n",
|
||||
|
@ -1054,8 +1059,8 @@ Boolean DeleteLoginItemLaunchAgent(long brandID, passwd *pw)
|
|||
fflush(stdout);
|
||||
}
|
||||
|
||||
// Create a LaunchAgent for the specified user, replacing any LaunchAgent created
|
||||
// previously (such as by Installer or by installing a differently branded BOINC.)
|
||||
// Create a LaunchAgent to finish uninstall for the specified user, replacing any LaunchAgent
|
||||
// created previously (such as by Uninstaller or by installing a differently branded BOINC.)
|
||||
|
||||
// Create LaunchAgents directory for this user if it does not yet exist
|
||||
snprintf(s, sizeof(s), "/Users/%s/Library/LaunchAgents", pw->pw_name);
|
||||
|
|
Loading…
Reference in New Issue