Skip to content

Commit

Permalink
okay
Browse files Browse the repository at this point in the history
  • Loading branch information
comex committed Mar 18, 2011
1 parent d1bbb99 commit 5b46cd5
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 129 deletions.
104 changes: 28 additions & 76 deletions locutus/locutus.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@
#include <fcntl.h>
#include <errno.h>
#include "inject.h"
#include "bzlib.h"
#include <common/common.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CFNetwork/CFNetwork.h>
#include <libgen.h>
#include <sys/stat.h>

// todo: test interrupted downloads
// darken

//#define TINY

Expand All @@ -35,25 +38,28 @@ static size_t downloaded_bytes;
static struct request {
CFStringRef url;
const char *output;
bool is_bz2;
CFStringRef content_type;
union {
struct {};
struct {
CFReadStreamRef read_stream;
bz_stream bz;
int out_fd;
bool finished;
size_t content_length;
};
};
} requests[] = {
{ CFSTR("http://a.qoid.us/test.bz2"), "/tmp/install", true, {}},
{ CFSTR("http://a.qoid.us/test"), "/tmp/foo", false, {}},
{ CFSTR("http://a.qoid.us/Cydia.png"), "/tmp/Cydia.png", false, {}}
{ CFSTR("http://a.qoid.us/test"), "/tmp/foo", CFSTR("application/x-bzip2"), {}},
#if defined(DEVICE_IPHONE3_1) || defined(DEVICE_IPOD4_1)
{ CFSTR("http://a.qoid.us/[email protected]"), "/tmp/[email protected]", CFSTR("image/png"), {}}
#else
{ CFSTR("http://a.qoid.us/Cydia.png"), "/tmp/Cydia.png", CFSTR("image/png"), {}}
#endif
}, *const requests_end = requests + sizeof(requests)/sizeof(*requests);

__attribute__((noreturn))
static void leave() {
// maybe remove temp?
exit(0);
}

Expand Down Expand Up @@ -90,23 +96,17 @@ static void pause_it(CFStringRef err) {

// handle an error or completion
static void handle_error(struct request *r, CFStringRef err) {
if(r->is_bz2) {
BZ2_bzDecompressEnd(&r->bz);
}
close(r->out_fd);
r->out_fd = 0;
if(err) {
pause_it(err);
} else {
rename(basename((char *) r->output), r->output);
r->finished = true;
CFReadStreamClose(r->read_stream);
CFRelease(r->read_stream);
r->read_stream = NULL;

static char buf[64] = "locutus.got-";
strncpy(buf + 12, basename((char *) r->output), sizeof(buf) - 12);
notify_post(buf);

for(struct request *r = requests; r < requests_end; r++) {
if(!r->finished) return;
}
Expand All @@ -130,13 +130,7 @@ static void request_callback(CFReadStreamRef stream, CFStreamEventType event_typ
}
break;
case kCFStreamEventEndEncountered:
if(r->is_bz2) {
if(r->read_stream) { // end of the bz2 file but no BZ_STREAM_END
handle_error(r, CFSTR("compressed data was truncated"));
}
} else {
handle_error(r, NULL);
}
handle_error(r, NULL);
break;
case kCFStreamEventHasBytesAvailable:
if(!r->content_length) {
Expand All @@ -148,14 +142,13 @@ static void request_callback(CFReadStreamRef stream, CFStreamEventType event_typ
if(code == 200) {
CFStringRef cl = CFHTTPMessageCopyHeaderFieldValue(response, CFSTR("Content-Length"));
if(!cl) {
handle_error(r, CFSTR("server fails"));
handle_error(r, CFSTR("Server fails (no length)"));
break;
} else {
r->content_length = CFStringGetIntValue(cl);
CFRelease(cl);
}
} else if(code == 206) {
#ifndef TINY
// partial content
off_t off = 0;
CFStringRef range = CFHTTPMessageCopyHeaderFieldValue(response, CFSTR("Content-Range"));
Expand All @@ -170,15 +163,20 @@ static void request_callback(CFReadStreamRef stream, CFStreamEventType event_typ
}
CFRelease(range);
}
if(off != lseek(r->out_fd, 0, SEEK_SET)) {
handle_error(r, CFSTR("server fails"));
if(off != lseek(r->out_fd, off, SEEK_SET)) {
handle_error(r, CFSTR("Server fails (206)"));
break;
}
#endif
} else {
fprintf(stderr, ">%s<\n", r->output);
handle_error(r, CFStringCreateWithFormat(NULL, NULL, CFSTR("HTTP response code %d"), (int) code));
break;
}
CFStringRef content_type = CFHTTPMessageCopyHeaderFieldValue(response, CFSTR("Content-Type"));
if(!content_type || kCFCompareEqualTo != CFStringCompare(content_type, r->content_type, kCFCompareCaseInsensitive)) {
handle_error(r, CFStringCreateWithFormat(NULL, NULL, CFSTR("Wrong Content-Type; are you on a fail Wi-Fi network?")));
}

}

// actually read
Expand All @@ -193,48 +191,7 @@ static void request_callback(CFReadStreamRef stream, CFStreamEventType event_typ

written += (size_t) idx;

if(!r->is_bz2) {
_assert((CFIndex) write(r->out_fd, compressed, idx) == idx);
} else {
r->bz.avail_in = (unsigned int) idx;
r->bz.next_in = compressed;
r->bz.avail_out = sizeof(uncompressed);
r->bz.next_out = uncompressed;
while(r->bz.avail_in > 0) {
int result = BZ2_bzDecompress(&r->bz);
if(result != BZ_STREAM_END && result != BZ_OK) {
CFStringRef error;
switch(result) {
case BZ_CONFIG_ERROR:
case BZ_SEQUENCE_ERROR:
case BZ_PARAM_ERROR:
_assert_zero(result); // I screwed up
case BZ_MEM_ERROR:
error = CFSTR("BZ2 memory error");
break;
case BZ_DATA_ERROR:
error = CFSTR("BZ2 data error (corrupt file)");
break;
case BZ_DATA_ERROR_MAGIC:
error = CFSTR("BZ2 data error (corrupt file, you might be behind a crappy transparent proxy)");
break;
default:
error = CFSTR("unknown BZ2 error");
break;
}
handle_error(r, error);
goto end;
}

size_t towrite = sizeof(uncompressed) - r->bz.avail_out;
_assert((size_t) write(r->out_fd, uncompressed, towrite) == towrite);
if(result == BZ_STREAM_END) {
// we're done
handle_error(r, NULL);
goto end;
}
}
}
_assert((CFIndex) write(r->out_fd, compressed, idx) == idx);
}
end:
did_download(written);
Expand All @@ -248,24 +205,16 @@ static void init_requests() {
for(struct request *r = requests; r < requests_end; r++) {
if(r->read_stream) continue;

if(r->is_bz2) {
_assert_zero(BZ2_bzDecompressInit(&r->bz, 0, 0));
}

CFURLRef url = _assert(CFURLCreateWithString(NULL, r->url, NULL));
CFHTTPMessageRef message = _assert(CFHTTPMessageCreateRequest(NULL, CFSTR("GET"), url, kCFHTTPVersion1_1));
CFRelease(url);

if(r->out_fd) {
#ifdef TINY
lseek(r->out_fd, 0, SEEK_SET);
#else
CFStringRef range = CFStringCreateWithFormat(NULL, NULL, CFSTR("bytes %d-%d"), (int) lseek(r->out_fd, 0, SEEK_CUR), (int) r->content_length - 1);
CFHTTPMessageSetHeaderFieldValue(message, CFSTR("Range"), range);
CFRelease(range);
#endif
} else {
r->out_fd = _assert(open(r->output, O_WRONLY | O_CREAT | O_TRUNC, 0644));
r->out_fd = _assert(open(basename((char *) r->output), O_WRONLY | O_CREAT | O_TRUNC, 0644));
}

r->read_stream = _assert(CFReadStreamCreateForHTTPRequest(NULL, message));
Expand All @@ -289,6 +238,7 @@ static void run_install() {
progress = 0.0;
update_state("INSTALLING_ICON_LABEL", NULL);
fprintf(stderr, "installing or something\n");
notify_post("locutus.installed");
leave();
}

Expand Down Expand Up @@ -355,6 +305,8 @@ int main() {
//syslog(LOG_EMERG, "omg hax\n");
//printf("omg hax\n");
//return 0;
mkdir("/tmp/locutus-temp", 0755); // might fail
_assert_zero(chdir("/tmp/locutus-temp"));

uint32_t one = 1;
_assert_zero(sysctlbyname("security.mac.vnode_enforce", NULL, NULL, &one, sizeof(one)));
Expand Down
93 changes: 43 additions & 50 deletions locutus/locutus_server.m
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include <mach/mach.h>
#include <mach-o/dyld.h>
#include <stdio.h>
//#include <servers/bootstrap.h>
#include <stdbool.h>
#include <stdlib.h>
#include <syslog.h>
Expand All @@ -10,7 +9,6 @@
#import <UIKit/UIKit.h>
#include <objc/runtime.h>


static NSString *const bundle_identifier = @"com.saurik.Cydia.notreally";

static notify_handler_t sk_handler;
Expand All @@ -21,10 +19,9 @@
static id icon;
static id icon_controller;
static id icon_model;

static NSString *display_name;

static UIImage *icon_image;
static UIAlertView *alert_view;
static NSString *display_name;

static inline NSString *_(NSString *key) {
NSString *r = [[NSBundle mainBundle] localizedStringForKey:key value:nil table:@"SpringBoard"];
Expand All @@ -49,6 +46,8 @@ -(void)remove;
-(void)setDelegate:(id)delegate;
-(void)setDownload:(id)download;
-(void)updateDisplayName;
-(id)darkenedIconImage:(id)image alpha:(float)alpha;
-(id)darkenedIcon:(id)image alpha:(float)alpha;
@end

@interface SBIconController {
Expand All @@ -66,21 +65,6 @@ -(void)addIcon:(id)icon;
//-(void)removeIcon:(id)icon;
@end

@interface MyDelegate : NSObject {
}
@end
@implementation MyDelegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if(buttonIndex == 0) {
sk_handler(0);
[alert_view release];
alert_view = nil;
} else {
notify_post("locutus.pause");
}
}
@end

static notify_handler_t sk_handler = ^(int token) {
NSLog(@"s/k");
[alert_view dismissWithClickedButtonIndex:0 animated:YES];
Expand Down Expand Up @@ -112,17 +96,23 @@ static void MyIcon_completeUninstall(id self, SEL sel) {
sk_handler(0);
}


static void MyIcon_alertView_clickedButtonAtIndex(id self, SEL sel, UIAlertView *alertView, NSInteger buttonIndex) {
if(buttonIndex == 0) {
sk_handler(0);
[alert_view release];
alert_view = nil;
} else {
notify_post("locutus.pause");
}
}

static void set_progress(float progress) {
id _progress = nil;
object_getInstanceVariable(icon, "_progress", (void **) &_progress);
[_progress setProgress:progress];
}

static void override(SEL sel, IMP imp) {
method_setImplementation(class_getInstanceMethod(MyIcon, sel), imp);
}
#define OVERRIDE(x) override(@selector(x), (IMP) MyIcon_##x)

__attribute__((constructor))
static void init() {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
Expand All @@ -131,11 +121,13 @@ static void init() {
char name[32];
sprintf(name, "MyIcon_%p", &init);
MyIcon = objc_allocateClassPair(objc_getClass("SBDownloadingIcon"), name, 0);
#define OVERRIDE(x) class_replaceMethod(MyIcon, @selector(x), (IMP) MyIcon_##x, "")
OVERRIDE(displayName);
OVERRIDE(applicationBundleID);
OVERRIDE(launch);
OVERRIDE(allowsUninstall);
OVERRIDE(completeUninstall);
class_addMethod(MyIcon, @selector(alertView:clickedButtonAtIndex:), (IMP) MyIcon_alertView_clickedButtonAtIndex, "@:@l");
objc_registerClassPair(MyIcon);

icon_controller = [objc_getClass("SBIconController") sharedInstance];
Expand Down Expand Up @@ -165,36 +157,37 @@ static void init() {
NSLog(@"err = <%@>", err);
if(![err isEqualToString:@"ok"]) {
[alert_view dismissWithClickedButtonIndex:0 animated:YES]; // shouldn't happen!
alert_view = [[UIAlertView alloc] initWithTitle:@"JailbreakMe" message:err delegate:[[MyDelegate alloc] init] cancelButtonTitle:_(@"DATA_PLAN_FAILED_TRY_LATER") otherButtonTitles:_(@"DATA_PLAN_FAILED_TRY_AGAIN"), nil];
alert_view = [[UIAlertView alloc] initWithTitle:@"There was a problem downloading the jailbreak files." message:err delegate:icon cancelButtonTitle:@"Cancel" otherButtonTitles:@"Retry", nil];
[alert_view show];
}
});

notify_register_dispatch("locutus.got-file", &tokens[2], dispatch_get_main_queue(), ^(int token) {
UIImage *image = [UIImage imageWithContentsOfFile:@"/tmp/Cydia.png"];
if(image) {
if([icon respondsToSelector:@selector(setDisplayedIconImage:)]) {
[icon setDisplayedIconImage:image];
} else {
[icon setDisplayedIcon:image];

if(!icon_image) {
icon_image = [UIImage imageWithContentsOfFile:@"/tmp/Cydia.png"];
if(icon_image) {
if([icon respondsToSelector:@selector(setDisplayedIconImage:)]) {
[icon setDisplayedIconImage:[icon darkenedIconImage:icon_image alpha:0.5]];
} else {
[icon setDisplayedIcon:[icon darkenedIcon:icon_image alpha:0.5]];
}
}
notify_cancel(token);
}
});

NSLog(@"done, MyIcon is now %p", MyIcon);

icon = [MyIcon alloc];
NSLog(@"omg");
icon = [icon initWithLeafIdentifier:bundle_identifier];
[icon setDelegate:icon_controller];
display_name = _(@"WAITING_ICON_LABEL");
NSLog(@"%@", icon);
[icon_model addIcon:icon];
//[icon setDownload:[[NSObject alloc] init]];
//[icon setDelegate:[[NSObject alloc] init]];
[icon_controller addNewIconToDesignatedLocation:icon animate:NO scrollToList:NO saveIconState:YES];
[icon_controller setIconToReveal:icon];
[icon release];
notify_register_dispatch("locutus.installed", &tokens[2], dispatch_get_main_queue(), ^(int token) {

});

dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"done, MyIcon is now %p", MyIcon);

icon = [[MyIcon alloc] initWithLeafIdentifier:bundle_identifier];
[icon setDelegate:icon_controller];
display_name = _(@"WAITING_ICON_LABEL");
NSLog(@"%@", icon);
[icon_model addIcon:icon];
[icon_controller addNewIconToDesignatedLocation:icon animate:NO scrollToList:NO saveIconState:YES];
[icon_controller setIconToReveal:icon];
[icon release];
});
[pool release];
}
Loading

0 comments on commit 5b46cd5

Please sign in to comment.