// 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