mirror of https://github.com/BOINC/boinc.git
Mac installer: To avoid invalidating our code signing: use a metapackage instead of modifying the property list file to trigger a system restart when needed.
This commit is contained in:
parent
c518170452
commit
10576cbcbc
|
@ -40,6 +40,7 @@ int file_exists(const char* path);
|
|||
int FixInfoPlistFile(char* name);
|
||||
int FixInfoPlist_Strings(char* myPath, char* name);
|
||||
int MakeBOINCPackageInfoPlistFile(char* myPath, char* brand);
|
||||
int MakeBOINCRestartPackageInfoPlistFile(char* myPath, char* brand);
|
||||
int MakeMetaPackageInfoPlistFile(char* myPath, char* brand);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
@ -91,6 +92,9 @@ int main(int argc, char** argv) {
|
|||
err = MakeBOINCPackageInfoPlistFile("./Pkg-Info.plist", "BOINC Manager");
|
||||
if (err) retval = err;
|
||||
|
||||
err = MakeBOINCRestartPackageInfoPlistFile("./Pkg_Restart-Info.plist", "BOINC Manager");
|
||||
if (err) retval = err;
|
||||
|
||||
err = MakeMetaPackageInfoPlistFile("./Mpkg-Info.plist", "BOINC Manager");
|
||||
return retval;
|
||||
}
|
||||
|
@ -284,7 +288,7 @@ int MakeBOINCPackageInfoPlistFile(char* myPath, char* brand) {
|
|||
retval = fclose(f);
|
||||
}
|
||||
else {
|
||||
puts("Error creating file Pkg-Info.plist\n");
|
||||
printf("Error creating file %s\n", myPath);
|
||||
retval = -1;
|
||||
}
|
||||
|
||||
|
@ -292,6 +296,58 @@ int MakeBOINCPackageInfoPlistFile(char* myPath, char* brand) {
|
|||
}
|
||||
|
||||
|
||||
// Create a MetaPackage whcih runs only BOINC,pkg but specifies Restart Required
|
||||
int MakeBOINCRestartPackageInfoPlistFile(char* myPath, char* brand) {
|
||||
int retval = 0;
|
||||
FILE *f;
|
||||
|
||||
if (IsFileCurrent(myPath))
|
||||
return 0;
|
||||
|
||||
f = fopen(myPath, "w");
|
||||
if (f)
|
||||
{
|
||||
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<dict>\n");
|
||||
fprintf(f, "\t<key>CFBundleGetInfoString</key>\n");
|
||||
fprintf(f, "\t<string>%s %s</string>\n", brand, BOINC_VERSION_STRING);
|
||||
fprintf(f, "\t<key>CFBundleIdentifier</key>\n\t<string>edu.berkeley.boinc_r</string>\n");
|
||||
fprintf(f, "\t<key>CFBundleShortVersionString</key>\n");
|
||||
fprintf(f, "\t<string>%s</string>\n", BOINC_VERSION_STRING);
|
||||
fprintf(f, "\t<key>IFMajorVersion</key>\n\t<integer>%d</integer>\n", BOINC_MAJOR_VERSION);
|
||||
fprintf(f, "\t<key>IFMinorVersion</key>\n\t<integer>%d</integer>\n", BOINC_MINOR_VERSION);
|
||||
fprintf(f, "\t<key>IFPkgFlagAllowBackRev</key>\n\t<integer>1</integer>\n");
|
||||
fprintf(f, "\t<key>IFPkgFlagAuthorizationAction</key>\n\t<string>AdminAuthorization</string>\n");
|
||||
fprintf(f, "\t<key>IFPkgFlagRestartAction</key>\n\t<string>RequiredRestart</string>\n");
|
||||
fprintf(f, "\t<key>IFPkgFlagRootVolumeOnly</key>\n\t<integer>1</integer>\n");
|
||||
fprintf(f, "\t<key>IFPkgFlagComponentDirectory</key>\n\t<string>../</string>\n");
|
||||
|
||||
fprintf(f, "\t<key>IFPkgFlagPackageList</key>\n");
|
||||
|
||||
fprintf(f, "\t<array>\n");
|
||||
fprintf(f, "\t\t<dict>\n");
|
||||
fprintf(f, "\t\t\t<key>IFPkgFlagPackageLocation</key>\n\t\t\t<string>BOINC.pkg</string>\n");
|
||||
fprintf(f, "\t\t\t<key>IFPkgFlagPackageSelection</key>\n\t\t\t<string>required</string>\n");
|
||||
fprintf(f, "\t\t</dict>\n");
|
||||
fprintf(f, "\t</array>\n");
|
||||
|
||||
fprintf(f, "\t<key>IFPkgFormatVersion</key>\n\t<real>0.10000000149011612</real>\n");
|
||||
fprintf(f, "</dict>\n</plist>\n");
|
||||
|
||||
fflush(f);
|
||||
retval = fclose(f);
|
||||
}
|
||||
else {
|
||||
printf("Error creating file %s\n", myPath);
|
||||
retval = -1;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
// Make a MetaPackage to install both BOINC and VirtualBox
|
||||
int MakeMetaPackageInfoPlistFile(char* myPath, char* brand) {
|
||||
int retval = 0;
|
||||
FILE *f;
|
||||
|
@ -313,7 +369,9 @@ int MakeMetaPackageInfoPlistFile(char* myPath, char* brand) {
|
|||
fprintf(f, "\t<key>IFMajorVersion</key>\n\t<integer>%d</integer>\n", BOINC_MAJOR_VERSION);
|
||||
fprintf(f, "\t<key>IFMinorVersion</key>\n\t<integer>%d</integer>\n", BOINC_MINOR_VERSION);
|
||||
fprintf(f, "\t<key>IFPkgFlagAllowBackRev</key>\n\t<integer>1</integer>\n");
|
||||
fprintf(f, "\t<key>IFPkgFlagAuthorizationAction</key>\n\t<string>RootAuthorization</string>\n");
|
||||
fprintf(f, "\t<key>IFPkgFlagAuthorizationAction</key>\n\t<string>AdminAuthorization</string>\n");
|
||||
fprintf(f, "\t<key>IFPkgFlagRestartAction</key>\n\t<string>NoRestart</string>\n");
|
||||
fprintf(f, "\t<key>IFPkgFlagRootVolumeOnly</key>\n\t<integer>1</integer>\n");
|
||||
fprintf(f, "\t<key>IFPkgFlagComponentDirectory</key>\n\t<string>../</string>\n");
|
||||
|
||||
fprintf(f, "\t<key>IFPkgFlagPackageList</key>\n");
|
||||
|
@ -337,7 +395,7 @@ int MakeMetaPackageInfoPlistFile(char* myPath, char* brand) {
|
|||
retval = fclose(f);
|
||||
}
|
||||
else {
|
||||
puts("Error creating file Mpkg-Info.plist\n");
|
||||
printf("Error creating file %s\n", myPath);
|
||||
retval = -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
void Initialize(void); /* function prototypes */
|
||||
Boolean IsUserMemberOfGroup(const char *userName, const char *groupName);
|
||||
OSStatus GetFinalAction(CFStringRef *restartValue);
|
||||
Boolean IsRestartNeeded();
|
||||
OSErr FindProcess (OSType typeToFind, OSType creatorToFind, ProcessSerialNumberPtr processSN);
|
||||
static OSErr QuitAppleEventHandler(const AppleEvent *appleEvt, AppleEvent* reply, UInt32 refcon);
|
||||
void print_to_log_file(const char *format, ...);
|
||||
|
@ -52,14 +52,17 @@ void strip_cr(char *buf);
|
|||
|
||||
Boolean gQuitFlag = false; /* global */
|
||||
|
||||
#if 0
|
||||
CFStringRef valueRestartRequired = CFSTR("RequiredRestart");
|
||||
CFStringRef valueLogoutRequired = CFSTR("RequiredLogout");
|
||||
CFStringRef valueNoRestart = CFSTR("NoRestart");
|
||||
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char pkgPath[MAXPATHLEN], infoPlistPath[MAXPATHLEN], MetaPkgPath[MAXPATHLEN];
|
||||
char pkgPath[MAXPATHLEN], pkgRestartPath[MAXPATHLEN];
|
||||
char infoPlistPath[MAXPATHLEN];
|
||||
char MetaPkgPath[MAXPATHLEN], MetaPkgRestartPath[MAXPATHLEN];
|
||||
char brand[64], s[256];
|
||||
char *p;
|
||||
ProcessSerialNumber ourPSN, installerPSN;
|
||||
|
@ -67,17 +70,10 @@ int main(int argc, char *argv[])
|
|||
long response;
|
||||
short itemHit;
|
||||
pid_t installerPID = 0;
|
||||
FSRef infoPlistFileRef;
|
||||
Boolean isDirectory, result;
|
||||
CFURLRef xmlURL = NULL;
|
||||
CFDataRef xmlDataIn = NULL;
|
||||
CFDataRef xmlDataOut = NULL;
|
||||
CFPropertyListRef propertyListRef = NULL;
|
||||
CFStringRef restartKey = CFSTR("IFPkgFlagRestartAction");
|
||||
CFStringRef currentValue = NULL, desiredValue = NULL;
|
||||
CFStringRef errorString = NULL;
|
||||
OSStatus err = noErr;
|
||||
struct stat stat_buf;
|
||||
Boolean restartNeeded = true;
|
||||
FILE *restartNeededFile;
|
||||
|
||||
Initialize();
|
||||
|
||||
|
@ -109,6 +105,13 @@ int main(int argc, char *argv[])
|
|||
|
||||
strlcpy(MetaPkgPath, pkgPath, sizeof(MetaPkgPath));
|
||||
strlcat(MetaPkgPath, "+VirtualBox.mpkg", sizeof(MetaPkgPath));
|
||||
|
||||
strlcpy(MetaPkgRestartPath, pkgPath, sizeof(MetaPkgRestartPath));
|
||||
strlcat(MetaPkgRestartPath, "+VirtualBox .mpkg", sizeof(MetaPkgRestartPath));
|
||||
|
||||
strlcpy(pkgRestartPath, pkgPath, sizeof(MetaPkgPath));
|
||||
strlcat(pkgRestartPath, ".mpkg", sizeof(pkgPath));
|
||||
|
||||
strlcat(pkgPath, ".pkg", sizeof(pkgPath));
|
||||
err = Gestalt(gestaltSystemVersion, &response);
|
||||
if (err != noErr)
|
||||
|
@ -132,78 +135,29 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
// Remove previous installer package receipt so we can run installer again
|
||||
// (affects only older versions of OS X and fixes a bug in those versions)
|
||||
// "rm -rf /Library/Receipts/GridRepublic.pkg"
|
||||
sprintf(s, "rm -rf \"/Library/Receipts/%s.pkg\"", brand);
|
||||
system (s);
|
||||
|
||||
restartNeeded = IsRestartNeeded();
|
||||
|
||||
// Write a temp file to tell our PostInstall.app whether restart is needed
|
||||
restartNeededFile = fopen("/tmp/BOINC_restart_flag", "w");
|
||||
if (restartNeededFile) {
|
||||
fputs(restartNeeded ? "1\n" : "0\n", restartNeededFile);
|
||||
fclose(restartNeededFile);
|
||||
}
|
||||
|
||||
err = Gestalt(gestaltSystemVersion, &response);
|
||||
if (err != noErr)
|
||||
return err;
|
||||
|
||||
err = GetFinalAction(&desiredValue);
|
||||
|
||||
strlcpy(infoPlistPath, pkgPath, sizeof(infoPlistPath));
|
||||
strlcat(infoPlistPath, "/Contents/Info.plist", sizeof(infoPlistPath));
|
||||
|
||||
err = FSPathMakeRef((UInt8*)infoPlistPath, &infoPlistFileRef, &isDirectory);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
xmlURL = CFURLCreateFromFSRef(NULL, &infoPlistFileRef);
|
||||
if (xmlURL == NULL)
|
||||
return -1;
|
||||
|
||||
// Read XML Data from file
|
||||
result = CFURLCreateDataAndPropertiesFromResource(NULL, xmlURL, &xmlDataIn, NULL, NULL, &err);
|
||||
if (err == noErr)
|
||||
if (!result)
|
||||
err = coreFoundationUnknownErr;
|
||||
|
||||
if (err == noErr) { // Convert XML Data to internal CFPropertyListRef / CFDictionaryRef format
|
||||
propertyListRef = CFPropertyListCreateFromXMLData(NULL, xmlDataIn, kCFPropertyListMutableContainersAndLeaves, &errorString);
|
||||
if (propertyListRef == NULL)
|
||||
err = coreFoundationUnknownErr;
|
||||
}
|
||||
|
||||
if (err == noErr) { // Get current value for our key
|
||||
currentValue = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)propertyListRef, restartKey);
|
||||
if (currentValue == NULL)
|
||||
err = coreFoundationUnknownErr;
|
||||
}
|
||||
|
||||
if (err == noErr) {
|
||||
if (CFStringCompare(currentValue, desiredValue, 0) != kCFCompareEqualTo) { // If current value != desired value
|
||||
// Replace value for key with desired value
|
||||
CFDictionaryReplaceValue((CFMutableDictionaryRef)propertyListRef, restartKey, desiredValue);
|
||||
|
||||
// Convert internal CFPropertyListRef / CFDictionaryRef format to XML data
|
||||
xmlDataOut = CFPropertyListCreateXMLData(NULL, propertyListRef);
|
||||
if (xmlDataOut == NULL)
|
||||
err = coreFoundationUnknownErr;
|
||||
|
||||
if (err == noErr) { // Write revised XML Data back to the file
|
||||
result = CFURLWriteDataAndPropertiesToResource (xmlURL, xmlDataOut, NULL, &err);
|
||||
if (err == noErr)
|
||||
if (!result)
|
||||
err = coreFoundationUnknownErr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (xmlURL)
|
||||
CFRelease(xmlURL);
|
||||
if (xmlDataIn)
|
||||
CFRelease(xmlDataIn);
|
||||
if (xmlDataOut)
|
||||
CFRelease(xmlDataOut);
|
||||
if (propertyListRef)
|
||||
CFRelease(propertyListRef);
|
||||
|
||||
if (err == noErr) {
|
||||
if ((response < 0x1050) || stat(MetaPkgPath, &stat_buf)) { // stat() returns zero on success
|
||||
sprintf(infoPlistPath, "open \"%s\" &", pkgPath);
|
||||
sprintf(infoPlistPath, "open \"%s\" &", restartNeeded ? pkgRestartPath : pkgPath);
|
||||
} else {
|
||||
sprintf(infoPlistPath, "open \"%s\" &", MetaPkgPath);
|
||||
sprintf(infoPlistPath, "open \"%s\" &", restartNeeded ? MetaPkgRestartPath : MetaPkgPath);
|
||||
}
|
||||
system(infoPlistPath);
|
||||
}
|
||||
|
@ -234,7 +188,7 @@ Boolean IsUserMemberOfGroup(const char *userName, const char *groupName) {
|
|||
}
|
||||
|
||||
|
||||
OSStatus GetFinalAction(CFStringRef *restartValue)
|
||||
Boolean IsRestartNeeded()
|
||||
{
|
||||
passwd *pw = NULL;
|
||||
group *grp = NULL;
|
||||
|
@ -244,61 +198,58 @@ OSStatus GetFinalAction(CFStringRef *restartValue)
|
|||
long response;
|
||||
char loginName[256];
|
||||
|
||||
*restartValue = valueRestartRequired;
|
||||
|
||||
grp = getgrnam(boinc_master_group_name);
|
||||
if (grp == NULL)
|
||||
return noErr; // Group boinc_master does not exist
|
||||
return true; // Group boinc_master does not exist
|
||||
|
||||
boinc_master_gid = grp->gr_gid;
|
||||
|
||||
grp = getgrnam(boinc_project_group_name);
|
||||
if (grp == NULL)
|
||||
return noErr; // Group boinc_project does not exist
|
||||
return true; // Group boinc_project does not exist
|
||||
|
||||
boinc_project_gid = grp->gr_gid;
|
||||
|
||||
pw = getpwnam(boinc_master_user_name);
|
||||
if (pw == NULL)
|
||||
return noErr; // User boinc_master does not exist
|
||||
return true; // User boinc_master does not exist
|
||||
|
||||
boinc_master_uid = pw->pw_uid;
|
||||
|
||||
if (pw->pw_gid != boinc_master_gid)
|
||||
return noErr; // User boinc_master does not have group boinc_master as its primary group
|
||||
return true; // User boinc_master does not have group boinc_master as its primary group
|
||||
|
||||
pw = getpwnam(boinc_project_user_name);
|
||||
if (pw == NULL)
|
||||
return noErr; // User boinc_project does not exist
|
||||
return true; // User boinc_project does not exist
|
||||
|
||||
boinc_project_uid = pw->pw_uid;
|
||||
|
||||
if (pw->pw_gid != boinc_project_gid)
|
||||
return noErr; // User boinc_project does not have group boinc_project as its primary group
|
||||
return true; // User boinc_project does not have group boinc_project as its primary group
|
||||
|
||||
err = Gestalt(gestaltSystemVersion, &response);
|
||||
if ((err == noErr) && (response >= 0x1050)) {
|
||||
if (boinc_master_gid < 501)
|
||||
return noErr; // We will change boinc_master_gid to a value > 501
|
||||
return true; // We will change boinc_master_gid to a value > 501
|
||||
if (boinc_project_gid < 501)
|
||||
return noErr; // We will change boinc_project_gid to a value > 501
|
||||
return true; // We will change boinc_project_gid to a value > 501
|
||||
if (boinc_master_uid < 501)
|
||||
return noErr; // We will change boinc_master_uid to a value > 501
|
||||
return true; // We will change boinc_master_uid to a value > 501
|
||||
if (boinc_project_uid < 501)
|
||||
return noErr; // We will change boinc_project_uid to a value > 501
|
||||
return true; // We will change boinc_project_uid to a value > 501
|
||||
}
|
||||
|
||||
#ifdef SANDBOX
|
||||
strncpy(loginName, getenv("USER"), sizeof(loginName)-1);
|
||||
if (loginName[0]) {
|
||||
if (IsUserMemberOfGroup(loginName, boinc_master_group_name)) {
|
||||
*restartValue = valueNoRestart;
|
||||
return noErr; // Logged in user is already a member of group boinc_master
|
||||
return false; // Logged in user is already a member of group boinc_master
|
||||
}
|
||||
}
|
||||
#endif // SANDBOX
|
||||
|
||||
return noErr;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ void Initialize(void); /* function prototypes */
|
|||
Boolean myFilterProc(DialogRef theDialog, EventRecord *theEvent, DialogItemIndex *itemHit);
|
||||
int DeleteReceipt(void);
|
||||
OSStatus CheckLogoutRequirement(int *finalAction);
|
||||
Boolean IsRestartNeeded();
|
||||
void CheckUserAndGroupConflicts();
|
||||
Boolean SetLoginItemOSAScript(long brandID, Boolean deleteLogInItem, char *userName);
|
||||
Boolean SetLoginItemAPI(long brandID, Boolean deleteLogInItem);
|
||||
|
@ -424,14 +425,14 @@ int main(int argc, char *argv[])
|
|||
pid_t waitPermissionsPID = 0;
|
||||
uid_t saved_euid, saved_uid, b_m_uid;
|
||||
passwd *pw;
|
||||
int finalInstallAction;
|
||||
Boolean restartNeeded;
|
||||
DialogRef theWin;
|
||||
|
||||
err = CheckLogoutRequirement(&finalInstallAction);
|
||||
printf("CheckLogoutRequirement returned %d\n", finalInstallAction);
|
||||
restartNeeded = IsRestartNeeded();
|
||||
printf("IsRestartNeeded() returned %d\n", (int)restartNeeded);
|
||||
fflush(stdout);
|
||||
|
||||
if (finalInstallAction == launchWhenDone) {
|
||||
if (!restartNeeded) {
|
||||
|
||||
// Wait for BOINC's RPC socket address to become available to user boinc_master, in
|
||||
// case we are upgrading from a version which did not run as user boinc_master.
|
||||
|
@ -536,7 +537,7 @@ int DeleteReceipt()
|
|||
int i;
|
||||
pid_t installerPID = 0;
|
||||
OSStatus err;
|
||||
int finalInstallAction;
|
||||
Boolean restartNeeded = true;
|
||||
FSRef fileRef;
|
||||
char s[256];
|
||||
struct stat sbuf;
|
||||
|
@ -544,8 +545,8 @@ int DeleteReceipt()
|
|||
|
||||
Initialize();
|
||||
|
||||
err = CheckLogoutRequirement(&finalInstallAction);
|
||||
// print_to_log_file("CheckLogoutRequirement returned %d\n", finalInstallAction);
|
||||
restartNeeded = IsRestartNeeded();
|
||||
// print_to_log_file("IsRestartNeeded() returned %d\n", (int)restartNeeded);
|
||||
|
||||
brandID = GetBrandID();
|
||||
|
||||
|
@ -556,7 +557,7 @@ int DeleteReceipt()
|
|||
|
||||
// err_fsref = FSPathMakeRef((StringPtr)"/Applications/GridRepublic Desktop.app", &fileRef, NULL);
|
||||
err_fsref = FSPathMakeRef((StringPtr)appPath[brandID], &fileRef, NULL);
|
||||
if (finalInstallAction == launchWhenDone) {
|
||||
if (!restartNeeded) {
|
||||
|
||||
err = FindProcess ('APPL', 'xins', &installerPSN);
|
||||
if (err == noErr) {
|
||||
|
@ -586,6 +587,21 @@ int DeleteReceipt()
|
|||
}
|
||||
|
||||
|
||||
// BOINC Installer.app wrote a file to tell us whether a restart is required
|
||||
Boolean IsRestartNeeded() {
|
||||
FILE *restartNeededFile;
|
||||
int value;
|
||||
|
||||
restartNeededFile = fopen("/tmp/BOINC_restart_flag", "r");
|
||||
if (restartNeededFile) {
|
||||
fscanf(restartNeededFile,"%d", &value);
|
||||
fclose(restartNeededFile);
|
||||
return (value != 0);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
OSStatus CheckLogoutRequirement(int *finalAction)
|
||||
{
|
||||
*finalAction = restartRequired;
|
||||
|
|
|
@ -275,6 +275,19 @@ if [ ! -d ../BOINC_Installer/New_Release_$1_$2_$3/boinc_$1.$2.$3_macOSX_$arch/BO
|
|||
fi
|
||||
cp -fp mac_installer/Description.plist ../BOINC_Installer/New_Release_$1_$2_$3/boinc_$1.$2.$3_macOSX_$arch/BOINC\ Installer.app/Contents/Resources/BOINC.pkg/Contents/Resources/en.lproj/
|
||||
|
||||
# Build the "BOINC.mpkg" metapackage (used if installer.app determines
|
||||
# that we need user to restart OS X after installation)
|
||||
mkdir -p "../BOINC_Installer/New_Release_$1_$2_$3/boinc_$1.$2.$3_macOSX_$arch/BOINC Installer.app/Contents/Resources/BOINC.mpkg/Contents/Resources"
|
||||
cp -fp mac_build/Pkg_Restart-Info.plist ../BOINC_Installer/New_Release_$1_$2_$3/boinc_$1.$2.$3_macOSX_$arch/BOINC\ Installer.app/Contents/Resources/BOINC.mpkg/Contents/Info.plist
|
||||
cp -fp mac_installer/License.rtf ../BOINC_Installer/New_Release_$1_$2_$3/boinc_$1.$2.$3_macOSX_$arch/BOINC\ Installer.app/Contents/Resources/BOINC.mpkg/Contents/Resources/
|
||||
cp -fp ../BOINC_Installer/Installer\ Resources/ReadMe.rtf ../BOINC_Installer/New_Release_$1_$2_$3/boinc_$1.$2.$3_macOSX_$arch/BOINC\ Installer.app/Contents/Resources/BOINC.mpkg/Contents/Resources/
|
||||
cat >> ../BOINC_Installer/New_Release_$1_$2_$3/boinc_$1.$2.$3_macOSX_$arch/BOINC\ Installer.app/Contents/Resources/BOINC.mpkg/Contents/Resources/package_version << ENDOFFILE
|
||||
major: $1
|
||||
minor: $2
|
||||
ENDOFFILE
|
||||
echo "pmkrpkg1" > ../BOINC_Installer/New_Release_$1_$2_$3/boinc_$1.$2.$3_macOSX_$arch/BOINC\ Installer.app/Contents/Resources/BOINC.mpkg/Contents/PkgInfo
|
||||
|
||||
|
||||
# Build the BOINC+VirtualBox.mpkg metapackage if VirtualBox.pkg exists
|
||||
|
||||
VirtualBoxPackageName="VirtualBox.pkg"
|
||||
|
@ -290,6 +303,12 @@ ENDOFFILE
|
|||
echo "pmkrpkg1" > ../BOINC_Installer/New_Release_$1_$2_$3/boinc_$1.$2.$3_macOSX_$arch/BOINC\ Installer.app/Contents/Resources/BOINC+VirtualBox.mpkg/Contents/PkgInfo
|
||||
|
||||
cp -fpR mac_installer/${VirtualBoxPackageName} ../BOINC_Installer/New_Release_$1_$2_$3/boinc_$1.$2.$3_macOSX_$arch/BOINC\ Installer.app/Contents/Resources/
|
||||
|
||||
# Now create the "BOINC+VirtualBox .mpkg" metapackage (used if installer.app
|
||||
# determines that we need user to restart OS X after installation)
|
||||
cp -fpR "../BOINC_Installer/New_Release_$1_$2_$3/boinc_$1.$2.$3_macOSX_$arch/BOINC Installer.app/Contents/Resources/BOINC+VirtualBox.mpkg" "../BOINC_Installer/New_Release_$1_$2_$3/boinc_$1.$2.$3_macOSX_$arch/BOINC Installer.app/Contents/Resources/BOINC+VirtualBox .mpkg"
|
||||
# Change "NoRestart" to "RequiredRestart" in BOINC+VirtualBox .mpkg
|
||||
sed -i "" s/"NoRestart"/"RequiredRestart"/g "../BOINC_Installer/New_Release_$1_$2_$3/boinc_$1.$2.$3_macOSX_$arch/BOINC Installer.app/Contents/Resources/BOINC+VirtualBox .mpkg/Contents/Info.plist"
|
||||
fi
|
||||
|
||||
# Build the stand-alone client distribution
|
||||
|
|
Loading…
Reference in New Issue