git.y1.nz

SameBoy

Accurate GB/GBC emulator
download: https://git.y1.nz/archives/sameboy.tar.gz
README | Files | Log | Refs | LICENSE

iOS/installer.m

      1 #import <Foundation/Foundation.h>
      2 #import <dlfcn.h>
      3 #import <objc/runtime.h>
      4 
      5 @interface LSApplicationProxy : NSObject
      6 @property (readonly, getter=isContainerized) bool containerized;
      7 @property (readonly) NSString *bundleIdentifier;
      8 @property (readonly) NSURL * bundleURL;
      9 @end
     10 
     11 @interface LSApplicationWorkspace : NSObject
     12 + (instancetype)defaultWorkspace;
     13 - (NSArray <LSApplicationProxy *> *)allInstalledApplications;
     14 - (bool)unregisterApplication:(NSURL *)url;
     15 - (bool)registerApplicationDictionary:(NSDictionary *)dict;
     16 @end
     17 
     18 @interface MCMAppDataContainer : NSObject
     19 + (MCMAppDataContainer *)containerWithIdentifier:(NSString *)identifier
     20                                createIfNecessary:(bool)create
     21                                          existed:(bool *)existed
     22                                            error:(NSError **)error;
     23 @property(readonly) NSURL *url;
     24 @end
     25 
     26 
     27 int main(int argc, char **argv)
     28 {
     29     if (argc != 2) return 1;
     30     // Make sure MobileContainerManager is loaded
     31     if (!dlopen("/System/Library/PrivateFrameworks/MobileContainerManager.framework/MobileContainerManager", RTLD_NOW)) return 1;
     32     
     33     bool uninstall = false;
     34     if (strcmp(argv[1], "uninstall") == 0) {
     35         uninstall = true;
     36     }
     37     else if (strcmp(argv[1], "install") != 0) {
     38         return 1;
     39     }
     40     
     41     NSString *installPath = @"/var/jb/Applications/SameBoy-iOS.app";
     42     if (access("/Applications/", W_OK) == 0) {
     43         installPath = @"/Applications/SameBoy-iOS.app";
     44     }
     45     NSLog(@"Install path is %@", installPath);
     46     
     47     for (LSApplicationProxy *app in [[LSApplicationWorkspace defaultWorkspace] allInstalledApplications]) {
     48         if (![app.bundleIdentifier isEqualToString:[NSBundle mainBundle].bundleIdentifier]) continue;
     49         if (![app.bundleURL.path.stringByResolvingSymlinksInPath isEqual:installPath.stringByResolvingSymlinksInPath]) {
     50             // Already installed elsewhere
     51             NSLog(@"Already installed at %@", app.bundleURL.path);
     52             return 1;
     53         }
     54         
     55         NSLog(@"Unregistering previous installation");
     56         // We're registered but not containerized (or just uninstalling), unregister ourselves first
     57         if (![[LSApplicationWorkspace defaultWorkspace] unregisterApplication:app.bundleURL]) return 1;
     58         
     59         break;
     60     }
     61     
     62     // Don't modify files if we're at the correct path already
     63     if (uninstall || ![[NSBundle mainBundle].bundlePath.stringByResolvingSymlinksInPath isEqual:installPath.stringByResolvingSymlinksInPath]) {
     64         // Remove any previous copy
     65         NSError *error = nil;
     66         if (!access(installPath.UTF8String, F_OK)) {
     67             NSLog(@"Removing previous installation");
     68             [[NSFileManager defaultManager] removeItemAtPath:installPath error:&error];
     69             if (error) {
     70                 NSLog(@"Error: %@", error);
     71                 return 1;
     72             }
     73         }
     74         
     75         // If we're uninstalling, we're done
     76         if (uninstall) return 0;
     77         
     78         NSLog(@"Installing...");
     79 
     80         [[NSFileManager defaultManager] moveItemAtPath:[NSBundle mainBundle].bundlePath toPath:installPath error:&error];
     81         if (error) {
     82             NSLog(@"Error: %@", error);
     83             return 1;
     84         }
     85     }
     86     
     87     
     88     NSLog(@"Registering...");
     89 
     90     NSString *container = [objc_getClass("MCMAppDataContainer") containerWithIdentifier:[NSBundle mainBundle].bundleIdentifier
     91                                                                       createIfNecessary:true
     92                                                                                 existed:nil
     93                                                                                   error:nil].url.path;
     94     
     95     return ![[LSApplicationWorkspace defaultWorkspace] registerApplicationDictionary:@{
     96         @"ApplicationType": @"System",
     97         @"CFBundleIdentifier": [NSBundle mainBundle].bundleIdentifier,
     98         @"CompatibilityState": @NO,
     99         @"Container": container,
    100         @"IsDeletable": @NO,
    101         @"Path": installPath,
    102         @"_LSBundlePlugins": @{},
    103         @"IsContainerized": @YES,
    104     }];
    105 }

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.