Mac installer: if installer package includes a custom skin, set preferences of all users to that skin.

svn path=/trunk/boinc/; revision=12696
This commit is contained in:
Charlie Fenton 2007-05-19 11:56:01 +00:00
parent d09ece4105
commit 30d03105b3
2 changed files with 95 additions and 2 deletions

View File

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

View File

@ -27,6 +27,7 @@
#include <unistd.h> // getlogin
#include <sys/types.h> // getpwname, getpwuid, getuid
#include <pwd.h> // getpwname, getpwuid, getuid
#include <grp.h> // getgrnam
#include <sys/wait.h> // waitpid
#include <dirent.h>
#include <sys/param.h> // 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;