1 /*
2 * Copyright (c) 2020 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "bundle_util.h"
17
18 #include <new>
19
20 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
21 #include <dirent.h>
22 #include <fcntl.h>
23 #include <stdio.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <time.h>
27 #include <unistd.h>
28 #include "bundle_daemon_client.h"
29 #else
30 #include "adapter.h"
31 #include "bundlems_log.h"
32 #include "cstdio"
33 #include "dirent.h"
34 #include "fcntl.h"
35 #include "los_tick.h"
36 #include "sys/stat.h"
37 #include "unistd.h"
38 #endif
39 #include <cstdlib>
40 #include "utils.h"
41
42 namespace OHOS {
43 const char DIGITSTR[] = "0123456789";
44 const uint8_t MAX_CHARACTER_VALUE = 26;
45 const uint8_t NUM_OF_TYPE = 3;
46 #ifdef __LITEOS_M__
47 const int32_t MAX_JSON_SIZE = 1024 * 64;
48 #else
49 const uint32_t MAX_JSON_SIZE = 1024 * 64;
50 #endif
51
52 /*
53 * path should not include ".." or "./" or ".\0"
54 */
CheckRealPath(const char * path)55 bool BundleUtil::CheckRealPath(const char *path)
56 {
57 if (path == nullptr) {
58 #ifdef APP_PLATFORM_WATCHGT
59 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] CheckRealPath path null");
60 #endif
61 return false;
62 }
63 if (strlen(path) > PATH_LENGTH) {
64 #ifdef APP_PLATFORM_WATCHGT
65 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] CheckRealPath path too long:%d", strlen(path));
66 #endif
67 return false;
68 }
69 char *next = const_cast<char *>(path);
70 for (; *next != '\0'; next++) {
71 if (*next != '.') {
72 continue;
73 }
74 next++;
75 if (*next == '\0' || *next == '.' || *next == '/') {
76 #ifdef APP_PLATFORM_WATCHGT
77 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] CheckRealPath path fail:%d", *next);
78 #endif
79 return false;
80 }
81 }
82 return true;
83 }
84
IsFile(const char * path)85 bool BundleUtil::IsFile(const char *path)
86 {
87 if (!CheckRealPath(path)) {
88 return false;
89 }
90
91 struct stat buf = { 0 };
92 int32_t ret = stat(path, &buf);
93 if (ret != 0) {
94 return false;
95 }
96
97 int32_t fp = open(path, O_RDONLY, S_IREAD | S_IWRITE);
98 if (fp >= 0) {
99 close(fp);
100 return true;
101 }
102 return false;
103 }
104
IsDir(const char * path)105 bool BundleUtil::IsDir(const char *path)
106 {
107 if (path == nullptr) {
108 return false;
109 }
110
111 struct stat buf = { 0 };
112 int32_t ret = stat(path, &buf);
113 if (ret != 0) {
114 return false;
115 }
116
117 if ((buf.st_mode & S_IFDIR) == S_IFDIR) {
118 return true;
119 }
120 return false;
121 }
122
EndWith(const char * str,const char * subStr)123 bool BundleUtil::EndWith(const char *str, const char *subStr)
124 {
125 if (str == nullptr || subStr == nullptr) {
126 return false;
127 }
128
129 int32_t strLen = strlen(str);
130 int32_t subStrLen = strlen(subStr);
131 if (strLen == 0 || subStrLen == 0 || strLen < subStrLen) {
132 return false;
133 }
134
135 while (subStrLen >= 1) {
136 if (str[strLen - 1] != subStr[subStrLen - 1]) {
137 return false;
138 }
139 strLen--;
140 subStrLen--;
141 }
142 return true;
143 }
144
StartWith(const char * str,const char * subStr)145 bool BundleUtil::StartWith(const char *str, const char *subStr)
146 {
147 if (str == nullptr || subStr == nullptr) {
148 return false;
149 }
150
151 int32_t strLen = strlen(str);
152 int32_t subStrLen = strlen(subStr);
153 if (strLen == 0 || subStrLen == 0 || strLen < subStrLen) {
154 return false;
155 }
156
157 int32_t index = 0;
158 while (index < subStrLen) {
159 if (str[index] != subStr[index]) {
160 return false;
161 }
162 index++;
163 }
164 return true;
165 }
166
IsDigitStr(const char * str)167 bool BundleUtil::IsDigitStr(const char *str)
168 {
169 if (str == nullptr) {
170 return false;
171 }
172 return strspn(str, DIGITSTR) == strlen(str);
173 }
174
GetFileSize(const char * filePath)175 uint32_t BundleUtil::GetFileSize(const char *filePath)
176 {
177 if (!CheckRealPath(filePath)) {
178 return 0;
179 }
180
181 struct stat fileInfo;
182 int32_t ret = stat(filePath, &fileInfo);
183 if (ret != 0) {
184 return 0;
185 }
186 return fileInfo.st_size;
187 }
188
GetFileFolderSize(const char * filePath)189 uint32_t BundleUtil::GetFileFolderSize(const char *filePath)
190 {
191 if (!CheckRealPath(filePath)) {
192 return 0;
193 }
194 List<char *>* list = new (std::nothrow)List<char *>();
195 if (list == nullptr) {
196 #ifdef APP_PLATFORM_WATCHGT
197 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] GetFolderSize failed, list is null");
198 #endif
199 return 0;
200 }
201
202 list->PushFront(Utils::Strdup(filePath));
203 uint32_t fileFolderSize = 0;
204 while (!list->IsEmpty()) {
205 char *curPath = list->Front();
206 if (curPath == nullptr) {
207 break;
208 }
209 fileFolderSize += GetCurrentFolderSize(curPath, list);
210 list->PopFront();
211 AdapterFree(curPath);
212 }
213
214 if (!list->IsEmpty()) {
215 #ifdef APP_PLATFORM_WATCHGT
216 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] After get folder size, list is still not empty");
217 #endif
218 for (auto node = list->Begin(); node != list->End(); node = node->next_) {
219 AdapterFree(node->value_);
220 }
221 }
222 delete list;
223 return fileFolderSize;
224 }
225
GetCurrentFolderSize(const char * dirPath,List<char * > * list)226 uint32_t BundleUtil::GetCurrentFolderSize(const char *dirPath, List<char *>* list)
227 {
228 DIR *dir = nullptr;
229 if ((dir = opendir(dirPath)) == nullptr) {
230 return 0;
231 }
232 dirent *dp = nullptr;
233 char filePath[PATH_LENGTH] = { 0 };
234 struct stat buf = { 0 };
235 uint32_t fileSize = 0;
236 while ((dp = readdir(dir)) != nullptr) {
237 if ((strcmp(dp->d_name, ".") == 0) || (strcmp(dp->d_name, "..")) == 0) {
238 continue;
239 }
240
241 if (memset_s(filePath, PATH_LENGTH, 0, PATH_LENGTH) != EOK) {
242 continue;
243 }
244
245 if (sprintf_s(filePath, PATH_LENGTH, "%s/%s", dirPath, dp->d_name) < 0) {
246 continue;
247 }
248
249 if (!IsDir(filePath)) {
250 if (stat(filePath, &buf) != 0 || buf.st_size <= 0) {
251 fileSize = 0;
252 break;
253 }
254 fileSize += buf.st_size;
255 } else {
256 list->PushBack(Utils::Strdup(filePath));
257 }
258 }
259 closedir(dir);
260 return fileSize;
261 }
262
DeleteJsonFile(const char * bundleName,const char * randStr)263 void BundleUtil::DeleteJsonFile(const char *bundleName, const char *randStr)
264 {
265 if (bundleName == nullptr || randStr == nullptr) {
266 return;
267 }
268 char *bundleTmpJsonPathComp[] = {
269 const_cast<char *>(JSON_PATH), const_cast<char *>(bundleName), const_cast<char *>(randStr),
270 const_cast<char *>(JSON_SUFFIX)
271 };
272
273 char *bundleTmpJsonPath = Strscat(bundleTmpJsonPathComp, sizeof(bundleTmpJsonPathComp) / sizeof(char *));
274 if (bundleTmpJsonPath == nullptr) {
275 return;
276 }
277
278 if (IsFile(bundleTmpJsonPath)) {
279 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
280 BundleDaemonClient::GetInstance().RemoveFile(bundleTmpJsonPath);
281 #else
282 (void)unlink(bundleTmpJsonPath);
283 #endif
284 AdapterFree(bundleTmpJsonPath);
285 return;
286 }
287 AdapterFree(bundleTmpJsonPath);
288
289 char *bundleJsonPathComp[] = {
290 const_cast<char *>(JSON_PATH), const_cast<char *>(bundleName), const_cast<char *>(JSON_SUFFIX)
291 };
292 char *bundleJsonPath = Strscat(bundleJsonPathComp, sizeof(bundleJsonPathComp) / sizeof(char *));
293 if (bundleJsonPath == nullptr) {
294 return;
295 }
296 if (IsFile(bundleJsonPath)) {
297 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
298 BundleDaemonClient::GetInstance().RemoveFile(bundleJsonPath);
299 #else
300 (void)unlink(bundleJsonPath);
301 #endif
302 }
303 AdapterFree(bundleJsonPath);
304 }
305
Strscat(char * str[],uint32_t len)306 char *BundleUtil::Strscat(char *str[], uint32_t len)
307 {
308 int32_t strSize = 0;
309 for (uint32_t i = 0; i < len; i++) {
310 if (str[i] == nullptr) {
311 return nullptr;
312 }
313 strSize += strlen(str[i]);
314 }
315
316 char *outStr = reinterpret_cast<char *>(AdapterMalloc((strSize + 1) * sizeof(char)));
317 if (outStr == nullptr) {
318 return nullptr;
319 }
320
321 char *pos = outStr;
322 int32_t count = 0;
323 for (uint32_t i = 0; i < len; i++) {
324 int32_t size = strlen(str[i]);
325 if (memcpy_s(pos, strSize + 1 - count, str[i], size) != EOK) {
326 AdapterFree(outStr);
327 return nullptr;
328 }
329 count += size;
330 pos += size;
331 }
332 *pos = '\0';
333 return outStr;
334 }
335
GetJsonStream(const char * path)336 cJSON *BundleUtil::GetJsonStream(const char *path)
337 {
338 struct stat fileInfo;
339 int32_t size = 0;
340
341 if (!IsFile(path)) {
342 #ifdef APP_PLATFORM_WATCHGT
343 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] GetJsonStream IsFile fail");
344 #endif
345 return nullptr;
346 }
347
348 if (stat(path, &fileInfo) != 0 || (size = fileInfo.st_size) <= 0) {
349 #ifdef APP_PLATFORM_WATCHGT
350 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] GetJsonStream path fail");
351 #endif
352 return nullptr;
353 }
354
355 if (size > MAX_JSON_SIZE) {
356 #ifdef APP_PLATFORM_WATCHGT
357 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] GetJsonStream size fail:%d", size);
358 #endif
359 return nullptr;
360 }
361
362 int32_t fp = open(path, O_RDONLY, S_IREAD | S_IWRITE);
363 if (fp < 0) {
364 #ifdef APP_PLATFORM_WATCHGT
365 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] GetJsonStream open fail:%d", fp);
366 #endif
367 return nullptr;
368 }
369
370 char *json = reinterpret_cast<char *>(AdapterMalloc(size));
371 if (json == nullptr) {
372 close(fp);
373 #ifdef APP_PLATFORM_WATCHGT
374 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] GetJsonStream AdapterMalloc fail");
375 #endif
376 return nullptr;
377 }
378
379 if (read(fp, json, size) != size) {
380 AdapterFree(json);
381 close(fp);
382 #ifdef APP_PLATFORM_WATCHGT
383 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] GetJsonStream read fail");
384 #endif
385 return nullptr;
386 }
387 close(fp);
388
389 cJSON *root = cJSON_Parse(json);
390 AdapterFree(json);
391 json = nullptr;
392 if (root == nullptr) {
393 #ifdef APP_PLATFORM_WATCHGT
394 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] cJSON_Parse fail");
395 #endif
396 }
397 return root;
398 }
399
CheckBundleJsonIsValid(const char * bundleName,char ** codePath,char ** appId,int32_t & versionCode)400 bool BundleUtil::CheckBundleJsonIsValid(const char *bundleName, char **codePath, char **appId, int32_t &versionCode)
401 {
402 if (bundleName == nullptr || codePath == nullptr || appId == nullptr) {
403 #ifdef APP_PLATFORM_WATCHGT
404 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] CheckBundleJsonIsValid parameters are not valid");
405 #endif
406 return false;
407 }
408
409 char bundleJsonPath[PATH_LENGTH] = { 0 };
410 if (sprintf_s(bundleJsonPath, PATH_LENGTH, "%s%s%s", JSON_PATH, bundleName, JSON_SUFFIX) < 0) {
411 #ifdef APP_PLATFORM_WATCHGT
412 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] failed to organize bundleJson data file path");
413 #endif
414 return false;
415 }
416
417 cJSON *object = GetJsonStream(bundleJsonPath);
418 if (object == nullptr) {
419 #ifdef APP_PLATFORM_WATCHGT
420 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] failed to open json file");
421 #endif
422 return false;
423 }
424
425 cJSON *item = cJSON_GetObjectItem(object, JSON_SUB_KEY_CODEPATH);
426 if (!cJSON_IsString(item)) {
427 cJSON_Delete(object);
428 #ifdef APP_PLATFORM_WATCHGT
429 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] result of parsing codePath is not a string");
430 #endif
431 return false;
432 }
433 *codePath = Utils::Strdup(item->valuestring);
434 if (*codePath == nullptr) {
435 cJSON_Delete(object);
436 #ifdef APP_PLATFORM_WATCHGT
437 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] parsed codePath is nullptr");
438 #endif
439 return false;
440 }
441 if (!IsDir(*codePath)) {
442 cJSON_Delete(object);
443 #ifdef APP_PLATFORM_WATCHGT
444 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] parsed codePath is not dir");
445 #endif
446 return false;
447 }
448 if (!EndWith(*codePath, bundleName)) {
449 cJSON_Delete(object);
450 #ifdef APP_PLATFORM_WATCHGT
451 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] parsed codePath is not valid");
452 #endif
453 return false;
454 }
455
456 item = cJSON_GetObjectItem(object, JSON_SUB_KEY_APPID);
457 if (!cJSON_IsString(item)) {
458 cJSON_Delete(object);
459 #ifdef APP_PLATFORM_WATCHGT
460 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] result of parsinng appId is not a string");
461 #endif
462 return false;
463 }
464 *appId = Utils::Strdup(item->valuestring);
465 if (*appId == nullptr) {
466 cJSON_Delete(object);
467 #ifdef APP_PLATFORM_WATCHGT
468 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] parsed appId is null");
469 #endif
470 return false;
471 }
472
473 item = cJSON_GetObjectItem(object, JSON_SUB_KEY_VERSIONCODE);
474 if (!cJSON_IsNumber(item)) {
475 cJSON_Delete(object);
476 #ifdef APP_PLATFORM_WATCHGT
477 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] result of parsinng versionCode is not a string");
478 #endif
479 return false;
480 }
481 versionCode = item->valueint;
482 if (versionCode < 0) {
483 cJSON_Delete(object);
484 #ifdef APP_PLATFORM_WATCHGT
485 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] parsed versionCode is not valid");
486 #endif
487 return false;
488 }
489
490 cJSON_Delete(object);
491 return true;
492 }
493
GetValueFromBundleJson(const char * bundleName,const char * key)494 char *BundleUtil::GetValueFromBundleJson(const char *bundleName, const char *key)
495 {
496 if (bundleName == nullptr || key == nullptr) {
497 return nullptr;
498 }
499
500 char bundleJsonPath[PATH_LENGTH] = { 0 };
501 if (sprintf_s(bundleJsonPath, PATH_LENGTH, "%s%s%s", JSON_PATH, bundleName, JSON_SUFFIX) < 0) {
502 return nullptr;
503 }
504
505 cJSON *object = GetJsonStream(bundleJsonPath);
506 if (object == nullptr) {
507 return nullptr;
508 }
509
510 cJSON *item = cJSON_GetObjectItem(object, key);
511 if (!cJSON_IsString(item)) {
512 cJSON_Delete(object);
513 return nullptr;
514 }
515
516 char *value = Utils::Strdup(item->valuestring);
517 cJSON_Delete(object);
518 return value;
519 }
520
GetValueFromBundleJson(const char * bundleName,const char * key,int32_t defaultValue)521 int32_t BundleUtil::GetValueFromBundleJson(const char *bundleName, const char *key, int32_t defaultValue)
522 {
523 if (bundleName == nullptr || key == nullptr) {
524 return defaultValue;
525 }
526
527 char bundleJsonPath[PATH_LENGTH] = { 0 };
528 if (sprintf_s(bundleJsonPath, PATH_LENGTH, "%s%s%s", JSON_PATH, bundleName, JSON_SUFFIX) < 0) {
529 return defaultValue;
530 }
531
532 cJSON *object = GetJsonStream(bundleJsonPath);
533 if (object == nullptr) {
534 return defaultValue;
535 }
536
537 cJSON *item = cJSON_GetObjectItem(object, key);
538 if (!cJSON_IsNumber(item)) {
539 cJSON_Delete(object);
540 return defaultValue;
541 }
542
543 int32_t value = item->valueint;
544 cJSON_Delete(object);
545 return value;
546 }
547
ConvertInstallRecordToJson(const InstallRecord & installRecord)548 cJSON *BundleUtil::ConvertInstallRecordToJson(const InstallRecord &installRecord)
549 {
550 cJSON *root = cJSON_CreateObject();
551 if (root == nullptr) {
552 return nullptr;
553 }
554
555 if ((cJSON_AddStringToObject(root, JSON_SUB_KEY_PACKAGE, installRecord.bundleName) == nullptr) ||
556 (cJSON_AddStringToObject(root, JSON_SUB_KEY_APPID, installRecord.appId) == nullptr) ||
557 #ifdef APP_PLATFORM_WATCHGT
558 #ifdef BC_TRANS_ENABLE
559 (cJSON_AddStringToObject(root, JSON_SUB_KEY_JSENGINE_VERSION, installRecord.jsEngineVersion) == nullptr) ||
560 (cJSON_AddNumberToObject(root, JSON_SUB_KEY_TRANSFORM_RESULT, installRecord.transformResult) == nullptr) ||
561 #endif
562 #endif
563 (cJSON_AddNumberToObject(root, JSON_SUB_KEY_VERSIONCODE, installRecord.versionCode) == nullptr) ||
564 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
565 (cJSON_AddNumberToObject(root, JSON_SUB_KEY_UID, installRecord.uid) == nullptr) ||
566 (cJSON_AddNumberToObject(root, JSON_SUB_KEY_GID, installRecord.gid) == nullptr) ||
567 #endif
568 (cJSON_AddStringToObject(root, JSON_SUB_KEY_CODEPATH, installRecord.codePath) == nullptr)) {
569 cJSON_Delete(root);
570 return nullptr;
571 }
572 return root;
573 }
574
CreateRandStr(char * str,uint32_t len)575 void BundleUtil::CreateRandStr(char *str, uint32_t len)
576 {
577 if (str == nullptr) {
578 return;
579 }
580 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
581 srand(time(NULL));
582 #else
583 srand(LOS_TickCountGet());
584 #endif
585 uint32_t i;
586 for (i = 0; i < len - 1; ++i) {
587 switch ((rand() % NUM_OF_TYPE)) {
588 case 0:
589 str[i] = 'A' + rand() % MAX_CHARACTER_VALUE;
590 break;
591 case 1:
592 str[i] = 'a' + rand() % MAX_CHARACTER_VALUE;
593 break;
594 default:
595 str[i] = '0' + rand() % MAX_SINGLE_DIGIT_VALUE;
596 break;
597 }
598 }
599 str[i] = '\0';
600 }
601
602 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
ObtainUidAndGidJson(bool flag)603 cJSON *BundleUtil::ObtainUidAndGidJson(bool flag)
604 {
605 std::string uidJsonPath = std::string(JSON_PATH) + UID_GID_MAP + JSON_SUFFIX;
606 cJSON *object = BundleUtil::GetJsonStream(uidJsonPath.c_str());
607 if ((object != nullptr) || (!flag)) {
608 return object;
609 }
610
611 object = cJSON_CreateObject();
612 if (object == nullptr) {
613 return nullptr;
614 }
615 cJSON *size = cJSON_CreateNumber(0);
616 if (size == nullptr) {
617 cJSON_Delete(object);
618 return nullptr;
619 }
620 if (!cJSON_AddItemToObject(object, PROFILE_KEY_UID_SIZE, size)) {
621 cJSON_Delete(size);
622 cJSON_Delete(object);
623 return nullptr;
624 }
625 cJSON *uids = cJSON_AddArrayToObject(object, PROFILE_KEY_UID_AND_GID);
626 if (uids == nullptr) {
627 cJSON_Delete(object);
628 return nullptr;
629 }
630 return object;
631 }
632
AddUidAndGidInfo(const InstallRecord & installRecord,cJSON * size,cJSON * uids)633 bool BundleUtil::AddUidAndGidInfo(const InstallRecord &installRecord, cJSON *size, cJSON *uids)
634 {
635 if ((size == nullptr) || (uids == nullptr)) {
636 return false;
637 }
638 cJSON_SetNumberValue(size, size->valueint + 1);
639 cJSON *uid = cJSON_CreateObject();
640 if (uid == nullptr) {
641 return false;
642 }
643 if ((cJSON_AddStringToObject(uid, JSON_SUB_KEY_PACKAGE, installRecord.bundleName) == nullptr) ||
644 (cJSON_AddNumberToObject(uid, JSON_SUB_KEY_UID, installRecord.uid) == nullptr) ||
645 (cJSON_AddNumberToObject(uid, JSON_SUB_KEY_GID, installRecord.gid) == nullptr)) {
646 cJSON_Delete(uid);
647 return false;
648 }
649 if (!cJSON_AddItemToArray(uids, uid)) {
650 cJSON_Delete(uid);
651 return false;
652 }
653 return true;
654 }
655
ConvertUidAndGidToJson(const InstallRecord & installRecord)656 cJSON *BundleUtil::ConvertUidAndGidToJson(const InstallRecord &installRecord)
657 {
658 if (installRecord.bundleName == nullptr) {
659 return nullptr;
660 }
661
662 cJSON *object = ObtainUidAndGidJson(true);
663 if (object == nullptr) {
664 return nullptr;
665 }
666
667 cJSON *size = cJSON_GetObjectItemCaseSensitive(object, PROFILE_KEY_UID_SIZE);
668 if (!cJSON_IsNumber(size)) {
669 cJSON_Delete(object);
670 return nullptr;
671 }
672 cJSON *uids = cJSON_GetObjectItemCaseSensitive(object, PROFILE_KEY_UID_AND_GID);
673 if (!cJSON_IsArray(uids)) {
674 cJSON_Delete(object);
675 return nullptr;
676 }
677
678 cJSON *item = nullptr;
679 cJSON_ArrayForEach(item, uids) {
680 cJSON *innerBundleName = cJSON_GetObjectItemCaseSensitive(item, JSON_SUB_KEY_PACKAGE);
681 if ((cJSON_IsString(innerBundleName)) && (innerBundleName->valuestring != nullptr)) {
682 if (strcmp(innerBundleName->valuestring, installRecord.bundleName) == 0) {
683 return object;
684 }
685 }
686 }
687
688 if (!AddUidAndGidInfo(installRecord, size, uids)) {
689 cJSON_Delete(object);
690 return nullptr;
691 }
692
693 return object;
694 }
695
DeleteInnerUidInfoFromUidArray(const char * bundleName,cJSON * size,cJSON * uids)696 bool BundleUtil::DeleteInnerUidInfoFromUidArray(const char *bundleName, cJSON *size, cJSON *uids)
697 {
698 if ((size == nullptr) || (uids == nullptr) || (bundleName == nullptr)) {
699 return false;
700 }
701 cJSON *uid = nullptr;
702 int32_t index = -1;
703 bool isFound = false;
704 cJSON_ArrayForEach(uid, uids) {
705 index++;
706 cJSON *innerBundleName = cJSON_GetObjectItemCaseSensitive(uid, JSON_SUB_KEY_PACKAGE);
707 if ((cJSON_IsString(innerBundleName)) && (innerBundleName->valuestring != nullptr)) {
708 if (strcmp(innerBundleName->valuestring, bundleName) == 0) {
709 isFound = true;
710 break;
711 }
712 }
713 }
714 if (isFound) {
715 cJSON_DeleteItemFromArray(uids, index);
716 cJSON_SetNumberValue(size, size->valueint - 1);
717 }
718 return true;
719 }
720
DeleteUidInfoFromJson(const char * bundleName)721 bool BundleUtil::DeleteUidInfoFromJson(const char *bundleName)
722 {
723 cJSON *object = ObtainUidAndGidJson(false);
724 if (object == nullptr) {
725 return false;
726 }
727
728 cJSON *size = cJSON_GetObjectItemCaseSensitive(object, PROFILE_KEY_UID_SIZE);
729 if (!cJSON_IsNumber(size)) {
730 cJSON_Delete(object);
731 return false;
732 }
733 cJSON *uids = cJSON_GetObjectItemCaseSensitive(object, PROFILE_KEY_UID_AND_GID);
734 if (!cJSON_IsArray(uids)) {
735 cJSON_Delete(object);
736 return false;
737 }
738 if (!DeleteInnerUidInfoFromUidArray(bundleName, size, uids)) {
739 cJSON_Delete(object);
740 return false;
741 }
742
743 std::string uidJsonPath = std::string(JSON_PATH) + UID_GID_MAP + JSON_SUFFIX;
744 if (size->valueint == 0) {
745 BundleDaemonClient::GetInstance().RemoveFile(uidJsonPath.c_str());
746 } else {
747 char *out = cJSON_Print(object);
748 if (out == nullptr) {
749 cJSON_Delete(object);
750 return false;
751 }
752 BundleDaemonClient::GetInstance().StoreContentToFile(uidJsonPath.c_str(), out, strlen(out) + 1);
753 cJSON_free(out);
754 }
755
756 cJSON_Delete(object);
757 return true;
758 }
759 #else
MkDirs(const char * dir)760 bool BundleUtil::MkDirs(const char *dir)
761 {
762 if (IsDir(dir)) {
763 return true;
764 }
765 if (strlen(dir) > PATH_LENGTH) {
766 #ifdef APP_PLATFORM_WATCHGT
767 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] MkDirs failed, path is too long");
768 #endif
769 return false;
770 }
771 int32_t len = strlen(dir);
772 char *rootDir = nullptr;
773 bool isRootDirExists = true;
774 for (int32_t i = 1; i < len; i++) {
775 if (dir[i] != '/') {
776 continue;
777 }
778 rootDir = GetRootDir(dir, i);
779 if (rootDir == nullptr) {
780 #ifdef APP_PLATFORM_WATCHGT
781 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] MkDirs failed, rootDir is null");
782 #endif
783 return false;
784 }
785 if (isRootDirExists) {
786 if (IsDir(rootDir)) {
787 UI_Free(rootDir);
788 rootDir = nullptr;
789 continue;
790 }
791 isRootDirExists = false;
792 }
793 if (mkdir(rootDir, S_IREAD | S_IWRITE) < 0) {
794 UI_Free(rootDir);
795 #ifdef APP_PLATFORM_WATCHGT
796 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] make rootDir failed");
797 #endif
798 return false;
799 }
800 UI_Free(rootDir);
801 rootDir = nullptr;
802 }
803 return (mkdir(dir, S_IREAD | S_IWRITE) < 0) ? false : true;
804 }
805
RemoveDir(const char * path)806 bool BundleUtil::RemoveDir(const char *path)
807 {
808 if (!IsDir(path)) {
809 (void) unlink(path);
810 return true;
811 }
812
813 List<char *>* list = new (std::nothrow)List<char *>();
814 if (list == nullptr) {
815 #ifdef APP_PLATFORM_WATCHGT
816 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] RemoveDir failed, list is null");
817 #endif
818 return false;
819 }
820 list->PushFront(Utils::Strdup(path));
821 while (!list->IsEmpty()) {
822 char *curPath = list->Front();
823 if (curPath == nullptr) {
824 break;
825 }
826 if (CheckDirIsEmpty(curPath, list)) {
827 list->PopFront();
828 if (rmdir(curPath) < 0) {
829 AdapterFree(curPath);
830 break;
831 }
832 AdapterFree(curPath);
833 }
834 }
835 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
836 for (auto node = list->Begin(); node != list->End(); node = node->next_) {
837 AdapterFree(node->value_);
838 }
839 #endif
840 if (!list->IsEmpty()) {
841 delete list;
842 #ifdef APP_PLATFORM_WATCHGT
843 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] After delete, file is still not empty");
844 #endif
845 return false;
846 }
847
848 delete list;
849 return true;
850 }
851
RenameDir(const char * oldDir,const char * newDir)852 bool BundleUtil::RenameDir(const char *oldDir, const char *newDir)
853 {
854 if (oldDir == nullptr || newDir == nullptr) {
855 return false;
856 }
857
858 if (IsDir(newDir) && !RemoveDir(newDir)) {
859 return false;
860 }
861 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
862 if (frename(oldDir, newDir) != 0) {
863 return false;
864 }
865 #else
866 if (rename(oldDir, newDir) != 0) {
867 return false;
868 }
869 #endif
870 return true;
871 }
872
RenameFile(const char * oldFile,const char * newFile)873 bool BundleUtil::RenameFile(const char *oldFile, const char *newFile)
874 {
875 if (oldFile == nullptr || newFile == nullptr) {
876 return false;
877 }
878
879 if (IsFile(newFile) && unlink(newFile) < 0) {
880 return false;
881 }
882
883 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
884 if (frename(oldFile, newFile) != 0) {
885 return false;
886 }
887 #else
888 if (rename(oldFile, newFile) != 0) {
889 return false;
890 }
891 #endif
892 return true;
893 }
894
GetRootDir(const char * dir,int32_t index)895 char *BundleUtil::GetRootDir(const char *dir, int32_t index)
896 {
897 char *rootDir = reinterpret_cast<char *>(UI_Malloc((index + 1) * sizeof(char)));
898 if (rootDir == nullptr) {
899 return nullptr;
900 }
901 errno_t err = strncpy_s(rootDir, index + 1, dir, index);
902 if (err != EOK) {
903 UI_Free(rootDir);
904 return nullptr;
905 }
906 return rootDir;
907 }
908
CheckDirIsEmpty(const char * dirPath,List<char * > * list)909 bool BundleUtil::CheckDirIsEmpty(const char *dirPath, List<char *>* list)
910 {
911 DIR *dir = nullptr;
912 if ((dir = opendir(dirPath)) == nullptr) {
913 return false;
914 }
915 bool isEmptyDir = true;
916 dirent *dp = nullptr;
917 char filePath[PATH_LENGTH] = { 0 };
918 while ((dp = readdir(dir)) != nullptr) {
919 if ((strcmp(dp->d_name, ".") == 0) || (strcmp(dp->d_name, "..")) == 0) {
920 continue;
921 }
922
923 if (memset_s(filePath, PATH_LENGTH, 0, PATH_LENGTH) != EOK) {
924 continue;
925 }
926
927 if (sprintf_s(filePath, PATH_LENGTH, "%s/%s", dirPath, dp->d_name) < 0) {
928 continue;
929 }
930
931 if (IsDir(filePath)) {
932 list->PushFront(Utils::Strdup(filePath));
933 isEmptyDir = false;
934 } else {
935 (void) unlink(filePath);
936 }
937 }
938 closedir(dir);
939 return isEmptyDir;
940 }
StoreJsonContentToFile(const char * packageJson,const cJSON * object)941 bool BundleUtil::StoreJsonContentToFile(const char *packageJson, const cJSON *object)
942 {
943 if (object == nullptr) {
944 #ifdef APP_PLATFORM_WATCHGT
945 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Json data object is null");
946 #endif
947 return false;
948 }
949
950 char *out = cJSON_Print(object);
951 if (out == nullptr) {
952 #ifdef APP_PLATFORM_WATCHGT
953 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] turn Json data to char sequence failed");
954 #endif
955 return false;
956 }
957
958 if (!CheckRealPath(packageJson)) {
959 cJSON_free(out);
960 #ifdef APP_PLATFORM_WATCHGT
961 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Json file path doest not exist");
962 #endif
963 return false;
964 }
965
966 if (IsFile(packageJson) && unlink(packageJson) < 0) {
967 cJSON_free(out);
968 #ifdef APP_PLATFORM_WATCHGT
969 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Json file path is invalid");
970 #endif
971 return false;
972 }
973
974 int32_t fp = open(packageJson, O_RDWR | O_CREAT, S_IREAD | S_IWRITE);
975 if (fp < 0) {
976 cJSON_free(out);
977 #ifdef APP_PLATFORM_WATCHGT
978 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] open Json file failed");
979 #endif
980 return false;
981 }
982
983 if (write(fp, out, strlen(out)) != strlen(out)) {
984 cJSON_free(out);
985 close(fp);
986 #ifdef APP_PLATFORM_WATCHGT
987 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] write to Json file failed");
988 #endif
989 return false;
990 }
991
992 cJSON_free(out);
993 close(fp);
994 return true;
995 }
996
FreeStrArrayMemory(char ** pointer,uint32_t len)997 void BundleUtil::FreeStrArrayMemory(char **pointer, uint32_t len)
998 {
999 if (len != 0 && pointer != nullptr) {
1000 for (uint32_t i = 0; i < len; i++) {
1001 AdapterFree(*(pointer + i));
1002 }
1003 AdapterFree(pointer);
1004 }
1005 }
1006 #endif
1007 } // namespace OHOS