X-Git-Url: https://git.saurik.com/cydia.git/blobdiff_plain/82e370b360798dcc8cdf41f68744788e503bb8a2..019bd407df21b38dc22972771fc8557e45a844d3:/setnsfpn.cpp diff --git a/setnsfpn.cpp b/setnsfpn.cpp index 6dc80c7b..5f727486 100644 --- a/setnsfpn.cpp +++ b/setnsfpn.cpp @@ -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 {{{ */ @@ -37,18 +37,7 @@ } \ } _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(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(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; }