Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mumble-voip/mumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/mumble/Overlay_macx.mm')
-rw-r--r--src/mumble/Overlay_macx.mm113
1 files changed, 110 insertions, 3 deletions
diff --git a/src/mumble/Overlay_macx.mm b/src/mumble/Overlay_macx.mm
index 7a73ada1a..b077499d6 100644
--- a/src/mumble/Overlay_macx.mm
+++ b/src/mumble/Overlay_macx.mm
@@ -96,13 +96,120 @@ void Overlay::setActive(bool act) {
static_cast<OverlayPrivateMac *>(d)->setActive(act);
}
+bool Overlay::supportsInstallableOverlay() {
+ return true;
+}
+
bool Overlay::isInstalled() {
- return false;
+ bool ret = false;
+
+ // Get the path where we expect the overlay loader to be installed.
+ NSString *path = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"MumbleOverlayLoaderBundle"];
+ if (! path) {
+ qWarning("Overlay_macx: No MumbleOverlayLoaderPath specified in Info.plist. "
+ "Pretending overlay is already installed.");
+ return false;
+ }
+
+ // Determine if the installed bundle is correctly installed (i.e. it's loadable)
+ NSBundle *bundle = [NSBundle bundleWithPath:path];
+ return [bundle preflightAndReturnError:NULL];
}
bool Overlay::needsUpgrade() {
- return false;
+ // Get required version from our own Info.plist
+ NSUInteger reqVersion = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"MumbleOverlayLoaderRequiredVersion"] unsignedIntegerValue];
+
+ // Load the overlay loader bundle.
+ NSBundle *bundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"MumbleOverlayLoaderBundle"]];
+ if (! bundle) {
+ qWarning("Overlay_macx: Unable to load the installed OSAX bundle. This shouldn't happen.");
+ return false;
+ }
+
+ // Get its version.
+ NSUInteger curVersion = [[bundle objectForInfoDictionaryKey:@"MumbleOverlayLoaderVersion"] unsignedIntegerValue];
+
+ // If the two versions do not match up, we need to upgrade.
+ return curVersion != reqVersion;
+}
+
+bool Overlay::installFiles() {
+ AuthorizationRef auth;
+ bool ret = false;
+ int pid, status;
+ OSStatus err;
+
+ // Get the tarball that we should install.
+ NSString *tarballPath = [NSString stringWithFormat:@"%@/%@", [[NSBundle mainBundle] bundlePath],
+ [[NSBundle mainBundle] objectForInfoDictionaryKey:@"MumbleOverlayInstallPayload"]];
+
+ // And the destination we should install it to.
+ NSString *destination = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"MumbleOverlayInstallDestintaion"];
+
+ if (! tarballPath || ! destination) {
+ qWarning("Overlay_macx: Info.plist does not specify installation parameters.");
+ return false;
+ }
+
+ // Request an AuthorizationRef. This is a mechanism in Mac OS X that allows a parent program
+ // to spawn child processes with euid = 0.
+ //
+ // When attempting to launch the child process, a dialog will pop up requesting the user to
+ // authorize the launch by logging in with as a user with admin privileges.
+ err = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &auth);
+ if (err == errAuthorizationSuccess) {
+ // This is the tar command that we execute to install our support files.
+ const char *argv[] = { "/usr/bin/tar", "-jxf", [tarballPath UTF8String], "-C", [destination UTF8String], NULL };
+ // Launch the child process.
+ err = AuthorizationExecuteWithPrivileges(auth, argv[0], kAuthorizationFlagDefaults, const_cast<char * const *>(&argv[1]), NULL);
+ if (err == errAuthorizationSuccess) {
+ // And wait until it is dead.
+ do {
+ pid = wait(&status);
+ } while (pid == -1 && errno == EINTR);
+ ret = (pid != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0);
+ } else
+ qWarning("Overlay_macx: Failed to AuthorizeExecuteWithPrivileges. (err=%i)", err);
+ } else
+ qWarning("Overlay_macx: Failed to acquire AuthorizationRef. (err=%i)", err);
+
+ if (! ret) {
+ qWarning("Overlay_macx: Failure in installer process. (pid=%i, exited=%u, exitStatus=%u)",
+ pid, WIFEXITED(status), WEXITSTATUS(status));
+ }
+
+ // Free the AuthorizationRef that we acquired earlier. We're done launching priviledged children.
+ AuthorizationFree(auth, kAuthorizationFlagDefaults);
+ return ret;
}
-void Overlay::installFiles() {
+bool Overlay::uninstallFiles() {
+ // Get the absolute path of our overlay loader bundle.
+ NSString *path = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"MumbleOverlayLoaderBundle"];
+ // Make sure it is unloaded, at least from ourselves, before we trash it.
+ [[NSBundle bundleWithPath:path] unload];
+
+ // This is a tiny AppleScript that kindly asks the Finder to throw
+ // the currently installed loader bundle into the trash.
+ //
+ // This is nice because we don't need to have any privileged code in
+ // Mumble itself that does it, and because it goes into the user's
+ // trash.
+ NSString *uninstallScript = [NSString stringWithFormat:@""
+ "set bundlePath to POSIX file \"%@\"\n"
+ "tell application \"Finder\" to delete bundlePath\n", path];
+
+ // Execute the script, and hope for the best.
+ NSError *error = nil;
+ NSString *script = [[NSAppleScript alloc] initWithSource:uninstallScript];
+ [script executeAndReturnError:&error];
+ [script release];
+
+ if (error) {
+ NSLog(@"%@", error);
+ return false;
+ }
+
+ return true;
}