169570cc8Sopenharmony_ci/*
269570cc8Sopenharmony_ci * Copyright (C) 2024 Huawei Device Co., Ltd.
369570cc8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
469570cc8Sopenharmony_ci * you may not use this file except in compliance with the License.
569570cc8Sopenharmony_ci * You may obtain a copy of the License at
669570cc8Sopenharmony_ci *
769570cc8Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
869570cc8Sopenharmony_ci *
969570cc8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1069570cc8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1169570cc8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1269570cc8Sopenharmony_ci * See the License for the specific language governing permissions and
1369570cc8Sopenharmony_ci * limitations under the License.
1469570cc8Sopenharmony_ci */
1569570cc8Sopenharmony_ci
1669570cc8Sopenharmony_ci#include "appspawn_utils.h"
1769570cc8Sopenharmony_ci
1869570cc8Sopenharmony_ci#include <ctype.h>
1969570cc8Sopenharmony_ci#include <dirent.h>
2069570cc8Sopenharmony_ci#include <fcntl.h>
2169570cc8Sopenharmony_ci#include <malloc.h>
2269570cc8Sopenharmony_ci#include <stdint.h>
2369570cc8Sopenharmony_ci#include <stdio.h>
2469570cc8Sopenharmony_ci#include <stdlib.h>
2569570cc8Sopenharmony_ci#include <string.h>
2669570cc8Sopenharmony_ci
2769570cc8Sopenharmony_ci#include <linux/if.h>
2869570cc8Sopenharmony_ci#include <sys/ioctl.h>
2969570cc8Sopenharmony_ci#include <sys/mount.h>
3069570cc8Sopenharmony_ci#include <sys/socket.h>
3169570cc8Sopenharmony_ci#include <sys/stat.h>
3269570cc8Sopenharmony_ci#include <sys/types.h>
3369570cc8Sopenharmony_ci
3469570cc8Sopenharmony_ci#include "appspawn_hook.h"
3569570cc8Sopenharmony_ci#include "cJSON.h"
3669570cc8Sopenharmony_ci#include "config_policy_utils.h"
3769570cc8Sopenharmony_ci#include "json_utils.h"
3869570cc8Sopenharmony_ci#include "parameter.h"
3969570cc8Sopenharmony_ci#include "securec.h"
4069570cc8Sopenharmony_ci
4169570cc8Sopenharmony_cistatic const AppSpawnCommonEnv COMMON_ENV[] = {
4269570cc8Sopenharmony_ci    {"HNP_PRIVATE_HOME", "/data/app", true},
4369570cc8Sopenharmony_ci    {"HNP_PUBLIC_HOME", "/data/service/hnp", true},
4469570cc8Sopenharmony_ci    {"PATH", "${HNP_PRIVATE_HOME}/bin:${HNP_PUBLIC_HOME}/bin:${PATH}", true},
4569570cc8Sopenharmony_ci    {"HOME", "/storage/Users/currentUser", false},
4669570cc8Sopenharmony_ci    {"TMPDIR", "/data/storage/el2/base/cache", false},
4769570cc8Sopenharmony_ci    {"SHELL", "/bin/sh", false},
4869570cc8Sopenharmony_ci    {"PWD", "/storage/Users/currentUser", false}
4969570cc8Sopenharmony_ci};
5069570cc8Sopenharmony_ci
5169570cc8Sopenharmony_ciint ConvertEnvValue(const char *srcEnv, char *dstEnv, int len)
5269570cc8Sopenharmony_ci{
5369570cc8Sopenharmony_ci    char *tmpEnv = NULL;
5469570cc8Sopenharmony_ci    char *ptr;
5569570cc8Sopenharmony_ci    char *tmpPtr1;
5669570cc8Sopenharmony_ci    char *tmpPtr2;
5769570cc8Sopenharmony_ci    char *envGet;
5869570cc8Sopenharmony_ci
5969570cc8Sopenharmony_ci    int srcLen = strlen(srcEnv) + 1;
6069570cc8Sopenharmony_ci    tmpEnv = malloc(srcLen);
6169570cc8Sopenharmony_ci    APPSPAWN_CHECK(tmpEnv != NULL, return -1, "malloc size=%{public}d fail", srcLen);
6269570cc8Sopenharmony_ci
6369570cc8Sopenharmony_ci    int ret = memcpy_s(tmpEnv, srcLen, srcEnv, srcLen);
6469570cc8Sopenharmony_ci    if (ret != EOK) {
6569570cc8Sopenharmony_ci        APPSPAWN_LOGE("Failed to copy env value");
6669570cc8Sopenharmony_ci        free(tmpEnv);
6769570cc8Sopenharmony_ci        return -1;
6869570cc8Sopenharmony_ci    }
6969570cc8Sopenharmony_ci
7069570cc8Sopenharmony_ci    ptr = tmpEnv;
7169570cc8Sopenharmony_ci    dstEnv[0] = 0;
7269570cc8Sopenharmony_ci    while (((tmpPtr1 = strchr(ptr, '$')) != NULL) && (*(tmpPtr1 + 1) == '{') &&
7369570cc8Sopenharmony_ci        ((tmpPtr2 = strchr(tmpPtr1, '}')) != NULL)) {
7469570cc8Sopenharmony_ci        *tmpPtr1 = 0;
7569570cc8Sopenharmony_ci        ret = strcat_s(dstEnv, len, ptr);
7669570cc8Sopenharmony_ci        if (ret != 0) {
7769570cc8Sopenharmony_ci            APPSPAWN_LOGE("Failed to strcat env value");
7869570cc8Sopenharmony_ci            free(tmpEnv);
7969570cc8Sopenharmony_ci            return -1;
8069570cc8Sopenharmony_ci        }
8169570cc8Sopenharmony_ci        *tmpPtr2 = 0;
8269570cc8Sopenharmony_ci        tmpPtr1++;
8369570cc8Sopenharmony_ci        ptr = tmpPtr2 + 1;
8469570cc8Sopenharmony_ci        envGet = getenv(tmpPtr1 + 1);
8569570cc8Sopenharmony_ci        if (envGet == NULL) {
8669570cc8Sopenharmony_ci            continue;
8769570cc8Sopenharmony_ci        }
8869570cc8Sopenharmony_ci        ret = strcat_s(dstEnv, len, envGet);
8969570cc8Sopenharmony_ci        if (ret != 0) {
9069570cc8Sopenharmony_ci            APPSPAWN_LOGE("Failed to strcat env value");
9169570cc8Sopenharmony_ci            free(tmpEnv);
9269570cc8Sopenharmony_ci            return -1;
9369570cc8Sopenharmony_ci        }
9469570cc8Sopenharmony_ci    }
9569570cc8Sopenharmony_ci    ret = strcat_s(dstEnv, len, ptr);
9669570cc8Sopenharmony_ci    if (ret != 0) {
9769570cc8Sopenharmony_ci        APPSPAWN_LOGE("Failed to strcat env value");
9869570cc8Sopenharmony_ci        free(tmpEnv);
9969570cc8Sopenharmony_ci        return -1;
10069570cc8Sopenharmony_ci    }
10169570cc8Sopenharmony_ci    free(tmpEnv);
10269570cc8Sopenharmony_ci    return 0;
10369570cc8Sopenharmony_ci}
10469570cc8Sopenharmony_ci
10569570cc8Sopenharmony_civoid InitCommonEnv(void)
10669570cc8Sopenharmony_ci{
10769570cc8Sopenharmony_ci    uint32_t count = ARRAY_LENGTH(COMMON_ENV);
10869570cc8Sopenharmony_ci    int32_t ret;
10969570cc8Sopenharmony_ci    char envValue[MAX_ENV_VALUE_LEN];
11069570cc8Sopenharmony_ci    int developerMode = IsDeveloperModeOpen();
11169570cc8Sopenharmony_ci
11269570cc8Sopenharmony_ci    for (uint32_t i = 0; i < count; i++) {
11369570cc8Sopenharmony_ci        if ((COMMON_ENV[i].developerModeEnable == true && developerMode == false)) {
11469570cc8Sopenharmony_ci            continue;
11569570cc8Sopenharmony_ci        }
11669570cc8Sopenharmony_ci        ret = ConvertEnvValue(COMMON_ENV[i].envValue, envValue, MAX_ENV_VALUE_LEN);
11769570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, return, "Convert env value fail name=%{public}s, value=%{public}s",
11869570cc8Sopenharmony_ci            COMMON_ENV[i].envName, COMMON_ENV[i].envValue);
11969570cc8Sopenharmony_ci        ret = setenv(COMMON_ENV[i].envName, envValue, true);
12069570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, return, "Set env fail name=%{public}s, value=%{public}s",
12169570cc8Sopenharmony_ci            COMMON_ENV[i].envName, envValue);
12269570cc8Sopenharmony_ci    }
12369570cc8Sopenharmony_ci}
12469570cc8Sopenharmony_ci
12569570cc8Sopenharmony_ciuint64_t DiffTime(const struct timespec *startTime, const struct timespec *endTime)
12669570cc8Sopenharmony_ci{
12769570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(startTime != NULL, return 0);
12869570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(endTime != NULL, return 0);
12969570cc8Sopenharmony_ci
13069570cc8Sopenharmony_ci    uint64_t diff = (uint64_t)((endTime->tv_sec - startTime->tv_sec) * 1000000);  // 1000000 s-us
13169570cc8Sopenharmony_ci    if (endTime->tv_nsec > startTime->tv_nsec) {
13269570cc8Sopenharmony_ci        diff += (endTime->tv_nsec - startTime->tv_nsec) / 1000;  // 1000 ns - us
13369570cc8Sopenharmony_ci    } else {
13469570cc8Sopenharmony_ci        diff -= (startTime->tv_nsec - endTime->tv_nsec) / 1000;  // 1000 ns - us
13569570cc8Sopenharmony_ci    }
13669570cc8Sopenharmony_ci    return diff;
13769570cc8Sopenharmony_ci}
13869570cc8Sopenharmony_ci
13969570cc8Sopenharmony_ciint MakeDirRec(const char *path, mode_t mode, int lastPath)
14069570cc8Sopenharmony_ci{
14169570cc8Sopenharmony_ci    APPSPAWN_CHECK(path != NULL && *path != '\0', return -1, "Invalid path to create");
14269570cc8Sopenharmony_ci    char buffer[PATH_MAX] = {0};
14369570cc8Sopenharmony_ci    const char slash = '/';
14469570cc8Sopenharmony_ci    const char *p = path;
14569570cc8Sopenharmony_ci    char *curPos = strchr(path, slash);
14669570cc8Sopenharmony_ci    while (curPos != NULL) {
14769570cc8Sopenharmony_ci        int len = curPos - p;
14869570cc8Sopenharmony_ci        p = curPos + 1;
14969570cc8Sopenharmony_ci        if (len == 0) {
15069570cc8Sopenharmony_ci            curPos = strchr(p, slash);
15169570cc8Sopenharmony_ci            continue;
15269570cc8Sopenharmony_ci        }
15369570cc8Sopenharmony_ci        int ret = memcpy_s(buffer, PATH_MAX, path, p - path - 1);
15469570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, return -1, "Failed to copy path");
15569570cc8Sopenharmony_ci        ret = mkdir(buffer, mode);
15669570cc8Sopenharmony_ci        if (ret == -1 && errno != EEXIST) {
15769570cc8Sopenharmony_ci            return errno;
15869570cc8Sopenharmony_ci        }
15969570cc8Sopenharmony_ci        curPos = strchr(p, slash);
16069570cc8Sopenharmony_ci    }
16169570cc8Sopenharmony_ci    if (lastPath) {
16269570cc8Sopenharmony_ci        if (mkdir(path, mode) == -1 && errno != EEXIST) {
16369570cc8Sopenharmony_ci            return errno;
16469570cc8Sopenharmony_ci        }
16569570cc8Sopenharmony_ci    }
16669570cc8Sopenharmony_ci    return 0;
16769570cc8Sopenharmony_ci}
16869570cc8Sopenharmony_ci
16969570cc8Sopenharmony_cistatic void TrimTail(char *buffer, uint32_t maxLen)
17069570cc8Sopenharmony_ci{
17169570cc8Sopenharmony_ci    uint32_t index = maxLen - 1;
17269570cc8Sopenharmony_ci    while (index > 0) {
17369570cc8Sopenharmony_ci        if (isspace(buffer[index])) {
17469570cc8Sopenharmony_ci            buffer[index] = '\0';
17569570cc8Sopenharmony_ci            index--;
17669570cc8Sopenharmony_ci            continue;
17769570cc8Sopenharmony_ci        }
17869570cc8Sopenharmony_ci        break;
17969570cc8Sopenharmony_ci    }
18069570cc8Sopenharmony_ci}
18169570cc8Sopenharmony_ci
18269570cc8Sopenharmony_ciint32_t StringSplit(const char *str, const char *separator, void *context, SplitStringHandle handle)
18369570cc8Sopenharmony_ci{
18469570cc8Sopenharmony_ci    APPSPAWN_CHECK(str != NULL && handle != NULL && separator != NULL, return APPSPAWN_ARG_INVALID, "Invalid arg ");
18569570cc8Sopenharmony_ci
18669570cc8Sopenharmony_ci    int ret = 0;
18769570cc8Sopenharmony_ci    char *tmp = (char *)str;
18869570cc8Sopenharmony_ci    char buffer[PATH_MAX] = {0};
18969570cc8Sopenharmony_ci    uint32_t len = strlen(separator);
19069570cc8Sopenharmony_ci    uint32_t index = 0;
19169570cc8Sopenharmony_ci    while ((*tmp != '\0') && (index < (uint32_t)sizeof(buffer))) {
19269570cc8Sopenharmony_ci        if (index == 0 && isspace(*tmp)) {
19369570cc8Sopenharmony_ci            tmp++;
19469570cc8Sopenharmony_ci            continue;
19569570cc8Sopenharmony_ci        }
19669570cc8Sopenharmony_ci        if (strncmp(tmp, separator, len) != 0) {
19769570cc8Sopenharmony_ci            buffer[index++] = *tmp;
19869570cc8Sopenharmony_ci            tmp++;
19969570cc8Sopenharmony_ci            continue;
20069570cc8Sopenharmony_ci        }
20169570cc8Sopenharmony_ci        tmp += len;
20269570cc8Sopenharmony_ci        buffer[index] = '\0';
20369570cc8Sopenharmony_ci        TrimTail(buffer, index);
20469570cc8Sopenharmony_ci        index = 0;
20569570cc8Sopenharmony_ci
20669570cc8Sopenharmony_ci        int result = handle(buffer, context);
20769570cc8Sopenharmony_ci        if (result != 0) {
20869570cc8Sopenharmony_ci            ret = result;
20969570cc8Sopenharmony_ci        }
21069570cc8Sopenharmony_ci    }
21169570cc8Sopenharmony_ci    if (index > 0) {
21269570cc8Sopenharmony_ci        buffer[index] = '\0';
21369570cc8Sopenharmony_ci        TrimTail(buffer, index);
21469570cc8Sopenharmony_ci        index = 0;
21569570cc8Sopenharmony_ci        int result = handle(buffer, context);
21669570cc8Sopenharmony_ci        if (result != 0) {
21769570cc8Sopenharmony_ci            ret = result;
21869570cc8Sopenharmony_ci        }
21969570cc8Sopenharmony_ci    }
22069570cc8Sopenharmony_ci    return ret;
22169570cc8Sopenharmony_ci}
22269570cc8Sopenharmony_ci
22369570cc8Sopenharmony_cichar *GetLastStr(const char *str, const char *dst)
22469570cc8Sopenharmony_ci{
22569570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(str != NULL, return NULL);
22669570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(dst != NULL, return NULL);
22769570cc8Sopenharmony_ci
22869570cc8Sopenharmony_ci    char *end = (char *)str + strlen(str);
22969570cc8Sopenharmony_ci    size_t len = strlen(dst);
23069570cc8Sopenharmony_ci    while (end != str) {
23169570cc8Sopenharmony_ci        if (strncmp(end, dst, len) == 0) {
23269570cc8Sopenharmony_ci            return end;
23369570cc8Sopenharmony_ci        }
23469570cc8Sopenharmony_ci        end--;
23569570cc8Sopenharmony_ci    }
23669570cc8Sopenharmony_ci    return NULL;
23769570cc8Sopenharmony_ci}
23869570cc8Sopenharmony_ci
23969570cc8Sopenharmony_cichar *ReadFile(const char *fileName)
24069570cc8Sopenharmony_ci{
24169570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(fileName != NULL, return NULL);
24269570cc8Sopenharmony_ci    char *buffer = NULL;
24369570cc8Sopenharmony_ci    FILE *fd = NULL;
24469570cc8Sopenharmony_ci    do {
24569570cc8Sopenharmony_ci        struct stat fileStat;
24669570cc8Sopenharmony_ci        if (stat(fileName, &fileStat) != 0 ||
24769570cc8Sopenharmony_ci            fileStat.st_size <= 0 || fileStat.st_size > MAX_JSON_FILE_LEN) {
24869570cc8Sopenharmony_ci            return NULL;
24969570cc8Sopenharmony_ci        }
25069570cc8Sopenharmony_ci        fd = fopen(fileName, "r");
25169570cc8Sopenharmony_ci        APPSPAWN_CHECK(fd != NULL, break, "Failed to open file  %{public}s", fileName);
25269570cc8Sopenharmony_ci
25369570cc8Sopenharmony_ci        buffer = (char *)malloc((size_t)(fileStat.st_size + 1));
25469570cc8Sopenharmony_ci        APPSPAWN_CHECK(buffer != NULL, break, "Failed to alloc mem %{public}s", fileName);
25569570cc8Sopenharmony_ci
25669570cc8Sopenharmony_ci        size_t ret = fread(buffer, fileStat.st_size, 1, fd);
25769570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 1, break, "Failed to read %{public}s to buffer", fileName);
25869570cc8Sopenharmony_ci        buffer[fileStat.st_size] = '\0';
25969570cc8Sopenharmony_ci        (void)fclose(fd);
26069570cc8Sopenharmony_ci        return buffer;
26169570cc8Sopenharmony_ci    } while (0);
26269570cc8Sopenharmony_ci
26369570cc8Sopenharmony_ci    if (fd != NULL) {
26469570cc8Sopenharmony_ci        (void)fclose(fd);
26569570cc8Sopenharmony_ci        fd = NULL;
26669570cc8Sopenharmony_ci    }
26769570cc8Sopenharmony_ci    if (buffer != NULL) {
26869570cc8Sopenharmony_ci        free(buffer);
26969570cc8Sopenharmony_ci    }
27069570cc8Sopenharmony_ci    return NULL;
27169570cc8Sopenharmony_ci}
27269570cc8Sopenharmony_ci
27369570cc8Sopenharmony_cicJSON *GetJsonObjFromFile(const char *jsonPath)
27469570cc8Sopenharmony_ci{
27569570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(jsonPath != NULL && *jsonPath != '\0', NULL);
27669570cc8Sopenharmony_ci    char *buffer = ReadFile(jsonPath);
27769570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(buffer != NULL, NULL);
27869570cc8Sopenharmony_ci    cJSON *json = cJSON_Parse(buffer);
27969570cc8Sopenharmony_ci    free(buffer);
28069570cc8Sopenharmony_ci    return json;
28169570cc8Sopenharmony_ci}
28269570cc8Sopenharmony_ci
28369570cc8Sopenharmony_ciint ParseJsonConfig(const char *basePath, const char *fileName, ParseConfig parseConfig, ParseJsonContext *context)
28469570cc8Sopenharmony_ci{
28569570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(basePath != NULL, return APPSPAWN_ARG_INVALID);
28669570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(fileName != NULL, return APPSPAWN_ARG_INVALID);
28769570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(parseConfig != NULL, return APPSPAWN_ARG_INVALID);
28869570cc8Sopenharmony_ci
28969570cc8Sopenharmony_ci    // load sandbox config
29069570cc8Sopenharmony_ci    char path[PATH_MAX] = {};
29169570cc8Sopenharmony_ci    CfgFiles *files = GetCfgFiles(basePath);
29269570cc8Sopenharmony_ci    if (files == NULL) {
29369570cc8Sopenharmony_ci        return APPSPAWN_SANDBOX_NONE;
29469570cc8Sopenharmony_ci    }
29569570cc8Sopenharmony_ci    int ret = 0;
29669570cc8Sopenharmony_ci    for (int i = 0; i < MAX_CFG_POLICY_DIRS_CNT; ++i) {
29769570cc8Sopenharmony_ci        if (files->paths[i] == NULL) {
29869570cc8Sopenharmony_ci            continue;
29969570cc8Sopenharmony_ci        }
30069570cc8Sopenharmony_ci        int len = snprintf_s(path, sizeof(path), sizeof(path) - 1, "%s%s", files->paths[i], fileName);
30169570cc8Sopenharmony_ci        APPSPAWN_CHECK(len > 0 && (size_t)len < sizeof(path), ret = APPSPAWN_SANDBOX_INVALID;
30269570cc8Sopenharmony_ci            continue, "Failed to format sandbox config file name %{public}s %{public}s", files->paths[i], fileName);
30369570cc8Sopenharmony_ci        cJSON *root = GetJsonObjFromFile(path);
30469570cc8Sopenharmony_ci        APPSPAWN_CHECK(root != NULL, ret = APPSPAWN_SANDBOX_INVALID;
30569570cc8Sopenharmony_ci            continue, "Failed to load app data sandbox config %{public}s", path);
30669570cc8Sopenharmony_ci        int rc = parseConfig(root, context);
30769570cc8Sopenharmony_ci        if (rc != 0) {
30869570cc8Sopenharmony_ci            ret = rc;
30969570cc8Sopenharmony_ci        }
31069570cc8Sopenharmony_ci        cJSON_Delete(root);
31169570cc8Sopenharmony_ci    }
31269570cc8Sopenharmony_ci    FreeCfgFiles(files);
31369570cc8Sopenharmony_ci    return ret;
31469570cc8Sopenharmony_ci}
31569570cc8Sopenharmony_ci
31669570cc8Sopenharmony_civoid DumpCurrentDir(char *buffer, uint32_t bufferLen, const char *dirPath)
31769570cc8Sopenharmony_ci{
31869570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(buffer != NULL, return);
31969570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(dirPath != NULL, return);
32069570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(bufferLen > 0, return);
32169570cc8Sopenharmony_ci
32269570cc8Sopenharmony_ci    DIR *pDir = opendir(dirPath);
32369570cc8Sopenharmony_ci    APPSPAWN_CHECK(pDir != NULL, return, "Read dir :%{public}s failed.%{public}d", dirPath, errno);
32469570cc8Sopenharmony_ci
32569570cc8Sopenharmony_ci    struct dirent *dp;
32669570cc8Sopenharmony_ci    while ((dp = readdir(pDir)) != NULL) {
32769570cc8Sopenharmony_ci        if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) {
32869570cc8Sopenharmony_ci            continue;
32969570cc8Sopenharmony_ci        }
33069570cc8Sopenharmony_ci        if (dp->d_type == DT_DIR) {
33169570cc8Sopenharmony_ci            APPSPAWN_LOGW(" Current path %{public}s/%{public}s ", dirPath, dp->d_name);
33269570cc8Sopenharmony_ci            int ret = snprintf_s(buffer, bufferLen, bufferLen - 1, "%s/%s", dirPath, dp->d_name);
33369570cc8Sopenharmony_ci            APPSPAWN_CHECK(ret > 0, break, "Failed to snprintf_s errno: %{public}d", errno);
33469570cc8Sopenharmony_ci            char *path = strdup(buffer);
33569570cc8Sopenharmony_ci            DumpCurrentDir(buffer, bufferLen, path);
33669570cc8Sopenharmony_ci            free(path);
33769570cc8Sopenharmony_ci        }
33869570cc8Sopenharmony_ci    }
33969570cc8Sopenharmony_ci    closedir(pDir);
34069570cc8Sopenharmony_ci    return;
34169570cc8Sopenharmony_ci}
34269570cc8Sopenharmony_ci
34369570cc8Sopenharmony_cistatic FILE *g_dumpToStream = NULL;
34469570cc8Sopenharmony_civoid SetDumpToStream(FILE *stream)
34569570cc8Sopenharmony_ci{
34669570cc8Sopenharmony_ci    g_dumpToStream = stream;
34769570cc8Sopenharmony_ci}
34869570cc8Sopenharmony_ci
34969570cc8Sopenharmony_ci#if defined(__clang__)
35069570cc8Sopenharmony_ci#    pragma clang diagnostic push
35169570cc8Sopenharmony_ci#    pragma clang diagnostic ignored "-Wvarargs"
35269570cc8Sopenharmony_ci#elif defined(__GNUC__)
35369570cc8Sopenharmony_ci#    pragma GCC diagnostic push
35469570cc8Sopenharmony_ci#    pragma GCC diagnostic ignored "-Wvarargs"
35569570cc8Sopenharmony_ci#elif defined(_MSC_VER)
35669570cc8Sopenharmony_ci#    pragma warning(push)
35769570cc8Sopenharmony_ci#endif
35869570cc8Sopenharmony_ci
35969570cc8Sopenharmony_civoid AppSpawnDump(const char *fmt, ...)
36069570cc8Sopenharmony_ci{
36169570cc8Sopenharmony_ci    if (g_dumpToStream == NULL) {
36269570cc8Sopenharmony_ci        return;
36369570cc8Sopenharmony_ci    }
36469570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(fmt != NULL, return);
36569570cc8Sopenharmony_ci    char format[128] = {0};  // 128 max buffer for format
36669570cc8Sopenharmony_ci    uint32_t size = strlen(fmt);
36769570cc8Sopenharmony_ci    int curr = 0;
36869570cc8Sopenharmony_ci    for (uint32_t index = 0; index < size; index++) {
36969570cc8Sopenharmony_ci        if (curr >= (int)sizeof(format)) {  // invalid format
37069570cc8Sopenharmony_ci            return;
37169570cc8Sopenharmony_ci        }
37269570cc8Sopenharmony_ci        if (fmt[index] != '%') {
37369570cc8Sopenharmony_ci            format[curr++] = fmt[index];
37469570cc8Sopenharmony_ci            continue;
37569570cc8Sopenharmony_ci        }
37669570cc8Sopenharmony_ci        if (strncmp(&fmt[index + 1], "{public}", strlen("{public}")) == 0) {
37769570cc8Sopenharmony_ci            format[curr++] = fmt[index];
37869570cc8Sopenharmony_ci            index += strlen("{public}");
37969570cc8Sopenharmony_ci            continue;
38069570cc8Sopenharmony_ci        }
38169570cc8Sopenharmony_ci        if (strncmp(&fmt[index + 1], "{private}", strlen("{private}")) == 0) {
38269570cc8Sopenharmony_ci            format[curr++] = fmt[index];
38369570cc8Sopenharmony_ci            index += strlen("{private}");
38469570cc8Sopenharmony_ci            continue;
38569570cc8Sopenharmony_ci        }
38669570cc8Sopenharmony_ci    }
38769570cc8Sopenharmony_ci    va_list vargs;
38869570cc8Sopenharmony_ci    va_start(vargs, format);
38969570cc8Sopenharmony_ci    (void)vfprintf(g_dumpToStream, format, vargs);
39069570cc8Sopenharmony_ci    va_end(vargs);
39169570cc8Sopenharmony_ci    (void)fflush(g_dumpToStream);
39269570cc8Sopenharmony_ci}
39369570cc8Sopenharmony_ci
39469570cc8Sopenharmony_ciint IsDeveloperModeOpen()
39569570cc8Sopenharmony_ci{
39669570cc8Sopenharmony_ci    char tmp[32] = {0};  // 32 max
39769570cc8Sopenharmony_ci    int ret = GetParameter("const.security.developermode.state", "", tmp, sizeof(tmp));
39869570cc8Sopenharmony_ci    APPSPAWN_LOGV("IsDeveloperModeOpen ret %{public}d result: %{public}s", ret, tmp);
39969570cc8Sopenharmony_ci    int enabled = (ret > 0 && strcmp(tmp, "true") == 0);
40069570cc8Sopenharmony_ci    return enabled;
40169570cc8Sopenharmony_ci}
40269570cc8Sopenharmony_ci
40369570cc8Sopenharmony_ci#if defined(__clang__)
40469570cc8Sopenharmony_ci#    pragma clang diagnostic pop
40569570cc8Sopenharmony_ci#elif defined(__GNUC__)
40669570cc8Sopenharmony_ci#    pragma GCC diagnostic pop
40769570cc8Sopenharmony_ci#elif defined(_MSC_VER)
40869570cc8Sopenharmony_ci#    pragma warning(pop)
40969570cc8Sopenharmony_ci#endif
41069570cc8Sopenharmony_ci
41169570cc8Sopenharmony_ciuint32_t GetSpawnTimeout(uint32_t def)
41269570cc8Sopenharmony_ci{
41369570cc8Sopenharmony_ci    uint32_t value = def;
41469570cc8Sopenharmony_ci    char data[32] = {};  // 32 length
41569570cc8Sopenharmony_ci    int ret = GetParameter("persist.appspawn.reqMgr.timeout", "0", data, sizeof(data));
41669570cc8Sopenharmony_ci    if (ret > 0 && strcmp(data, "0") != 0) {
41769570cc8Sopenharmony_ci        errno = 0;
41869570cc8Sopenharmony_ci        value = (uint32_t)atoi(data);
41969570cc8Sopenharmony_ci        return (errno != 0) ? def : ((value < def) ? def : value);
42069570cc8Sopenharmony_ci    }
42169570cc8Sopenharmony_ci    return value;
42269570cc8Sopenharmony_ci}
42369570cc8Sopenharmony_ci
42469570cc8Sopenharmony_ciint EnableNewNetNamespace(void)
42569570cc8Sopenharmony_ci{
42669570cc8Sopenharmony_ci    int fd = open(DEVICE_VIRTUAL_NET_IO_FLAGS, O_WRONLY);
42769570cc8Sopenharmony_ci    APPSPAWN_CHECK(fd >= 0, return APPSPAWN_SYSTEM_ERROR, "Failed to open file errno %{public}d", errno);
42869570cc8Sopenharmony_ci
42969570cc8Sopenharmony_ci    int ret = write(fd, IFF_LOOPBACK_VALUE, IFF_LOOPBACK_SIZE);
43069570cc8Sopenharmony_ci    if (ret < 0) {
43169570cc8Sopenharmony_ci        APPSPAWN_LOGE("Failed to write to file errno %{public}d", errno);
43269570cc8Sopenharmony_ci    } else {
43369570cc8Sopenharmony_ci        APPSPAWN_LOGI("Successfully enabled new net namespace");
43469570cc8Sopenharmony_ci    }
43569570cc8Sopenharmony_ci
43669570cc8Sopenharmony_ci    close(fd);
43769570cc8Sopenharmony_ci    return (ret >= 0) ? 0 : APPSPAWN_SYSTEM_ERROR;
43869570cc8Sopenharmony_ci}
43969570cc8Sopenharmony_ci
44069570cc8Sopenharmony_civoid EnableCache(void)
44169570cc8Sopenharmony_ci{
44269570cc8Sopenharmony_ci    APPSPAWN_LOGV("enable cache for app process");
44369570cc8Sopenharmony_ci    // enable cache for app process
44469570cc8Sopenharmony_ci    mallopt(M_OHOS_CONFIG, M_TCACHE_PERFORMANCE_MODE);
44569570cc8Sopenharmony_ci    mallopt(M_OHOS_CONFIG, M_ENABLE_OPT_TCACHE);
44669570cc8Sopenharmony_ci    mallopt(M_SET_THREAD_CACHE, M_THREAD_CACHE_ENABLE);
44769570cc8Sopenharmony_ci    mallopt(M_DELAYED_FREE, M_DELAYED_FREE_ENABLE);
44869570cc8Sopenharmony_ci}
449