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 "config_policy_ffi.h"
17 
18 #include <vector>
19 #include <securec.h>
20 #include "config_policy_utils.h"
21 #include "hisysevent_adapter.h"
22 #include "config_policy_log.h"
23 
24 namespace OHOS::Customization::ConfigPolicy {
25 
26 static constexpr int MAX_MALLOC_LEN = 1024;
27 
MallocCStringArr(const std::vector<const char * > & origin)28 char** MallocCStringArr(const std::vector<const char*>& origin)
29 {
30     if (origin.empty()) {
31         return nullptr;
32     }
33     auto size = origin.size();
34     if (size > MAX_MALLOC_LEN) {
35         return nullptr;
36     }
37     auto arr = static_cast<char**>(malloc(sizeof(char*) * size));
38     if (arr == nullptr) {
39         return nullptr;
40     }
41     for (size_t i = 0; i < size; i++) {
42         size_t len = strlen(origin[i]) + 1;
43         arr[i] = static_cast<char*>(malloc(sizeof(char) * len));
44         if (arr[i] == nullptr) {
45             continue;
46         }
47         errno_t ret = strcpy_s(arr[i], len, origin[i]);
48         if (ret != 0) {
49             free(arr[i]);
50             arr[i] = nullptr;
51         }
52     }
53     return arr;
54 }
55 
56 extern "C" {
CJ_GetCfgDirList()57     RetDataCArrString CJ_GetCfgDirList()
58     {
59         LOGI("CJ_GetCfgDirList start");
60         RetDataCArrString ret = { .code = SUCCESS_CODE, .data = { .head = nullptr, .size = 0 } };
61         CfgDir *cfgDir = GetCfgDirList();
62 
63         std::vector<const char*> dirList;
64         if (cfgDir != nullptr) {
65             for (size_t i = 0; i < MAX_CFG_POLICY_DIRS_CNT; i++) {
66                 if (cfgDir->paths[i] != nullptr) {
67                     dirList.push_back(cfgDir->paths[i]);
68                 }
69             }
70         }
71 
72         ret.data.head = MallocCStringArr(dirList);
73         ret.data.size = static_cast<int64_t>(ret.data.head == nullptr ? 0 : dirList.size());
74 
75         FreeCfgDirList(cfgDir);
76         ReportConfigPolicyEvent(ReportType::CONFIG_POLICY_EVENT, "getCfgDirList", "");
77         LOGI("CJ_GetCfgDirList ok");
78         return ret;
79     }
80 
CJ_GetCfgFiles(const char * relPath)81     RetDataCArrString CJ_GetCfgFiles(const char* relPath)
82     {
83         LOGI("CJ_GetCfgFiles start");
84         RetDataCArrString ret = { .code = SUCCESS_CODE, .data = { .head = nullptr, .size = 0 } };
85         LOGI("input path: [%{public}s]", relPath)
86         std::string extra("");
87         CfgFiles *cfgFiles = GetCfgFilesEx(relPath, FOLLOWX_MODE_DEFAULT, extra.c_str());
88 
89         std::vector<const char*> fileList;
90         if (cfgFiles != nullptr) {
91             for (size_t i = 0; i < MAX_CFG_POLICY_DIRS_CNT; i++) {
92                 if (cfgFiles->paths[i] != nullptr) {
93                     fileList.push_back(cfgFiles->paths[i]);
94                 }
95             }
96         }
97 
98         ret.data.head = MallocCStringArr(fileList);
99         ret.data.size = static_cast<int64_t>(ret.data.head == nullptr ? 0 : fileList.size());
100 
101         FreeCfgFiles(cfgFiles);
102         ReportConfigPolicyEvent(ReportType::CONFIG_POLICY_EVENT, "getCfgFiles", "");
103         return ret;
104     }
105 
CJ_GetOneCfgFile(const char * relPath)106     RetDataCString CJ_GetOneCfgFile(const char* relPath)
107     {
108         LOGI("CJ_GetOneCfgFile start");
109         RetDataCString ret = { .code = SUCCESS_CODE, .data = nullptr };
110         char outBuf[MAX_PATH_LEN] = {0};
111         std::string extra("");
112         char* filePath = GetOneCfgFileEx(relPath, outBuf, MAX_PATH_LEN, FOLLOWX_MODE_DEFAULT, extra.c_str());
113 
114         if (filePath == nullptr) {
115             LOGI("GetOneCfgFileEx result is nullptr.");
116             return ret;
117         } else {
118             LOGI("GetOneCfgFile return [%{public}s]", filePath);
119         }
120         ReportConfigPolicyEvent(ReportType::CONFIG_POLICY_EVENT, "getOneCfgFile", "");
121         size_t pathLen = strlen(filePath) + 1;
122         ret.data = static_cast<char*>(malloc(sizeof(char) * pathLen));
123         if (ret.data == nullptr) {
124             return ret;
125         }
126         errno_t err = strcpy_s(ret.data, pathLen, filePath);
127         if (err != 0) {
128             free(ret.data);
129             ret.data = nullptr;
130         }
131         return ret;
132     }
133 }
134 } // namespace OHOS::Customization::ConfigPolicy
135