1 | // This is an open source non-commercial project. Dear PVS-Studio, please check |
2 | // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com |
3 | |
4 | // users.c -- operating system user information |
5 | |
6 | #include <uv.h> |
7 | |
8 | #include "nvim/ascii.h" |
9 | #include "nvim/os/os.h" |
10 | #include "nvim/garray.h" |
11 | #include "nvim/memory.h" |
12 | #include "nvim/strings.h" |
13 | #ifdef HAVE_PWD_H |
14 | # include <pwd.h> |
15 | #endif |
16 | |
17 | // Initialize users garray and fill it with os usernames. |
18 | // Return Ok for success, FAIL for failure. |
19 | int os_get_usernames(garray_T *users) |
20 | { |
21 | if (users == NULL) { |
22 | return FAIL; |
23 | } |
24 | ga_init(users, sizeof(char *), 20); |
25 | |
26 | # if defined(HAVE_GETPWENT) && defined(HAVE_PWD_H) |
27 | struct passwd *pw; |
28 | |
29 | setpwent(); |
30 | while ((pw = getpwent()) != NULL) { |
31 | // pw->pw_name shouldn't be NULL but just in case... |
32 | if (pw->pw_name != NULL) { |
33 | GA_APPEND(char *, users, xstrdup(pw->pw_name)); |
34 | } |
35 | } |
36 | endpwent(); |
37 | # endif |
38 | |
39 | return OK; |
40 | } |
41 | |
42 | // Insert user name in s[len]. |
43 | // Return OK if a name found. |
44 | int os_get_user_name(char *s, size_t len) |
45 | { |
46 | #ifdef UNIX |
47 | return os_get_uname((uv_uid_t)getuid(), s, len); |
48 | #else |
49 | // TODO(equalsraf): Windows GetUserName() |
50 | return os_get_uname((uv_uid_t)0, s, len); |
51 | #endif |
52 | } |
53 | |
54 | // Insert user name for "uid" in s[len]. |
55 | // Return OK if a name found. |
56 | // If the name is not found, write the uid into s[len] and return FAIL. |
57 | int os_get_uname(uv_uid_t uid, char *s, size_t len) |
58 | { |
59 | #if defined(HAVE_PWD_H) && defined(HAVE_GETPWUID) |
60 | struct passwd *pw; |
61 | |
62 | if ((pw = getpwuid(uid)) != NULL // NOLINT(runtime/threadsafe_fn) |
63 | && pw->pw_name != NULL && *(pw->pw_name) != NUL) { |
64 | STRLCPY(s, pw->pw_name, len); |
65 | return OK; |
66 | } |
67 | #endif |
68 | snprintf(s, len, "%d" , (int)uid); |
69 | return FAIL; // a number is not a name |
70 | } |
71 | |
72 | // Returns the user directory for the given username. |
73 | // The caller has to free() the returned string. |
74 | // If the username is not found, NULL is returned. |
75 | char *os_get_user_directory(const char *name) |
76 | { |
77 | #if defined(HAVE_GETPWNAM) && defined(HAVE_PWD_H) |
78 | if (name == NULL || *name == NUL) { |
79 | return NULL; |
80 | } |
81 | struct passwd *pw = getpwnam(name); // NOLINT(runtime/threadsafe_fn) |
82 | if (pw != NULL) { |
83 | // save the string from the static passwd entry into malloced memory |
84 | return xstrdup(pw->pw_dir); |
85 | } |
86 | #endif |
87 | return NULL; |
88 | } |
89 | |
90 | |