mirror of https://github.com/opa334/TrollStore.git
1.0.1
This commit is contained in:
parent
a8e72590a5
commit
ee08cfeb1d
|
@ -1,6 +1,6 @@
|
||||||
Package: com.opa334.trollstoreroothelper
|
Package: com.opa334.trollstoreroothelper
|
||||||
Name: trollstoreroothelper
|
Name: trollstoreroothelper
|
||||||
Version: 1.0
|
Version: 1.0.1
|
||||||
Architecture: iphoneos-arm
|
Architecture: iphoneos-arm
|
||||||
Description: An awesome tool of some sort!!
|
Description: An awesome tool of some sort!!
|
||||||
Maintainer: opa334
|
Maintainer: opa334
|
||||||
|
|
|
@ -243,10 +243,13 @@ BOOL signApp(NSString* appPath, NSError** error)
|
||||||
return ldidRet == 0;
|
return ldidRet == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL installApp(NSString* appPath, BOOL sign, NSError** error)
|
// 170: failed to create container for app bundle
|
||||||
|
// 171: a non trollstore app with the same identifier is already installled
|
||||||
|
// 172: no info.plist found in app
|
||||||
|
int installApp(NSString* appPath, BOOL sign, NSError** error)
|
||||||
{
|
{
|
||||||
NSString* appId = appIdForAppPath(appPath);
|
NSString* appId = appIdForAppPath(appPath);
|
||||||
if(!appId) return NO;
|
if(!appId) return 172;
|
||||||
|
|
||||||
if(sign)
|
if(sign)
|
||||||
{
|
{
|
||||||
|
@ -261,15 +264,27 @@ BOOL installApp(NSString* appPath, BOOL sign, NSError** error)
|
||||||
if(!appContainer || mcmError)
|
if(!appContainer || mcmError)
|
||||||
{
|
{
|
||||||
if(error) *error = mcmError;
|
if(error) *error = mcmError;
|
||||||
return NO;
|
return 170;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the bundle is empty
|
||||||
|
BOOL isEmpty = YES;
|
||||||
|
NSArray* bundleItems = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:appContainer.url.path error:error];
|
||||||
|
for(NSString* bundleItem in bundleItems)
|
||||||
|
{
|
||||||
|
if([bundleItem.pathExtension isEqualToString:@"app"])
|
||||||
|
{
|
||||||
|
isEmpty = NO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure there isn't already an app store app installed with the same identifier
|
// Make sure there isn't already an app store app installed with the same identifier
|
||||||
NSURL* trollStoreMarkURL = [appContainer.url URLByAppendingPathComponent:@"_TrollStore"];
|
NSURL* trollStoreMarkURL = [appContainer.url URLByAppendingPathComponent:@"_TrollStore"];
|
||||||
if(existed && ![trollStoreMarkURL checkResourceIsReachableAndReturnError:nil])
|
if(existed && !isEmpty && ![trollStoreMarkURL checkResourceIsReachableAndReturnError:nil])
|
||||||
{
|
{
|
||||||
NSLog(@"[installApp] already installed and not a TrollStore app... bailing out");
|
NSLog(@"[installApp] already installed and not a TrollStore app... bailing out");
|
||||||
return NO;
|
return 171;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply correct permissions
|
// Apply correct permissions
|
||||||
|
@ -297,7 +312,7 @@ BOOL installApp(NSString* appPath, BOOL sign, NSError** error)
|
||||||
|
|
||||||
// chown 0 all root binaries
|
// chown 0 all root binaries
|
||||||
NSDictionary* mainInfoDictionary = [NSDictionary dictionaryWithContentsOfFile:[appPath stringByAppendingPathComponent:@"Info.plist"]];
|
NSDictionary* mainInfoDictionary = [NSDictionary dictionaryWithContentsOfFile:[appPath stringByAppendingPathComponent:@"Info.plist"]];
|
||||||
if(!mainInfoDictionary) return NO;
|
if(!mainInfoDictionary) return 172;
|
||||||
NSObject* tsRootBinaries = mainInfoDictionary[@"TSRootBinaries"];
|
NSObject* tsRootBinaries = mainInfoDictionary[@"TSRootBinaries"];
|
||||||
if([tsRootBinaries isKindOfClass:[NSArray class]])
|
if([tsRootBinaries isKindOfClass:[NSArray class]])
|
||||||
{
|
{
|
||||||
|
@ -349,18 +364,18 @@ BOOL installApp(NSString* appPath, BOOL sign, NSError** error)
|
||||||
|
|
||||||
NSLog(@"[installApp] app installed, adding to icon cache now...");
|
NSLog(@"[installApp] app installed, adding to icon cache now...");
|
||||||
registerPath((char*)newAppPath.UTF8String, 0);
|
registerPath((char*)newAppPath.UTF8String, 0);
|
||||||
return YES;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return suc;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL uninstallApp(NSString* appId, NSError** error)
|
int uninstallApp(NSString* appId, NSError** error)
|
||||||
{
|
{
|
||||||
NSString* appPath = appPathForAppId(appId, error);
|
NSString* appPath = appPathForAppId(appId, error);
|
||||||
if(!appPath) return NO;
|
if(!appPath) return 1;
|
||||||
|
|
||||||
LSApplicationProxy* appProxy = [LSApplicationProxy applicationProxyForIdentifier:appId];
|
LSApplicationProxy* appProxy = [LSApplicationProxy applicationProxyForIdentifier:appId];
|
||||||
NSLog(@"appProxy: %@", appProxy);
|
NSLog(@"appProxy: %@", appProxy);
|
||||||
|
@ -398,23 +413,36 @@ BOOL uninstallApp(NSString* appId, NSError** error)
|
||||||
NSLog(@"deleting %@", [appPath stringByDeletingLastPathComponent]);
|
NSLog(@"deleting %@", [appPath stringByDeletingLastPathComponent]);
|
||||||
|
|
||||||
// delete app
|
// delete app
|
||||||
return [[NSFileManager defaultManager] removeItemAtPath:[appPath stringByDeletingLastPathComponent] error:error];
|
BOOL deleteSuc = [[NSFileManager defaultManager] removeItemAtPath:[appPath stringByDeletingLastPathComponent] error:error];
|
||||||
|
if(deleteSuc)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL installIpa(NSString* ipaPath, NSError** error)
|
// 166: IPA does not exist or is not accessible
|
||||||
|
// 167: IPA does not appear to contain an app
|
||||||
|
|
||||||
|
int installIpa(NSString* ipaPath, NSError** error)
|
||||||
{
|
{
|
||||||
|
if(![[NSFileManager defaultManager] fileExistsAtPath:ipaPath]) return 166;
|
||||||
|
|
||||||
BOOL suc = NO;
|
BOOL suc = NO;
|
||||||
NSString* tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSUUID UUID].UUIDString];
|
NSString* tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSUUID UUID].UUIDString];
|
||||||
|
|
||||||
suc = [[NSFileManager defaultManager] createDirectoryAtPath:tmpPath withIntermediateDirectories:NO attributes:nil error:error];
|
suc = [[NSFileManager defaultManager] createDirectoryAtPath:tmpPath withIntermediateDirectories:NO attributes:nil error:error];
|
||||||
if(!suc) return NO;
|
if(!suc) return 1;
|
||||||
|
|
||||||
extract(ipaPath, tmpPath);
|
extract(ipaPath, tmpPath);
|
||||||
|
|
||||||
NSString* tmpPayloadPath = [tmpPath stringByAppendingPathComponent:@"Payload"];
|
NSString* tmpPayloadPath = [tmpPath stringByAppendingPathComponent:@"Payload"];
|
||||||
|
|
||||||
NSArray* items = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:tmpPayloadPath error:error];
|
NSArray* items = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:tmpPayloadPath error:error];
|
||||||
if(!items) return NO;
|
if(!items) return 167;
|
||||||
|
|
||||||
NSString* tmpAppPath;
|
NSString* tmpAppPath;
|
||||||
for(NSString* item in items)
|
for(NSString* item in items)
|
||||||
|
@ -425,13 +453,13 @@ BOOL installIpa(NSString* ipaPath, NSError** error)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!tmpAppPath) return NO;
|
if(!tmpAppPath) return 167;
|
||||||
|
|
||||||
suc = installApp(tmpAppPath, YES, error);
|
int ret = installApp(tmpAppPath, YES, error);
|
||||||
|
|
||||||
[[NSFileManager defaultManager] removeItemAtPath:tmpAppPath error:nil];
|
[[NSFileManager defaultManager] removeItemAtPath:tmpAppPath error:nil];
|
||||||
|
|
||||||
return suc;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uninstallAllApps(void)
|
void uninstallAllApps(void)
|
||||||
|
@ -470,17 +498,17 @@ BOOL installTrollStore(NSString* pathToTar)
|
||||||
/*}*/
|
/*}*/
|
||||||
|
|
||||||
|
|
||||||
if(![[NSFileManager defaultManager] fileExistsAtPath:pathToTar]) return NO;
|
if(![[NSFileManager defaultManager] fileExistsAtPath:pathToTar]) return 1;
|
||||||
if(![pathToTar.pathExtension isEqualToString:@"tar"]) return NO;
|
if(![pathToTar.pathExtension isEqualToString:@"tar"]) return 1;
|
||||||
|
|
||||||
NSString* tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSUUID UUID].UUIDString];
|
NSString* tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSUUID UUID].UUIDString];
|
||||||
BOOL suc = [[NSFileManager defaultManager] createDirectoryAtPath:tmpPath withIntermediateDirectories:NO attributes:nil error:nil];
|
BOOL suc = [[NSFileManager defaultManager] createDirectoryAtPath:tmpPath withIntermediateDirectories:NO attributes:nil error:nil];
|
||||||
if(!suc) return NO;
|
if(!suc) return 1;
|
||||||
|
|
||||||
extract(pathToTar, tmpPath);
|
extract(pathToTar, tmpPath);
|
||||||
|
|
||||||
NSString* tmpTrollStore = [tmpPath stringByAppendingPathComponent:@"TrollStore.app"];
|
NSString* tmpTrollStore = [tmpPath stringByAppendingPathComponent:@"TrollStore.app"];
|
||||||
if(![[NSFileManager defaultManager] fileExistsAtPath:tmpTrollStore]) return NO;
|
if(![[NSFileManager defaultManager] fileExistsAtPath:tmpTrollStore]) return 1;
|
||||||
|
|
||||||
// Save existing ldid installation if it exists
|
// Save existing ldid installation if it exists
|
||||||
NSString* existingLdidPath = [trollStoreAppPath() stringByAppendingPathComponent:@"ldid"];
|
NSString* existingLdidPath = [trollStoreAppPath() stringByAppendingPathComponent:@"ldid"];
|
||||||
|
@ -629,33 +657,33 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||||
NSBundle* mcmBundle = [NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/MobileContainerManager.framework"];
|
NSBundle* mcmBundle = [NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/MobileContainerManager.framework"];
|
||||||
[mcmBundle load];
|
[mcmBundle load];
|
||||||
|
|
||||||
BOOL suc = NO;
|
int ret = 0;
|
||||||
NSError* error;
|
NSError* error;
|
||||||
|
|
||||||
NSString* cmd = [NSString stringWithUTF8String:argv[1]];
|
NSString* cmd = [NSString stringWithUTF8String:argv[1]];
|
||||||
if([cmd isEqualToString:@"install"])
|
if([cmd isEqualToString:@"install"])
|
||||||
{
|
{
|
||||||
if(argc <= 2) return -2;
|
if(argc <= 2) return -3;
|
||||||
NSString* ipaPath = [NSString stringWithUTF8String:argv[2]];
|
NSString* ipaPath = [NSString stringWithUTF8String:argv[2]];
|
||||||
suc = installIpa(ipaPath, &error);
|
ret = installIpa(ipaPath, &error);
|
||||||
} else if([cmd isEqualToString:@"uninstall"])
|
} else if([cmd isEqualToString:@"uninstall"])
|
||||||
{
|
{
|
||||||
if(argc <= 2) return -2;
|
if(argc <= 2) return -3;
|
||||||
NSString* appId = [NSString stringWithUTF8String:argv[2]];
|
NSString* appId = [NSString stringWithUTF8String:argv[2]];
|
||||||
suc = uninstallApp(appId, &error);
|
ret = uninstallApp(appId, &error);
|
||||||
} else if([cmd isEqualToString:@"install-trollstore"])
|
} else if([cmd isEqualToString:@"install-trollstore"])
|
||||||
{
|
{
|
||||||
if(argc <= 2) return -2;
|
if(argc <= 2) return -3;
|
||||||
NSString* tsTar = [NSString stringWithUTF8String:argv[2]];
|
NSString* tsTar = [NSString stringWithUTF8String:argv[2]];
|
||||||
suc = installTrollStore(tsTar);
|
ret = installTrollStore(tsTar);
|
||||||
NSLog(@"installed troll store? %d", suc);
|
NSLog(@"installed troll store? %d", ret==0);
|
||||||
} else if([cmd isEqualToString:@"uninstall-trollstore"])
|
} else if([cmd isEqualToString:@"uninstall-trollstore"])
|
||||||
{
|
{
|
||||||
uninstallAllApps();
|
uninstallAllApps();
|
||||||
uninstallTrollStore(YES);
|
uninstallTrollStore(YES);
|
||||||
} else if([cmd isEqualToString:@"install-ldid"])
|
} else if([cmd isEqualToString:@"install-ldid"])
|
||||||
{
|
{
|
||||||
if(argc <= 2) return -2;
|
if(argc <= 2) return -3;
|
||||||
NSString* ldidPath = [NSString stringWithUTF8String:argv[2]];
|
NSString* ldidPath = [NSString stringWithUTF8String:argv[2]];
|
||||||
installLdid(ldidPath);
|
installLdid(ldidPath);
|
||||||
} else if([cmd isEqualToString:@"refresh"])
|
} else if([cmd isEqualToString:@"refresh"])
|
||||||
|
@ -667,7 +695,7 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||||
refreshAppRegistrations();
|
refreshAppRegistrations();
|
||||||
} else if([cmd isEqualToString:@"install-persistence-helper"])
|
} else if([cmd isEqualToString:@"install-persistence-helper"])
|
||||||
{
|
{
|
||||||
if(argc <= 2) return -2;
|
if(argc <= 2) return -3;
|
||||||
NSString* systemAppId = [NSString stringWithUTF8String:argv[2]];
|
NSString* systemAppId = [NSString stringWithUTF8String:argv[2]];
|
||||||
installPersistenceHelper(systemAppId);
|
installPersistenceHelper(systemAppId);
|
||||||
} else if([cmd isEqualToString:@"uninstall-persistence-helper"])
|
} else if([cmd isEqualToString:@"uninstall-persistence-helper"])
|
||||||
|
@ -680,6 +708,8 @@ int main(int argc, char *argv[], char *envp[]) {
|
||||||
NSLog(@"error: %@", error);
|
NSLog(@"error: %@", error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return !suc;
|
NSLog(@"returning %d", ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,8 +52,8 @@ Installer</string>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Support iOS 15.0 - 15.1.1" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="s80-eR-fY3">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Supports iOS 15.0 - 15.1.1" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="s80-eR-fY3">
|
||||||
<rect key="frame" x="114.5" y="249" width="185" height="21"/>
|
<rect key="frame" x="110.5" y="249" width="193" height="21"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
|
|
Binary file not shown.
|
@ -50,7 +50,7 @@
|
||||||
<string>iPhoneOS</string>
|
<string>iPhoneOS</string>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1.0</string>
|
<string>1.0.1</string>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>UIDeviceFamily</key>
|
<key>UIDeviceFamily</key>
|
||||||
|
@ -215,7 +215,7 @@
|
||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||||
<true/>
|
<false/>
|
||||||
<key>TSRootBinaries</key>
|
<key>TSRootBinaries</key>
|
||||||
<array>
|
<array>
|
||||||
<string>trollstorehelper</string>
|
<string>trollstorehelper</string>
|
||||||
|
|
|
@ -6,7 +6,10 @@
|
||||||
|
|
||||||
- (void)reloadTable
|
- (void)reloadTable
|
||||||
{
|
{
|
||||||
[self.tableView reloadData];
|
dispatch_async(dispatch_get_main_queue(), ^
|
||||||
|
{
|
||||||
|
[self.tableView reloadData];
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)loadView
|
- (void)loadView
|
||||||
|
@ -52,7 +55,7 @@
|
||||||
{
|
{
|
||||||
NSString* appPath = [[TSApplicationsManager sharedInstance] installedAppPaths][indexPath.row];
|
NSString* appPath = [[TSApplicationsManager sharedInstance] installedAppPaths][indexPath.row];
|
||||||
NSString* appId = [[TSApplicationsManager sharedInstance] appIdForAppPath:appPath];
|
NSString* appId = [[TSApplicationsManager sharedInstance] appIdForAppPath:appPath];
|
||||||
[[TSApplicationsManager sharedInstance] uninstallApp:appId error:nil];
|
[[TSApplicationsManager sharedInstance] uninstallApp:appId];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
- (NSString*)appIdForAppPath:(NSString*)appPath;
|
- (NSString*)appIdForAppPath:(NSString*)appPath;
|
||||||
- (NSString*)displayNameForAppPath:(NSString*)appPath;
|
- (NSString*)displayNameForAppPath:(NSString*)appPath;
|
||||||
|
|
||||||
- (int)installIpa:(NSString*)pathToIpa error:(NSError**)error;
|
- (NSError*)errorForCode:(int)code;
|
||||||
- (int)uninstallApp:(NSString*)appId error:(NSError**)error;
|
- (int)installIpa:(NSString*)pathToIpa;
|
||||||
|
- (int)uninstallApp:(NSString*)appId;
|
||||||
|
|
||||||
@end
|
@end
|
|
@ -2,6 +2,8 @@
|
||||||
#import "TSUtil.h"
|
#import "TSUtil.h"
|
||||||
#import "../Helper/Shared.h"
|
#import "../Helper/Shared.h"
|
||||||
|
|
||||||
|
#define TrollStoreErrorDomain @"TrollStoreErrorDomain"
|
||||||
|
|
||||||
@implementation TSApplicationsManager
|
@implementation TSApplicationsManager
|
||||||
|
|
||||||
+ (instancetype)sharedInstance
|
+ (instancetype)sharedInstance
|
||||||
|
@ -50,16 +52,42 @@
|
||||||
return displayName;
|
return displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (int)installIpa:(NSString*)pathToIpa error:(NSError**)error
|
- (NSError*)errorForCode:(int)code
|
||||||
{
|
{
|
||||||
int ret = spawnRoot(helperPath(), @[@"install", pathToIpa]) == 0;
|
NSString* errorDescription = @"Unknown Error";
|
||||||
|
switch(code)
|
||||||
|
{
|
||||||
|
case 166:
|
||||||
|
errorDescription = @"The IPA file does not exist or is not accessible.";
|
||||||
|
break;
|
||||||
|
case 167:
|
||||||
|
errorDescription = @"The IPA file does not appear to contain an app.";
|
||||||
|
break;
|
||||||
|
case 170:
|
||||||
|
errorDescription = @"Failed to create container for app bundle.";
|
||||||
|
break;
|
||||||
|
case 171:
|
||||||
|
errorDescription = @"A non-TrollStore app with the same identifier is already installed. If you are absolutely sure it is not, try refreshing icon cache in TrollStore settings or try rebooting your device.";
|
||||||
|
break;
|
||||||
|
case 172:
|
||||||
|
errorDescription = @"The app does not seem to contain an Info.plist";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSError* error = [NSError errorWithDomain:TrollStoreErrorDomain code:code userInfo:@{NSLocalizedDescriptionKey : errorDescription}];
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int)installIpa:(NSString*)pathToIpa
|
||||||
|
{
|
||||||
|
int ret = spawnRoot(helperPath(), @[@"install", pathToIpa]);
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"ApplicationsChanged" object:nil];
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"ApplicationsChanged" object:nil];
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (int)uninstallApp:(NSString*)appId error:(NSError**)error
|
- (int)uninstallApp:(NSString*)appId
|
||||||
{
|
{
|
||||||
int ret = spawnRoot(helperPath(), @[@"uninstall", appId]) == 0;
|
int ret = spawnRoot(helperPath(), @[@"uninstall", appId]);
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"ApplicationsChanged" object:nil];
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"ApplicationsChanged" object:nil];
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,45 +5,86 @@
|
||||||
|
|
||||||
@implementation TSSceneDelegate
|
@implementation TSSceneDelegate
|
||||||
|
|
||||||
- (void)handleURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts
|
- (void)handleURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts scene:(UIWindowScene*)scene
|
||||||
{
|
{
|
||||||
|
UIWindow* keyWindow = nil;
|
||||||
|
for(UIWindow* window in scene.windows)
|
||||||
|
{
|
||||||
|
if(window.isKeyWindow)
|
||||||
|
{
|
||||||
|
keyWindow = window;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for(UIOpenURLContext* context in URLContexts)
|
for(UIOpenURLContext* context in URLContexts)
|
||||||
{
|
{
|
||||||
NSLog(@"openURLContexts %@", context.URL);
|
NSLog(@"openURLContexts %@", context.URL);
|
||||||
NSURL* url = context.URL;
|
NSURL* url = context.URL;
|
||||||
if (url != nil && [url isFileURL]) {
|
if (url != nil && [url isFileURL]) {
|
||||||
BOOL shouldExit = NO;
|
|
||||||
|
|
||||||
[url startAccessingSecurityScopedResource];
|
[url startAccessingSecurityScopedResource];
|
||||||
NSURL* tmpCopyURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:url.lastPathComponent]];
|
NSURL* tmpCopyURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:url.lastPathComponent]];
|
||||||
|
|
||||||
[[NSFileManager defaultManager] copyItemAtURL:url toURL:tmpCopyURL error:nil];
|
[[NSFileManager defaultManager] copyItemAtURL:url toURL:tmpCopyURL error:nil];
|
||||||
|
|
||||||
|
void (^doneBlock)(BOOL) = ^(BOOL shouldExit)
|
||||||
|
{
|
||||||
|
[[NSFileManager defaultManager] removeItemAtURL:tmpCopyURL error:nil];
|
||||||
|
[url stopAccessingSecurityScopedResource];
|
||||||
|
[[NSFileManager defaultManager] removeItemAtURL:url error:nil];
|
||||||
|
|
||||||
|
if(shouldExit)
|
||||||
|
{
|
||||||
|
NSLog(@"Respring + Exit");
|
||||||
|
respring();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if ([url.pathExtension isEqualToString:@"ipa"]) {
|
if ([url.pathExtension isEqualToString:@"ipa"])
|
||||||
// Install IPA
|
{
|
||||||
NSError* error;
|
UIAlertController* infoAlert = [UIAlertController alertControllerWithTitle:@"Installing" message:@"" preferredStyle:UIAlertControllerStyleAlert];
|
||||||
int ret = [[TSApplicationsManager sharedInstance] installIpa:tmpCopyURL.path error:&error];
|
UIActivityIndicatorView* activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(5,5,50,50)];
|
||||||
NSLog(@"installed app! ret:%d, error: %@", ret, error);
|
activityIndicator.hidesWhenStopped = YES;
|
||||||
|
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleMedium;
|
||||||
|
[activityIndicator startAnimating];
|
||||||
|
[infoAlert.view addSubview:activityIndicator];
|
||||||
|
|
||||||
|
[keyWindow.rootViewController presentViewController:infoAlert animated:YES completion:nil];
|
||||||
|
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
|
||||||
|
{
|
||||||
|
// Install IPA
|
||||||
|
int ret = [[TSApplicationsManager sharedInstance] installIpa:tmpCopyURL.path];
|
||||||
|
NSError* error = [[TSApplicationsManager sharedInstance] errorForCode:ret];
|
||||||
|
|
||||||
|
NSLog(@"installed app! ret:%d, error: %@", ret, error);
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^
|
||||||
|
{
|
||||||
|
[infoAlert dismissViewControllerAnimated:YES completion:^
|
||||||
|
{
|
||||||
|
if(ret != 0)
|
||||||
|
{
|
||||||
|
UIAlertController* errorAlert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"Install Error %d", ret] message:[error localizedDescription] preferredStyle:UIAlertControllerStyleAlert];
|
||||||
|
UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:nil];
|
||||||
|
[errorAlert addAction:closeAction];
|
||||||
|
|
||||||
|
[keyWindow.rootViewController presentViewController:errorAlert animated:YES completion:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
doneBlock(NO);
|
||||||
|
}];
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else if([url.pathExtension isEqualToString:@"tar"])
|
else if([url.pathExtension isEqualToString:@"tar"])
|
||||||
{
|
{
|
||||||
// Update TrollStore itself
|
// Update TrollStore itself
|
||||||
NSLog(@"Updating TrollStore...");
|
NSLog(@"Updating TrollStore...");
|
||||||
int ret = spawnRoot(helperPath(), @[@"install-trollstore", tmpCopyURL.path]);
|
int ret = spawnRoot(helperPath(), @[@"install-trollstore", tmpCopyURL.path]);
|
||||||
if(ret == 0) shouldExit = YES;
|
doneBlock(ret == 0);
|
||||||
NSLog(@"Updated TrollStore!");
|
NSLog(@"Updated TrollStore!");
|
||||||
}
|
}
|
||||||
|
|
||||||
[[NSFileManager defaultManager] removeItemAtURL:tmpCopyURL error:nil];
|
|
||||||
[url stopAccessingSecurityScopedResource];
|
|
||||||
|
|
||||||
if(shouldExit)
|
|
||||||
{
|
|
||||||
NSLog(@"Respring + Exit");
|
|
||||||
respring();
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,16 +96,16 @@
|
||||||
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
|
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
|
||||||
|
|
||||||
NSLog(@"scene:%@ willConnectToSession:%@ options:%@", scene, session, connectionOptions);
|
NSLog(@"scene:%@ willConnectToSession:%@ options:%@", scene, session, connectionOptions);
|
||||||
if(connectionOptions.URLContexts.count)
|
|
||||||
{
|
|
||||||
[self handleURLContexts:connectionOptions.URLContexts];
|
|
||||||
}
|
|
||||||
|
|
||||||
UIWindowScene* windowScene = (UIWindowScene*)scene;
|
UIWindowScene* windowScene = (UIWindowScene*)scene;
|
||||||
_window = [[UIWindow alloc] initWithWindowScene:windowScene];
|
_window = [[UIWindow alloc] initWithWindowScene:windowScene];
|
||||||
_rootViewController = [[TSRootViewController alloc] init];
|
_rootViewController = [[TSRootViewController alloc] init];
|
||||||
_window.rootViewController = _rootViewController;
|
_window.rootViewController = _rootViewController;
|
||||||
[_window makeKeyAndVisible];
|
[_window makeKeyAndVisible];
|
||||||
|
|
||||||
|
if(connectionOptions.URLContexts.count)
|
||||||
|
{
|
||||||
|
[self handleURLContexts:connectionOptions.URLContexts scene:(UIWindowScene*)scene];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -103,7 +144,7 @@
|
||||||
- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts
|
- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts
|
||||||
{
|
{
|
||||||
NSLog(@"scene:%@ openURLContexts:%@", scene, URLContexts);
|
NSLog(@"scene:%@ openURLContexts:%@", scene, URLContexts);
|
||||||
[self handleURLContexts:URLContexts];
|
[self handleURLContexts:URLContexts scene:(UIWindowScene*)scene];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
|
@ -103,6 +103,7 @@
|
||||||
detail:nil
|
detail:nil
|
||||||
cell:PSStaticTextCell
|
cell:PSStaticTextCell
|
||||||
edit:nil];
|
edit:nil];
|
||||||
|
[ldidInstalledSpecifier setProperty:@NO forKey:@"enabled"];
|
||||||
ldidInstalledSpecifier.identifier = @"ldidInstalled";
|
ldidInstalledSpecifier.identifier = @"ldidInstalled";
|
||||||
[_specifiers addObject:ldidInstalledSpecifier];
|
[_specifiers addObject:ldidInstalledSpecifier];
|
||||||
}
|
}
|
||||||
|
@ -135,6 +136,7 @@
|
||||||
detail:nil
|
detail:nil
|
||||||
cell:PSStaticTextCell
|
cell:PSStaticTextCell
|
||||||
edit:nil];
|
edit:nil];
|
||||||
|
[installedPersistenceHelperSpecifier setProperty:@NO forKey:@"enabled"];
|
||||||
installedPersistenceHelperSpecifier.identifier = @"persistenceHelperInstalled";
|
installedPersistenceHelperSpecifier.identifier = @"persistenceHelperInstalled";
|
||||||
[_specifiers addObject:installedPersistenceHelperSpecifier];
|
[_specifiers addObject:installedPersistenceHelperSpecifier];
|
||||||
}
|
}
|
||||||
|
@ -153,7 +155,7 @@
|
||||||
detail:nil
|
detail:nil
|
||||||
cell:PSStaticTextCell
|
cell:PSStaticTextCell
|
||||||
edit:nil];
|
edit:nil];
|
||||||
|
[installedPersistenceHelperSpecifier setProperty:@NO forKey:@"enabled"];
|
||||||
installedPersistenceHelperSpecifier.identifier = @"persistenceHelperInstalled";
|
installedPersistenceHelperSpecifier.identifier = @"persistenceHelperInstalled";
|
||||||
[_specifiers addObject:installedPersistenceHelperSpecifier];
|
[_specifiers addObject:installedPersistenceHelperSpecifier];
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ int spawnRoot(NSString* path, NSArray* args)
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (waitpid(task_pid, &status, 0) != -1) {
|
if (waitpid(task_pid, &status, 0) != -1) {
|
||||||
printf("Child status %dn", WEXITSTATUS(status));
|
NSLog(@"Child status %d", WEXITSTATUS(status));
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
perror("waitpid");
|
perror("waitpid");
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
Package: com.opa334.trollstore
|
Package: com.opa334.trollstore
|
||||||
Name: TrollStore
|
Name: TrollStore
|
||||||
Version: 1.0
|
Version: 1.0.1
|
||||||
Architecture: iphoneos-arm
|
Architecture: iphoneos-arm
|
||||||
Description: An awesome application!
|
Description: An awesome application!
|
||||||
Maintainer: opa334
|
Maintainer: opa334
|
||||||
|
|
Loading…
Reference in New Issue