]> git.saurik.com Git - cydia.git/blob - cydo.cpp
Ignore .dSYM folders I am suddenly ending up with.
[cydia.git] / cydo.cpp
1 /* Cydia - iPhone UIKit Front-End for Debian APT
2 * Copyright (C) 2008-2015 Jay Freeman (saurik)
3 */
4
5 /* GNU General Public License, Version 3 {{{ */
6 /*
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.
11 *
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.
16 *
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/>.
19 **/
20 /* }}} */
21
22 #include "CyteKit/UCPlatform.h"
23
24 #include <cstdio>
25 #include <cstdlib>
26
27 #include <errno.h>
28 #include <sysexits.h>
29 #include <unistd.h>
30
31 #include <launch.h>
32
33 #include <sys/stat.h>
34
35 #include <Menes/Function.h>
36
37 struct timeval _ltv;
38 bool _itv;
39
40 typedef Function<void, const char *, launch_data_t> LaunchDataIterator;
41
42 void launch_data_dict_iterate(launch_data_t data, LaunchDataIterator code) {
43 launch_data_dict_iterate(data, [](launch_data_t value, const char *name, void *baton) {
44 (*static_cast<LaunchDataIterator *>(baton))(name, value);
45 }, &code);
46 }
47
48 int main(int argc, char *argv[]) {
49 auto request(launch_data_new_string(LAUNCH_KEY_GETJOBS));
50 auto response(launch_msg(request));
51 launch_data_free(request);
52
53 _assert(response != NULL);
54 _assert(launch_data_get_type(response) == LAUNCH_DATA_DICTIONARY);
55
56 auto parent(getppid());
57
58 auto cydia(false);
59
60 struct stat correct;
61 if (lstat("/Applications/Cydia.app/Cydia", &correct) == -1) {
62 fprintf(stderr, "you have no arms left");
63 return EX_NOPERM;
64 }
65
66 launch_data_dict_iterate(response, [=, &cydia](const char *name, launch_data_t value) {
67 if (launch_data_get_type(value) != LAUNCH_DATA_DICTIONARY)
68 return;
69
70 auto integer(launch_data_dict_lookup(value, LAUNCH_JOBKEY_PID));
71 if (integer == NULL || launch_data_get_type(integer) != LAUNCH_DATA_INTEGER)
72 return;
73
74 auto pid(launch_data_get_integer(integer));
75 if (pid != parent)
76 return;
77
78 auto variables(launch_data_dict_lookup(value, LAUNCH_JOBKEY_ENVIRONMENTVARIABLES));
79 if (variables != NULL && launch_data_get_type(variables) == LAUNCH_DATA_DICTIONARY) {
80 auto dyld(false);
81
82 launch_data_dict_iterate(variables, [&dyld](const char *name, launch_data_t value) {
83 if (strncmp(name, "DYLD_", 5) == 0)
84 dyld = true;
85 });
86
87 if (dyld)
88 return;
89 }
90
91 auto string(launch_data_dict_lookup(value, LAUNCH_JOBKEY_PROGRAM));
92 if (string == NULL || launch_data_get_type(string) != LAUNCH_DATA_STRING) {
93 auto array(launch_data_dict_lookup(value, LAUNCH_JOBKEY_PROGRAMARGUMENTS));
94 if (array == NULL || launch_data_get_type(array) != LAUNCH_DATA_ARRAY)
95 return;
96 if (launch_data_array_get_count(array) == 0)
97 return;
98
99 string = launch_data_array_get_index(array, 0);
100 if (string == NULL || launch_data_get_type(string) != LAUNCH_DATA_STRING)
101 return;
102 }
103
104 auto program(launch_data_get_string(string));
105 if (program == NULL)
106 return;
107
108 struct stat check;
109 if (lstat(program, &check) == -1)
110 return;
111
112 if (correct.st_dev == check.st_dev && correct.st_ino == check.st_ino)
113 cydia = true;
114 });
115
116 if (!cydia) {
117 fprintf(stderr, "none shall pass\n");
118 return EX_NOPERM;
119 }
120
121 setuid(0);
122 setgid(0);
123
124 if (argc < 2 || argv[1][0] != '/')
125 argv[0] = "/usr/bin/dpkg";
126 else {
127 --argc;
128 ++argv;
129 }
130
131 execv(argv[0], argv);
132 return EX_UNAVAILABLE;
133 }