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 "common/napi_helper.cpp"
17 #include "common/native_common.h"
18 #include "napi/native_api.h"
19 #include <cerrno>
20 #include <cstring>
21 #include <ifaddrs.h>
22 #include <js_native_api_types.h>
23 #include <net/if.h>
24 #include <pwd.h>
25 #include <sys/inotify.h>
26 #include <unistd.h>
27 
28 #define ONEVAL 1
29 #define MINUSONE (-1)
30 #define MINUSTWO (-2)
31 #define MINUSTHR (-3)
32 #define MAX_NAMBER 1024
33 #define TEST_BUFFER_SIZE 256
34 #define PARAM_0 0
35 #define PARAM_1 1
36 #define PARAM_2 2
37 #define PARAM_UNNORMAL (-1)
38 #define ERRON_0 0
39 
Getpwent(napi_env env, napi_callback_info info)40 static napi_value Getpwent(napi_env env, napi_callback_info info)
41 {
42     struct passwd *p = getpwent();
43     napi_value result = nullptr;
44     if (p != nullptr) {
45         napi_create_int32(env, PARAM_0, &result);
46     } else {
47         napi_create_int32(env, PARAM_UNNORMAL, &result);
48     }
49     return result;
50 }
51 
Setpwent(napi_env env, napi_callback_info info)52 static napi_value Setpwent(napi_env env, napi_callback_info info)
53 {
54     errno = ERRON_0;
55     struct passwd *getval = getpwent();
56     napi_value result;
57     if (getval == nullptr) {
58         napi_create_int32(env, MINUSONE, &result);
59     }
60     if (errno != PARAM_0) {
61         napi_create_int32(env, errno, &result);
62     }
63     char buf[MAX_NAMBER] = {0};
64     strcpy(buf, getval->pw_name);
65     setpwent();
66     getval = getpwent();
67     if (getval == nullptr) {
68         napi_create_int32(env, MINUSTWO, &result);
69     }
70     if (strcmp(getval->pw_name, buf)) {
71         napi_create_int32(env, MINUSTHR, &result);
72     }
73     if (errno == PARAM_0) {
74         napi_create_int32(env, errno, &result);
75     } else {
76         napi_create_int32(env, MINUSONE, &result);
77     }
78     return result;
79 }
Getpwnam(napi_env env, napi_callback_info info)80 static napi_value Getpwnam(napi_env env, napi_callback_info info)
81 {
82     struct passwd *pw = nullptr;
83     errno = ERRON_0;
84     pw = getpwnam("root");
85     napi_value result = nullptr;
86     if (pw != nullptr) {
87         napi_create_int32(env, PARAM_0, &result);
88     } else {
89         napi_create_int32(env, PARAM_UNNORMAL, &result);
90     }
91     return result;
92 }
93 
EndPwEnt(napi_env env, napi_callback_info info)94 static napi_value EndPwEnt(napi_env env, napi_callback_info info)
95 {
96     errno = ERRON_0;
97     int backResult = PARAM_0;
98     endpwent();
99     napi_value result = nullptr;
100     napi_create_int32(env, backResult, &result);
101     return result;
102 }
103 
GetpwnamR(napi_env env, napi_callback_info info)104 static napi_value GetpwnamR(napi_env env, napi_callback_info info)
105 {
106     struct passwd pwd = {PARAM_0};
107     struct passwd *p = nullptr;
108     char buf[TEST_BUFFER_SIZE] = {PARAM_0};
109     memset(&buf, PARAM_0, sizeof buf);
110     getpwnam_r("root", &pwd, buf, TEST_BUFFER_SIZE, &p);
111     napi_value result;
112     if (p != nullptr) {
113         napi_create_int32(env, PARAM_0, &result);
114     } else {
115         napi_create_int32(env, PARAM_UNNORMAL, &result);
116     }
117     return result;
118 }
119 
GetpwuidR(napi_env env, napi_callback_info info)120 static napi_value GetpwuidR(napi_env env, napi_callback_info info)
121 {
122     struct passwd pw = {PARAM_0};
123     struct passwd *res = nullptr;
124     char buf[TEST_BUFFER_SIZE];
125 
126     int ret = getpwuid_r(getuid(), &pw, buf, sizeof(buf), &res);
127     napi_value result;
128     if (ret != MINUSONE) {
129         napi_create_int32(env, PARAM_0, &result);
130     } else {
131         napi_create_int32(env, PARAM_UNNORMAL, &result);
132     }
133     return result;
134 }
135 
Getpwuid(napi_env env, napi_callback_info info)136 static napi_value Getpwuid(napi_env env, napi_callback_info info)
137 {
138     struct passwd *ret = nullptr;
139     errno = ERRON_0;
140     ret = getpwuid(getuid());
141     napi_value result = nullptr;
142     if (ret != nullptr) {
143         napi_create_int32(env, PARAM_0, &result);
144     } else {
145         if (errno == ERRON_0) {
146             napi_create_int32(env, PARAM_0, &result);
147         } else {
148             napi_create_int32(env, PARAM_UNNORMAL, &result);
149         }
150     }
151     return result;
152 }
153 
154 EXTERN_C_START
Init(napi_env env, napi_value exports)155 static napi_value Init(napi_env env, napi_value exports)
156 {
157     napi_property_descriptor desc[] = {
158         {"setpwent", nullptr, Setpwent, nullptr, nullptr, nullptr, napi_default, nullptr},
159         {"endpwent", nullptr, EndPwEnt, nullptr, nullptr, nullptr, napi_default, nullptr},
160         {"getpwent", nullptr, Getpwent, nullptr, nullptr, nullptr, napi_default, nullptr},
161         {"getpwnam", nullptr, Getpwnam, nullptr, nullptr, nullptr, napi_default, nullptr},
162         {"getpwnamR", nullptr, GetpwnamR, nullptr, nullptr, nullptr, napi_default, nullptr},
163         {"getpwuid", nullptr, Getpwuid, nullptr, nullptr, nullptr, napi_default, nullptr},
164         {"getpwuidR", nullptr, GetpwuidR, nullptr, nullptr, nullptr, napi_default, nullptr},
165     };
166     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
167     return exports;
168 }
169 
170 EXTERN_C_END
171 
172 static napi_module demoModule = {
173     .nm_version = 1,
174     .nm_flags = 0,
175     .nm_filename = nullptr,
176     .nm_register_func = Init,
177     .nm_modname = "pwd",
178     .nm_priv = ((void *)0),
179     .reserved = {0},
180 };
181 
RegisterModule(void)182 extern "C" __attribute__((constructor)) void RegisterModule(void) { napi_module_register(&demoModule); }
183