X-Git-Url: https://git.saurik.com/cydia.git/blobdiff_plain/3dfdb1463ea4e9be01b93d62e70d8bd1f108d03b..12762dfadae0a8f450bc8fc25ad31384d4c096ef:/Cydia.mm?ds=sidebyside diff --git a/Cydia.mm b/Cydia.mm index f59dcc85..7a5a33d1 100644 --- a/Cydia.mm +++ b/Cydia.mm @@ -35,6 +35,9 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +// XXX: wtf/FastMalloc.h... wtf? +#define USE_SYSTEM_MALLOC 1 + /* #include Directives {{{ */ #import "UICaboodle.h" @@ -52,15 +55,6 @@ // XXX: remove #import -#import -//#include - -#include -#include -#include - -#import - #include #include @@ -85,6 +79,8 @@ #include #include #include +#include +#include #include #include @@ -102,6 +98,8 @@ extern "C" { #import "BrowserView.h" #import "ResetView.h" + +#import "substrate.h" /* }}} */ //#define _finline __attribute__((force_inline)) @@ -174,7 +172,10 @@ void NSLogRect(const char *fix, const CGRect &rect) { NSLog(@"%s(%g,%g)+(%g,%g)", fix, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); } -static const NSStringCompareOptions CompareOptions_ = NSCaseInsensitiveSearch | NSNumericSearch | NSDiacriticInsensitiveSearch | NSWidthInsensitiveSearch | NSForcedOrderingSearch; +/* NSForcedOrderingSearch doesn't work on the iPhone */ +static const NSStringCompareOptions BaseCompareOptions_ = NSNumericSearch | NSDiacriticInsensitiveSearch | NSWidthInsensitiveSearch; +static const NSStringCompareOptions ForcedCompareOptions_ = BaseCompareOptions_; +static const NSStringCompareOptions LaxCompareOptions_ = BaseCompareOptions_ | NSCaseInsensitiveSearch; /* iPhoneOS 2.0 Compatibility {{{ */ #ifdef __OBJC2__ @@ -261,10 +262,11 @@ extern NSString * const kCAFilterNearest; #define lprintf(args...) fprintf(stderr, args) -#define ForRelease 1 -#define ForSaurik 1 && !ForRelease +#define ForRelease 0 +#define ForSaurik (1 && !ForRelease) +#define IgnoreInstall (0 && !ForRelease) #define RecycleWebViews 0 -#define AlwaysReload 1 && !ForRelease +#define AlwaysReload (1 && !ForRelease) /* Radix Sort {{{ */ @interface NSMutableArray (Radix) @@ -382,6 +384,19 @@ typedef enum { kUIControlAllEvents = (kUIControlEventMouseDown | kUIControlEventMouseMovedInside | kUIControlEventMouseMovedOutside | kUIControlEventMouseUpInside | kUIControlEventMouseUpOutside) } UIControlEventMasks; +NSUInteger DOMNodeList$countByEnumeratingWithState$objects$count$(DOMNodeList *self, SEL sel, NSFastEnumerationState *state, id *objects, NSUInteger count) { + size_t length([self length] - state->state); + if (length <= 0) + return 0; + else if (length > count) + length = count; + for (size_t i(0); i != length; ++i) + objects[i] = [self item:state->state++]; + state->itemsPtr = objects; + state->mutationsPtr = (unsigned long *) self; + return length; +} + @interface NSString (UIKit) - (NSString *) stringByAddingPercentEscapes; - (NSString *) stringByReplacingCharacter:(unsigned short)arg0 withCharacter:(unsigned short)arg1; @@ -588,6 +603,7 @@ static const float KeyboardTime_ = 0.3f; #define SpringBoard_ "/System/Library/LaunchDaemons/com.apple.SpringBoard.plist" #define SandboxTemplate_ "/usr/share/sandbox/SandboxTemplate.sb" +#define NotifyConfig_ "/etc/notify.conf" static CGColor Blue_; static CGColor Blueish_; @@ -613,25 +629,18 @@ static UIFont *Font18Bold_; static UIFont *Font22Bold_; static const char *Machine_ = NULL; -static const NSString *UniqueID_ = NULL; - -unsigned Major_; -unsigned Minor_; -unsigned BugFix_; +static const NSString *UniqueID_ = nil; +static const NSString *Build_ = nil; CFLocaleRef Locale_; CGColorSpaceRef space_; -#define FW_LEAST(major, minor, bugfix) \ - (major < Major_ || major == Major_ && \ - (minor < Minor_ || minor == Minor_ && \ - bugfix <= BugFix_)) - bool bootstrap_; bool reload_; static NSDictionary *SectionMap_; static NSMutableDictionary *Metadata_; +static NSMutableDictionary *Indices_; static _transient NSMutableDictionary *Settings_; static _transient NSString *Role_; static _transient NSMutableDictionary *Packages_; @@ -756,6 +765,7 @@ bool isSectionVisible(NSString *section) { - (RVPage *) pageForURL:(NSURL *)url hasTag:(int *)tag; - (RVPage *) pageForPackage:(NSString *)name; - (void) openMailToURL:(NSURL *)url; +- (void) clearFirstResponder; @end /* }}} */ @@ -1055,7 +1065,7 @@ class Progress : return NSOrderedDescending; } - return [lhs compare:rhs options:CompareOptions_]; + return [lhs compare:rhs options:LaxCompareOptions_]; } - (NSDictionary *) record { @@ -1225,6 +1235,7 @@ class Progress : - (Source *) source; - (NSString *) role; +- (NSString *) rating; - (BOOL) matches:(NSString *)text; @@ -1287,7 +1298,7 @@ class Progress : } + (NSArray *) _attributeKeys { - return [NSArray arrayWithObjects:@"applications", @"author", @"depiction", @"description", @"essential", @"homepage", @"icon", @"id", @"installed", @"latest", @"maintainer", @"name", @"purposes", @"section", @"size", @"source", @"sponsor", @"tagline", @"warnings", nil]; + return [NSArray arrayWithObjects:@"applications", @"author", @"depiction", @"description", @"essential", @"homepage", @"icon", @"id", @"installed", @"latest", @"maintainer", @"name", @"purposes", @"rating", @"section", @"size", @"source", @"sponsor", @"tagline", @"warnings", nil]; } - (NSArray *) attributeKeys { @@ -1718,6 +1729,8 @@ class Progress : [warnings addObject:@"illegal package identifier"]; else for (size_t i(0); i != length; ++i) if ( + /* XXX: technically this is not allowed */ + (name[i] < 'A' || name[i] > 'Z') && (name[i] < 'a' || name[i] > 'z') && (name[i] < '0' || name[i] > '9') && (i == 0 || name[i] != '+' && name[i] != '-' && name[i] != '.') @@ -1725,17 +1738,25 @@ class Progress : if (strcmp(name, "cydia") != 0) { bool cydia = false; + bool _private = false; bool stash = false; + bool repository = [[self section] isEqualToString:@"Repositories"]; + if (NSArray *files = [self files]) for (NSString *file in files) if (!cydia && [file isEqualToString:@"/Applications/Cydia.app"]) cydia = true; + else if (!_private && [file isEqualToString:@"/private"]) + _private = true; else if (!stash && [file isEqualToString:@"/var/stash"]) stash = true; - if (cydia) + /* XXX: this is not sensitive enough. only some folders are valid. */ + if (cydia && !repository) [warnings addObject:@"files installed into Cydia.app"]; + if (_private) + [warnings addObject:@"files installed with /private/*"]; if (stash) [warnings addObject:@"files installed to /var/stash"]; } @@ -1791,6 +1812,13 @@ class Progress : return role_; } +- (NSString *) rating { + if (NSString *rating = [Indices_ objectForKey:@"Rating"]) + return [rating stringByReplacingOccurrencesOfString:@"@P" withString:[id_ stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; + else + return nil; +} + - (BOOL) matches:(NSString *)text { if (text == nil) return NO; @@ -1863,7 +1891,7 @@ class Progress : return NSOrderedDescending; } - return [lhs compare:rhs options:CompareOptions_]; + return [lhs compare:rhs options:LaxCompareOptions_]; } - (NSComparisonResult) compareBySection:(Package *)package { @@ -1875,9 +1903,8 @@ class Progress : else if (lhs != NULL && rhs == NULL) return NSOrderedDescending; else if (lhs != NULL && rhs != NULL) { - NSComparisonResult result = [lhs compare:rhs options:CompareOptions_]; - if (result != NSOrderedSame) - return result; + NSComparisonResult result([lhs compare:rhs options:LaxCompareOptions_]); + return result != NSOrderedSame ? result : [lhs compare:rhs options:ForcedCompareOptions_]; } return NSOrderedSame; @@ -1997,7 +2024,7 @@ class Progress : return NSOrderedDescending; } - return [lhs compare:rhs options:CompareOptions_]; + return [lhs compare:rhs options:LaxCompareOptions_]; } - (Section *) initWithName:(NSString *)name { @@ -2831,8 +2858,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { return @"Cancel"; } -- (NSString *) _rightButtonTitle { +- (id) _rightButtonTitle { +#if AlwaysReload || IgnoreInstall + return @"Reload"; +#else return issues_ == nil ? @"Confirm" : nil; +#endif } - (void) _leftButtonClicked { @@ -2841,6 +2872,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { #if !AlwaysReload - (void) _rightButtonClicked { +#if IgnoreInstall + return [super _rightButtonClicked]; +#endif if (essential_ != nil) [essential_ popupAlertAnimated:YES]; else { @@ -2910,6 +2944,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { id delegate_; BOOL running_; SHA1SumValue springlist_; + SHA1SumValue notifyconf_; SHA1SumValue sandplate_; size_t received_; NSTimeInterval last_; @@ -3129,6 +3164,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { Finish_ = 4; } + if (Finish_ < 4) { + FileFd file(NotifyConfig_, FileFd::ReadOnly); + MMap mmap(file, MMap::ReadOnly); + SHA1Summation sha1; + sha1.Add(reinterpret_cast(mmap.Data()), mmap.Size()); + if (!(notifyconf_ == sha1.Result())) + Finish_ = 4; + } + if (Finish_ < 3) { FileFd file(SpringBoard_, FileFd::ReadOnly); MMap mmap(file, MMap::ReadOnly); @@ -3229,6 +3273,14 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { sandplate_ = sha1.Result(); } + { + FileFd file(NotifyConfig_, FileFd::ReadOnly); + MMap mmap(file, MMap::ReadOnly); + SHA1Summation sha1; + sha1.Add(reinterpret_cast(mmap.Data()), mmap.Size()); + notifyconf_ = sha1.Result(); + } + { FileFd file(SpringBoard_, FileFd::ReadOnly); MMap mmap(file, MMap::ReadOnly); @@ -3845,7 +3897,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame { - [[frame windowObject] evaluateWebScript:@"document.base.target = '_top'"]; return [super webView:sender didFinishLoadForFrame:frame]; } @@ -3880,7 +3931,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } #endif -- (NSString *) _rightButtonTitle { +- (id) _rightButtonTitle { int count = [buttons_ count]; return count == 0 ? nil : count != 1 ? @"Modify" : [buttons_ objectAtIndex:0]; } @@ -3927,6 +3978,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } } +- (bool) _loading { + return false; +} + - (void) reloadData { [self setPackage:[database_ packageWithName:name_]]; [self reloadButtons]; @@ -4565,7 +4620,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { return [[list_ table] isRowDeletionEnabled] ? @"Add" : nil; } -- (NSString *) rightButtonTitle { +- (id) rightButtonTitle { return [[list_ table] isRowDeletionEnabled] ? @"Done" : @"Edit"; } @@ -4636,7 +4691,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { return @"Packages"; } -- (NSString *) rightButtonTitle { +- (id) rightButtonTitle { return Role_ != nil && [Role_ isEqualToString:@"Developer"] ? nil : expert_ ? @"Expert" : @"Simple"; } @@ -4723,21 +4778,17 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } #if !AlwaysReload -- (NSString *) _rightButtonTitle { +- (id) _rightButtonTitle { return nil; } #endif -@end -/* }}} */ +- (bool) _loading { + return false; +} -@interface WebView (Cydia) -- (void) setScriptDebugDelegate:(id)delegate; -- (void) _setFormDelegate:(id)delegate; -- (void) _setUIKitDelegate:(id)delegate; -- (void) setWebMailDelegate:(id)delegate; -- (void) _setLayoutInterval:(float)interval; @end +/* }}} */ /* Indirect Delegate {{{ */ @interface IndirectDelegate : NSProxy { @@ -4775,572 +4826,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @end /* }}} */ -/* Browser Implementation {{{ */ -@implementation BrowserView - -- (void) dealloc { - if (challenge_ != nil) - [challenge_ release]; - - WebView *webview = [webview_ webView]; - [webview setFrameLoadDelegate:nil]; - [webview setResourceLoadDelegate:nil]; - [webview setUIDelegate:nil]; - [webview setScriptDebugDelegate:nil]; - [webview setPolicyDelegate:nil]; - - [webview setDownloadDelegate:nil]; - - [webview _setFormDelegate:nil]; - [webview _setUIKitDelegate:nil]; - [webview setWebMailDelegate:nil]; - [webview setEditingDelegate:nil]; - - [webview_ setDelegate:nil]; - [webview_ setGestureDelegate:nil]; - - //NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; - - [webview close]; - -#if RecycleWebViews - [webview_ removeFromSuperview]; - [Documents_ addObject:[webview_ autorelease]]; -#else - [webview_ release]; -#endif - - [indirect_ setDelegate:nil]; - [indirect_ release]; - - [scroller_ setDelegate:nil]; - - [scroller_ release]; - [urls_ release]; - [indicator_ release]; - if (title_ != nil) - [title_ release]; - [super dealloc]; -} - -- (void) loadURL:(NSURL *)url cachePolicy:(NSURLRequestCachePolicy)policy { - [self loadRequest:[NSURLRequest - requestWithURL:url - cachePolicy:policy - timeoutInterval:30.0 - ]]; -} - -- (void) loadURL:(NSURL *)url { - [self loadURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy]; -} - -- (NSURLRequest *) _addHeadersToRequest:(NSURLRequest *)request { - NSMutableURLRequest *copy = [request mutableCopy]; - - if (Machine_ != NULL) - [copy addValue:[NSString stringWithUTF8String:Machine_] forHTTPHeaderField:@"X-Machine"]; - if (UniqueID_ != nil) - [copy addValue:UniqueID_ forHTTPHeaderField:@"X-Unique-ID"]; - - if (Role_ != nil) - [copy addValue:Role_ forHTTPHeaderField:@"X-Role"]; - - return copy; -} - -- (void) loadRequest:(NSURLRequest *)request { - pushed_ = true; - [webview_ loadRequest:request]; -} - -- (void) reloadURL { - if ([urls_ count] == 0) - return; - NSURL *url = [[[urls_ lastObject] retain] autorelease]; - [urls_ removeLastObject]; - [self loadURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData]; -} - -- (WebView *) webView { - return [webview_ webView]; -} - -- (void) view:(UIView *)sender didSetFrame:(CGRect)frame { - [scroller_ setContentSize:frame.size]; -} - -- (void) view:(UIView *)sender didSetFrame:(CGRect)frame oldFrame:(CGRect)old { - [self view:sender didSetFrame:frame]; -} - -- (void) pushPage:(RVPage *)page { - [self setBackButtonTitle:title_]; - [page setDelegate:delegate_]; - [book_ pushPage:page]; -} - -- (BOOL) getSpecial:(NSURL *)url { - NSString *href([url absoluteString]); - NSString *scheme([[url scheme] lowercaseString]); - RVPage *page = nil; - - if ([href hasPrefix:@"apptapp://package/"]) - page = [delegate_ pageForPackage:[href substringFromIndex:18]]; - else if ([scheme isEqualToString:@"cydia"]) { - page = [delegate_ pageForURL:url hasTag:NULL]; - if (page == nil) - return false; - } else if (![scheme isEqualToString:@"apptapp"]) - return false; - - if (page != nil) - [self pushPage:page]; - return true; -} - -- (void) webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame { - UIActionSheet *sheet = [[[UIActionSheet alloc] - initWithTitle:@"JavaScript Alert" - buttons:[NSArray arrayWithObjects:@"OK", nil] - defaultButtonIndex:0 - delegate:self - context:@"alert" - ] autorelease]; - - [sheet setBodyText:message]; - [sheet popupAlertAnimated:YES]; -} - -- (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame { - [window setValue:delegate_ forKey:@"cydia"]; -} - -- (void) webView:(WebView *)sender decidePolicyForNewWindowAction:(NSDictionary *)dictionary request:(NSURLRequest *)request newFrameName:(NSString *)name decisionListener:(id)listener { - if (NSURL *url = [request URL]) { - if (![self getSpecial:url]) { - NSString *scheme([[url scheme] lowercaseString]); - if ([scheme isEqualToString:@"mailto"]) - [delegate_ openMailToURL:url]; - else goto use; - } - - [listener ignore]; - } else use: - [listener use]; -} - -- (void) webView:(WebView *)webView decidePolicyForMIMEType:(NSString *)type request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener { - if ([WebView canShowMIMEType:type]) - [listener use]; - else { - // XXX: handle more mime types! - [listener ignore]; - if (frame == [webView mainFrame]) - [UIApp openURL:[request URL]]; - } -} - -- (void) webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)action request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener { - NSURL *url([request URL]); - - if (url == nil) use: { - [listener use]; - return; - } - - const NSArray *capability(reinterpret_cast(GSSystemGetCapability(kGSDisplayIdentifiersCapability))); - - if ( - [capability containsObject:@"com.apple.Maps"] && [url mapsURL] || - [capability containsObject:@"com.apple.youtube"] && [url youTubeURL] - ) { - open: - [UIApp openURL:url]; - ignore: - [listener ignore]; - return; - } - - int store(_not(int)); - if (NSURL *itms = [url itmsURL:&store]) { - NSLog(@"itms#%@#%u#%@", url, store, itms); - if ( - store == 1 && [capability containsObject:@"com.apple.MobileStore"] || - store == 2 && [capability containsObject:@"com.apple.AppStore"] - ) { - url = itms; - goto open; - } - } - - NSString *scheme([[url scheme] lowercaseString]); - - if ([scheme isEqualToString:@"tel"]) { - // XXX: intelligence - goto open; - } - - if ([scheme isEqualToString:@"mailto"]) { - [delegate_ openMailToURL:url]; - goto ignore; - } - - if ([self getSpecial:url]) - goto ignore; - else if ([WebView _canHandleRequest:request]) - goto use; - else if ([url isSpringboardHandledURL]) - goto open; - else - goto use; -} - -- (void) webView:(WebView *)sender setStatusText:(NSString *)text { - //lprintf("Status:%s\n", [text UTF8String]); -} - -- (void) _pushPage { - if (pushed_) - return; - pushed_ = true; - [book_ pushPage:self]; -} - -- (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button { - NSString *context([sheet context]); - - if ([context isEqualToString:@"alert"]) - [sheet dismiss]; - else if ([context isEqualToString:@"challenge"]) { - id sender([challenge_ sender]); - - switch (button) { - case 1: { - NSString *username([[sheet textFieldAtIndex:0] text]); - NSString *password([[sheet textFieldAtIndex:1] text]); - - NSURLCredential *credential([NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistenceForSession]); - - [sender useCredential:credential forAuthenticationChallenge:challenge_]; - } break; - - case 2: - [sender cancelAuthenticationChallenge:challenge_]; - break; - - default: - _assert(false); - } - - [challenge_ release]; - challenge_ = nil; - - [sheet dismiss]; - } -} - -- (void) webView:(WebView *)sender resource:(id)identifier didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge fromDataSource:(WebDataSource *)source { - challenge_ = [challenge retain]; - - NSURLProtectionSpace *space([challenge protectionSpace]); - NSString *realm([space realm]); - if (realm == nil) - realm = @""; - - UIActionSheet *sheet = [[[UIActionSheet alloc] - initWithTitle:realm - buttons:[NSArray arrayWithObjects:@"Login", @"Cancel", nil] - defaultButtonIndex:0 - delegate:self - context:@"challenge" - ] autorelease]; - - [sheet setNumberOfRows:1]; - - [sheet addTextFieldWithValue:@"" label:@"username"]; - [sheet addTextFieldWithValue:@"" label:@"password"]; - - UITextField *username([sheet textFieldAtIndex:0]); { - UITextInputTraits *traits([username textInputTraits]); - [traits setAutocapitalizationType:UITextAutocapitalizationTypeNone]; - [traits setAutocorrectionType:UITextAutocorrectionTypeNo]; - [traits setKeyboardType:UIKeyboardTypeASCIICapable]; - [traits setReturnKeyType:UIReturnKeyNext]; - } - - UITextField *password([sheet textFieldAtIndex:1]); { - UITextInputTraits *traits([password textInputTraits]); - [traits setAutocapitalizationType:UITextAutocapitalizationTypeNone]; - [traits setAutocorrectionType:UITextAutocorrectionTypeNo]; - [traits setKeyboardType:UIKeyboardTypeASCIICapable]; - // XXX: UIReturnKeyDone - [traits setReturnKeyType:UIReturnKeyNext]; - [traits setSecureTextEntry:YES]; - } - - [sheet popupAlertAnimated:YES]; -} - -- (NSURLRequest *) webView:(WebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)source { - NSURL *url = [request URL]; - if ([self getSpecial:url]) - return nil; - [self _pushPage]; - return [self _addHeadersToRequest:request]; -} - -- (WebView *) _createWebViewWithRequest:(NSURLRequest *)request pushed:(BOOL)pushed { - [self setBackButtonTitle:title_]; - - BrowserView *browser = [[[BrowserView alloc] initWithBook:book_] autorelease]; - [browser setDelegate:delegate_]; - - if (pushed) { - [browser loadRequest:[self _addHeadersToRequest:request]]; - [book_ pushPage:browser]; - } - - return [browser webView]; -} - -- (WebView *) webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request { - return [self _createWebViewWithRequest:request pushed:(request != nil)]; -} - -- (WebView *) webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request windowFeatures:(NSDictionary *)features { - return [self _createWebViewWithRequest:request pushed:YES]; -} - -- (void) webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame { - if ([frame parentFrame] != nil) - return; - - title_ = [title retain]; - [book_ reloadTitleForPage:self]; -} - -- (void) webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)frame { - if ([frame parentFrame] != nil) - return; - - reloading_ = false; - loading_ = true; - [indicator_ startAnimation]; - [self reloadButtons]; - - if (title_ != nil) { - [title_ release]; - title_ = nil; - } - - [book_ reloadTitleForPage:self]; - - WebView *webview = [webview_ webView]; - NSString *href = [webview mainFrameURL]; - [urls_ addObject:[NSURL URLWithString:href]]; - - [scroller_ scrollPointVisibleAtTopLeft:CGPointZero]; - - CGRect webrect = [scroller_ bounds]; - webrect.size.height = 0; - [webview_ setFrame:webrect]; -} - -- (void) _finishLoading { - if (!reloading_) { - loading_ = false; - [indicator_ stopAnimation]; - [self reloadButtons]; - } -} - -- (BOOL) webView:(WebView *)sender shouldScrollToPoint:(struct CGPoint)point forFrame:(WebFrame *)frame { - return [webview_ webView:sender shouldScrollToPoint:point forFrame:frame]; -} - -- (void) webView:(WebView *)sender didReceiveViewportArguments:(id)arguments forFrame:(WebFrame *)frame { - return [webview_ webView:sender didReceiveViewportArguments:arguments forFrame:frame]; -} - -- (void) webView:(WebView *)sender needsScrollNotifications:(id)notifications forFrame:(WebFrame *)frame { - return [webview_ webView:sender needsScrollNotifications:notifications forFrame:frame]; -} - -- (void) webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame { - return [webview_ webView:sender didCommitLoadForFrame:frame]; -} - -- (void) webView:(WebView *)sender didReceiveDocTypeForFrame:(WebFrame *)frame { - return [webview_ webView:sender didReceiveDocTypeForFrame:frame]; -} - -- (void) webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame { - if ([frame parentFrame] == nil) - [self _finishLoading]; - return [webview_ webView:sender didFinishLoadForFrame:frame]; -} - -- (void) webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { - if ([frame parentFrame] != nil) - return; - [self _finishLoading]; - - [self loadURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@?%@", - [[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"error" ofType:@"html"]] absoluteString], - [[error localizedDescription] stringByAddingPercentEscapes] - ]]]; -} - -- (void) webView:(WebView *)sender addMessageToConsole:(NSDictionary *)dictionary { -#if ForSaurik - lprintf("Console:%s\n", [[dictionary description] UTF8String]); -#endif -} - -- (id) initWithBook:(RVBook *)book { - if ((self = [super initWithBook:book]) != nil) { - loading_ = false; - - struct CGRect bounds = [self bounds]; - - UIImageView *pinstripe = [[[UIImageView alloc] initWithFrame:bounds] autorelease]; - [pinstripe setImage:[UIImage applicationImageNamed:@"pinstripe.png"]]; - [self addSubview:pinstripe]; - - scroller_ = [[UIScroller alloc] initWithFrame:bounds]; - [self addSubview:scroller_]; - - [scroller_ setScrollingEnabled:YES]; - [scroller_ setAdjustForContentSizeChange:YES]; - [scroller_ setClipsSubviews:YES]; - [scroller_ setAllowsRubberBanding:YES]; - [scroller_ setScrollDecelerationFactor:0.99]; - [scroller_ setDelegate:self]; - - CGRect webrect = [scroller_ bounds]; - webrect.size.height = 0; - - WebView *webview; - -#if RecycleWebViews - webview_ = [Documents_ lastObject]; - if (webview_ != nil) { - webview_ = [webview_ retain]; - webview = [webview_ webView]; - [Documents_ removeLastObject]; - [webview_ setFrame:webrect]; - } else { -#else - if (true) { -#endif - webview_ = [[UIWebDocumentView alloc] initWithFrame:webrect]; - webview = [webview_ webView]; - - [webview_ setTileSize:CGSizeMake(webrect.size.width, 500)]; - - [webview_ setAllowsMessaging:YES]; - - [webview_ setTilingEnabled:YES]; - [webview_ setDrawsGrid:NO]; - [webview_ setLogsTilingChanges:NO]; - [webview_ setTileMinificationFilter:kCAFilterNearest]; - [webview_ setDetectsPhoneNumbers:NO]; - [webview_ setAutoresizes:YES]; - - [webview_ setViewportSize:CGSizeMake(980, -1) forDocumentTypes:0x10]; - [webview_ setViewportSize:CGSizeMake(320, -1) forDocumentTypes:0x2]; - [webview_ setViewportSize:CGSizeMake(320, -1) forDocumentTypes:0x8]; - - [webview_ _setDocumentType:0x4]; - - [webview_ setZoomsFocusedFormControl:YES]; - [webview_ setContentsPosition:7]; - [webview_ setEnabledGestures:0xa]; - [webview_ setValue:[NSNumber numberWithBool:YES] forGestureAttribute:UIGestureAttributeIsZoomRubberBandEnabled]; - [webview_ setValue:[NSNumber numberWithBool:YES] forGestureAttribute:UIGestureAttributeUpdatesScroller]; - - [webview_ setSmoothsFonts:YES]; - - [webview _setUsesLoaderCache:YES]; - [webview setGroupName:@"Cydia"]; - //[webview _setLayoutInterval:0.5]; - } - - [webview_ setDelegate:self]; - [webview_ setGestureDelegate:self]; - [scroller_ addSubview:webview_]; - - //NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; - - CGSize indsize = [UIProgressIndicator defaultSizeForStyle:UIProgressIndicatorStyleMediumWhite]; - indicator_ = [[UIProgressIndicator alloc] initWithFrame:CGRectMake(281, 12, indsize.width, indsize.height)]; - [indicator_ setStyle:UIProgressIndicatorStyleMediumWhite]; - - Package *package([[Database sharedInstance] packageWithName:@"cydia"]); - NSString *application = package == nil ? @"Cydia" : [NSString - stringWithFormat:@"Cydia/%@", - [package installed] - ]; [webview setApplicationNameForUserAgent:application]; - - indirect_ = [[IndirectDelegate alloc] initWithDelegate:self]; - - [webview setFrameLoadDelegate:self]; - [webview setResourceLoadDelegate:indirect_]; - [webview setUIDelegate:self]; - [webview setScriptDebugDelegate:self]; - [webview setPolicyDelegate:self]; - - urls_ = [[NSMutableArray alloc] initWithCapacity:16]; - - [self setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; - [scroller_ setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; - [pinstripe setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; - } return self; -} - -- (void) didFinishGesturesInView:(UIView *)view forEvent:(id)event { - [webview_ redrawScaledDocument]; -} - -- (void) _rightButtonClicked { - reloading_ = true; - [self reloadURL]; -} - -- (NSString *) _rightButtonTitle { - return @"Reload"; -} - -- (NSString *) rightButtonTitle { - return loading_ ? @"" : [self _rightButtonTitle]; -} - -- (NSString *) title { - return title_ == nil ? @"Loading" : title_; -} - -- (NSString *) backButtonTitle { - return @"Browser"; -} - -- (void) setPageActive:(BOOL)active { - if (!active) - [indicator_ removeFromSuperview]; - else - [[book_ navigationBar] addSubview:indicator_]; -} - -- (void) resetViewAnimated:(BOOL)animated { -} - -- (void) setPushed:(bool)pushed { - pushed_ = pushed; -} - -@end -/* }}} */ +#include /* Cydia Book {{{ */ @interface CYBook : RVBook < @@ -5618,6 +5105,16 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { return request; } +- (void) _returnPNGWithImage:(UIImage *)icon forRequest:(NSURLRequest *)request { + id client([self client]); + NSData *data(UIImagePNGRepresentation(icon)); + + NSURLResponse *response([[[NSURLResponse alloc] initWithURL:[request URL] MIMEType:@"image/png" expectedContentLength:-1 textEncodingName:nil] autorelease]); + [client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; + [client URLProtocol:self didLoadData:data]; + [client URLProtocolDidFinishLoading:self]; +} + - (void) startLoading { id client([self client]); NSURLRequest *request([self request]); @@ -5646,47 +5143,32 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { Package *package([database packageWithName:path]); if (package == nil) goto fail; - UIImage *icon([package icon]); - - NSData *data(UIImagePNGRepresentation(icon)); - - NSURLResponse *response([[[NSURLResponse alloc] initWithURL:[request URL] MIMEType:@"image/png" expectedContentLength:-1 textEncodingName:nil] autorelease]); - [client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; - [client URLProtocol:self didLoadData:data]; - [client URLProtocolDidFinishLoading:self]; + [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"]; - - NSData *data(UIImagePNGRepresentation(icon)); - - NSURLResponse *response([[[NSURLResponse alloc] initWithURL:[request URL] MIMEType:@"image/png" expectedContentLength:-1 textEncodingName:nil] autorelease]); - [client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; - [client URLProtocol:self didLoadData:data]; - [client URLProtocolDidFinishLoading:self]; + [self _returnPNGWithImage:icon forRequest:request]; + } else if ([command isEqualToString:@"uikit-image"]) { + if (path == nil) + goto fail; + path = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + UIImage *icon(_UIImageWithName(path)); + [self _returnPNGWithImage:icon forRequest:request]; } else if ([command isEqualToString:@"section-icon"]) { if (path == nil) goto fail; path = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSString *section(Simplify(path)); - UIImage *icon([UIImage imageAtPath:[NSString stringWithFormat:@"%@/Sections/%@.png", App_, section]]); if (icon == nil) icon = [UIImage applicationImageNamed:@"unknown.png"]; - - NSData *data(UIImagePNGRepresentation(icon)); - - NSURLResponse *response([[[NSURLResponse alloc] initWithURL:[request URL] MIMEType:@"image/png" expectedContentLength:-1 textEncodingName:nil] autorelease]); - [client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; - [client URLProtocol:self didLoadData:data]; - [client URLProtocolDidFinishLoading:self]; + [self _returnPNGWithImage:icon forRequest:request]; } else fail: { [client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorResourceUnavailable userInfo:nil]]; } @@ -5905,7 +5387,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { return @"Sections"; } -- (NSString *) rightButtonTitle { +- (id) rightButtonTitle { return [sections_ count] == 0 ? nil : editing_ ? @"Done" : @"Edit"; } @@ -6113,7 +5595,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { return [(CYBook *)book_ updating] ? nil : @"Refresh"; } -- (NSString *) rightButtonTitle { +- (id) rightButtonTitle { return upgrades_ == 0 ? nil : [NSString stringWithFormat:@"Upgrade (%u)", upgrades_]; } @@ -6250,10 +5732,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { if ((self = [super initWithBook:book]) != nil) { CGRect pageBounds = [book_ pageBounds]; - /*UIImageView *pinstripe = [[[UIImageView alloc] initWithFrame:pageBounds] autorelease]; - [pinstripe setImage:[UIImage applicationImageNamed:@"pinstripe.png"]]; - [self addSubview:pinstripe];*/ - transition_ = [[UITransitionView alloc] initWithFrame:pageBounds]; [self addSubview:transition_]; @@ -7099,7 +6577,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button { NSString *context([sheet context]); - if ([context isEqualToString:@"fixhalf"]) { + if ([context isEqualToString:@"missing"]) + [sheet dismiss]; + else if ([context isEqualToString:@"fixhalf"]) { switch (button) { case 1: @synchronized (self) { @@ -7218,10 +6698,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { #if 0 [[[MailToView alloc] initWithView:underlay_ delegate:self url:url] autorelease]; #else - [UIApp openURL:url]; + [UIApp openURL:url];// asPanel:YES]; #endif } +- (void) clearFirstResponder { + if (id responder = [window_ firstResponder]) + [responder resignFirstResponder]; +} + - (RVPage *) pageForPackage:(NSString *)name { if (Package *package = [database_ packageWithName:name]) { PackageView *view = [[[PackageView alloc] initWithBook:book_ database:database_] autorelease]; @@ -7246,29 +6731,39 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (RVPage *) pageForURL:(NSURL *)url hasTag:(int *)tag { - NSString *href = [url absoluteString]; - if (tag != NULL) tag = 0; - if ([href isEqualToString:@"cydia://add-source"]) + NSString *scheme([[url scheme] lowercaseString]); + if (![scheme isEqualToString:@"cydia"]) + return nil; + NSString *path([url absoluteString]); + if ([path length] < 8) + return nil; + path = [path substringFromIndex:8]; + if (![path hasPrefix:@"/"]) + path = [@"/" stringByAppendingString:path]; + + if ([path isEqualToString:@"/add-source"]) return [[[AddSourceView alloc] initWithBook:book_ database:database_] autorelease]; - else if ([href isEqualToString:@"cydia://sources"]) + else if ([path isEqualToString:@"/storage"]) + return [self _pageForURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"storage" ofType:@"html"]] withClass:[BrowserView class]]; + else if ([path isEqualToString:@"/sources"]) return [[[SourceTable alloc] initWithBook:book_ database:database_] autorelease]; - else if ([href isEqualToString:@"cydia://packages"]) + else if ([path isEqualToString:@"/packages"]) return [[[InstalledView alloc] initWithBook:book_ database:database_] autorelease]; - else if ([href hasPrefix:@"cydia://url/"]) - return [self _pageForURL:[NSURL URLWithString:[href substringFromIndex:12]] withClass:[BrowserView class]]; - else if ([href hasPrefix:@"cydia://launch/"]) - [self launchApplicationWithIdentifier:[href substringFromIndex:15] suspended:NO]; - else if ([href hasPrefix:@"cydia://package-settings/"]) - return [[[SettingsView alloc] initWithBook:book_ database:database_ package:[href substringFromIndex:25]] autorelease]; - else if ([href hasPrefix:@"cydia://package-signature/"]) - return [[[SignatureView alloc] initWithBook:book_ database:database_ package:[href substringFromIndex:26]] autorelease]; - else if ([href hasPrefix:@"cydia://package/"]) - return [self pageForPackage:[href substringFromIndex:16]]; - else if ([href hasPrefix:@"cydia://files/"]) { - NSString *name = [href substringFromIndex:14]; + else if ([path hasPrefix:@"/url/"]) + return [self _pageForURL:[NSURL URLWithString:[path substringFromIndex:5]] withClass:[BrowserView class]]; + else if ([path hasPrefix:@"/launch/"]) + [self launchApplicationWithIdentifier:[path substringFromIndex:8] suspended:NO]; + else if ([path hasPrefix:@"/package-settings/"]) + return [[[SettingsView alloc] initWithBook:book_ database:database_ package:[path substringFromIndex:18]] autorelease]; + else if ([path hasPrefix:@"/package-signature/"]) + return [[[SignatureView alloc] initWithBook:book_ database:database_ package:[path substringFromIndex:19]] autorelease]; + else if ([path hasPrefix:@"/package/"]) + return [self pageForPackage:[path substringFromIndex:9]]; + else if ([path hasPrefix:@"/files/"]) { + NSString *name = [path substringFromIndex:7]; if (Package *package = [database_ packageWithName:name]) { FileTable *files = [[[FileTable alloc] initWithBook:book_ database:database_] autorelease]; @@ -7349,22 +6844,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [self finish]; } -/* Web Scripting {{{ */ -+ (NSString *) webScriptNameForSelector:(SEL)selector { - if (selector == @selector(supports:)) - return @"supports"; - return nil; -} - -+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector { - return selector != @selector(supports:); -} - -- (BOOL) supports:(NSString *)feature { - return [feature isEqualToString:@"window.open"]; -} -/* }}} */ - - (void) showKeyboard:(BOOL)show { CGSize keysize = [UIKeyboard defaultSize]; CGRect keydown = {{0, [overlay_ bounds].size.height}, keysize}; @@ -7452,6 +6931,8 @@ id Dealloc_(id self, SEL selector) { }*/ int main(int argc, char *argv[]) { _pooled + class_addMethod(objc_getClass("DOMNodeList"), @selector(countByEnumeratingWithState:objects:count:), (IMP) &DOMNodeList$countByEnumeratingWithState$objects$count$, "I20@0:4^{NSFastEnumerationState}8^@12I16"); + bool substrate(false); if (argc != 0) { @@ -7526,9 +7007,20 @@ int main(int argc, char *argv[]) { _pooled UniqueID_ = [[UIDevice currentDevice] uniqueIdentifier]; + if (NSDictionary *system = [NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"]) + Build_ = [system objectForKey:@"ProductBuildVersion"]; + /*AddPreferences(@"/Applications/Preferences.app/Settings-iPhone.plist"); AddPreferences(@"/Applications/Preferences.app/Settings-iPod.plist");*/ + /*if ((Indices_ = [[NSMutableDictionary alloc] initWithContentsOfFile:@"/var/lib/cydia/indices.plist"]) == NULL) + Indices_ = [[NSMutableDictionary alloc] init];*/ + + Indices_ = [NSMutableDictionary dictionaryWithObjectsAndKeys: + @"http://"/*"cache.saurik.com/"*/"cydia.saurik.com/server/rating/@", @"Rating", + @"http://"/*"cache.saurik.com/"*/"cydia.saurik.com/repotag/@", @"RepoTag", + nil]; + if ((Metadata_ = [[NSMutableDictionary alloc] initWithContentsOfFile:@"/var/lib/cydia/metadata.plist"]) == NULL) Metadata_ = [[NSMutableDictionary alloc] initWithCapacity:2]; else { @@ -7561,8 +7053,10 @@ int main(int argc, char *argv[]) { _pooled Documents_ = [[[NSMutableArray alloc] initWithCapacity:4] autorelease]; #endif - if (substrate && access("/Library/MobileSubstrate/MobileSubstrate.dylib", F_OK) == 0) - dlopen("/Library/MobileSubstrate/MobileSubstrate.dylib", RTLD_LAZY | RTLD_GLOBAL); + if (substrate && access("/Applications/WinterBoard.app/WinterBoard.dylib", F_OK) == 0) + dlopen("/Applications/WinterBoard.app/WinterBoard.dylib", RTLD_LAZY | RTLD_GLOBAL); + /*if (substrate && access("/Library/MobileSubstrate/MobileSubstrate.dylib", F_OK) == 0) + dlopen("/Library/MobileSubstrate/MobileSubstrate.dylib", RTLD_LAZY | RTLD_GLOBAL);*/ if (access("/User", F_OK) != 0) system("/usr/libexec/cydia/firmware.sh");