};
// }}}
-struct Root {
- static bool root_;
+static void setreugid(uid_t uid, gid_t gid) {
+ _assert(setreuid(uid, uid) != -1);
+ _assert(setregid(gid, gid) != -1);
+}
- Root(bool real) {
- _assert(!root_);
- root_ = true;
+static void setreguid(gid_t gid, uid_t uid) {
+ _assert(setregid(gid, gid) != -1);
+ _assert(setreuid(uid, uid) != -1);
+}
+
+struct Root {
+ Root() {
_trace();
- _assert(setreuid(real ? 0 : 501, 0) != -1);
+ setreugid(0, 0);
+ _assert(pthread_setugid_np(0, 0) != -1);
+ setreguid(501, 501);
}
~Root() {
- root_ = false;
_trace();
- _assert(setreuid(501, 501) != -1);
- }
-
- operator bool() const {
- return true;
+ setreugid(0, 0);
+ _assert(pthread_setugid_np(KAUTH_UID_NONE, KAUTH_GID_NONE) != -1);
+ setreguid(501, 501);
}
};
-bool Root::root_;
-
-#define _root(real) \
- if (__attribute__((__unused__)) const Root &root = Root(real))
+#define _root(code) \
+ ({ Root _root; code; })
static NSString *Colon_;
NSString *Elision_;
}
_end
+ _root(_system->Lock());
+
_trace();
OpProgress progress;
bool opened;
}
}
+ _system->UnLock();
return;
}
_trace();
- (void) configure {
NSString *dpkg = [NSString stringWithFormat:@"dpkg --configure -a --status-fd %u", statusfd_];
_trace();
- system([dpkg UTF8String]);
+ _root(system([dpkg UTF8String]));
_trace();
}
RestartSubstrate_ = true;
_system->UnLock();
- pkgPackageManager::OrderResult result;
- _root(true) result = manager_->DoInstall(statusfd_);
+ pkgPackageManager::OrderResult result(_root(manager_->DoInstall(statusfd_)));
if ([self popErrorWithTitle:title])
return;
_assert(close(fds[0]) != -1);
_assert(close(fds[1]) != -1);
/* XXX: this should probably not use du */
- execl("/usr/libexec/cydia/du", "du", "-s", [path UTF8String], NULL);
+ _root(execl("/usr/libexec/cydia/du", "du", "-s", [path UTF8String], NULL));
exit(1);
} else {
_assert(close(fds[1]) != -1);
if ([context isEqualToString:@"remove"]) {
if (button == [alert cancelButtonIndex])
- [self dismissModalViewControllerAnimated:YES];
+ [self _doContinue];
else if (button == [alert firstOtherButtonIndex]) {
[self performSelector:@selector(complete) withObject:nil afterDelay:0];
}
pid_t pid(ExecFork());
if (pid == 0) {
- execl("/usr/bin/sbreload", "sbreload", NULL);
+ _root(execl("/usr/bin/sbreload", "sbreload", NULL));
perror("sbreload");
exit(0);
if ([context isEqualToString:@"modify"]) {
if (button != [sheet cancelButtonIndex]) {
- [self _clickButtonWithName:buttons_[button].first];
+ [self performSelector:@selector(_clickButtonWithName:) withObject:buttons_[button].first afterDelay:0];
}
[sheet dismissWithClickedButtonIndex:-1 animated:YES];
pid_t pid(ExecFork());
if (pid == 0) {
- FILE *dpkg(popen("dpkg --set-selections", "w"));
+ FILE *dpkg(_root(popen("dpkg --set-selections", "w")));
fwrite(package, strlen(package), 1, dpkg);
if (on)
[super storeCachedResponse:cached forRequest:request];
}
+- (void) createDiskCachePath {
+ [super createDiskCachePath];
+ _root(chown([[self diskCachePath] UTF8String], 501, 501));
+}
+
@end
@interface Cydia : UIApplication <
_H<UIWindow> window_;
_H<CydiaTabBarController> tabbar_;
_H<CyteTabBarController> emulated_;
+ _H<AppCacheController> appcache_;
_H<NSMutableArray> essential_;
_H<NSMutableArray> broken_;
if (NSData *data = [NSPropertyListSerialization dataFromPropertyList:Metadata_ format:NSPropertyListBinaryFormat_v1_0 errorDescription:&error]) {
_trace();
NSError *error(nil);
- _root(true) if (![data writeToFile:@"/var/lib/cydia/metadata.plist" options:NSAtomicWrite error:&error])
+ if (!_root([data writeToFile:@"/var/lib/cydia/metadata.plist" options:NSAtomicWrite error:&error]))
NSLog(@"failure to save metadata data: %@", error);
_trace();
}
}
- CydiaWriteSources();
+ _root(CydiaWriteSources());
}
// Navigation controller for the queuing badge.
bool recently = false;
if (update != nil) {
NSTimeInterval interval([update timeIntervalSinceNow]);
- if (interval <= 0 && interval > -(15*60))
+ if (interval > -(15*60))
recently = true;
}
[self setApplicationIconBadgeNumber:0];
}
+ Queuing_ = false;
[self _updateData];
if (hud != nil)
} else if ([context isEqualToString:@"fixhalf"]) {
if (button == [alert cancelButtonIndex]) {
@synchronized (self) {
- _root(false) for (Package *broken in (id) broken_) {
+ for (Package *broken in (id) broken_) {
[broken remove];
-
NSString *id = [broken id];
- unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.prerm", id] UTF8String]);
- unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.postrm", id] UTF8String]);
- unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.preinst", id] UTF8String]);
- unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.postinst", id] UTF8String]);
+
+ _root({
+ unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.prerm", id] UTF8String]);
+ unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.postrm", id] UTF8String]);
+ unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.preinst", id] UTF8String]);
+ unlink([[NSString stringWithFormat:@"/var/lib/dpkg/info/%@.postinst", id] UTF8String]);
+ });
}
[self resolve];
NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]);
_trace();
- system([command UTF8String]);
+ _root(system([command UTF8String]));
_trace();
[pool release];
return true;
}
+- (void) suspendReturningToLastApp:(BOOL)returning {
+ if ([self isSafeToSuspend])
+ [super suspendReturningToLastApp:returning];
+}
+
+- (void) suspend {
+ if ([self isSafeToSuspend])
+ [super suspend];
+}
+
+- (void) applicationSuspend {
+ if ([self isSafeToSuspend])
+ [super applicationSuspend];
+}
+
- (void) applicationSuspend:(__GSEvent *)event {
if ([self isSafeToSuspend])
[super applicationSuspend:event];
[self saveState];
}
+- (void) applicationDidEnterBackground:(UIApplication *)application {
+ [self saveState];
+}
+
+- (void) applicationWillEnterForeground:(UIApplication *)application {
+ NSDate *closed = [Metadata_ objectForKey:@"LastClosed"];
+ if (closed == nil)
+ return;
+
+ NSTimeInterval interval([closed timeIntervalSinceNow]);
+
+ if (interval <= -(30)) {
+ [tabbar_ setSelectedIndex:0];
+ [[[tabbar_ viewControllers] objectAtIndex:0] popToRootViewControllerAnimated:NO];
+ }
+
+ if (interval <= -(15)) {
+ if (IsReachable("cydia.saurik.com")) {
+ [tabbar_ beginUpdate];
+ [appcache_ reloadURLWithCache:YES];
+ }
+ }
+}
+
- (void) setConfigurationData:(NSString *)data {
static Pcre conffile_r("^'(.*)' '(.*)' ([01]) ([01])$");
- (void) stash {
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque];
UpdateExternalStatus(1);
- _root(true) [self yieldToSelector:@selector(system:) withObject:@"/usr/libexec/cydia/free.sh"];
+ [self yieldToSelector:@selector(system:) withObject:@"/usr/libexec/cydia/free.sh"];
UpdateExternalStatus(0);
[self removeStashController];
broken_ = [NSMutableArray arrayWithCapacity:4];
// XXX: I really need this thing... like, seriously... I'm sorry
- [[[AppCacheController alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/appcache/", UI_]]] reloadData];
+ appcache_ = [[[AppCacheController alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/appcache/", UI_]]] autorelease];
+ [appcache_ reloadData];
window_ = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
[window_ orderFront:self];
NSDate *closed = [Metadata_ objectForKey:@"LastClosed"];
if (valid && closed != nil) {
NSTimeInterval interval([closed timeIntervalSinceNow]);
- // XXX: Is 30 minutes the optimal time here?
if (interval <= -(30*60))
valid = NO;
}
}
int main(int argc, char *argv[]) {
- seteuid(501);
+ setreugid(501, 501);
NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]);
} broken = nil;
/* }}} */
- CydiaWriteSources();
+ _root(CydiaWriteSources());
_trace();
- _root(true) MetaFile_.Open("/var/lib/cydia/metadata.cb0");
+ _root(MetaFile_.Open("/var/lib/cydia/metadata.cb0"));
_trace();
if (Packages_ != nil) {
int version([[NSString stringWithContentsOfFile:@"/var/lib/cydia/firmware.ver"] intValue]);
- _root(true) if (access("/User", F_OK) != 0 || version != 6) {
+ if (access("/User", F_OK) != 0 || version != 6) {
_trace();
- system("/usr/libexec/cydia/firmware.sh");
+ _root(system("/usr/libexec/cydia/firmware.sh"));
_trace();
}
//UIKeyboardDisableAutomaticAppearance();
/* }}} */
+ _root({
+ chown([Cache("ApplicationCache.db") UTF8String], 501, 501);
+ chown([Cache("Cache.db") UTF8String], 501, 501);
+ chown([Cache("Cache.db-shm") UTF8String], 501, 501);
+ chown([Cache("Cache.db-wal") UTF8String], 501, 501);
+ });
+
$SBSSetInterceptsMenuButtonForever = reinterpret_cast<void (*)(bool)>(dlsym(RTLD_DEFAULT, "SBSSetInterceptsMenuButtonForever"));
const char *symbol(kCFCoreFoundationVersionNumber >= 800 ? "MGGetBoolAnswer" : "GSSystemHasCapability");