• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 #include "distributedfile_service.h"
16 
17 #include <exception>
18 #include <fcntl.h>
19 #include <unistd.h>
20 
21 #include "bundle_mgr_interface.h"
22 #include "bundle_mgr_proxy.h"
23 #include "device_manager_agent.h"
24 #include "ipc_skeleton.h"
25 #include "iservice_registry.h"
26 #include "message_parcel.h"
27 #include "parcel.h"
28 #include "softbus_agent.h"
29 #include "system_ability_definition.h"
30 #include "utils_directory.h"
31 #include "utils_log.h"
32 
33 namespace OHOS {
34 namespace Storage {
35 namespace DistributedFile {
36 namespace {
37     constexpr int32_t FILE_BLOCK_SIZE = 1024;
38     constexpr char TEMP_FILE_NAME[] = "/data/system_ce/tmp";
39 }
40 
41 REGISTER_SYSTEM_ABILITY_BY_ID(DistributedFileService, FILEMANAGEMENT_DISTRIBUTED_FILE_SERVICE_SA_ID, false);
42 
OnDump()43 void DistributedFileService::OnDump()
44 {
45     LOGI("OnDump");
46 }
47 
OnStart()48 void DistributedFileService::OnStart()
49 {
50     PublishSA();
51     StartManagers();
52 }
53 
OnStop()54 void DistributedFileService::OnStop()
55 {
56     LOGI("OnStop");
57 }
58 
PublishSA()59 void DistributedFileService::PublishSA()
60 {
61     bool ret = SystemAbility::Publish(this);
62     if (!ret) {
63         LOGE("Leave, publishing DistributedFileService failed!");
64         return;
65     }
66 }
67 
StartManagers()68 void DistributedFileService::StartManagers()
69 {
70     DeviceManagerAgent::GetInstance();
71 }
72 
CreateSourceResources(const std::vector<std::string> & sourceFileList,std::vector<char * > & sFileList)73 int32_t DistributedFileService::CreateSourceResources(const std::vector<std::string> &sourceFileList,
74     std::vector<char *> &sFileList)
75 {
76     if (sourceFileList.size() != 1) {
77         return DFS_MEM_ERROR;
78     }
79     for (int index = 0; index < sourceFileList.size(); ++index) {
80         LOGI("DistributedFileService::SendFile Source File List %{public}d, %{public}s, %{public}d",
81             index, sourceFileList.at(index).c_str(), sourceFileList.at(index).length());
82         if (index == 0) {
83             std::string tmpString("/data/system_ce/tmp");
84             int32_t length = tmpString.length();
85             if (length <= 0) {
86                 return DFS_MEM_ERROR;
87             }
88             char *sTemp = new char[length + 1];
89             if (sTemp == nullptr) {
90                 return DFS_MEM_ERROR;
91             }
92             sFileList.push_back(sTemp);
93             if (memset_s(sTemp, length + 1, '\0', length + 1) != EOK) {
94                 return DFS_MEM_ERROR;
95             }
96             if (memcpy_s(sTemp, length + 1, tmpString.c_str(), length) != EOK) {
97                 return DFS_MEM_ERROR;
98             }
99             sTemp[length] = '\0';
100         } else {
101             int32_t length = sourceFileList.at(index).length();
102             if (length <= 0) {
103                 return DFS_MEM_ERROR;
104             }
105             char *sTemp = new char[length + 1];
106             if (sTemp == nullptr) {
107                 return DFS_MEM_ERROR;
108             }
109             sFileList.push_back(sTemp);
110             if (memset_s(sTemp, length + 1, '\0', length + 1) != EOK) {
111                 return DFS_MEM_ERROR;
112             }
113             if (memcpy_s(sTemp, length + 1, sourceFileList.at(index).c_str(), length) != EOK) {
114                 return DFS_MEM_ERROR;
115             }
116             sTemp[length] = '\0';
117         }
118     }
119     return DFS_NO_ERROR;
120 }
121 
CreateDestResources(const std::vector<std::string> & destinationFileList,std::vector<char * > & dFileList)122 int32_t DistributedFileService::CreateDestResources(const std::vector<std::string> &destinationFileList,
123     std::vector<char *> &dFileList)
124 {
125     if (destinationFileList.size() > 1) {
126         return DFS_MEM_ERROR;
127     }
128 
129     for (int index = 0; index < destinationFileList.size(); ++index) {
130         int32_t length = destinationFileList.at(index).length();
131         if (length <= 0) {
132             return DFS_MEM_ERROR;
133         }
134         char *sTemp = new char[length + 1];
135         if (sTemp == nullptr) {
136             return DFS_MEM_ERROR;
137         }
138         dFileList.push_back(sTemp);
139         if (memset_s(sTemp, length + 1, '\0', length + 1) != EOK) {
140             return DFS_MEM_ERROR;
141         }
142         if (memcpy_s(sTemp, length + 1, destinationFileList.at(index).c_str(), length) != EOK) {
143             return DFS_MEM_ERROR;
144         }
145         sTemp[length] = '\0';
146     }
147     return DFS_NO_ERROR;
148 }
149 
DestroyFileList(std::vector<char * > & fileList)150 void DistributedFileService::DestroyFileList(std::vector<char *> &fileList)
151 {
152     if (fileList.empty()) {
153         LOGE("Send file list is empty");
154         return;
155     }
156 
157     for (size_t index = 0; index < fileList.size(); ++index) {
158         char *temp = fileList.at(index);
159         if (temp != nullptr) {
160             LOGI("destroy list index [%{public}d] memory", index);
161             delete[] temp;
162         }
163     }
164     fileList.clear();
165 }
166 
SendFile(const std::string & cid,const std::vector<std::string> & sourceFileList,const std::vector<std::string> & destinationFileList,const uint32_t fileCount)167 int32_t DistributedFileService::SendFile(const std::string &cid,
168                                          const std::vector<std::string> &sourceFileList,
169                                          const std::vector<std::string> &destinationFileList,
170                                          const uint32_t fileCount)
171 {
172     int32_t result = DFS_NO_ERROR;
173     if (cid.empty() || fileCount != 1 || sourceFileList.empty() || sourceFileList.size() != fileCount ||
174         destinationFileList.size() > 1) {
175         LOGE("SendFile params failed");
176         return DFS_PARAM_FILE_COUNT_ERROR;
177     }
178 
179     std::vector<char *> sFileList;
180     std::vector<char *> dFileList;
181 
182     result = CreateSourceResources(sourceFileList, sFileList);
183 
184     if (!destinationFileList.empty()) {
185         result = CreateDestResources(destinationFileList, dFileList);
186     }
187 
188     if (result != DFS_MEM_ERROR) {
189         auto softBusAgent = SoftbusAgent::GetInstance();
190         result = softBusAgent->SendFile(cid, (const char **)sFileList.data(),
191             (const char **)dFileList.data(), fileCount);
192     }
193 
194     DestroyFileList(sFileList);
195     DestroyFileList(dFileList);
196     return result;
197 }
198 
OpenFile(int32_t fd,const std::string & fileName,int32_t mode)199 int32_t DistributedFileService::OpenFile(int32_t fd, const std::string &fileName, int32_t mode)
200 {
201     if (fd <= 0 || fileName.empty()) {
202         return DFS_FILE_OP_ERROR;
203     }
204 
205     const char *tmpFile = TEMP_FILE_NAME;
206     struct stat fileStat;
207     bool fileExist = (stat(tmpFile, &fileStat) == 0);
208     if (fileExist) {
209         int32_t result = remove(tmpFile);
210         if (result != 0) {
211             close(fd);
212             LOGE("DFS SA remove temp file result %{public}d, %{public}d", result, errno);
213             return DFS_FILE_OP_ERROR;
214         }
215     }
216 
217     int32_t writeFd = open(tmpFile, O_WRONLY | O_CREAT, (S_IREAD | S_IWRITE) | S_IRGRP | S_IROTH);
218     if (writeFd <= 0) {
219         close(fd);
220         LOGE("DFS SA open temp file failed %{public}d, %{public}d", writeFd, errno);
221         return DFS_FILE_OP_ERROR;
222     }
223     auto buffer = std::make_unique<char[]>(FILE_BLOCK_SIZE);
224     ssize_t actLen = 0;
225     do {
226         actLen = read(fd, buffer.get(), FILE_BLOCK_SIZE);
227         if (actLen > 0) {
228             write(writeFd, buffer.get(), actLen);
229         } else if (actLen == 0) {
230             break;
231         } else {
232             if (errno == EINTR) {
233                 actLen = FILE_BLOCK_SIZE;
234             } else {
235                 close(fd);
236                 close(writeFd);
237                 return DFS_FILE_OP_ERROR;
238             }
239         }
240     } while (actLen > 0);
241 
242     close(fd);
243     close(writeFd);
244 
245     return DFS_SUCCESS;
246 }
247 
RegisterNotifyCallback(sptr<IFileTransferCallback> & callback)248 int32_t DistributedFileService::RegisterNotifyCallback(sptr<IFileTransferCallback> &callback)
249 {
250     SoftbusAgent::GetInstance()->SetTransCallback(callback);
251     LOGD("DistributedFileService::RegisterNotifyCallback: cb[%{public}p]", callback->AsObject().GetRefPtr());
252     return DFS_SUCCESS;
253 }
254 
UnRegisterNotifyCallback()255 int32_t DistributedFileService::UnRegisterNotifyCallback()
256 {
257     SoftbusAgent::GetInstance()->RemoveTransCallbak();
258     return DFS_SUCCESS;
259 }
260 
IsDeviceOnline(const std::string & cid)261 int32_t DistributedFileService::IsDeviceOnline(const std::string &cid)
262 {
263     std::set<std::string> onlineDevice = DeviceManagerAgent::GetInstance()->getOnlineDevs();
264     if (onlineDevice.find(cid) != onlineDevice.end()) {
265         return DEVICE_ONLINE;
266     }
267     return DEVICE_NOT_ONLINE;
268 }
269 } // namespace DistributedFile
270 } // namespace Storage
271 } // namespace OHOS
272