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 <unistd.h>
17 #include <fcntl.h>
18 #include <sys/types.h>
19 #include "unique_fd.h"
20 #include "b_json/b_json_service_disposal_config.h"
21 
22 #include "cJSON.h"
23 
24 namespace OHOS::FileManagement::Backup {
25 using namespace std;
26 
27 namespace {
28     const string PATH_BUNDLE_BACKUP_HOME = "/data/service/el2/100/backup/";
29     const string CONFIG_NAME = "RestoreDisposalConfig.json";
30 }
31 
BJsonDisposalConfig()32 BJsonDisposalConfig::BJsonDisposalConfig()
33 {
34     string filePath = PATH_BUNDLE_BACKUP_HOME + CONFIG_NAME;
35     if (access(filePath.c_str(), F_OK) == 0) {
36         HILOGI("file exist filePath:%{public}s", filePath.c_str());
37         return;
38     }
39     HILOGI("Failed to access filePath :%{public}s", filePath.c_str());
40     UniqueFd fd(open(filePath.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR));
41     if (fd < 0) {
42         HILOGE("Failed to creat filePath :%{public}s", filePath.c_str());
43         return;
44     }
45     cJSON *jsonObjectDis = cJSON_CreateObject();
46     if (jsonObjectDis == nullptr) {
47         HILOGE("Creat json failed");
48         return;
49     }
50     cJSON *jsonArray = cJSON_CreateArray();
51     if (jsonArray == nullptr) {
52         HILOGE("Creat json failed");
53         cJSON_Delete(jsonObjectDis);
54         return;
55     }
56     cJSON_AddItemToObject(jsonObjectDis, "DispoasalConfigFile", jsonArray);
57 
58     char *newStr = cJSON_Print(jsonObjectDis);
59     if (newStr == nullptr) {
60         HILOGE("cJSON_Print json failed");
61         cJSON_Delete(jsonObjectDis);
62         return;
63     }
64     ofstream outFile(filePath);
65     if (!outFile.is_open()) {
66         HILOGE("open json failed");
67         free(newStr);
68         cJSON_Delete(jsonObjectDis);
69         return;
70     }
71     outFile << newStr;
72     outFile.close();
73     free(newStr);
74     cJSON_Delete(jsonObjectDis);
75     HILOGI("Creat filePath ok :%{public}s", filePath.c_str());
76 }
77 
AppendIntoDisposalConfigFile(const string & bundleName)78 bool BJsonDisposalConfig::AppendIntoDisposalConfigFile(const string& bundleName)
79 {
80     string filePath = PATH_BUNDLE_BACKUP_HOME + CONFIG_NAME;
81     ifstream inFile(filePath);
82     if (!inFile.is_open()) {
83         HILOGE("open json failed");
84         return false;
85     }
86     string jsonString((istreambuf_iterator<char>(inFile)), istreambuf_iterator<char>());
87     inFile.close();
88 
89     cJSON *jsonObjectDis = cJSON_Parse(jsonString.c_str());
90     if (jsonObjectDis == nullptr) {
91         HILOGE("parse json failed");
92         return false;
93     }
94 
95     cJSON *configArray = cJSON_GetObjectItem(jsonObjectDis, "DispoasalConfigFile");
96     if (configArray == nullptr || !cJSON_IsArray(configArray)) {
97         HILOGE("parse json failed");
98         cJSON_Delete(jsonObjectDis);
99         return false;
100     }
101     cJSON *newItem = cJSON_CreateObject();
102     if (newItem == nullptr) {
103         HILOGE("parse json failed");
104         cJSON_Delete(jsonObjectDis);
105         return false;
106     }
107 
108     cJSON_AddStringToObject(newItem, "bundleName", bundleName.c_str());
109     cJSON_AddItemToArray(configArray, newItem);
110     char *newStr = cJSON_Print(jsonObjectDis);
111     if (newStr == nullptr) {
112         HILOGE("cJSON_Print json failed");
113         cJSON_Delete(jsonObjectDis);
114         return false;
115     }
116     ofstream outFile(filePath);
117     if (!outFile.is_open()) {
118         HILOGE("open json failed");
119         free(newStr);
120         cJSON_Delete(jsonObjectDis);
121         return false;
122     }
123     outFile << newStr;
124     outFile.close();
125 
126     free(newStr);
127     cJSON_Delete(jsonObjectDis);
128     return true;
129 }
130 
DeleteFromDisposalConfigFile(const string & bundleName)131 bool BJsonDisposalConfig::DeleteFromDisposalConfigFile(const string& bundleName)
132 {
133     lock_guard<mutex> autoLock(fileMutex_);
134     string filePath = PATH_BUNDLE_BACKUP_HOME + CONFIG_NAME;
135     ifstream input(filePath);
136     if (!input.is_open()) {
137         HILOGE("open json failed");
138         return false;
139     }
140 
141     string jsonString((istreambuf_iterator<char>(input)), istreambuf_iterator<char>());
142     input.close();
143 
144     cJSON *jsonObjectDis = cJSON_Parse(jsonString.c_str());
145     if (jsonObjectDis == nullptr) {
146         HILOGE("parse json failed");
147         return false;
148     }
149 
150     cJSON *configArray = cJSON_GetObjectItem(jsonObjectDis, "DispoasalConfigFile");
151     if (configArray == nullptr || !cJSON_IsArray(configArray)) {
152         cJSON_Delete(jsonObjectDis);
153         return false;
154     }
155     for (int i = 0; i < cJSON_GetArraySize(configArray); ++i) {
156         cJSON *item = cJSON_GetArrayItem(configArray, i);
157         if (item != nullptr && cJSON_GetObjectItem(item, "bundleName") != nullptr &&
158             cJSON_GetObjectItem(item, "bundleName")->type == cJSON_String &&
159             cJSON_GetObjectItem(item, "bundleName")->valuestring == bundleName) {
160             cJSON_DeleteItemFromArray(configArray, i);
161             break;
162         }
163     }
164     char *newStr = cJSON_Print(jsonObjectDis);
165     if (newStr == nullptr) {
166         HILOGE("cJSON_Print json failed");
167         cJSON_Delete(jsonObjectDis);
168         return false;
169     }
170     ofstream output(filePath);
171     if (!output.is_open()) {
172         HILOGE("open json failed");
173         free(newStr);
174         cJSON_Delete(jsonObjectDis);
175         return false;
176     }
177     output << newStr;
178     output.close();
179 
180     free(newStr);
181     cJSON_Delete(jsonObjectDis);
182     return true;
183 }
184 
IfBundleNameInDisposalConfigFile(const string & bundleName)185 bool BJsonDisposalConfig::IfBundleNameInDisposalConfigFile(const string& bundleName)
186 {
187     lock_guard<mutex> autoLock(fileMutex_);
188     string filePath = PATH_BUNDLE_BACKUP_HOME + CONFIG_NAME;
189     ifstream inFile(filePath);
190     if (!inFile.is_open()) {
191         HILOGE("open json failed");
192         return false;
193     }
194 
195     string jsonString((istreambuf_iterator<char>(inFile)), istreambuf_iterator<char>());
196     inFile.close();
197 
198     cJSON *jsonObjectDis = cJSON_Parse(jsonString.c_str());
199     if (jsonObjectDis == nullptr) {
200         HILOGE("parse json failed");
201         return false;
202     }
203 
204     cJSON *configArray = cJSON_GetObjectItem(jsonObjectDis, "DispoasalConfigFile");
205     if (configArray == nullptr || !cJSON_IsArray(configArray)) {
206         HILOGE("parse json failed");
207         cJSON_Delete(jsonObjectDis);
208         return false;
209     }
210     bool ifBundlename = false;
211     for (int i = 0; i < cJSON_GetArraySize(configArray); ++i) {
212         cJSON *item = cJSON_GetArrayItem(configArray, i);
213         if (item != nullptr && cJSON_GetObjectItem(item, "bundleName") != nullptr &&
214             cJSON_GetObjectItem(item, "bundleName")->type == cJSON_String &&
215             cJSON_GetObjectItem(item, "bundleName")->valuestring == bundleName) {
216             ifBundlename = true;
217         }
218     }
219 
220     if (!ifBundlename) {
221         AppendIntoDisposalConfigFile(bundleName);
222         HILOGI("AppendIntoDisposalConfigFile OK");
223     }
224 
225     cJSON_Delete(jsonObjectDis);
226     return true;
227 }
228 
GetBundleNameFromConfigFile()229 vector<string> BJsonDisposalConfig::GetBundleNameFromConfigFile()
230 {
231     lock_guard<mutex> autoLock(fileMutex_);
232     string filePath = PATH_BUNDLE_BACKUP_HOME + CONFIG_NAME;
233     vector<string> bundleNameList;
234     ifstream inFile(filePath);
235     if (!inFile.is_open()) {
236         HILOGE("open json failed");
237         return {};
238     }
239     string jsonString((istreambuf_iterator<char>(inFile)), istreambuf_iterator<char>());
240     inFile.close();
241 
242     cJSON *jsonObjectDis = cJSON_Parse(jsonString.c_str());
243     if (jsonObjectDis == nullptr) {
244         HILOGE("parse json failed");
245         return {};
246     }
247 
248     cJSON *configArray = cJSON_GetObjectItem(jsonObjectDis, "DispoasalConfigFile");
249     if (configArray == nullptr || !cJSON_IsArray(configArray)) {
250         HILOGE("parse json failed");
251         cJSON_Delete(jsonObjectDis);
252         return {};
253     }
254     for (int i = 0; i < cJSON_GetArraySize(configArray); ++i) {
255         cJSON *item = cJSON_GetArrayItem(configArray, i);
256         if (item != nullptr && cJSON_GetObjectItem(item, "bundleName") != nullptr &&
257             cJSON_GetObjectItem(item, "bundleName")->type == cJSON_String) {
258             bundleNameList.push_back(cJSON_GetObjectItem(item, "bundleName")->valuestring);
259         }
260     }
261     cJSON_Delete(jsonObjectDis);
262     return bundleNameList;
263 }
264 
DeleteConfigFile()265 bool BJsonDisposalConfig::DeleteConfigFile()
266 {
267     string filePath = PATH_BUNDLE_BACKUP_HOME + CONFIG_NAME;
268     if (access(filePath.c_str(), F_OK) != 0) {
269         HILOGE("File is not exist");
270         return false;
271     }
272     if (remove(filePath.c_str()) != 0) {
273         HILOGE("Delete DisposalConfigFile failed");
274         return false;
275     }
276     HILOGI("All Restore Finished, Delete DisposalConfigFile OK");
277     return true;
278 }
279 } // namespace OHOS::FileManagement::Backup
280