From 30d03105b3da93cd00d50d1c340e28c020de63ef Mon Sep 17 00:00:00 2001 From: Charlie Fenton Date: Sat, 19 May 2007 11:56:01 +0000 Subject: [PATCH] Mac installer: if installer package includes a custom skin, set preferences of all users to that skin. svn path=/trunk/boinc/; revision=12696 --- checkin_notes | 7 +++ mac_installer/PostInstall.cpp | 90 ++++++++++++++++++++++++++++++++++- 2 files changed, 95 insertions(+), 2 deletions(-) diff --git a/checkin_notes b/checkin_notes index 4230698af8..f8097031e5 100755 --- a/checkin_notes +++ b/checkin_notes @@ -5069,3 +5069,10 @@ David 18 May 2007 html/ops/ job_times.php + +Charlie 19 May 2007 + - Mac installer: if installer package includes a custom skin, set + preferences of all users to that skin. + + mac_installer/ + PostInstall.cpp diff --git a/mac_installer/PostInstall.cpp b/mac_installer/PostInstall.cpp index 6decd782da..a588fe04eb 100755 --- a/mac_installer/PostInstall.cpp +++ b/mac_installer/PostInstall.cpp @@ -27,6 +27,7 @@ #include // getlogin #include // getpwname, getpwuid, getuid #include // getpwname, getpwuid, getuid +#include // getgrnam #include // waitpid #include #include // for MAXPATHLEN @@ -51,6 +52,7 @@ long GetBrandID(void); int TestRPCBind(void); OSErr FindProcess (OSType typeToFind, OSType creatorToFind, ProcessSerialNumberPtr processSN); pid_t FindProcessPID(char* name, pid_t thePID); +int FindSkinName(char *name, size_t len); static OSErr QuitBOINCManager(OSType signature); static OSErr QuitAppleEventHandler(const AppleEvent *appleEvt, AppleEvent* reply, UInt32 refcon); void print_to_log_file(const char *format, ...); @@ -484,6 +486,7 @@ void SetUIDBackToUser (void) // Find all visible users and set their login item to launch BOINC Manager. // If user is a member of group admin, add user to groups boinc_master and boinc_project. +// If our install package included a skin, set all user's preferences to use that skin, OSErr UpdateAllVisibleUsers(long brandID) { DIR *dirp; @@ -491,11 +494,17 @@ OSErr UpdateAllVisibleUsers(long brandID) passwd *pw; uid_t saved_uid; Boolean deleteLoginItem; + char skinName[256]; + FILE *oldPrefs, *newPrefs; + char oldFileName[MAXPATHLEN], tempFilename[MAXPATHLEN]; + char buf[1024]; + int wroteSkinName; + struct stat sbuf; + group *grp; + OSStatus err, statErr; #ifdef SANDBOX char *p; - group *grp; short i; - OSErr err = noErr; grp = getgrnam("admin"); if (grp == NULL) { // Should never happen @@ -504,6 +513,8 @@ OSErr UpdateAllVisibleUsers(long brandID) } #endif + FindSkinName(skinName, sizeof(skinName)); + dirp = opendir("/Users"); if (dirp == NULL) { // Should never happen puts("opendir(\"/Users\") failed\n"); @@ -540,6 +551,46 @@ OSErr UpdateAllVisibleUsers(long brandID) saved_uid = geteuid(); seteuid(pw->pw_uid); // Temporarily set effective uid to this user SetLoginItem(brandID, deleteLoginItem); // Set login item for this user + + if (skinName[0]) { + sprintf(oldFileName, "/Users/%s/Library/Preferences/BOINC Manager Preferences", dp->d_name); + sprintf(tempFilename, "/Users/%s/Library/Preferences/BOINC Manager NewPrefs", dp->d_name); + newPrefs = fopen(tempFilename, "w"); + if (newPrefs) { + wroteSkinName = 0; + statErr = stat(oldFileName, &sbuf); + + oldPrefs = fopen(oldFileName, "r"); + if (oldPrefs) { + while (fgets(buf, sizeof(buf), oldPrefs)) { + if (strstr(buf, "Skin=")) { + fprintf(newPrefs, "Skin=%s\n", skinName); + wroteSkinName = 1; + } else { + fputs(buf, newPrefs); + } + } + fclose(oldPrefs); + } + + if (! wroteSkinName) + fprintf(newPrefs, "Skin=%s\n", skinName); + + fclose(newPrefs); + rename(tempFilename, oldFileName); // Deletes old file + if (! statErr) { + chown(oldFileName, sbuf.st_uid, sbuf.st_gid); + chmod(oldFileName, sbuf.st_mode); + } else { + chmod(oldFileName, 0664); + pw = getpwnam(dp->d_name); + grp = getgrnam(dp->d_name); + if (pw && grp) + chown(oldFileName, pw->pw_uid, grp->gr_gid); + } + } + } + seteuid(saved_uid); // Set effective uid back to privileged user } @@ -656,6 +707,41 @@ static char * PersistentFGets(char *buf, size_t buflen, FILE *f) { } +int FindSkinName(char *name, size_t len) +{ + FILE *f; + char buf[MAXPATHLEN]; + char *pattern = "/BOINC Data/skins/"; + char *p, *q; + + name[0] = '\0'; + + f = popen("lsbom -ds ./Contents/Archive.bom", "r"); + if (f == NULL) + return 0; + + while (PersistentFGets(buf, sizeof(buf), f)) { + p = strstr(buf, pattern); + if (p) { + p += strlen(pattern); + q = strchr(p, '/'); + if (q) *q = 0; + q = strchr(p, '\n'); + if (q) *q = 0; + + if (strlen(p) > (len-1)) + return 0; + strlcpy(name, p, len); + pclose(f); + return 1; + } + } + pclose(f); + return 0; +} + + + pid_t FindProcessPID(char* name, pid_t thePID) { FILE *f;