/* 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 {{{ */
};
// }}}
-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_;
static int Finish_;
static bool RestartSubstrate_;
-static bool UpgradeCydia_;
static NSArray *Finishes_;
#define SpringBoard_ "/System/Library/LaunchDaemons/com.apple.SpringBoard.plist"
static NSString *SerialNumber_ = nil;
static NSString *ChipID_ = nil;
static NSString *BBSNum_ = nil;
-static _H<NSString> Token_;
static _H<NSString> UniqueID_;
static _H<NSString> UserAgent_;
static _H<NSString> Product_;
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<NSDate> Backgrounded_;
static _transient NSMutableDictionary *Values_;
static _transient NSMutableDictionary *Sections_;
_H<NSMutableDictionary> Sources_;
static _transient NSNumber *Version_;
-bool Changed_;
static time_t now_;
bool IsWildcat_;
static _H<NSMutableDictionary> SessionData_;
static _H<NSObject> HostConfig_;
static _H<NSMutableSet> BridgedHosts_;
-static _H<NSMutableSet> TokenHosts_;
static _H<NSMutableSet> InsecureHosts_;
static _H<NSMutableSet> PipelinedHosts_;
static _H<NSMutableSet> CachedURLs_;
}
/* }}} */
-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"]);
CYPool pool_;
unsigned era_;
+ _H<NSDate> delock_;
pkgCacheFile cache_;
pkgDepCache::Policy *policy_;
}
// }}}
+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_;
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 {
return;
if (NSMutableArray *sections = [record_ objectForKey:@"Sections"])
- if ([sections containsObject:section]) {
+ if ([sections containsObject:section])
[sections removeObject:section];
- Changed_ = true;
- }
}
- (bool) removeSection:(NSString *)section {
- (void) _remove {
[Sources_ removeObjectForKey:[self key]];
- Changed_ = true;
}
- (bool) remove {
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_;
list_ = new pkgSourceList();
_profile(reloadDataWithInvocation$ReadMainList)
- if ([self popErrorWithTitle:title forOperation:list_->ReadMainList()])
+ if ([self popErrorWithTitle:title forReadList:*list_])
return;
_end
}
_end
- _root(_system->Lock());
+ delock_ = GetStatusDate();
_trace();
OpProgress progress;
}
}
- _system->UnLock();
return;
}
_trace();
} }
- (void) configure {
- NSString *dpkg = [NSString stringWithFormat:@"dpkg --configure -a --status-fd %u", statusfd_];
+ NSString *dpkg = [NSString stringWithFormat:@"/usr/libexec/cydo --configure -a --status-fd %u", statusfd_];
_trace();
- _root(system([dpkg UTF8String]));
+ system([dpkg UTF8String]);
_trace();
}
return false;
pkgSourceList list;
- if ([self popErrorWithTitle:title forOperation:list.ReadMainList()])
+ if ([self popErrorWithTitle:title forReadList:list])
return false;
manager_ = (_system->CreatePM(cache_));
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()]];
if (substrate)
RestartSubstrate_ = true;
- _system->UnLock();
- pkgPackageManager::OrderResult result(_root(manager_->DoInstall(statusfd_)));
+ 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;
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()]];
[self update];
}
+- (bool) delocked {
+ return ![delock_ isEqual:GetStatusDate()];
+}
+
- (bool) upgrade {
NSString *title(UCLocalize("UPGRADE"));
if ([self popErrorWithTitle:title forOperation:pkgDistUpgrade(cache_)])
NSString *title(UCLocalize("REFRESHING_DATA"));
pkgSourceList list;
- if ([self popErrorWithTitle:title forOperation:list.ReadMainList()])
+ if ([self popErrorWithTitle:title forReadList:list])
return;
FileFd lock;
_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];
@"operator",
@"role",
@"serial",
- @"token",
@"version",
nil];
}
return [NSString stringWithUTF8String:Machine_];
}
-- (NSString *) token {
- return (id) Token_ ?: [NSNull null];
-}
-
+ (NSString *) webScriptNameForSelector:(SEL)selector {
if (false);
else if (selector == @selector(addBridgedHost:))
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))
[Values_ removeObjectForKey:key];
else
[Values_ setObject:value forKey:key];
-
- [delegate_ performSelectorOnMainThread:@selector(updateValues) withObject:nil waitUntilDone:YES];
} }
- (id) getSessionValue:(NSString *)key {
[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])
[[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 {
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;
}
issues_ = [NSMutableArray arrayWithCapacity:4];
- UpgradeCydia_ = false;
-
for (Package *package in packages) {
pkgCache::PkgIterator iterator([package iterator]);
NSString *name([package id]);
[removes addObject:name];
}
- if ([name isEqualToString:@"cydia"])
- UpgradeCydia_ = true;
-
substrate_ |= DepSubstrate(policy->GetCandidateVer(iterator));
substrate_ |= DepSubstrate(iterator.CurrentVer());
}
}
- (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 {
}
[metadata setObject:[NSNumber numberWithBool:([switch_ isOn] == NO)] forKey:@"Hidden"];
- Changed_ = true;
}
- (void) setSection:(Section *)section editing:(BOOL)editing {
[alert setCancelButtonIndex:0];
[alert setMessage:
- @"Copyright \u00a9 2008-2014\n"
+ @"Copyright \u00a9 2008-2015\n"
"SaurikIT, LLC\n"
"\n"
"Jay Freeman (saurik)\n"
} return self;
}
-- (void) setUpdate:(NSDate *)date {
- [self beginUpdate];
-}
-
- (void) beginUpdate {
if (updating_)
return;
pid_t pid(ExecFork());
if (pid == 0) {
- FILE *dpkg(_root(popen("dpkg --set-selections", "w")));
+ FILE *dpkg(popen("/usr/libexec/cydo --set-selections", "w"));
fwrite(package, strlen(package), 1, dpkg);
if (on)
if (source == nil) return;
[Sources_ removeObjectForKey:[source key]];
- Changed_ = true;
[delegate_ _saveConfig];
[delegate_ reloadDataWithInvocation:nil];
- (void) createDiskCachePath {
[super createDiskCachePath];
- _root(chown([[self diskCachePath] UTF8String], 501, 501));
}
@end
}
- (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.
[[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]);
// 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 {
CydiaAddSource(href, @"./");
}
-- (void) updateValues {
- Changed_ = true;
-}
-
- (void) resolve {
pkgProblemResolver *resolver = [database_ resolver];
- (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();
}
@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];
NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]);
_trace();
- _root(system([command UTF8String]));
+ system([command UTF8String]);
_trace();
[pool release];
}
- (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];
}
- (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];
[appcache_ reloadURLWithCache:YES];
}
}
+
+ if ([database_ delocked])
+ [self reloadData];
}
- (void) setConfigurationData:(NSString *)data {
- (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];
[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];
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))
}
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]);
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];
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) {
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<NSMutableArray> 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());
+ broken = nil;
- _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();
-
- 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();
}
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);
_config->Set("Dir::State::Lists", [Cache("lists") UTF8String]);
+
+ std::string logs("/var/mobile/Library/Logs/Cydia");
+ mkdir(logs.c_str(), 0755);
+ _config->Set("Dir::Log::Terminal", logs + "/apt.log");
+
+ _config->Set("Dir::Bin::dpkg", "/usr/libexec/cydia/cydo");
/* }}} */
/* Color Choices {{{ */
space_ = CGColorSpaceCreateDeviceRGB();
//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<void (*)(bool)>(dlsym(RTLD_DEFAULT, "SBSSetInterceptsMenuButtonForever"));
const char *symbol(kCFCoreFoundationVersionNumber >= 800 ? "MGGetBoolAnswer" : "GSSystemHasCapability");