blob: 12ce0b5280340f3126976736fa31f90a541d0103 [file] [log] [blame]
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -04001/*
2 Copyright 2012 bigbiff/Dees_Troy TeamWin
3 This file is part of TWRP/TeamWin Recovery Project.
4
5 TWRP is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 TWRP is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with TWRP. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19#include <iostream>
20#include <fstream>
21#include <sstream>
22#include <string>
23#include <vector>
24#include <string.h>
25#include <libgen.h>
26#include <unistd.h>
27#include <sys/stat.h>
28#include <dirent.h>
bigbiff bigbiff84a3f1a2013-12-28 18:32:15 -050029#include <errno.h>
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -040030#include "gui/rapidxml.hpp"
31#include "fixPermissions.hpp"
32#include "twrp-functions.hpp"
Dees_Troy2673cec2013-04-02 20:22:16 +000033#include "twcommon.h"
bigbiff bigbiff872a3b92013-10-18 20:50:25 -040034#ifdef HAVE_SELINUX
35#include "selinux/selinux.h"
36#include "selinux/label.h"
37#include "selinux/android.h"
38#include "selinux/label.h"
39#endif
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -040040
41using namespace std;
42using namespace rapidxml;
43
bigbiff bigbiff872a3b92013-10-18 20:50:25 -040044#ifdef HAVE_SELINUX
45int fixPermissions::restorecon(string entry, struct stat *sb) {
46 char *oldcontext, *newcontext;
47 struct selabel_handle *sehandle;
Dees Troya7b8de52014-02-03 14:58:32 +000048 struct selinux_opt selinux_options[] = {
49 { SELABEL_OPT_PATH, "/file_contexts" }
50 };
51 sehandle = selabel_open(SELABEL_CTX_FILE, selinux_options, 1);
bigbiff bigbiff872a3b92013-10-18 20:50:25 -040052 if (lgetfilecon(entry.c_str(), &oldcontext) < 0) {
53 LOGINFO("Couldn't get selinux context for %s\n", entry.c_str());
54 return -1;
55 }
56 if (selabel_lookup(sehandle, &newcontext, entry.c_str(), sb->st_mode) < 0) {
57 LOGINFO("Couldn't lookup selinux context for %s\n", entry.c_str());
58 return -1;
59 }
60 LOGINFO("Relabeling %s from %s to %s\n", entry.c_str(), oldcontext, newcontext);
61 if (lsetfilecon(entry.c_str(), newcontext) < 0) {
62 LOGINFO("Couldn't label %s with %s: %s\n", entry.c_str(), newcontext, strerror(errno));
63 }
64 freecon(oldcontext);
65 freecon(newcontext);
66 return 0;
67}
68
69int fixPermissions::fixDataDataContexts(void) {
70 DIR *d;
71 struct dirent *de;
72 struct stat sb;
73 struct selabel_handle *selinux_handle;
74 struct selinux_opt selinux_options[] = {
75 { SELABEL_OPT_PATH, "/file_contexts" }
76 };
bigbiff bigbiff6b600f92014-01-05 18:13:43 -050077
bigbiff bigbiff872a3b92013-10-18 20:50:25 -040078 selinux_handle = selabel_open(SELABEL_CTX_FILE, selinux_options, 1);
bigbiff bigbiff6b600f92014-01-05 18:13:43 -050079
bigbiff bigbiff872a3b92013-10-18 20:50:25 -040080 if (!selinux_handle)
81 printf("No file contexts for SELinux\n");
82 else
83 printf("SELinux contexts loaded from /file_contexts\n");
bigbiff bigbiff6b600f92014-01-05 18:13:43 -050084
bigbiff bigbiff872a3b92013-10-18 20:50:25 -040085 d = opendir("/data/data");
bigbiff bigbiff6b600f92014-01-05 18:13:43 -050086
bigbiff bigbiff872a3b92013-10-18 20:50:25 -040087 while (( de = readdir(d)) != NULL) {
88 stat(de->d_name, &sb);
89 string f = "/data/data/";
90 f = f + de->d_name;
91 restorecon(f, &sb);
92 }
bigbiff bigbiff6b600f92014-01-05 18:13:43 -050093 closedir(d);
94 return 0;
95}
96
97int fixPermissions::fixDataInternalContexts(void) {
98 DIR *d;
99 struct dirent *de;
100 struct stat sb;
101 string dir;
102
103 if (TWFunc::Path_Exists("/data/media")) {
104 dir = "/data/media";
105 }
106 else {
107 dir = "/data/media/0";
108 }
109 LOGINFO("Fixing %s contexts\n", dir.c_str());
110 d = opendir(dir.c_str());
111
112 while (( de = readdir(d)) != NULL) {
113 stat(de->d_name, &sb);
114 string f;
115 f = dir + de->d_name;
116 restorecon(f, &sb);
117 }
118 closedir(d);
bigbiff bigbiff872a3b92013-10-18 20:50:25 -0400119 return 0;
120}
121#endif
122
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400123int fixPermissions::fixPerms(bool enable_debug, bool remove_data_for_missing_apps) {
124 packageFile = "/data/system/packages.xml";
125 debug = enable_debug;
126 remove_data = remove_data_for_missing_apps;
Dees_Troy201d76b2012-11-16 17:12:02 +0000127 multi_user = TWFunc::Path_Exists("/data/user");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400128
129 if (!(TWFunc::Path_Exists(packageFile))) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000130 gui_print("Can't check permissions\n");
131 gui_print("after Factory Reset.\n");
132 gui_print("Please boot rom and try\n");
133 gui_print("again after you reboot into\n");
134 gui_print("recovery.\n");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400135 return -1;
136 }
137
Dees_Troy2673cec2013-04-02 20:22:16 +0000138 gui_print("Fixing permissions...\nLoading packages...\n");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400139 if ((getPackages()) != 0) {
140 return -1;
141 }
Dees_Troy32f2ca82013-02-02 17:03:12 +0000142
Dees_Troy2673cec2013-04-02 20:22:16 +0000143 gui_print("Fixing /system/app permissions...\n");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400144 if ((fixSystemApps()) != 0) {
145 return -1;
146 }
147
grimsrudcbec59f2013-07-29 15:46:22 +0200148 gui_print("Fixing /data/app permissions...\n");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400149 if ((fixDataApps()) != 0) {
150 return -1;
151 }
152
Dees_Troy201d76b2012-11-16 17:12:02 +0000153 if (multi_user) {
154 DIR *d = opendir("/data/user");
155 string new_path, user_id;
156
157 if (d == NULL) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000158 LOGERR("Error opening '/data/user'\n");
Dees_Troy201d76b2012-11-16 17:12:02 +0000159 return -1;
160 }
161
162 if (d) {
163 struct dirent *p;
164 while ((p = readdir(d))) {
165 if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, ".."))
166 continue;
167
168 new_path = "/data/user/";
169 new_path.append(p->d_name);
170 user_id = "u";
171 user_id += p->d_name;
172 user_id += "_";
173 if (p->d_type == DT_LNK) {
174 char link[512], realPath[512];
175 strcpy(link, new_path.c_str());
176 memset(realPath, 0, sizeof(realPath));
177 while (readlink(link, realPath, sizeof(realPath)) > 0) {
178 strcpy(link, realPath);
179 memset(realPath, 0, sizeof(realPath));
180 }
181 new_path = link;
182 } else if (p->d_type != DT_DIR) {
183 continue;
184 } else {
185 new_path.append("/");
186 // We're probably going to need to fix permissions on multi user but
187 // it will have to wait for another time. Need to figure out where
188 // the uid and gid is stored for other users.
189 continue;
190 }
Dees_Troy2673cec2013-04-02 20:22:16 +0000191 gui_print("Fixing %s permissions...\n", new_path.c_str());
Dees_Troy201d76b2012-11-16 17:12:02 +0000192 if ((fixDataData(new_path)) != 0) {
193 closedir(d);
194 return -1;
195 }
196 }
197 closedir(d);
198 }
199 } else {
grimsrudcbec59f2013-07-29 15:46:22 +0200200 gui_print("Fixing /data/data permissions...\n");
Dees_Troy201d76b2012-11-16 17:12:02 +0000201 if ((fixDataData("/data/data/")) != 0) {
202 return -1;
203 }
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400204 }
bigbiff bigbiff872a3b92013-10-18 20:50:25 -0400205 #ifdef HAVE_SELINUX
bigbiff bigbiff6b600f92014-01-05 18:13:43 -0500206 gui_print("Fixing /data/data/ contexts.\n");
bigbiff bigbiff872a3b92013-10-18 20:50:25 -0400207 fixDataDataContexts();
bigbiff bigbiff6b600f92014-01-05 18:13:43 -0500208 fixDataInternalContexts();
bigbiff bigbiff872a3b92013-10-18 20:50:25 -0400209 #endif
Dees_Troy2673cec2013-04-02 20:22:16 +0000210 gui_print("Done fixing permissions.\n");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400211 return 0;
212}
213
214int fixPermissions::pchown(string fn, int puid, int pgid) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000215 LOGINFO("Fixing %s, uid: %d, gid: %d\n", fn.c_str(), puid, pgid);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400216 if (chown(fn.c_str(), puid, pgid) != 0) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000217 LOGERR("Unable to chown '%s' %i %i\n", fn.c_str(), puid, pgid);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400218 return -1;
219 }
220 return 0;
221}
222
223int fixPermissions::pchmod(string fn, string mode) {
224 long mask = 0;
Dees_Troy2673cec2013-04-02 20:22:16 +0000225 LOGINFO("Fixing %s, mode: %s\n", fn.c_str(), mode.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400226 for ( std::string::size_type n = 0; n < mode.length(); ++n) {
227 if (n == 0) {
228 if (mode[n] == '0')
229 continue;
230 else if (mode[n] == '1')
231 mask = S_ISVTX;
232 else if (mode[n] == '2')
233 mask = S_ISGID;
234 }
235 else if (n == 1) {
236 if (mode[n] == '7') {
237 mask |= S_IRWXU;
238 }
239 if (mode[n] == '6') {
240 mask |= S_IRUSR;
241 mask |= S_IWUSR;
242 }
243 if (mode[n] == '5') {
244 mask |= S_IRUSR;
245 mask |= S_IXUSR;
246 }
247 if (mode[n] == '4')
248 mask |= S_IRUSR;
249 if (mode[n] == '3') {
250 mask |= S_IWUSR;
251 mask |= S_IRUSR;
252 }
253 if (mode[n] == '2')
254 mask |= S_IWUSR;
255 if (mode[n] == '1')
256 mask |= S_IXUSR;
257 }
258 else if (n == 2) {
259 if (mode[n] == '7') {
260 mask |= S_IRWXG;
261 }
262 if (mode[n] == '6') {
263 mask |= S_IRGRP;
264 mask |= S_IWGRP;
265 }
266 if (mode[n] == '5') {
267 mask |= S_IRGRP;
268 mask |= S_IXGRP;
269 }
270 if (mode[n] == '4')
271 mask |= S_IRGRP;
272 if (mode[n] == '3') {
273 mask |= S_IWGRP;
274 mask |= S_IXGRP;
275 }
276 if (mode[n] == '2')
277 mask |= S_IWGRP;
278 if (mode[n] == '1')
279 mask |= S_IXGRP;
280 }
281 else if (n == 3) {
282 if (mode[n] == '7') {
283 mask |= S_IRWXO;
284 }
285 if (mode[n] == '6') {
286 mask |= S_IROTH;
287 mask |= S_IWOTH;
288 }
289 if (mode[n] == '5') {
290 mask |= S_IROTH;
291 mask |= S_IXOTH;
292 }
293 if (mode[n] == '4')
294 mask |= S_IROTH;
295 if (mode[n] == '3') {
296 mask |= S_IWOTH;
297 mask |= S_IXOTH;
298 }
299 if (mode[n] == '2')
Dees_Troy6480ce02012-10-10 10:26:54 -0400300 mask |= S_IWOTH;
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400301 if (mode[n] == '1')
Dees_Troy6480ce02012-10-10 10:26:54 -0400302 mask |= S_IXOTH;
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400303 }
304 }
305
306 if (chmod(fn.c_str(), mask) != 0) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000307 LOGERR("Unable to chmod '%s' %l\n", fn.c_str(), mask);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400308 return -1;
309 }
310
311 return 0;
312}
313
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400314int fixPermissions::fixSystemApps() {
315 temp = head;
316 while (temp != NULL) {
317 if (TWFunc::Path_Exists(temp->codePath)) {
318 if (temp->appDir.compare("/system/app") == 0) {
bigbiff bigbiff872a3b92013-10-18 20:50:25 -0400319 if (debug) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000320 LOGINFO("Looking at '%s'\n", temp->codePath.c_str());
321 LOGINFO("Fixing permissions on '%s'\n", temp->pkgName.c_str());
322 LOGINFO("Directory: '%s'\n", temp->appDir.c_str());
323 LOGINFO("Original package owner: %d, group: %d\n", temp->uid, temp->gid);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400324 }
325 if (pchown(temp->codePath, 0, 0) != 0)
326 return -1;
327 if (pchmod(temp->codePath, "0644") != 0)
328 return -1;
329 }
330 } else {
331 //Remove data directory since app isn't installed
332 if (remove_data && TWFunc::Path_Exists(temp->dDir) && temp->appDir.size() >= 9 && temp->appDir.substr(0, 9) != "/mnt/asec") {
333 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000334 LOGINFO("Looking at '%s', removing data dir: '%s', appDir: '%s'", temp->codePath.c_str(), temp->dDir.c_str(), temp->appDir.c_str());
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500335 if (TWFunc::removeDir(temp->dDir, false) != 0) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000336 LOGINFO("Unable to removeDir '%s'\n", temp->dDir.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400337 return -1;
338 }
339 }
340 }
341 temp = temp->next;
342 }
343 return 0;
344}
345
346int fixPermissions::fixDataApps() {
347 bool fix = false;
348 int new_gid = 0;
349 string perms = "0000";
350
351 temp = head;
352 while (temp != NULL) {
353 if (TWFunc::Path_Exists(temp->codePath)) {
354 if (temp->appDir.compare("/data/app") == 0 || temp->appDir.compare("/sd-ext/app") == 0) {
355 fix = true;
356 new_gid = 1000;
357 perms = "0644";
358 } else if (temp->appDir.compare("/data/app-private") == 0 || temp->appDir.compare("/sd-ext/app-private") == 0) {
359 fix = true;
360 new_gid = temp->gid;
361 perms = "0640";
362 } else
363 fix = false;
364 if (fix) {
365 if (debug) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000366 LOGINFO("Looking at '%s'\n", temp->codePath.c_str());
367 LOGINFO("Fixing permissions on '%s'\n", temp->pkgName.c_str());
368 LOGINFO("Directory: '%s'\n", temp->appDir.c_str());
369 LOGINFO("Original package owner: %d, group: %d\n", temp->uid, temp->gid);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400370 }
371 if (pchown(temp->codePath, 1000, new_gid) != 0)
372 return -1;
373 if (pchmod(temp->codePath, perms) != 0)
374 return -1;
375 }
376 } else {
377 //Remove data directory since app isn't installed
378 if (remove_data && TWFunc::Path_Exists(temp->dDir) && temp->appDir.size() >= 9 && temp->appDir.substr(0, 9) != "/mnt/asec") {
379 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000380 LOGINFO("Looking at '%s', removing data dir: '%s', appDir: '%s'", temp->codePath.c_str(), temp->dDir.c_str(), temp->appDir.c_str());
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500381 if (TWFunc::removeDir(temp->dDir, false) != 0) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000382 LOGINFO("Unable to removeDir '%s'\n", temp->dDir.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400383 return -1;
384 }
385 }
386 }
387 temp = temp->next;
388 }
389 return 0;
390}
391
392int fixPermissions::fixAllFiles(string directory, int gid, int uid, string file_perms) {
393 vector <string> files;
394 string file;
395
396 files = listAllFiles(directory);
397 for (unsigned i = 0; i < files.size(); ++i) {
398 file = directory + "/";
399 file.append(files.at(i));
400 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000401 LOGINFO("Looking at file '%s'\n", file.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400402 if (pchmod(file, file_perms) != 0)
403 return -1;
404 if (pchown(file, uid, gid) != 0)
405 return -1;
406 }
407 return 0;
408}
409
Dees_Troy201d76b2012-11-16 17:12:02 +0000410int fixPermissions::fixDataData(string dataDir) {
411 string directory, dir;
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400412
413 temp = head;
414 while (temp != NULL) {
Dees_Troy201d76b2012-11-16 17:12:02 +0000415 dir = dataDir + temp->dDir;
416 if (TWFunc::Path_Exists(dir)) {
417 vector <string> dataDataDirs = listAllDirectories(dir);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400418 for (unsigned n = 0; n < dataDataDirs.size(); ++n) {
Dees_Troy201d76b2012-11-16 17:12:02 +0000419 directory = dir + "/";
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400420 directory.append(dataDataDirs.at(n));
421 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000422 LOGINFO("Looking at data directory: '%s'\n", directory.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400423 if (dataDataDirs.at(n) == ".") {
Dees_Troy201d76b2012-11-16 17:12:02 +0000424 if (pchmod(directory, "0755") != 0)
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400425 return -1;
426 if (pchown(directory.c_str(), temp->uid, temp->gid) != 0)
427 return -1;
428 if (fixAllFiles(directory, temp->uid, temp->gid, "0755") != 0)
429 return -1;
430 }
431 else if (dataDataDirs.at(n) == "..") {
432 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000433 LOGINFO("Skipping ..\n");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400434 continue;
435 }
436 else if (dataDataDirs.at(n) == "lib") {
437 if (pchmod(directory.c_str(), "0755") != 0)
438 return -1;
439 if (pchown(directory.c_str(), 1000, 1000) != 0)
440 return -1;
441 if (fixAllFiles(directory, temp->uid, temp->gid, "0755") != 0)
442 return -1;
443 }
444 else if (dataDataDirs.at(n) == "shared_prefs") {
445 if (pchmod(directory.c_str(), "0771") != 0)
446 return -1;
447 if (pchown(directory.c_str(), temp->uid, temp->gid) != 0)
448 return -1;
449 if (fixAllFiles(directory, temp->uid, temp->gid, "0660") != 0)
450 return -1;
451 }
452 else if (dataDataDirs.at(n) == "databases") {
453 if (pchmod(directory.c_str(), "0771") != 0)
454 return -1;
455 if (pchown(directory.c_str(), temp->uid, temp->gid) != 0)
456 return -1;
457 if (fixAllFiles(directory, temp->uid, temp->gid, "0660") != 0)
458 return -1;
459 }
460 else if (dataDataDirs.at(n) == "cache") {
461 if (pchmod(directory.c_str(), "0771") != 0)
462 return -1;
463 if (pchown(directory.c_str(), temp->uid, temp->gid) != 0)
464 return -1;
465 if (fixAllFiles(directory, temp->uid, temp->gid, "0600") != 0)
466 return -1;
467 }
468 else {
469 if (pchmod(directory.c_str(), "0771") != 0)
470 return -1;
471 if (pchown(directory.c_str(), temp->uid, temp->gid) != 0)
472 return -1;
473 if (fixAllFiles(directory, temp->uid, temp->gid, "0755") != 0)
474 return -1;
475 }
476 }
477 }
478 temp = temp->next;
479 }
480 return 0;
481}
482
483vector <string> fixPermissions::listAllDirectories(string path) {
484 DIR *dir = opendir(path.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400485 vector <string> dirs;
486
487 if (dir == NULL) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000488 LOGERR("Error opening '%s'\n", path.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400489 return dirs;
490 }
Dees_Troy201d76b2012-11-16 17:12:02 +0000491 struct dirent *entry = readdir(dir);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400492 while (entry != NULL) {
493 if (entry->d_type == DT_DIR)
494 dirs.push_back(entry->d_name);
495 entry = readdir(dir);
496 }
497 closedir(dir);
498 return dirs;
499}
500
501vector <string> fixPermissions::listAllFiles(string path) {
502 DIR *dir = opendir(path.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400503 vector <string> files;
504
505 if (dir == NULL) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000506 LOGERR("Error opening '%s'\n", path.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400507 return files;
508 }
Dees_Troy201d76b2012-11-16 17:12:02 +0000509 struct dirent *entry = readdir(dir);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400510 while (entry != NULL) {
511 if (entry->d_type == DT_REG)
512 files.push_back(entry->d_name);
513 entry = readdir(dir);
514 }
515 closedir(dir);
516 return files;
517}
518
519int fixPermissions::getPackages() {
520 int len = 0;
521 bool skiploop = false;
522 vector <string> skip;
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400523 string name;
524 head = NULL;
525
526 skip.push_back("/system/framework/framework-res.apk");
527 skip.push_back("/system/framework/com.htc.resources.apk");
528
529 ifstream xmlFile(packageFile.c_str());
530 xmlFile.seekg(0, ios::end);
531 len = (int) xmlFile.tellg();
532 xmlFile.seekg(0, ios::beg);
533 char xmlBuf[len + 1];
534 xmlFile.read(&xmlBuf[0], len);
535 xmlBuf[len] = '\0';
536 xml_document<> pkgDoc;
Dees_Troy34614eb2013-04-05 12:02:14 -0500537 LOGINFO("parsing package, %i...\n", len);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400538 pkgDoc.parse<parse_full>(&xmlBuf[0]);
539
540 xml_node<> * pkgNode = pkgDoc.first_node("packages");
Dees_Troy34614eb2013-04-05 12:02:14 -0500541 if (pkgNode == NULL) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000542 LOGERR("No packages found to fix.\n");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400543 return -1;
544 }
Dees_Troy34614eb2013-04-05 12:02:14 -0500545 xml_node <> * next = pkgNode->first_node("package");
546 if (next == NULL) {
547 LOGERR("No package found to fix.\n");
548 return -1;
549 }
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400550
551 //Get packages
552 while (next->first_attribute("name") != NULL) {
553 package* temp = new package;
554 for (unsigned n = 0; n < skip.size(); ++n) {
555 if (skip.at(n).compare(next->first_attribute("codePath")->value()) == 0) {
556 skiploop = true;
557 break;
558 }
559 }
560
561 if (skiploop == true) {
562 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000563 LOGINFO("Skipping package %s\n", next->first_attribute("codePath")->value());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400564 free(temp);
565 next = next->next_sibling();
566 skiploop = false;
567 continue;
568 }
569 name.append((next->first_attribute("name")->value()));
570 temp->pkgName = next->first_attribute("name")->value();
571 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000572 LOGINFO("Loading pkg: %s\n", next->first_attribute("name")->value());
Dees_Troy201d76b2012-11-16 17:12:02 +0000573 if (next->first_attribute("codePath") == NULL) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000574 LOGINFO("Problem with codePath on %s\n", next->first_attribute("name")->value());
Dees_Troy201d76b2012-11-16 17:12:02 +0000575 } else {
576 temp->codePath = next->first_attribute("codePath")->value();
577 temp->app = basename(next->first_attribute("codePath")->value());
578 temp->appDir = dirname(next->first_attribute("codePath")->value());
579 }
580 temp->dDir = name;
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400581 if ( next->first_attribute("sharedUserId") != NULL) {
582 temp->uid = atoi(next->first_attribute("sharedUserId")->value());
583 temp->gid = atoi(next->first_attribute("sharedUserId")->value());
584 }
585 else {
Dees_Troy201d76b2012-11-16 17:12:02 +0000586 if (next->first_attribute("userId") == NULL) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000587 LOGINFO("Problem with userID on %s\n", next->first_attribute("name")->value());
Dees_Troy201d76b2012-11-16 17:12:02 +0000588 } else {
589 temp->uid = atoi(next->first_attribute("userId")->value());
590 temp->gid = atoi(next->first_attribute("userId")->value());
591 }
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400592 }
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400593 temp->next = head;
594 head = temp;
Dees_Troy201d76b2012-11-16 17:12:02 +0000595 if (next->next_sibling("package") == NULL)
596 break;
597 name.clear();
598 next = next->next_sibling("package");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400599 }
600 //Get updated packages
601 next = pkgNode->first_node("updated-package");
602 if (next != NULL) {
603 while (next->first_attribute("name") != NULL) {
604 package* temp = new package;
605 for (unsigned n = 0; n < skip.size(); ++n) {
606 if (skip.at(n).compare(next->first_attribute("codePath")->value()) == 0) {
607 skiploop = true;
608 break;
609 }
610 }
611
612 if (skiploop == true) {
613 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000614 LOGINFO("Skipping package %s\n", next->first_attribute("codePath")->value());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400615 free(temp);
616 next = next->next_sibling();
617 skiploop = false;
618 continue;
619 }
620 name.append((next->first_attribute("name")->value()));
621 temp->pkgName = next->first_attribute("name")->value();
622 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000623 LOGINFO("Loading pkg: %s\n", next->first_attribute("name")->value());
Dees_Troy201d76b2012-11-16 17:12:02 +0000624 if (next->first_attribute("codePath") == NULL) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000625 LOGINFO("Problem with codePath on %s\n", next->first_attribute("name")->value());
Dees_Troy201d76b2012-11-16 17:12:02 +0000626 } else {
627 temp->codePath = next->first_attribute("codePath")->value();
628 temp->app = basename(next->first_attribute("codePath")->value());
629 temp->appDir = dirname(next->first_attribute("codePath")->value());
630 }
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400631
Dees_Troy201d76b2012-11-16 17:12:02 +0000632 temp->dDir = name;
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400633 if ( next->first_attribute("sharedUserId") != NULL) {
634 temp->uid = atoi(next->first_attribute("sharedUserId")->value());
635 temp->gid = atoi(next->first_attribute("sharedUserId")->value());
636 }
637 else {
Dees_Troy201d76b2012-11-16 17:12:02 +0000638 if (next->first_attribute("userId") == NULL) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000639 LOGINFO("Problem with userID on %s\n", next->first_attribute("name")->value());
Dees_Troy201d76b2012-11-16 17:12:02 +0000640 } else {
641 temp->uid = atoi(next->first_attribute("userId")->value());
642 temp->gid = atoi(next->first_attribute("userId")->value());
643 }
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400644 }
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400645 temp->next = head;
646 head = temp;
Dees_Troy201d76b2012-11-16 17:12:02 +0000647 if (next->next_sibling("package") == NULL)
648 break;
649 name.clear();
650 next = next->next_sibling("package");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400651 }
652 }
653 return 0;
654}