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#ifndef HNP_BASE_H
17#define HNP_BASE_H
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <limits.h>
22#include <stdbool.h>
23
24#include "securec.h"
25
26#include "contrib/minizip/zip.h"
27
28#ifndef HNP_CLI
29
30#include "hilog/log.h"
31#undef LOG_TAG
32#define LOG_TAG "APPSPAWN_HNP"
33#undef LOG_DOMAIN
34#define LOG_DOMAIN (0xD002C00 + 0x11)
35
36#endif
37
38#ifdef __cplusplus
39extern "C" {
40#endif
41
42#ifndef MAX_FILE_PATH_LEN
43#define MAX_FILE_PATH_LEN 4096
44#endif
45
46#define HNP_VERSION_LEN 32
47#define BUFFER_SIZE 1024
48#define MAX_PACKAGE_HNP_NUM 256
49
50#define HNP_CFG_FILE_NAME "hnp.json"
51#define HNP_PACKAGE_INFO_JSON_FILE_PATH "/data/service/el1/startup/hnp_info.json"
52#define HNP_ELF_FILE_CHECK_HEAD_LEN 4
53
54#ifdef _WIN32
55#define DIR_SPLIT_SYMBOL '\\'
56#else
57#define DIR_SPLIT_SYMBOL '/'
58#endif
59
60#ifndef APPSPAWN_TEST
61#define APPSPAWN_STATIC static
62#else
63#define APPSPAWN_STATIC
64#endif
65
66/* Native软件二进制软链接配置 */
67typedef struct NativeBinLinkStru {
68    char source[MAX_FILE_PATH_LEN];
69    char target[MAX_FILE_PATH_LEN];
70} NativeBinLink;
71
72/* hnp配置文件信息 */
73typedef struct HnpCfgInfoStru {
74    char name[MAX_FILE_PATH_LEN];
75    char version[HNP_VERSION_LEN];    // Native软件包版本号
76    bool isInstall;                   // 是否已安装
77    unsigned int linkNum;             // 软链接配置个数
78    NativeBinLink *links;
79} HnpCfgInfo;
80
81/* hnp package文件信息
82 * @attention:版本控住逻辑如下
83 * @li 1.当前版本仍被其他hap使用,但是安装此版本的hap被卸载了,不会卸载当前版本,直到升级版本后
84 * @li 2.如果安装版本不是当前版本,安装版本随hap一起卸载,如果安装版本是当前版本,则根据规则1进行卸载
85 * 例如:
86 * 1.a安装v1,b安装v2,c 安装v3
87 * 1.1 状态:hnppublic:[v1,v2,v3],hnp_info:[a cur=v3,ins=v1],[b cur=v3,ins=v2],[c cur=v3,ins=v3]
88 * 1.2 卸载b
89 * 状态:hnppublic:[v1,v3],hnp_info:[a cur=v3,ins=v1],[c cur=v3,ins=v3]
90 * 1.3 卸载c
91 * 1.3.1 状态:hnppublic:[v1,v2,v3],hnp_info:[a cur=v3,ins=v1],[b cur=v3,ins=v2]
92 * 1.3.2 d安装v4
93 * 1.3.2.1 状态:hnppublic:[v1,v2,v4],hnp_info:[a cur=v4,ins=v1],[b cur=v4,ins=v2],[d cur=v4,ins=v4]
94 * 1.3.2.2 卸载d
95 * 状态:d被卸载,hnppublic:[v1,v2,v4],hnp_info:[a cur=v4,ins=v1],[b cur=v4,ins=v2]
96 * 1.4 卸载a,b
97 * 1.4.1 状态:hnppublic:[v3],hnp_info:[c cur=v3,ins=v3]
98 * 1.4.2 卸载c
99 * 状态:hnppublic:[],hnp_info:[]
100 * 1.5 f安装v3
101 * 1.5.1 状态:hnppublic:[v1,v2,v3],hnp_info:[a cur=v3,ins=v1],[b cur=v3,ins=v2],[c cur=v3,ins=v3],[f cur=v3,ins=none]
102 * 1.5.2 卸载c
103 * 1.5.2.1 状态:hnppublic:[v1,v2,v3],hnp_info:[a cur=v3,ins=v1],[b cur=v3,ins=v2],[f cur=v3,ins=none]
104 * 1.5.3 卸载f
105 * 1.5.3.1 状态:hnppublic:[v1,v2,v3],hnp_info:[a cur=v3,ins=v1],[b cur=v3,ins=v2],[c cur=v3,ins=v3]
106 */
107typedef struct HnpPackageInfoStru {
108    char name[MAX_FILE_PATH_LEN];
109    char currentVersion[HNP_VERSION_LEN];    // Native当前软件包版本号
110    char installVersion[HNP_VERSION_LEN];    // Native安装软件包版本号,非此hap安装值为none
111    bool hnpExist;                           // hnp是否被其他hap使用
112} HnpPackageInfo;
113
114/* 日志级别 */
115typedef enum  {
116    HNP_LOG_INFO    = 0,
117    HNP_LOG_WARN    = 1,
118    HNP_LOG_ERROR   = 2,
119    HNP_LOG_DEBUG   = 3,
120    HNP_LOG_BUTT
121} HNP_LOG_LEVEL_E;
122
123/* 安装验签 */
124typedef struct HnpSignMapInfoStru {
125    char key[MAX_FILE_PATH_LEN];
126    char value[MAX_FILE_PATH_LEN];
127} HnpSignMapInfo;
128
129/* 数字索引 */
130enum {
131    HNP_INDEX_0 = 0,
132    HNP_INDEX_1,
133    HNP_INDEX_2,
134    HNP_INDEX_3,
135    HNP_INDEX_4,
136    HNP_INDEX_5,
137    HNP_INDEX_6,
138    HNP_INDEX_7
139};
140
141// 错误码生成
142#define HNP_ERRNO_HNP_MID               0x80
143#define HNP_ERRNO_HIGH16_MAKE()  (HNP_ERRNO_HNP_MID << 16)
144#define HNP_ERRNO_LOW16_MAKE(Mid, Errno)  (((Mid) << 8) + (Errno))
145#define HNP_ERRNO_COMMON(Mid, Errno) (HNP_ERRNO_HIGH16_MAKE() | HNP_ERRNO_LOW16_MAKE(Mid, Errno))
146
147#define HNP_ERRNO_PARAM_INVALID     0x22
148#define HNP_ERRNO_NOMEM             0x23
149
150enum {
151    HNP_MID_MAIN        = 0x10,
152    HNP_MID_BASE        = 0x11,
153    HNP_MID_PACK        = 0x12,
154    HNP_MID_INSTALLER   = 0x13
155};
156
157/* hnp_main模块*/
158// 0x801001 操作类型非法
159#define HNP_ERRNO_OPERATOR_TYPE_INVALID         HNP_ERRNO_COMMON(HNP_MID_MAIN, 0x1)
160
161// 0x801002 缺少必要的操作参数
162#define HNP_ERRNO_OPERATOR_ARGV_MISS            HNP_ERRNO_COMMON(HNP_MID_MAIN, 0x2)
163
164/* hnp_base模块*/
165// 0x801101 打开文件失败
166#define HNP_ERRNO_BASE_FILE_OPEN_FAILED         HNP_ERRNO_COMMON(HNP_MID_BASE, 0x1)
167
168// 0x801102 读取文件失败
169#define HNP_ERRNO_BASE_FILE_READ_FAILED         HNP_ERRNO_COMMON(HNP_MID_BASE, 0x2)
170
171// 0x801103 fseek设置失败
172#define HNP_ERRNO_BASE_FILE_SEEK_FAILED         HNP_ERRNO_COMMON(HNP_MID_BASE, 0x3)
173
174// 0x801104 ftell设置失败
175#define HNP_ERRNO_BASE_FILE_TELL_FAILED         HNP_ERRNO_COMMON(HNP_MID_BASE, 0x4)
176
177// 0x801105 realpath失败
178#define HNP_ERRNO_BASE_REALPATHL_FAILED         HNP_ERRNO_COMMON(HNP_MID_BASE, 0x5)
179
180// 0x801106 获取文件大小为0
181#define HNP_ERRNO_BASE_GET_FILE_LEN_NULL        HNP_ERRNO_COMMON(HNP_MID_BASE, 0x6)
182
183// 0x801107 字符串大小超出限制
184#define HNP_ERRNO_BASE_STRING_LEN_OVER_LIMIT    HNP_ERRNO_COMMON(HNP_MID_BASE, 0x7)
185
186// 0x801108 目录打开失败
187#define HNP_ERRNO_BASE_DIR_OPEN_FAILED          HNP_ERRNO_COMMON(HNP_MID_BASE, 0x8)
188
189// 0x801109 sprintf拼装失败
190#define HNP_ERRNO_BASE_SPRINTF_FAILED           HNP_ERRNO_COMMON(HNP_MID_BASE, 0x9)
191
192// 0x80110a 生成压缩文件失败
193#define HNP_ERRNO_BASE_CREATE_ZIP_FAILED        HNP_ERRNO_COMMON(HNP_MID_BASE, 0xa)
194
195// 0x80110b 写文件失败
196#define HNP_ERRNO_BASE_FILE_WRITE_FAILED        HNP_ERRNO_COMMON(HNP_MID_BASE, 0xb)
197
198// 0x80110c 拷贝失败
199#define HNP_ERRNO_BASE_COPY_FAILED              HNP_ERRNO_COMMON(HNP_MID_BASE, 0xc)
200
201// 0x80110d 获取文件属性失败
202#define HNP_ERRNO_GET_FILE_ATTR_FAILED          HNP_ERRNO_COMMON(HNP_MID_BASE, 0xd)
203
204// 0x80110e 解压缩打开文件失败
205#define HNP_ERRNO_BASE_UNZIP_OPEN_FAILED        HNP_ERRNO_COMMON(HNP_MID_BASE, 0xe)
206
207// 0x80110f 解压缩获取文件信息失败
208#define HNP_ERRNO_BASE_UNZIP_GET_INFO_FAILED    HNP_ERRNO_COMMON(HNP_MID_BASE, 0xf)
209
210// 0x801110 解压缩获取文件信息失败
211#define HNP_ERRNO_BASE_UNZIP_READ_FAILED        HNP_ERRNO_COMMON(HNP_MID_BASE, 0x10)
212
213// 0x801111 生成软链接失败
214#define HNP_ERRNO_GENERATE_SOFT_LINK_FAILED     HNP_ERRNO_COMMON(HNP_MID_BASE, 0x11)
215
216// 0x801112 进程正在运行
217#define HNP_ERRNO_PROCESS_RUNNING               HNP_ERRNO_COMMON(HNP_MID_BASE, 0x12)
218
219// 0x801113 入参失败
220#define HNP_ERRNO_BASE_PARAMS_INVALID           HNP_ERRNO_COMMON(HNP_MID_BASE, 0x13)
221
222// 0x801114 strdup失败
223#define HNP_ERRNO_BASE_STRDUP_FAILED            HNP_ERRNO_COMMON(HNP_MID_BASE, 0x14)
224
225// 0x801115 设置权限失败
226#define HNP_ERRNO_BASE_CHMOD_FAILED             HNP_ERRNO_COMMON(HNP_MID_BASE, 0x15)
227
228// 0x801116 删除目录失败
229#define HNP_ERRNO_BASE_UNLINK_FAILED            HNP_ERRNO_COMMON(HNP_MID_BASE, 0x16)
230
231// 0x801117 对应进程不存在
232#define HNP_ERRNO_BASE_PROCESS_NOT_FOUND        HNP_ERRNO_COMMON(HNP_MID_BASE, 0x17)
233
234// 0x801118 创建路径失败
235#define HNP_ERRNO_BASE_MKDIR_PATH_FAILED        HNP_ERRNO_COMMON(HNP_MID_BASE, 0x18)
236
237// 0x801119 读取配置文件流失败
238#define HNP_ERRNO_BASE_READ_FILE_STREAM_FAILED  HNP_ERRNO_COMMON(HNP_MID_BASE, 0x19)
239
240// 0x80111a 解析json信息失败
241#define HNP_ERRNO_BASE_PARSE_JSON_FAILED        HNP_ERRNO_COMMON(HNP_MID_BASE, 0x1a)
242
243// 0x80111b 未找到json项
244#define HNP_ERRNO_BASE_PARSE_ITEM_NO_FOUND      HNP_ERRNO_COMMON(HNP_MID_BASE, 0x1b)
245
246// 0x80111c 解析json数组失败
247#define HNP_ERRNO_BASE_GET_ARRAY_ITRM_FAILED    HNP_ERRNO_COMMON(HNP_MID_BASE, 0x1c)
248
249// 0x80111d 内存拷贝失败
250#define HNP_ERRNO_BASE_MEMCPY_FAILED            HNP_ERRNO_COMMON(HNP_MID_BASE, 0x1d)
251
252// 0x80111e 创建json数组失败
253#define HNP_ERRNO_BASE_JSON_ARRAY_CREATE_FAILED HNP_ERRNO_COMMON(HNP_MID_BASE, 0x1e)
254
255// 0x80111f 获取文件属性失败
256#define HNP_ERRNO_BASE_STAT_FAILED              HNP_ERRNO_COMMON(HNP_MID_BASE, 0x1f)
257
258int GetFileSizeByHandle(FILE *file, int *size);
259
260int ReadFileToStream(const char *filePath, char **stream, int *streamLen);
261
262int GetRealPath(char *srcPath, char *realPath);
263
264int HnpZip(const char *inputDir, zipFile zf);
265
266int HnpUnZip(const char *inputFile, const char *outputDir, const char *hnpSignKeyPrefix,
267    HnpSignMapInfo *hnpSignMapInfos, int *count);
268
269int HnpAddFileToZip(zipFile zf, char *filename, char *buff, int size);
270
271void HnpLogPrintf(int logLevel, char *module, const char *format, ...);
272
273int HnpCfgGetFromZip(const char *inputFile, HnpCfgInfo *hnpCfg);
274
275int HnpSymlink(const char *srcFile, const char *dstFile);
276
277int HnpProcessRunCheck(const char *runPath);
278
279int HnpDeleteFolder(const char *path);
280
281int HnpCreateFolder(const char* path);
282
283
284int ParseHnpCfgFile(const char *hnpCfgPath, HnpCfgInfo *hnpCfg);
285
286int GetHnpJsonBuff(HnpCfgInfo *hnpCfg, char **buff);
287
288int HnpCfgGetFromSteam(char *cfgStream, HnpCfgInfo *hnpCfg);
289
290int HnpInstallInfoJsonWrite(const char *hapPackageName, const HnpCfgInfo *hnpCfg);
291
292int HnpPackageInfoGet(const char *packageName, HnpPackageInfo **packageInfoOut, int *count);
293
294int HnpPackageInfoHnpDelete(const char *packageName, const char *name, const char *version);
295
296int HnpPackageInfoDelete(const char *packageName);
297
298char *HnpCurrentVersionUninstallCheck(const char *name);
299
300int HnpFileCountGet(const char *path, int *count);
301
302int HnpPathFileCount(const char *path);
303
304char *HnpCurrentVersionGet(const char *name);
305
306#ifdef HNP_CLI
307#define HNP_LOGI(args, ...) \
308    HnpLogPrintf(HNP_LOG_INFO, "HNP", "[%{public}s:%{public}d]" args, (__FILE_NAME__), (__LINE__), ##__VA_ARGS__)
309#else
310#define HNP_LOGI(args, ...) \
311    HILOG_INFO(LOG_CORE, "[%{public}s:%{public}d]" args, (__FILE_NAME__), (__LINE__), ##__VA_ARGS__); \
312    HnpLogPrintf(HNP_LOG_INFO, "HNP", "[%{public}s:%{public}d]" args, (__FILE_NAME__), (__LINE__), ##__VA_ARGS__)
313#endif
314
315#ifdef HNP_CLI
316#define HNP_LOGE(args, ...) \
317    HnpLogPrintf(HNP_LOG_ERROR, "HNP", "[%{public}s:%{public}d]" args, (__FILE_NAME__), (__LINE__), ##__VA_ARGS__)
318#else
319#define HNP_LOGE(args, ...) \
320    HILOG_ERROR(LOG_CORE, "[%{public}s:%{public}d]" args, (__FILE_NAME__), (__LINE__), ##__VA_ARGS__); \
321    HnpLogPrintf(HNP_LOG_ERROR, "HNP", "[%{public}s:%{public}d]" args, (__FILE_NAME__), (__LINE__), ##__VA_ARGS__)
322#endif
323
324#ifdef __cplusplus
325}
326#endif
327
328#endif