|
@@ -52,6 +52,42 @@
|
|
|
#import <objc/runtime.h>
|
|
|
#import "rocketbootstrap.h"
|
|
|
#import "AppSupport/CPDistributedMessagingCenter.h"
|
|
|
+#import <MobileCoreServices/MobileCoreServices.h>
|
|
|
+#import "NSTask.h"
|
|
|
+
|
|
|
+#include <errno.h>
|
|
|
+#include <libgen.h>
|
|
|
+#include <string.h>
|
|
|
+#include <unistd.h>
|
|
|
+#include <getopt.h>
|
|
|
+
|
|
|
+@interface PBSSystemService : NSObject
|
|
|
++(id)sharedInstance;
|
|
|
+-(void)endpointForProviderType:(id)arg1 withIdentifier:(id)arg2 responseBlock:(/*^block*/id)arg3 ;
|
|
|
+-(void)launchKioskApp;
|
|
|
+-(void)sleepSystemForReason:(id)arg1 ;
|
|
|
+-(void)wakeSystemForReason:(id)arg1 ;
|
|
|
+-(void)relaunchBackboardd;
|
|
|
+-(void)relaunch;
|
|
|
+-(void)reboot;
|
|
|
+-(id)infoForProvidersWithType:(id)arg1 ;
|
|
|
+-(void)deactivateApplication;
|
|
|
+-(void)registerServiceProviderEndpoint:(id)arg1 forProviderType:(id)arg2 ;
|
|
|
+-(void)deactivateScreenSaver;
|
|
|
+
|
|
|
+@end
|
|
|
+
|
|
|
+@interface LSApplicationWorkspace : NSObject
|
|
|
++ (id)defaultWorkspace;
|
|
|
+- (BOOL)_LSPrivateRebuildApplicationDatabasesForSystemApps:(BOOL)arg1 internal:(BOOL)arg2 user:(BOOL)arg3;
|
|
|
+- (BOOL)registerApplicationDictionary:(NSDictionary *)applicationDictionary;
|
|
|
+- (BOOL)registerBundleWithInfo:(NSDictionary *)bundleInfo options:(NSDictionary *)options type:(unsigned long long)arg3 progress:(id)arg4 ;
|
|
|
+- (BOOL)registerApplication:(NSURL *)url;
|
|
|
+- (BOOL)registerPlugin:(NSURL *)url;
|
|
|
+- (BOOL)unregisterApplication:(NSURL *)url;
|
|
|
+- (NSArray *)installedPlugins;
|
|
|
+-(void)_LSPrivateSyncWithMobileInstallation;
|
|
|
+@end
|
|
|
|
|
|
#define DLog(format, ...) CFShow((__bridge CFStringRef)[NSString stringWithFormat:format, ## __VA_ARGS__]);
|
|
|
|
|
@@ -154,21 +190,92 @@ static void inject_dylib(const char* name, pid_t pid, const char* dylib) {
|
|
|
@end
|
|
|
@implementation MessageHandler
|
|
|
|
|
|
++ (NSString *)returnForProcess:(NSString *)call
|
|
|
+{
|
|
|
+ if (call==nil)
|
|
|
+ return 0;
|
|
|
+ char line[200];
|
|
|
+ FILE* fp = popen([call UTF8String], "r");
|
|
|
+ NSMutableArray *lines = [[NSMutableArray alloc]init];
|
|
|
+ if (fp)
|
|
|
+ {
|
|
|
+ while (fgets(line, sizeof line, fp))
|
|
|
+ {
|
|
|
+ NSString *s = [NSString stringWithCString:line encoding:NSUTF8StringEncoding];
|
|
|
+ s = [s stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
|
|
+ [lines addObject:s];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ pclose(fp);
|
|
|
+ return [lines componentsJoinedByString:@"\n"];
|
|
|
+}
|
|
|
+
|
|
|
+- (BOOL)forceReboot {
|
|
|
+
|
|
|
+ NSString *command = @"/usr/bin/dpkg -s com.nito.nitotv4 | grep Version | cut -d \" \" -f2";
|
|
|
+ int _returnCode = 0;
|
|
|
+ BOOL _finished = FALSE;
|
|
|
+ NSMutableArray *lines = [NSMutableArray new];
|
|
|
+ char line[200];
|
|
|
+
|
|
|
+ FILE* fp = popen([command UTF8String], "r");
|
|
|
+
|
|
|
+ if (fp)
|
|
|
+ {
|
|
|
+ while (fgets(line, sizeof line, fp))
|
|
|
+ {
|
|
|
+ NSString *s = [NSString stringWithCString:line encoding:NSUTF8StringEncoding];
|
|
|
+ s = [s stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
|
|
+ [lines addObject:s];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ pclose(fp);
|
|
|
+ BOOL reboot = FALSE;
|
|
|
+ NSString *version = [lines lastObject];
|
|
|
+
|
|
|
+ //DLog(@"nitoTV version: -%@-", version);
|
|
|
+
|
|
|
+ NSString *minimumVersion = @"2.4-103";
|
|
|
+
|
|
|
+ //DDLogInfo(@"package: '%@' online version: '%@' installed version: '%@'", objectName, onlineVersion, installedVersion);
|
|
|
+ NSComparisonResult theResult = [minimumVersion compare:version options:NSNumericSearch];
|
|
|
+
|
|
|
+ if ( theResult == NSOrderedDescending )
|
|
|
+ {
|
|
|
+ //DLog(@"minimum version %@ is less than installedVersion: %@", minimumVersion, version);
|
|
|
+ reboot = true;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return reboot;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
//called from PBReloadHelper in tvOS 9 circumstances so we can rebuild the cache with proper entitlements
|
|
|
--(void)rebuildCache:(id)a
|
|
|
+-(void)rebuildCache:(BOOL)reboot
|
|
|
{
|
|
|
DLog(@"Rebuilding cache...\n");
|
|
|
+ LSApplicationWorkspace *workspace = [LSApplicationWorkspace defaultWorkspace];
|
|
|
+ //[workspace _LSClearSchemaCaches]; //may or may not be necessary
|
|
|
+ [workspace _LSPrivateRebuildApplicationDatabasesForSystemApps:YES internal:YES user:NO];
|
|
|
|
|
|
- Class WSCLASS = objc_getClass("LSApplicationWorkspace");
|
|
|
+ BOOL forceReboot = [self forceReboot];
|
|
|
|
|
|
- id workspace = nil;
|
|
|
- if (WSCLASS != nil)
|
|
|
- {
|
|
|
- workspace = [WSCLASS defaultWorkspace];
|
|
|
+ if (reboot || forceReboot){
|
|
|
+ DLog(@"Respringing...\n");
|
|
|
+ /*
|
|
|
+ dlopen("/System/Library/PrivateFrameworks/PineBoardServices.framework/PineBoardServices", RTLD_NOW);
|
|
|
+ id systemService = [objc_getClass("PBSSystemService") sharedInstance];
|
|
|
+ DLog(@"system service: %@", systemService);
|
|
|
+ [systemService relaunchBackboardd];
|
|
|
+ */
|
|
|
+ NSString *killallPath = [MessageHandler returnForProcess:@"/usr/bin/which killall"];
|
|
|
+ NSTask *installTask = [NSTask launchedTaskWithLaunchPath:killallPath arguments:@[@"-9", @"backboardd"]];
|
|
|
+
|
|
|
}
|
|
|
|
|
|
- [workspace _LSClearSchemaCaches]; //may or may not be necessary
|
|
|
- [workspace _LSPrivateRebuildApplicationDatabasesForSystemApps:YES internal:YES user:YES];
|
|
|
+
|
|
|
|
|
|
}
|
|
|
|
|
@@ -182,12 +289,39 @@ static void inject_dylib(const char* name, pid_t pid, const char* dylib) {
|
|
|
|
|
|
@end
|
|
|
|
|
|
+#define OPTION_FLAGS "r"
|
|
|
+char *progname;
|
|
|
+
|
|
|
+static struct option longopts[] = {
|
|
|
+
|
|
|
+ { "reboot", no_argument, NULL, 'r' },
|
|
|
+ { NULL, 0, NULL, 0 }
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
int main(int argc, char* argv[]) {
|
|
|
|
|
|
platformize_me();
|
|
|
- printf("uicache for tvOS\n");
|
|
|
+ printf("uicache for tvOS slim edition\n");
|
|
|
+ bool reboot = false;
|
|
|
+ int flag;
|
|
|
+// NSString *value = nil;
|
|
|
+ while ((flag = getopt_long(argc, argv, OPTION_FLAGS, longopts, NULL)) != -1) {
|
|
|
+ switch(flag) {
|
|
|
+ case 'r':
|
|
|
+ reboot = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ MessageHandler *mh = [MessageHandler new];
|
|
|
+ [mh rebuildCache:reboot];
|
|
|
+ return 0;
|
|
|
+ //[[LSApplicationWorkspace defaultWorkspace] _LSPrivateRebuildApplicationDatabasesForSystemApps:YES internal:YES user:NO];
|
|
|
|
|
|
/*
|
|
|
+
|
|
|
printf("based on asu_inject from AppSyncUnified\n");
|
|
|
|
|
|
printf("Creating queue...\n");
|
|
@@ -198,7 +332,7 @@ int main(int argc, char* argv[]) {
|
|
|
|
|
|
printf("Waiting for queue to come back...\n");
|
|
|
|
|
|
- */
|
|
|
+ */
|
|
|
|
|
|
/* wait for queue to come back */
|
|
|
|