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 "network/softbus/softbus_handler_asset.h"
17
18 #include <filesystem>
19 #include <fstream>
20 #include <memory>
21 #include <regex>
22 #include <sstream>
23 #include <unistd.h>
24
25 #include "asset_callback_manager.h"
26 #include "device_manager.h"
27 #include "dfs_error.h"
28 #include "dm_device_info.h"
29 #include "ipc_skeleton.h"
30 #include "network/softbus/softbus_asset_recv_listener.h"
31 #include "network/softbus/softbus_asset_send_listener.h"
32 #include "network/softbus/softbus_session_listener.h"
33 #include "network/softbus/softbus_session_pool.h"
34 #include "refbase.h"
35 #include "softbus_bus_center.h"
36 #include "utils_log.h"
37
38 namespace OHOS {
39 namespace Storage {
40 namespace DistributedFile {
41 using namespace OHOS::FileManagement;
42 constexpr size_t MAX_SIZE = 500;
43 constexpr size_t BUFFER_SIZE = 512;
44 const int32_t DFS_QOS_TYPE_MIN_BW = 90 * 1024 * 1024;
45 const int32_t DFS_QOS_TYPE_MAX_LATENCY = 10000;
46 const int32_t DFS_QOS_TYPE_MIN_LATENCY = 2000;
47 const uint32_t MAX_ONLINE_DEVICE_SIZE = 10000;
48 const std::string RELATIVE_PATH_FLAG = "/account/device_view/local/data/";
49 const std::string DST_BUNDLE_NAME_FLAG = "/";
50 const std::string TEMP_DIR = "ASSET_TEMP";
51 const std::string ASSET_POSTFIX_SINGLE = ".asset_single?";
52 const std::string ASSET_POSTFIX_ZIP = ".asset_zip?";
SoftBusHandlerAsset()53 SoftBusHandlerAsset::SoftBusHandlerAsset()
54 {
55 ISocketListener fileSendListener;
56 fileSendListener.OnBind = nullptr;
57 fileSendListener.OnShutdown = SoftBusAssetSendListener::OnSendShutdown;
58 fileSendListener.OnFile = SoftBusAssetSendListener::OnFile;
59 fileSendListener.OnBytes = nullptr;
60 fileSendListener.OnMessage = nullptr;
61 fileSendListener.OnQos = nullptr;
62 sessionListener_[DFS_ASSET_ROLE_SEND] = fileSendListener;
63
64 ISocketListener fileReceiveListener;
65 fileReceiveListener.OnBind = SoftbusAssetRecvListener::OnAssetRecvBind;
66 fileReceiveListener.OnShutdown = SoftbusAssetRecvListener::OnRecvShutdown;
67 fileReceiveListener.OnFile = SoftbusAssetRecvListener::OnFile;
68 fileReceiveListener.OnBytes = nullptr;
69 fileReceiveListener.OnMessage = nullptr;
70 fileReceiveListener.OnQos = nullptr;
71 sessionListener_[DFS_ASSET_ROLE_RECV] = fileReceiveListener;
72 }
73
74 SoftBusHandlerAsset::~SoftBusHandlerAsset() = default;
75
GetInstance()76 SoftBusHandlerAsset &SoftBusHandlerAsset::GetInstance()
77 {
78 LOGD("SoftBusHandlerAsset::GetInstance");
79 static SoftBusHandlerAsset assetHandle;
80 return assetHandle;
81 }
82
CreateAssetLocalSessionServer()83 void SoftBusHandlerAsset::CreateAssetLocalSessionServer()
84 {
85 LOGI("CreateAssetLocalSessionServer Enter.");
86 {
87 std::lock_guard<std::mutex> lock(serverIdMapMutex_);
88 if (serverIdMap_.find(ASSET_LOCAL_SESSION_NAME) != serverIdMap_.end()) {
89 LOGI("%s: Session already create.", ASSET_LOCAL_SESSION_NAME.c_str());
90 return;
91 }
92 }
93
94 SocketInfo serverInfo = {
95 .name = const_cast<char*>(ASSET_LOCAL_SESSION_NAME.c_str()),
96 .pkgName = const_cast<char*>(SERVICE_NAME.c_str()),
97 .dataType = DATA_TYPE_FILE,
98 };
99 int32_t socketId = Socket(serverInfo);
100 if (socketId < E_OK) {
101 LOGE("Create Socket fail socketId, socketId = %{public}d", socketId);
102 return;
103 }
104 QosTV qos[] = {
105 {.qos = QOS_TYPE_MIN_BW, .value = DFS_QOS_TYPE_MIN_BW},
106 {.qos = QOS_TYPE_MAX_LATENCY, .value = DFS_QOS_TYPE_MAX_LATENCY},
107 {.qos = QOS_TYPE_MIN_LATENCY, .value = DFS_QOS_TYPE_MIN_LATENCY},
108 };
109 int32_t ret = Listen(socketId, qos, sizeof(qos) / sizeof(qos[0]), &sessionListener_[DFS_ASSET_ROLE_RECV]);
110 if (ret != E_OK) {
111 LOGE("Listen SocketClient error");
112 Shutdown(socketId);
113 return;
114 }
115 SoftBusSessionPool::SessionInfo sessionInfo{.uid = IPCSkeleton::GetCallingUid()};
116 SoftBusSessionPool::GetInstance().AddSessionInfo(ASSET_LOCAL_SESSION_NAME, sessionInfo);
117 {
118 std::lock_guard<std::mutex> lock(serverIdMapMutex_);
119 serverIdMap_.insert(std::make_pair(ASSET_LOCAL_SESSION_NAME, socketId));
120 }
121 LOGI("CreateAssetLocalSessionServer Success.");
122 }
123
DeleteAssetLocalSessionServer()124 void SoftBusHandlerAsset::DeleteAssetLocalSessionServer()
125 {
126 LOGI("DeleteAssetLocalSessionServer Enter.");
127 std::lock_guard<std::mutex> lock(serverIdMapMutex_);
128 if (!serverIdMap_.empty()) {
129 auto it = serverIdMap_.find(ASSET_LOCAL_SESSION_NAME);
130 if (it == serverIdMap_.end()) {
131 LOGI("%s: Session already delete.", ASSET_LOCAL_SESSION_NAME.c_str());
132 return;
133 }
134 int32_t socketId = it->second;
135 serverIdMap_.erase(it);
136 Shutdown(socketId);
137 LOGI("RemoveSessionServer success.");
138 }
139 SoftBusSessionPool::GetInstance().DeleteSessionInfo(ASSET_LOCAL_SESSION_NAME);
140 }
141
AssetBind(const std::string & dstNetworkId,int32_t & socketId)142 int32_t SoftBusHandlerAsset::AssetBind(const std::string &dstNetworkId, int32_t &socketId)
143 {
144 if (dstNetworkId.empty()) {
145 LOGI("The parameter is empty");
146 return E_OPEN_SESSION;
147 }
148 LOGI("AssetBind Enter.");
149 if (!IsSameAccount(dstNetworkId)) {
150 LOGI("The source and sink device is not same account, not support.");
151 return E_OPEN_SESSION;
152 }
153 QosTV qos[] = {
154 {.qos = QOS_TYPE_MIN_BW, .value = DFS_QOS_TYPE_MIN_BW},
155 {.qos = QOS_TYPE_MAX_LATENCY, .value = DFS_QOS_TYPE_MAX_LATENCY},
156 {.qos = QOS_TYPE_MIN_LATENCY, .value = DFS_QOS_TYPE_MIN_LATENCY},
157 };
158 SocketInfo clientInfo = {
159 .name = const_cast<char*>((ASSET_LOCAL_SESSION_NAME.c_str())),
160 .peerName = const_cast<char*>(ASSET_LOCAL_SESSION_NAME.c_str()),
161 .peerNetworkId = const_cast<char*>(dstNetworkId.c_str()),
162 .pkgName = const_cast<char*>(SERVICE_NAME.c_str()),
163 .dataType = DATA_TYPE_FILE,
164 };
165
166 socketId = Socket(clientInfo);
167 if (socketId < E_OK) {
168 LOGE("Create OpenSoftbusChannel Socket error");
169 return E_OPEN_SESSION;
170 }
171
172 int32_t ret = Bind(socketId, qos, sizeof(qos) / sizeof(qos[0]), &sessionListener_[DFS_ASSET_ROLE_SEND]);
173 if (ret != E_OK) {
174 LOGE("Bind SocketClient error");
175 Shutdown(socketId);
176 return ret;
177 }
178 LOGI("OpenSession success.");
179 return E_OK;
180 }
181
AssetSendFile(int32_t socketId,const std::string & sendFile,bool isSingleFile)182 int32_t SoftBusHandlerAsset::AssetSendFile(int32_t socketId, const std::string& sendFile, bool isSingleFile)
183 {
184 auto assetObj = GetAssetObj(socketId);
185 if (assetObj == nullptr) {
186 LOGE("get assetObj fail.");
187 return ERR_BAD_VALUE;
188 }
189 if (!IsSameAccount(assetObj->dstNetworkId_)) {
190 LOGI("The source and sink device is not same account, not support.");
191 return ERR_BAD_VALUE;
192 }
193
194 const char *src[MAX_SIZE] = {};
195 src[0] = sendFile.c_str();
196
197 auto dstFile = GetDstFile(sendFile, assetObj->srcBundleName_,
198 assetObj->dstBundleName_, assetObj->sessionId_, isSingleFile);
199 if (dstFile.empty()) {
200 LOGE("GetFileName failed or file is empty");
201 return ERR_BAD_VALUE;
202 }
203 const char *dst[MAX_SIZE] = {};
204 dst[0] = dstFile.c_str();
205
206 LOGI("AssetSendFile Enter.");
207 int32_t ret = ::SendFile(socketId, src, dst, 1);
208 if (ret != E_OK) {
209 LOGE("SendFile failed, sessionId = %{public}d", socketId);
210 return ret;
211 }
212 return E_OK;
213 }
214
closeAssetBind(int32_t socketId)215 void SoftBusHandlerAsset::closeAssetBind(int32_t socketId)
216 {
217 LOGI("closeAssetBind Enter.");
218 RemoveAssetObj(socketId);
219 Shutdown(socketId);
220 }
221
OnAssetRecvBind(int32_t socketId,const std::string & srcNetWorkId)222 void SoftBusHandlerAsset::OnAssetRecvBind(int32_t socketId, const std::string &srcNetWorkId)
223 {
224 if (!IsSameAccount(srcNetWorkId)) {
225 LOGE("The source and sink device is not same account, not support.");
226 Shutdown(socketId);
227 return;
228 }
229 std::lock_guard<std::mutex> lock(clientInfoMutex_);
230 clientInfoMap_.insert(std::make_pair(socketId, srcNetWorkId));
231 }
232
GetClientInfo(int32_t socketId)233 std::string SoftBusHandlerAsset::GetClientInfo(int32_t socketId)
234 {
235 std::lock_guard<std::mutex> lock(clientInfoMutex_);
236 auto iter = clientInfoMap_.find(socketId);
237 if (iter == clientInfoMap_.end()) {
238 LOGE("ClientInfo not registered");
239 return "";
240 }
241 return iter->second;
242 }
243
RemoveClientInfo(int32_t socketId)244 void SoftBusHandlerAsset::RemoveClientInfo(int32_t socketId)
245 {
246 std::lock_guard<std::mutex> lock(clientInfoMutex_);
247 auto it = clientInfoMap_.find(socketId);
248 if (it != clientInfoMap_.end()) {
249 clientInfoMap_.erase(it->first);
250 }
251 }
252
AddAssetObj(int32_t socketId,const sptr<AssetObj> & assetObj)253 void SoftBusHandlerAsset::AddAssetObj(int32_t socketId, const sptr<AssetObj> &assetObj)
254 {
255 std::lock_guard<std::mutex> lock(assetObjMapMutex_);
256 auto iter = assetObjMap_.find(socketId);
257 if (iter != assetObjMap_.end()) {
258 LOGI("assetObj exist.");
259 return;
260 }
261 assetObjMap_.insert(std::pair<int32_t, sptr<AssetObj>>(socketId, assetObj));
262 }
263
GetAssetObj(int32_t socketId)264 sptr<AssetObj> SoftBusHandlerAsset::GetAssetObj(int32_t socketId)
265 {
266 std::lock_guard<std::mutex> lock(assetObjMapMutex_);
267 auto iter = assetObjMap_.find(socketId);
268 if (iter == assetObjMap_.end()) {
269 LOGE("AssetObj not exist");
270 return nullptr;
271 }
272
273 return iter->second;
274 }
275
RemoveAssetObj(int32_t socketId)276 void SoftBusHandlerAsset::RemoveAssetObj(int32_t socketId)
277 {
278 std::lock_guard<std::mutex> lock(assetObjMapMutex_);
279 auto iter = assetObjMap_.find(socketId);
280 if (iter != assetObjMap_.end()) {
281 assetObjMap_.erase(iter);
282 }
283 }
284
GenerateAssetObjInfo(int32_t socketId,const std::string & fileName,const sptr<AssetObj> & assetObj)285 int32_t SoftBusHandlerAsset::GenerateAssetObjInfo(int32_t socketId,
286 const std::string &fileName,
287 const sptr<AssetObj> &assetObj)
288 {
289 size_t pos = fileName.find(RELATIVE_PATH_FLAG);
290 if (pos == std::string::npos) {
291 LOGE("Generate dstBundleName fail, firstFile is %{public}s", GetAnonyString(fileName).c_str());
292 return FileManagement::ERR_BAD_VALUE;
293 }
294 std::string relativeFileName = fileName.substr(pos + RELATIVE_PATH_FLAG.length());
295
296 pos = relativeFileName.find(DST_BUNDLE_NAME_FLAG);
297 if (pos == std::string::npos) {
298 LOGE("Generate dstBundleName fail, relativeFirstFile is %{public}s", GetAnonyString(fileName).c_str());
299 return FileManagement::ERR_BAD_VALUE;
300 }
301 auto dstBundleName = relativeFileName.substr(0, pos);
302 assetObj->dstBundleName_ = dstBundleName;
303
304 std::smatch match;
305 std::regex sessionIdRegex("sessionId=([^&]+)");
306 if (!std::regex_search(fileName, match, sessionIdRegex)) {
307 LOGE("Generate sessionId fail, relativeFirstFile is %{public}s", GetAnonyString(fileName).c_str());
308 return FileManagement::ERR_BAD_VALUE;
309 }
310 assetObj->sessionId_ = match[1].str();
311
312 std::regex srcBundleNameRegex("srcBundleName=([^&]+)");
313 if (!std::regex_search(fileName, match, srcBundleNameRegex)) {
314 LOGE("Generate srcBundleName fail, relativeFirstFile is %{public}s", GetAnonyString(fileName).c_str());
315 return FileManagement::ERR_BAD_VALUE;
316 }
317 assetObj->srcBundleName_ = match[1].str();
318
319 assetObj->dstNetworkId_ = GetLocalNetworkId();
320 if (assetObj->dstNetworkId_.empty()) {
321 LOGE("Failed to get info of local devices");
322 return FileManagement::ERR_BAD_VALUE;
323 }
324 return FileManagement::ERR_OK;
325 }
326
IsSameAccount(const std::string & networkId)327 bool SoftBusHandlerAsset::IsSameAccount(const std::string &networkId)
328 {
329 std::vector<DistributedHardware::DmDeviceInfo> deviceList;
330 DistributedHardware::DeviceManager::GetInstance().GetTrustedDeviceList(SERVICE_NAME, "", deviceList);
331 if (deviceList.size() == 0 || deviceList.size() > MAX_ONLINE_DEVICE_SIZE) {
332 LOGE("trust device list size is invalid, size=%zu", deviceList.size());
333 return false;
334 }
335 for (const auto &deviceInfo : deviceList) {
336 if (std::string(deviceInfo.networkId) == networkId) {
337 return (deviceInfo.authForm == DistributedHardware::DmAuthForm::IDENTICAL_ACCOUNT);
338 }
339 }
340 return false;
341 }
342
GetDstFile(const std::string & file,const std::string & srcBundleName,const std::string & dstBundleName,const std::string & sessionId,bool isSingleFile)343 std::string SoftBusHandlerAsset::GetDstFile(const std::string &file,
344 const std::string &srcBundleName,
345 const std::string &dstBundleName,
346 const std::string &sessionId,
347 bool isSingleFile)
348 {
349 std::stringstream dstFile;
350 size_t pos = file.find(srcBundleName);
351 if (pos == std::string::npos) {
352 return "";
353 }
354 std::string tempDir;
355 if (isSingleFile) {
356 tempDir = ASSET_POSTFIX_SINGLE;
357 } else {
358 tempDir = ASSET_POSTFIX_ZIP;
359 }
360 dstFile << dstBundleName << "/" << TEMP_DIR << file.substr(pos + srcBundleName.length())
361 << tempDir << "srcBundleName=" << srcBundleName << "&sessionId=" << sessionId;
362
363 return dstFile.str();
364 }
365
GenerateUris(const std::vector<std::string> & fileList,const std::string & dstBundleName,bool isSingleFile)366 std::vector<std::string> SoftBusHandlerAsset::GenerateUris(const std::vector<std::string> &fileList,
367 const std::string &dstBundleName,
368 bool isSingleFile)
369 {
370 auto tempDir = dstBundleName + "/" + TEMP_DIR;
371 std::vector<std::string> uris;
372 if (isSingleFile) {
373 std::stringstream uri;
374 std::string file = fileList[0];
375 size_t posPrefix = file.find(tempDir);
376 if (posPrefix == std::string::npos) {
377 LOGE("not find tempDir in fileList.");
378 return {};
379 }
380 size_t posPostfix = file.find(ASSET_POSTFIX_SINGLE);
381 if (posPostfix == std::string::npos) {
382 LOGE("not find asset postfix in fileList.");
383 return {};
384 }
385 uri <<"file://" << dstBundleName << "/data/storage/el2/distributedfiles"
386 << file.substr(posPrefix + tempDir.length(), posPostfix - posPrefix - tempDir.length());
387 uris.emplace_back(uri.str());
388 return uris;
389 }
390 for (auto file : fileList) {
391 std::stringstream uri;
392 size_t posPrefix = file.find(tempDir);
393 if (posPrefix == std::string::npos) {
394 LOGE("not find tempDir in fileList.");
395 return {};
396 }
397 uri <<"file://" << dstBundleName << "/data/storage/el2/distributedfiles"
398 << file.substr(posPrefix + tempDir.length());
399 uris.emplace_back(uri.str());
400 }
401 return uris;
402 }
403
CompressFile(const std::vector<std::string> & fileList,const std::string & relativePath,const std::string & zipFileName)404 int32_t SoftBusHandlerAsset::CompressFile(const std::vector<std::string> &fileList,
405 const std::string &relativePath,
406 const std::string &zipFileName)
407 {
408 LOGI("CompressFile begin.");
409 zipFile outputFile = zipOpen64(zipFileName.c_str(), APPEND_STATUS_CREATE);
410 if (!outputFile) {
411 LOGE("Minizip failed to zipOpen, zipFileName = %{public}s", GetAnonyString(zipFileName).c_str());
412 return E_ZIP;
413 }
414
415 for (const std::string& rootFile : fileList) {
416 size_t pos = rootFile.find(relativePath);
417 if (pos == std::string::npos) {
418 LOGE("rootFile not have relativePath");
419 return E_ZIP;
420 }
421 auto file = rootFile.substr(pos + relativePath.length());
422
423 int err = zipOpenNewFileInZip3_64(outputFile, file.c_str(), NULL, NULL, 0, NULL, 0, NULL,
424 Z_DEFLATED, 0, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, NULL, 0, 0);
425 if (err != ZIP_OK) {
426 LOGE("Minizip failed to zipOpenNewFileInZip, file = %{public}s", GetAnonyString(file).c_str());
427 zipClose(outputFile, NULL);
428 return E_ZIP;
429 }
430
431 FILE* f = fopen(rootFile.c_str(), "rb");
432 if (f == NULL) {
433 LOGE("open file fail, path is %{public}s", GetAnonyString(rootFile).c_str());
434 return E_ZIP;
435 }
436 const size_t pageSize { getpagesize() };
437 auto buf = std::make_unique<char[]>(pageSize);
438 size_t actLen;
439 do {
440 actLen = fread(buf.get(), 1, pageSize, f);
441 if (actLen > 0) {
442 zipWriteInFileInZip(outputFile, buf.get(), actLen);
443 }
444 } while (actLen == pageSize);
445 if (fclose(f) != 0) {
446 LOGE("Minizip failed to fclose");
447 }
448 zipCloseFileInZip(outputFile);
449 }
450 zipClose(outputFile, NULL);
451 LOGI("CompressFile end.");
452 return E_OK;
453 }
454
DecompressFile(const std::string & unZipFileName,const std::string & relativePath)455 std::vector<std::string> SoftBusHandlerAsset::DecompressFile(const std::string &unZipFileName,
456 const std::string &relativePath)
457 {
458 LOGI("DecompressFile begin.");
459 if (!IsDir(relativePath)) {
460 MkDirRecurse(relativePath, S_IRWXU | S_IRWXG | S_IXOTH);
461 }
462
463 unzFile zipFile = unzOpen64(unZipFileName.c_str());
464 if (!zipFile) {
465 LOGE("Minizip failed to unzOpen, zipFileName = %{public}s", GetAnonyString(unZipFileName).c_str());
466 return {};
467 }
468
469 unz_global_info64 globalInfo;
470 if (unzGetGlobalInfo64(zipFile, &globalInfo) != UNZ_OK) {
471 unzClose(zipFile);
472 LOGE("Minizip failed to unzGetGlobalInfo");
473 return {};
474 }
475
476 std::vector<std::string> fileList;
477
478 for (size_t i = 0; i < globalInfo.number_entry; ++i) {
479 std::string filePath = ExtractFile(zipFile, relativePath.c_str());
480 if (!filePath.empty()) {
481 fileList.push_back(filePath);
482 }
483 unzCloseCurrentFile(zipFile);
484 unzGoToNextFile(zipFile);
485 }
486 unzClose(zipFile);
487 LOGI("DecompressFile end.");
488 return fileList;
489 }
490
GetLocalNetworkId()491 std::string SoftBusHandlerAsset::GetLocalNetworkId()
492 {
493 NodeBasicInfo tmpNodeInfo;
494 int errCode = GetLocalNodeDeviceInfo(SERVICE_NAME.c_str(), &tmpNodeInfo);
495 if (errCode != 0) {
496 LOGE("Failed to get info of local devices");
497 return "";
498 }
499 return tmpNodeInfo.networkId;
500 }
501
MkDir(const std::string & path,mode_t mode)502 int32_t SoftBusHandlerAsset::MkDir(const std::string &path, mode_t mode)
503 {
504 return TEMP_FAILURE_RETRY(mkdir(path.c_str(), mode));
505 }
506
MkDirRecurse(const std::string & path,mode_t mode)507 bool SoftBusHandlerAsset::MkDirRecurse(const std::string& path, mode_t mode)
508 {
509 size_t pos = path.rfind("/");
510 if (pos == std::string::npos) {
511 LOGE("is not a dir, path : %{public}s", GetAnonyString(path).c_str());
512 }
513 auto dirPath = path.substr(0, pos);
514
515 std::string::size_type index = 0;
516 do {
517 std::string subPath = dirPath;
518 index = path.find('/', index + 1);
519 if (index != std::string::npos) {
520 subPath = path.substr(0, index);
521 }
522
523 if (TEMP_FAILURE_RETRY(access(subPath.c_str(), F_OK)) != 0) {
524 if (MkDir(subPath, mode) != 0 && errno != EEXIST) {
525 return false;
526 }
527 }
528 } while (index != std::string::npos);
529
530 return TEMP_FAILURE_RETRY(access(path.c_str(), F_OK)) == 0;
531 }
532
IsDir(const std::string & path)533 bool SoftBusHandlerAsset::IsDir(const std::string &path)
534 {
535 // check whether the path exists
536 struct stat st;
537 int ret = TEMP_FAILURE_RETRY(lstat(path.c_str(), &st));
538 if (ret) {
539 return false;
540 }
541 return S_ISDIR(st.st_mode);
542 }
543
ExtractFile(unzFile unZipFile,const std::string & dir)544 std::string SoftBusHandlerAsset::ExtractFile(unzFile unZipFile, const std::string &dir)
545 {
546 auto filename = std::make_unique<char[]>(BUFFER_SIZE);
547 unz_file_info64 fileInfo;
548 if (unzGetCurrentFileInfo64(unZipFile, &fileInfo, filename.get(), BUFFER_SIZE, NULL, 0, NULL, 0) != UNZ_OK) {
549 LOGE("Minizip failed to unzGetCurrentFileInfo64");
550 return "";
551 }
552 std::string filenameWithPath(filename.get());
553 filenameWithPath = dir + filenameWithPath;
554 size_t pos = filenameWithPath.rfind('/');
555 if (pos == std::string::npos) {
556 LOGE("file path error, %{public}s", GetAnonyString(filenameWithPath).c_str());
557 return "";
558 }
559 std::string filenameWithoutPath = filenameWithPath.substr(pos + 1);
560
561 if (!IsDir(filenameWithPath)) {
562 MkDirRecurse(filenameWithPath, S_IRWXU | S_IRWXG | S_IXOTH);
563 }
564 if (unzOpenCurrentFile(unZipFile) != UNZ_OK) {
565 LOGE("Minizip failed to unzOpenCurrentFile, filepath is %{public}s", GetAnonyString(filenameWithPath).c_str());
566 }
567 std::fstream file;
568 file.open(filenameWithPath, std::ios_base::out | std::ios_base::binary);
569 if (!file.is_open()) {
570 LOGE("open zip file fail, path is %{public}s", GetAnonyString(filenameWithPath).c_str());
571 return "";
572 }
573 const size_t pageSize = { getpagesize() };
574 auto fileData = std::make_unique<char[]>(pageSize);
575 int32_t bytesRead;
576 do {
577 bytesRead = unzReadCurrentFile(unZipFile, (voidp)fileData.get(), pageSize);
578 if (bytesRead < 0) {
579 LOGE("Minizip failed to unzReadCurrentFile, filepath is %{public}s",
580 GetAnonyString(filenameWithPath).c_str());
581 file.close();
582 return "";
583 }
584 file.write(fileData.get(), bytesRead);
585 } while (bytesRead > 0);
586 file.close();
587 return filenameWithPath;
588 }
589
RemoveFile(const std::string & path,bool isRemove)590 void SoftBusHandlerAsset::RemoveFile(const std::string &path, bool isRemove)
591 {
592 LOGI("RemoveFile path is %{public}s", GetAnonyString(path).c_str());
593 if (!isRemove) {
594 LOGI("this file is not need remove");
595 return;
596 }
597 bool ret = std::filesystem::remove(path.c_str());
598 if (!ret) {
599 LOGE("remove file fail, remove path is %{public}s", GetAnonyString(path).c_str());
600 }
601 }
602 } // namespace DistributedFile
603 } // namespace Storage
604 } // namespace OHOS