1 /*
2 * Copyright (c) 2022 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 "stat_entity.h"
17 #include "stat_n_exporter.h"
18
19 #include <cstdio>
20 #include <cstdlib>
21 #include <cstring>
22 #include <memory>
23 #include <securec.h>
24
25 #include "filemgmt_libhilog.h"
26
27 namespace OHOS::FileManagement::ModuleFileIO {
28 using namespace std;
29 using namespace OHOS::FileManagement::LibN;
30
CheckStatMode(napi_env env,napi_callback_info info,mode_t mode)31 static napi_value CheckStatMode(napi_env env, napi_callback_info info, mode_t mode)
32 {
33 NFuncArg funcArg(env, info);
34 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
35 HILOGE("Number of arguments unmatched");
36 NError(EINVAL).ThrowErr(env);
37 return nullptr;
38 }
39
40 auto statEntity = NClass::GetEntityOf<StatEntity>(env, funcArg.GetThisVar());
41 if (!statEntity) {
42 HILOGE("Failed to get stat entity");
43 return nullptr;
44 }
45
46 bool check = (statEntity->stat_.st_mode & S_IFMT) == mode;
47 return NVal::CreateBool(env, check).val_;
48 }
49
IsBlockDevice(napi_env env,napi_callback_info info)50 napi_value StatNExporter::IsBlockDevice(napi_env env, napi_callback_info info)
51 {
52 return CheckStatMode(env, info, S_IFBLK);
53 }
54
IsCharacterDevice(napi_env env,napi_callback_info info)55 napi_value StatNExporter::IsCharacterDevice(napi_env env, napi_callback_info info)
56 {
57 return CheckStatMode(env, info, S_IFCHR);
58 }
59
IsDirectory(napi_env env,napi_callback_info info)60 napi_value StatNExporter::IsDirectory(napi_env env, napi_callback_info info)
61 {
62 return CheckStatMode(env, info, S_IFDIR);
63 }
64
IsFIFO(napi_env env,napi_callback_info info)65 napi_value StatNExporter::IsFIFO(napi_env env, napi_callback_info info)
66 {
67 return CheckStatMode(env, info, S_IFIFO);
68 }
69
IsFile(napi_env env,napi_callback_info info)70 napi_value StatNExporter::IsFile(napi_env env, napi_callback_info info)
71 {
72 return CheckStatMode(env, info, S_IFREG);
73 }
74
IsSocket(napi_env env,napi_callback_info info)75 napi_value StatNExporter::IsSocket(napi_env env, napi_callback_info info)
76 {
77 return CheckStatMode(env, info, S_IFSOCK);
78 }
79
IsSymbolicLink(napi_env env,napi_callback_info info)80 napi_value StatNExporter::IsSymbolicLink(napi_env env, napi_callback_info info)
81 {
82 return CheckStatMode(env, info, S_IFLNK);
83 }
84
GetIno(napi_env env,napi_callback_info info)85 napi_value StatNExporter::GetIno(napi_env env, napi_callback_info info)
86 {
87 NFuncArg funcArg(env, info);
88 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
89 HILOGE("Number of arguments unmatched");
90 NError(EINVAL).ThrowErr(env);
91 return nullptr;
92 }
93
94 auto statEntity = NClass::GetEntityOf<StatEntity>(env, funcArg.GetThisVar());
95 if (!statEntity) {
96 HILOGE("Failed to get stat entity");
97 return nullptr;
98 }
99
100 return NVal::CreateBigInt64(env, statEntity->stat_.st_ino).val_;
101 }
102
GetMode(napi_env env,napi_callback_info info)103 napi_value StatNExporter::GetMode(napi_env env, napi_callback_info info)
104 {
105 NFuncArg funcArg(env, info);
106 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
107 HILOGE("Number of arguments unmatched");
108 NError(EINVAL).ThrowErr(env);
109 return nullptr;
110 }
111
112 auto statEntity = NClass::GetEntityOf<StatEntity>(env, funcArg.GetThisVar());
113 if (!statEntity) {
114 HILOGE("Failed to get stat entity");
115 return nullptr;
116 }
117
118 return NVal::CreateInt64(env, statEntity->stat_.st_mode & S_PERMISSION).val_;
119 }
120
GetUid(napi_env env,napi_callback_info info)121 napi_value StatNExporter::GetUid(napi_env env, napi_callback_info info)
122 {
123 NFuncArg funcArg(env, info);
124 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
125 HILOGE("Number of arguments unmatched");
126 NError(EINVAL).ThrowErr(env);
127 return nullptr;
128 }
129
130 auto statEntity = NClass::GetEntityOf<StatEntity>(env, funcArg.GetThisVar());
131 if (!statEntity) {
132 HILOGE("Failed to get stat entity");
133 return nullptr;
134 }
135
136 return NVal::CreateInt64(env, statEntity->stat_.st_uid).val_;
137 }
138
GetGid(napi_env env,napi_callback_info info)139 napi_value StatNExporter::GetGid(napi_env env, napi_callback_info info)
140 {
141 NFuncArg funcArg(env, info);
142 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
143 HILOGE("Number of arguments unmatched");
144 NError(EINVAL).ThrowErr(env);
145 return nullptr;
146 }
147
148 auto statEntity = NClass::GetEntityOf<StatEntity>(env, funcArg.GetThisVar());
149 if (!statEntity) {
150 HILOGE("Failed to get stat entity");
151 return nullptr;
152 }
153
154 return NVal::CreateInt64(env, statEntity->stat_.st_gid).val_;
155 }
156
GetSize(napi_env env,napi_callback_info info)157 napi_value StatNExporter::GetSize(napi_env env, napi_callback_info info)
158 {
159 NFuncArg funcArg(env, info);
160 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
161 HILOGE("Number of arguments unmatched");
162 NError(EINVAL).ThrowErr(env);
163 return nullptr;
164 }
165
166 auto statEntity = NClass::GetEntityOf<StatEntity>(env, funcArg.GetThisVar());
167 if (!statEntity) {
168 HILOGE("Failed to get stat entity");
169 return nullptr;
170 }
171
172 return NVal::CreateInt64(env, statEntity->stat_.st_size).val_;
173 }
174
GetAtime(napi_env env,napi_callback_info info)175 napi_value StatNExporter::GetAtime(napi_env env, napi_callback_info info)
176 {
177 NFuncArg funcArg(env, info);
178 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
179 HILOGE("Number of arguments unmatched");
180 NError(EINVAL).ThrowErr(env);
181 return nullptr;
182 }
183
184 auto statEntity = NClass::GetEntityOf<StatEntity>(env, funcArg.GetThisVar());
185 if (!statEntity) {
186 HILOGE("Failed to get stat entity");
187 return nullptr;
188 }
189
190 return NVal::CreateInt64(env, statEntity->stat_.st_atim.tv_sec).val_;
191 }
192
GetMtime(napi_env env,napi_callback_info info)193 napi_value StatNExporter::GetMtime(napi_env env, napi_callback_info info)
194 {
195 NFuncArg funcArg(env, info);
196 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
197 HILOGE("Number of arguments unmatched");
198 NError(EINVAL).ThrowErr(env);
199 return nullptr;
200 }
201
202 auto statEntity = NClass::GetEntityOf<StatEntity>(env, funcArg.GetThisVar());
203 if (!statEntity) {
204 HILOGE("Failed to get stat entity");
205 return nullptr;
206 }
207
208 return NVal::CreateInt64(env, statEntity->stat_.st_mtim.tv_sec).val_;
209 }
210
GetCtime(napi_env env,napi_callback_info info)211 napi_value StatNExporter::GetCtime(napi_env env, napi_callback_info info)
212 {
213 NFuncArg funcArg(env, info);
214 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
215 HILOGE("Number of arguments unmatched");
216 NError(EINVAL).ThrowErr(env);
217 return nullptr;
218 }
219
220 auto statEntity = NClass::GetEntityOf<StatEntity>(env, funcArg.GetThisVar());
221 if (!statEntity) {
222 HILOGE("Failed to get stat entity");
223 return nullptr;
224 }
225
226 return NVal::CreateInt64(env, statEntity->stat_.st_ctim.tv_sec).val_;
227 }
228
Constructor(napi_env env,napi_callback_info info)229 napi_value StatNExporter::Constructor(napi_env env, napi_callback_info info)
230 {
231 NFuncArg funcArg(env, info);
232 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
233 HILOGE("Number of arguments unmatched");
234 NError(EINVAL).ThrowErr(env);
235 return nullptr;
236 }
237
238 unique_ptr<StatEntity> statEntity = make_unique<StatEntity>();
239 if (!NClass::SetEntityFor<StatEntity>(env, funcArg.GetThisVar(), move(statEntity))) {
240 HILOGE("Failed to set stat entity");
241 NError(EINVAL).ThrowErr(env);
242 return nullptr;
243 }
244 return funcArg.GetThisVar();
245 }
246
Export()247 bool StatNExporter::Export()
248 {
249 vector<napi_property_descriptor> props = {
250 NVal::DeclareNapiFunction("isBlockDevice", IsBlockDevice),
251 NVal::DeclareNapiFunction("isCharacterDevice", IsCharacterDevice),
252 NVal::DeclareNapiFunction("isDirectory", IsDirectory),
253 NVal::DeclareNapiFunction("isFIFO", IsFIFO),
254 NVal::DeclareNapiFunction("isFile", IsFile),
255 NVal::DeclareNapiFunction("isSocket", IsSocket),
256 NVal::DeclareNapiFunction("isSymbolicLink", IsSymbolicLink),
257
258 NVal::DeclareNapiGetter("ino", GetIno),
259 NVal::DeclareNapiGetter("mode", GetMode),
260 NVal::DeclareNapiGetter("uid", GetUid),
261 NVal::DeclareNapiGetter("gid", GetGid),
262 NVal::DeclareNapiGetter("size", GetSize),
263 NVal::DeclareNapiGetter("atime", GetAtime),
264 NVal::DeclareNapiGetter("mtime", GetMtime),
265 NVal::DeclareNapiGetter("ctime", GetCtime),
266 };
267
268 string className = GetClassName();
269 bool succ = false;
270 napi_value classValue = nullptr;
271 tie(succ, classValue) = NClass::DefineClass(exports_.env_, className, StatNExporter::Constructor,
272 std::move(props));
273 if (!succ) {
274 HILOGE("Failed to define class");
275 NError(EIO).ThrowErr(exports_.env_);
276 return false;
277 }
278 succ = NClass::SaveClass(exports_.env_, className, classValue);
279 if (!succ) {
280 HILOGE("Failed to save class");
281 NError(EIO).ThrowErr(exports_.env_);
282 return false;
283 }
284
285 return exports_.AddProp(className, classValue);
286 }
287
GetClassName()288 string StatNExporter::GetClassName()
289 {
290 return StatNExporter::className_;
291 }
292
StatNExporter(napi_env env,napi_value exports)293 StatNExporter::StatNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {}
294
~StatNExporter()295 StatNExporter::~StatNExporter() {}
296 } // namespace OHOS::FileManagement::ModuleFileIO