1 /*
2 * Copyright (c) 2023-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 #include "file_operations_local.h"
16
17 #include <cerrno>
18 #include <dirent.h>
19
20 #include "file_operations_cloud.h"
21 #include "file_operations_helper.h"
22 #include "utils_log.h"
23
24 namespace OHOS {
25 namespace FileManagement {
26 namespace CloudDisk {
27 using namespace std;
28 static const int32_t BUNDLE_NAME_OFFSET = 1000000000;
29 static const int32_t STAT_MODE_DIR = 0771;
30 static const float LOOKUP_TIMEOUT = 60.0;
31
Lookup(fuse_req_t req,fuse_ino_t parent,const char * name)32 void FileOperationsLocal::Lookup(fuse_req_t req, fuse_ino_t parent, const char *name) {}
33
GetAttr(fuse_req_t req,fuse_ino_t ino,struct fuse_file_info * fi)34 void FileOperationsLocal::GetAttr(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
35 {
36 struct CloudDiskFuseData *data = reinterpret_cast<struct CloudDiskFuseData *>(fuse_req_userdata(req));
37 if (ino == FUSE_ROOT_ID) {
38 string path = FileOperationsHelper::GetCloudDiskRootPath(data->userId);
39
40 struct stat statBuf;
41 int err = stat(path.c_str(), &statBuf);
42 if (err != 0) {
43 LOGE("lookup %{public}s error, err: %{public}d", path.c_str(), err);
44 fuse_reply_err(req, err);
45 return;
46 }
47 fuse_reply_attr(req, &statBuf, 0);
48 return;
49 }
50 auto inoPtr = FileOperationsHelper::FindCloudDiskInode(data, static_cast<int64_t>(ino));
51 if (inoPtr == nullptr) {
52 fuse_reply_err(req, EINVAL);
53 LOGE("inode not found");
54 return;
55 }
56 fuse_reply_attr(req, &inoPtr->stat, 0);
57 }
58
ReadDir(fuse_req_t req,fuse_ino_t ino,size_t size,off_t off,struct fuse_file_info * fi)59 void FileOperationsLocal::ReadDir(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
60 struct fuse_file_info *fi)
61 {
62 (void) fi;
63 string path;
64 struct CloudDiskFuseData *data =
65 reinterpret_cast<struct CloudDiskFuseData *>(fuse_req_userdata(req));
66 if (ino == FUSE_ROOT_ID) {
67 path = FileOperationsHelper::GetCloudDiskRootPath(data->userId);
68 } else {
69 auto inoPtr = FileOperationsHelper::FindCloudDiskInode(data, static_cast<int64_t>(ino));
70 if (inoPtr == nullptr) {
71 fuse_reply_err(req, EINVAL);
72 LOGE("inode not found");
73 return;
74 }
75 path = inoPtr->path;
76 }
77 DIR* dir = opendir(path.c_str());
78 if (dir == NULL) {
79 LOGE("opendir error %{public}d, path:%{public}s", errno, path.c_str());
80 return;
81 }
82
83 struct dirent *entry;
84 string entryData;
85 size_t len = 0;
86 while ((entry = readdir(dir)) != NULL) {
87 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
88 continue;
89 }
90
91 string childPath = FileOperationsHelper::GetCloudDiskLocalPath(data->userId,
92 entry->d_name);
93 int64_t key = FileOperationsHelper::FindLocalId(data, std::to_string(ino) +
94 entry->d_name);
95 auto childPtr = FileOperationsHelper::FindCloudDiskInode(data, key);
96 if (childPtr == nullptr) {
97 childPtr = FileOperationsHelper::GenerateCloudDiskInode(data, ino,
98 entry->d_name, childPath.c_str());
99 }
100 if (childPtr == nullptr) {
101 continue;
102 }
103 FileOperationsHelper::AddDirEntry(req, entryData, len, entry->d_name, childPtr);
104 }
105 FileOperationsHelper::FuseReplyLimited(req, entryData.c_str(), len, off, size);
106 closedir(dir);
107 return;
108 }
109 } // namespace CloudDisk
110 } // namespace FileManagement
111 } // namespace OHOS
112