// This file is part of BOINC. // http://boinc.berkeley.edu // Copyright (C) 2018 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 // as published by the Free Software Foundation, // either version 3 of the License, or (at your option) any later version. // // BOINC is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with BOINC. If not, see . // // main.cpp // boinc_Finish_Install // Usage: boinc_Finish_Install [-d] [appName] // // * Deletes Login Items of all possible branded and unbranded BOINC Managers for current user. // * If first argument is -d then also kills the application specified by the second argument. // * If first argument is the name of a branded or unbranded BOINC Manager, adds it as a Login // Item for the current user and launches it. // // TODO: Do we ned to code sign this app? // #define VERBOSE_TEST 0 /* for debugging callPosixSpawn */ #if VERBOSE_TEST #define CREATE_LOG 1 /* for debugging */ #else #define CREATE_LOG 0 /* for debugging */ #endif #define USE_SPECIAL_LOG_FILE 1 #include #include #include #include // waitpid #include // for MAXPATHLEN #include #include #include #include #include #include #include // getpwname, getpwuid, getuid #include #include "mac_branding.h" int callPosixSpawn(const char *cmd); long GetBrandID(char *path); static void FixLaunchServicesDataBase(void); 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); int main(int argc, const char * argv[]) { int i, err; char cmd[2048]; char *userName; passwd *pw; // Wait until we are the active login (in case of fast user switching) userName = getlogin(); while (!IsUserActive(userName)) { sleep(1); } for (i=0; ipw_name); 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, Noitifications may display the icon for the wrong // branding, due to the Launch Services database having one of the // other copies of BOINC Manager as the first entry. Each user has // their own copy of the Launch Services database, so this must be // done for each user. // // This probably will happen only on BOINC development systems where // Xcode has generated copies of BOINC Manager. static void FixLaunchServicesDataBase() { long brandID = 0; 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); for (i=0; i(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