X-Git-Url: https://git.saurik.com/cydia.git/blobdiff_plain/b6f9e52acfe57d119e3f85cd5982497be0a491e8..68bd7c60c69be8fbf1d8a5ef7dc8ca62883351a5:/MobileCydia.mm diff --git a/MobileCydia.mm b/MobileCydia.mm index 6b23cf5e..d8f39d7b 100644 --- a/MobileCydia.mm +++ b/MobileCydia.mm @@ -66,6 +66,8 @@ #include +#include + #include #include @@ -119,6 +121,7 @@ extern "C" { #include #include +#include "Sources.h" #include #include "Menes/Menes.h" @@ -206,8 +209,7 @@ void PrintTimes() { #define _end } /* }}} */ -#include "Version.h" -#define Cydia_ CYDIA_VERSION +extern NSString *Cydia_; #define lprintf(args...) fprintf(stderr, args) @@ -263,6 +265,15 @@ static _finline NSString *CydiaURL(NSString *path) { return [[NSString stringWithUTF8String:page] stringByAppendingString:path]; } +static void ReapZombie(pid_t pid) { + int status; + wait: + if (waitpid(pid, &status, 0) == -1) + if (errno == EINTR) + goto wait; + else _assert(false); +} + static _finline void UpdateExternalStatus(uint64_t newStatus) { int notify_token; if (notify_register_check("com.saurik.Cydia.status", ¬ify_token) == NOTIFY_STATUS_OK) { @@ -272,9 +283,9 @@ static _finline void UpdateExternalStatus(uint64_t newStatus) { notify_post("com.saurik.Cydia.status"); } -static CGFloat CYStatusBarHeight(UIInterfaceOrientation orientation) { +static CGFloat CYStatusBarHeight() { CGSize size([[UIApplication sharedApplication] statusBarFrame].size); - return UIInterfaceOrientationIsPortrait(orientation) ? size.height : size.width; + return UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]) ? size.height : size.width; } /* NSForcedOrderingSearch doesn't work on the iPhone */ @@ -402,7 +413,6 @@ NSUInteger DOMNodeList$countByEnumeratingWithState$objects$count$(DOMNodeList *s /* Cydia NSString Additions {{{ */ @interface NSString (Cydia) - (NSComparisonResult) compareByPath:(NSString *)other; -- (NSString *) stringByCachingURLWithCurrentCDN; - (NSString *) stringByAddingPercentEscapesIncludingReserved; @end @@ -438,13 +448,6 @@ NSUInteger DOMNodeList$countByEnumeratingWithState$objects$count$(DOMNodeList *s return result == NSOrderedSame ? value : result; } -- (NSString *) stringByCachingURLWithCurrentCDN { - return [self - stringByReplacingOccurrencesOfString:@"://cydia.saurik.com/" - withString:@"://cache.cydia.saurik.com/" - ]; -} - - (NSString *) stringByAddingPercentEscapesIncludingReserved { return [(id)CFURLCreateStringByAddingPercentEscapes( kCFAllocatorDefault, @@ -682,16 +685,15 @@ static _H Font18Bold_; static _H Font22Bold_; static const char *Machine_ = NULL; -static NSString *System_ = nil; +static _H System_; static NSString *SerialNumber_ = nil; static NSString *ChipID_ = nil; static NSString *BBSNum_ = nil; static _H Token_; static NSString *UniqueID_ = nil; -static NSString *PLMN_ = nil; -static NSString *Build_ = nil; -static NSString *Product_ = nil; -static NSString *Safari_ = nil; +static _H UserAgent_; +static _H Product_; +static _H Safari_; static CFLocaleRef Locale_; static NSArray *Languages_; @@ -704,15 +706,16 @@ static _transient NSString *Role_; static _transient NSMutableDictionary *Packages_; static _transient NSMutableDictionary *Values_; static _transient NSMutableDictionary *Sections_; -static _transient NSMutableDictionary *Sources_; +_H Sources_; static _transient NSNumber *Version_; -static _transient _H CydiaSource_; -static bool Changed_; +bool Changed_; static time_t now_; bool IsWildcat_; static CGFloat ScreenScale_; static NSString *Idiom_; +static _H Firmware_; +static NSString *Major_; static _H SessionData_; static _H HostConfig_; @@ -728,45 +731,6 @@ static NSString *kCydiaProgressEventTypeStatus = @"Status"; static NSString *kCydiaProgressEventTypeWarning = @"Warning"; /* }}} */ -static void AddSource(NSDictionary *source) { - [Sources_ setObject:source forKey:[NSString stringWithFormat:@"%@:%@:%@", [source objectForKey:@"Type"], [source objectForKey:@"URI"], [source objectForKey:@"Distribution"]]]; - Changed_ = true; -} - -static void AddSource(NSString *href, NSString *distribution, NSArray *sections = nil) { - AddSource([NSMutableDictionary dictionaryWithObjectsAndKeys: - @"deb", @"Type", - href, @"URI", - distribution, @"Distribution", - sections ?: [NSMutableArray array], @"Sections", - nil]); -} - -static void WriteSources() { - FILE *file(fopen("/etc/apt/sources.list.d/cydia.list", "w")); - _assert(file != NULL); - - fprintf(file, "deb http://%s/ tangelo-3.7 main\n", - [CydiaSource_ UTF8String] - ); - - for (NSString *key in [Sources_ allKeys]) { - NSDictionary *source([Sources_ objectForKey:key]); - - NSArray *sections([source objectForKey:@"Sections"] ?: [NSArray array]); - - fprintf(file, "%s %s %s%s%s\n", - [[source objectForKey:@"Type"] UTF8String], - [[source objectForKey:@"URI"] UTF8String], - [[source objectForKey:@"Distribution"] UTF8String], - [sections count] == 0 ? "" : " ", - [[sections componentsJoinedByString:@" "] UTF8String] - ); - } - - fclose(file); -} - /* Display Helpers {{{ */ inline float Interpolate(float begin, float end, float fraction) { return (end - begin) * fraction + begin; @@ -1343,7 +1307,7 @@ static void PackageImport(const void *key, const void *value, void *context) { - (Source *) initWithMetaIndex:(metaIndex *)index forDatabase:(Database *)database inPool:(apr_pool_t *)pool; -- (NSComparisonResult) compareByNameAndType:(Source *)source; +- (NSComparisonResult) compareByName:(Source *)source; - (NSString *) depictionForPackage:(NSString *)package; - (NSString *) supportForPackage:(NSString *)package; @@ -1351,12 +1315,10 @@ static void PackageImport(const void *key, const void *value, void *context) { - (NSDictionary *) record; - (BOOL) trusted; -- (NSString *) uri; +- (NSString *) rooturi; - (NSString *) distribution; - (NSString *) type; -- (NSString *) base; - - (NSString *) key; - (NSString *) host; @@ -1367,6 +1329,7 @@ static void PackageImport(const void *key, const void *value, void *context) { - (NSString *) version; - (NSString *) defaultIcon; +- (NSURL *) iconURL; @end @@ -1412,17 +1375,19 @@ static void PackageImport(const void *key, const void *value, void *context) { + (NSArray *) _attributeKeys { return [NSArray arrayWithObjects: + @"baseuri", @"distribution", @"host", @"key", + @"iconuri", @"label", @"name", @"origin", + @"rooturi", @"sections", @"shortDescription", @"trusted", @"type", - @"uri", @"version", nil]; } @@ -1532,13 +1497,7 @@ static void PackageImport(const void *key, const void *value, void *context) { return [NSString stringWithString:[(NSString *) CYStringCreate(start, end - start) autorelease]]; } } -- (NSComparisonResult) compareByNameAndType:(Source *)source { - NSDictionary *lhr = [self record]; - NSDictionary *rhr = [source record]; - - if ((lhr == nil) != (rhr == nil)) - return lhr == nil ? NSOrderedDescending : NSOrderedAscending; - +- (NSComparisonResult) compareByName:(Source *)source { NSString *lhs = [self name]; NSString *rhs = [source name]; @@ -1627,7 +1586,7 @@ static void PackageImport(const void *key, const void *value, void *context) { return trusted_; } -- (NSString *) uri { +- (NSString *) rooturi { return uri_; } @@ -1639,8 +1598,21 @@ static void PackageImport(const void *key, const void *value, void *context) { return type_; } -- (NSString *) base { - return base_; +- (NSString *) baseuri { + return base_.empty() ? nil : (id) base_; +} + +- (NSString *) iconuri { + if (NSString *base = [self baseuri]) + return [base stringByAppendingString:@"CydiaIcon.png"]; + + return nil; +} + +- (NSURL *) iconURL { + if (NSString *uri = [self iconuri]) + return [NSURL URLWithString:uri]; + return nil; } - (NSString *) key { @@ -1835,6 +1807,7 @@ static void PackageImport(const void *key, const void *value, void *context) { /* }}} */ /* Package Class {{{ */ struct ParsedPackage { + CYString md5sum_; CYString tagline_; CYString architecture_; @@ -1851,11 +1824,12 @@ struct ParsedPackage { }; @interface Package : NSObject { - uint32_t era_ : 26; + uint32_t era_ : 25; uint32_t role_ : 3; uint32_t essential_ : 1; uint32_t obsolete_ : 1; uint32_t ignored_ : 1; + uint32_t pooled_ : 1; apr_pool_t *pool_; @@ -2102,6 +2076,8 @@ struct PackageNameOrdering : } - (void) dealloc { + if (!pooled_) + apr_pool_destroy(pool_); if (parsed_ != NULL) delete parsed_; [super dealloc]; @@ -2142,6 +2118,7 @@ struct PackageNameOrdering : @"longDescription", @"longSection", @"maintainer", + @"md5sum", @"mode", @"name", @"purposes", @@ -2230,6 +2207,7 @@ struct PackageNameOrdering : {"support", &parsed->support_}, {"sponsor", &parsed->sponsor_}, {"author", &parsed->author_}, + {"md5sum", &parsed->md5sum_}, }; for (size_t i(0); i != sizeof(names) / sizeof(names[0]); ++i) { @@ -2268,7 +2246,12 @@ struct PackageNameOrdering : - (Package *) initWithVersion:(pkgCache::VerIterator)version withZone:(NSZone *)zone inPool:(apr_pool_t *)pool database:(Database *)database { if ((self = [super init]) != nil) { _profile(Package$initWithVersion) - pool_ = pool; + if (pool == NULL) + apr_pool_create(&pool_, NULL); + else { + pool_ = pool; + pooled_ = true; + } database_ = database; era_ = [database era]; @@ -2459,6 +2442,10 @@ struct PackageNameOrdering : return maintainer.empty() ? nil : [MIMEAddress addressWithString:[NSString stringWithUTF8String:maintainer.c_str()]]; } } +- (NSString *) md5sum { + return parsed_ == NULL ? nil : (id) parsed_->md5sum_; +} + - (size_t) size { @synchronized (database_) { if ([database_ era] != era_ || version_.end()) @@ -2631,11 +2618,19 @@ struct PackageNameOrdering : } - (BOOL) hasMode { +@synchronized (database_) { + if ([database_ era] != era_ || iterator_.end()) + return nil; + pkgDepCache::StateCache &state([database_ cache][iterator_]); return state.Mode != pkgDepCache::ModeKeep; -} +} } - (NSString *) mode { +@synchronized (database_) { + if ([database_ era] != era_ || iterator_.end()) + return nil; + pkgDepCache::StateCache &state([database_ cache][iterator_]); switch (state.Mode) { @@ -2667,7 +2662,7 @@ struct PackageNameOrdering : } _nodefault } -} +} } - (NSString *) id { return id_; @@ -3342,7 +3337,7 @@ class CydiaLogCleaner : if (static_cast(cache_) == NULL) return nil; pkgCache::PkgIterator iterator(cache_->FindPkg([name UTF8String])); - return iterator.end() ? nil : [Package packageWithIterator:iterator withZone:NULL inPool:pool_ database:self]; + return iterator.end() ? nil : [Package packageWithIterator:iterator withZone:NULL inPool:NULL database:self]; } } - (id) init { @@ -3463,6 +3458,10 @@ class CydiaLogCleaner : lprintf("%c:[%s]\n", warning ? 'W' : 'E', error.c_str()); + static Pcre no_pubkey("^GPG error:.* NO_PUBKEY .*$"); + if (warning && no_pubkey(error.c_str())) + continue; + [delegate_ addProgressEventOnMainThread:[CydiaProgressEvent eventWithMessage:[NSString stringWithUTF8String:error.c_str()] ofType:(warning ? kCydiaProgressEventTypeWarning : kCydiaProgressEventTypeError)] forTask:title]; } @@ -3955,14 +3954,17 @@ static _H Diversions_; + (NSArray *) _attributeKeys { return [NSArray arrayWithObjects: @"bbsnum", - @"cydiaSource", + @"build", + @"coreFoundationVersionNumber", @"device", @"ecid", @"firmware", @"hostname", @"idiom", + @"mcc", + @"mnc", @"model", - @"plmn", + @"operator", @"role", @"serial", @"token", @@ -3979,7 +3981,15 @@ static _H Diversions_; } - (NSString *) version { - return @ Cydia_; + return Cydia_; +} + +- (NSString *) build { + return System_; +} + +- (NSString *) coreFoundationVersionNumber { + return [NSString stringWithFormat:@"%.2f", kCFCoreFoundationVersionNumber]; } - (NSString *) device { @@ -3998,8 +4008,22 @@ static _H Diversions_; return (id) Idiom_ ?: [NSNull null]; } -- (NSString *) plmn { - return (id) PLMN_ ?: [NSNull null]; +- (NSString *) mcc { + if (CFStringRef (*$CTSIMSupportCopyMobileSubscriberCountryCode)(CFAllocatorRef) = reinterpret_cast(dlsym(RTLD_DEFAULT, "CTSIMSupportCopyMobileSubscriberCountryCode"))) + return [(NSString *) (*$CTSIMSupportCopyMobileSubscriberCountryCode)(kCFAllocatorDefault) autorelease]; + return nil; +} + +- (NSString *) mnc { + if (CFStringRef (*$CTSIMSupportCopyMobileSubscriberNetworkCode)(CFAllocatorRef) = reinterpret_cast(dlsym(RTLD_DEFAULT, "CTSIMSupportCopyMobileSubscriberNetworkCode"))) + return [(NSString *) (*$CTSIMSupportCopyMobileSubscriberNetworkCode)(kCFAllocatorDefault) autorelease]; + return nil; +} + +- (NSString *) operator { + if (CFStringRef (*$CTRegistrationCopyOperatorName)(CFAllocatorRef) = reinterpret_cast(dlsym(RTLD_DEFAULT, "CTRegistrationCopyOperatorName"))) + return [(NSString *) (*$CTRegistrationCopyOperatorName)(kCFAllocatorDefault) autorelease]; + return nil; } - (NSString *) bbsnum { @@ -4082,8 +4106,6 @@ static _H Diversions_; return @"removeButton"; else if (selector == @selector(saveConfig)) return @"saveConfig"; - else if (selector == @selector(setCydiaSource:)) - return @"setCydiaSource"; else if (selector == @selector(setMetadataValue::)) return @"setMetadataValue"; else if (selector == @selector(setSessionValue::)) @@ -4112,6 +4134,10 @@ static _H Diversions_; return @"setPasteboardString"; else if (selector == @selector(setPasteboardURL:)) return @"setPasteboardURL"; + else if (selector == @selector(setScrollAlwaysBounceVertical:)) + return @"setScrollAlwaysBounceVertical"; + else if (selector == @selector(setScrollIndicatorStyle:)) + return @"setScrollIndicatorStyle"; else if (selector == @selector(setToken:)) return @"setToken"; else if (selector == @selector(setViewportWidth:)) @@ -4138,6 +4164,14 @@ static _H Diversions_; [delegate_ performSelectorOnMainThread:@selector(unloadData) withObject:nil waitUntilDone:NO]; } +- (void) setScrollAlwaysBounceVertical:(NSNumber *)value { + [indirect_ performSelectorOnMainThread:@selector(setScrollAlwaysBounceVerticalNumber:) withObject:value waitUntilDone:NO]; +} + +- (void) setScrollIndicatorStyle:(NSString *)style { + [indirect_ performSelectorOnMainThread:@selector(setScrollIndicatorStyleWithName:) withObject:style waitUntilDone:NO]; +} + - (void) addInternalRedirect:(NSString *)from :(NSString *)to { [CydiaWebViewController performSelectorOnMainThread:@selector(addDiversion:) withObject:[[[Diversion alloc] initWithFrom:from to:to] autorelease] waitUntilDone:NO]; } @@ -4186,25 +4220,6 @@ static _H Diversions_; return value; } -- (void) _setCydiaSource:(NSString *)source { - @synchronized (HostConfig_) { - CydiaSource_ = source; - [Metadata_ setObject:source forKey:@"CydiaSource"]; - } - - Changed_ = true; -} - -- (void) setCydiaSource:(NSString *)source { - [self performSelectorOnMainThread:@selector(_setCydiaSource:) withObject:source waitUntilDone:NO]; -} - -- (NSString *) cydiaSource { - @synchronized (HostConfig_) { - return (id) CydiaSource_ ?: [NSNull null]; - } -} - - (NSArray *) getMetadataKeys { @synchronized (Values_) { return [Values_ allKeys]; @@ -4371,12 +4386,7 @@ static _H Diversions_; fclose(du); } else _assert(close(fds[0])); - int status; - wait: - if (waitpid(pid, &status, 0) == -1) - if (errno == EINTR) - goto wait; - else _assert(false); + ReapZombie(pid); return value; } @@ -4515,7 +4525,9 @@ static _H Diversions_; return request_ == nil ? nil : [NSURL URLWithString:[NSString stringWithFormat:@"cydia://url/%@", [[request_ URL] absoluteString]]]; } -+ (void) initialize { ++ (void) _initialize { + [super _initialize]; + Diversions_ = [NSMutableSet setWithCapacity:0]; } @@ -4562,19 +4574,27 @@ static _H Diversions_; NSMutableURLRequest *copy([[super webView:view resource:resource willSendRequest:request redirectResponse:response fromDataSource:source] mutableCopy]); - if (System_ != NULL && [copy valueForHTTPHeaderField:@"X-System"] == nil) - [copy setValue:System_ forHTTPHeaderField:@"X-System"]; + if ([copy valueForHTTPHeaderField:@"X-Cydia-Cf-Version"] == nil) + [copy setValue:[NSString stringWithFormat:@"%.2f", kCFCoreFoundationVersionNumber] forHTTPHeaderField:@"X-Cydia-Cf-Version"]; if (Machine_ != NULL && [copy valueForHTTPHeaderField:@"X-Machine"] == nil) [copy setValue:[NSString stringWithUTF8String:Machine_] forHTTPHeaderField:@"X-Machine"]; + bool bridged; bool token; + @synchronized (HostConfig_) { - token = [TokenHosts_ containsObject:host] || [BridgedHosts_ containsObject:host]; + bridged = [BridgedHosts_ containsObject:host]; + token = [TokenHosts_ containsObject:host]; } - if ([url isCydiaSecure] && token) { - if (Token_ != nil && [copy valueForHTTPHeaderField:@"X-Cydia-Token"] == nil) - [copy setValue:Token_ forHTTPHeaderField:@"X-Cydia-Token"]; + 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"]; + } } return copy; @@ -4586,16 +4606,7 @@ static _H Diversions_; } - (NSString *) applicationNameForUserAgent { - NSString *application([NSString stringWithFormat:@"Cydia/%@", @ Cydia_]); - - if (Safari_ != nil) - application = [NSString stringWithFormat:@"Safari/%@ %@", Safari_, application]; - if (Build_ != nil) - application = [NSString stringWithFormat:@"Mobile/%@ %@", Build_, application]; - if (Product_ != nil) - application = [NSString stringWithFormat:@"Version/%@ %@", Product_, application]; - - return application; + return UserAgent_; } - (id) init { @@ -4614,6 +4625,11 @@ static _H Diversions_; @implementation AppCacheController - (void) didReceiveMemoryWarning { + // XXX: this doesn't work +} + +- (bool) retainsNetworkActivityIndicator { + return false; } @end @@ -5212,6 +5228,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { ] autorelease]; } +- (void) uicache { + _trace(); + system("su -c /usr/bin/uicache mobile"); + _trace(); +} + - (void) invoke:(NSInvocation *)invocation withTitle:(NSString *)title { UpdateExternalStatus(1); @@ -5289,9 +5311,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { case 4: [progress_ setFinish:UCLocalize("REBOOT_DEVICE")]; break; } - _trace(); - system("su -c /usr/bin/uicache mobile"); - _trace(); + UIProgressHUD *hud([delegate_ addProgressHUD]); + [hud setText:UCLocalize("LOADING")]; + [self yieldToSelector:@selector(uicache)]; + [delegate_ removeProgressHUD:hud]; UpdateExternalStatus(Finish_ == 0 ? 0 : 2); @@ -5496,11 +5519,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { CGRect rect; rect.size = [(UIImage *) icon_ size]; - rect.size.width /= 4; - rect.size.height /= 4; + while (rect.size.width > 16 || rect.size.height > 16) { + rect.size.width /= 2; + rect.size.height /= 2; + } - rect.origin.x = 14 - rect.size.width / 4; - rect.origin.y = 14 - rect.size.height / 4; + rect.origin.x = 18 - rect.size.width / 2; + rect.origin.y = 18 - rect.size.height / 2; [icon_ drawInRect:rect]; } @@ -5512,8 +5537,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { rect.size.width /= 4; rect.size.height /= 4; - rect.origin.x = 20 - rect.size.width / 4; - rect.origin.y = 20 - rect.size.height / 4; + rect.origin.x = 23 - rect.size.width / 2; + rect.origin.y = 23 - rect.size.height / 2; [badge_ drawInRect:rect]; } @@ -5537,8 +5562,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { CGRect rect; rect.size = [(UIImage *) icon_ size]; - rect.size.width /= 2; - rect.size.height /= 2; + while (rect.size.width > 32 || rect.size.height > 32) { + rect.size.width /= 2; + rect.size.height /= 2; + } rect.origin.x = 25 - rect.size.width / 2; rect.origin.y = 25 - rect.size.height / 2; @@ -5749,14 +5776,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) loadView { - [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]]; - - list_ = [[[UITableView alloc] initWithFrame:[[self view] bounds]] autorelease]; + list_ = [[[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]; [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; [list_ setRowHeight:24.0f]; [(UITableView *) list_ setDataSource:self]; [list_ setDelegate:self]; - [[self view] addSubview:list_]; + [self setView:list_]; } - (void) viewDidLoad { @@ -6080,7 +6105,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { CGRect intersection = CGRectIntersection(viewframe, kbframe); if (kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iPhoneOS_3_0) // XXX: _UIApplicationLinkedOnOrAfter(4) - intersection.size.height += CYStatusBarHeight([self interfaceOrientation]); + intersection.size.height += CYStatusBarHeight(); [self resizeForKeyboardBounds:intersection duration:duration curve:curve]; } @@ -6200,11 +6225,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) loadView { - [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]]; + UIView *view([[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]); + [view setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)]; + [self setView:view]; list_ = [[[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStylePlain] autorelease]; [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; - [[self view] addSubview:list_]; + [view addSubview:list_]; // XXX: is 20 the most optimal number here? [list_ setSectionIndexMinimumDisplayRowCount:20]; @@ -6254,6 +6281,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { NSArray *packages; + reload: if ([self shouldYield]) { do { UIProgressHUD *hud; @@ -6271,12 +6299,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { if (hud != nil) [delegate_ removeProgressHUD:hud]; } while (reloading_ == 2); - - reloading_ = 0; } else { packages = [self _reloadPackages]; } +@synchronized (database_) { + if (era_ != [database_ era]) + goto reload; + reloading_ = 0; + packages_ = packages; indices_ = [NSMutableDictionary dictionaryWithCapacity:32]; @@ -6362,7 +6393,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [(UITableView *) list_ setDataSource:self]; [list_ reloadData]; _end -} +} } - (void) reloadData { [super reloadData]; @@ -6488,9 +6519,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { return [NSURL URLWithString:@"cydia://home"]; } -- (void) didReceiveMemoryWarning { -} - - (void) aboutButtonClicked { UIAlertView *alert([[[UIAlertView alloc] init] autorelease]); @@ -6533,7 +6561,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (id) init { if ((self = [super init]) != nil) { - [self setURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/#!/manage/", UI_]]]; + [self setURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"manage" ofType:@"html"]]]; } return self; } @@ -6558,13 +6586,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [delegate_ queue]; } -- (UIBarButtonItem *) customButton { +- (UIBarButtonItem *) rightButton { return Queuing_ ? [[[UIBarButtonItem alloc] initWithTitle:UCLocalize("QUEUE") style:UIBarButtonItemStyleDone target:self action:@selector(queueButtonClicked) - ] autorelease] : [super customButton]; + ] autorelease] : nil; } - (void) queueStatusDidChange { @@ -6724,7 +6752,32 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @implementation CYTabBarController +- (void) didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + + // presenting a UINavigationController on 2.x does not update its transitionView + // it thereby will not allow its topViewController to be unloaded by memory pressure + if (kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iPhoneOS_3_0) { + UIViewController *selected([self selectedViewController]); + for (UINavigationController *controller in [self viewControllers]) + if (controller != selected) + if (UIViewController *top = [controller topViewController]) + [top unloadView]; + } +} + - (void) setUnselectedViewController:(UIViewController *)transient { + if (kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iPhoneOS_3_0) { + if (transient != nil) { + [[[self viewControllers] objectAtIndex:0] pushViewController:transient animated:YES]; + [self setSelectedIndex:0]; + } return; + } + + UINavigationController *navigation([[[UINavigationController alloc] init] autorelease]); + [navigation setViewControllers:[NSArray arrayWithObject:transient]]; + transient = navigation; + NSMutableArray *controllers = [[self viewControllers] mutableCopy]; if (transient != nil) { if (transient_ == nil) @@ -6752,6 +6805,14 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController { if ([self unselectedViewController]) [self setUnselectedViewController:nil]; + + // presenting a UINavigationController on 2.x does not update its transitionView + // if this view was unloaded, the tranitionView may currently be presenting nothing + if (kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iPhoneOS_3_0) { + UINavigationController *navigation((UINavigationController *) viewController); + [navigation pushViewController:[[[UIViewController alloc] init] autorelease] animated:NO]; + [navigation popViewControllerAnimated:NO]; + } } - (NSArray *) navigationURLCollection { @@ -6767,6 +6828,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { return items; } +- (void) dismissModalViewControllerAnimated:(BOOL)animated { + if ([self modalViewController] == nil && [self unselectedViewController] != nil) + [self setUnselectedViewController:nil]; + else + [super dismissModalViewControllerAnimated:YES]; +} + - (void) unloadData { [super unloadData]; @@ -6905,7 +6973,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { CGRect barframe([refreshbar_ frame]); if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iPhoneOS_3_0) // XXX: _UIApplicationLinkedOnOrAfter(4) - barframe.origin.y = CYStatusBarHeight([self interfaceOrientation]); + barframe.origin.y = CYStatusBarHeight(); else barframe.origin.y = 0; @@ -7089,15 +7157,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [package parse]; UIImage *icon([package icon]); [self _returnPNGWithImage:icon forRequest:request]; - } else if ([command isEqualToString:@"source-icon"]) { - if (path == nil) - goto fail; - path = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; - NSString *source(Simplify(path)); - UIImage *icon([UIImage imageAtPath:[NSString stringWithFormat:@"%@/Sources/%@.png", App_, source]]); - if (icon == nil) - icon = [UIImage applicationImageNamed:@"unknown.png"]; - [self _returnPNGWithImage:icon forRequest:request]; } else if ([command isEqualToString:@"uikit-image"]) { if (path == nil) goto fail; @@ -7266,14 +7325,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) loadView { - [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]]; - - list_ = [[[UITableView alloc] initWithFrame:[[self view] bounds]] autorelease]; + list_ = [[[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]; [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; [list_ setRowHeight:45.0f]; [(UITableView *) list_ setDataSource:self]; [list_ setDelegate:self]; - [[self view] addSubview:list_]; + [self setView:list_]; } - (void) viewDidLoad { @@ -7448,14 +7505,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) loadView { - [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]]; - - list_ = [[[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStylePlain] autorelease]; + list_ = [[[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStylePlain] autorelease]; [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; [list_ setRowHeight:73]; [(UITableView *) list_ setDataSource:self]; [list_ setDelegate:self]; - [[self view] addSubview:list_]; + [self setView:list_]; } - (void) viewDidLoad { @@ -7822,15 +7877,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { _assert(false); } - _forever { - int status; - int result(waitpid(pid, &status, 0)); - - if (result != -1) { - _assert(result == pid); - break; - } - } + ReapZombie(pid); } - (void) onIgnored:(id)control { @@ -7856,13 +7903,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) loadView { - [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]]; + UIView *view([[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]); + [view setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)]; + [self setView:view]; table_ = [[[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStyleGrouped] autorelease]; [table_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; [(UITableView *) table_ setDataSource:self]; [table_ setDelegate:self]; - [[self view] addSubview:table_]; + [view addSubview:table_]; subscribedSwitch_ = [[[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 50, 20)] autorelease]; [subscribedSwitch_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin]; @@ -7995,6 +8044,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @interface SourceCell : CyteTableViewCell < CyteTableViewCellDelegate > { + _H url_; _H icon_; _H origin_; _H label_; @@ -8006,31 +8056,28 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @implementation SourceCell -- (void) _setImage:(UIImage *)image { - icon_ = image; - [content_ setNeedsDisplay]; +- (void) _setImage:(NSArray *)data { + if ([url_ isEqual:[data objectAtIndex:0]]) { + icon_ = [data objectAtIndex:1]; + [content_ setNeedsDisplay]; + } } -- (void) _setSource:(Source *)source { +- (void) _setSource:(NSURL *) url { NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]); - if (NSString *base = [source base]) - if ([base length] != 0) { - NSURL *url([NSURL URLWithString:[base stringByAppendingString:@"CydiaIcon.png"]]); - - if (NSData *data = [NSURLConnection - sendSynchronousRequest:[NSURLRequest - requestWithURL:url - //cachePolicy:NSURLRequestUseProtocolCachePolicy - //timeoutInterval:5 - ] - - returningResponse:NULL - error:NULL - ]) - if (UIImage *image = [UIImage imageWithData:data]) - [self performSelectorOnMainThread:@selector(_setImage:) withObject:image waitUntilDone:NO]; - } + if (NSData *data = [NSURLConnection + sendSynchronousRequest:[NSURLRequest + requestWithURL:url + //cachePolicy:NSURLRequestUseProtocolCachePolicy + //timeoutInterval:5 + ] + + returningResponse:NULL + error:NULL + ]) + if (UIImage *image = [UIImage imageWithData:data]) + [self performSelectorOnMainThread:@selector(_setImage:) withObject:[NSArray arrayWithObjects:url, image, nil] waitUntilDone:NO]; [pool release]; } @@ -8039,11 +8086,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { icon_ = [UIImage applicationImageNamed:@"unknown.png"]; origin_ = [source name]; - label_ = [source uri]; + label_ = [source rooturi]; [content_ setNeedsDisplay]; - [NSThread detachNewThreadSelector:@selector(_setSource:) toTarget:self withObject:source]; + url_ = [source iconURL]; + [NSThread detachNewThreadSelector:@selector(_setSource:) toTarget:self withObject:url_]; } - (SourceCell *) initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier { @@ -8058,6 +8106,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [content_ setDelegate:self]; [content_ setOpaque:YES]; + + [[content_ layer] setContentsGravity:kCAGravityTopLeft]; } return self; } @@ -8069,19 +8119,31 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { bool highlighted(highlighted_); float width(rect.size.width); - if (icon_ != nil) - [icon_ drawInRect:CGRectMake(10, 10, 30, 30)]; + if (icon_ != nil) { + CGRect rect; + rect.size = [(UIImage *) icon_ size]; + + while (rect.size.width > 32 || rect.size.height > 32) { + rect.size.width /= 2; + rect.size.height /= 2; + } + + rect.origin.x = 25 - rect.size.width / 2; + rect.origin.y = 25 - rect.size.height / 2; + + [icon_ drawInRect:rect]; + } if (highlighted) UISetColor(White_); if (!highlighted) UISetColor(Black_); - [origin_ drawAtPoint:CGPointMake(48, 8) forWidth:(width - 80) withFont:Font18Bold_ lineBreakMode:UILineBreakModeTailTruncation]; + [origin_ drawAtPoint:CGPointMake(48, 8) forWidth:(width - 65) withFont:Font18Bold_ lineBreakMode:UILineBreakModeTailTruncation]; if (!highlighted) - UISetColor(Blue_); - [label_ drawAtPoint:CGPointMake(58, 29) forWidth:(width - 95) withFont:Font12_ lineBreakMode:UILineBreakModeTailTruncation]; + UISetColor(Gray_); + [label_ drawAtPoint:CGPointMake(48, 29) forWidth:(width - 65) withFont:Font12_ lineBreakMode:UILineBreakModeTailTruncation]; } @end @@ -8127,6 +8189,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { UITableViewDelegate > { _transient Database *database_; + unsigned era_; + _H list_; _H sources_; int offset_; @@ -8179,38 +8243,24 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView { - return offset_ == 0 ? 1 : 2; + return 1; } - (NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { - switch (section + (offset_ == 0 ? 1 : 0)) { - case 0: return UCLocalize("ENTERED_BY_USER"); - case 1: return UCLocalize("INSTALLED_BY_PACKAGE"); - - _nodefault - } + return nil; } - (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - int count = [sources_ count]; - switch (section) { - case 0: return (offset_ == 0 ? count : offset_); - case 1: return count - offset_; - - _nodefault - } + return [sources_ count]; } - (Source *) sourceAtIndexPath:(NSIndexPath *)indexPath { - unsigned idx = 0; - switch (indexPath.section) { - case 0: idx = indexPath.row; break; - case 1: idx = indexPath.row + offset_; break; +@synchronized (database_) { + if ([database_ era] != era_) + return nil; - _nodefault - } - return [sources_ objectAtIndex:idx]; -} + return [sources_ objectAtIndex:[indexPath row]]; +} } - (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellIdentifier = @"SourceCell"; @@ -8251,6 +8301,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) complete { [delegate_ addTrivialSource:href_]; + href_ = nil; + [delegate_ syncData]; } @@ -8261,7 +8313,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { href = [href substringFromIndex:(colon.location + 3)]; href = [href stringByAddingPercentEscapes]; href = [CydiaURL(@"api/repotag/") stringByAppendingString:href]; - href = [href stringByCachingURLWithCurrentCDN]; NSURL *url([NSURL URLWithString:href]); @@ -8292,17 +8343,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { trivial_bz2_ == nil && trivial_gz_ == nil ) { + NSString *warning(cydia_ ? [self yieldToSelector:@selector(getWarning)] : nil); + [delegate_ releaseNetworkActivityIndicator]; [delegate_ removeProgressHUD:hud_]; hud_ = nil; - bool defer(false); - if (cydia_) { - if (NSString *warning = [self yieldToSelector:@selector(getWarning)]) { - defer = true; - + if (warning != nil) { UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:UCLocalize("SOURCE_WARNING") message:warning @@ -8316,8 +8365,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [alert setContext:@"warning"]; [alert setNumberOfRows:1]; [alert show]; - } else - [self complete]; + + // XXX: there used to be this great mechanism called yieldToPopup... who deleted it? + error_ = nil; + return; + } + + [self complete]; } else if (error_ != nil) { UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:UCLocalize("VERIFICATION_ERROR") @@ -8329,6 +8383,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [alert setContext:@"urlerror"]; [alert show]; + + href_ = nil; } else { UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:UCLocalize("NOT_REPOSITORY") @@ -8340,9 +8396,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [alert setContext:@"trivial"]; [alert show]; + + href_ = nil; } - href_ = nil; error_ = nil; } } @@ -8379,8 +8436,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [request setValue:[NSString stringWithUTF8String:Machine_] forHTTPHeaderField:@"X-Machine"]; if ([url isCydiaSecure]) { - if (UniqueID_ != nil) + if (UniqueID_ != nil) { [request setValue:UniqueID_ forHTTPHeaderField:@"X-Unique-ID"]; + [request setValue:UniqueID_ forHTTPHeaderField:@"X-Cydia-Id"]; + } } return [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease]; @@ -8428,7 +8487,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { else if ([context isEqualToString:@"warning"]) { switch (button) { case 1: - [self complete]; + [self performSelector:@selector(complete) withObject:nil afterDelay:0]; break; case 0: @@ -8437,21 +8496,17 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { _nodefault } - href_ = nil; - [alert dismissWithClickedButtonIndex:-1 animated:YES]; } } - (void) loadView { - [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]]; - - list_ = [[[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStylePlain] autorelease]; + list_ = [[[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStylePlain] autorelease]; [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; - [list_ setRowHeight:56]; + [list_ setRowHeight:53]; [(UITableView *) list_ setDataSource:self]; [list_ setDelegate:self]; - [[self view] addSubview:list_]; + [self setView:list_]; } - (void) viewDidLoad { @@ -8478,6 +8533,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) reloadData { [super reloadData]; +@synchronized (database_) { + era_ = [database_ era]; + pkgSourceList list; if ([database_ popErrorWithTitle:UCLocalize("SOURCES") forOperation:list.ReadMainList()]) return; @@ -8485,7 +8543,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { sources_ = [NSMutableArray arrayWithCapacity:16]; [sources_ addObjectsFromArray:[database_ sources]]; _trace(); - [sources_ sortUsingSelector:@selector(compareByNameAndType:)]; + [sources_ sortUsingSelector:@selector(compareByName:)]; _trace(); int count([sources_ count]); @@ -8499,7 +8557,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [list_ setEditing:NO]; [self updateButtonsForEditingStatus:NO animated:NO]; [list_ reloadData]; -} +} } - (void) showAddSourcePrompt { UIAlertView *alert = [[[UIAlertView alloc] @@ -8589,13 +8647,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @implementation SettingsController - (void) loadView { - [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]]; - - table_ = [[[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStyleGrouped] autorelease]; + table_ = [[[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStyleGrouped] autorelease]; [table_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; [table_ setDelegate:self]; [(UITableView *) table_ setDataSource:self]; - [[self view] addSubview:table_]; + [self setView:table_]; NSArray *items = [NSArray arrayWithObjects: UCLocalize("USER"), @@ -8603,6 +8659,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { UCLocalize("DEVELOPER"), nil]; segment_ = [[[UISegmentedControl alloc] initWithItems:items] autorelease]; + [segment_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin)]; container_ = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, [[self view] frame].size.width, 44.0f)] autorelease]; [container_ addSubview:segment_]; } @@ -8771,8 +8828,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @implementation StashController - (void) loadView { - [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]]; - [[self view] setBackgroundColor:[UIColor viewFlipsideBackgroundColor]]; + UIView *view([[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]); + [view setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)]; + [self setView:view]; + + [view setBackgroundColor:[UIColor viewFlipsideBackgroundColor]]; spinner_ = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge] autorelease]; CGRect spinrect = [spinner_ frame]; @@ -8780,7 +8840,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { spinrect.origin.y = [[self view] frame].size.height - 80.0f; [spinner_ setFrame:spinrect]; [spinner_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin]; - [[self view] addSubview:spinner_]; + [view addSubview:spinner_]; [spinner_ startAnimating]; CGRect captrect; @@ -8796,7 +8856,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [caption_ setBackgroundColor:[UIColor clearColor]]; [caption_ setShadowColor:[UIColor blackColor]]; [caption_ setTextAlignment:UITextAlignmentCenter]; - [[self view] addSubview:caption_]; + [view addSubview:caption_]; CGRect statusrect; statusrect.size.width = [[self view] frame].size.width; @@ -8811,7 +8871,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [status_ setBackgroundColor:[UIColor clearColor]]; [status_ setShadowColor:[UIColor blackColor]]; [status_ setTextAlignment:UITextAlignmentCenter]; - [[self view] addSubview:status_]; + [view addSubview:status_]; } - (void) releaseSubviews { @@ -8953,9 +9013,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) _saveConfig { - _trace(); - MetaFile_.Sync(); - _trace(); + @synchronized (database_) { + _trace(); + MetaFile_.Sync(); + _trace(); + } if (Changed_) { NSString *error(nil); @@ -8973,7 +9035,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } } - WriteSources(); + CydiaWriteSources(); } // Navigation controller for the queuing badge. @@ -9060,9 +9122,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [database_ yieldToSelector:@selector(reloadDataWithInvocation:) withObject:invocation]; - if (hud != nil) - [self removeProgressHUD:hud]; - size_t changes(0); [essential_ removeAllObjects]; @@ -9094,6 +9153,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } [self _updateData]; + + if (hud != nil) + [self removeProgressHUD:hud]; } } - (void) updateData { @@ -9171,15 +9233,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) addSource:(NSDictionary *) source { - AddSource(source); + CydiaAddSource(source); } - (void) addSource:(NSString *)href withDistribution:(NSString *)distribution andSections:(NSArray *)sections { - AddSource(href, distribution, sections); + CydiaAddSource(href, distribution, sections); } - (void) addTrivialSource:(NSString *)href { - AddSource(href, @"./"); + CydiaAddSource(href, @"./"); } - (void) updateValues { @@ -9436,10 +9498,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { if (UIViewController *modal = [target modalViewController]) target = modal; - UIView *view([target view]); - [view addSubview:hud]; - - [hud showInView:[tabbar_ view]]; + [hud showInView:[target view]]; ++locked_; return hud; @@ -9461,7 +9520,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { if ([[url absoluteString] length] <= [scheme length] + 3) return nil; NSString *path([[url absoluteString] substringFromIndex:[scheme length] + 3]); - NSArray *components([path pathComponents]); + NSArray *components([path componentsSeparatedByString:@"/"]); if ([scheme isEqualToString:@"apptapp"] && [components count] > 0 && [[components objectAtIndex:0] isEqualToString:@"package"]) return [self pageForPackage:[components objectAtIndex:1]]; @@ -9482,6 +9541,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { controller = [[[ManageController alloc] init] autorelease]; } + if ([base isEqualToString:@"storage"]) { + controller = [[[CydiaWebViewController alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/storage/", UI_]]] autorelease]; + } + if ([base isEqualToString:@"sources"]) { controller = [[[SourcesController alloc] initWithDatabase:database_] autorelease]; } @@ -9559,11 +9622,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (BOOL) openCydiaURL:(NSURL *)url forExternal:(BOOL)external { CyteViewController *page([self pageForURL:url forExternal:external]); - if (page != nil) { - UINavigationController *nav = [[[UINavigationController alloc] init] autorelease]; - [nav setViewControllers:[NSArray arrayWithObject:page]]; - [tabbar_ setUnselectedViewController:nav]; - } + if (page != nil) + [tabbar_ setUnselectedViewController:page]; return page != nil; } @@ -9648,10 +9708,14 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [self removeStashController]; - if (ExecFork() == 0) { + pid_t pid(ExecFork()); + if (pid == 0) { execlp("launchctl", "launchctl", "stop", "com.apple.SpringBoard", NULL); perror("launchctl stop"); + exit(0); } + + ReapZombie(pid); } - (void) setupViewControllers { @@ -9683,16 +9747,25 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) _sendMemoryWarningNotification { - [[NSNotificationCenter defaultCenter] postNotificationName:@"UIApplicationDidReceiveMemoryWarningNotification" object:[UIApplication sharedApplication]]; + if (kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iPhoneOS_3_0) // XXX: maybe 4_0? + [[NSNotificationCenter defaultCenter] postNotificationName:@"UIApplicationMemoryWarningNotification" object:[UIApplication sharedApplication]]; + else + [[NSNotificationCenter defaultCenter] postNotificationName:@"UIApplicationDidReceiveMemoryWarningNotification" object:[UIApplication sharedApplication]]; } - (void) _sendMemoryWarningNotifications { while (true) { [self performSelectorOnMainThread:@selector(_sendMemoryWarningNotification) withObject:nil waitUntilDone:NO]; - usleep(250000); + sleep(2); + //usleep(2000000); } } +- (void) applicationDidReceiveMemoryWarning:(UIApplication *)application { + NSLog(@"--"); + [[NSURLCache sharedURLCache] removeAllCachedResponses]; +} + - (void) applicationDidFinishLaunching:(id)unused { //[NSThread detachNewThreadSelector:@selector(_sendMemoryWarningNotifications) toTarget:self withObject:nil]; @@ -9813,8 +9886,8 @@ _trace(); NSDate *closed = [Metadata_ objectForKey:@"LastClosed"]; if (valid && closed != nil) { NSTimeInterval interval([closed timeIntervalSinceNow]); - // XXX: Is 15 minutes the optimal time here? - if (interval > 0 && interval <= -(15*60)) + // XXX: Is 30 minutes the optimal time here? + if (interval <= -(30*60)) valid = NO; } @@ -9958,7 +10031,6 @@ MSHook(id, NSURLConnection$init$, NSURLConnection *self, SEL _cmd, NSURLRequest NSURL *url([copy URL]); - NSString *href([url absoluteString]); NSString *host([url host]); NSString *scheme([[url scheme] lowercaseString]); @@ -9971,9 +10043,9 @@ MSHook(id, NSURLConnection$init$, NSURLConnection *self, SEL _cmd, NSURLRequest if (NSString *control = [copy valueForHTTPHeaderField:@"Cache-Control"]) if ([control isEqualToString:@"max-age=0"]) - if ([CachedURLs_ containsObject:href]) { + if ([CachedURLs_ containsObject:url]) { #if !ForRelease - NSLog(@"~~~: %@", href); + NSLog(@"~~~: %@", url); #endif [copy setCachePolicy:NSURLRequestReturnCacheDataDontLoad]; @@ -10020,6 +10092,13 @@ int main(int argc, char *argv[]) { NSLog(@"unknown UIUserInterfaceIdiom!"); } + Pcre pattern("^([0-9]+\\.[0-9]+)"); + + if (pattern([device systemVersion])) + Firmware_ = pattern[1]; + if (pattern(Cydia_)) + Major_ = pattern[1]; + SessionData_ = [NSMutableDictionary dictionaryWithCapacity:4]; HostConfig_ = [[[NSObject alloc] init] autorelease]; @@ -10031,7 +10110,11 @@ int main(int argc, char *argv[]) { CachedURLs_ = [NSMutableSet setWithCapacity:32]; } - UI_ = CydiaURL([NSString stringWithFormat:@"ui/ios~%@", Idiom_]); + NSString *ui(@"ui/ios"); + if (Idiom_ != nil) + ui = [ui stringByAppendingString:[NSString stringWithFormat:@"~%@", Idiom_]]; + ui = [ui stringByAppendingString:[NSString stringWithFormat:@"/%@", Major_]]; + UI_ = CydiaURL(ui); PackageName = reinterpret_cast(method_getImplementation(class_getInstanceMethod([Package class], @selector(cyname)))); @@ -10173,28 +10256,21 @@ int main(int argc, char *argv[]) { UniqueID_ = [device uniqueIdentifier]; - CFStringRef (*$CTSIMSupportCopyMobileSubscriberCountryCode)(CFAllocatorRef); - $CTSIMSupportCopyMobileSubscriberCountryCode = reinterpret_cast(dlsym(RTLD_DEFAULT, "CTSIMSupportCopyMobileSubscriberCountryCode")); - CFStringRef mcc($CTSIMSupportCopyMobileSubscriberCountryCode == NULL ? NULL : (*$CTSIMSupportCopyMobileSubscriberCountryCode)(kCFAllocatorDefault)); - - CFStringRef (*$CTSIMSupportCopyMobileSubscriberNetworkCode)(CFAllocatorRef); - $CTSIMSupportCopyMobileSubscriberNetworkCode = reinterpret_cast(dlsym(RTLD_DEFAULT, "CTSIMSupportCopyMobileSubscriberCountryCode")); - CFStringRef mnc($CTSIMSupportCopyMobileSubscriberNetworkCode == NULL ? NULL : (*$CTSIMSupportCopyMobileSubscriberNetworkCode)(kCFAllocatorDefault)); - - if (mcc != NULL && mnc != NULL) - PLMN_ = [NSString stringWithFormat:@"%@%@", mcc, mnc]; - - if (mnc != NULL) - CFRelease(mnc); - if (mcc != NULL) - CFRelease(mcc); - - if (NSDictionary *system = [NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"]) - Build_ = [system objectForKey:@"ProductBuildVersion"]; if (NSDictionary *info = [NSDictionary dictionaryWithContentsOfFile:@"/Applications/MobileSafari.app/Info.plist"]) { Product_ = [info objectForKey:@"SafariProductVersion"]; Safari_ = [info objectForKey:@"CFBundleVersion"]; } + + NSString *agent([NSString stringWithFormat:@"Cydia/%@ CF/%.2f", Cydia_, kCFCoreFoundationVersionNumber]); + + if (Pcre match = Pcre("^[0-9]+(\\.[0-9]+)+", Safari_)) + agent = [NSString stringWithFormat:@"Safari/%@ %@", match[0], agent]; + if (Pcre match = Pcre("^[0-9]+[A-Z][0-9]+[a-z]?", System_)) + agent = [NSString stringWithFormat:@"Mobile/%@ %@", match[0], agent]; + if (Pcre match = Pcre("^[0-9]+(\\.[0-9]+)+", Product_)) + agent = [NSString stringWithFormat:@"Version/%@ %@", match[0], agent]; + + UserAgent_ = agent; /* }}} */ /* Load Database {{{ */ _trace(); @@ -10216,10 +10292,6 @@ int main(int argc, char *argv[]) { Token_ = [Metadata_ objectForKey:@"Token"]; Version_ = [Metadata_ objectForKey:@"Version"]; - - @synchronized (HostConfig_) { - CydiaSource_ = [Metadata_ objectForKey:@"CydiaSource"]; - } } if (Settings_ != nil) @@ -10245,18 +10317,11 @@ int main(int argc, char *argv[]) { [Metadata_ setObject:Version_ forKey:@"Version"]; } - @synchronized (HostConfig_) { - if (CydiaSource_ == nil) { - CydiaSource_ = @"apt.saurik.com"; - [Metadata_ setObject:CydiaSource_ forKey:@"CydiaSource"]; - } - } - if ([Version_ unsignedIntValue] == 0) { - AddSource(@"http://apt.thebigboss.org/repofiles/cydia/", @"stable", [NSMutableArray arrayWithObject:@"main"]); - AddSource(@"http://apt.modmyi.com/", @"stable", [NSMutableArray arrayWithObject:@"main"]); - AddSource(@"http://cydia.zodttd.com/repo/cydia/", @"stable", [NSMutableArray arrayWithObject:@"main"]); - AddSource(@"http://repo666.ultrasn0w.com/", @"./"); + CydiaAddSource(@"http://apt.thebigboss.org/repofiles/cydia/", @"stable", [NSMutableArray arrayWithObject:@"main"]); + CydiaAddSource(@"http://apt.modmyi.com/", @"stable", [NSMutableArray arrayWithObject:@"main"]); + CydiaAddSource(@"http://cydia.zodttd.com/repo/cydia/", @"stable", [NSMutableArray arrayWithObject:@"main"]); + CydiaAddSource(@"http://repo666.ultrasn0w.com/", @"./"); Version_ = [NSNumber numberWithUnsignedInt:1]; [Metadata_ setObject:Version_ forKey:@"Version"]; @@ -10267,7 +10332,7 @@ int main(int argc, char *argv[]) { } /* }}} */ - WriteSources(); + CydiaWriteSources(); _trace(); MetaFile_.Open("/var/lib/cydia/metadata.cb0"); @@ -10304,11 +10369,7 @@ int main(int argc, char *argv[]) { int version([[NSString stringWithContentsOfFile:@"/var/lib/cydia/firmware.ver"] intValue]); - if (access("/tmp/.cydia.fw", F_OK) == 0) { - unlink("/tmp/.cydia.fw"); - goto firmware; - } else if (access("/User", F_OK) != 0 || version < 4) { - firmware: + if (access("/User", F_OK) != 0 || version != 5) { _trace(); system("/usr/libexec/cydia/firmware.sh"); _trace();