1cc290419Sopenharmony_ci/* 2cc290419Sopenharmony_ci * Copyright (C) 2021 Huawei Device Co., Ltd. 3cc290419Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4cc290419Sopenharmony_ci * you may not use this file except in compliance with the License. 5cc290419Sopenharmony_ci * You may obtain a copy of the License at 6cc290419Sopenharmony_ci * 7cc290419Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8cc290419Sopenharmony_ci * 9cc290419Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10cc290419Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11cc290419Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12cc290419Sopenharmony_ci * See the License for the specific language governing permissions and 13cc290419Sopenharmony_ci * limitations under the License. 14cc290419Sopenharmony_ci */ 15cc290419Sopenharmony_ci#include "file.h" 16cc290419Sopenharmony_ci#include "serial_struct.h" 17cc290419Sopenharmony_ci 18cc290419Sopenharmony_cinamespace Hdc { 19cc290419Sopenharmony_ciHdcFile::HdcFile(HTaskInfo hTaskInfo) 20cc290419Sopenharmony_ci : HdcTransferBase(hTaskInfo) 21cc290419Sopenharmony_ci{ 22cc290419Sopenharmony_ci commandBegin = CMD_FILE_BEGIN; 23cc290419Sopenharmony_ci commandData = CMD_FILE_DATA; 24cc290419Sopenharmony_ci isStableBuf = hTaskInfo->isStableBuf; 25cc290419Sopenharmony_ci} 26cc290419Sopenharmony_ci 27cc290419Sopenharmony_ciHdcFile::~HdcFile() 28cc290419Sopenharmony_ci{ 29cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "~HdcFile channelId:%u", taskInfo->channelId); 30cc290419Sopenharmony_ci}; 31cc290419Sopenharmony_ci 32cc290419Sopenharmony_civoid HdcFile::StopTask() 33cc290419Sopenharmony_ci{ 34cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "StopTask channelId:%u", taskInfo->channelId); 35cc290419Sopenharmony_ci singalStop = true; 36cc290419Sopenharmony_ci}; 37cc290419Sopenharmony_ci 38cc290419Sopenharmony_cibool HdcFile::BeginTransfer(CtxFile *context, const string &command) 39cc290419Sopenharmony_ci{ 40cc290419Sopenharmony_ci int argc = 0; 41cc290419Sopenharmony_ci bool ret = false; 42cc290419Sopenharmony_ci StartTraceScope("HdcFile::BeginTransfer"); 43cc290419Sopenharmony_ci char **argv = Base::SplitCommandToArgs(command.c_str(), &argc); 44cc290419Sopenharmony_ci if (argc < CMD_ARG1_COUNT || argv == nullptr) { 45cc290419Sopenharmony_ci LogMsg(MSG_FAIL, "Transfer path split failed"); 46cc290419Sopenharmony_ci if (argv) { 47cc290419Sopenharmony_ci delete[](reinterpret_cast<char *>(argv)); 48cc290419Sopenharmony_ci } 49cc290419Sopenharmony_ci return false; 50cc290419Sopenharmony_ci } 51cc290419Sopenharmony_ci if (!SetMasterParameters(context, command.c_str(), argc, argv)) { 52cc290419Sopenharmony_ci delete[](reinterpret_cast<char *>(argv)); 53cc290419Sopenharmony_ci return false; 54cc290419Sopenharmony_ci } 55cc290419Sopenharmony_ci uv_fs_t *openReq = new uv_fs_t; 56cc290419Sopenharmony_ci if (openReq == nullptr) { 57cc290419Sopenharmony_ci delete[](reinterpret_cast<char *>(argv)); 58cc290419Sopenharmony_ci LogMsg(MSG_FAIL, "HdcFile::BeginTransfer new openReq failed"); 59cc290419Sopenharmony_ci return false; 60cc290419Sopenharmony_ci } 61cc290419Sopenharmony_ci memset_s(openReq, sizeof(uv_fs_t), 0, sizeof(uv_fs_t)); 62cc290419Sopenharmony_ci openReq->data = context; 63cc290419Sopenharmony_ci do { 64cc290419Sopenharmony_ci ++refCount; 65cc290419Sopenharmony_ci uv_fs_open(loopTask, openReq, context->localPath.c_str(), O_RDONLY, S_IWUSR | S_IRUSR, OnFileOpen); 66cc290419Sopenharmony_ci context->master = true; 67cc290419Sopenharmony_ci ret = true; 68cc290419Sopenharmony_ci } while (false); 69cc290419Sopenharmony_ci if (!ret) { 70cc290419Sopenharmony_ci LogMsg(MSG_FAIL, "Transfer path failed, Master:%s Slave:%s", context->localPath.c_str(), 71cc290419Sopenharmony_ci context->remotePath.c_str()); 72cc290419Sopenharmony_ci } 73cc290419Sopenharmony_ci delete[](reinterpret_cast<char *>(argv)); 74cc290419Sopenharmony_ci return ret; 75cc290419Sopenharmony_ci} 76cc290419Sopenharmony_ci 77cc290419Sopenharmony_cibool HdcFile::SetMasterParameters(CtxFile *context, const char *command, int argc, char **argv) 78cc290419Sopenharmony_ci{ 79cc290419Sopenharmony_ci int srcArgvIndex = 0; 80cc290419Sopenharmony_ci string errStr; 81cc290419Sopenharmony_ci const string cmdOptionTstmp = "-a"; 82cc290419Sopenharmony_ci const string cmdOptionSync = "-sync"; 83cc290419Sopenharmony_ci const string cmdOptionZip = "-z"; 84cc290419Sopenharmony_ci const string cmdOptionModeSync = "-m"; 85cc290419Sopenharmony_ci 86cc290419Sopenharmony_ci for (int i = 0; i < argc; i++) { 87cc290419Sopenharmony_ci if (argv[i] == cmdOptionZip) { 88cc290419Sopenharmony_ci context->transferConfig.compressType = COMPRESS_LZ4; 89cc290419Sopenharmony_ci ++srcArgvIndex; 90cc290419Sopenharmony_ci } else if (argv[i] == cmdOptionSync) { 91cc290419Sopenharmony_ci context->transferConfig.updateIfNew = true; 92cc290419Sopenharmony_ci ++srcArgvIndex; 93cc290419Sopenharmony_ci } else if (argv[i] == cmdOptionTstmp) { 94cc290419Sopenharmony_ci // The time zone difference may cause the display time on the PC and the 95cc290419Sopenharmony_ci // device to differ by several hours 96cc290419Sopenharmony_ci // 97cc290419Sopenharmony_ci // ls -al --full-time 98cc290419Sopenharmony_ci context->transferConfig.holdTimestamp = true; 99cc290419Sopenharmony_ci ++srcArgvIndex; 100cc290419Sopenharmony_ci } else if (argv[i] == CMD_OPTION_CLIENTCWD) { 101cc290419Sopenharmony_ci context->transferConfig.clientCwd = argv[i + 1]; 102cc290419Sopenharmony_ci srcArgvIndex += CMD_ARG1_COUNT; // skip 2args 103cc290419Sopenharmony_ci } else if (argv[i] == cmdOptionModeSync) { 104cc290419Sopenharmony_ci context->fileModeSync = true; 105cc290419Sopenharmony_ci ++srcArgvIndex; 106cc290419Sopenharmony_ci } else if (argv[i] == CMDSTR_REMOTE_PARAMETER) { 107cc290419Sopenharmony_ci ++srcArgvIndex; 108cc290419Sopenharmony_ci } else if (argv[i][0] == '-') { 109cc290419Sopenharmony_ci LogMsg(MSG_FAIL, "Unknown file option: %s", argv[i]); 110cc290419Sopenharmony_ci return false; 111cc290419Sopenharmony_ci } 112cc290419Sopenharmony_ci } 113cc290419Sopenharmony_ci if (argc == srcArgvIndex) { 114cc290419Sopenharmony_ci LogMsg(MSG_FAIL, "There is no local and remote path"); 115cc290419Sopenharmony_ci return false; 116cc290419Sopenharmony_ci } 117cc290419Sopenharmony_ci context->remotePath = argv[argc - 1]; 118cc290419Sopenharmony_ci context->localPath = argv[argc - CMD_FILE_PENULT_PARAM]; 119cc290419Sopenharmony_ci if (taskInfo->serverOrDaemon) { 120cc290419Sopenharmony_ci // master and server 121cc290419Sopenharmony_ci if ((srcArgvIndex + 1) == argc) { 122cc290419Sopenharmony_ci LogMsg(MSG_FAIL, "There is no remote path"); 123cc290419Sopenharmony_ci return false; 124cc290419Sopenharmony_ci } 125cc290419Sopenharmony_ci ExtractRelativePath(context->transferConfig.clientCwd, context->localPath); 126cc290419Sopenharmony_ci } else { 127cc290419Sopenharmony_ci if ((srcArgvIndex + 1) == argc) { 128cc290419Sopenharmony_ci context->remotePath = "."; 129cc290419Sopenharmony_ci context->localPath = argv[argc - 1]; 130cc290419Sopenharmony_ci } 131cc290419Sopenharmony_ci } 132cc290419Sopenharmony_ci 133cc290419Sopenharmony_ci context->localName = Base::GetFullFilePath(context->localPath); 134cc290419Sopenharmony_ci 135cc290419Sopenharmony_ci mode_t mode = mode_t(~S_IFMT); 136cc290419Sopenharmony_ci if (!Base::CheckDirectoryOrPath(context->localPath.c_str(), true, true, errStr, mode) && (mode & S_IFDIR)) { 137cc290419Sopenharmony_ci context->isDir = true; 138cc290419Sopenharmony_ci GetSubFilesRecursively(context->localPath, context->localName, &context->taskQueue); 139cc290419Sopenharmony_ci if (context->taskQueue.size() == 0) { 140cc290419Sopenharmony_ci LogMsg(MSG_FAIL, "Operation failed, because the source folder is empty."); 141cc290419Sopenharmony_ci return false; 142cc290419Sopenharmony_ci } 143cc290419Sopenharmony_ci context->fileCnt = 0; 144cc290419Sopenharmony_ci context->dirSize = 0; 145cc290419Sopenharmony_ci context->localDirName = Base::GetPathWithoutFilename(context->localPath); 146cc290419Sopenharmony_ci 147cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "localDirName = %s", context->localDirName.c_str()); 148cc290419Sopenharmony_ci 149cc290419Sopenharmony_ci context->localName = context->taskQueue.back(); 150cc290419Sopenharmony_ci context->localPath = context->localDirName + context->localName; 151cc290419Sopenharmony_ci 152cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "localPath = %s", context->localPath.c_str()); 153cc290419Sopenharmony_ci context->taskQueue.pop_back(); 154cc290419Sopenharmony_ci } 155cc290419Sopenharmony_ci return true; 156cc290419Sopenharmony_ci} 157cc290419Sopenharmony_ci 158cc290419Sopenharmony_civoid HdcFile::CheckMaster(CtxFile *context) 159cc290419Sopenharmony_ci{ 160cc290419Sopenharmony_ci StartTraceScope("HdcFile::CheckMaster"); 161cc290419Sopenharmony_ci if (context->fileModeSync) { 162cc290419Sopenharmony_ci string s = SerialStruct::SerializeToString(context->fileMode); 163cc290419Sopenharmony_ci SendToAnother(CMD_FILE_MODE, reinterpret_cast<uint8_t *>(const_cast<char *>(s.c_str())), s.size()); 164cc290419Sopenharmony_ci } else { 165cc290419Sopenharmony_ci string s = SerialStruct::SerializeToString(context->transferConfig); 166cc290419Sopenharmony_ci SendToAnother(CMD_FILE_CHECK, reinterpret_cast<uint8_t *>(const_cast<char *>(s.c_str())), s.size()); 167cc290419Sopenharmony_ci } 168cc290419Sopenharmony_ci} 169cc290419Sopenharmony_ci 170cc290419Sopenharmony_civoid HdcFile::WhenTransferFinish(CtxFile *context) 171cc290419Sopenharmony_ci{ 172cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "WhenTransferFinish fileCnt:%d", context->fileCnt); 173cc290419Sopenharmony_ci uint8_t flag = 1; 174cc290419Sopenharmony_ci context->fileCnt++; 175cc290419Sopenharmony_ci context->dirSize += context->indexIO; 176cc290419Sopenharmony_ci SendToAnother(CMD_FILE_FINISH, &flag, 1); 177cc290419Sopenharmony_ci} 178cc290419Sopenharmony_ci 179cc290419Sopenharmony_civoid HdcFile::TransferSummary(CtxFile *context) 180cc290419Sopenharmony_ci{ 181cc290419Sopenharmony_ci uint64_t nMSec = Base::GetRuntimeMSec() - 182cc290419Sopenharmony_ci (context->fileCnt > 1 ? context->transferDirBegin : context->transferBegin); 183cc290419Sopenharmony_ci uint64_t fSize = context->fileCnt > 1 ? context->dirSize : context->indexIO; 184cc290419Sopenharmony_ci double fRate = static_cast<double>(fSize) / nMSec; // / /1000 * 1000 = 0 185cc290419Sopenharmony_ci if (context->indexIO >= context->fileSize || context->lastErrno == 0) { 186cc290419Sopenharmony_ci LogMsg(MSG_OK, "FileTransfer finish, Size:%lld, File count = %d, time:%lldms rate:%.2lfkB/s", 187cc290419Sopenharmony_ci fSize, context->fileCnt, nMSec, fRate); 188cc290419Sopenharmony_ci } else { 189cc290419Sopenharmony_ci constexpr int bufSize = 1024; 190cc290419Sopenharmony_ci char buf[bufSize] = { 0 }; 191cc290419Sopenharmony_ci uv_strerror_r(static_cast<int>(-context->lastErrno), buf, bufSize); 192cc290419Sopenharmony_ci LogMsg(MSG_FAIL, "Transfer Stop at:%lld/%lld(Bytes), Reason: %s", context->indexIO, context->fileSize, 193cc290419Sopenharmony_ci buf); 194cc290419Sopenharmony_ci } 195cc290419Sopenharmony_ci} 196cc290419Sopenharmony_ci 197cc290419Sopenharmony_cibool HdcFile::FileModeSync(const uint16_t cmd, uint8_t *payload, const int payloadSize) 198cc290419Sopenharmony_ci{ 199cc290419Sopenharmony_ci StartTraceScope("HdcFile::FileModeSync"); 200cc290419Sopenharmony_ci if (ctxNow.master) { 201cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "FileModeSync master ctxNow.fileModeSync = %d size = %zu", ctxNow.fileModeSync, 202cc290419Sopenharmony_ci ctxNow.dirMode.size()); 203cc290419Sopenharmony_ci if (ctxNow.dirMode.size() > 0) { 204cc290419Sopenharmony_ci auto mode = ctxNow.dirMode.back(); 205cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "file = %s permissions: %o uId = %u, gId = %u conext = %s", 206cc290419Sopenharmony_ci mode.fullName.c_str(), mode.perm, mode.uId, mode.gId, mode.context.c_str()); 207cc290419Sopenharmony_ci string s = SerialStruct::SerializeToString(mode); 208cc290419Sopenharmony_ci ctxNow.dirMode.pop_back(); 209cc290419Sopenharmony_ci SendToAnother(CMD_DIR_MODE, reinterpret_cast<uint8_t *>(const_cast<char *>(s.c_str())), s.size()); 210cc290419Sopenharmony_ci } else { 211cc290419Sopenharmony_ci string s = SerialStruct::SerializeToString(ctxNow.transferConfig); 212cc290419Sopenharmony_ci SendToAnother(CMD_FILE_CHECK, reinterpret_cast<uint8_t *>(const_cast<char *>(s.c_str())), s.size()); 213cc290419Sopenharmony_ci } 214cc290419Sopenharmony_ci } else { 215cc290419Sopenharmony_ci ctxNow.fileModeSync = true; 216cc290419Sopenharmony_ci string serialString(reinterpret_cast<char *>(payload), payloadSize); 217cc290419Sopenharmony_ci if (cmd == CMD_FILE_MODE) { 218cc290419Sopenharmony_ci SerialStruct::ParseFromString(ctxNow.fileMode, serialString); 219cc290419Sopenharmony_ci } else { 220cc290419Sopenharmony_ci FileMode dirMode; 221cc290419Sopenharmony_ci SerialStruct::ParseFromString(dirMode, serialString); 222cc290419Sopenharmony_ci 223cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "file = %s permissions: %o uId = %u, gId = %u context = %s", 224cc290419Sopenharmony_ci dirMode.fullName.c_str(), dirMode.perm, dirMode.uId, dirMode.gId, dirMode.context.c_str()); 225cc290419Sopenharmony_ci 226cc290419Sopenharmony_ci vector<string> dirsOfOptName; 227cc290419Sopenharmony_ci if (dirMode.fullName.find('/') != string::npos) { 228cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "dir mode create parent dir from linux system"); 229cc290419Sopenharmony_ci Base::SplitString(dirMode.fullName, "/", dirsOfOptName); 230cc290419Sopenharmony_ci } else if (dirMode.fullName.find('\\') != string::npos) { 231cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "dir mode create parent dir from windows system"); 232cc290419Sopenharmony_ci Base::SplitString(dirMode.fullName, "\\", dirsOfOptName); 233cc290419Sopenharmony_ci } else { 234cc290419Sopenharmony_ci dirsOfOptName.emplace_back(dirMode.fullName); 235cc290419Sopenharmony_ci } 236cc290419Sopenharmony_ci 237cc290419Sopenharmony_ci dirMode.fullName = ""; 238cc290419Sopenharmony_ci for (auto s : dirsOfOptName) { 239cc290419Sopenharmony_ci if (dirMode.fullName.empty()) { 240cc290419Sopenharmony_ci dirMode.fullName = s; 241cc290419Sopenharmony_ci } else { 242cc290419Sopenharmony_ci dirMode.fullName = dirMode.fullName + Base::GetPathSep() + s; 243cc290419Sopenharmony_ci } 244cc290419Sopenharmony_ci } 245cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "dir = %s permissions: %o uId = %u, gId = %u context = %s", 246cc290419Sopenharmony_ci dirMode.fullName.c_str(), dirMode.perm, dirMode.uId, dirMode.gId, dirMode.context.c_str()); 247cc290419Sopenharmony_ci ctxNow.dirModeMap.insert(std::make_pair(dirMode.fullName, dirMode)); 248cc290419Sopenharmony_ci } 249cc290419Sopenharmony_ci SendToAnother(CMD_FILE_MODE, nullptr, 0); 250cc290419Sopenharmony_ci } 251cc290419Sopenharmony_ci return true; 252cc290419Sopenharmony_ci} 253cc290419Sopenharmony_ci 254cc290419Sopenharmony_cibool HdcFile::SlaveCheck(uint8_t *payload, const int payloadSize) 255cc290419Sopenharmony_ci{ 256cc290419Sopenharmony_ci bool ret = true; 257cc290419Sopenharmony_ci bool childRet = false; 258cc290419Sopenharmony_ci string errStr; 259cc290419Sopenharmony_ci // parse option 260cc290419Sopenharmony_ci string serialString(reinterpret_cast<char *>(payload), payloadSize); 261cc290419Sopenharmony_ci TransferConfig &stat = ctxNow.transferConfig; 262cc290419Sopenharmony_ci SerialStruct::ParseFromString(stat, serialString); 263cc290419Sopenharmony_ci ctxNow.fileSize = stat.fileSize; 264cc290419Sopenharmony_ci ctxNow.localPath = stat.path; 265cc290419Sopenharmony_ci ctxNow.master = false; 266cc290419Sopenharmony_ci#ifdef HDC_DEBUG 267cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "HdcFile fileSize got %" PRIu64 "", ctxNow.fileSize); 268cc290419Sopenharmony_ci#endif 269cc290419Sopenharmony_ci 270cc290419Sopenharmony_ci if (!CheckLocalPath(ctxNow.localPath, stat.optionalName, errStr)) { 271cc290419Sopenharmony_ci LogMsg(MSG_FAIL, "%s", errStr.c_str()); 272cc290419Sopenharmony_ci return false; 273cc290419Sopenharmony_ci } 274cc290419Sopenharmony_ci 275cc290419Sopenharmony_ci if (!CheckFilename(ctxNow.localPath, stat.optionalName, errStr)) { 276cc290419Sopenharmony_ci LogMsg(MSG_FAIL, "%s", errStr.c_str()); 277cc290419Sopenharmony_ci return false; 278cc290419Sopenharmony_ci } 279cc290419Sopenharmony_ci // check path 280cc290419Sopenharmony_ci childRet = SmartSlavePath(stat.clientCwd, ctxNow.localPath, stat.optionalName.c_str()); 281cc290419Sopenharmony_ci if (childRet && ctxNow.transferConfig.updateIfNew) { // file exist and option need update 282cc290419Sopenharmony_ci // if is newer 283cc290419Sopenharmony_ci uv_fs_t fs = {}; 284cc290419Sopenharmony_ci uv_fs_stat(nullptr, &fs, ctxNow.localPath.c_str(), nullptr); 285cc290419Sopenharmony_ci uv_fs_req_cleanup(&fs); 286cc290419Sopenharmony_ci if ((uint64_t)fs.statbuf.st_mtim.tv_sec >= ctxNow.transferConfig.mtime) { 287cc290419Sopenharmony_ci LogMsg(MSG_FAIL, "Target file is the same date or newer,path: %s", ctxNow.localPath.c_str()); 288cc290419Sopenharmony_ci return false; 289cc290419Sopenharmony_ci } 290cc290419Sopenharmony_ci } 291cc290419Sopenharmony_ci uv_fs_t *openReq = new uv_fs_t; 292cc290419Sopenharmony_ci if (openReq == nullptr) { 293cc290419Sopenharmony_ci LogMsg(MSG_FAIL, "HdcFile::SlaveCheck new openReq failed"); 294cc290419Sopenharmony_ci return false; 295cc290419Sopenharmony_ci } 296cc290419Sopenharmony_ci memset_s(openReq, sizeof(uv_fs_t), 0, sizeof(uv_fs_t)); 297cc290419Sopenharmony_ci openReq->data = &ctxNow; 298cc290419Sopenharmony_ci // begin work 299cc290419Sopenharmony_ci ++refCount; 300cc290419Sopenharmony_ci uv_fs_open(loopTask, openReq, ctxNow.localPath.c_str(), UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY, 301cc290419Sopenharmony_ci S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH, OnFileOpen); 302cc290419Sopenharmony_ci if (ctxNow.transferDirBegin == 0) { 303cc290419Sopenharmony_ci ctxNow.transferDirBegin = Base::GetRuntimeMSec(); 304cc290419Sopenharmony_ci } 305cc290419Sopenharmony_ci ctxNow.transferBegin = Base::GetRuntimeMSec(); 306cc290419Sopenharmony_ci return ret; 307cc290419Sopenharmony_ci} 308cc290419Sopenharmony_ci 309cc290419Sopenharmony_civoid HdcFile::TransferNext(CtxFile *context) 310cc290419Sopenharmony_ci{ 311cc290419Sopenharmony_ci context->localName = context->taskQueue.back(); 312cc290419Sopenharmony_ci context->localPath = context->localDirName + context->localName; 313cc290419Sopenharmony_ci context->taskQueue.pop_back(); 314cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "TransferNext localPath = %s queuesize:%d", 315cc290419Sopenharmony_ci context->localPath.c_str(), ctxNow.taskQueue.size()); 316cc290419Sopenharmony_ci uv_fs_t *openReq = new uv_fs_t; 317cc290419Sopenharmony_ci if (openReq == nullptr) { 318cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "HdcFile::TransferNext new openReq failed for file %s", context->localPath.c_str()); 319cc290419Sopenharmony_ci OnFileOpenFailed(context); 320cc290419Sopenharmony_ci return; 321cc290419Sopenharmony_ci } 322cc290419Sopenharmony_ci memset_s(openReq, sizeof(uv_fs_t), 0, sizeof(uv_fs_t)); 323cc290419Sopenharmony_ci openReq->data = context; 324cc290419Sopenharmony_ci do { 325cc290419Sopenharmony_ci ++refCount; 326cc290419Sopenharmony_ci uv_fs_open(loopTask, openReq, context->localPath.c_str(), O_RDONLY, S_IWUSR | S_IRUSR, OnFileOpen); 327cc290419Sopenharmony_ci } while (false); 328cc290419Sopenharmony_ci 329cc290419Sopenharmony_ci return; 330cc290419Sopenharmony_ci} 331cc290419Sopenharmony_ci 332cc290419Sopenharmony_cibool HdcFile::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) 333cc290419Sopenharmony_ci{ 334cc290419Sopenharmony_ci HdcTransferBase::CommandDispatch(command, payload, payloadSize); 335cc290419Sopenharmony_ci bool ret = true; 336cc290419Sopenharmony_ci StartTraceScope("HdcFile::CommandDispatch"); 337cc290419Sopenharmony_ci switch (command) { 338cc290419Sopenharmony_ci case CMD_FILE_INIT: { // initial 339cc290419Sopenharmony_ci string s = string(reinterpret_cast<char *>(payload), payloadSize); 340cc290419Sopenharmony_ci ret = BeginTransfer(&ctxNow, s); 341cc290419Sopenharmony_ci ctxNow.transferBegin = Base::GetRuntimeMSec(); 342cc290419Sopenharmony_ci break; 343cc290419Sopenharmony_ci } 344cc290419Sopenharmony_ci case CMD_FILE_CHECK: { 345cc290419Sopenharmony_ci ret = SlaveCheck(payload, payloadSize); 346cc290419Sopenharmony_ci break; 347cc290419Sopenharmony_ci } 348cc290419Sopenharmony_ci case CMD_FILE_MODE: 349cc290419Sopenharmony_ci case CMD_DIR_MODE: { 350cc290419Sopenharmony_ci ret = FileModeSync(command, payload, payloadSize); 351cc290419Sopenharmony_ci break; 352cc290419Sopenharmony_ci } 353cc290419Sopenharmony_ci case CMD_FILE_FINISH: { 354cc290419Sopenharmony_ci if (*payload) { // close-step3 355cc290419Sopenharmony_ci if (ctxNow.isFdOpen) { 356cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "OnFileIO fs_close, localPath:%s result:%d, closeReqSubmitted:%d", 357cc290419Sopenharmony_ci ctxNow.localPath.c_str(), ctxNow.openFd, ctxNow.closeReqSubmitted); 358cc290419Sopenharmony_ci CloseFd(ctxNow.openFd); 359cc290419Sopenharmony_ci // solve the fd leak caused by early exit due to illegal operation on a directory. 360cc290419Sopenharmony_ci ctxNow.isFdOpen = false; 361cc290419Sopenharmony_ci } 362cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "Dir = %d taskQueue size = %d", ctxNow.isDir, ctxNow.taskQueue.size()); 363cc290419Sopenharmony_ci if (ctxNow.isDir && (ctxNow.taskQueue.size() > 0)) { 364cc290419Sopenharmony_ci TransferNext(&ctxNow); 365cc290419Sopenharmony_ci } else { 366cc290419Sopenharmony_ci ctxNow.ioFinish = true; 367cc290419Sopenharmony_ci ctxNow.transferDirBegin = 0; 368cc290419Sopenharmony_ci --(*payload); 369cc290419Sopenharmony_ci SendToAnother(CMD_FILE_FINISH, payload, 1); 370cc290419Sopenharmony_ci } 371cc290419Sopenharmony_ci } else { // close-step3 372cc290419Sopenharmony_ci TransferSummary(&ctxNow); 373cc290419Sopenharmony_ci TaskFinish(); 374cc290419Sopenharmony_ci } 375cc290419Sopenharmony_ci break; 376cc290419Sopenharmony_ci } 377cc290419Sopenharmony_ci default: 378cc290419Sopenharmony_ci break; 379cc290419Sopenharmony_ci } 380cc290419Sopenharmony_ci return ret; 381cc290419Sopenharmony_ci} 382cc290419Sopenharmony_ci} // namespace Hdc 383