X-Git-Url: https://git.saurik.com/cydia.git/blobdiff_plain/232b396b15248b956dd18092649f378b0db8bd4d..ca0a920d902e70044e20bbd4efd993e5d63789e7:/MobileCydia.mm diff --git a/MobileCydia.mm b/MobileCydia.mm index d0b89fba..86e6a6f2 100644 --- a/MobileCydia.mm +++ b/MobileCydia.mm @@ -1,5 +1,5 @@ /* Cydia - iPhone UIKit Front-End for Debian APT - * Copyright (C) 2008-2014 Jay Freeman (saurik) + * Copyright (C) 2008-2015 Jay Freeman (saurik) */ /* GNU General Public License, Version 3 {{{ */ @@ -237,35 +237,6 @@ union SplitHash { }; // }}} -static void setreugid(uid_t uid, gid_t gid) { - _assert(setreuid(uid, uid) != -1); - _assert(setregid(gid, gid) != -1); -} - -static void setreguid(gid_t gid, uid_t uid) { - _assert(setregid(gid, gid) != -1); - _assert(setreuid(uid, uid) != -1); -} - -struct Root { - Root() { - _trace(); - setreugid(0, 0); - _assert(pthread_setugid_np(0, 0) != -1); - setreguid(501, 501); - } - - ~Root() { - _trace(); - setreugid(0, 0); - _assert(pthread_setugid_np(KAUTH_UID_NONE, KAUTH_GID_NONE) != -1); - setreguid(501, 501); - } -}; - -#define _root(code) \ - ({ Root _root; code; }) - static NSString *Colon_; NSString *Elision_; static NSString *Error_; @@ -707,7 +678,6 @@ static const NSString *UI_; static int Finish_; static bool RestartSubstrate_; -static bool UpgradeCydia_; static NSArray *Finishes_; #define SpringBoard_ "/System/Library/LaunchDaemons/com.apple.SpringBoard.plist" @@ -746,7 +716,6 @@ static _H System_; static NSString *SerialNumber_ = nil; static NSString *ChipID_ = nil; static NSString *BBSNum_ = nil; -static _H Token_; static _H UniqueID_; static _H UserAgent_; static _H Product_; @@ -806,15 +775,15 @@ static CFLocaleRef Locale_; static NSArray *Languages_; static CGColorSpaceRef space_; +#define CacheState_ "/var/mobile/Library/Caches/com.saurik.Cydia/CacheState.plist" +#define SavedState_ "/var/mobile/Library/Caches/com.saurik.Cydia/SavedState.plist" + static NSDictionary *SectionMap_; -static NSMutableDictionary *Metadata_; -static _transient NSMutableDictionary *Settings_; -static _transient NSMutableDictionary *Packages_; +static _H Backgrounded_; static _transient NSMutableDictionary *Values_; static _transient NSMutableDictionary *Sections_; _H Sources_; static _transient NSNumber *Version_; -bool Changed_; static time_t now_; bool IsWildcat_; @@ -826,7 +795,6 @@ static NSString *Major_; static _H SessionData_; static _H HostConfig_; static _H BridgedHosts_; -static _H TokenHosts_; static _H InsecureHosts_; static _H PipelinedHosts_; static _H CachedURLs_; @@ -902,20 +870,6 @@ NSString *Simplify(NSString *title) { } /* }}} */ -NSString *GetLastUpdate() { - NSDate *update = [Metadata_ objectForKey:@"LastUpdate"]; - - if (update == nil) - return UCLocalize("NEVER_OR_UNKNOWN"); - - CFDateFormatterRef formatter = CFDateFormatterCreate(NULL, Locale_, kCFDateFormatterMediumStyle, kCFDateFormatterMediumStyle); - CFStringRef formatted = CFDateFormatterCreateStringWithDate(NULL, formatter, (CFDateRef) update); - - CFRelease(formatter); - - return [(NSString *) formatted autorelease]; -} - bool isSectionVisible(NSString *section) { NSDictionary *metadata([Sections_ objectForKey:(section ?: @"")]); NSNumber *hidden(metadata == nil ? nil : [metadata objectForKey:@"Hidden"]); @@ -1119,6 +1073,7 @@ typedef std::map< unsigned long, _H > SourceMap; CYPool pool_; unsigned era_; + _H delock_; pkgCacheFile cache_; pkgDepCache::Policy *policy_; @@ -1523,6 +1478,30 @@ static void PackageImport(const void *key, const void *value, void *context) { } // }}} +static NSDate *GetStatusDate() { + return [[[NSFileManager defaultManager] attributesOfItemAtPath:@"/var/lib/dpkg/status" error:NULL] fileModificationDate]; +} + +static void SaveConfig(NSObject *lock) { + @synchronized (lock) { + _trace(); + MetaFile_.Sync(); + _trace(); + } + + CFPreferencesSetMultiple((CFDictionaryRef) [NSDictionary dictionaryWithObjectsAndKeys: + Values_, @"CydiaValues", + Sections_, @"CydiaSections", + (id) Sources_, @"CydiaSources", + Version_, @"CydiaVersion", + nil], NULL, CFSTR("com.saurik.Cydia"), kCFPreferencesCurrentUser, kCFPreferencesCurrentHost); + + if (!CFPreferencesAppSynchronize(CFSTR("com.saurik.Cydia"))) + NSLog(@"CFPreferencesAppSynchronize(com.saurik.Cydia) == false"); + + CydiaWriteSources(); +} + /* Source Class {{{ */ @interface Source : NSObject { unsigned era_; @@ -1785,14 +1764,10 @@ static void PackageImport(const void *key, const void *value, void *context) { if (record_ == nil) return; else if (NSMutableArray *sections = [record_ objectForKey:@"Sections"]) { - if (![sections containsObject:section]) { + if (![sections containsObject:section]) [sections addObject:section]; - Changed_ = true; - } - } else { + } else [record_ setObject:[NSMutableArray arrayWithObject:section] forKey:@"Sections"]; - Changed_ = true; - } } - (bool) addSection:(NSString *)section { @@ -1808,10 +1783,8 @@ static void PackageImport(const void *key, const void *value, void *context) { return; if (NSMutableArray *sections = [record_ objectForKey:@"Sections"]) - if ([sections containsObject:section]) { + if ([sections containsObject:section]) [sections removeObject:section]; - Changed_ = true; - } } - (bool) removeSection:(NSString *)section { @@ -1824,7 +1797,6 @@ static void PackageImport(const void *key, const void *value, void *context) { - (void) _remove { [Sources_ removeObjectForKey:[self key]]; - Changed_ = true; } - (bool) remove { @@ -3770,6 +3742,26 @@ class CydiaLogCleaner : return [self popErrorWithTitle:title] || !success; } +- (bool) _isEtceteraAptSourcesListDirectoryCydiaListSymbolicallyLinkedToMobileCachesCydiaSourceList { + char target[1024]; + ssize_t length(readlink("/etc/apt/sources.list.d/cydia.list", target, sizeof(target) - 1)); + if (length == -1) + return false; + if (length >= sizeof(target)) + return false; + target[length] = '\0'; + return strcmp(target, "/var/mobile/Library/Caches/com.saurik.Cydia/sources.list") == 0; +} + +- (bool) popErrorWithTitle:(NSString *)title forReadList:(pkgSourceList &)list { + if ([self popErrorWithTitle:title forOperation:list.ReadMainList()]) + return true; + if (![self _isEtceteraAptSourcesListDirectoryCydiaListSymbolicallyLinkedToMobileCachesCydiaSourceList]) + if ([self popErrorWithTitle:title forOperation:list.Read(SOURCES_LIST)]) + return true; + return false; +} + - (void) reloadDataWithInvocation:(NSInvocation *)invocation { @synchronized (self) { ++era_; @@ -3814,7 +3806,7 @@ class CydiaLogCleaner : list_ = new pkgSourceList(); _profile(reloadDataWithInvocation$ReadMainList) - if ([self popErrorWithTitle:title forOperation:list_->ReadMainList()]) + if ([self popErrorWithTitle:title forReadList:*list_]) return; _end @@ -3825,7 +3817,7 @@ class CydiaLogCleaner : } _end - _root(_system->Lock()); + delock_ = GetStatusDate(); _trace(); OpProgress progress; @@ -3862,7 +3854,6 @@ class CydiaLogCleaner : } } - _system->UnLock(); return; } _trace(); @@ -4032,7 +4023,7 @@ class CydiaLogCleaner : return false; pkgSourceList list; - if ([self popErrorWithTitle:title forOperation:list.ReadMainList()]) + if ([self popErrorWithTitle:title forReadList:list]) return false; manager_ = (_system->CreatePM(cache_)); @@ -4050,7 +4041,7 @@ class CydiaLogCleaner : NSMutableArray *before = [NSMutableArray arrayWithCapacity:16]; { pkgSourceList list; - if ([self popErrorWithTitle:title forOperation:list.ReadMainList()]) + if ([self popErrorWithTitle:title forReadList:list]) return; for (pkgSourceList::const_iterator source = list.begin(); source != list.end(); ++source) [before addObject:[NSString stringWithUTF8String:(*source)->GetURI().c_str()]]; @@ -4091,8 +4082,27 @@ class CydiaLogCleaner : if (substrate) RestartSubstrate_ = true; - _system->UnLock(); + if (![delock_ isEqual:GetStatusDate()]) { + [delegate_ addProgressEventOnMainThread:[CydiaProgressEvent eventWithMessage:UCLocalize("DPKG_LOCKED") ofType:kCydiaProgressEventTypeError] forTask:title]; + return; + } + + delock_ = nil; + pkgPackageManager::OrderResult result(manager_->DoInstall(statusfd_)); + + NSString *oextended(@"/var/lib/apt/extended_states"); + NSString *nextended(Cache("extended_states")); + + struct stat info; + if (stat([nextended UTF8String], &info) != -1 && (info.st_mode & S_IFMT) == S_IFREG) { + system([[NSString stringWithFormat:@"/usr/libexec/cydia/cydo /bin/mv -f %@ %@", nextended, oextended] UTF8String]); + system([[NSString stringWithFormat:@"/usr/libexec/cydia/cydo /bin/chown 0:0 %@", oextended] UTF8String]); + } + + unlink([nextended UTF8String]); + symlink([oextended UTF8String], [nextended UTF8String]); + if ([self popErrorWithTitle:title]) return; @@ -4108,7 +4118,7 @@ class CydiaLogCleaner : NSMutableArray *after = [NSMutableArray arrayWithCapacity:16]; { pkgSourceList list; - if ([self popErrorWithTitle:title forOperation:list.ReadMainList()]) + if ([self popErrorWithTitle:title forReadList:list]) return; for (pkgSourceList::const_iterator source = list.begin(); source != list.end(); ++source) [after addObject:[NSString stringWithUTF8String:(*source)->GetURI().c_str()]]; @@ -4118,6 +4128,10 @@ class CydiaLogCleaner : [self update]; } +- (bool) delocked { + return ![delock_ isEqual:GetStatusDate()]; +} + - (bool) upgrade { NSString *title(UCLocalize("UPGRADE")); if ([self popErrorWithTitle:title forOperation:pkgDistUpgrade(cache_)]) @@ -4133,7 +4147,7 @@ class CydiaLogCleaner : NSString *title(UCLocalize("REFRESHING_DATA")); pkgSourceList list; - if ([self popErrorWithTitle:title forOperation:list.ReadMainList()]) + if ([self popErrorWithTitle:title forReadList:list]) return; FileFd lock; @@ -4148,8 +4162,10 @@ class CydiaLogCleaner : _error->Discard(); else { [self popErrorWithTitle:title forOperation:success]; - [Metadata_ setObject:[NSDate date] forKey:@"LastUpdate"]; - Changed_ = true; + + [[NSDictionary dictionaryWithObjectsAndKeys: + [NSDate date], @"LastUpdate", + nil] writeToFile:@ CacheState_ atomically:YES]; } [delegate_ performSelectorOnMainThread:@selector(releaseNetworkActivityIndicator) withObject:nil waitUntilDone:YES]; @@ -4322,7 +4338,6 @@ static _H Diversions_; @"operator", @"role", @"serial", - @"token", @"version", nil]; } @@ -4401,10 +4416,6 @@ static _H Diversions_; return [NSString stringWithUTF8String:Machine_]; } -- (NSString *) token { - return (id) Token_ ?: [NSNull null]; -} - + (NSString *) webScriptNameForSelector:(SEL)selector { if (false); else if (selector == @selector(addBridgedHost:)) @@ -4417,8 +4428,6 @@ static _H Diversions_; return @"addPipelinedHost"; else if (selector == @selector(addSource:::)) return @"addSource"; - else if (selector == @selector(addTokenHost:)) - return @"addTokenHost"; else if (selector == @selector(addTrivialSource:)) return @"addTrivialSource"; else if (selector == @selector(close)) @@ -4612,8 +4621,6 @@ static _H Diversions_; [Values_ removeObjectForKey:key]; else [Values_ setObject:value forKey:key]; - - [delegate_ performSelectorOnMainThread:@selector(updateValues) withObject:nil waitUntilDone:YES]; } } - (id) getSessionValue:(NSString *)key { @@ -4639,11 +4646,6 @@ static _H Diversions_; [InsecureHosts_ addObject:host]; } } -- (void) addTokenHost:(NSString *)host { -@synchronized (HostConfig_) { - [TokenHosts_ addObject:host]; -} } - - (void) addPipelinedHost:(NSString *)host scheme:(NSString *)scheme { @synchronized (HostConfig_) { if (scheme != (id) [WebUndefined undefined]) @@ -4806,19 +4808,8 @@ ssize_t DiskUsage(const char *path); [[objc_getClass("UIPasteboard") generalPasteboard] setURL:[NSURL URLWithString:value]]; } -- (void) _setToken:(NSString *)token { - Token_ = token; - - if (token == nil) - [Metadata_ removeObjectForKey:@"Token"]; - else - [Metadata_ setObject:Token_ forKey:@"Token"]; - - Changed_ = true; -} - - (void) setToken:(NSString *)token { - [self performSelectorOnMainThread:@selector(_setToken:) withObject:token waitUntilDone:NO]; + // XXX: the website expects this :/ } - (void) scrollToBottom:(NSNumber *)animated { @@ -4954,23 +4945,12 @@ ssize_t DiskUsage(const char *path); if (Machine_ != NULL && [copy valueForHTTPHeaderField:@"X-Machine"] == nil) [copy setValue:[NSString stringWithUTF8String:Machine_] forHTTPHeaderField:@"X-Machine"]; - bool bridged; - bool token; - - @synchronized (HostConfig_) { + bool bridged; @synchronized (HostConfig_) { bridged = [BridgedHosts_ containsObject:host]; - token = [TokenHosts_ containsObject:host]; } - if ([url isCydiaSecure]) { - if (bridged) { - if (UniqueID_ != nil && [copy valueForHTTPHeaderField:@"X-Cydia-Id"] == nil) - [copy setValue:UniqueID_ forHTTPHeaderField:@"X-Cydia-Id"]; - } else if (token) { - if (Token_ != nil && [copy valueForHTTPHeaderField:@"X-Cydia-Token"] == nil) - [copy setValue:Token_ forHTTPHeaderField:@"X-Cydia-Token"]; - } - } + if ([url isCydiaSecure] && bridged && UniqueID_ != nil && [copy valueForHTTPHeaderField:@"X-Cydia-Id"] == nil) + [copy setValue:UniqueID_ forHTTPHeaderField:@"X-Cydia-Id"]; return copy; } @@ -5150,8 +5130,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { issues_ = [NSMutableArray arrayWithCapacity:4]; - UpgradeCydia_ = false; - for (Package *package in packages) { pkgCache::PkgIterator iterator([package iterator]); NSString *name([package id]); @@ -5263,9 +5241,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [removes addObject:name]; } - if ([name isEqualToString:@"cydia"]) - UpgradeCydia_ = true; - substrate_ |= DepSubstrate(policy->GetCandidateVer(iterator)); substrate_ |= DepSubstrate(iterator.CurrentVer()); } @@ -5556,31 +5531,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) reloadSpringBoard { - if (kCFCoreFoundationVersionNumber > 700) { // XXX: iOS 6.x + if (kCFCoreFoundationVersionNumber >= 700) // XXX: iOS 6.x system("/bin/launchctl stop com.apple.backboardd"); - sleep(15); - system("/usr/bin/killall backboardd SpringBoard sbreload"); - return; - } - - pid_t pid(ExecFork()); - if (pid == 0) { - if (setsid() == -1) - perror("setsid"); - - pid_t pid(ExecFork()); - if (pid == 0) { - _root(execl("/usr/bin/sbreload", "sbreload", NULL)); - perror("sbreload"); - - exit(0); - } ReapZombie(pid); - - exit(0); - } ReapZombie(pid); - + else + system("/bin/launchctl stop com.apple.SpringBoard"); sleep(15); - system("/usr/bin/killall backboardd SpringBoard sbreload"); + system("/usr/bin/killall backboardd SpringBoard"); } - (void) close { @@ -6051,7 +6007,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } [metadata setObject:[NSNumber numberWithBool:([switch_ isOn] == NO)] forKey:@"Hidden"]; - Changed_ = true; } - (void) setSection:(Section *)section editing:(BOOL)editing { @@ -6904,7 +6859,7 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi [alert setCancelButtonIndex:0]; [alert setMessage: - @"Copyright \u00a9 2008-2014\n" + @"Copyright \u00a9 2008-2015\n" "SaurikIT, LLC\n" "\n" "Jay Freeman (saurik)\n" @@ -6983,10 +6938,6 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi } return self; } -- (void) setUpdate:(NSDate *)date { - [self beginUpdate]; -} - - (void) beginUpdate { if (updating_) return; @@ -8431,7 +8382,6 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi if (source == nil) return; [Sources_ removeObjectForKey:[source key]]; - Changed_ = true; [delegate_ _saveConfig]; [delegate_ reloadDataWithInvocation:nil]; @@ -8910,7 +8860,6 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi - (void) createDiskCachePath { [super createDiskCachePath]; - _root(chown([[self diskCachePath] UTF8String], 501, 501)); } @end @@ -9037,29 +8986,7 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi } - (void) _saveConfig { - @synchronized (database_) { - _trace(); - MetaFile_.Sync(); - _trace(); - } - - if (Changed_) { - NSString *error(nil); - - if (NSData *data = [NSPropertyListSerialization dataFromPropertyList:Metadata_ format:NSPropertyListBinaryFormat_v1_0 errorDescription:&error]) { - _trace(); - NSError *error(nil); - if (!_root([data writeToFile:@"/var/lib/cydia/metadata.plist" options:NSAtomicWrite error:&error])) - NSLog(@"failure to save metadata data: %@", error); - _trace(); - - Changed_ = false; - } else { - NSLog(@"failure to serialize metadata: %@", error); - } - } - - _root(CydiaWriteSources()); + SaveConfig(database_); } // Navigation controller for the queuing badge. @@ -9086,9 +9013,11 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi [[navigation tabBarItem] setBadgeValue:(Queuing_ ? UCLocalize("Q_D") : nil)]; } -- (void) _refreshIfPossible:(NSDate *)update { +- (void) _refreshIfPossible { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSDate *update([[NSDictionary dictionaryWithContentsOfFile:@ CacheState_] objectForKey:@"LastUpdate"]); + bool recently = false; if (update != nil) { NSTimeInterval interval([update timeIntervalSinceNow]); @@ -9110,14 +9039,14 @@ static void HomeControllerReachabilityCallback(SCNetworkReachabilityRef reachabi // We are going to load, so remember that. loaded_ = true; - [tabbar_ performSelectorOnMainThread:@selector(setUpdate:) withObject:update waitUntilDone:NO]; + [tabbar_ performSelectorOnMainThread:@selector(beginUpdate) withObject:nil waitUntilDone:NO]; } [pool release]; } - (void) refreshIfPossible { - [NSThread detachNewThreadSelector:@selector(_refreshIfPossible:) toTarget:self withObject:[Metadata_ objectForKey:@"LastUpdate"]]; + [NSThread detachNewThreadSelector:@selector(_refreshIfPossible) toTarget:self withObject:nil]; } - (void) reloadDataWithInvocation:(NSInvocation *)invocation { @@ -9269,10 +9198,6 @@ _end CydiaAddSource(href, @"./"); } -- (void) updateValues { - Changed_ = true; -} - - (void) resolve { pkgProblemResolver *resolver = [database_ resolver]; @@ -9352,14 +9277,7 @@ _end - (void) _uicache { _trace(); - - if (UpgradeCydia_ && Finish_ > 0) { - setreugid(0, 0); - system("su -c /usr/bin/uicache mobile"); - } else { - system("/usr/bin/uicache"); - } - + system("/usr/bin/uicache"); _trace(); } @@ -9432,14 +9350,7 @@ _end @synchronized (self) { for (Package *broken in (id) broken_) { [broken remove]; - NSString *id = [broken id]; - - _root({ - unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.prerm", id] UTF8String]); - unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.postrm", id] UTF8String]); - unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.preinst", id] UTF8String]); - unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.postinst", id] UTF8String]); - }); + system([[NSString stringWithFormat:@"/usr/libexec/cydia/cydo /usr/libexec/cydia/fixhalf.sh %@", [broken id]] UTF8String]); } [self resolve]; @@ -9474,7 +9385,7 @@ _end NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]); _trace(); - _root(system([command UTF8String])); + system([command UTF8String]); _trace(); [pool release]; @@ -9710,10 +9621,11 @@ _end } - (void) saveState { - [Metadata_ setObject:[tabbar_ navigationURLCollection] forKey:@"InterfaceState"]; - [Metadata_ setObject:[NSDate date] forKey:@"LastClosed"]; - [Metadata_ setObject:[NSNumber numberWithInt:[tabbar_ selectedIndex]] forKey:@"InterfaceIndex"]; - Changed_ = true; + [[NSDictionary dictionaryWithObjectsAndKeys: + @"InterfaceState", [tabbar_ navigationURLCollection], + @"LastClosed", [NSDate date], + @"InterfaceIndex", [NSNumber numberWithInt:[tabbar_ selectedIndex]], + nil] writeToFile:@ SavedState_ atomically:YES]; [self _saveConfig]; } @@ -9725,15 +9637,15 @@ _end - (void) applicationDidEnterBackground:(UIApplication *)application { if (kCFCoreFoundationVersionNumber < 1000 && [self isSafeToSuspend]) return [self terminateWithSuccess]; + Backgrounded_ = [NSDate date]; [self saveState]; } - (void) applicationWillEnterForeground:(UIApplication *)application { - NSDate *closed = [Metadata_ objectForKey:@"LastClosed"]; - if (closed == nil) + if (Backgrounded_ == nil) return; - NSTimeInterval interval([closed timeIntervalSinceNow]); + NSTimeInterval interval([Backgrounded_ timeIntervalSinceNow]); if (interval <= -(30*60)) { [tabbar_ setSelectedIndex:0]; @@ -9746,6 +9658,9 @@ _end [appcache_ reloadURLWithCache:YES]; } } + + if ([database_ delocked]) + [self reloadData]; } - (void) setConfigurationData:(NSString *)data { @@ -9790,7 +9705,7 @@ _end - (void) stash { [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque]; UpdateExternalStatus(1); - [self yieldToSelector:@selector(system:) withObject:@"/usr/libexec/cydia/free.sh"]; + [self yieldToSelector:@selector(system:) withObject:@"/usr/libexec/cydia/cydo /usr/libexec/cydia/free.sh"]; UpdateExternalStatus(0); [self removeStashController]; @@ -9979,8 +9894,10 @@ _trace(); [self refreshIfPossible]; [self disemulate]; - int savedIndex = [[Metadata_ objectForKey:@"InterfaceIndex"] intValue]; - NSArray *saved = [[[Metadata_ objectForKey:@"InterfaceState"] mutableCopy] autorelease]; + NSDictionary *state([NSDictionary dictionaryWithContentsOfFile:@ SavedState_]); + + int savedIndex = [[state objectForKey:@"InterfaceIndex"] intValue]; + NSArray *saved = [[[state objectForKey:@"InterfaceState"] mutableCopy] autorelease]; int standardIndex = 0; NSArray *standard = [self defaultStartPages]; @@ -9989,7 +9906,7 @@ _trace(); if (saved == nil) valid = NO; - NSDate *closed = [Metadata_ objectForKey:@"LastClosed"]; + NSDate *closed = [state objectForKey:@"LastClosed"]; if (valid && closed != nil) { NSTimeInterval interval([closed timeIntervalSinceNow]); if (interval <= -(30*60)) @@ -10138,7 +10055,9 @@ MSHook(id, NSUserDefaults$objectForKey$, NSUserDefaults *self, SEL _cmd, NSStrin } int main(int argc, char *argv[]) { - setreugid(501, 501); + int fd(open("/tmp/cydia.log", O_WRONLY | O_APPEND | O_CREAT, 0644)); + dup2(fd, 2); + close(fd); NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]); @@ -10173,7 +10092,6 @@ int main(int argc, char *argv[]) { HostConfig_ = [[[NSObject alloc] init] autorelease]; @synchronized (HostConfig_) { BridgedHosts_ = [NSMutableSet setWithCapacity:4]; - TokenHosts_ = [NSMutableSet setWithCapacity:4]; InsecureHosts_ = [NSMutableSet setWithCapacity:4]; PipelinedHosts_ = [NSMutableSet setWithCapacity:4]; CachedURLs_ = [NSMutableSet setWithCapacity:32]; @@ -10383,45 +10301,49 @@ int main(int argc, char *argv[]) { UserAgent_ = agent; /* }}} */ /* Load Database {{{ */ - _trace(); - Metadata_ = [[[NSMutableDictionary alloc] initWithContentsOfFile:@"/var/lib/cydia/metadata.plist"] autorelease]; - _trace(); SectionMap_ = [[[NSDictionary alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Sections" ofType:@"plist"]] autorelease]; - if (Metadata_ == NULL) - Metadata_ = [NSMutableDictionary dictionaryWithCapacity:2]; - else { - Settings_ = [Metadata_ objectForKey:@"Settings"]; - - Packages_ = [Metadata_ objectForKey:@"Packages"]; - - Values_ = [Metadata_ objectForKey:@"Values"]; - Sections_ = [Metadata_ objectForKey:@"Sections"]; - Sources_ = [Metadata_ objectForKey:@"Sources"]; + _trace(); + mkdir("/var/mobile/Library/Cydia", 0755); + MetaFile_.Open("/var/mobile/Library/Cydia/metadata.cb0"); + _trace(); - Token_ = [Metadata_ objectForKey:@"Token"]; + // XXX: port this to NSUserDefaults when you aren't in such a rush + Values_ = [[[(NSDictionary *) CFPreferencesCopyAppValue(CFSTR("CydiaValues"), CFSTR("com.saurik.Cydia")) autorelease] mutableCopy] autorelease]; + Sections_ = [[[(NSDictionary *) CFPreferencesCopyAppValue(CFSTR("CydiaSections"), CFSTR("com.saurik.Cydia")) autorelease] mutableCopy] autorelease]; + Sources_ = [[[(NSDictionary *) CFPreferencesCopyAppValue(CFSTR("CydiaSources"), CFSTR("com.saurik.Cydia")) autorelease] mutableCopy] autorelease]; + Version_ = [(NSNumber *) CFPreferencesCopyAppValue(CFSTR("CydiaVersion"), CFSTR("com.saurik.Cydia")) autorelease]; - Version_ = [Metadata_ objectForKey:@"Version"]; - } + _trace(); + NSDictionary *metadata([[[NSMutableDictionary alloc] initWithContentsOfFile:@"/var/lib/cydia/metadata.plist"] autorelease]); - if (Values_ == nil) { + if (Values_ == nil) + Values_ = [metadata objectForKey:@"Values"]; + if (Values_ == nil) Values_ = [[[NSMutableDictionary alloc] initWithCapacity:4] autorelease]; - [Metadata_ setObject:Values_ forKey:@"Values"]; - } - if (Sections_ == nil) { + if (Sections_ == nil) + Sections_ = [metadata objectForKey:@"Sections"]; + if (Sections_ == nil) Sections_ = [[[NSMutableDictionary alloc] initWithCapacity:32] autorelease]; - [Metadata_ setObject:Sections_ forKey:@"Sections"]; - } - if (Sources_ == nil) { + if (Sources_ == nil) + Sources_ = [metadata objectForKey:@"Sources"]; + if (Sources_ == nil) Sources_ = [[[NSMutableDictionary alloc] initWithCapacity:0] autorelease]; - [Metadata_ setObject:Sources_ forKey:@"Sources"]; - } - if (Version_ == nil) { + // XXX: this wrong, but in a way that doesn't matter :/ + if (Version_ == nil) + Version_ = [metadata objectForKey:@"Version"]; + if (Version_ == nil) Version_ = [NSNumber numberWithUnsignedInt:0]; - [Metadata_ setObject:Version_ forKey:@"Version"]; + + if (NSDictionary *packages = [metadata objectForKey:@"Packages"]) { + bool fail(false); + CFDictionaryApplyFunction((CFDictionaryRef) packages, &PackageImport, &fail); + _trace(); + if (fail) + NSLog(@"unable to import package preferences... from 2010? oh well :/"); } if ([Version_ unsignedIntValue] == 0) { @@ -10431,68 +10353,36 @@ int main(int argc, char *argv[]) { CydiaAddSource(@"http://repo666.ultrasn0w.com/", @"./"); Version_ = [NSNumber numberWithUnsignedInt:1]; - [Metadata_ setObject:Version_ forKey:@"Version"]; - [Metadata_ removeObjectForKey:@"LastUpdate"]; - - Changed_ = true; + if (NSMutableDictionary *cache = [NSMutableDictionary dictionaryWithContentsOfFile:@ CacheState_]) { + [cache removeObjectForKey:@"LastUpdate"]; + [cache writeToFile:@ CacheState_ atomically:YES]; + } } _H broken([NSMutableArray array]); for (NSString *key in (id) Sources_) if ([key rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"# "]].location != NSNotFound) [broken addObject:key]; - if ([broken count] != 0) { + if ([broken count] != 0) for (NSString *key in (id) broken) [Sources_ removeObjectForKey:key]; - Changed_ = true; - } broken = nil; - /* }}} */ - - _root(CydiaWriteSources()); - - _trace(); - mkdir("/var/mobile/Library/Cydia", 0755); - MetaFile_.Open("/var/mobile/Library/Cydia/metadata.cb0"); - _trace(); - - if (Packages_ != nil) { - bool fail(false); - CFDictionaryApplyFunction((CFDictionaryRef) Packages_, &PackageImport, &fail); - _trace(); + broken = nil; - if (!fail) { - [Metadata_ removeObjectForKey:@"Packages"]; - Packages_ = nil; - Changed_ = true; - } - } + SaveConfig(nil); + system("/usr/libexec/cydia/cydo /bin/rm -f /var/lib/cydia/metadata.plist"); + /* }}} */ Finishes_ = [NSArray arrayWithObjects:@"return", @"reopen", @"restart", @"reload", @"reboot", nil]; -#define MobileSubstrate_(name) \ - if (substrate && access("/Library/MobileSubstrate/DynamicLibraries/" #name ".dylib", F_OK) == 0) { \ - void *handle(dlopen("/Library/MobileSubstrate/DynamicLibraries/" #name ".dylib", RTLD_LAZY | RTLD_GLOBAL)); \ - if (handle == NULL) \ - NSLog(@"%s", dlerror()); \ - } - - MobileSubstrate_(Activator) - MobileSubstrate_(libstatusbar) - MobileSubstrate_(SimulatedKeyEvents) - MobileSubstrate_(WinterBoard) - - /*if (substrate && access("/Library/MobileSubstrate/MobileSubstrate.dylib", F_OK) == 0) - dlopen("/Library/MobileSubstrate/MobileSubstrate.dylib", RTLD_LAZY | RTLD_GLOBAL);*/ - if (kCFCoreFoundationVersionNumber > 1000) - _root(system([[NSString stringWithFormat:@"/usr/libexec/cydia/setnsfpn /var/lib"] UTF8String])); + system("/usr/libexec/cydia/cydo /usr/libexec/cydia/setnsfpn /var/lib"); int version([[NSString stringWithContentsOfFile:@"/var/lib/cydia/firmware.ver"] intValue]); if (access("/User", F_OK) != 0 || version != 6) { _trace(); - _root(system("/usr/libexec/cydia/firmware.sh")); + system("/usr/libexec/cydia/cydo /usr/libexec/cydia/firmware.sh"); _trace(); } @@ -10520,6 +10410,9 @@ int main(int argc, char *argv[]) { mkdir([Cache("archives/partial") UTF8String], 0755); _config->Set("Dir::Cache", [Cache_ UTF8String]); + symlink("/var/lib/apt/extended_states", [Cache("extended_states") UTF8String]); + _config->Set("Dir::State", [Cache_ UTF8String]); + mkdir([Cache("lists") UTF8String], 0755); mkdir([Cache("lists/partial") UTF8String], 0755); mkdir([Cache("periodic") UTF8String], 0755); @@ -10553,13 +10446,6 @@ int main(int argc, char *argv[]) { //UIKeyboardDisableAutomaticAppearance(); /* }}} */ - _root({ - chown([Cache("ApplicationCache.db") UTF8String], 501, 501); - chown([Cache("Cache.db") UTF8String], 501, 501); - chown([Cache("Cache.db-shm") UTF8String], 501, 501); - chown([Cache("Cache.db-wal") UTF8String], 501, 501); - }); - $SBSSetInterceptsMenuButtonForever = reinterpret_cast(dlsym(RTLD_DEFAULT, "SBSSetInterceptsMenuButtonForever")); const char *symbol(kCFCoreFoundationVersionNumber >= 800 ? "MGGetBoolAnswer" : "GSSystemHasCapability");