diff options
author | Guy Harris <guy@alum.mit.edu> | 2015-05-22 18:34:38 -0700 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2015-05-23 01:37:06 +0000 |
commit | 11f2e869e49fe89e132e44a8006e499d6d5fdd0a (patch) | |
tree | 15245708fc26a25129f47a6af5b756a769514a71 /packaging | |
parent | 51f7a9aef3b4d6b33e84a6042b305baf4e3fa90d (diff) | |
download | wireshark-11f2e869e49fe89e132e44a8006e499d6d5fdd0a.tar.gz |
Have Wireshark.app try to fix broken XQuartz installations.
If the user had a pre-Yosemite system with XQuartz installed, and
upgraded to Yosemite, the Yosemite installer will have removed the
/usr/X11 symlink. If we have /opt/X11 but not /usr/X11, ask the user if
we should fix the XQuartz installation and, if they say to do so, run a
little helper as root in order to re-install the symlink.
Bug: 10640
Change-Id: I0495bd60b7c913ad04eb4ef62817dc39bcebefe7
Reviewed-on: https://code.wireshark.org/review/8595
Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'packaging')
-rw-r--r-- | packaging/macosx/Resources/XQuartzFixer.c | 17 | ||||
-rw-r--r-- | packaging/macosx/ScriptExec/ScriptExec.xcodeproj/project.pbxproj | 4 | ||||
-rw-r--r-- | packaging/macosx/ScriptExec/main.c | 107 | ||||
-rwxr-xr-x | packaging/macosx/osx-app.sh | 2 |
4 files changed, 126 insertions, 4 deletions
diff --git a/packaging/macosx/Resources/XQuartzFixer.c b/packaging/macosx/Resources/XQuartzFixer.c new file mode 100644 index 0000000000..5c82b62d20 --- /dev/null +++ b/packaging/macosx/Resources/XQuartzFixer.c @@ -0,0 +1,17 @@ +#include <unistd.h> + +/* + * Very simple program, which is run with root privileges. + * All it does is attempt to symlink /usr/X11 to /opt/X11, in order + * to fix an XQuartz installation that's been damaged by an OS X + * installer on an OS upgrade (the Yosemite installer does that). + */ +static const char opt_x11[] = "/opt/X11"; +static const char usr_x11[] = "/usr/X11"; + +int +main(void) +{ + (void) symlink(opt_x11, usr_x11); + return 0; +} diff --git a/packaging/macosx/ScriptExec/ScriptExec.xcodeproj/project.pbxproj b/packaging/macosx/ScriptExec/ScriptExec.xcodeproj/project.pbxproj index bcb54fe658..f0150aa843 100644 --- a/packaging/macosx/ScriptExec/ScriptExec.xcodeproj/project.pbxproj +++ b/packaging/macosx/ScriptExec/ScriptExec.xcodeproj/project.pbxproj @@ -16,6 +16,7 @@ B8DCE045056DAC3500C390B0 /* MenuBar.nib in Resources */ = {isa = PBXBuildFile; fileRef = B8DCE042056DAC3500C390B0 /* MenuBar.nib */; }; B8DCE049056DAC5000C390B0 /* script in Resources */ = {isa = PBXBuildFile; fileRef = B8DCE048056DAC5000C390B0 /* script */; }; B8DCE04F056DACAE00C390B0 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B8DCE04E056DACAE00C390B0 /* Security.framework */; }; + EB3FA3601B10087D009BA8CB /* ServiceManagement.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EB3FA35F1B10087D009BA8CB /* ServiceManagement.framework */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -32,6 +33,7 @@ B8DCE042056DAC3500C390B0 /* MenuBar.nib */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; path = MenuBar.nib; sourceTree = "<group>"; }; B8DCE048056DAC5000C390B0 /* script */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.sh; path = script; sourceTree = "<group>"; }; B8DCE04E056DACAE00C390B0 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = /System/Library/Frameworks/Security.framework; sourceTree = "<absolute>"; }; + EB3FA35F1B10087D009BA8CB /* ServiceManagement.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ServiceManagement.framework; path = ../../../../../../../../System/Library/Frameworks/ServiceManagement.framework; sourceTree = "<group>"; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -42,6 +44,7 @@ 8D0C4E920486CD37000505A6 /* Carbon.framework in Frameworks */, 8D0C4E930486CD37000505A6 /* libstdc++.a in Frameworks */, B8DCE04F056DACAE00C390B0 /* Security.framework in Frameworks */, + EB3FA3601B10087D009BA8CB /* ServiceManagement.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -91,6 +94,7 @@ 20286C32FDCF999611CA2CEA /* External Frameworks and Libraries */ = { isa = PBXGroup; children = ( + EB3FA35F1B10087D009BA8CB /* ServiceManagement.framework */, 20286C33FDCF999611CA2CEA /* Carbon.framework */, 4A9504CAFFE6A41611CA0CBA /* CoreServices.framework */, 4A9504C8FFE6A3BC11CA0CBA /* ApplicationServices.framework */, diff --git a/packaging/macosx/ScriptExec/main.c b/packaging/macosx/ScriptExec/main.c index 3c0612b05e..171477d3a9 100644 --- a/packaging/macosx/ScriptExec/main.c +++ b/packaging/macosx/ScriptExec/main.c @@ -52,6 +52,8 @@ #include <Security/Authorization.h> #include <Security/AuthorizationTags.h> +#include <ServiceManagement/ServiceManagement.h> + // Unix stuff #include <sys/param.h> #include <string.h> @@ -73,6 +75,7 @@ // names of files bundled with app #define kScriptFileName "script" #define kOpenDocFileName "openDoc" +#define kXQuartzFixerFileName CFSTR("XQuartzFixer") // custom carbon event class #define kEventClassRedFatalAlert 911 @@ -96,6 +99,7 @@ static OSErr ExecuteScript(char *script, pid_t *pid); static void GetParameters(void); static unsigned char* GetScript(void); static unsigned char* GetOpenDoc(void); +static CFStringRef GetXQuartzFixer(void); OSErr LoadMenuBar(char *appName); @@ -201,12 +205,14 @@ int main(int argc, char* argv[]) // No. Is /usr/X11 a directory? if (lstat("/usr/X11", &statb_usr_x11) != -1 && S_ISDIR(statb_opt_x11.st_mode)) { - // It's a directory; assume it contains the stub libraries. - x11_type = XQUARTZ_STUB; - } else { + // It's a directory; assume it contains the stub libraries. + x11_type = XQUARTZ_STUB; +fprintf(stderr, "XQuartz stub\n"); + } else { // It's not a directory; assume we need X11 installed. x11_type = NO_X11; - } +fprintf(stderr, "No X11\n"); + } } else { // Yes. Is /usr/X11 a symbolic link to /opt/X11? if (lstat("/usr/X11", &statb_usr_x11) != -1 && @@ -216,20 +222,24 @@ int main(int argc, char* argv[]) if (link_length == -1) { // Couldn't read it; broken X11 x11_type = BROKEN_XQUARTZ; +fprintf(stderr, "Broken XQuartz\n"); } else { // Read it; nul-terminate the string symlink_target[link_length] = '\0'; if (strcmp(symlink_target, "/opt/X11") == 0) { // Yes, it points to /opt/X11, so that's good x11_type = XQUARTZ; +fprintf(stderr, "XQuartz\n"); } else { // No, it doesn't - broken x11_type = BROKEN_XQUARTZ; +fprintf(stderr, "Broken XQuartz\n"); } } } else { // Non-existent or not a symlink x11_type = BROKEN_XQUARTZ; +fprintf(stderr, "Broken XQuartz\n"); } } } else { @@ -237,9 +247,11 @@ int main(int argc, char* argv[]) if (lstat("/usr/X11", &statb_usr_x11) == -1) { // No /usr/X11; tell the user to install X11 x11_type = NO_X11; +fprintf(stderr, "No X11\n"); } else { // Assume it's OK x11_type = BUNDLED_X11; +fprintf(stderr, "Bundled X11\n"); } } @@ -276,6 +288,70 @@ int main(int argc, char* argv[]) GetParameters(); //load data from files containing exec settings + /* + * If we have a broken XQuartz installation, offer the user + * the choice to repair it, by re-planting the /usr/X11 symlink. + */ + if (x11_type == BROKEN_XQUARTZ) { + SInt16 itemHit; + AlertStdAlertParamRec params; + + params.movable = true; + params.helpButton = false; + params.filterProc = NULL; + params.defaultText = "\pYes, please repair it"; + params.cancelText = "\pNo, don't repair it"; + params.otherText = NULL; + params.defaultButton = kAlertStdAlertOKButton; + params.cancelButton = kAlertStdAlertCancelButton; + params.position = kWindowDefaultPosition; + + StandardAlert(kAlertNoteAlert, "\pYour XQuartz installation appears to be damaged. Would you like it to be repaired?", + "\pWireshark will not be able to work if it is not repaired.", + ¶ms, &itemHit); + + if (itemHit == kAlertStdAlertOKButton) { + CFStringRef job_label = CFSTR("org.wireshark.fixXQuartz"); + AuthorizationItem authItem = { kSMRightBlessPrivilegedHelper, 0, NULL, 0 }; + AuthorizationRights authRights = { 1, &authItem }; + AuthorizationFlags flags = kAuthorizationFlagInteractionAllowed | kAuthorizationFlagPreAuthorize | kAuthorizationFlagExtendRights; + AuthorizationRef auth; + const void *keys[3] = { + CFSTR("Label"), + CFSTR("RunAtLoad"), + CFSTR("Program") + }; + const void *values[3]; + CFDictionaryRef dict; + CFErrorRef error; + + if (AuthorizationCreate(&authRights, + kAuthorizationEmptyEnvironment, flags, &auth) == errAuthorizationSuccess) { + (void) SMJobRemove(kSMDomainSystemLaunchd, job_label, auth, false, NULL); + + values[0] = job_label; + values[1] = kCFBooleanTrue; + values[2] = GetXQuartzFixer(); + dict = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 3, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + if (SMJobSubmit(kSMDomainSystemLaunchd, dict, auth, &error)) { + // Job ran, so XQuartz should be fixed + x11_type = XQUARTZ; + } else { + // Fail + } + if (error) { + CFRelease( error ); + } + + (void) SMJobRemove(kSMDomainSystemLaunchd, job_label, auth, false, NULL); + AuthorizationFree(auth, 0); + } + } + } + // compile "icon clicked" script so it's ready to execute // Don't tell it to activate if it's not installed; // that will pop up the annoying "where is XQuartz?"/"where is X11?" @@ -513,6 +589,29 @@ static unsigned char* GetOpenDoc (void) return path; } +/////////////////////////////////////// +// Gets the path to XQuartzFixer in Resources folder +/////////////////////////////////////// +static CFStringRef GetXQuartzFixer (void) +{ + CFBundleRef appBundle; + CFURLRef XQuartzFixerFileURL; + CFStringRef path; + + //get CF URL for XQuartzFixer + if (! (appBundle = CFBundleGetMainBundle())) return NULL; + if (! (XQuartzFixerFileURL = CFBundleCopyResourceURL(appBundle, kXQuartzFixerFileName, NULL, + NULL))) return NULL; + + //Get file system path from Core Foundation URL + path = CFURLCopyFileSystemPath( XQuartzFixerFileURL, kCFURLPOSIXPathStyle ); + + //dispose of the CF variables + CFRelease(XQuartzFixerFileURL); + + return path; +} + #pragma mark - ///////////////////////////////////// diff --git a/packaging/macosx/osx-app.sh b/packaging/macosx/osx-app.sh index 3475d1628b..22c8fe024f 100755 --- a/packaging/macosx/osx-app.sh +++ b/packaging/macosx/osx-app.sh @@ -308,6 +308,7 @@ res_list=" " if [ "$ui_toolkit" = "gtk" ] ; then + cc -o "$resdir"/Resources/XQuartzFixer -Os -Wall -W "$resdir"/Resources/XQuartzFixer.c res_list=" $res_list bin @@ -317,6 +318,7 @@ if [ "$ui_toolkit" = "gtk" ] ; then MenuBar.nib ProgressWindow.nib themes + XQuartzFixer " fi |