• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-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_session_listener.h"
17 
18 #include "copy/file_size_utils.h"
19 #include "dfs_error.h"
20 #include "network/softbus/softbus_session_pool.h"
21 #include "network/softbus/softbus_permission_check.h"
22 #include "os_account_manager.h"
23 #include "sandbox_helper.h"
24 #include "string"
25 #include "uri.h"
26 #include "utils_directory.h"
27 #include "utils_log.h"
28 
29 namespace OHOS {
30 namespace Storage {
31 namespace DistributedFile {
32 constexpr size_t MAX_SIZE = 500;
33 constexpr int32_t DEFAULT_USER_ID = 100;
34 const std::string FILE_SCHEMA = "file://";
35 const std::string DOCS = "docs";
36 const std::string NETWORK_ID = "?networkid=";
37 const std::string FILE_SEPARATOR = "/";
38 const std::string DISTRIBUTED_PATH = "distributedfiles/.remote_share/";
39 const std::string MEDIA = "media";
40 using namespace OHOS::AppFileService;
41 using namespace OHOS::FileManagement;
42 
QueryActiveUserId()43 int32_t SoftBusSessionListener::QueryActiveUserId()
44 {
45     std::vector<int32_t> ids;
46     ErrCode errCode = AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids);
47     if (errCode != FileManagement::ERR_OK || ids.empty()) {
48         LOGE("Query active userid failed, errCode: %{public}d, ", errCode);
49         return DEFAULT_USER_ID;
50     }
51     return ids[0];
52 }
53 
GetFileName(const std::vector<std::string> & fileList,const std::string & path,const std::string & dstPath)54 std::vector<std::string> SoftBusSessionListener::GetFileName(const std::vector<std::string> &fileList,
55                                                              const std::string &path,
56                                                              const std::string &dstPath)
57 {
58     std::vector<std::string> tmp;
59     if (Utils::IsFolder(path)) {
60         for (const auto &it : fileList) {
61             tmp.push_back(it.substr(path.size() + 1));
62         }
63         return tmp;
64     }
65     if (dstPath.find("??") == 0) {
66         auto pos = dstPath.rfind("/");
67         tmp.push_back(dstPath.substr(pos + 1));
68     } else {
69         auto pos = path.rfind("/");
70         tmp.push_back(path.substr(pos + 1));
71     }
72     return tmp;
73 }
74 
OnSessionOpened(int32_t sessionId,PeerSocketInfo info)75 void SoftBusSessionListener::OnSessionOpened(int32_t sessionId, PeerSocketInfo info)
76 {
77     LOGI("OnSessionOpened sessionId = %{public}d", sessionId);
78     if (!SoftBusPermissionCheck::IsSameAccount(info.networkId)) {
79         LOGI("The source and sink device is not same account, not support.");
80         Shutdown(sessionId);
81         return;
82     }
83     std::string sessionName = info.name;
84     SoftBusSessionPool::SessionInfo sessionInfo;
85     auto ret = SoftBusSessionPool::GetInstance().GetSessionInfo(sessionName, sessionInfo);
86     if (!ret) {
87         LOGE("GetSessionInfo failed");
88         return;
89     }
90 
91     std::string physicalPath = GetRealPath(sessionInfo.srcUri);
92     if (physicalPath.empty()) {
93         LOGE("GetRealPath failed");
94         return;
95     }
96 
97     auto fileList = OHOS::Storage::DistributedFile::Utils::GetFilePath(physicalPath);
98     if (fileList.empty()) {
99         LOGE("GetFilePath failed or file is empty");
100         return;
101     }
102 
103     const char *src[MAX_SIZE] = {};
104     for (size_t i = 0; i < fileList.size() && fileList.size() < MAX_SIZE; i++) {
105         src[i] = fileList.at(i).c_str();
106     }
107 
108     auto fileNameList = GetFileName(fileList, physicalPath, sessionInfo.dstPath);
109     if (fileNameList.empty()) {
110         LOGE("GetFileName failed or file is empty");
111         return;
112     }
113     const char *dst[MAX_SIZE] = {};
114     for (size_t i = 0; i < fileNameList.size() && fileList.size() < MAX_SIZE; i++) {
115         dst[i] = fileNameList.at(i).c_str();
116     }
117     LOGI("Enter SendFile.");
118     ret = ::SendFile(sessionId, src, dst, static_cast<uint32_t>(fileList.size()));
119     if (ret != E_OK) {
120         LOGE("SendFile failed, sessionId = %{public}d", sessionId);
121     }
122     SoftBusSessionPool::GetInstance().DeleteSessionInfo(sessionName);
123 }
124 
OnSessionClosed(int32_t sessionId,ShutdownReason reason)125 void SoftBusSessionListener::OnSessionClosed(int32_t sessionId, ShutdownReason reason)
126 {
127     (void)reason;
128     std::string sessionName = "";
129     sessionName = SoftBusHandler::GetSessionName(sessionId);
130     LOGI("OnSessionClosed, sessionId = %{public}d", sessionId);
131     SoftBusHandler::GetInstance().CloseSessionWithSessionName(sessionName);
132 }
133 
GetLocalUri(const std::string & uri)134 std::string SoftBusSessionListener::GetLocalUri(const std::string &uri)
135 {
136     auto pos = uri.find(NETWORK_ID);
137     if (pos == std::string::npos) {
138         return "";
139     }
140     return uri.substr(0, pos);
141 }
142 
GetBundleName(const std::string & uri)143 std::string SoftBusSessionListener::GetBundleName(const std::string &uri)
144 {
145     auto pos = uri.find(FILE_SCHEMA);
146     if (pos == std::string::npos) {
147         return "";
148     }
149     auto tmpUri = uri.substr(pos + FILE_SCHEMA.size());
150     if (tmpUri.empty()) {
151         return "";
152     }
153     auto bundleNamePos = tmpUri.find(FILE_SEPARATOR);
154     if (bundleNamePos == std::string::npos) {
155         return "";
156     }
157     return tmpUri.substr(0, bundleNamePos);
158 }
159 
GetSandboxPath(const std::string & uri)160 std::string SoftBusSessionListener::GetSandboxPath(const std::string &uri)
161 {
162     auto pos = uri.find(DISTRIBUTED_PATH);
163     if (pos == std::string::npos) {
164         return "";
165     }
166     return uri.substr(pos + DISTRIBUTED_PATH.size());
167 }
168 
GetRealPath(const std::string & srcUri)169 std::string SoftBusSessionListener::GetRealPath(const std::string &srcUri)
170 {
171     std::string localUri = GetLocalUri(srcUri);
172     if (localUri.empty()) {
173         LOGE("get local uri failed.");
174         return localUri;
175     }
176     std::string physicalPath;
177     if (SandboxHelper::GetPhysicalPath(localUri, std::to_string(QueryActiveUserId()), physicalPath) != E_OK) {
178         LOGE("GetPhysicalPath failed, invalid uri");
179         return "";
180     }
181     if (physicalPath.empty() || physicalPath.size() >= PATH_MAX) {
182         LOGE("PhysicalPath.size() = %{public}zu", physicalPath.size());
183         return "";
184     }
185     if (!FileSizeUtils::IsFilePathValid(physicalPath)) {
186         LOGE("Check physicalPath err, physicalPath is forbidden");
187         return "";
188     }
189     char realPath[PATH_MAX] = { 0x00 };
190     if (realpath(physicalPath.c_str(), realPath) == nullptr) {
191         LOGE("realpath failed, error: %{public}d", errno);
192         return "";
193     }
194     return physicalPath;
195 }
196 } // namespace DistributedFile
197 } // namespace Storage
198 } // namespace OHOS