• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 <stdio.h>
17 #include <stdlib.h>
18 
19 #include "cJSON.h"
20 #include "securec.h"
21 
22 #include "hnp_base.h"
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
ParseLinksJsonToCfgInfo(cJSON * linksItem,HnpCfgInfo * hnpCfg)28 static int ParseLinksJsonToCfgInfo(cJSON *linksItem, HnpCfgInfo *hnpCfg)
29 {
30     NativeBinLink *linkArray = NULL;
31 
32     int linkArrayNum = cJSON_GetArraySize(linksItem);
33     if (linkArrayNum > 0) {
34         hnpCfg->linkNum = (size_t)linkArrayNum;
35         linkArray = (NativeBinLink*)malloc(sizeof(NativeBinLink) * linkArrayNum);
36         if (linkArray == NULL) {
37             HNP_LOGE("malloc unsuccess.");
38             return HNP_ERRNO_NOMEM;
39         }
40         for (int i = 0; i < linkArrayNum; i++) {
41             cJSON *link = cJSON_GetArrayItem(linksItem, i);
42             if (link == NULL) {
43                 free(linkArray);
44                 return HNP_ERRNO_BASE_GET_ARRAY_ITRM_FAILED;
45             }
46             cJSON *sourceItem = cJSON_GetObjectItem(link, "source");
47             if ((sourceItem == NULL) || (sourceItem->valuestring == NULL)) {
48                 HNP_LOGE("get source info in cfg unsuccess.");
49                 free(linkArray);
50                 return HNP_ERRNO_BASE_PARSE_ITEM_NO_FOUND;
51             }
52             if (strcpy_s(linkArray[i].source, MAX_FILE_PATH_LEN, sourceItem->valuestring) != EOK) {
53                 HNP_LOGE("strcpy unsuccess.");
54                 free(linkArray);
55                 return HNP_ERRNO_BASE_COPY_FAILED;
56             }
57             linkArray[i].target[0] = '\0';  //允许target不填,软链接默认使用原二进制名称
58             cJSON *targetItem = cJSON_GetObjectItem(link, "target");
59             if ((targetItem != NULL) && (targetItem->valuestring != NULL) &&
60                 (strcpy_s(linkArray[i].target, MAX_FILE_PATH_LEN, targetItem->valuestring) != EOK)) {
61                 HNP_LOGE("strcpy unsuccess.");
62                 free(linkArray);
63                 return HNP_ERRNO_BASE_COPY_FAILED;
64             }
65         }
66         hnpCfg->links = linkArray;
67     } else {
68         hnpCfg->linkNum = 0;
69     }
70     return 0;
71 }
72 
ParseJsonStreamToHnpCfgInfo(cJSON * json,HnpCfgInfo * hnpCfg)73 static int ParseJsonStreamToHnpCfgInfo(cJSON *json, HnpCfgInfo *hnpCfg)
74 {
75     int ret;
76 
77     cJSON *typeItem = cJSON_GetObjectItem(json, "type");
78     if ((typeItem == NULL) || (typeItem->valuestring == NULL)) {
79         HNP_LOGE("get type info in cfg unsuccess.");
80         return HNP_ERRNO_BASE_PARSE_ITEM_NO_FOUND;
81     }
82     if (strcmp(typeItem->valuestring, "hnp-config") != 0) {
83         HNP_LOGE("type info not match.type=%{public}s", typeItem->valuestring);
84         return HNP_ERRNO_BASE_PARSE_ITEM_NO_FOUND;
85     }
86     cJSON *nameItem = cJSON_GetObjectItem(json, "name");
87     if ((nameItem == NULL) || (nameItem->valuestring == NULL)) {
88         HNP_LOGE("get name info in cfg unsuccess.");
89         return HNP_ERRNO_BASE_PARSE_ITEM_NO_FOUND;
90     }
91     ret = strcpy_s(hnpCfg->name, MAX_FILE_PATH_LEN, nameItem->valuestring);
92     if (ret != EOK) {
93         HNP_LOGE("strcpy unsuccess.");
94         return HNP_ERRNO_BASE_COPY_FAILED;
95     }
96     cJSON *versionItem = cJSON_GetObjectItem(json, "version");
97     if ((versionItem == NULL) || (versionItem->valuestring == NULL)) {
98         HNP_LOGE("get version info in cfg unsuccess.");
99         return HNP_ERRNO_BASE_PARSE_ITEM_NO_FOUND;
100     }
101     ret = strcpy_s(hnpCfg->version, HNP_VERSION_LEN, versionItem->valuestring);
102     if (ret != EOK) {
103         HNP_LOGE("strcpy unsuccess.");
104         return HNP_ERRNO_BASE_COPY_FAILED;
105     }
106     cJSON *installItem = cJSON_GetObjectItem(json, "install");
107     if (installItem == NULL) {
108         HNP_LOGE("get install info in cfg unsuccess.");
109         return HNP_ERRNO_BASE_PARSE_ITEM_NO_FOUND;
110     }
111     cJSON *linksItem = cJSON_GetObjectItem(installItem, "links");
112     if (linksItem != NULL) {
113         ret = ParseLinksJsonToCfgInfo(linksItem, hnpCfg);
114         if (ret != 0) {
115             return ret;
116         }
117     } else {
118         hnpCfg->linkNum = 0;
119     }
120     return 0;
121 }
122 
ParseHnpCfgFile(const char * hnpCfgPath,HnpCfgInfo * hnpCfg)123 int ParseHnpCfgFile(const char *hnpCfgPath, HnpCfgInfo *hnpCfg)
124 {
125     int ret;
126     char *cfgStream = NULL;
127     cJSON *json;
128     int size;
129 
130     ret = ReadFileToStream(hnpCfgPath, &cfgStream, &size);
131     if (ret != 0) {
132         HNP_LOGE("read cfg file[%{public}s] unsuccess.", hnpCfgPath);
133         return HNP_ERRNO_BASE_READ_FILE_STREAM_FAILED;
134     }
135     json = cJSON_Parse(cfgStream);
136     free(cfgStream);
137     if (json == NULL) {
138         HNP_LOGE("parse json file[%{public}s] unsuccess.", hnpCfgPath);
139         return HNP_ERRNO_BASE_PARSE_JSON_FAILED;
140     }
141     ret = ParseJsonStreamToHnpCfgInfo(json, hnpCfg);
142     cJSON_Delete(json);
143 
144     return ret;
145 }
146 
HnpCfgGetFromSteam(char * cfgStream,HnpCfgInfo * hnpCfg)147 int HnpCfgGetFromSteam(char *cfgStream, HnpCfgInfo *hnpCfg)
148 {
149     cJSON *json;
150     int ret;
151 
152     if (cfgStream == NULL) {
153         HNP_LOGE("hnp cfg file not found.");
154         return HNP_ERRNO_BASE_READ_FILE_STREAM_FAILED;
155     }
156 
157     json = cJSON_Parse(cfgStream);
158     if (json == NULL) {
159         HNP_LOGE("parse json file unsuccess.");
160         return HNP_ERRNO_BASE_PARSE_JSON_FAILED;
161     }
162     ret = ParseJsonStreamToHnpCfgInfo(json, hnpCfg);
163     cJSON_Delete(json);
164 
165     return ret;
166 }
GetHnpJsonBuff(HnpCfgInfo * hnpCfg,char ** buff)167 int GetHnpJsonBuff(HnpCfgInfo *hnpCfg, char **buff)
168 {
169     cJSON *root = cJSON_CreateObject();
170 
171     cJSON_AddStringToObject(root, "type", "hnp-config");
172     cJSON_AddStringToObject(root, "name", hnpCfg->name);
173     cJSON_AddStringToObject(root, "version", hnpCfg->version);
174     cJSON_AddObjectToObject(root, "install");
175     char *str = cJSON_Print(root);
176     cJSON_Delete(root);
177 
178     *buff = str;
179     return 0;
180 }
181 
HnpInstallHapExistCheck(const char * hnpPackageName,cJSON * json,cJSON ** hapItemOut,int * hapIndex)182 static bool HnpInstallHapExistCheck(const char *hnpPackageName, cJSON *json, cJSON **hapItemOut, int *hapIndex)
183 {
184     cJSON *hapItem = NULL;
185     bool hapExist = false;
186     cJSON *hapJson = NULL;
187 
188     for (int i = 0; i < cJSON_GetArraySize(json); i++) {
189         hapItem = cJSON_GetArrayItem(json, i);
190         hapJson = cJSON_GetObjectItem(hapItem, "hap");
191         if ((hapJson != NULL) && (cJSON_IsString(hapJson)) && (strcmp(hapJson->valuestring, hnpPackageName) == 0)) {
192             hapExist = true;
193             *hapItemOut = hapItem;
194             *hapIndex = i;
195             break;
196         }
197     }
198 
199     return hapExist;
200 }
201 
HnpInstallHnpExistCheck(cJSON * hnpItemArr,const char * name,cJSON ** hnpItemOut,int * hnpIndex,const char * version)202 static bool HnpInstallHnpExistCheck(cJSON *hnpItemArr, const char *name, cJSON **hnpItemOut, int *hnpIndex,
203     const char *version)
204 {
205     if (hnpItemArr == NULL) {
206         return false;
207     }
208 
209     for (int i = 0; i < cJSON_GetArraySize(hnpItemArr); i++) {
210         cJSON *hnpItem = cJSON_GetArrayItem(hnpItemArr, i);
211         cJSON *nameJson = cJSON_GetObjectItem(hnpItem, "name");
212         cJSON *versionJson = cJSON_GetObjectItem(hnpItem, "current_version");
213         if ((nameJson != NULL) && (strcmp(nameJson->valuestring, name) == 0)) {
214             *hnpItemOut = hnpItem;
215             *hnpIndex = i;
216             if (version == NULL) {
217                 return true;
218             }
219             if ((versionJson != NULL) && (strcmp(versionJson->valuestring, version) == 0)) {
220                 return true;
221             }
222         }
223     }
224 
225     return false;
226 }
227 
HnpPackageVersionUpdateAll(cJSON * json,const HnpCfgInfo * hnpCfg)228 static void HnpPackageVersionUpdateAll(cJSON *json, const HnpCfgInfo *hnpCfg)
229 {
230     for (int i = 0; i < cJSON_GetArraySize(json); i++) {
231         cJSON *hapItem = cJSON_GetArrayItem(json, i);
232         cJSON *hnpItemArr = cJSON_GetObjectItem(hapItem, "hnp");
233         for (int j = 0; j < cJSON_GetArraySize(hnpItemArr); j++) {
234             cJSON *hnpItem = cJSON_GetArrayItem(hnpItemArr, j);
235             cJSON *nameItem = cJSON_GetObjectItem(hnpItem, "name");
236             if ((nameItem == NULL) ||
237                 ((cJSON_IsString(nameItem)) && (strcmp(nameItem->valuestring, hnpCfg->name) != 0))) {
238                 continue;
239             }
240             cJSON *version = cJSON_GetObjectItem(hnpItem, "current_version");
241             if (version == NULL) {
242                 break;
243             }
244             cJSON_SetValuestring(version, hnpCfg->version);
245             break;
246         }
247     }
248 
249     return;
250 }
251 
HnpHapJsonWrite(cJSON * json)252 static int HnpHapJsonWrite(cJSON *json)
253 {
254     FILE *fp = fopen(HNP_PACKAGE_INFO_JSON_FILE_PATH, "wb");
255     if (fp == NULL) {
256         HNP_LOGE("open file:%{public}s unsuccess!", HNP_PACKAGE_INFO_JSON_FILE_PATH);
257         return HNP_ERRNO_BASE_FILE_OPEN_FAILED;
258     }
259     char *jsonStr = cJSON_Print(json);
260     if (jsonStr == NULL) {
261         HNP_LOGE("get json str unsuccess!");
262         (void)fclose(fp);
263         return HNP_ERRNO_BASE_PARAMS_INVALID;
264     }
265     size_t jsonStrSize = strlen(jsonStr);
266     size_t writeLen = fwrite(jsonStr, sizeof(char), jsonStrSize, fp);
267     (void)fclose(fp);
268     free(jsonStr);
269     if (writeLen != jsonStrSize) {
270         HNP_LOGE("package info write file:%{public}s unsuccess!", HNP_PACKAGE_INFO_JSON_FILE_PATH);
271         return HNP_ERRNO_BASE_FILE_WRITE_FAILED;
272     }
273 
274     return 0;
275 }
276 
HnpHapJsonHnpAdd(bool hapExist,cJSON * json,cJSON * hapItem,const char * hnpPackageName,const HnpCfgInfo * hnpCfg)277 static int HnpHapJsonHnpAdd(bool hapExist, cJSON *json, cJSON *hapItem, const char *hnpPackageName,
278     const HnpCfgInfo *hnpCfg)
279 {
280     cJSON *hnpItemArr = NULL;
281     int ret;
282 
283     if (hapExist) {
284         hnpItemArr = cJSON_GetObjectItem(hapItem, "hnp");
285         if (hnpItemArr == NULL) {
286             HNP_LOGE("hnp item array get unsuccess");
287             return HNP_ERRNO_BASE_PARSE_ITEM_NO_FOUND;
288         }
289     } else {
290         hapItem = cJSON_CreateObject();
291         if (hapItem == NULL) {
292             HNP_LOGE("hnp json write create hap object unsuccess");
293             return HNP_ERRNO_BASE_JSON_ARRAY_CREATE_FAILED;
294         }
295         cJSON_AddStringToObject(hapItem, "hap", hnpPackageName);
296         hnpItemArr = cJSON_CreateArray();
297         if (hnpItemArr == NULL) {
298             HNP_LOGE("hnp json write array create unsuccess");
299             cJSON_Delete(hapItem);
300             return HNP_ERRNO_BASE_JSON_ARRAY_CREATE_FAILED;
301         }
302         cJSON_AddItemToObject(hapItem, "hnp", hnpItemArr);
303         cJSON_AddItemToArray(json, hapItem);
304     }
305 
306     cJSON *hnpItem = cJSON_CreateObject();
307     if (hnpItem == NULL) {
308         HNP_LOGE("hnp json write create hnp object unsuccess");
309         return HNP_ERRNO_BASE_JSON_ARRAY_CREATE_FAILED;
310     }
311     cJSON_AddItemToObject(hnpItem, "name", cJSON_CreateString(hnpCfg->name));
312     cJSON_AddItemToObject(hnpItem, "current_version", cJSON_CreateString(hnpCfg->version));
313     if (hnpCfg->isInstall) {
314         cJSON_AddItemToObject(hnpItem, "install_version", cJSON_CreateString(hnpCfg->version));
315     } else {
316         cJSON_AddItemToObject(hnpItem, "install_version", cJSON_CreateString("none"));
317     }
318     cJSON_AddItemToArray(hnpItemArr, hnpItem);
319 
320     HnpPackageVersionUpdateAll(json, hnpCfg);
321 
322     ret = HnpHapJsonWrite(json);
323     return ret;
324 }
325 
HnpInstallInfoJsonWrite(const char * hapPackageName,const HnpCfgInfo * hnpCfg)326 int HnpInstallInfoJsonWrite(const char *hapPackageName, const HnpCfgInfo *hnpCfg)
327 {
328     bool hapExist = false;
329     int hapIndex = 0;
330     int hnpIndex = 0;
331     char *infoStream;
332     int size;
333     cJSON *hapItem = NULL;
334     cJSON *hnpItem = NULL;
335     cJSON *json = NULL;
336 
337     if ((hapPackageName == NULL) || (hnpCfg == NULL)) {
338         return HNP_ERRNO_BASE_PARAMS_INVALID;
339     }
340 
341     int ret = ReadFileToStream(HNP_PACKAGE_INFO_JSON_FILE_PATH, &infoStream, &size);
342     if (ret != 0) {
343         if ((ret == HNP_ERRNO_BASE_FILE_OPEN_FAILED) || (ret == HNP_ERRNO_BASE_GET_FILE_LEN_NULL)) {
344             if ((json = cJSON_CreateArray()) == NULL) {
345                 HNP_LOGE("hnp json write array create unsuccess");
346                 return HNP_ERRNO_BASE_JSON_ARRAY_CREATE_FAILED;
347             }
348         } else {
349             HNP_LOGE("hnp json write read hnp info file unsuccess");
350             return HNP_ERRNO_BASE_READ_FILE_STREAM_FAILED;
351         }
352     } else {
353         json = cJSON_Parse(infoStream);
354         free(infoStream);
355         if (json == NULL) {
356             HNP_LOGE("hnp json write parse json file unsuccess.");
357             return HNP_ERRNO_BASE_PARSE_JSON_FAILED;
358         }
359         hapExist = HnpInstallHapExistCheck(hapPackageName, json, &hapItem, &hapIndex);
360     }
361 
362     if (hapExist) {
363         cJSON *hnpItemArr = cJSON_GetObjectItem(hapItem, "hnp");
364         bool hnpExist = HnpInstallHnpExistCheck(hnpItemArr, hnpCfg->name, &hnpItem, &hnpIndex, NULL);
365         if (hnpExist) {
366             cJSON *versionJson = cJSON_GetObjectItem(hnpItem, "current_version");
367             if (versionJson != NULL) { // 当前版本存在,即非新增版本,仅更新current_version即可,无需更新install_version
368                 cJSON_SetValuestring(versionJson, hnpCfg->version);
369                 HnpPackageVersionUpdateAll(json, hnpCfg);
370                 ret = HnpHapJsonWrite(json);
371                 cJSON_Delete(json);
372                 return ret;
373             }
374         }
375     }
376 
377     ret = HnpHapJsonHnpAdd(hapExist, json, hapItem, hapPackageName, hnpCfg);
378     cJSON_Delete(json);
379     return ret;
380 }
381 
HnpOtherPackageInstallCheck(const char * name,const char * version,int packageIndex,cJSON * json)382 static bool HnpOtherPackageInstallCheck(const char *name, const char *version, int packageIndex, cJSON *json)
383 {
384     bool hnpExist = false;
385     int hnpIndex = 0;
386 
387     for (int i = 0; i < cJSON_GetArraySize(json); i++) {
388         if (i == packageIndex) {
389             continue;
390         }
391         cJSON *hapItem = cJSON_GetArrayItem(json, i);
392         cJSON *hnpItemArr = cJSON_GetObjectItem(hapItem, "hnp");
393         cJSON *hnpItem = NULL;
394         hnpExist = HnpInstallHnpExistCheck(hnpItemArr, name, &hnpItem, &hnpIndex, version);
395         if (hnpExist) {
396             return true;
397         }
398     }
399 
400     return false;
401 }
402 
HnpPackageInfoGetOut(HnpPackageInfo * packageInfos,int sum,HnpPackageInfo ** packageInfoOut,int * count)403 static int HnpPackageInfoGetOut(HnpPackageInfo *packageInfos, int sum, HnpPackageInfo **packageInfoOut, int *count)
404 {
405     HnpPackageInfo *ptr;
406 
407     if (sum == 0) {
408         return 0;
409     }
410 
411     ptr = malloc(sizeof(HnpPackageInfo) * sum);
412     if (ptr == NULL) {
413         HNP_LOGE("malloc hnp info unsuccess.");
414         return HNP_ERRNO_NOMEM;
415     }
416 
417     if (memcpy_s(ptr, sizeof(HnpPackageInfo) * sum, packageInfos, sizeof(HnpPackageInfo) * sum) != 0) {
418         free(ptr);
419         HNP_LOGE("memcpy hnp info unsuccess.");
420         return HNP_ERRNO_BASE_MEMCPY_FAILED;
421     }
422 
423     *packageInfoOut = ptr;
424     *count = sum;
425     return 0;
426 }
427 
HnpPackageJsonGet(cJSON ** pJson)428 static int HnpPackageJsonGet(cJSON **pJson)
429 {
430     char *infoStream;
431     int size;
432 
433     int ret = ReadFileToStream(HNP_PACKAGE_INFO_JSON_FILE_PATH, &infoStream, &size);
434     if (ret != 0) {
435         if (ret == HNP_ERRNO_BASE_FILE_OPEN_FAILED || ret == HNP_ERRNO_BASE_GET_FILE_LEN_NULL) {
436             return 0;
437         }
438         HNP_LOGE("package info get read hnp info file unsuccess");
439         return HNP_ERRNO_BASE_READ_FILE_STREAM_FAILED;
440     }
441 
442     cJSON *json = cJSON_Parse(infoStream);
443     free(infoStream);
444     if (json == NULL) {
445         HNP_LOGE("package info get parse json file unsuccess.");
446         return HNP_ERRNO_BASE_PARSE_JSON_FAILED;
447     }
448 
449     *pJson = json;
450 
451     return 0;
452 }
453 
454 /**
455  * 读取配置文件 仅当未安装过对应hnp或者当前hap与之前安装者一致 方可覆盖
456  */
CanRecovery(const char * hnpPackageName,HnpCfgInfo * hnpCfg)457 bool CanRecovery(const char *hnpPackageName, HnpCfgInfo *hnpCfg)
458 {
459     cJSON *json = NULL;
460 
461     int ret = HnpPackageJsonGet(&json);
462     HNP_ERROR_CHECK(ret == 0, return false, "Get Package Json failed");
463     HNP_INFO_CHECK(json != NULL, return true, "No Config, ingore");
464     HNP_INFO_CHECK(cJSON_IsArray(json), cJSON_Delete(json);
465         return false, "Config file structed damaged");
466 
467     // 默认可以覆盖
468     bool canRecovery = true;
469     cJSON *hapItem = NULL;
470     cJSON *hapJson = NULL;
471 
472     for (int i = 0; i < cJSON_GetArraySize(json); i++) {
473         hapItem = cJSON_GetArrayItem(json, i);
474         hapJson = cJSON_GetObjectItem(hapItem, HAP_PACKAGE_INFO_HAP_PREFIX);
475         HNP_ERROR_CHECK(hapJson != NULL && cJSON_IsString(hapJson), continue,
476             "invalid hap info");
477         cJSON *hnpItemArr = cJSON_GetObjectItem(hapItem, HAP_PACKAGE_INFO_HNP_PREFIX);
478         HNP_ERROR_CHECK(hnpItemArr != NULL && cJSON_IsArray(hnpItemArr), continue,
479             "invalid hnp info");
480         for (int j = 0; j < cJSON_GetArraySize(hnpItemArr); j++) {
481             cJSON *hnpItem = cJSON_GetArrayItem(hnpItemArr, j);
482             cJSON *name = cJSON_GetObjectItem(hnpItem, HAP_PACKAGE_INFO_NAME_PREFIX);
483             HNP_ERROR_CHECK(name != NULL && cJSON_IsString(name), continue,
484                 "invalid name info");
485 
486             HNP_ONLY_EXPER(strcmp(name->valuestring, hnpCfg->name) != 0, continue);
487             // 找到对应hnp的安装信息时 要求当前hap与安装hap包名一致
488             canRecovery = false;
489             HNP_LOGI("Found hnp Info %{public}s %{public}s", hapJson->valuestring, hnpPackageName);
490             if (strcmp(hapJson->valuestring, hnpPackageName) == 0) {
491                 cJSON_Delete(json);
492                 return true;
493             }
494         }
495     }
496     cJSON_Delete(json);
497     return canRecovery;
498 }
499 
HnpPackageInfoGet(const char * packageName,HnpPackageInfo ** packageInfoOut,int * count)500 int HnpPackageInfoGet(const char *packageName, HnpPackageInfo **packageInfoOut, int *count)
501 {
502     bool hnpExist = false;
503     int hapIndex = 0;
504     HnpPackageInfo packageInfos[MAX_PACKAGE_HNP_NUM] = {0};
505     int sum = 0;
506     cJSON *json = NULL;
507 
508     int ret = HnpPackageJsonGet(&json);
509     if (ret != 0 || json == NULL) {
510         return ret;
511     }
512 
513     cJSON *hapItem = NULL;
514     if (HnpInstallHapExistCheck(packageName, json, &hapItem, &hapIndex) == false) {
515         cJSON_Delete(json);
516         return 0;
517     }
518 
519     cJSON *hnpItemArr = cJSON_GetObjectItem(hapItem, "hnp");
520     for (int j = 0; j < cJSON_GetArraySize(hnpItemArr); j++) {
521         cJSON *hnpItem = cJSON_GetArrayItem(hnpItemArr, j);
522         cJSON *name = cJSON_GetObjectItem(hnpItem, "name");
523         cJSON *version = cJSON_GetObjectItem(hnpItem, "current_version");
524         cJSON *installVersion = cJSON_GetObjectItem(hnpItem, "install_version");
525         if (name == NULL || version == NULL || installVersion == NULL || !cJSON_IsString(name) ||
526             !cJSON_IsString(version) || !cJSON_IsString(installVersion)) {
527             continue;
528         }
529         hnpExist = HnpOtherPackageInstallCheck(name->valuestring, version->valuestring, hapIndex, json);
530         // 当卸载当前版本未被其他hap使用或者存在安装版本的时候,需要卸载对应的当前版本或者安装版本
531         if (!hnpExist || strcmp(installVersion->valuestring, "none") != 0) {
532             if (sum >= MAX_PACKAGE_HNP_NUM - 1) {
533                 HNP_LOGE("package info num over limit");
534                 cJSON_Delete(json);
535                 return HNP_ERRNO_BASE_FILE_COUNT_OVER;
536             }
537 
538             if ((strcpy_s(packageInfos[sum].name, MAX_FILE_PATH_LEN, name->valuestring) != EOK) ||
539                 (strcpy_s(packageInfos[sum].currentVersion, HNP_VERSION_LEN, version->valuestring) != EOK) ||
540                 (strcpy_s(packageInfos[sum].installVersion, HNP_VERSION_LEN, installVersion->valuestring) != EOK)) {
541                 HNP_LOGE("strcpy hnp info name[%{public}s],version[%{public}s],install version[%{public}s] unsuccess.",
542                     name->valuestring, version->valuestring, installVersion->valuestring);
543                 cJSON_Delete(json);
544                 return HNP_ERRNO_BASE_COPY_FAILED;
545             }
546             packageInfos[sum].hnpExist = hnpExist;
547             sum++;
548         }
549     }
550     cJSON_Delete(json);
551 
552     return HnpPackageInfoGetOut(packageInfos, sum, packageInfoOut, count);
553 }
554 
HnpPackageInfoHnpDelete(const char * packageName,const char * name,const char * version)555 int HnpPackageInfoHnpDelete(const char *packageName, const char *name, const char *version)
556 {
557     char *infoStream;
558     int size;
559     cJSON *hapItem = NULL;
560     cJSON *hnpItem = NULL;
561     int hapIndex = 0;
562     bool hapExist = false;
563     int hnpIndex = 0;
564     bool hnpExist = false;
565 
566     int ret = ReadFileToStream(HNP_PACKAGE_INFO_JSON_FILE_PATH, &infoStream, &size);
567     if (ret != 0) {
568         if (ret == HNP_ERRNO_BASE_FILE_OPEN_FAILED || ret == HNP_ERRNO_BASE_GET_FILE_LEN_NULL) {
569             return 0;
570         } else {
571             HNP_LOGE("hnp delete read hnp info file unsuccess");
572             return HNP_ERRNO_BASE_READ_FILE_STREAM_FAILED;
573         }
574     }
575 
576     cJSON *json = cJSON_Parse(infoStream);
577     free(infoStream);
578     if (json == NULL) {
579         HNP_LOGE("hnp delete parse json file unsuccess.");
580         return HNP_ERRNO_BASE_PARSE_JSON_FAILED;
581     }
582 
583     hapExist = HnpInstallHapExistCheck(packageName, json, &hapItem, &hapIndex);
584     if (!hapExist) {
585         cJSON_Delete(json);
586         return 0;
587     }
588 
589     cJSON *hnpItemArr = cJSON_GetObjectItem(hapItem, "hnp");
590     hnpExist = HnpInstallHnpExistCheck(hnpItemArr, name, &hnpItem, &hnpIndex, version);
591     if (hnpExist) {
592         cJSON_DeleteItemFromArray(hnpItemArr, hnpIndex);
593     }
594 
595     ret = HnpHapJsonWrite(json);
596     cJSON_Delete(json);
597     return ret;
598 }
599 
HnpPackageInfoDelete(const char * packageName)600 int HnpPackageInfoDelete(const char *packageName)
601 {
602     char *infoStream;
603     int size;
604     cJSON *hapItem = NULL;
605     int hapIndex = 0;
606     bool hapExist = false;
607 
608     int ret = ReadFileToStream(HNP_PACKAGE_INFO_JSON_FILE_PATH, &infoStream, &size);
609     if (ret != 0) {
610         if (ret == HNP_ERRNO_BASE_FILE_OPEN_FAILED || ret == HNP_ERRNO_BASE_GET_FILE_LEN_NULL) {
611             return 0;
612         }
613         HNP_LOGE("package info delete read hnp info file unsuccess");
614         return HNP_ERRNO_BASE_READ_FILE_STREAM_FAILED;
615     }
616 
617     cJSON *json = cJSON_Parse(infoStream);
618     free(infoStream);
619     if (json == NULL) {
620         HNP_LOGE("package info delete parse json file unsuccess.");
621         return HNP_ERRNO_BASE_PARSE_JSON_FAILED;
622     }
623 
624     hapExist = HnpInstallHapExistCheck(packageName, json, &hapItem, &hapIndex);
625     if (hapExist) {
626         cJSON_DeleteItemFromArray(json, hapIndex);
627     }
628 
629     ret = HnpHapJsonWrite(json);
630     cJSON_Delete(json);
631     return ret;
632 }
633 
HnpNeedUnInstallHnpVersionGet(cJSON * hnpItemArr,const char * name)634 static char *HnpNeedUnInstallHnpVersionGet(cJSON *hnpItemArr, const char *name)
635 {
636     char *version = NULL;
637     if (hnpItemArr == NULL) {
638         return NULL;
639     }
640 
641     for (int i = 0; i < cJSON_GetArraySize(hnpItemArr); i++) {
642         cJSON *hnpItem = cJSON_GetArrayItem(hnpItemArr, i);
643         cJSON *nameItem = cJSON_GetObjectItem(hnpItem, "name");
644         cJSON *currentItem = cJSON_GetObjectItem(hnpItem, "current_version");
645         cJSON *installItem = cJSON_GetObjectItem(hnpItem, "install_version");
646         if ((nameItem != NULL) && (currentItem != NULL) && (installItem != NULL) &&
647             (cJSON_IsString(nameItem)) && (cJSON_IsString(currentItem)) && (cJSON_IsString(installItem)) &&
648             (nameItem->valuestring != NULL) && (strcmp(nameItem->valuestring, name) == 0) &&
649             (currentItem->valuestring != NULL) && (installItem->valuestring != NULL) &&
650             (strcmp(currentItem->valuestring, installItem->valuestring) == 0)) {
651             version = strdup(currentItem->valuestring);
652             return version;
653         }
654     }
655 
656     return NULL;
657 }
658 
HnpCurrentVersionGet(const char * name)659 char *HnpCurrentVersionGet(const char *name)
660 {
661     if (name == NULL) {
662         return NULL;
663     }
664     char *infoStream;
665     int size;
666     cJSON *hapItem = NULL;
667     char *version = NULL;
668 
669     int ret = ReadFileToStream(HNP_PACKAGE_INFO_JSON_FILE_PATH, &infoStream, &size);
670     if (ret != 0) {
671         return NULL;
672     }
673 
674     cJSON *json = cJSON_Parse(infoStream);
675     free(infoStream);
676     if (json == NULL) {
677         HNP_LOGE("hnp delete parse json file unsuccess.");
678         return NULL;
679     }
680 
681     for (int i = 0; i < cJSON_GetArraySize(json); i++) {
682         hapItem = cJSON_GetArrayItem(json, i);
683         cJSON *hnpItemArr = cJSON_GetObjectItem(hapItem, "hnp");
684         if (hnpItemArr == NULL) {
685             cJSON_Delete(json);
686             return NULL;
687         }
688 
689         for (int j = 0; j < cJSON_GetArraySize(hnpItemArr); j++) {
690             cJSON *hnpItem = cJSON_GetArrayItem(hnpItemArr, j);
691             cJSON *nameItem = cJSON_GetObjectItem(hnpItem, "name");
692             cJSON *versionItem = cJSON_GetObjectItem(hnpItem, "current_version");
693             if ((nameItem != NULL) && (versionItem != NULL) && (cJSON_IsString(nameItem)) &&
694                 (cJSON_IsString(versionItem)) && (versionItem->valuestring != NULL) &&
695                 (nameItem->valuestring != NULL) && (strcmp(nameItem->valuestring, name) == 0)) {
696                 version = strdup(versionItem->valuestring);
697                 cJSON_Delete(json);
698                 return version;
699             }
700         }
701     }
702 
703     cJSON_Delete(json);
704     return NULL;
705 }
706 
HnpCurrentVersionUninstallCheck(const char * name)707 char *HnpCurrentVersionUninstallCheck(const char *name)
708 {
709     if (name == NULL) {
710         return NULL;
711     }
712     char *infoStream;
713     int size;
714     cJSON *hapItem = NULL;
715     char *version = NULL;
716 
717     int ret = ReadFileToStream(HNP_PACKAGE_INFO_JSON_FILE_PATH, &infoStream, &size);
718     if (ret != 0) {
719         return NULL;
720     }
721 
722     cJSON *json = cJSON_Parse(infoStream);
723     free(infoStream);
724     if (json == NULL) {
725         HNP_LOGE("hnp delete parse json file unsuccess.");
726         return NULL;
727     }
728 
729     for (int i = 0; i < cJSON_GetArraySize(json); i++) {
730         hapItem = cJSON_GetArrayItem(json, i);
731         cJSON *hnpItemArr = cJSON_GetObjectItem(hapItem, "hnp");
732         version = HnpNeedUnInstallHnpVersionGet(hnpItemArr, name);
733         if (version != NULL) {
734             break;
735         }
736     }
737 
738     cJSON_Delete(json);
739     return version;
740 }
741 
742 #ifdef __cplusplus
743 }
744 #endif