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 "b_json/b_json_clear_data_config.h"
17
18 #include <unistd.h>
19 #include <fcntl.h>
20 #include <sys/types.h>
21 #include <fstream>
22 #include "unique_fd.h"
23 #include "filemgmt_libhilog.h"
24
25 #include "cJSON.h"
26
27 namespace OHOS::FileManagement::Backup {
28 using namespace std;
29
30 namespace {
31 const string PATH_BUNDLE_BACKUP_HOME = "/data/service/el2/100/backup/";
32 const string CONFIG_NAME = "ClearDataConfig.json";
33 }
34
BJsonClearDataConfig()35 BJsonClearDataConfig::BJsonClearDataConfig()
36 {
37 string filePath = PATH_BUNDLE_BACKUP_HOME + CONFIG_NAME;
38 if (access(filePath.c_str(), F_OK) == 0) {
39 HILOGI("file exist filePath:%{public}s", filePath.c_str());
40 return;
41 }
42 HILOGI("Failed to access filePath :%{public}s", filePath.c_str());
43 UniqueFd fd(open(filePath.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR));
44 if (fd < 0) {
45 HILOGE("Failed to creat filePath :%{public}s", filePath.c_str());
46 return;
47 }
48 cJSON *jsonObjectDis = cJSON_CreateObject();
49 if (jsonObjectDis == nullptr) {
50 HILOGE("Creat json failed");
51 return;
52 }
53 cJSON *jsonArray = cJSON_CreateArray();
54 if (jsonArray == nullptr) {
55 HILOGE("Creat json failed");
56 cJSON_Delete(jsonObjectDis);
57 return;
58 }
59 cJSON_AddItemToObject(jsonObjectDis, "ClearDataConfigFile", jsonArray);
60
61 char *newStr = cJSON_Print(jsonObjectDis);
62 if (newStr == nullptr) {
63 HILOGE("cJSON_Print json failed");
64 cJSON_Delete(jsonObjectDis);
65 return;
66 }
67 ofstream outFile(filePath);
68 if (!outFile.is_open()) {
69 HILOGE("open json failed");
70 cJSON_free(newStr);
71 cJSON_Delete(jsonObjectDis);
72 return;
73 }
74 outFile << newStr;
75 outFile.close();
76 cJSON_free(newStr);
77 cJSON_Delete(jsonObjectDis);
78 HILOGI("Creat filePath ok :%{public}s", filePath.c_str());
79 }
80
HasClearBundleRecord()81 bool BJsonClearDataConfig::HasClearBundleRecord()
82 {
83 lock_guard<mutex> autoLock(fileMutex_);
84 string filePath = PATH_BUNDLE_BACKUP_HOME + CONFIG_NAME;
85 ifstream inFile(filePath);
86 if (!inFile.is_open()) {
87 HILOGE("open json failed");
88 return false;
89 }
90
91 string jsonString((istreambuf_iterator<char>(inFile)), istreambuf_iterator<char>());
92 inFile.close();
93
94 cJSON *jsonObjectDis = cJSON_Parse(jsonString.c_str());
95 if (jsonObjectDis == nullptr) {
96 HILOGE("parse json failed");
97 return false;
98 }
99
100 cJSON *configArray = cJSON_GetObjectItem(jsonObjectDis, "ClearDataConfigFile");
101 if (configArray == nullptr) {
102 HILOGE("parse json failed");
103 cJSON_Delete(jsonObjectDis);
104 return false;
105 }
106
107 int recordSize = cJSON_GetArraySize(configArray);
108 cJSON_Delete(jsonObjectDis);
109 return recordSize > 0;
110 }
111
FindClearBundleRecord(const string & bundleName)112 bool BJsonClearDataConfig::FindClearBundleRecord(const string& bundleName)
113 {
114 lock_guard<mutex> autoLock(fileMutex_);
115 string filePath = PATH_BUNDLE_BACKUP_HOME + CONFIG_NAME;
116 ifstream inFile(filePath);
117 if (!inFile.is_open()) {
118 HILOGE("open json failed");
119 return false;
120 }
121
122 string jsonString((istreambuf_iterator<char>(inFile)), istreambuf_iterator<char>());
123 inFile.close();
124
125 cJSON *jsonObjectDis = cJSON_Parse(jsonString.c_str());
126 if (jsonObjectDis == nullptr) {
127 HILOGE("parse json failed");
128 return false;
129 }
130
131 cJSON *configArray = cJSON_GetObjectItem(jsonObjectDis, "ClearDataConfigFile");
132 if (configArray == nullptr) {
133 HILOGE("parse json failed");
134 cJSON_Delete(jsonObjectDis);
135 return false;
136 }
137 bool ifBundlename = false;
138 for (int i = 0; i < cJSON_GetArraySize(configArray); ++i) {
139 cJSON *item = cJSON_GetArrayItem(configArray, i);
140 if (item != nullptr && cJSON_GetObjectItem(item, "bundleName") != nullptr &&
141 cJSON_GetObjectItem(item, "bundleName")->type == cJSON_String &&
142 cJSON_GetObjectItem(item, "bundleName")->valuestring == bundleName) {
143 ifBundlename = true;
144 }
145 }
146
147 cJSON_Delete(jsonObjectDis);
148 return ifBundlename;
149 }
150
InsertClearBundleRecord(const string & bundleName)151 bool BJsonClearDataConfig::InsertClearBundleRecord(const string& bundleName)
152 {
153 lock_guard<mutex> autoLock(fileMutex_);
154 string filePath = PATH_BUNDLE_BACKUP_HOME + CONFIG_NAME;
155 ifstream inFile(filePath);
156 if (!inFile.is_open()) {
157 HILOGE("open json failed");
158 return false;
159 }
160
161 string jsonString((istreambuf_iterator<char>(inFile)), istreambuf_iterator<char>());
162 inFile.close();
163
164 cJSON *jsonObjectDis = cJSON_Parse(jsonString.c_str());
165 if (jsonObjectDis == nullptr) {
166 HILOGE("parse json failed");
167 return false;
168 }
169
170 cJSON *configArray = cJSON_GetObjectItem(jsonObjectDis, "ClearDataConfigFile");
171 if (configArray == nullptr) {
172 HILOGE("parse json failed");
173 cJSON_Delete(jsonObjectDis);
174 return false;
175 }
176
177 for (int i = 0; i < cJSON_GetArraySize(configArray); ++i) {
178 cJSON *item = cJSON_GetArrayItem(configArray, i);
179 if (item != nullptr && cJSON_GetObjectItem(item, "bundleName") != nullptr &&
180 cJSON_GetObjectItem(item, "bundleName")->type == cJSON_String &&
181 cJSON_GetObjectItem(item, "bundleName")->valuestring == bundleName) {
182 HILOGI("record already exist, bundleName=%{public}s", bundleName.c_str());
183 cJSON_Delete(jsonObjectDis);
184 return true;
185 }
186 }
187
188 if (!WriteClearBundleRecord(bundleName)) {
189 HILOGE("InsertClearBundleRecord Failed");
190 cJSON_Delete(jsonObjectDis);
191 return false;
192 }
193
194 HILOGI("InsertClearBundleRecord Ok");
195 cJSON_Delete(jsonObjectDis);
196 return true;
197 }
198
DeleteClearBundleRecord(const string & bundleName)199 bool BJsonClearDataConfig::DeleteClearBundleRecord(const string& bundleName)
200 {
201 lock_guard<mutex> autoLock(fileMutex_);
202 string filePath = PATH_BUNDLE_BACKUP_HOME + CONFIG_NAME;
203 ifstream input(filePath);
204 if (!input.is_open()) {
205 HILOGE("open json failed");
206 return false;
207 }
208
209 string jsonString((istreambuf_iterator<char>(input)), istreambuf_iterator<char>());
210 input.close();
211
212 cJSON *jsonObjectDis = cJSON_Parse(jsonString.c_str());
213 if (jsonObjectDis == nullptr) {
214 HILOGE("parse json failed");
215 return false;
216 }
217
218 cJSON *configArray = cJSON_GetObjectItem(jsonObjectDis, "ClearDataConfigFile");
219 if (configArray == nullptr) {
220 cJSON_Delete(jsonObjectDis);
221 return false;
222 }
223 for (int i = 0; i < cJSON_GetArraySize(configArray); ++i) {
224 cJSON *item = cJSON_GetArrayItem(configArray, i);
225 if (item != nullptr && cJSON_GetObjectItem(item, "bundleName") != nullptr &&
226 cJSON_GetObjectItem(item, "bundleName")->type == cJSON_String &&
227 cJSON_GetObjectItem(item, "bundleName")->valuestring == bundleName) {
228 cJSON_DeleteItemFromArray(configArray, i);
229 break;
230 }
231 }
232 char *newStr = cJSON_Print(jsonObjectDis);
233 if (newStr == nullptr) {
234 HILOGE("cJSON_Print json failed");
235 cJSON_Delete(jsonObjectDis);
236 return false;
237 }
238 ofstream output(filePath);
239 if (!output.is_open()) {
240 HILOGE("open json failed");
241 cJSON_free(newStr);
242 cJSON_Delete(jsonObjectDis);
243 return false;
244 }
245 output << newStr;
246 output.close();
247
248 cJSON_free(newStr);
249 cJSON_Delete(jsonObjectDis);
250 return true;
251 }
252
GetAllClearBundleRecords()253 vector<string> BJsonClearDataConfig::GetAllClearBundleRecords()
254 {
255 lock_guard<mutex> autoLock(fileMutex_);
256 string filePath = PATH_BUNDLE_BACKUP_HOME + CONFIG_NAME;
257 vector<string> bundleNameList;
258 ifstream inFile(filePath);
259 if (!inFile.is_open()) {
260 HILOGE("open json failed");
261 return {};
262 }
263 string jsonString((istreambuf_iterator<char>(inFile)), istreambuf_iterator<char>());
264 inFile.close();
265
266 cJSON *jsonObjectDis = cJSON_Parse(jsonString.c_str());
267 if (jsonObjectDis == nullptr) {
268 HILOGE("parse json failed");
269 return {};
270 }
271
272 cJSON *configArray = cJSON_GetObjectItem(jsonObjectDis, "ClearDataConfigFile");
273 if (configArray == nullptr) {
274 HILOGE("parse json failed");
275 cJSON_Delete(jsonObjectDis);
276 return {};
277 }
278 for (int i = 0; i < cJSON_GetArraySize(configArray); ++i) {
279 cJSON *item = cJSON_GetArrayItem(configArray, i);
280 if (item != nullptr && cJSON_GetObjectItem(item, "bundleName") != nullptr &&
281 cJSON_GetObjectItem(item, "bundleName")->type == cJSON_String) {
282 bundleNameList.push_back(cJSON_GetObjectItem(item, "bundleName")->valuestring);
283 }
284 }
285 cJSON_Delete(jsonObjectDis);
286 return bundleNameList;
287 }
288
DeleteConfigFile()289 bool BJsonClearDataConfig::DeleteConfigFile()
290 {
291 string filePath = PATH_BUNDLE_BACKUP_HOME + CONFIG_NAME;
292 if (access(filePath.c_str(), F_OK) != 0) {
293 HILOGE("File is not exist");
294 return false;
295 }
296 if (remove(filePath.c_str()) != 0) {
297 HILOGE("Delete ClearDataConfigFile failed");
298 return false;
299 }
300 HILOGI("All Restore Finished, Delete ClearDataConfigFile OK");
301 return true;
302 }
303
WriteClearBundleRecord(const string & bundleName)304 bool BJsonClearDataConfig::WriteClearBundleRecord(const string& bundleName)
305 {
306 string filePath = PATH_BUNDLE_BACKUP_HOME + CONFIG_NAME;
307 ifstream inFile(filePath);
308 if (!inFile.is_open()) {
309 HILOGE("open json failed");
310 return false;
311 }
312 string jsonString((istreambuf_iterator<char>(inFile)), istreambuf_iterator<char>());
313 inFile.close();
314
315 cJSON *jsonObjectDis = cJSON_Parse(jsonString.c_str());
316 if (jsonObjectDis == nullptr) {
317 HILOGE("parse json failed");
318 return false;
319 }
320
321 cJSON *configArray = cJSON_GetObjectItem(jsonObjectDis, "ClearDataConfigFile");
322 if (configArray == nullptr) {
323 HILOGE("parse json failed");
324 cJSON_Delete(jsonObjectDis);
325 return false;
326 }
327 cJSON *newItem = cJSON_CreateObject();
328 if (configArray == nullptr || newItem == nullptr) {
329 HILOGE("parse json failed");
330 cJSON_Delete(jsonObjectDis);
331 return false;
332 }
333
334 cJSON_AddStringToObject(newItem, "bundleName", bundleName.c_str());
335 cJSON_AddItemToArray(configArray, newItem);
336 char *newStr = cJSON_Print(jsonObjectDis);
337 if (newStr == nullptr) {
338 HILOGE("cJSON_Print json failed");
339 cJSON_Delete(jsonObjectDis);
340 return false;
341 }
342 ofstream outFile(filePath);
343 if (!outFile.is_open()) {
344 HILOGE("open json failed");
345 cJSON_free(newStr);
346 cJSON_Delete(jsonObjectDis);
347 return false;
348 }
349 outFile << newStr;
350 outFile.close();
351
352 cJSON_free(newStr);
353 cJSON_Delete(jsonObjectDis);
354 return true;
355 }
356 } // namespace OHOS::FileManagement::Backup