]>
git.saurik.com Git - cydia.git/blob - setnsfpn.cpp
1 /* Cydia - iPhone UIKit Front-End for Debian APT
2 * Copyright (C) 2008-2014 Jay Freeman (saurik)
5 /* GNU General Public License, Version 3 {{{ */
7 * Cydia is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published
9 * by the Free Software Foundation, either version 3 of the License,
10 * or (at your option) any later version.
12 * Cydia is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Cydia. If not, see <http://www.gnu.org/licenses/>.
30 #define _syscall(expr) ({ typeof(expr) _value; for (;;) { \
32 if ((long) _value != -1) \
34 if (errno != EINTR) { \
40 int $
getdirentries(int, char *, int, long *) __asm("_getdirentries");
47 char d_name
[__DARWIN_MAXNAMLEN
+ 1];
50 #define getdirentries $getdirentries
51 #define dirent $dirent
77 File::operator int() const {
81 static int setnsfpn(const char *path
, size_t before
, Recurse recurse
) {
82 File
fd(_syscall(open_dprotected_np(path
, O_RDONLY
| O_SYMLINK
, 0, O_DP_GETRAWENCRYPTED
)));
84 if (recurse
== RecurseMaybe
) {
86 _syscall(fstat(fd
, &stat
));
87 switch (stat
.st_mode
& S_IFMT
) {
102 int mode(_syscall(fcntl(fd
, F_GETPROTECTIONCLASS
)));
103 if (mode
!= -1 && mode
!= 4) {
104 if (recurse
== RecurseYes
) {
109 int size(_syscall(getdirentries(fd
, buffer
, sizeof(buffer
), &address
)));
113 const char *next(buffer
), *stop(next
+ size
);
114 while (next
!= stop
) {
115 const dirent
*dir(reinterpret_cast<const dirent
*>(next
));
116 const char *name(dir
->d_name
);
117 size_t after(strlen(name
));
120 else if (after
== 1 && name
[0] == '.');
121 else if (after
== 2 && name
[0] == '.' && name
[1] == '.');
123 size_t both(before
+ 1 + after
);
125 memcpy(sub
, path
, before
);
127 memcpy(sub
+ before
+ 1, name
, after
);
130 switch (dir
->d_type
) {
137 setnsfpn(sub
, both
, RecurseYes
);
140 setnsfpn(sub
, both
, RecurseNo
);
145 next
+= dir
->d_reclen
;
150 _syscall(fcntl(fd
, F_SETPROTECTIONCLASS
, 4));
156 int main(int argc
, const char *argv
[]) {
157 return setnsfpn(argv
[1], strlen(argv
[1]), RecurseMaybe
);