]> git.saurik.com Git - cydia.git/blobdiff - setnsfpn.cpp
Allow user to select a specific candidate version.
[cydia.git] / setnsfpn.cpp
index 6dc80c7bf2126aafe2eb3debe3fcfe71c38a395b..5f72748603f628038f190b2612adc40476674057 100644 (file)
@@ -1,5 +1,5 @@
 /* Cydia - iPhone UIKit Front-End for Debian APT
- * Copyright (C) 2008-2014  Jay Freeman (saurik)
+ * Copyright (C) 2008-2015  Jay Freeman (saurik)
 */
 
 /* GNU General Public License, Version 3 {{{ */
     } \
 } _value; })
 
-int $getdirentries(int, char *, int, long *) __asm("_getdirentries");
-
-struct $dirent {
-    __uint32_t d_ino;
-    __uint16_t d_reclen;
-    __uint8_t  d_type;
-    __uint8_t  d_namlen;
-    char d_name[__DARWIN_MAXNAMLEN + 1];
-};
-
-#define getdirentries $getdirentries
-#define dirent $dirent
+extern "C" int __getdirentries64(int, char *, int, long *);
 
 enum Recurse {
     RecurseYes,
@@ -100,56 +89,55 @@ static int setnsfpn(const char *path, size_t before, Recurse recurse) {
     }
 
     int mode(_syscall(fcntl(fd, F_GETPROTECTIONCLASS)));
-    if (mode != -1 && mode != 4) {
-        if (recurse == RecurseYes) {
-            long address(0);
-
-            for (;;) {
-                char buffer[4096];
-                int size(_syscall(getdirentries(fd, buffer, sizeof(buffer), &address)));
-                if (size == 0)
-                    break;
-
-                const char *next(buffer), *stop(next + size);
-                while (next != stop) {
-                    const dirent *dir(reinterpret_cast<const dirent *>(next));
-                    const char *name(dir->d_name);
-                    size_t after(strlen(name));
-
-                    if (false);
-                    else if (after == 1 && name[0] == '.');
-                    else if (after == 2 && name[0] == '.' && name[1] == '.');
-                    else {
-                        size_t both(before + 1 + after);
-                        char sub[both + 1];
-                        memcpy(sub, path, before);
-                        sub[before] = '/';
-                        memcpy(sub + before + 1, name, after);
-                        sub[both] = '\0';
-
-                        switch (dir->d_type) {
-                            case DT_LNK:
-                                break;
-                            default:
-                                return -1;
+    if (mode == 4)
+        return 0;
+
+    if (recurse == RecurseYes)
+        for (long address(0);;) {
+            char buffer[4096];
+            int size(_syscall(__getdirentries64(fd, buffer, sizeof(buffer), &address)));
+            if (size == 0)
+                break;
 
-                            case DT_DIR:
-                                setnsfpn(sub, both, RecurseYes);
-                                break;
-                            case DT_REG:
-                                setnsfpn(sub, both, RecurseNo);
-                                break;
-                        }
+            const char *next(buffer), *stop(next + size);
+            while (next != stop) {
+                const dirent *dir(reinterpret_cast<const dirent *>(next));
+                const char *name(dir->d_name);
+                size_t after(strlen(name));
+
+                if (dir->d_ino == 0);
+                else if (after == 1 && name[0] == '.');
+                else if (after == 2 && name[0] == '.' && name[1] == '.');
+                else {
+                    size_t both(before + 1 + after);
+                    char sub[both + 1];
+                    memcpy(sub, path, before);
+                    sub[before] = '/';
+                    memcpy(sub + before + 1, name, after);
+                    sub[both] = '\0';
+
+                    switch (dir->d_type) {
+                        case DT_LNK:
+                            break;
+                        default:
+                            return -1;
+
+                        case DT_DIR:
+                            if (setnsfpn(sub, both, RecurseYes) != 0)
+                                return -1;
+                            break;
+                        case DT_REG:
+                            if (setnsfpn(sub, both, RecurseNo) != 0)
+                                return -1;
+                            break;
                     }
-
-                    next += dir->d_reclen;
                 }
+
+                next += dir->d_reclen;
             }
         }
 
-        _syscall(fcntl(fd, F_SETPROTECTIONCLASS, 4));
-    }
-
+    _syscall(fcntl(fd, F_SETPROTECTIONCLASS, 4));
     return 0;
 }