1 /*
2 * Copyright (C) 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 #define MLOG_TAG "Media_Cloud_Utils"
17
18 #include "cloud_media_file_utils.h"
19
20 #include <sys/ioctl.h>
21 #include <sys/xattr.h>
22
23 #include <fcntl.h>
24 #include <sys/stat.h>
25 #include <sys/statvfs.h>
26
27 #include "hmdfs.h"
28 #include "media_log.h"
29 #include "media_file_utils.h"
30
31 namespace OHOS::Media::CloudSync {
32 constexpr unsigned WRITEOPEN_CMD = 0x02;
33 #define HMDFS_IOC_GET_WRITEOPEN_CNT _IOR(HMDFS_IOC, WRITEOPEN_CMD, uint32_t)
34 #define O_RDONLY 00
35
GetParentPathAndFilename(const std::string & path,std::string & parentPath,std::string & filename)36 bool CloudMediaFileUtils::GetParentPathAndFilename(
37 const std::string &path, std::string &parentPath, std::string &filename)
38 {
39 size_t slashIndex = path.rfind("/");
40 size_t pointIndex = path.rfind(".");
41 if (slashIndex == std::string::npos || pointIndex == std::string::npos || slashIndex >= pointIndex) {
42 MEDIA_ERR_LOG("Invalid path: %{public}s.", MediaFileUtils::DesensitizePath(path).c_str());
43 return false;
44 }
45 parentPath = path.substr(0, slashIndex + 1);
46 filename = path.substr(slashIndex + 1);
47 return true;
48 }
49
GetFileSizeV2(const std::string & filePath,size_t & size)50 bool CloudMediaFileUtils::GetFileSizeV2(const std::string &filePath, size_t &size)
51 {
52 MEDIA_WARN_LOG("GetFileSize enter: %{public}s", filePath.c_str());
53 struct stat statbuf;
54 if (stat(filePath.c_str(), &statbuf) == -1) {
55 MEDIA_WARN_LOG("GetFileSize Failed, errno: %{public}d, path: %{public}s", errno, filePath.c_str());
56 size = 0;
57 return false;
58 }
59 if (statbuf.st_size < 0) {
60 MEDIA_WARN_LOG("GetFileSize negative, path: %{public}s", filePath.c_str());
61 size = 0;
62 return false;
63 }
64 size = static_cast<size_t>(statbuf.st_size);
65 MEDIA_WARN_LOG("GetFileSize end: %{public}s", filePath.c_str());
66 return true;
67 }
68
LocalWriteOpen(const std::string & dfsPath)69 bool CloudMediaFileUtils::LocalWriteOpen(const std::string &dfsPath)
70 {
71 std::unique_ptr<char[]> absPath = std::make_unique<char[]>(PATH_MAX + 1);
72 if (realpath(dfsPath.c_str(), absPath.get()) == nullptr) {
73 return false;
74 }
75 std::string realPath = absPath.get();
76 char resolvedPath[PATH_MAX] = {'\0'};
77 char *realPaths = realpath(realPath.c_str(), resolvedPath);
78 if (realPaths == NULL) {
79 MEDIA_ERR_LOG("realpath failed");
80 return false;
81 }
82 int fd = open(realPaths, O_RDONLY);
83 if (fd < 0) {
84 MEDIA_ERR_LOG("open failed, errno:%{public}d", errno);
85 return false;
86 }
87 uint32_t writeOpenCnt = 0;
88 int ret = ioctl(fd, HMDFS_IOC_GET_WRITEOPEN_CNT, &writeOpenCnt);
89 close(fd);
90 if (ret < 0) {
91 MEDIA_ERR_LOG("ioctl failed, errno:%{public}d", errno);
92 return false;
93 }
94
95 return writeOpenCnt != 0;
96 }
97 } // namespace OHOS::Media::CloudSync