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