1 /*
2 * Copyright (c) 2023 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 #include "file_uri.h"
17
18 #include <unistd.h>
19 #include <sys/stat.h>
20 #include <sys/types.h>
21
22 #include "uri.h"
23
24 #include "common_func.h"
25 #include "log.h"
26 #include "sandbox_helper.h"
27 #include "parameter.h"
28
29 using namespace std;
30 namespace OHOS {
31 namespace AppFileService {
32 namespace ModuleFileUri {
33 const std::string PATH_SHARE = "/data/storage/el2/share";
34 const std::string MODE_RW = "/rw/";
35 const std::string MODE_R = "/r/";
36 const std::string FILE_SCHEME_PREFIX = "file://";
37 const std::string FILE_MANAGER_AUTHORITY = "docs";
38 const std::string MEDIA_AUTHORITY = "media";
39 const std::string NETWORK_PARA = "?networkid=";
40 const std::string BACKFLASH = "/";
41 const std::string FULL_MOUNT_ENABLE_PARAMETER = "const.filemanager.full_mount.enable";
CheckFileManagerFullMountEnable()42 static bool CheckFileManagerFullMountEnable()
43 {
44 char value[] = "false";
45 int retSystem = GetParameter(FULL_MOUNT_ENABLE_PARAMETER.c_str(), "false", value, sizeof(value));
46 if (retSystem > 0 && !strcmp(value, "true")) {
47 LOGD("The full mount enable parameter is true");
48 return true;
49 }
50 LOGD("The full mount enable parameter is false");
51 return false;
52 }
53
GetName()54 string FileUri::GetName()
55 {
56 string sandboxPath = SandboxHelper::Decode(uri_.GetPath());
57 size_t posLast = sandboxPath.find_last_of("/");
58 if (posLast == string::npos) {
59 return "";
60 }
61
62 if (posLast == sandboxPath.size()) {
63 return "";
64 }
65
66 return sandboxPath.substr(posLast + 1);
67 }
68
GetPath()69 string FileUri::GetPath()
70 {
71 string sandboxPath = SandboxHelper::Decode(uri_.GetPath());
72 string bundleName = uri_.GetAuthority();
73 if (bundleName == MEDIA_AUTHORITY && sandboxPath.find(".") != string::npos) {
74 size_t pos = sandboxPath.rfind("/");
75 if (pos == string::npos) {
76 return "";
77 }
78 return sandboxPath.substr(0, pos);
79 }
80
81 return sandboxPath;
82 }
83
GetRealPath()84 string FileUri::GetRealPath()
85 {
86 string sandboxPath = SandboxHelper::Decode(uri_.GetPath());
87 string realPath = sandboxPath;
88 string bundleName = uri_.GetAuthority();
89 if (bundleName == FILE_MANAGER_AUTHORITY &&
90 uri_.ToString().find(NETWORK_PARA) == string::npos &&
91 (access(realPath.c_str(), F_OK) == 0 || CheckFileManagerFullMountEnable())) {
92 return realPath;
93 }
94
95 if (((bundleName != "") && (bundleName != CommonFunc::GetSelfBundleName())) ||
96 uri_.ToString().find(NETWORK_PARA) != string::npos) {
97 realPath = PATH_SHARE + MODE_RW + bundleName + sandboxPath;
98 if (access(realPath.c_str(), F_OK) != 0) {
99 realPath = PATH_SHARE + MODE_R + bundleName + sandboxPath;
100 }
101 }
102 return realPath;
103 }
104
GetRealPathBySA(const std::string & targetBundleName)105 string FileUri::GetRealPathBySA(const std::string &targetBundleName)
106 {
107 string sandboxPath = SandboxHelper::Decode(uri_.GetPath());
108 string realPath = sandboxPath;
109 string bundleName = uri_.GetAuthority();
110 if (bundleName == FILE_MANAGER_AUTHORITY &&
111 uri_.ToString().find(NETWORK_PARA) == string::npos &&
112 (access(realPath.c_str(), F_OK) == 0 || CheckFileManagerFullMountEnable())) {
113 return realPath;
114 }
115 realPath = PATH_SHARE + MODE_R + bundleName + sandboxPath;
116 return realPath;
117 }
118
ToString()119 string FileUri::ToString()
120 {
121 return uri_.ToString();
122 }
123
GetFullDirectoryUri()124 string FileUri::GetFullDirectoryUri()
125 {
126 string uri = uri_.ToString();
127 struct stat fileInfo;
128 if (stat(GetRealPath().c_str(), &fileInfo) != 0) {
129 LOGE("fileInfo is error,%{public}s", strerror(errno));
130 return "";
131 }
132 if (S_ISREG(fileInfo.st_mode)) {
133 LOGD("uri's st_mode is reg");
134 size_t pos = uri.rfind("/");
135 return uri.substr(0, pos);
136 }
137 if (S_ISDIR(fileInfo.st_mode)) {
138 LOGD("uri's st_mode is dir");
139 return uri;
140 }
141 LOGD("uri's st_mode is not reg and dir");
142 return "";
143 }
144
IsRemoteUri()145 bool FileUri::IsRemoteUri()
146 {
147 size_t pos = uri_.ToString().find(NETWORK_PARA);
148 if (pos != string::npos && pos > 0 && pos < uri_.ToString().size() - NETWORK_PARA.size()) {
149 if (uri_.ToString().substr(pos + NETWORK_PARA.size()).find(BACKFLASH) == string::npos) {
150 return true;
151 }
152 }
153 return false;
154 }
155
CheckUriFormat(const std::string & uri)156 bool FileUri::CheckUriFormat(const std::string &uri)
157 {
158 if (uri.find(FILE_SCHEME_PREFIX) != 0) {
159 LOGE("URI is missing file://");
160 return false;
161 }
162 return true;
163 }
164
FileUri(const string & uriOrPath)165 FileUri::FileUri(const string &uriOrPath): uri_(
166 (uriOrPath.find(FILE_SCHEME_PREFIX) == 0) ? uriOrPath : CommonFunc::GetUriFromPath(uriOrPath)
167 )
168 {}
169 }
170 } // namespace AppFileService
171 } // namespace OHOS