2 * <pwd.h> wrapper functions.
5 * Jonathan Pryor (jonpryor@vt.edu)
7 * Copyright (C) 2004 Jonathan Pryor
20 struct Mono_Posix_Syscall__Passwd {
21 /* string */ char *pw_name;
22 /* string */ char *pw_passwd;
23 /* uid_t */ mph_uid_t pw_uid;
24 /* gid_t */ mph_gid_t pw_gid;
25 /* string */ char *pw_gecos;
26 /* string */ char *pw_dir;
27 /* string */ char *pw_shell;
28 /* string */ char *_pw_buf_;
32 * Copy the native `passwd' structure to it's managed representation.
34 * To minimize separate mallocs, all the strings are allocated within the same
35 * memory block (stored in _pw_buf_).
38 copy_passwd (struct Mono_Posix_Syscall__Passwd *to, struct passwd *from)
40 enum {PW_NAME = 0, PW_PASSWD, PW_GECOS, PW_DIR, PW_SHELL, PW_LAST};
41 size_t buflen, len[PW_LAST];
42 /* bool */ unsigned char copy[PW_LAST] = {0};
43 const char *source[PW_LAST];
48 to->pw_uid = from->pw_uid;
49 to->pw_gid = from->pw_gid;
58 source[PW_NAME] = from->pw_name;
59 source[PW_PASSWD] = from->pw_passwd;
60 source[PW_GECOS] = from->pw_gecos;
61 source[PW_DIR] = from->pw_dir;
62 source[PW_SHELL] = from->pw_shell;
64 dest[PW_NAME] = &to->pw_name;
65 dest[PW_PASSWD] = &to->pw_passwd;
66 dest[PW_GECOS] = &to->pw_gecos;
67 dest[PW_DIR] = &to->pw_dir;
68 dest[PW_SHELL] = &to->pw_shell;
72 /* over-rigorous checking for integer overflow */
73 for (i = 0; i != PW_LAST; ++i) {
74 len[i] = strlen (source[i]);
75 if (len[i] < INT_MAX - buflen) {
81 cur = to->_pw_buf_ = (char*) malloc (buflen);
86 for (i = 0; i != PW_LAST; ++i) {
88 *dest[i] = strcpy (cur, source[i]);
97 Mono_Posix_Syscall_getpwnam (const char *name, struct Mono_Posix_Syscall__Passwd *pwbuf)
106 pw = getpwnam (name);
110 if (copy_passwd (pwbuf, pw) == -1) {
118 Mono_Posix_Syscall_getpwuid (mph_uid_t uid, struct Mono_Posix_Syscall__Passwd *pwbuf)
133 if (copy_passwd (pwbuf, pw) == -1) {
141 Mono_Posix_Syscall_getpwnam_r (const char *name,
142 struct Mono_Posix_Syscall__Passwd *pwbuf,
143 struct passwd **pwbufp)
148 struct passwd _pwbuf;
159 buf2 = realloc (buf, buflen *= 2);
166 } while ((r = getpwnam_r (name, &_pwbuf, buf, buflen, pwbufp)) &&
169 if (r == 0 && copy_passwd (pwbuf, &_pwbuf) == -1)
177 Mono_Posix_Syscall_getpwuid_r (mph_uid_t uid,
178 struct Mono_Posix_Syscall__Passwd *pwbuf,
179 struct passwd **pwbufp)
184 struct passwd _pwbuf;
195 buf2 = realloc (buf, buflen *= 2);
202 } while ((r = getpwuid_r (uid, &_pwbuf, buf, buflen, pwbufp)) &&
205 if (r == 0 && copy_passwd (pwbuf, &_pwbuf) == -1)
213 Mono_Posix_Syscall_getpwent (struct Mono_Posix_Syscall__Passwd *pwbuf)
226 if (copy_passwd (pwbuf, pw) == -1) {
233 #ifdef HAVE_FGETPWENT
235 Mono_Posix_Syscall_fgetpwent (FILE *stream, struct Mono_Posix_Syscall__Passwd *pwbuf)
244 pw = fgetpwent (stream);
248 if (copy_passwd (pwbuf, pw) == -1) {
254 #endif /* ndef FGETPWENT */