blob: 2fa1b66f2d01a8184d6bf90da643ac0fa3b52969 [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>
29#include "gui/rapidxml.hpp"
30#include "fixPermissions.hpp"
31#include "twrp-functions.hpp"
Dees_Troy2673cec2013-04-02 20:22:16 +000032#include "twcommon.h"
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -040033
34using namespace std;
35using namespace rapidxml;
36
37int fixPermissions::fixPerms(bool enable_debug, bool remove_data_for_missing_apps) {
38 packageFile = "/data/system/packages.xml";
39 debug = enable_debug;
40 remove_data = remove_data_for_missing_apps;
Dees_Troy201d76b2012-11-16 17:12:02 +000041 multi_user = TWFunc::Path_Exists("/data/user");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -040042
43 if (!(TWFunc::Path_Exists(packageFile))) {
Dees_Troy2673cec2013-04-02 20:22:16 +000044 gui_print("Can't check permissions\n");
45 gui_print("after Factory Reset.\n");
46 gui_print("Please boot rom and try\n");
47 gui_print("again after you reboot into\n");
48 gui_print("recovery.\n");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -040049 return -1;
50 }
51
Dees_Troy2673cec2013-04-02 20:22:16 +000052 gui_print("Fixing permissions...\nLoading packages...\n");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -040053 if ((getPackages()) != 0) {
54 return -1;
55 }
Dees_Troy32f2ca82013-02-02 17:03:12 +000056
Dees_Troy2673cec2013-04-02 20:22:16 +000057 gui_print("Fixing /system/app permissions...\n");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -040058 if ((fixSystemApps()) != 0) {
59 return -1;
60 }
61
grimsrudcbec59f2013-07-29 15:46:22 +020062 gui_print("Fixing /data/app permissions...\n");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -040063 if ((fixDataApps()) != 0) {
64 return -1;
65 }
66
Dees_Troy201d76b2012-11-16 17:12:02 +000067 if (multi_user) {
68 DIR *d = opendir("/data/user");
69 string new_path, user_id;
70
71 if (d == NULL) {
Dees_Troy2673cec2013-04-02 20:22:16 +000072 LOGERR("Error opening '/data/user'\n");
Dees_Troy201d76b2012-11-16 17:12:02 +000073 return -1;
74 }
75
76 if (d) {
77 struct dirent *p;
78 while ((p = readdir(d))) {
79 if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, ".."))
80 continue;
81
82 new_path = "/data/user/";
83 new_path.append(p->d_name);
84 user_id = "u";
85 user_id += p->d_name;
86 user_id += "_";
87 if (p->d_type == DT_LNK) {
88 char link[512], realPath[512];
89 strcpy(link, new_path.c_str());
90 memset(realPath, 0, sizeof(realPath));
91 while (readlink(link, realPath, sizeof(realPath)) > 0) {
92 strcpy(link, realPath);
93 memset(realPath, 0, sizeof(realPath));
94 }
95 new_path = link;
96 } else if (p->d_type != DT_DIR) {
97 continue;
98 } else {
99 new_path.append("/");
100 // We're probably going to need to fix permissions on multi user but
101 // it will have to wait for another time. Need to figure out where
102 // the uid and gid is stored for other users.
103 continue;
104 }
Dees_Troy2673cec2013-04-02 20:22:16 +0000105 gui_print("Fixing %s permissions...\n", new_path.c_str());
Dees_Troy201d76b2012-11-16 17:12:02 +0000106 if ((fixDataData(new_path)) != 0) {
107 closedir(d);
108 return -1;
109 }
110 }
111 closedir(d);
112 }
113 } else {
grimsrudcbec59f2013-07-29 15:46:22 +0200114 gui_print("Fixing /data/data permissions...\n");
Dees_Troy201d76b2012-11-16 17:12:02 +0000115 if ((fixDataData("/data/data/")) != 0) {
116 return -1;
117 }
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400118 }
Dees_Troy2673cec2013-04-02 20:22:16 +0000119 gui_print("Done fixing permissions.\n");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400120 return 0;
121}
122
123int fixPermissions::pchown(string fn, int puid, int pgid) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000124 LOGINFO("Fixing %s, uid: %d, gid: %d\n", fn.c_str(), puid, pgid);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400125 if (chown(fn.c_str(), puid, pgid) != 0) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000126 LOGERR("Unable to chown '%s' %i %i\n", fn.c_str(), puid, pgid);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400127 return -1;
128 }
129 return 0;
130}
131
132int fixPermissions::pchmod(string fn, string mode) {
133 long mask = 0;
Dees_Troy2673cec2013-04-02 20:22:16 +0000134 LOGINFO("Fixing %s, mode: %s\n", fn.c_str(), mode.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400135 for ( std::string::size_type n = 0; n < mode.length(); ++n) {
136 if (n == 0) {
137 if (mode[n] == '0')
138 continue;
139 else if (mode[n] == '1')
140 mask = S_ISVTX;
141 else if (mode[n] == '2')
142 mask = S_ISGID;
143 }
144 else if (n == 1) {
145 if (mode[n] == '7') {
146 mask |= S_IRWXU;
147 }
148 if (mode[n] == '6') {
149 mask |= S_IRUSR;
150 mask |= S_IWUSR;
151 }
152 if (mode[n] == '5') {
153 mask |= S_IRUSR;
154 mask |= S_IXUSR;
155 }
156 if (mode[n] == '4')
157 mask |= S_IRUSR;
158 if (mode[n] == '3') {
159 mask |= S_IWUSR;
160 mask |= S_IRUSR;
161 }
162 if (mode[n] == '2')
163 mask |= S_IWUSR;
164 if (mode[n] == '1')
165 mask |= S_IXUSR;
166 }
167 else if (n == 2) {
168 if (mode[n] == '7') {
169 mask |= S_IRWXG;
170 }
171 if (mode[n] == '6') {
172 mask |= S_IRGRP;
173 mask |= S_IWGRP;
174 }
175 if (mode[n] == '5') {
176 mask |= S_IRGRP;
177 mask |= S_IXGRP;
178 }
179 if (mode[n] == '4')
180 mask |= S_IRGRP;
181 if (mode[n] == '3') {
182 mask |= S_IWGRP;
183 mask |= S_IXGRP;
184 }
185 if (mode[n] == '2')
186 mask |= S_IWGRP;
187 if (mode[n] == '1')
188 mask |= S_IXGRP;
189 }
190 else if (n == 3) {
191 if (mode[n] == '7') {
192 mask |= S_IRWXO;
193 }
194 if (mode[n] == '6') {
195 mask |= S_IROTH;
196 mask |= S_IWOTH;
197 }
198 if (mode[n] == '5') {
199 mask |= S_IROTH;
200 mask |= S_IXOTH;
201 }
202 if (mode[n] == '4')
203 mask |= S_IROTH;
204 if (mode[n] == '3') {
205 mask |= S_IWOTH;
206 mask |= S_IXOTH;
207 }
208 if (mode[n] == '2')
Dees_Troy6480ce02012-10-10 10:26:54 -0400209 mask |= S_IWOTH;
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400210 if (mode[n] == '1')
Dees_Troy6480ce02012-10-10 10:26:54 -0400211 mask |= S_IXOTH;
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400212 }
213 }
214
215 if (chmod(fn.c_str(), mask) != 0) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000216 LOGERR("Unable to chmod '%s' %l\n", fn.c_str(), mask);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400217 return -1;
218 }
219
220 return 0;
221}
222
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400223int fixPermissions::fixSystemApps() {
224 temp = head;
225 while (temp != NULL) {
226 if (TWFunc::Path_Exists(temp->codePath)) {
227 if (temp->appDir.compare("/system/app") == 0) {
228 if (debug) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000229 LOGINFO("Looking at '%s'\n", temp->codePath.c_str());
230 LOGINFO("Fixing permissions on '%s'\n", temp->pkgName.c_str());
231 LOGINFO("Directory: '%s'\n", temp->appDir.c_str());
232 LOGINFO("Original package owner: %d, group: %d\n", temp->uid, temp->gid);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400233 }
234 if (pchown(temp->codePath, 0, 0) != 0)
235 return -1;
236 if (pchmod(temp->codePath, "0644") != 0)
237 return -1;
238 }
239 } else {
240 //Remove data directory since app isn't installed
241 if (remove_data && TWFunc::Path_Exists(temp->dDir) && temp->appDir.size() >= 9 && temp->appDir.substr(0, 9) != "/mnt/asec") {
242 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000243 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 -0500244 if (TWFunc::removeDir(temp->dDir, false) != 0) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000245 LOGINFO("Unable to removeDir '%s'\n", temp->dDir.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400246 return -1;
247 }
248 }
249 }
250 temp = temp->next;
251 }
252 return 0;
253}
254
255int fixPermissions::fixDataApps() {
256 bool fix = false;
257 int new_gid = 0;
258 string perms = "0000";
259
260 temp = head;
261 while (temp != NULL) {
262 if (TWFunc::Path_Exists(temp->codePath)) {
263 if (temp->appDir.compare("/data/app") == 0 || temp->appDir.compare("/sd-ext/app") == 0) {
264 fix = true;
265 new_gid = 1000;
266 perms = "0644";
267 } else if (temp->appDir.compare("/data/app-private") == 0 || temp->appDir.compare("/sd-ext/app-private") == 0) {
268 fix = true;
269 new_gid = temp->gid;
270 perms = "0640";
271 } else
272 fix = false;
273 if (fix) {
274 if (debug) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000275 LOGINFO("Looking at '%s'\n", temp->codePath.c_str());
276 LOGINFO("Fixing permissions on '%s'\n", temp->pkgName.c_str());
277 LOGINFO("Directory: '%s'\n", temp->appDir.c_str());
278 LOGINFO("Original package owner: %d, group: %d\n", temp->uid, temp->gid);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400279 }
280 if (pchown(temp->codePath, 1000, new_gid) != 0)
281 return -1;
282 if (pchmod(temp->codePath, perms) != 0)
283 return -1;
284 }
285 } else {
286 //Remove data directory since app isn't installed
287 if (remove_data && TWFunc::Path_Exists(temp->dDir) && temp->appDir.size() >= 9 && temp->appDir.substr(0, 9) != "/mnt/asec") {
288 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000289 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 -0500290 if (TWFunc::removeDir(temp->dDir, false) != 0) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000291 LOGINFO("Unable to removeDir '%s'\n", temp->dDir.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400292 return -1;
293 }
294 }
295 }
296 temp = temp->next;
297 }
298 return 0;
299}
300
301int fixPermissions::fixAllFiles(string directory, int gid, int uid, string file_perms) {
302 vector <string> files;
303 string file;
304
305 files = listAllFiles(directory);
306 for (unsigned i = 0; i < files.size(); ++i) {
307 file = directory + "/";
308 file.append(files.at(i));
309 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000310 LOGINFO("Looking at file '%s'\n", file.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400311 if (pchmod(file, file_perms) != 0)
312 return -1;
313 if (pchown(file, uid, gid) != 0)
314 return -1;
315 }
316 return 0;
317}
318
Dees_Troy201d76b2012-11-16 17:12:02 +0000319int fixPermissions::fixDataData(string dataDir) {
320 string directory, dir;
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400321
322 temp = head;
323 while (temp != NULL) {
Dees_Troy201d76b2012-11-16 17:12:02 +0000324 dir = dataDir + temp->dDir;
325 if (TWFunc::Path_Exists(dir)) {
326 vector <string> dataDataDirs = listAllDirectories(dir);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400327 for (unsigned n = 0; n < dataDataDirs.size(); ++n) {
Dees_Troy201d76b2012-11-16 17:12:02 +0000328 directory = dir + "/";
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400329 directory.append(dataDataDirs.at(n));
330 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000331 LOGINFO("Looking at data directory: '%s'\n", directory.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400332 if (dataDataDirs.at(n) == ".") {
Dees_Troy201d76b2012-11-16 17:12:02 +0000333 if (pchmod(directory, "0755") != 0)
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400334 return -1;
335 if (pchown(directory.c_str(), temp->uid, temp->gid) != 0)
336 return -1;
337 if (fixAllFiles(directory, temp->uid, temp->gid, "0755") != 0)
338 return -1;
339 }
340 else if (dataDataDirs.at(n) == "..") {
341 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000342 LOGINFO("Skipping ..\n");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400343 continue;
344 }
345 else if (dataDataDirs.at(n) == "lib") {
346 if (pchmod(directory.c_str(), "0755") != 0)
347 return -1;
348 if (pchown(directory.c_str(), 1000, 1000) != 0)
349 return -1;
350 if (fixAllFiles(directory, temp->uid, temp->gid, "0755") != 0)
351 return -1;
352 }
353 else if (dataDataDirs.at(n) == "shared_prefs") {
354 if (pchmod(directory.c_str(), "0771") != 0)
355 return -1;
356 if (pchown(directory.c_str(), temp->uid, temp->gid) != 0)
357 return -1;
358 if (fixAllFiles(directory, temp->uid, temp->gid, "0660") != 0)
359 return -1;
360 }
361 else if (dataDataDirs.at(n) == "databases") {
362 if (pchmod(directory.c_str(), "0771") != 0)
363 return -1;
364 if (pchown(directory.c_str(), temp->uid, temp->gid) != 0)
365 return -1;
366 if (fixAllFiles(directory, temp->uid, temp->gid, "0660") != 0)
367 return -1;
368 }
369 else if (dataDataDirs.at(n) == "cache") {
370 if (pchmod(directory.c_str(), "0771") != 0)
371 return -1;
372 if (pchown(directory.c_str(), temp->uid, temp->gid) != 0)
373 return -1;
374 if (fixAllFiles(directory, temp->uid, temp->gid, "0600") != 0)
375 return -1;
376 }
377 else {
378 if (pchmod(directory.c_str(), "0771") != 0)
379 return -1;
380 if (pchown(directory.c_str(), temp->uid, temp->gid) != 0)
381 return -1;
382 if (fixAllFiles(directory, temp->uid, temp->gid, "0755") != 0)
383 return -1;
384 }
385 }
386 }
387 temp = temp->next;
388 }
389 return 0;
390}
391
392vector <string> fixPermissions::listAllDirectories(string path) {
393 DIR *dir = opendir(path.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400394 vector <string> dirs;
395
396 if (dir == NULL) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000397 LOGERR("Error opening '%s'\n", path.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400398 return dirs;
399 }
Dees_Troy201d76b2012-11-16 17:12:02 +0000400 struct dirent *entry = readdir(dir);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400401 while (entry != NULL) {
402 if (entry->d_type == DT_DIR)
403 dirs.push_back(entry->d_name);
404 entry = readdir(dir);
405 }
406 closedir(dir);
407 return dirs;
408}
409
410vector <string> fixPermissions::listAllFiles(string path) {
411 DIR *dir = opendir(path.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400412 vector <string> files;
413
414 if (dir == NULL) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000415 LOGERR("Error opening '%s'\n", path.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400416 return files;
417 }
Dees_Troy201d76b2012-11-16 17:12:02 +0000418 struct dirent *entry = readdir(dir);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400419 while (entry != NULL) {
420 if (entry->d_type == DT_REG)
421 files.push_back(entry->d_name);
422 entry = readdir(dir);
423 }
424 closedir(dir);
425 return files;
426}
427
428int fixPermissions::getPackages() {
429 int len = 0;
430 bool skiploop = false;
431 vector <string> skip;
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400432 string name;
433 head = NULL;
434
435 skip.push_back("/system/framework/framework-res.apk");
436 skip.push_back("/system/framework/com.htc.resources.apk");
437
438 ifstream xmlFile(packageFile.c_str());
439 xmlFile.seekg(0, ios::end);
440 len = (int) xmlFile.tellg();
441 xmlFile.seekg(0, ios::beg);
442 char xmlBuf[len + 1];
443 xmlFile.read(&xmlBuf[0], len);
444 xmlBuf[len] = '\0';
445 xml_document<> pkgDoc;
Dees_Troy34614eb2013-04-05 12:02:14 -0500446 LOGINFO("parsing package, %i...\n", len);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400447 pkgDoc.parse<parse_full>(&xmlBuf[0]);
448
449 xml_node<> * pkgNode = pkgDoc.first_node("packages");
Dees_Troy34614eb2013-04-05 12:02:14 -0500450 if (pkgNode == NULL) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000451 LOGERR("No packages found to fix.\n");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400452 return -1;
453 }
Dees_Troy34614eb2013-04-05 12:02:14 -0500454 xml_node <> * next = pkgNode->first_node("package");
455 if (next == NULL) {
456 LOGERR("No package found to fix.\n");
457 return -1;
458 }
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400459
460 //Get packages
461 while (next->first_attribute("name") != NULL) {
462 package* temp = new package;
463 for (unsigned n = 0; n < skip.size(); ++n) {
464 if (skip.at(n).compare(next->first_attribute("codePath")->value()) == 0) {
465 skiploop = true;
466 break;
467 }
468 }
469
470 if (skiploop == true) {
471 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000472 LOGINFO("Skipping package %s\n", next->first_attribute("codePath")->value());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400473 free(temp);
474 next = next->next_sibling();
475 skiploop = false;
476 continue;
477 }
478 name.append((next->first_attribute("name")->value()));
479 temp->pkgName = next->first_attribute("name")->value();
480 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000481 LOGINFO("Loading pkg: %s\n", next->first_attribute("name")->value());
Dees_Troy201d76b2012-11-16 17:12:02 +0000482 if (next->first_attribute("codePath") == NULL) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000483 LOGINFO("Problem with codePath on %s\n", next->first_attribute("name")->value());
Dees_Troy201d76b2012-11-16 17:12:02 +0000484 } else {
485 temp->codePath = next->first_attribute("codePath")->value();
486 temp->app = basename(next->first_attribute("codePath")->value());
487 temp->appDir = dirname(next->first_attribute("codePath")->value());
488 }
489 temp->dDir = name;
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400490 if ( next->first_attribute("sharedUserId") != NULL) {
491 temp->uid = atoi(next->first_attribute("sharedUserId")->value());
492 temp->gid = atoi(next->first_attribute("sharedUserId")->value());
493 }
494 else {
Dees_Troy201d76b2012-11-16 17:12:02 +0000495 if (next->first_attribute("userId") == NULL) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000496 LOGINFO("Problem with userID on %s\n", next->first_attribute("name")->value());
Dees_Troy201d76b2012-11-16 17:12:02 +0000497 } else {
498 temp->uid = atoi(next->first_attribute("userId")->value());
499 temp->gid = atoi(next->first_attribute("userId")->value());
500 }
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400501 }
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400502 temp->next = head;
503 head = temp;
Dees_Troy201d76b2012-11-16 17:12:02 +0000504 if (next->next_sibling("package") == NULL)
505 break;
506 name.clear();
507 next = next->next_sibling("package");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400508 }
509 //Get updated packages
510 next = pkgNode->first_node("updated-package");
511 if (next != NULL) {
512 while (next->first_attribute("name") != NULL) {
513 package* temp = new package;
514 for (unsigned n = 0; n < skip.size(); ++n) {
515 if (skip.at(n).compare(next->first_attribute("codePath")->value()) == 0) {
516 skiploop = true;
517 break;
518 }
519 }
520
521 if (skiploop == true) {
522 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000523 LOGINFO("Skipping package %s\n", next->first_attribute("codePath")->value());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400524 free(temp);
525 next = next->next_sibling();
526 skiploop = false;
527 continue;
528 }
529 name.append((next->first_attribute("name")->value()));
530 temp->pkgName = next->first_attribute("name")->value();
531 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000532 LOGINFO("Loading pkg: %s\n", next->first_attribute("name")->value());
Dees_Troy201d76b2012-11-16 17:12:02 +0000533 if (next->first_attribute("codePath") == NULL) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000534 LOGINFO("Problem with codePath on %s\n", next->first_attribute("name")->value());
Dees_Troy201d76b2012-11-16 17:12:02 +0000535 } else {
536 temp->codePath = next->first_attribute("codePath")->value();
537 temp->app = basename(next->first_attribute("codePath")->value());
538 temp->appDir = dirname(next->first_attribute("codePath")->value());
539 }
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400540
Dees_Troy201d76b2012-11-16 17:12:02 +0000541 temp->dDir = name;
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400542 if ( next->first_attribute("sharedUserId") != NULL) {
543 temp->uid = atoi(next->first_attribute("sharedUserId")->value());
544 temp->gid = atoi(next->first_attribute("sharedUserId")->value());
545 }
546 else {
Dees_Troy201d76b2012-11-16 17:12:02 +0000547 if (next->first_attribute("userId") == NULL) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000548 LOGINFO("Problem with userID on %s\n", next->first_attribute("name")->value());
Dees_Troy201d76b2012-11-16 17:12:02 +0000549 } else {
550 temp->uid = atoi(next->first_attribute("userId")->value());
551 temp->gid = atoi(next->first_attribute("userId")->value());
552 }
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400553 }
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400554 temp->next = head;
555 head = temp;
Dees_Troy201d76b2012-11-16 17:12:02 +0000556 if (next->next_sibling("package") == NULL)
557 break;
558 name.clear();
559 next = next->next_sibling("package");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400560 }
561 }
562 return 0;
563}