Skip to content

Commit

Permalink
Added iOS 7 support. Fixed bug with Cydia not being killed.
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanb93 committed Nov 13, 2014
1 parent ec41401 commit 332af81
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 53 deletions.
111 changes: 67 additions & 44 deletions CyDelete8.xm
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ static NSOperationQueue *uninstallQueue;
#define SBLocalizedString(key) [[NSBundle mainBundle] localizedStringForKey:key value:@"None" table:@"SpringBoard"]
#define CDLocalizedString(key) [cyDelBundle localizedStringForKey:key value:key table:nil]

#ifndef kCFCoreFoundationVersionNumber_iOS_8_0
#define kCFCoreFoundationVersionNumber_iOS_8_0 1129.15
#endif

@interface CDUninstallOperation : NSOperation {
BOOL _executing;
BOOL _finished;
Expand Down Expand Up @@ -89,6 +93,27 @@ __attribute__((unused)) static int getFreeMemory() {
return (availMem * pageSize) / 1024 / 1024;
}

__attribute__((unused)) static NSMutableString *outputForShellCommand(NSString *cmd) {
FILE *fp;
char buf[1024];
NSMutableString* finalRet;

fp = popen([cmd UTF8String], "r");
if (fp == NULL) {
return nil;
}

fgets(buf, 1024, fp);
finalRet = [NSMutableString stringWithUTF8String:buf];

if(pclose(fp) != 0) {
return nil;
}

return finalRet;
}


#define fexists(n) access(n, F_OK)

static char *owner(const char *_bundle, const char *_title, const char *_path) {
Expand Down Expand Up @@ -191,52 +216,16 @@ static id ownerForSBApplication(SBApplication *application) {
return self;
}

- (bool)runCMD
{
//Path to the setuid appliaction that gets us root permissions.
const char *setuid = "/usr/libexec/cydelete/setuid";
//Path to our uninstall script that we want to run as root.
char commandChar[] = "/usr/libexec/cydelete/uninstall_dpkg.sh";

//Horrible method to convert NSString to Char array.
char packageChar [strlen([_package UTF8String]) + 1];
strcpy(packageChar, [_package UTF8String]);

//Char literal array containing shell script path and package name.
char *argv[] = {commandChar, packageChar, NULL};

//Create a pid_t object to hold reference to spawned process.
pid_t pid;

//Spawn a new process using posix_spawn as System() is depricated on iOS 8.
int status = posix_spawn(&pid, setuid, NULL, NULL, argv, NULL);

//Status 0 indicates successful spawn. Not that apt-get was success though.
if (status == 0) {
if (waitpid(pid, &status, 0) != -1) {
//Return a success.
return true;
}
}
//Return failure.
return false;
}

- (void)displayError {
NSString *body = [NSString stringWithFormat:CDLocalizedString(@"PACKAGE_UNINSTALL_ERROR_BODY"), _package];
UIAlertView *delView = [[UIAlertView alloc] initWithTitle:CDLocalizedString(@"PACKAGE_UNINSTALL_ERROR_TITLE") message:body delegate:nil cancelButtonTitle:@"Okay" otherButtonTitles:nil];
[delView show];
}

- (void)main {
bool output = [self runCMD];
if(output) {
removeBundleFromMIList(_package);
}
else {
[self performSelectorOnMainThread:@selector(displayError) withObject:nil waitUntilDone:NO];
}

NSString *command = [NSString stringWithFormat:@"/usr/libexec/cydelete/setuid /usr/libexec/cydelete/uninstall_dpkg.sh %@", _package];
NSString *output = outputForShellCommand(command);
if(!output) [self performSelectorOnMainThread:@selector(displayError) withObject:nil waitUntilDone:NO];
[self completeOperation];
}

Expand All @@ -257,8 +246,17 @@ static void removeBundleFromMIList(NSString *bundle) {
%orig;
}
else {

//Get the package details for the bundle ID.
id package = [iconPackagesDict objectForKey:[application bundleIdentifier]];
id package = nil;

if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) {
package = [iconPackagesDict objectForKey:[application bundleIdentifier]];
}
else {
package = [iconPackagesDict objectForKey:[application displayIdentifer]];
}

// We were called with an application that doesn't have an entry in the packages list.
if(!package) package = ownerForSBApplication(application);
// We still don't have an entry (or a NSNull). We should probably bail out.
Expand All @@ -277,6 +275,7 @@ static void removeBundleFromMIList(NSString *bundle) {
else {
//Add the package to the Uninstall operation queue.
[uninstallQueue addOperation:[[CDUninstallDpkgOperation alloc] initWithPackage:package]];
removeBundleFromMIList([application bundleIdentifier]);
}
}
}
Expand All @@ -288,11 +287,17 @@ static void removeBundleFromMIList(NSString *bundle) {
@end

static void uninstallClickedForIcon(SBIcon *self) {

//Get the application for this icon.
SBApplication *app = [self application];

//Get the bundle identifer for this application.
NSString *bundle = [app bundleIdentifier];
NSString *bundle = nil;
if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) {
bundle = [app bundleIdentifier];
}
else {
bundle = [app displayIdentifer];
}

//If iconPackagesDict does not contain this current application's bundle ID.
if(![[iconPackagesDict allKeys] containsObject:bundle]) {
Expand All @@ -305,6 +310,7 @@ static void uninstallClickedForIcon(SBIcon *self) {

%hook SBIconController
- (void)iconCloseBoxTapped:(id)_i {
%log;
SBIconView *iconView = _i;
SBIcon *icon = [iconView icon];
SBApplication *app = [icon application];
Expand All @@ -321,7 +327,13 @@ static void uninstallClickedForIcon(SBIcon *self) {
%new(c@:)
-(BOOL)cydelete_allowsUninstall {
//Get the bundle ID for this application.
NSString *bundle = [[self application] bundleIdentifier];
NSString *bundle = nil;
if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) {
bundle = [[self application] bundleIdentifier];
}
else {
bundle = [[self application] displayIdentifer];
}
//If the application is an Apple application.
bool isApple = ([bundle hasPrefix:@"com.apple."] && ![bundle hasPrefix:@"com.apple.samplecode."]);
//If the application is Cydia and user has protected it.
Expand Down Expand Up @@ -373,7 +385,18 @@ static void uninstallClickedForIcon(SBIcon *self) {
}

-(NSString *)uninstallAlertBody {
id package = [iconPackagesDict objectForKey:[[self application] bundleIdentifier]];

NSString *bundle = nil;

if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) {
bundle = [[self application] bundleIdentifier];
}
else {
bundle = [[self application] displayIdentifer];
}

id package = [iconPackagesDict objectForKey:bundle];

NSString *body;
if(package == [NSNull null]) {
body = [NSString stringWithFormat:SBLocalizedString(@"DELETE_WIDGET_BODY"),
Expand Down
4 changes: 2 additions & 2 deletions Cydelete8/Resources/Cydelete8.plist
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
<string>PSGroupCell</string>
<key>footerText</key>
<string>
There is no DRM protection on this application but please help support future development (my coffee fund) by purchasing through the Cydia store or donating via PayPal.
There is no DRM protection on this application but please help support future development (my coffee fund) by donating via PayPal.
CyDelete8 © 2014 Ryan Burke
CyDelete © 2009-2011 Dustin L. Howett
Expand All @@ -90,6 +90,6 @@ Released under the GPLv3 Licence.
</dict>
</array>
<key>title</key>
<string>CyDelete8 Community</string>
<string>CyDelete8</string>
</dict>
</plist>
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ CyDelete8_FILES = CyDelete8.xm
CyDelete8_FRAMEWORKS = Foundation, UIKit

include $(THEOS_MAKE_PATH)/tweak.mk
SUBPROJECTS += setuid Cydelete8
SUBPROJECTS += setuid CyDelete8
include $(THEOS_MAKE_PATH)/aggregate.mk

after-install::
Expand Down
4 changes: 2 additions & 2 deletions layout/DEBIAN/control
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
Package: com.ryanburke.cydelete8
Name: CyDelete8
Depends: firmware (>=8.0), mobilesubstrate, preferenceloader, apt, bash
Depends: firmware (>=7.0), mobilesubstrate, preferenceloader, apt, bash
Version: 1.0
Architecture: iphoneos-arm
Description: Allows you to uninstall applications installed via Cydia from the Springboard just like AppStore applications. Just hold an icon down and tap on the X and the app will be uninstalled! This application is a new branch of the original CyDelete, created by @DHowett, bringing new support for iOS 8.
Description: Allows you to uninstall applications installed via Cydia from the Springboard just like AppStore applications. Just hold an icon down and tap on the X and the app will be uninstalled! This application is a new branch of the original CyDelete, created by @DHowett, bringing new support for iOS 8. Supports iOS 7 and 8.
Maintainer: Ryan Burke <[email protected]>
Author: Ryan Burke <[email protected]>
Section: Tweaks
Expand Down
3 changes: 2 additions & 1 deletion layout/usr/libexec/cydelete/uninstall_dpkg.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/bin/bash
export PATH=/usr/bin:/bin:/sbin:/usr/sbin
killall MobileCydia
killall -9 MobileCydia
sleep 3
apt-get -y remove $1 2>/tmp/aptoutput 1>/dev/null
exitcode=$?
rm -rf /tmp/aptoutput &> /dev/null
Expand Down
4 changes: 1 addition & 3 deletions setuid/setuid.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@

int main(int argc, char **argv) {
setuid(0);
char *params[] = {argv[0], argv[1], NULL};
char *env[] = {NULL};
execve(argv[0], params, env);
execve(argv[1], (argc > 1) ? argv+1 : 0, 0);
return 0;
}

0 comments on commit 332af81

Please sign in to comment.