Native软件包管理打包功能代码

Signed-off-by: 郭桦炜 <guohuawei1@huawei.com>
This commit is contained in:
郭桦炜 2024-02-28 02:17:18 +00:00
parent abe72dec27
commit dd0ae0d1d7
15 changed files with 1469 additions and 1 deletions

View File

@ -206,6 +206,7 @@ group("appspawn_all") {
deps += [ ":appspawn_server" ]
deps += [ "etc:etc_files" ]
deps += [ "interfaces/innerkits:appspawn_socket_client" ]
deps += [ "service/hnp:hnp" ]
} else {
deps += [ "lite:appspawn_lite" ]
}

View File

@ -56,7 +56,9 @@
"ace_engine_lite",
"surface_lite",
"ui_lite",
"code_signature"
"code_signature",
"bounds_checking_function",
"zlib"
],
"third_party": [
"bounds_checking_function",

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HNP_API_H
#define HNP_API_H
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
FALSE,
TRUE
} Bool;
#define HNP_API_ERRNO_BASE 0x2000
// 0x2001 参数非法
#define HNP_API_ERRNO_PARAM_INVALID (HNP_API_ERRNO_BASE + 0x1)
// 0x2002 fork子进程失败
#define HNP_API_ERRNO_FORK_FAILED (HNP_API_ERRNO_BASE + 0x2)
// 0x2003 等待子进程退出失败
#define HNP_API_WAIT_PID_FAILED (HNP_API_ERRNO_BASE + 0x3)
/**
* Install native software package.
*
* @param userId Indicates id of user.
* @param hnpPath Indicates the directory path of hnp file.
* @param isForce Indicates whether to force install.
*
* @return 0:success;other means failure.
*/
int NativeInstallHnp(const char *userId, const char *hnpPath, Bool isForce);
/**
* Uninstall native software package.
*
* @param userId Indicates id of user.
* @param hnpName Indicates the name of native software.
* @param hnpVersion Indicates the version of native software.
*
* @return 0:success;other means failure.
*/
int NativeUnInstallHnp(const char *userId, const char *hnpName, const char *hnpVersion);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,127 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>
#include "hilog/log.h"
#include "hnp_api.h"
#ifdef __cplusplus
extern "C" {
#endif
#define HNPAPI_LOG(fmt, ...) \
HILOG_INFO(LOG_CORE, "[%{public}s:%{public}d]" fmt, (__FILE_NAME__), (__LINE__), ##__VA_ARGS__)
#define MAX_ARGV_NUM 256
#define MAX_ENV_NUM (128 + 2)
/* 数字索引 */
enum {
HNP_INDEX_0 = 0,
HNP_INDEX_1,
HNP_INDEX_2,
HNP_INDEX_3,
HNP_INDEX_4,
HNP_INDEX_5,
HNP_INDEX_6,
HNP_INDEX_7
};
static int StartHnpProcess(char *const argv[], char *const apcEnv[])
{
pid_t pid;
int ret;
int status;
int exitVal = -1;
pid = vfork();
if (pid < 0) {
HNPAPI_LOG("\r\n [HNP API] fork unsuccess!\r\n");
return HNP_API_ERRNO_FORK_FAILED;
} else if (pid == 0) {
HNPAPI_LOG("\r\n [HNP API] this is fork children!\r\n");
ret = execve("./hnp", argv, apcEnv);
if (ret < 0) {
HNPAPI_LOG("\r\n [HNP API] execve unsuccess!\r\n");
_exit(-1);
}
_exit(0);
}
HNPAPI_LOG("\r\n [HNP API] this is fork father! chid=%d\r\n", pid);
if (waitpid(pid, &status, 0) == -1) {
HNPAPI_LOG("\r\n [HNP API] wait pid unsuccess!\r\n");
return HNP_API_WAIT_PID_FAILED;
}
if (WIFEXITED(status)) {
exitVal = WEXITSTATUS(status);
}
if (WIFSIGNALED(status)) {
exitVal = WTERMSIG(status);
}
HNPAPI_LOG("\r\n [HNP API] Child process exited with exitval=%d\r\n", exitVal);
return exitVal;
}
int NativeInstallHnp(const char *userId, const char *hnpPath, Bool isForce)
{
char *argv[MAX_ARGV_NUM] = {0};
char *apcEnv[MAX_ENV_NUM] = {0};
if ((userId == NULL) || (hnpPath == NULL)) {
return HNP_API_ERRNO_PARAM_INVALID;
}
HNPAPI_LOG("\r\n [HNP API] native package install! userId=%s, hnpPath=%s, IsForce=%d\r\n",
userId, hnpPath, isForce);
argv[HNP_INDEX_0] = "hnp";
argv[HNP_INDEX_1] = "install";
argv[HNP_INDEX_2] = (char*)userId;
argv[HNP_INDEX_3] = (char*)hnpPath;
return StartHnpProcess(argv, apcEnv);
}
int NativeUnInstallHnp(const char *userId, const char *hnpName, const char *hnpVersion)
{
char *argv[MAX_ARGV_NUM] = {0};
char *apcEnv[MAX_ENV_NUM] = {0};
if ((userId == NULL) || (hnpName == NULL) || (hnpVersion == NULL)) {
return HNP_API_ERRNO_PARAM_INVALID;
}
HNPAPI_LOG("\r\n [HNP API] native package uninstall! userId=%s, hnpName=%s, hnpVersion=%s\r\n",
userId, hnpName, hnpVersion);
argv[HNP_INDEX_0] = "hnp";
argv[HNP_INDEX_1] = "uninstall";
argv[HNP_INDEX_2] = (char*)userId;
argv[HNP_INDEX_3] = (char*)hnpName;
argv[HNP_INDEX_4] = (char*)hnpVersion;
return StartHnpProcess(argv, apcEnv);
}
#ifdef __cplusplus
}
#endif

87
service/hnp/BUILD.gn Normal file
View File

@ -0,0 +1,87 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//base/startup/appspawn/appspawn.gni")
import("//build/ohos.gni")
if (!defined(ohos_lite)) {
ohos_executable("hnp") {
include_dirs = [
"base",
"installer/include",
]
sources = [
"${appspawn_path}/service/hnp/base/hnp_file.c",
"${appspawn_path}/service/hnp/base/hnp_log.c",
"${appspawn_path}/service/hnp/base/hnp_zip.c",
"${appspawn_path}/service/hnp/hnp_main.c",
"${appspawn_path}/service/hnp/installer/src/hnp_installer.c",
]
configs = []
cflags = []
deps = [ "//third_party/cJSON:cjson" ]
external_deps = [
"bounds_checking_function:libsec_shared",
"hilog:libhilog",
"zlib:shared_libz",
]
install_enable = true
subsystem_name = "${subsystem_name}"
part_name = "${part_name}"
}
ohos_executable("hnpcli") {
include_dirs = [
"pack/include",
"base",
]
sources = [
"${appspawn_path}/service/hnp/base/hnp_file.c",
"${appspawn_path}/service/hnp/base/hnp_log.c",
"${appspawn_path}/service/hnp/base/hnp_zip.c",
"${appspawn_path}/service/hnp/hnpcli_main.c",
"${appspawn_path}/service/hnp/pack/src/hnp_pack.c",
]
configs = []
cflags = []
deps = [ "//third_party/cJSON:cjson" ]
external_deps = [
"bounds_checking_function:libsec_shared",
"hilog:libhilog",
"zlib:shared_libz",
]
install_enable = true
subsystem_name = "${subsystem_name}"
part_name = "${part_name}"
}
ohos_shared_library("hnpapi") {
include_dirs = [ "${appspawn_path}/interfaces/innerkits/hnp/include" ]
sources = [ "${appspawn_path}/interfaces/innerkits/hnp/src/hnp_api.c" ]
configs = []
defines = []
cflags = [
"-fvisibility=hidden",
"-fstack-protector-all",
]
external_deps = [ "hilog:libhilog" ]
install_enable = true
subsystem_name = "${subsystem_name}"
part_name = "${part_name}"
}
}
group("hnpcli_host_toolchain") {
deps = [ ":hnpcli($host_toolchain)" ]
}

164
service/hnp/base/hnp_base.h Normal file
View File

@ -0,0 +1,164 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HNP_BASE_H
#define HNP_BASE_H
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "securec.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MAX_FILE_PATH_LEN PATH_MAX
#define HNP_HEAD_MAGIC 0x12345678
#define HNP_HEAD_VERSION 1
#define HNP_VERSION_LEN 32
#ifdef _WIN32
#define DIR_SPLIT_SYMBOL '\\'
#else
#define DIR_SPLIT_SYMBOL '/'
#endif
/* Native软件二进制软链接配置 */
typedef struct NativeBinLinkStru {
char source[MAX_FILE_PATH_LEN];
char target[MAX_FILE_PATH_LEN];
} NativeBinLink;
/* hnp文件头结构 */
typedef struct NativeHnpHeadStru {
unsigned int magic; // 魔术字校验
unsigned int version; // 版本号
unsigned int headLen; // hnp结构头大小
unsigned int reserve; // 预留字段
char hnpVersion[HNP_VERSION_LEN]; // Native软件包版本号
unsigned int linkNum; // 软链接配置个数
NativeBinLink links[0];
} NativeHnpHead;
/* 日志级别 */
typedef enum {
HNP_LOG_INFO = 0,
HNP_LOG_WARN = 1,
HNP_LOG_ERROR = 2,
HNP_LOG_DEBUG = 3,
HNP_LOG_BUTT
} HNP_LOG_LEVEL_E;
/* 数字索引 */
enum {
HNP_INDEX_0 = 0,
HNP_INDEX_1,
HNP_INDEX_2,
HNP_INDEX_3,
HNP_INDEX_4,
HNP_INDEX_5,
HNP_INDEX_6,
HNP_INDEX_7
};
// 错误码生成
#define HNP_ERRNO_HNP_MID 0x80
#define HNP_ERRNO_HIGH16_MAKE() (HNP_ERRNO_HNP_MID << 16)
#define HNP_ERRNO_LOW16_MAKE(Mid, Errno) (((Mid) << 8) + (Errno))
#define HNP_ERRNO_COMMON(Mid, Errno) (HNP_ERRNO_HIGH16_MAKE() | HNP_ERRNO_LOW16_MAKE(Mid, Errno))
#define HNP_ERRNO_PARAM_INVALID 0x22
#define HNP_ERRNO_NOMEM 0x23
enum {
HNP_MID_MAIN = 0x10,
HNP_MID_BASE = 0x11,
HNP_MID_PACK = 0x12,
HNP_MID_INSTALLER = 0x13
};
/* hnp_main模块*/
// 0x801001 操作类型非法
#define HNP_ERRNO_OPERATOR_TYPE_INVALID HNP_ERRNO_COMMON(HNP_MID_MAIN, 0x1)
/* hnp_base模块*/
// 0x801101 打开文件失败
#define HNP_ERRNO_BASE_FILE_OPEN_FAILED HNP_ERRNO_COMMON(HNP_MID_BASE, 0x1)
// 0x801102 读取文件失败
#define HNP_ERRNO_BASE_FILE_READ_FAILED HNP_ERRNO_COMMON(HNP_MID_BASE, 0x2)
// 0x801103 fseek设置失败
#define HNP_ERRNO_BASE_FILE_SEEK_FAILED HNP_ERRNO_COMMON(HNP_MID_BASE, 0x3)
// 0x801104 ftell设置失败
#define HNP_ERRNO_BASE_FILE_TELL_FAILED HNP_ERRNO_COMMON(HNP_MID_BASE, 0x4)
// 0x801105 realpath失败
#define HNP_ERRNO_BASE_REALPATHL_FAILED HNP_ERRNO_COMMON(HNP_MID_BASE, 0x5)
// 0x801106 获取文件大小为0
#define HNP_ERRNO_BASE_GET_FILE_LEN_NULL HNP_ERRNO_COMMON(HNP_MID_BASE, 0x6)
// 0x801107 字符串大小超出限制
#define HNP_ERRNO_BASE_STRING_LEN_OVER_LIMIT HNP_ERRNO_COMMON(HNP_MID_BASE, 0x7)
// 0x801108 目录打开失败
#define HNP_ERRNO_BASE_DIR_OPEN_FAILED HNP_ERRNO_COMMON(HNP_MID_BASE, 0x8)
// 0x801109 sprintf拼装失败
#define HNP_ERRNO_BASE_SPRINTF_FAILED HNP_ERRNO_COMMON(HNP_MID_BASE, 0x9)
// 0x80110a 生成压缩文件失败
#define HNP_ERRNO_BASE_CREATE_ZIP_FAILED HNP_ERRNO_COMMON(HNP_MID_BASE, 0xa)
// 0x80110b 写文件失败
#define HNP_ERRNO_BASE_FILE_WRITE_FAILED HNP_ERRNO_COMMON(HNP_MID_BASE, 0xb)
// 0x80110c 拷贝失败
#define HNP_ERRNO_BASE_COPY_FAILED HNP_ERRNO_COMMON(HNP_MID_BASE, 0xc)
// 0x80110d 获取文件属性失败
#define HNP_ERRNO_GET_FILE_ATTR_FAILED HNP_ERRNO_COMMON(HNP_MID_BASE, 0xd)
int GetFileSizeByHandle(FILE *file, int *size);
int ReadFileToStream(const char *filePath, char **stream, int *streamLen);
int GetRealPath(char *srcPath, char *realPath);
int HnpZip(const char *inputDir, const char *outputFile);
int HnpUnZip(const char *inputFile, const char *outputDir);
int HnpWriteToZipHead(const char *zipFile, char *buff, int len);
void HnpLogPrintf(int logLevel, char *module, const char *format, ...);
#define HNP_LOGI(args...) \
HnpLogPrintf(HNP_LOG_INFO, "HNP", ##args)
#define HNP_LOGE(args...) \
HnpLogPrintf(HNP_LOG_ERROR, "HNP", ##args)
#ifdef __cplusplus
}
#endif
#endif

124
service/hnp/base/hnp_file.c Normal file
View File

@ -0,0 +1,124 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#ifdef _WIN32
#include <windows.h>
#endif
#include "hnp_base.h"
#ifdef __cplusplus
extern "C" {
#endif
int GetFileSizeByHandle(FILE *file, int *size)
{
int ret;
int len;
ret = fseek(file, 0, SEEK_END);
if (ret != 0) {
HNP_LOGE("fseek end unsuccess.");
return HNP_ERRNO_BASE_FILE_SEEK_FAILED;
}
len = ftell(file);
if (len < 0) {
HNP_LOGE("ftell unsuccess. len=%d", len);
return HNP_ERRNO_BASE_FILE_TELL_FAILED;
}
ret = fseek(file, 0, SEEK_SET);
if (ret != 0) {
HNP_LOGE("fseek set unsuccess. ");
return HNP_ERRNO_BASE_FILE_SEEK_FAILED;
}
*size = len;
return 0;
}
int ReadFileToStream(const char *filePath, char **stream, int *streamLen)
{
int ret;
FILE *file;
int size = 0;
char *streamTmp;
file = fopen(filePath, "rb");
if (file == NULL) {
HNP_LOGE("open file[%s] unsuccess. ", filePath);
return HNP_ERRNO_BASE_FILE_OPEN_FAILED;
}
ret = GetFileSizeByHandle(file, &size);
if (ret != 0) {
HNP_LOGE("get file[%s] size unsuccess.", filePath);
(void)fclose(file);
return ret;
}
if (size == 0) {
HNP_LOGE("get file[%s] size is null.", filePath);
return HNP_ERRNO_BASE_GET_FILE_LEN_NULL;
}
streamTmp = (char*)malloc(size);
if (streamTmp == NULL) {
HNP_LOGE("malloc unsuccess. size=%d", size);
(void)fclose(file);
return HNP_ERRNO_NOMEM;
}
ret = fread(streamTmp, sizeof(char), size, file);
if (ret != size) {
HNP_LOGE("fread unsuccess. ret=%d, size=%d", ret, size);
(void)fclose(file);
free(streamTmp);
return HNP_ERRNO_BASE_FILE_READ_FAILED;
}
*stream = streamTmp;
*streamLen = size;
(void)fclose(file);
return 0;
}
int GetRealPath(char *srcPath, char *realPath)
{
char dstTmpPath[PATH_MAX];
if (srcPath == NULL || realPath == NULL) {
return HNP_ERRNO_PARAM_INVALID;
}
#ifdef _WIN32
DWORD ret = GetFullPathName(srcPath, PATH_MAX, dstTmpPath, NULL);
#else
char *ret = realpath(srcPath, dstTmpPath);
#endif
if (ret == 0) {
HNP_LOGE("realpath unsuccess. path=%s", srcPath);
return HNP_ERRNO_BASE_REALPATHL_FAILED;
}
if (strlen(dstTmpPath) >= MAX_FILE_PATH_LEN) {
HNP_LOGE("realpath over max path len. len=%d", strlen(dstTmpPath));
return HNP_ERRNO_BASE_STRING_LEN_OVER_LIMIT;
}
if (strcpy_s(realPath, MAX_FILE_PATH_LEN, dstTmpPath) != EOK) {
HNP_LOGE("strcpy unsuccess.");
return HNP_ERRNO_BASE_COPY_FAILED;
}
return 0;
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdarg.h>
#include "securec.h"
#include "hnp_base.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MAX_LOG_BUFF_LEN 1024
const char *g_logLevelName[HNP_LOG_BUTT] = {"INFO", "WARN", "ERROR", "DEBUG"};
void HnpLogPrintf(int logLevel, char *module, const char *format, ...)
{
int ret;
ret = fprintf(stdout, "\n[%s][%s]", g_logLevelName[logLevel], module);
if (ret < 0) {
return;
}
va_list args;
va_start(args, format);
ret = vfprintf(stdout, format, args);
va_end(args);
if (ret < 0) {
return;
}
return;
}
#ifdef __cplusplus
}
#endif

237
service/hnp/base/hnp_zip.c Normal file
View File

@ -0,0 +1,237 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#ifdef _WIN32
#include <windows.h>
#endif
#include "zlib.h"
#include "contrib/minizip/zip.h"
#include "securec.h"
#include "hnp_base.h"
#ifdef __cplusplus
extern "C" {
#endif
// 向zip压缩包中添加文件
static int ZipAddFile(const char* file, int offset, zipFile zf)
{
int err;
char buf[1024];
int len;
FILE *f;
err = zipOpenNewFileInZip3(zf, file + offset, NULL, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_BEST_COMPRESSION,
0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, NULL, 0);
if (err != ZIP_OK) {
HNP_LOGE("open new file[%s] in zip unsuccess ", file);
return HNP_ERRNO_BASE_CREATE_ZIP_FAILED;
}
f = fopen(file, "rb");
if (f == NULL) {
HNP_LOGE("open file[%s] unsuccess ", file);
return HNP_ERRNO_BASE_FILE_OPEN_FAILED;
}
while ((len = fread(buf, 1, sizeof(buf), f)) > 0) {
zipWriteInFileInZip(zf, buf, len);
}
(void)fclose(f);
zipCloseFileInZip(zf);
return 0;
}
// 判断是否为目录
static int IsDirPath(struct dirent *entry, char *fullPath, int *isDir)
{
#ifdef _WIN32
DWORD fileAttr = GetFileAttributes(fullPath);
if (fileAttr == INVALID_FILE_ATTRIBUTES) {
HNP_LOGE("get file[%s] attr unsuccess.", fullPath);
return HNP_ERRNO_GET_FILE_ATTR_FAILED;
}
*isDir = (int)(fileAttr & FILE_ATTRIBUTE_DIRECTORY);
#else
*isDir = (int)(entry->d_type == DT_DIR);
#endif
return 0;
}
// sourcePath--文件夹路径 zf--压缩文件句柄
static int ZipAddDir(const char *sourcePath, int offset, zipFile zf)
{
struct dirent *entry;
char fullPath[MAX_FILE_PATH_LEN];
int isDir;
DIR *dir = opendir(sourcePath);
if (dir == NULL) {
HNP_LOGE("open dir=%s unsuccess ", sourcePath);
return HNP_ERRNO_BASE_DIR_OPEN_FAILED;
}
while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
if (sprintf_s(fullPath, MAX_FILE_PATH_LEN, "%s%c%s", sourcePath, DIR_SPLIT_SYMBOL, entry->d_name) < 0) {
HNP_LOGE("sprintf unsuccess.");
closedir(dir);
return HNP_ERRNO_BASE_SPRINTF_FAILED;
}
int ret = IsDirPath(entry, fullPath, &isDir);
if (ret != 0) {
closedir(dir);
return ret;
}
if (isDir) {
int endPos = strlen(fullPath);
fullPath[endPos] = DIR_SPLIT_SYMBOL;
fullPath[endPos + 1] = '\0';
if (zipOpenNewFileInZip3(zf, fullPath + offset, NULL, NULL, 0, NULL, 0, NULL, Z_DEFLATED,
Z_BEST_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, NULL, 0) != ZIP_OK) {
HNP_LOGE("open new file[%s] in zip unsuccess ", fullPath);
closedir(dir);
return HNP_ERRNO_BASE_CREATE_ZIP_FAILED;
}
zipCloseFileInZip(zf);
if ((ret = ZipAddDir(fullPath, offset, zf)) != 0) {
HNP_LOGE("zip add dir[%s] unsuccess ", fullPath);
closedir(dir);
return ret;
}
} else {
if ((ret = ZipAddFile(fullPath, offset, zf)) != 0) {
HNP_LOGE("zip add file[%s] unsuccess ", fullPath);
closedir(dir);
return ret;
}
}
}
closedir(dir);
return 0;
}
static int ZipDir(const char *sourcePath, int offset, const char *zipPath)
{
int ret;
zipFile zf = zipOpen(zipPath, APPEND_STATUS_CREATE);
if (zf == NULL) {
HNP_LOGE("open zip=%s unsuccess ", zipPath);
return HNP_ERRNO_BASE_CREATE_ZIP_FAILED;
}
// 将外层文件夹信息保存到zip文件中
ret = zipOpenNewFileInZip3(zf, sourcePath + offset, NULL, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_BEST_COMPRESSION,
0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, NULL, 0);
if (ret != ZIP_OK) {
HNP_LOGE("open new file[%s] in zip unsuccess ", sourcePath + offset);
zipClose(zf, NULL);
return HNP_ERRNO_BASE_CREATE_ZIP_FAILED;
}
zipCloseFileInZip(zf);
ret = ZipAddDir(sourcePath, offset, zf);
zipClose(zf, NULL);
return ret;
}
int HnpZip(const char *inputDir, const char *outputFile)
{
int ret;
char *strPtr;
int offset;
char sourcePath[MAX_FILE_PATH_LEN];
HNP_LOGI("HnpZip dir=%s, output=%s ", inputDir, outputFile);
// zip压缩文件内只保存相对路径不保存绝对路径信息偏移到压缩文件夹位置
strPtr = strrchr(inputDir, DIR_SPLIT_SYMBOL);
if (strPtr == NULL) {
offset = 0;
} else {
offset = strPtr - inputDir + 1;
}
// zip函数根据后缀是否'/'区分目录还是文件
ret = sprintf_s(sourcePath, MAX_FILE_PATH_LEN, "%s%c", inputDir, DIR_SPLIT_SYMBOL);
if (ret < 0) {
HNP_LOGE("sprintf unsuccess.");
return HNP_ERRNO_BASE_SPRINTF_FAILED;
}
ret = ZipDir(sourcePath, offset, outputFile);
return ret;
}
int HnpUnZip(const char *inputFile, const char *outputDir)
{
HNP_LOGI("HnpUnZip zip=%s, output=%s", inputFile, outputDir);
return -1;
}
int HnpWriteToZipHead(const char *zipFile, char *buff, int len)
{
int size;
char *buffTmp;
int ret = ReadFileToStream(zipFile, &buffTmp, &size);
if (ret != 0) {
HNP_LOGE("read file:%s to stream unsuccess!", zipFile);
return ret;
}
FILE *fp = fopen(zipFile, "w");
if (fp == NULL) {
free(buffTmp);
HNP_LOGE("open file:%s unsuccess!", zipFile);
return HNP_ERRNO_BASE_FILE_OPEN_FAILED;
}
int writeLen = fwrite(buff, sizeof(char), len, fp);
if (writeLen != len) {
HNP_LOGE("write file:%s unsuccess! len=%d, write=%d", zipFile, len, writeLen);
(void)fclose(fp);
free(buffTmp);
return HNP_ERRNO_BASE_FILE_WRITE_FAILED;
}
writeLen = fwrite(buffTmp, sizeof(char), size, fp);
(void)fclose(fp);
free(buffTmp);
if (writeLen != size) {
HNP_LOGE("write file:%s unsuccess! size=%d, write=%d", zipFile, size, writeLen);
return HNP_ERRNO_BASE_FILE_WRITE_FAILED;
}
return 0;
}
#ifdef __cplusplus
}
#endif

99
service/hnp/hnp_main.c Normal file
View File

@ -0,0 +1,99 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string.h>
#include "hnp_base.h"
#include "hnp_installer.h"
#ifdef __cplusplus
extern "C" {
#endif
extern int HnpShowHelp(int argc, char *argv[]);
typedef int (*HNP_CMD_PROCESS_FUNC)(int argc, char *argv[]);
typedef struct NativeManagerCmdInfoStru {
char *cmd;
HNP_CMD_PROCESS_FUNC process;
} NativeManagerCmdInfo;
NativeManagerCmdInfo g_nativeManagerCmd[] = {
{"help", HnpShowHelp},
{"install", HnpCmdInstall},
{"uninstall", HnpCmdUnInstall}
};
int HnpShowHelp(int argc, char *argv[])
{
(void)argc;
(void)argv;
HNP_LOGI("\r\nusage:hnp <command> <args>\r\n"
"\r\nThese are common hnp commands used in various situations:\r\n"
"\r\ninstall: install native software"
"\r\n hnp install [user id] [hnp package dir] <-f>\r\n"
"\r\nuninstall: uninstall native software"
"\r\n hnp uninstall [user id] [software name] [software version]\r\n"
"\r\nfor example:\r\n"
"\r\n hnp install /usr1/hnp 1000 -f\r\n"
" hnp uninstall 1000 native_sample 1.1\r\n");
return 0;
}
static NativeManagerCmdInfo* HnpCmdCheck(const char *cmd)
{
int i;
int cmdNum = sizeof(g_nativeManagerCmd) / sizeof(NativeManagerCmdInfo);
for (i = 0; i < cmdNum; i++) {
if (!strcmp(cmd, g_nativeManagerCmd[i].cmd)) {
return &g_nativeManagerCmd[i];
}
}
return NULL;
}
int main(int argc, char *argv[])
{
int ret;
NativeManagerCmdInfo *cmdInfo = NULL;
if (argc < HNP_INDEX_2) {
HnpShowHelp(argc, argv);
return HNP_ERRNO_PARAM_INVALID;
}
HNP_LOGI("native manager process start.");
/* 检验用户命令,获取对应的处理函数 */
cmdInfo = HnpCmdCheck(argv[HNP_INDEX_1]);
if (cmdInfo == NULL) {
HNP_LOGE("invalid cmd!. cmd:%s", argv[HNP_INDEX_1]);
return HNP_ERRNO_OPERATOR_TYPE_INVALID;
}
/* 执行命令 */
ret = cmdInfo->process(argc, argv);
HNP_LOGI("native manager process exit. ret=%d ", ret);
return ret;
}
#ifdef __cplusplus
}
#endif

98
service/hnp/hnpcli_main.c Normal file
View File

@ -0,0 +1,98 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string.h>
#include "hnp_base.h"
#include "hnp_pack.h"
#ifdef __cplusplus
extern "C" {
#endif
extern int HnpCliShowHelp(int argc, char *argv[]);
typedef int (*HNP_CMD_PROCESS_FUNC)(int argc, char *argv[]);
typedef struct NativeManagerCmdInfoStru {
char *cmd;
HNP_CMD_PROCESS_FUNC process;
} NativeManagerCmdInfo;
NativeManagerCmdInfo g_nativeManagerCmd[] = {
{"help", HnpCliShowHelp},
{"pack", HnpCmdPack}
};
int HnpCliShowHelp(int argc, char *argv[])
{
(void)argc;
(void)argv;
HNP_LOGI("\r\nusage:hnpcli <command> <args> [-cfg <link cfg file>][-name <native package name>]"
"[-v <native package version>]\r\n"
"\r\nThese are common hnp commands used in various situations:\r\n"
"\r\npack: packet native software package to .hnp file"
"\r\n hnpcli pack [source path] [dst path] -name [software name] -v [software version]"
"\r\n hnpcli pack [source path] [dst path] -cfg [link config file]\r\n"
"\r\nfor example:\r\n"
"\r\n hnpcli pack /usr1/native_sample /usr1/output -name native_sample -v 1.1\r\n"
" hnpcli pack /usr1/native_sample /usr1/output -cfg /usr1/native_sample.cfg\r\n");
return 0;
}
static NativeManagerCmdInfo* HnpCmdCheck(const char *cmd)
{
int i;
int cmdNum = sizeof(g_nativeManagerCmd) / sizeof(NativeManagerCmdInfo);
for (i = 0; i < cmdNum; i++) {
if (!strcmp(cmd, g_nativeManagerCmd[i].cmd)) {
return &g_nativeManagerCmd[i];
}
}
return NULL;
}
int main(int argc, char *argv[])
{
int ret;
NativeManagerCmdInfo *cmdInfo = NULL;
if (argc < HNP_INDEX_2) {
HnpCliShowHelp(argc, argv);
return HNP_ERRNO_PARAM_INVALID;
}
HNP_LOGI("native manager process start.");
/* 检验用户命令,获取对应的处理函数 */
cmdInfo = HnpCmdCheck(argv[HNP_INDEX_1]);
if (cmdInfo == NULL) {
HNP_LOGE("invalid cmd!. cmd:%s", argv[HNP_INDEX_1]);
return HNP_ERRNO_OPERATOR_TYPE_INVALID;
}
/* 执行命令 */
ret = cmdInfo->process(argc, argv);
HNP_LOGI("native manager process exit. ret=%d ", ret);
return ret;
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HNP_INSTALLER_H
#define HNP_INSTALLER_H
#ifdef __cplusplus
extern "C" {
#endif
int HnpCmdInstall(int argc, char *argv[]);
int HnpCmdUnInstall(int argc, char *argv[]);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "hnp_base.h"
#ifdef __cplusplus
extern "C" {
#endif
int HnpCmdInstall(int argc, char *argv[])
{
HNP_LOGI("\r\ninstall cmd not support now!");
return -1;
}
int HnpCmdUnInstall(int argc, char *argv[])
{
HNP_LOGI("\r\nuninstall cmd not support now!");
return -1;
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HNP_PACK_H
#define HNP_PACK_H
#include "hnp_base.h"
#ifdef __cplusplus
extern "C" {
#endif
// 0x801201 打包命令参数错误
#define HNP_ERRNO_PACK_ARGV_NUM_INVALID HNP_ERRNO_COMMON(HNP_MID_PACK, 0x1)
// 0x801202 获取绝对路径失败
#define HNP_ERRNO_PACK_GET_REALPATH_FAILED HNP_ERRNO_COMMON(HNP_MID_PACK, 0x2)
// 0x801203 缺少操作参数
#define HNP_ERRNO_PACK_MISS_OPERATOR_PARAM HNP_ERRNO_COMMON(HNP_MID_PACK, 0x3)
// 0x801204 读取配置文件流失败
#define HNP_ERRNO_PACK_READ_FILE_STREAM_FAILED HNP_ERRNO_COMMON(HNP_MID_PACK, 0x4)
// 0x801205 解析json信息失败
#define HNP_ERRNO_PACK_PARSE_JSON_FAILED HNP_ERRNO_COMMON(HNP_MID_PACK, 0x5)
// 0x801206 未找到json项
#define HNP_ERRNO_PACK_PARSE_ITEM_NO_FOUND HNP_ERRNO_COMMON(HNP_MID_PACK, 0x6)
// 0x801207 解析json数组失败
#define HNP_ERRNO_PACK_GET_ARRAY_ITRM_FAILED HNP_ERRNO_COMMON(HNP_MID_PACK, 0x7)
// 0x801208 组装hnp输出路径失败
#define HNP_ERRNO_PACK_GET_HNP_PATH_FAILED HNP_ERRNO_COMMON(HNP_MID_PACK, 0x8)
// 0x801209 压缩目录失败
#define HNP_ERRNO_PACK_ZIP_DIR_FAILED HNP_ERRNO_COMMON(HNP_MID_PACK, 0x9)
int HnpCmdPack(int argc, char *argv[]);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,286 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include "securec.h"
#include "cJSON.h"
#include "hnp_pack.h"
#ifdef __cplusplus
extern "C" {
#endif
static int PackHnp(const char *hnpSrcPath, const char *hnpDstPath, const char *hnpName, NativeHnpHead *hnpHead)
{
int ret;
char hnp_file_path[MAX_FILE_PATH_LEN];
HNP_LOGI("PackHnp start. srcPath=%s, hnpName=%s, hnpVer=%s, hnpDstPath=%s ",
hnpSrcPath, hnpName, hnpHead->hnpVersion, hnpDstPath);
/* 拼接hnp文件名 */
ret = sprintf_s(hnp_file_path, MAX_FILE_PATH_LEN, "%s/%s.hnp", hnpDstPath, hnpName);
if (ret < 0) {
HNP_LOGE("sprintf unsuccess.");
return HNP_ERRNO_PACK_GET_HNP_PATH_FAILED;
}
/* 将软件包压缩成独立的.hnp文件 */
ret = HnpZip(hnpSrcPath, hnp_file_path);
if (ret != 0) {
HNP_LOGE("zip dir unsuccess! srcPath=%s, hnpName=%s, hnpVer=%s, hnpDstPath=%s ret=%d",
hnpSrcPath, hnpName, hnpHead->hnpVersion, hnpDstPath, ret);
return HNP_ERRNO_PACK_ZIP_DIR_FAILED;
}
hnpHead->magic = HNP_HEAD_MAGIC;
hnpHead->version = HNP_HEAD_VERSION;
hnpHead->headLen = sizeof(NativeHnpHead) + hnpHead->linkNum * sizeof(NativeBinLink);
/* 向生成的.hnp文件头写入配置信息 */
ret = HnpWriteToZipHead(hnp_file_path, (char*)hnpHead, hnpHead->headLen);
HNP_LOGI("PackHnp end. srcPath=%s, hnpName=%s, hnpVer=%s, hnpDstPath=%s headlen=%d, linkNum=%d, ret=%d",
hnpSrcPath, hnpName, hnpHead->hnpVersion, hnpDstPath, hnpHead->headLen, hnpHead->linkNum, ret);
return ret;
}
static int ParseLinksJsonToHnpHead(cJSON *linksItem, NativeHnpHead *hnpHead, NativeBinLink **linkArr)
{
NativeBinLink *linkArray = NULL;
int i;
int linkArrayNum = cJSON_GetArraySize(linksItem);
if (linkArrayNum != 0) {
hnpHead->linkNum = linkArrayNum;
linkArray = (NativeBinLink*)malloc(sizeof(NativeBinLink) * linkArrayNum);
if (linkArray == NULL) {
HNP_LOGE("malloc unsuccess.");
return HNP_ERRNO_NOMEM;
}
for (i = 0; i < linkArrayNum; i++) {
cJSON *link = cJSON_GetArrayItem(linksItem, i);
if (link == NULL) {
free(linkArray);
return HNP_ERRNO_PACK_GET_ARRAY_ITRM_FAILED;
}
cJSON *sourceItem = cJSON_GetObjectItem(link, "source");
if (sourceItem == NULL) {
HNP_LOGE("get source info in cfg unsuccess.");
free(linkArray);
return HNP_ERRNO_PACK_PARSE_ITEM_NO_FOUND;
}
if (strcpy_s(linkArray[i].source, MAX_FILE_PATH_LEN, sourceItem->valuestring) != EOK) {
HNP_LOGE("strcpy unsuccess.");
free(linkArray);
return HNP_ERRNO_BASE_COPY_FAILED;
}
cJSON *targetItem = cJSON_GetObjectItem(link, "target");
if (targetItem == NULL) {
HNP_LOGE("get target info in cfg unsuccess.");
free(linkArray);
return HNP_ERRNO_PACK_PARSE_ITEM_NO_FOUND;
}
if (strcpy_s(linkArray[i].target, MAX_FILE_PATH_LEN, targetItem->valuestring) != EOK) {
HNP_LOGE("strcpy unsuccess.");
free(linkArray);
return HNP_ERRNO_BASE_COPY_FAILED;
}
}
*linkArr = linkArray;
} else {
hnpHead->linkNum = 0;
}
return 0;
}
static int ParseJsonStreamToHnpHead(cJSON *json, char *name, NativeHnpHead *hnpHead, NativeBinLink **linkArr)
{
int ret;
cJSON *typeItem = cJSON_GetObjectItem(json, "type");
if (typeItem == NULL) {
HNP_LOGE("get type info in cfg unsuccess.");
return HNP_ERRNO_PACK_PARSE_ITEM_NO_FOUND;
}
if (strcmp(typeItem->valuestring, "hnp-config") != 0) {
HNP_LOGE("type info not match.type=%s", typeItem->valuestring);
return HNP_ERRNO_PACK_PARSE_ITEM_NO_FOUND;
}
cJSON *nameItem = cJSON_GetObjectItem(json, "name");
if (nameItem == NULL) {
HNP_LOGE("get name info in cfg unsuccess.");
return HNP_ERRNO_PACK_PARSE_ITEM_NO_FOUND;
}
ret = strcpy_s(name, MAX_FILE_PATH_LEN, nameItem->valuestring);
if (ret != EOK) {
HNP_LOGE("strcpy unsuccess.");
return HNP_ERRNO_BASE_COPY_FAILED;
}
cJSON *versionItem = cJSON_GetObjectItem(json, "version");
if (versionItem == NULL) {
HNP_LOGE("get version info in cfg unsuccess.");
return HNP_ERRNO_PACK_PARSE_ITEM_NO_FOUND;
}
ret = strcpy_s(hnpHead->hnpVersion, HNP_VERSION_LEN, versionItem->valuestring);
if (ret != EOK) {
HNP_LOGE("strcpy unsuccess.");
return HNP_ERRNO_BASE_COPY_FAILED;
}
cJSON *installItem = cJSON_GetObjectItem(json, "install");
if (installItem == NULL) {
HNP_LOGE("get install info in cfg unsuccess.");
return HNP_ERRNO_PACK_PARSE_ITEM_NO_FOUND;
}
cJSON *linksItem = cJSON_GetObjectItem(installItem, "links");
if (linksItem != NULL) {
ret = ParseLinksJsonToHnpHead(linksItem, hnpHead, linkArr);
if (ret != 0) {
return ret;
}
} else {
hnpHead->linkNum = 0;
}
return 0;
}
static int ParseHnpCfgToHead(const char *hnpCfgPath, char *name, NativeHnpHead *hnpHead, NativeBinLink **linkArr)
{
int ret;
char *cfgStream = NULL;
cJSON *json;
int size;
ret = ReadFileToStream(hnpCfgPath, &cfgStream, &size);
if (ret != 0) {
HNP_LOGE("read cfg file[%s] unsuccess.", hnpCfgPath);
return HNP_ERRNO_PACK_READ_FILE_STREAM_FAILED;
}
json = cJSON_Parse(cfgStream);
free(cfgStream);
if (json == NULL) {
HNP_LOGE("parse json file[%s] unsuccess.", hnpCfgPath);
return HNP_ERRNO_PACK_PARSE_JSON_FAILED;
}
ret = ParseJsonStreamToHnpHead(json, name, hnpHead, linkArr);
cJSON_Delete(json);
return ret;
}
static int PackHnpWithCfg(const char *hnpSrcPath, const char *hnpDstPath, const char *hnpCfgPath)
{
NativeHnpHead head;
NativeHnpHead *hnpHead;
NativeBinLink *linkArr = NULL;
char name[MAX_FILE_PATH_LEN] = {0};
int ret;
HNP_LOGI("pack hnp start. srcPath=%s, hnpCfg=%s, hnpDstPath=%s",
hnpSrcPath, hnpCfgPath, hnpDstPath);
ret = ParseHnpCfgToHead(hnpCfgPath, name, &head, &linkArr);
if (ret != 0) {
HNP_LOGE("parse hnp cfg[%s] unsuccess! ret=%d", hnpCfgPath, ret);
return ret;
}
int headLen = sizeof(NativeHnpHead) + head.linkNum * sizeof(NativeBinLink);
if (head.linkNum != 0) {
hnpHead = (NativeHnpHead*)malloc(headLen);
if (hnpHead == NULL) {
free(linkArr);
return HNP_ERRNO_NOMEM;
}
(void)memcpy_s(hnpHead, headLen, &head, sizeof(NativeHnpHead));
(void)memcpy_s(hnpHead->links, sizeof(NativeBinLink) * head.linkNum,
linkArr, sizeof(NativeBinLink) * head.linkNum);
} else {
hnpHead = &head;
}
HNP_LOGI("pack hnp end. ret=%d, hnpName=%s, version=%s, linksNum=%d",
ret, name, hnpHead->hnpVersion, hnpHead->linkNum);
ret = PackHnp(hnpSrcPath, hnpDstPath, name, hnpHead);
if (head.linkNum != 0) {
free(linkArr);
free(hnpHead);
}
return ret;
}
int HnpCmdPack(int argc, char *argv[])
{
int index = 0;
char srcPath[MAX_FILE_PATH_LEN];
char dstPath[MAX_FILE_PATH_LEN];
char cfgPath[MAX_FILE_PATH_LEN] = {0};
char *name = NULL;
char *version = NULL;
if (argc < HNP_INDEX_4) {
HNP_LOGE("pack args num[%u] unsuccess!", argc);
return HNP_ERRNO_PACK_ARGV_NUM_INVALID;
}
if ((GetRealPath(argv[HNP_INDEX_2], srcPath) != 0) || (GetRealPath(argv[HNP_INDEX_3], dstPath) != 0)) {
HNP_LOGE("pack path invalid! srcPath=%s, dstPath=%s", argv[HNP_INDEX_2], argv[HNP_INDEX_3]);
return HNP_ERRNO_PACK_GET_REALPATH_FAILED;
}
index = HNP_INDEX_4;
while (index < argc) {
if ((!strcmp(argv[index], "-name")) && (index + 1 < argc)) {
name = argv[++index];
} else if ((!strcmp(argv[index], "-v")) && (index + 1 < argc)) {
version = argv[++index];
} else if ((!strcmp(argv[index], "-cfg")) && (index + 1 < argc)) {
if (GetRealPath(argv[++index], cfgPath) != 0) {
HNP_LOGE("cfg path[%s] invalid!", argv[index]);
return HNP_ERRNO_PACK_GET_REALPATH_FAILED;
}
}
index++;
}
if ((name != NULL) && (version != NULL)) {
NativeHnpHead hnpHead;
hnpHead.linkNum = 0;
if (strcpy_s(hnpHead.hnpVersion, HNP_VERSION_LEN, version) != EOK) {
HNP_LOGE("strcpy unsuccess.");
return HNP_ERRNO_BASE_COPY_FAILED;
}
return PackHnp(srcPath, dstPath, name, &hnpHead);
}
if (cfgPath[0] != '\0') {
return PackHnpWithCfg(srcPath, dstPath, cfgPath);
}
HNP_LOGE("pack args parse miss! \r\n");
return HNP_ERRNO_PACK_MISS_OPERATOR_PARAM;
}
#ifdef __cplusplus
}
#endif