X-Git-Url: https://git.saurik.com/cydia.git/blobdiff_plain/247bedb6ab47e07cecd3900ba9d1430d3ec2a3e4..64ffa33263f912a9747b9716f04e9cdcb0b857a9:/MobileCydia.mm diff --git a/MobileCydia.mm b/MobileCydia.mm index 3c11b91e..92f5a0ae 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) @@ -245,6 +247,11 @@ union SplitHash { }; // }}} +static NSString *Colon_; +NSString *Elision_; +static NSString *Error_; +static NSString *Warning_; + static const NSUInteger UIViewAutoresizingFlexibleBoth(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight); static _finline NSString *CydiaURL(NSString *path) { @@ -267,9 +274,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 */ @@ -697,19 +704,25 @@ static NSMutableDictionary *Metadata_; static _transient NSMutableDictionary *Settings_; static _transient NSString *Role_; static _transient NSMutableDictionary *Packages_; +static _transient NSMutableDictionary *Values_; static _transient NSMutableDictionary *Sections_; -static _transient NSMutableDictionary *Sources_; -static bool Changed_; +_H Sources_; +static _transient NSNumber *Version_; +_H CydiaSource_; +bool Changed_; static time_t now_; bool IsWildcat_; static CGFloat ScreenScale_; static NSString *Idiom_; +_H Firmware_; +static NSString *Major_; static _H SessionData_; static _H HostConfig_; static _H BridgedHosts_; static _H TokenHosts_; +static _H InsecureHosts_; static _H PipelinedHosts_; static _H CachedURLs_; @@ -828,6 +841,8 @@ static NSString *CYHex(NSData *data, bool reverse = false) { @class CYPackageController; @protocol CydiaDelegate +- (void) returnToCydia; +- (void) saveState; - (void) retainNetworkActivityIndicator; - (void) releaseNetworkActivityIndicator; - (void) clearPackage:(Package *)package; @@ -840,6 +855,7 @@ static NSString *CYHex(NSData *data, bool reverse = false) { - (void) loadData; - (void) updateData; - (void) syncData; +- (void) addSource:(NSDictionary *)source; - (void) addTrivialSource:(NSString *)href; - (void) showSettings; - (UIProgressHUD *) addProgressHUD; @@ -878,6 +894,7 @@ class Status : } virtual void IMSHit(pkgAcquire::ItemDesc &item) { + Done(item); } virtual void Fetch(pkgAcquire::ItemDesc &item) { @@ -887,6 +904,9 @@ class Status : } virtual void Done(pkgAcquire::ItemDesc &item) { + NSString *name([NSString stringWithUTF8String:item.ShortDesc.c_str()]); + CydiaProgressEvent *event([CydiaProgressEvent eventWithMessage:[NSString stringWithFormat:Colon_, UCLocalize("DONE"), name] ofType:kCydiaProgressEventTypeStatus forItem:item]); + [delegate_ performSelectorOnMainThread:@selector(addProgressEvent:) withObject:event waitUntilDone:YES]; } virtual void Fail(pkgAcquire::ItemDesc &item) { @@ -1261,6 +1281,10 @@ static void PackageImport(const void *key, const void *value, void *context) { /* Source Class {{{ */ @interface Source : NSObject { + unsigned era_; + Database *database_; + metaIndex *index_; + CYString depiction_; CYString description_; CYString label_; @@ -1282,9 +1306,9 @@ static void PackageImport(const void *key, const void *value, void *context) { BOOL trusted_; } -- (Source *) initWithMetaIndex:(metaIndex *)index inPool:(apr_pool_t *)pool; +- (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; @@ -1292,12 +1316,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; @@ -1308,6 +1330,7 @@ static void PackageImport(const void *key, const void *value, void *context) { - (NSString *) version; - (NSString *) defaultIcon; +- (NSURL *) iconURL; @end @@ -1333,18 +1356,39 @@ static void PackageImport(const void *key, const void *value, void *context) { authority_ = nil; } ++ (NSString *) webScriptNameForSelector:(SEL)selector { + if (false); + else if (selector == @selector(addSection:)) + return @"addSection"; + else if (selector == @selector(getField:)) + return @"getField"; + else if (selector == @selector(removeSection:)) + return @"removeSection"; + else if (selector == @selector(remove)) + return @"remove"; + else + return nil; +} + ++ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector { + return [self webScriptNameForSelector:selector] == nil; +} + + (NSArray *) _attributeKeys { return [NSArray arrayWithObjects: + @"baseuri", @"distribution", @"host", @"key", + @"iconuri", @"label", @"name", @"origin", + @"rooturi", + @"sections", @"shortDescription", @"trusted", @"type", - @"uri", @"version", nil]; } @@ -1417,19 +1461,44 @@ static void PackageImport(const void *key, const void *value, void *context) { authority_ = [url path]; } -- (Source *) initWithMetaIndex:(metaIndex *)index inPool:(apr_pool_t *)pool { +- (Source *) initWithMetaIndex:(metaIndex *)index forDatabase:(Database *)database inPool:(apr_pool_t *)pool { if ((self = [super init]) != nil) { + era_ = [database era]; + database_ = database; + index_ = index; + [self setMetaIndex:index inPool:pool]; } return self; } -- (NSComparisonResult) compareByNameAndType:(Source *)source { - NSDictionary *lhr = [self record]; - NSDictionary *rhr = [source record]; +- (NSString *) getField:(NSString *)name { +@synchronized (database_) { + if ([database_ era] != era_ || index_ == NULL) + return nil; + + debReleaseIndex *dindex(dynamic_cast(index_)); + if (dindex == NULL) + return nil; + + FileFd fd; + if (!fd.Open(dindex->MetaIndexFile("Release"), FileFd::ReadOnly)) { + _error->Discard(); + return nil; + } + + pkgTagFile tags(&fd); + + pkgTagSection section; + tags.Step(section); + + const char *start, *end; + if (!section.Find([name UTF8String], start, end)) + return (NSString *) [NSNull null]; - if (lhr != rhr) - return lhr == nil ? NSOrderedDescending : NSOrderedAscending; + return [NSString stringWithString:[(NSString *) CYStringCreate(start, end - start) autorelease]]; +} } +- (NSComparisonResult) compareByName:(Source *)source { NSString *lhs = [self name]; NSString *rhs = [source name]; @@ -1454,6 +1523,62 @@ static void PackageImport(const void *key, const void *value, void *context) { return support_.empty() ? nil : [static_cast(support_) stringByReplacingOccurrencesOfString:@"*" withString:package]; } +- (NSArray *) sections { + return record_ == nil ? (id) [NSNull null] : [record_ objectForKey:@"Sections"] ?: [NSArray array]; +} + +- (void) _addSection:(NSString *)section { + if (record_ == nil) + return; + else if (NSMutableArray *sections = [record_ objectForKey:@"Sections"]) { + if (![sections containsObject:section]) { + [sections addObject:section]; + Changed_ = true; + } + } else { + [record_ setObject:[NSMutableArray arrayWithObject:section] forKey:@"Sections"]; + Changed_ = true; + } +} + +- (bool) addSection:(NSString *)section { + if (record_ == nil) + return false; + + [self performSelectorOnMainThread:@selector(_addSection:) withObject:section waitUntilDone:NO]; + return true; +} + +- (void) _removeSection:(NSString *)section { + if (record_ == nil) + return; + + if (NSMutableArray *sections = [record_ objectForKey:@"Sections"]) + if ([sections containsObject:section]) { + [sections removeObject:section]; + Changed_ = true; + } +} + +- (bool) removeSection:(NSString *)section { + if (record_ == nil) + return false; + + [self performSelectorOnMainThread:@selector(_removeSection:) withObject:section waitUntilDone:NO]; + return true; +} + +- (void) _remove { + [Sources_ removeObjectForKey:[self key]]; + Changed_ = true; +} + +- (bool) remove { + bool value(record_ != nil); + [self performSelectorOnMainThread:@selector(_remove) withObject:nil waitUntilDone:NO]; + return value; +} + - (NSDictionary *) record { return record_; } @@ -1462,7 +1587,7 @@ static void PackageImport(const void *key, const void *value, void *context) { return trusted_; } -- (NSString *) uri { +- (NSString *) rooturi { return uri_; } @@ -1474,8 +1599,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 { @@ -1670,8 +1808,10 @@ static void PackageImport(const void *key, const void *value, void *context) { /* }}} */ /* Package Class {{{ */ struct ParsedPackage { + CYString md5sum_; CYString tagline_; + CYString architecture_; CYString icon_; CYString depiction_; @@ -1685,11 +1825,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_; @@ -1936,6 +2077,8 @@ struct PackageNameOrdering : } - (void) dealloc { + if (!pooled_) + apr_pool_destroy(pool_); if (parsed_ != NULL) delete parsed_; [super dealloc]; @@ -1964,6 +2107,7 @@ struct PackageNameOrdering : + (NSArray *) _attributeKeys { return [NSArray arrayWithObjects: @"applications", + @"architecture", @"author", @"depiction", @"essential", @@ -1975,6 +2119,7 @@ struct PackageNameOrdering : @"longDescription", @"longSection", @"maintainer", + @"md5sum", @"mode", @"name", @"purposes", @@ -2010,6 +2155,12 @@ struct PackageNameOrdering : return relations; } } +- (NSString *) architecture { + [self parse]; +@synchronized (database_) { + return parsed_->architecture_.empty() ? [NSNull null] : (id) parsed_->architecture_; +} } + - (NSString *) getField:(NSString *)name { @synchronized (database_) { if ([database_ era] != era_ || file_.end()) @@ -2021,7 +2172,7 @@ struct PackageNameOrdering : if (!parser.Find([name UTF8String], start, end)) return (NSString *) [NSNull null]; - return [(NSString *) CYStringCreate(start, end - start) autorelease]; + return [NSString stringWithString:[(NSString *) CYStringCreate(start, end - start) autorelease]]; } } - (void) parse { @@ -2048,6 +2199,7 @@ struct PackageNameOrdering : const char *name_; CYString *value_; } names[] = { + {"architecture", &parsed->architecture_}, {"icon", &parsed->icon_}, {"depiction", &parsed->depiction_}, {"homepage", &parsed->homepage_}, @@ -2056,6 +2208,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) { @@ -2094,7 +2247,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]; @@ -2285,6 +2443,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()) @@ -2316,8 +2478,29 @@ struct PackageNameOrdering : } } - (NSString *) shortDescription { - return parsed_ == NULL ? nil : static_cast(parsed_->tagline_); -} + if (parsed_ != NULL) + return static_cast(parsed_->tagline_); + +@synchronized (database_) { + pkgRecords::Parser &parser([database_ records]->Lookup(file_)); + + const char *start, *end; + if (!parser.ShortDesc(start, end)) + return nil; + + if (end - start > 200) + end = start + 200; + + /* + if (const char *stop = reinterpret_cast(memchr(start, '\n', end - start))) + end = stop; + + while (end != start && end[-1] == '\r') + --end; + */ + + return [(id) CYStringCreate(start, end - start) autorelease]; +} } - (unichar) index { _profile(Package$index) @@ -2489,14 +2672,12 @@ struct PackageNameOrdering : if (parsed_ != NULL) if (NSString *href = parsed_->icon_) if ([href hasPrefix:@"file:///"]) - // XXX: correct escaping - icon = [UIImage imageAtPath:[href substringFromIndex:7]]; + icon = [UIImage imageAtPath:[[href substringFromIndex:7] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; if (icon == nil) if (section != nil) - icon = [UIImage imageAtPath:[NSString stringWithFormat:@"%@/Sections/%@.png", App_, section]]; + icon = [UIImage imageAtPath:[NSString stringWithFormat:@"%@/Sections/%@.png", App_, [section stringByReplacingOccurrencesOfString:@" " withString:@"_"]]]; if (icon == nil) if (Source *source = [self source]) if (NSString *dicon = [source defaultIcon]) if ([dicon hasPrefix:@"file:///"]) - // XXX: correct escaping - icon = [UIImage imageAtPath:[dicon substringFromIndex:7]]; + icon = [UIImage imageAtPath:[[dicon substringFromIndex:7] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; if (icon == nil) icon = [UIImage applicationImageNamed:@"unknown.png"]; return icon; @@ -2697,33 +2878,34 @@ struct PackageNameOrdering : NSRange range; NSUInteger length; - [self parse]; - - string = [self id]; + string = [self name]; length = [string length]; for (NSString *term in query) { range = [string rangeOfString:term options:MatchCompareOptions_]; if (range.location != NSNotFound) - rank_ -= 10 * 100000 / length; + rank_ -= 6 * 1000000 / length; } - string = [self name]; + if (rank_ == 0) { + string = [self id]; + length = [string length]; - for (NSString *term in query) { - range = [string rangeOfString:term options:MatchCompareOptions_]; - if (range.location != NSNotFound) - rank_ -= 6 * 100000 / length; + for (NSString *term in query) { + range = [string rangeOfString:term options:MatchCompareOptions_]; + if (range.location != NSNotFound) + rank_ -= 6 * 1000000 / length; + } } string = [self shortDescription]; length = [string length]; - NSUInteger stop(std::min(length, 100)); + NSUInteger stop(std::min(length, 200)); for (NSString *term in query) { range = [string rangeOfString:term options:MatchCompareOptions_ range:NSMakeRange(0, stop)]; if (range.location != NSNotFound) - rank_ -= 2 * 100000 / length; + rank_ -= 2 * 100000; } return rank_ != 0; @@ -2997,11 +3179,6 @@ struct PackageNameOrdering : @end /* }}} */ -static NSString *Colon_; -NSString *Elision_; -static NSString *Error_; -static NSString *Warning_; - class CydiaLogCleaner : public pkgArchiveCleaner { @@ -3147,11 +3324,13 @@ class CydiaLogCleaner : } - (Package *) packageWithName:(NSString *)name { + if (name == nil) + return nil; @synchronized (self) { 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 { @@ -3385,7 +3564,7 @@ class CydiaLogCleaner : } for (pkgSourceList::const_iterator source = list_->begin(); source != list_->end(); ++source) { - Source *object([[[Source alloc] initWithMetaIndex:*source inPool:pool_] autorelease]); + Source *object([[[Source alloc] initWithMetaIndex:*source forDatabase:self inPool:pool_] autorelease]); [sourceList_ addObject:object]; std::vector *indices = (*source)->GetIndexFiles(); @@ -3764,6 +3943,7 @@ static _H Diversions_; + (NSArray *) _attributeKeys { return [NSArray arrayWithObjects: @"bbsnum", + @"cydiaSource", @"device", @"ecid", @"firmware", @@ -3787,7 +3967,7 @@ static _H Diversions_; } - (NSString *) version { - return @ Cydia_; + return Cydia_; } - (NSString *) device { @@ -3838,10 +4018,14 @@ static _H Diversions_; if (false); else if (selector == @selector(addBridgedHost:)) return @"addBridgedHost"; + else if (selector == @selector(addInsecureHost:)) + return @"addInsecureHost"; else if (selector == @selector(addInternalRedirect::)) return @"addInternalRedirect"; else if (selector == @selector(addPipelinedHost:scheme:)) return @"addPipelinedHost"; + else if (selector == @selector(addSource:::)) + return @"addSource"; else if (selector == @selector(addTokenHost:)) return @"addTokenHost"; else if (selector == @selector(addTrivialSource:)) @@ -3868,6 +4052,10 @@ static _H Diversions_; return @"getPreferredLanguages"; else if (selector == @selector(getPackageById:)) return @"getPackageById"; + else if (selector == @selector(getMetadataKeys)) + return @"getMetadataKeys"; + else if (selector == @selector(getMetadataValue:)) + return @"getMetadataValue"; else if (selector == @selector(getSessionValue:)) return @"getSessionValue"; else if (selector == @selector(installPackages:)) @@ -3880,6 +4068,12 @@ static _H Diversions_; return @"refreshSources"; else if (selector == @selector(removeButton)) 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::)) return @"setSessionValue"; else if (selector == @selector(substitutePackageNames:)) @@ -3980,6 +4174,45 @@ 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]; +} } + +- (id) getMetadataValue:(NSString *)key { +@synchronized (Values_) { + return [Values_ objectForKey:key]; +} } + +- (void) setMetadataValue:(NSString *)key :(NSString *)value { +@synchronized (Values_) { + if (value == nil || value == (id) [WebUndefined undefined] || value == (id) [NSNull null]) + [Values_ removeObjectForKey:key]; + else + [Values_ setObject:value forKey:key]; + + [delegate_ performSelectorOnMainThread:@selector(updateValues) withObject:nil waitUntilDone:YES]; +} } + - (id) getSessionValue:(NSString *)key { @synchronized (SessionData_) { return [SessionData_ objectForKey:key]; @@ -3998,6 +4231,11 @@ static _H Diversions_; [BridgedHosts_ addObject:host]; } } +- (void) addInsecureHost:(NSString *)host { +@synchronized (HostConfig_) { + [InsecureHosts_ addObject:host]; +} } + - (void) addTokenHost:(NSString *)host { @synchronized (HostConfig_) { [TokenHosts_ addObject:host]; @@ -4017,6 +4255,20 @@ static _H Diversions_; [indirect_ performSelectorOnMainThread:@selector(popViewControllerWithNumber:) withObject:value waitUntilDone:NO]; } +- (void) addSource:(NSString *)href :(NSString *)distribution :(WebScriptObject *)sections { + NSMutableArray *array([NSMutableArray arrayWithCapacity:[sections count]]); + + for (NSString *section in sections) + [array addObject:section]; + + [delegate_ performSelectorOnMainThread:@selector(addSource:) withObject:[NSMutableDictionary dictionaryWithObjectsAndKeys: + @"deb", @"Type", + href, @"URI", + distribution, @"Distribution", + array, @"Sections", + nil] waitUntilDone:NO]; +} + - (void) addTrivialSource:(NSString *)href { [delegate_ performSelectorOnMainThread:@selector(addTrivialSource:) withObject:href waitUntilDone:NO]; } @@ -4025,6 +4277,10 @@ static _H Diversions_; [delegate_ performSelectorOnMainThread:@selector(syncData) withObject:nil waitUntilDone:NO]; } +- (void) saveConfig { + [delegate_ performSelectorOnMainThread:@selector(_saveConfig) withObject:nil waitUntilDone:NO]; +} + - (NSArray *) getAllSources { return [[Database sharedInstance] sources]; } @@ -4221,6 +4477,24 @@ static _H Diversions_; @end /* }}} */ +@interface NSURL (CydiaSecure) +@end + +@implementation NSURL (CydiaSecure) + +- (bool) isCydiaSecure { + if ([[[self scheme] lowercaseString] isEqualToString:@"https"]) + return true; + + @synchronized (HostConfig_) { + if ([InsecureHosts_ containsObject:[self host]]) + return true; + } + + return false; +} + +@end /* Cydia Browser Controller {{{ */ @implementation CydiaWebViewController @@ -4229,7 +4503,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]; } @@ -4283,12 +4559,14 @@ static _H Diversions_; bool token; @synchronized (HostConfig_) { - token = [TokenHosts_ containsObject:host]; + token = [TokenHosts_ containsObject:host] || [BridgedHosts_ containsObject:host]; } - if (token) { + if ([url isCydiaSecure] && token) { if (Token_ != nil && [copy valueForHTTPHeaderField:@"X-Cydia-Token"] == nil) [copy setValue:Token_ forHTTPHeaderField:@"X-Cydia-Token"]; + if (UniqueID_ != nil && [copy valueForHTTPHeaderField:@"X-Cydia-Id"] == nil) + [copy setValue:UniqueID_ forHTTPHeaderField:@"X-Cydia-Id"]; } return copy; @@ -4300,7 +4578,7 @@ static _H Diversions_; } - (NSString *) applicationNameForUserAgent { - NSString *application([NSString stringWithFormat:@"Cydia/%@", @ Cydia_]); + NSString *application([NSString stringWithFormat:@"Cydia/%@", Cydia_]); if (Safari_ != nil) application = [NSString stringWithFormat:@"Safari/%@ %@", Safari_, application]; @@ -4318,6 +4596,18 @@ static _H Diversions_; } return self; } +@end + +@interface AppCacheController : CydiaWebViewController { +} + +@end + +@implementation AppCacheController + +- (void) didReceiveMemoryWarning { +} + @end /* }}} */ @@ -4423,8 +4713,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) _doContinue { - [self dismissModalViewControllerAnimated:YES]; [delegate_ cancelAndClear:NO]; + [self dismissModalViewControllerAnimated:YES]; } - (id) invokeDefaultMethodWithArguments:(NSArray *)args { @@ -4859,8 +5149,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) close { UpdateExternalStatus(0); + if (Finish_ > 1) + [delegate_ saveState]; + switch (Finish_) { case 0: + [delegate_ returnToCydia]; break; case 1: @@ -5063,7 +5357,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { bool commercial_; _H source_; _H badge_; - _H package_; _H placard_; bool summarized_; } @@ -5105,83 +5398,84 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { source_ = nil; badge_ = nil; placard_ = nil; - package_ = nil; - [package parse]; + if (package == nil) + [content_ setBackgroundColor:[UIColor whiteColor]]; + else { + [package parse]; - Source *source = [package source]; + Source *source = [package source]; - icon_ = [package icon]; + icon_ = [package icon]; - if (NSString *name = [package name]) - name_ = [NSString stringWithString:name]; + if (NSString *name = [package name]) + name_ = [NSString stringWithString:name]; - NSString *description(nil); + NSString *description(nil); - if (description == nil && IsWildcat_) - description = [package longDescription]; - if (description == nil) - description = [package shortDescription]; + if (description == nil && IsWildcat_) + description = [package longDescription]; + if (description == nil) + description = [package shortDescription]; - if (description != nil) - description_ = [NSString stringWithString:description]; + if (description != nil) + description_ = [NSString stringWithString:description]; - commercial_ = [package isCommercial]; + commercial_ = [package isCommercial]; - package_ = package; + NSString *label = nil; + bool trusted = false; - NSString *label = nil; - bool trusted = false; + if (source != nil) { + label = [source label]; + trusted = [source trusted]; + } else if ([[package id] isEqualToString:@"firmware"]) + label = UCLocalize("APPLE"); + else + label = [NSString stringWithFormat:UCLocalize("SLASH_DELIMITED"), UCLocalize("UNKNOWN"), UCLocalize("LOCAL")]; - if (source != nil) { - label = [source label]; - trusted = [source trusted]; - } else if ([[package id] isEqualToString:@"firmware"]) - label = UCLocalize("APPLE"); - else - label = [NSString stringWithFormat:UCLocalize("SLASH_DELIMITED"), UCLocalize("UNKNOWN"), UCLocalize("LOCAL")]; + NSString *from(label); - NSString *from(label); + NSString *section = [package simpleSection]; + if (section != nil && ![section isEqualToString:label]) { + section = [[NSBundle mainBundle] localizedStringForKey:section value:nil table:@"Sections"]; + from = [NSString stringWithFormat:UCLocalize("PARENTHETICAL"), from, section]; + } - NSString *section = [package simpleSection]; - if (section != nil && ![section isEqualToString:label]) { - section = [[NSBundle mainBundle] localizedStringForKey:section value:nil table:@"Sections"]; - from = [NSString stringWithFormat:UCLocalize("PARENTHETICAL"), from, section]; - } + source_ = [NSString stringWithFormat:UCLocalize("FROM"), from]; - source_ = [NSString stringWithFormat:UCLocalize("FROM"), from]; + if (NSString *purpose = [package primaryPurpose]) + badge_ = [UIImage imageAtPath:[NSString stringWithFormat:@"%@/Purposes/%@.png", App_, purpose]]; - if (NSString *purpose = [package primaryPurpose]) - badge_ = [UIImage imageAtPath:[NSString stringWithFormat:@"%@/Purposes/%@.png", App_, purpose]]; + UIColor *color; + NSString *placard; - UIColor *color; - NSString *placard; + if (NSString *mode = [package mode]) { + if ([mode isEqualToString:@"REMOVE"] || [mode isEqualToString:@"PURGE"]) { + color = RemovingColor_; + //placard = @"removing"; + } else { + color = InstallingColor_; + //placard = @"installing"; + } - if (NSString *mode = [package_ mode]) { - if ([mode isEqualToString:@"REMOVE"] || [mode isEqualToString:@"PURGE"]) { - color = RemovingColor_; - //placard = @"removing"; + // XXX: the removing/installing placards are not @2x + placard = nil; } else { - color = InstallingColor_; - //placard = @"installing"; + color = [UIColor whiteColor]; + + if ([package installed] != nil) + placard = @"installed"; + else + placard = nil; } - // XXX: the removing/installing placards are not @2x - placard = nil; - } else { - color = [UIColor whiteColor]; + [content_ setBackgroundColor:color]; - if ([package installed] != nil) - placard = @"installed"; - else - placard = nil; + if (placard != nil) + placard_ = [UIImage imageAtPath:[NSString stringWithFormat:@"%@/%@.png", App_, placard]]; } - [content_ setBackgroundColor:color]; - - if (placard != nil) - placard_ = [UIImage imageAtPath:[NSString stringWithFormat:@"%@/%@.png", App_, placard]]; - [self setNeedsDisplay]; [content_ setNeedsDisplay]; } @@ -5194,11 +5488,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]; } @@ -5210,8 +5506,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]; } @@ -5235,8 +5531,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; @@ -5466,14 +5764,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) releaseSubviews { list_ = nil; + package_ = nil; + files_ = nil; + [super releaseSubviews]; } - (id) initWithDatabase:(Database *)database { if ((self = [super init]) != nil) { database_ = database; - - files_ = [NSMutableArray arrayWithCapacity:32]; } return self; } @@ -5481,7 +5780,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { package_ = nil; name_ = nil; - [files_ removeAllObjects]; + files_ = [NSMutableArray arrayWithCapacity:32]; if (package != nil) { package_ = package; @@ -5637,7 +5936,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { if ((self = [super init]) != nil) { database_ = database; buttons_ = [NSMutableArray arrayWithCapacity:4]; - name_ = [NSString stringWithString:name]; + name_ = name == nil ? @"" : [NSString stringWithString:name]; [self setURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/#!/package/%@", UI_, (id) name_]]]; } return self; } @@ -5777,7 +6076,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]; } @@ -5855,7 +6154,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { PackageCell *cell((PackageCell *) [table dequeueReusableCellWithIdentifier:@"Package"]); if (cell == nil) cell = [[[PackageCell alloc] init] autorelease]; - [cell setPackage:[self packageAtIndexPath:path] asSummary:[self isSummarized]]; + + Package *package([database_ packageWithName:[[self packageAtIndexPath:path] id]]); + [cell setPackage:package asSummary:[self isSummarized]]; return cell; } @@ -5866,7 +6167,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (NSArray *) sectionIndexTitlesForTableView:(UITableView *)tableView { - if ([self showsSections]) + if (![self showsSections]) return nil; return index_; @@ -5891,18 +6192,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { database_ = database; title_ = [title copy]; [[self navigationItem] setTitle:title_]; - -#if TryIndexedCollation - if ([[self class] hasIndexedCollation]) - index_ = [[objc_getClass("UILocalizedIndexedCollation") currentCollation] sectionIndexTitles]; - else -#endif - index_ = [NSMutableArray arrayWithCapacity:32]; - - indices_ = [NSMutableDictionary dictionaryWithCapacity:32]; - - packages_ = [NSArray array]; - sections_ = [NSMutableArray arrayWithCapacity:16]; } return self; } @@ -5925,6 +6214,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) releaseSubviews { list_ = nil; + packages_ = nil; + sections_ = nil; + index_ = nil; + indices_ = nil; + [super releaseSubviews]; } @@ -5981,13 +6275,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { packages_ = packages; - [indices_ removeAllObjects]; - [sections_ removeAllObjects]; + indices_ = [NSMutableDictionary dictionaryWithCapacity:32]; + sections_ = [NSMutableArray arrayWithCapacity:16]; Section *section = nil; #if TryIndexedCollation if ([[self class] hasIndexedCollation]) { + index_ = [[objc_getClass("UILocalizedIndexedCollation") currentCollation] sectionIndexTitles]; + id collation = [objc_getClass("UILocalizedIndexedCollation") currentCollation]; NSArray *titles = [collation sectionIndexTitles]; int secidx = -1; @@ -6020,7 +6316,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } else #endif { - [index_ removeAllObjects]; + index_ = [NSMutableArray arrayWithCapacity:32]; bool sectioned([self showsSections]); if (!sectioned) { @@ -6066,7 +6362,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) reloadData { [super reloadData]; - [self performSelector:@selector(_reloadData) withObject:nil afterDelay:0]; + + if ([self shouldYield]) + [self performSelector:@selector(_reloadData) withObject:nil afterDelay:0]; + else + [self _reloadData]; } - (void) resetCursor { @@ -6184,6 +6484,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { return [NSURL URLWithString:@"cydia://home"]; } +- (void) didReceiveMemoryWarning { +} + - (void) aboutButtonClicked { UIAlertView *alert([[[UIAlertView alloc] init] autorelease]); @@ -6460,6 +6763,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]; @@ -6598,7 +6908,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; @@ -6682,8 +6992,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) reloadData { [super reloadData]; - if (UIViewController *visible = [self visibleViewController]) + UIViewController *visible([self visibleViewController]); + if (visible != nil) [visible reloadData]; + + // on the iPad, this view controller is ALSO visible. :( + if (IsWildcat_) + if (UIViewController *top = [self topViewController]) + if (top != visible) + [top reloadData]; } - (void) unloadData { @@ -6775,15 +7092,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; @@ -6794,8 +7102,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { if (path == nil) goto fail; path = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; - NSString *section(Simplify(path)); - UIImage *icon([UIImage imageAtPath:[NSString stringWithFormat:@"%@/Sections/%@.png", App_, [section stringByReplacingOccurrencesOfString:@" " withString:@"_"]]]); + UIImage *icon([UIImage imageAtPath:[NSString stringWithFormat:@"%@/Sections/%@.png", App_, [path stringByReplacingOccurrencesOfString:@" " withString:@"_"]]]); if (icon == nil) icon = [UIImage applicationImageNamed:@"unknown.png"]; [self _returnPNGWithImage:icon forRequest:request]; @@ -6972,15 +7279,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) releaseSubviews { list_ = nil; + sections_ = nil; + filtered_ = nil; + [super releaseSubviews]; } - (id) initWithDatabase:(Database *)database { if ((self = [super init]) != nil) { database_ = database; - - sections_ = [NSMutableArray arrayWithCapacity:16]; - filtered_ = [NSMutableArray arrayWithCapacity:16]; } return self; } @@ -6989,8 +7296,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { NSArray *packages = [database_ packages]; - [sections_ removeAllObjects]; - [filtered_ removeAllObjects]; + sections_ = [NSMutableArray arrayWithCapacity:16]; + filtered_ = [NSMutableArray arrayWithCapacity:16]; NSMutableDictionary *sections([NSMutableDictionary dictionaryWithCapacity:32]); @@ -7110,7 +7417,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { PackageCell *cell((PackageCell *) [table dequeueReusableCellWithIdentifier:@"Package"]); if (cell == nil) cell = [[[PackageCell alloc] init] autorelease]; - [cell setPackage:[self packageAtIndexPath:path] asSummary:false]; + + Package *package([database_ packageWithName:[[self packageAtIndexPath:path] id]]); + [cell setPackage:package asSummary:false]; return cell; } @@ -7129,6 +7438,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) upgradeButtonClicked { [delegate_ distUpgrade]; + [[self navigationItem] setRightBarButtonItem:nil animated:YES]; } - (void) loadView { @@ -7151,15 +7461,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) releaseSubviews { list_ = nil; + packages_ = nil; + sections_ = nil; + [super releaseSubviews]; } - (id) initWithDatabase:(Database *)database { if ((self = [super init]) != nil) { database_ = database; - - packages_ = [NSArray array]; - sections_ = [NSMutableArray arrayWithCapacity:16]; } return self; } @@ -7204,7 +7514,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { goto reload; packages_ = packages; - [sections_ removeAllObjects]; + sections_ = [NSMutableArray arrayWithCapacity:16]; Section *upgradable = [[[Section alloc] initWithName:UCLocalize("AVAILABLE_UPGRADES") localize:NO] autorelease]; Section *ignored = nil; @@ -7268,21 +7578,19 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [list_ reloadData]; - if (upgrades_ > 0) - [[self navigationItem] setRightBarButtonItem:[[[UIBarButtonItem alloc] - initWithTitle:[NSString stringWithFormat:UCLocalize("PARENTHETICAL"), UCLocalize("UPGRADE"), [NSString stringWithFormat:@"%u", upgrades_]] - style:UIBarButtonItemStylePlain - target:self - action:@selector(upgradeButtonClicked) - ] autorelease]]; + [[self navigationItem] setRightBarButtonItem:(upgrades_ == 0 ? nil : [[[UIBarButtonItem alloc] + initWithTitle:[NSString stringWithFormat:UCLocalize("PARENTHETICAL"), UCLocalize("UPGRADE"), [NSString stringWithFormat:@"%u", upgrades_]] + style:UIBarButtonItemStylePlain + target:self + action:@selector(upgradeButtonClicked) + ] autorelease]) animated:YES]; - if (![delegate_ updating]) - [[self navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] - initWithTitle:UCLocalize("REFRESH") - style:UIBarButtonItemStylePlain - target:self - action:@selector(refreshButtonClicked) - ] autorelease]]; + [[self navigationItem] setLeftBarButtonItem:([delegate_ updating] ? nil : [[[UIBarButtonItem alloc] + initWithTitle:UCLocalize("REFRESH") + style:UIBarButtonItemStylePlain + target:self + action:@selector(refreshButtonClicked) + ] autorelease]) animated:YES]; PrintTimes(); } } @@ -7448,7 +7756,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @implementation PackageSettingsController - (NSURL *) navigationURL { - return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://package/%@/settings", [package_ id]]]; + return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://package/%@/settings", (id) name_]]; } - (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView { @@ -7697,26 +8005,21 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [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:image waitUntilDone:NO]; [pool release]; } @@ -7725,11 +8028,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]; + if (NSURL *url = [source iconURL]) + [NSThread detachNewThreadSelector:@selector(_setSource:) toTarget:self withObject:url]; } - (SourceCell *) initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier { @@ -7744,6 +8048,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [content_ setDelegate:self]; [content_ setOpaque:YES]; + + [[content_ layer] setContentsGravity:kCAGravityTopLeft]; } return self; } @@ -7755,19 +8061,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 - 60) withFont:Font18Bold_ lineBreakMode:UILineBreakModeTailTruncation]; if (!highlighted) UISetColor(Blue_); - [label_ drawAtPoint:CGPointMake(58, 29) forWidth:(width - 95) withFont:Font12_ lineBreakMode:UILineBreakModeTailTruncation]; + [label_ drawAtPoint:CGPointMake(58, 29) forWidth:(width - 75) withFont:Font12_ lineBreakMode:UILineBreakModeTailTruncation]; } @end @@ -7785,7 +8103,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @implementation SourceController - (NSURL *) navigationURL { - return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://sources/%@", [source_ name]]]; + return [NSURL URLWithString:[NSString stringWithFormat:@"cydia://sources/%@", [key_ stringByAddingPercentEscapesIncludingReserved]]]; } - (id) initWithDatabase:(Database *)database source:(Source *)source { @@ -7865,37 +8183,19 @@ 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; - - _nodefault - } - return [sources_ objectAtIndex:idx]; + return [sources_ objectAtIndex:[indexPath row]]; } - (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { @@ -7983,12 +8283,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [delegate_ removeProgressHUD:hud_]; hud_ = nil; - bool defer(false); - if (cydia_) { if (NSString *warning = [self yieldToSelector:@selector(getWarning)]) { - defer = true; - UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:UCLocalize("SOURCE_WARNING") message:warning @@ -8002,8 +8298,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") @@ -8051,8 +8352,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (NSURLConnection *) _requestHRef:(NSString *)href method:(NSString *)method { + NSURL *url([NSURL URLWithString:href]); + NSMutableURLRequest *request = [NSMutableURLRequest - requestWithURL:[NSURL URLWithString:href] + requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:120.0 ]; @@ -8061,8 +8364,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { if (Machine_ != NULL) [request setValue:[NSString stringWithUTF8String:Machine_] forHTTPHeaderField:@"X-Machine"]; - if (UniqueID_ != nil) - [request setValue:UniqueID_ forHTTPHeaderField:@"X-Unique-ID"]; + + if ([url isCydiaSecure]) { + 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]; } @@ -8129,7 +8437,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { list_ = [[[UITableView alloc] initWithFrame:[[self view] bounds] style:UITableViewStylePlain] autorelease]; [list_ setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; - [list_ setRowHeight:56]; + [list_ setRowHeight:53]; [(UITableView *) list_ setDataSource:self]; [list_ setDelegate:self]; [[self view] addSubview:list_]; @@ -8145,13 +8453,14 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) releaseSubviews { list_ = nil; + sources_ = nil; + [super releaseSubviews]; } - (id) initWithDatabase:(Database *)database { if ((self = [super init]) != nil) { database_ = database; - sources_ = [NSMutableArray arrayWithCapacity:16]; } return self; } @@ -8162,10 +8471,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { if ([database_ popErrorWithTitle:UCLocalize("SOURCES") forOperation:list.ReadMainList()]) return; - [sources_ removeAllObjects]; + sources_ = [NSMutableArray arrayWithCapacity:16]; [sources_ addObjectsFromArray:[database_ sources]]; _trace(); - [sources_ sortUsingSelector:@selector(compareByNameAndType:)]; + [sources_ sortUsingSelector:@selector(compareByName:)]; _trace(); int count([sources_ count]); @@ -8283,6 +8592,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_]; } @@ -8628,6 +8938,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } } +- (void) returnToCydia { + [self _loaded]; +} + - (void) _saveConfig { _trace(); MetaFile_.Sync(); @@ -8648,6 +8962,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { NSLog(@"failure to serialize metadata: %@", error); } } + + CydiaWriteSources(); } // Navigation controller for the queuing badge. @@ -8662,7 +8978,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) _updateData { [self _saveConfig]; - [self unloadData]; UINavigationController *navigation = [self queueNavigationController]; @@ -8769,8 +9084,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } [self _updateData]; - - [self refreshIfPossible]; } } - (void) updateData { @@ -8838,36 +9151,28 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) reloadData { [self reloadDataWithInvocation:nil]; + if ([database_ progressDelegate] == nil) + [self _loaded]; } - (void) syncData { [self _saveConfig]; + [self detachNewProgressSelector:@selector(update_) toTarget:self forController:nil title:@"UPDATING_SOURCES"]; +} - FILE *file(fopen("/etc/apt/sources.list.d/cydia.list", "w")); - _assert(file != NULL); - - for (NSString *key in [Sources_ allKeys]) { - NSDictionary *source([Sources_ objectForKey:key]); - - fprintf(file, "%s %s %s\n", - [[source objectForKey:@"Type"] UTF8String], - [[source objectForKey:@"URI"] UTF8String], - [[source objectForKey:@"Distribution"] UTF8String] - ); - } - - fclose(file); +- (void) addSource:(NSDictionary *) source { + CydiaAddSource(source); +} - [self detachNewProgressSelector:@selector(update_) toTarget:self forController:nil title:@"UPDATING_SOURCES"]; +- (void) addSource:(NSString *)href withDistribution:(NSString *)distribution andSections:(NSArray *)sections { + CydiaAddSource(href, distribution, sections); } - (void) addTrivialSource:(NSString *)href { - [Sources_ setObject:[NSDictionary dictionaryWithObjectsAndKeys: - @"deb", @"Type", - href, @"URI", - @"./", @"Distribution", - nil] forKey:[NSString stringWithFormat:@"deb:%@:./", href]]; + CydiaAddSource(href, @"./"); +} +- (void) updateValues { Changed_ = true; } @@ -8958,6 +9263,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { ++locked_; [self detachNewProgressSelector:@selector(perform_) toTarget:self forController:navigation title:@"RUNNING"]; --locked_; + [self refreshIfPossible]; } - (void) showSettings { @@ -9111,7 +9417,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (UIProgressHUD *) addProgressHUD { - UIProgressHUD *hud([[[UIProgressHUD alloc] initWithWindow:window_] autorelease]); + UIProgressHUD *hud([[[UIProgressHUD alloc] init] autorelease]); [hud setAutoresizingMask:UIViewAutoresizingFlexibleBoth]; [window_ setUserInteractionEnabled:NO]; @@ -9123,7 +9429,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { UIView *view([target view]); [view addSubview:hud]; - [hud show:YES]; + [hud showInView:[tabbar_ view]]; ++locked_; return hud; @@ -9131,7 +9437,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) removeProgressHUD:(UIProgressHUD *)hud { --locked_; - [hud show:NO]; + [hud hide]; [hud removeFromSuperview]; [window_ setUserInteractionEnabled:YES]; } @@ -9211,7 +9517,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { controller = [[[SourcesController alloc] initWithDatabase:database_] autorelease]; [(SourcesController *)controller showAddSourcePrompt]; } else { - Source *source = [database_ sourceWithKey:argument]; + Source *source = [database_ sourceWithKey:[argument stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; controller = [[[SourceController alloc] initWithDatabase:database_ source:source] autorelease]; } } @@ -9270,15 +9576,19 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [super applicationWillResignActive:application]; } -- (void) applicationWillTerminate:(UIApplication *)application { - Changed_ = true; +- (void) saveState { [Metadata_ setObject:[tabbar_ navigationURLCollection] forKey:@"InterfaceState"]; [Metadata_ setObject:[NSDate date] forKey:@"LastClosed"]; [Metadata_ setObject:[NSNumber numberWithInt:[tabbar_ selectedIndex]] forKey:@"InterfaceIndex"]; + Changed_ = true; [self _saveConfig]; } +- (void) applicationWillTerminate:(UIApplication *)application { + [self saveState]; +} + - (void) setConfigurationData:(NSString *)data { static Pcre conffile_r("^'(.*)' '(.*)' ([01]) ([01])$"); @@ -9362,7 +9672,20 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [tabbar_ setUpdateDelegate:self]; } +- (void) _sendMemoryWarningNotification { + [[NSNotificationCenter defaultCenter] postNotificationName:@"UIApplicationDidReceiveMemoryWarningNotification" object:[UIApplication sharedApplication]]; +} + +- (void) _sendMemoryWarningNotifications { + while (true) { + [self performSelectorOnMainThread:@selector(_sendMemoryWarningNotification) withObject:nil waitUntilDone:NO]; + usleep(250000); + } +} + - (void) applicationDidFinishLaunching:(id)unused { + //[NSThread detachNewThreadSelector:@selector(_sendMemoryWarningNotifications) toTarget:self withObject:nil]; + _trace(); if ([self respondsToSelector:@selector(setApplicationSupportsShakeToEdit:)]) [self setApplicationSupportsShakeToEdit:NO]; @@ -9394,7 +9717,7 @@ _trace(); broken_ = [NSMutableArray arrayWithCapacity:4]; // XXX: I really need this thing... like, seriously... I'm sorry - [[[CydiaWebViewController alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/appcache/", UI_]]] reloadData]; + [[[AppCacheController alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/appcache/", UI_]]] reloadData]; window_ = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; [window_ orderFront:self]; @@ -9461,7 +9784,8 @@ _trace(); [window_ setUserInteractionEnabled:NO]; } - [self reloadData]; + [self reloadDataWithInvocation:nil]; + [self refreshIfPossible]; PrintTimes(); [self disemulate]; @@ -9686,17 +10010,29 @@ 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]; @synchronized (HostConfig_) { BridgedHosts_ = [NSMutableSet setWithCapacity:4]; TokenHosts_ = [NSMutableSet setWithCapacity:4]; + InsecureHosts_ = [NSMutableSet setWithCapacity:4]; PipelinedHosts_ = [NSMutableSet setWithCapacity:4]; 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)))); @@ -9836,7 +10172,7 @@ int main(int argc, char *argv[]) { ChipID_ = [CYHex((NSData *) CYIOGetValue("IODeviceTree:/chosen", @"unique-chip-id"), true) uppercaseString]; BBSNum_ = CYHex((NSData *) CYIOGetValue("IOService:/AppleARMPE/baseband", @"snum"), false); - UniqueID_ = [[UIDevice currentDevice] uniqueIdentifier]; + UniqueID_ = [device uniqueIdentifier]; CFStringRef (*$CTSIMSupportCopyMobileSubscriberCountryCode)(CFAllocatorRef); $CTSIMSupportCopyMobileSubscriberCountryCode = reinterpret_cast(dlsym(RTLD_DEFAULT, "CTSIMSupportCopyMobileSubscriberCountryCode")); @@ -9873,15 +10209,28 @@ int main(int argc, char *argv[]) { Settings_ = [Metadata_ objectForKey:@"Settings"]; Packages_ = [Metadata_ objectForKey:@"Packages"]; + + Values_ = [Metadata_ objectForKey:@"Values"]; Sections_ = [Metadata_ objectForKey:@"Sections"]; Sources_ = [Metadata_ objectForKey:@"Sources"]; Token_ = [Metadata_ objectForKey:@"Token"]; + + Version_ = [Metadata_ objectForKey:@"Version"]; + + @synchronized (HostConfig_) { + CydiaSource_ = [Metadata_ objectForKey:@"CydiaSource"]; + } } if (Settings_ != nil) Role_ = [Settings_ objectForKey:@"Role"]; + if (Values_ == nil) { + Values_ = [[[NSMutableDictionary alloc] initWithCapacity:4] autorelease]; + [Metadata_ setObject:Values_ forKey:@"Values"]; + } + if (Sections_ == nil) { Sections_ = [[[NSMutableDictionary alloc] initWithCapacity:32] autorelease]; [Metadata_ setObject:Sections_ forKey:@"Sections"]; @@ -9891,8 +10240,36 @@ int main(int argc, char *argv[]) { Sources_ = [[[NSMutableDictionary alloc] initWithCapacity:0] autorelease]; [Metadata_ setObject:Sources_ forKey:@"Sources"]; } + + if (Version_ == nil) { + Version_ = [NSNumber numberWithUnsignedInt:0]; + [Metadata_ setObject:Version_ forKey:@"Version"]; + } + + @synchronized (HostConfig_) { + if (CydiaSource_ == nil) { + CydiaSource_ = @"apt.saurik.com"; + [Metadata_ setObject:CydiaSource_ forKey:@"CydiaSource"]; + } + } + + if ([Version_ unsignedIntValue] == 0) { + 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"]; + + [Metadata_ removeObjectForKey:@"LastUpdate"]; + + Changed_ = true; + } /* }}} */ + CydiaWriteSources(); + _trace(); MetaFile_.Open("/var/lib/cydia/metadata.cb0"); _trace();