• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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