X-Git-Url: https://git.saurik.com/cydia.git/blobdiff_plain/eef85b05cc02b3528dd83e9c1acf40aeb347d44f..9856894f5f6603e9938128d85cebf7f5792d452d:/Cydia.mm?ds=sidebyside diff --git a/Cydia.mm b/Cydia.mm index d9891097..8702e29a 100644 --- a/Cydia.mm +++ b/Cydia.mm @@ -1,7 +1,9 @@ /* #include Directives {{{ */ #include #include -#import +#include + +#include #include #include @@ -25,7 +27,8 @@ extern "C" { #include } -#include +#include +#include #include #include @@ -56,6 +59,12 @@ while (false) @end /* }}} */ +#ifdef SRK_ASPEN +#define UITable UITableView +#endif + +OBJC_EXPORT const char *class_getName(Class cls); + /* Reset View (UIView) {{{ */ @interface UIView (CYResetView) - (void) resetViewAnimated:(BOOL)animated; @@ -64,7 +73,7 @@ while (false) @implementation UIView (CYResetView) - (void) resetViewAnimated:(BOOL)animated { - fprintf(stderr, "%s\n", self->isa->name); + fprintf(stderr, "%s\n", class_getName(self->isa)); _assert(false); } @@ -184,9 +193,9 @@ unsigned Minor_; unsigned BugFix_; #define FW_LEAST(major, minor, bugfix) \ - (major > Major_ || major == Major_ && \ - (minor > Minor_ || minor == Minor_ && \ - bugfix >= BugFix_)) + (major < Major_ || major == Major_ && \ + (minor < Minor_ || minor == Minor_ && \ + bugfix <= BugFix_)) bool bootstrap_ = false; @@ -462,6 +471,7 @@ inline float interpolate(float begin, float end, float fraction) { /* }}} */ @class Package; +@class Source; /* Database Interface {{{ */ @interface Database : NSObject { @@ -471,6 +481,10 @@ inline float interpolate(float begin, float end, float fraction) { pkgAcquire *fetcher_; FileFd *lock_; SPtr manager_; + pkgSourceList *list_; + + NSMutableDictionary *sources_; + NSMutableArray *packages_; id delegate_; Status status_; @@ -490,6 +504,7 @@ inline float interpolate(float begin, float end, float fraction) { - (pkgRecords *) records; - (pkgProblemResolver *) resolver; - (pkgAcquire &) fetcher; +- (NSArray *) packages; - (void) reloadData; - (void) prepare; @@ -498,6 +513,7 @@ inline float interpolate(float begin, float end, float fraction) { - (void) upgrade; - (void) setDelegate:(id)delegate; +- (Source *) getSource:(const pkgCache::PkgFileIterator &)file; @end /* }}} */ @@ -921,6 +937,138 @@ void AddTextView(NSMutableDictionary *fields, NSMutableArray *packages, NSString @end /* }}} */ +/* Source Class {{{ */ +@interface Source : NSObject { + NSString *description_; + NSString *label_; + NSString *origin_; + + NSString *uri_; + NSString *distribution_; + NSString *type_; + NSString *version_; + + NSString *defaultIcon_; + + BOOL trusted_; +} + +- (void) dealloc; + +- (Source *) initWithMetaIndex:(metaIndex *)index; + +- (BOOL) trusted; + +- (NSString *) uri; +- (NSString *) distribution; +- (NSString *) type; + +- (NSString *) description; +- (NSString *) label; +- (NSString *) origin; +- (NSString *) version; + +- (NSString *) defaultIcon; +@end + +@implementation Source + +- (void) dealloc { + [uri_ release]; + [distribution_ release]; + [type_ release]; + + if (description_ != nil) + [description_ release]; + if (label_ != nil) + [label_ release]; + if (origin_ != nil) + [origin_ release]; + if (version_ != nil) + [version_ release]; + + [super dealloc]; +} + +- (Source *) initWithMetaIndex:(metaIndex *)index { + if ((self = [super init]) != nil) { + trusted_ = index->IsTrusted(); + + uri_ = [[NSString stringWithCString:index->GetURI().c_str()] retain]; + distribution_ = [[NSString stringWithCString:index->GetDist().c_str()] retain]; + type_ = [[NSString stringWithCString:index->GetType()] retain]; + + description_ = nil; + label_ = nil; + origin_ = nil; + + debReleaseIndex *dindex(dynamic_cast(index)); + if (dindex != NULL) { + std::ifstream release(dindex->MetaIndexFile("Release").c_str()); + std::string line; + while (std::getline(release, line)) { + std::string::size_type colon(line.find(':')); + if (colon == std::string::npos) + continue; + + std::string name(line.substr(0, colon)); + std::string value(line.substr(colon + 1)); + while (!value.empty() && value[0] == ' ') + value = value.substr(1); + + if (name == "Default-Icon") + defaultIcon_ = [[NSString stringWithCString:value.c_str()] retain]; + else if (name == "Description") + description_ = [[NSString stringWithCString:value.c_str()] retain]; + else if (name == "Label") + label_ = [[NSString stringWithCString:value.c_str()] retain]; + else if (name == "Origin") + origin_ = [[NSString stringWithCString:value.c_str()] retain]; + else if (name == "Version") + version_ = [[NSString stringWithCString:value.c_str()] retain]; + } + } + } return self; +} + +- (BOOL) trusted { + return trusted_; +} + +- (NSString *) uri { + return uri_; +} + +- (NSString *) distribution { + return distribution_; +} + +- (NSString *) type { + return type_; +} + +- (NSString *) description { + return description_; +} + +- (NSString *) label { + return label_; +} + +- (NSString *) origin { + return origin_; +} + +- (NSString *) version { + return version_; +} + +- (NSString *) defaultIcon { + return defaultIcon_; +} + +@end +/* }}} */ /* Package Class {{{ */ NSString *Scour(const char *field, const char *begin, const char *end) { size_t i(0), l(strlen(field)); @@ -955,6 +1103,7 @@ NSString *Scour(const char *field, const char *begin, const char *end) { Database *database_; pkgCache::VerIterator version_; pkgCache::VerFileIterator file_; + Source *source_; NSString *latest_; NSString *installed_; @@ -982,6 +1131,8 @@ NSString *Scour(const char *field, const char *begin, const char *end) { - (NSString *) latest; - (NSString *) installed; - (BOOL) upgradable; +- (BOOL) essential; +- (BOOL) broken; - (NSString *) id; - (NSString *) name; @@ -989,6 +1140,8 @@ NSString *Scour(const char *field, const char *begin, const char *end) { - (NSString *) icon; - (NSString *) website; +- (Source *) source; + - (BOOL) matches:(NSString *)text; - (NSComparisonResult) compareByName:(Package *)package; @@ -1012,6 +1165,12 @@ NSString *Scour(const char *field, const char *begin, const char *end) { [tagline_ release]; if (icon_ != nil) [icon_ release]; + if (website_ != nil) + [website_ release]; + + if (source_ != nil) + [source_ release]; + [super dealloc]; } @@ -1043,8 +1202,10 @@ NSString *Scour(const char *field, const char *begin, const char *end) { if (website_ != nil) website_ = [website_ retain]; + source_ = [[database_ getSource:file_.File()] retain]; + NSMutableDictionary *metadata = [Packages_ objectForKey:id_]; - if (metadata == nil) { + if (metadata == nil || [metadata count] == 0) { metadata = [NSMutableDictionary dictionaryWithObjectsAndKeys: now_, @"FirstSeen", nil]; @@ -1067,7 +1228,8 @@ NSString *Scour(const char *field, const char *begin, const char *end) { } - (NSString *) section { - return [[NSString stringWithCString:iterator_.Section()] stringByReplacingCharacter:'_' withCharacter:' ']; + const char *section = iterator_.Section(); + return section == NULL ? nil : [[NSString stringWithCString:section] stringByReplacingCharacter:'_' withCharacter:' ']; } - (Address *) maintainer { @@ -1115,8 +1277,18 @@ NSString *Scour(const char *field, const char *begin, const char *end) { } - (BOOL) upgradable { - NSString *installed = [self installed]; - return installed != nil && [[self latest] compare:installed] != NSOrderedSame ? YES : NO; + if (NSString *installed = [self installed]) + return [[self latest] compare:installed] != NSOrderedSame ? YES : NO; + else + return [self essential]; +} + +- (BOOL) essential { + return (iterator_->Flags & pkgCache::Flag::Essential) == 0 ? NO : YES; +} + +- (BOOL) broken { + return (*[database_ cache])[iterator_].InstBroken(); } - (NSString *) id { @@ -1139,6 +1311,10 @@ NSString *Scour(const char *field, const char *begin, const char *end) { return website_; } +- (Source *) source { + return source_; +} + - (BOOL) matches:(NSString *)text { if (text == nil) return NO; @@ -1178,9 +1354,19 @@ NSString *Scour(const char *field, const char *begin, const char *end) { } - (NSComparisonResult) compareBySectionAndName:(Package *)package { - NSComparisonResult result = [[self section] compare:[package section]]; - if (result != NSOrderedSame) - return result; + NSString *lhs = [self section]; + NSString *rhs = [package section]; + + if (lhs == NULL && rhs != NULL) + return NSOrderedAscending; + else if (lhs != NULL && rhs == NULL) + return NSOrderedDescending; + else if (lhs != NULL && rhs != NULL) { + NSComparisonResult result = [lhs compare:rhs]; + if (result != NSOrderedSame) + return result; + } + return [self compareByName:package]; } @@ -1321,14 +1507,14 @@ NSString *Scour(const char *field, const char *begin, const char *end) { } - (int) numberOfGroupsInPreferencesTable:(UIPreferencesTable *)table { - return 2; + return 3; } - (NSString *) preferencesTable:(UIPreferencesTable *)table titleForGroup:(int)group { switch (group) { case 0: return nil; - case 1: return @"Details"; - case 2: return @"Source"; + case 1: return @"Package Details"; + case 2: return @"Source Information"; default: _assert(false); } @@ -1345,7 +1531,7 @@ NSString *Scour(const char *field, const char *begin, const char *end) { switch (group) { case 0: return [package_ website] == nil ? 2 : 3; case 1: return 5; - case 2: return 0; + case 2: return 3; default: _assert(false); } @@ -1387,10 +1573,11 @@ NSString *Scour(const char *field, const char *begin, const char *end) { [cell setValue:(installed == nil ? @"n/a" : installed)]; } break; - case 2: + case 2: { [cell setTitle:@"Section"]; - [cell setValue:[package_ section]]; - break; + NSString *section([package_ section]); + [cell setValue:(section == nil ? @"n/a" : section)]; + } break; case 3: [cell setTitle:@"Expanded Size"]; @@ -1408,6 +1595,21 @@ NSString *Scour(const char *field, const char *begin, const char *end) { } break; case 2: switch (row) { + case 0: + [cell setTitle:[[package_ source] label]]; + [cell setValue:[[package_ source] version]]; + break; + + case 1: + [cell setValue:[[package_ source] description]]; + break; + + case 2: + [cell setTitle:@"Origin"]; + [cell setValue:[[package_ source] origin]]; + break; + + default: _assert(false); } break; default: _assert(false); @@ -1483,9 +1685,12 @@ NSString *Scour(const char *field, const char *begin, const char *end) { /* }}} */ /* Package Cell {{{ */ @interface PackageCell : UITableCell { + UIImageView *icon_; UITextLabel *name_; - UITextLabel *version_; UITextLabel *description_; + UITextLabel *source_; + UITextLabel *version_; + UIImageView *trusted_; SEL versioner_; } @@ -1504,9 +1709,12 @@ NSString *Scour(const char *field, const char *begin, const char *end) { @implementation PackageCell - (void) dealloc { + [icon_ release]; [name_ release]; - [version_ release]; [description_ release]; + [source_ release]; + [version_ release]; + [trusted_ release]; [super dealloc]; } @@ -1522,21 +1730,33 @@ NSString *Scour(const char *field, const char *begin, const char *end) { CGColor clear(space, 0, 0, 0, 0); - name_ = [[UITextLabel alloc] initWithFrame:CGRectMake(12, 7, 250, 25)]; + icon_ = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 30, 30)]; + + name_ = [[UITextLabel alloc] initWithFrame:CGRectMake(48, 12, 240, 25)]; [name_ setBackgroundColor:clear]; [name_ setFont:bold]; - version_ = [[UIRightTextLabel alloc] initWithFrame:CGRectMake(286, 7, 70, 25)]; + description_ = [[UITextLabel alloc] initWithFrame:CGRectMake(12, 46, 280, 20)]; + [description_ setBackgroundColor:clear]; + [description_ setFont:small]; + + source_ = [[UITextLabel alloc] initWithFrame:CGRectMake(12, 72, 225, 20)]; + [source_ setBackgroundColor:clear]; + [source_ setFont:large]; + + version_ = [[UIRightTextLabel alloc] initWithFrame:CGRectMake(286, 69, 70, 25)]; [version_ setBackgroundColor:clear]; [version_ setFont:large]; - description_ = [[UITextLabel alloc] initWithFrame:CGRectMake(13, 35, 280, 20)]; - [description_ setBackgroundColor:clear]; - [description_ setFont:small]; + //trusted_ = [[UIImageView alloc] initWithFrame:CGRectMake(278, 7, 16, 16)]; + trusted_ = [[UIImageView alloc] initWithFrame:CGRectMake(30, 30, 16, 16)]; + [trusted_ setImage:[UIImage applicationImageNamed:@"trusted.png"]]; + [self addSubview:icon_]; [self addSubview:name_]; - [self addSubview:version_]; [self addSubview:description_]; + [self addSubview:source_]; + [self addSubview:version_]; CGColorSpaceRelease(space); @@ -1547,9 +1767,43 @@ NSString *Scour(const char *field, const char *begin, const char *end) { } - (void) setPackage:(Package *)package { + Source *source = [package source]; + + UIImage *image = nil; + if (NSString *icon = [package icon]) + image = [UIImage imageAtPath:[icon substringFromIndex:6]]; + if (image == nil) if (NSString *icon = [source defaultIcon]) + image = [UIImage imageAtPath:[icon substringFromIndex:6]]; + if (image == nil) + image = [UIImage applicationImageNamed:@"unknown.png"]; + + [icon_ setImage:image]; + [icon_ zoomToScale:0.5f]; + [icon_ setFrame:CGRectMake(10, 10, 30, 30)]; + [name_ setText:[package name]]; [version_ setText:[package latest]]; [description_ setText:[package tagline]]; + + NSString *label; + bool trusted; + + if (source != nil) { + label = [source label]; + trusted = [source trusted]; + } else if ([[package id] isEqualToString:@"firmware"]) { + label = @"Apple"; + trusted = false; + } else { + label = @"Unknown/Local"; + trusted = false; + } + + [source_ setText:[NSString stringWithFormat:@"from %@", label]]; + + [trusted_ removeFromSuperview]; + if (trusted) + [self addSubview:trusted_]; } - (void) _setSelected:(float)fraction { @@ -1574,8 +1828,9 @@ NSString *Scour(const char *field, const char *begin, const char *end) { 1.0); [name_ setColor:black]; - [version_ setColor:blue]; [description_ setColor:gray]; + [source_ setColor:black]; + [version_ setColor:blue]; CGColorSpaceRelease(space); } @@ -1675,6 +1930,9 @@ NSString *Scour(const char *field, const char *begin, const char *end) { fetcher_ = NULL; lock_ = NULL; + sources_ = [[NSMutableDictionary dictionaryWithCapacity:16] retain]; + packages_ = [[NSMutableArray arrayWithCapacity:16] retain]; + int fds[2]; _assert(pipe(fds) != -1); @@ -1714,19 +1972,52 @@ NSString *Scour(const char *field, const char *begin, const char *end) { return *fetcher_; } +- (NSArray *) packages { + return packages_; +} + - (void) reloadData { _error->Discard(); + delete list_; manager_ = NULL; delete lock_; delete fetcher_; delete resolver_; delete records_; cache_.Close(); - _assert(cache_.Open(progress_, true)); + + if (!cache_.Open(progress_, true)) { + fprintf(stderr, "repairing corrupted database...\n"); + _error->Discard(); + [self update]; + _assert(cache_.Open(progress_, true)); + } + + now_ = [NSDate date]; + records_ = new pkgRecords(cache_); resolver_ = new pkgProblemResolver(cache_); fetcher_ = new pkgAcquire(&status_); lock_ = NULL; + + list_ = new pkgSourceList(); + _assert(list_->ReadMainList()); + + [sources_ removeAllObjects]; + for (pkgSourceList::const_iterator source = list_->begin(); source != list_->end(); ++source) { + std::vector *indices = (*source)->GetIndexFiles(); + for (std::vector::const_iterator index = indices->begin(); index != indices->end(); ++index) + [sources_ + setObject:[[[Source alloc] initWithMetaIndex:*source] autorelease] + forKey:[NSNumber numberWithLong:reinterpret_cast(*index)] + ]; + } + + [packages_ removeAllObjects]; + for (pkgCache::PkgIterator iterator = cache_->PkgBegin(); !iterator.end(); ++iterator) + if (Package *package = [Package packageWithIterator:iterator database:self]) + if ([package source] != nil || [package installed] != nil) + [packages_ addObject:package]; } - (void) prepare { @@ -1805,6 +2096,12 @@ NSString *Scour(const char *field, const char *begin, const char *end) { progress_.setDelegate(delegate); } +- (Source *) getSource:(const pkgCache::PkgFileIterator &)file { + pkgIndexFile *index(NULL); + list_->FindIndex(file, index); + return [sources_ objectForKey:[NSNumber numberWithLong:reinterpret_cast(index)]]; +} + @end /* }}} */ @@ -2173,7 +2470,7 @@ NSString *Scour(const char *field, const char *begin, const char *end) { } - (float) table:(UITable *)table heightForRow:(int)row { - return 64; + return 100; } - (UITableCell *) table:(UITable *)table cellForRow:(int)row column:(UITableColumn *)col reusing:(UITableCell *)reusing { @@ -2291,7 +2588,7 @@ NSString *Scour(const char *field, const char *begin, const char *end) { CGColor clear(space, 0, 0, 0, 0); CGColor white(space, 1, 1, 1, 1); - name_ = [[UITextLabel alloc] initWithFrame:CGRectMake(47, 9, 250, 25)]; + name_ = [[UITextLabel alloc] initWithFrame:CGRectMake(48, 9, 250, 25)]; [name_ setBackgroundColor:clear]; [name_ setFont:bold]; @@ -2322,7 +2619,8 @@ NSString *Scour(const char *field, const char *begin, const char *end) { [name_ setText:@"All Packages"]; [count_ setText:nil]; } else { - [name_ setText:[section name]]; + NSString *name = [section name]; + [name_ setText:(name == nil ? @"(No Section)" : name)]; [count_ setText:[NSString stringWithFormat:@"%d", [section count]]]; } } @@ -2537,10 +2835,10 @@ NSString *Scour(const char *field, const char *begin, const char *end) { Package *package = [packages_ objectAtIndex:offset]; NSString *name = [package section]; - if (section == nil || ![[section name] isEqual:name]) { + if (section == nil || name != nil && ![[section name] isEqual:name]) { section = [[[Section alloc] initWithName:name row:offset] autorelease]; - if ([name isEqualToString:section_]) + if (name == nil || [name isEqualToString:section_]) nsection = section; [sections addObject:section]; } @@ -2649,7 +2947,7 @@ NSString *Scour(const char *field, const char *begin, const char *end) { } - (float) table:(UITable *)table heightForRow:(int)row { - return 64; + return 100; } - (UITableCell *) table:(UITable *)table cellForRow:(int)row column:(UITableColumn *)col reusing:(UITableCell *)reusing { @@ -2759,11 +3057,19 @@ NSString *Scour(const char *field, const char *begin, const char *end) { else { NSDate *seen = [package seen]; - CFLocaleRef locale = CFLocaleCopyCurrent(); - CFDateFormatterRef formatter = CFDateFormatterCreate(NULL, locale, kCFDateFormatterMediumStyle, kCFDateFormatterMediumStyle); - CFStringRef formatted = CFDateFormatterCreateStringWithDate(NULL, formatter, (CFDateRef) seen); - - NSString *name = (NSString *) formatted; + NSString *name; + CFStringRef formatted = NULL; + + if (seen == nil) + name = @"n/a ?"; + else { + CFLocaleRef locale = CFLocaleCopyCurrent(); + CFDateFormatterRef formatter = CFDateFormatterCreate(NULL, locale, kCFDateFormatterMediumStyle, kCFDateFormatterMediumStyle); + formatted = CFDateFormatterCreateStringWithDate(NULL, formatter, (CFDateRef) seen); + name = (NSString *) formatted; + CFRelease(formatter); + CFRelease(locale); + } if (section == nil || ![[section name] isEqual:name]) { section = [[[Section alloc] initWithName:name row:offset] autorelease]; @@ -2772,9 +3078,8 @@ NSString *Scour(const char *field, const char *begin, const char *end) { [section addPackage:package]; - CFRelease(formatter); - CFRelease(formatted); - CFRelease(locale); + if (formatted != NULL) + CFRelease(formatted); } } @@ -3213,12 +3518,7 @@ NSString *Scour(const char *field, const char *begin, const char *end) { [Metadata_ setObject:Packages_ forKey:@"Packages"]; } - now_ = [NSDate date]; - - NSMutableArray *packages = [NSMutableArray arrayWithCapacity:count]; - for (pkgCache::PkgIterator iterator = [database_ cache]->PkgBegin(); !iterator.end(); ++iterator) - if (Package *package = [Package packageWithIterator:iterator database:database_]) - [packages addObject:package]; + NSArray *packages = [database_ packages]; [install_ setPackages:packages]; [changes_ setPackages:packages]; @@ -3255,7 +3555,32 @@ NSString *Scour(const char *field, const char *begin, const char *end) { - (void) perform { [database_ prepare]; - confirm_ = [[ConfirmationView alloc] initWithView:underlay_ database:database_ delegate:self]; + + if ([database_ cache]->BrokenCount() == 0) + confirm_ = [[ConfirmationView alloc] initWithView:underlay_ database:database_ delegate:self]; + else { + NSMutableArray *broken = [NSMutableArray arrayWithCapacity:16]; + NSArray *packages = [database_ packages]; + + for (size_t i(0); i != [packages count]; ++i) { + Package *package = [packages objectAtIndex:i]; + if ([package broken]) + [broken addObject:[package name]]; + } + + UIAlertSheet *sheet = [[[UIAlertSheet alloc] + initWithTitle:[NSString stringWithFormat:@"%d Broken Packages", [database_ cache]->BrokenCount()] + buttons:[NSArray arrayWithObjects:@"Okay", nil] + defaultButtonIndex:0 + delegate:self + context:self + ] autorelease]; + + [sheet setBodyText:[NSString stringWithFormat:@"The following packages have unmet dependencies:\n\n%@", [broken componentsJoinedByString:@"\n"]]]; + [sheet popupAlertAnimated:YES]; + + [self reloadData:NO]; + } } - (void) upgrade { @@ -3400,7 +3725,10 @@ NSString *Scour(const char *field, const char *begin, const char *end) { - (void) applicationWillSuspend { if (restart_) - system("launchctl stop com.apple.SpringBoard"); + if (FW_LEAST(1,1,3)) + notify_post("com.apple.language.changed"); + else + system("launchctl stop com.apple.SpringBoard"); [super applicationWillSuspend]; } @@ -3694,8 +4022,8 @@ int main(int argc, char *argv[]) { NSArray *versions = [prover componentsSeparatedByString:@"."]; int count = [versions count]; Major_ = count > 0 ? [[versions objectAtIndex:0] intValue] : 0; - Minor_ = count > 1 ? [[versions objectAtIndex:0] intValue] : 0; - BugFix_ = count > 2 ? [[versions objectAtIndex:0] intValue] : 0; + Minor_ = count > 1 ? [[versions objectAtIndex:1] intValue] : 0; + BugFix_ = count > 2 ? [[versions objectAtIndex:2] intValue] : 0; } } @@ -3724,7 +4052,8 @@ int main(int argc, char *argv[]) { Packages_ = [Metadata_ objectForKey:@"Packages"]; setenv("CYDIA", "", _not(int)); - system("/usr/libexec/cydia/firmware.sh"); + if (access("/User", F_OK) != 0) + system("/usr/libexec/cydia/firmware.sh"); system("dpkg --configure -a"); UIApplicationMain(argc, argv, [Cydia class]);