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