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) {
140 #ifdef HAVE_GETPWNAM_R
142 Mono_Posix_Syscall_getpwnam_r (const char *name,
143 struct Mono_Posix_Syscall__Passwd *pwbuf,
144 struct passwd **pwbufp)
149 struct passwd _pwbuf;
160 buf2 = realloc (buf, buflen *= 2);
167 } while ((r = getpwnam_r (name, &_pwbuf, buf, buflen, pwbufp)) &&
170 if (r == 0 && copy_passwd (pwbuf, &_pwbuf) == -1)
176 #endif /* ndef HAVE_GETPWNAM_R */
178 #ifdef HAVE_GETPWUID_R
180 Mono_Posix_Syscall_getpwuid_r (mph_uid_t uid,
181 struct Mono_Posix_Syscall__Passwd *pwbuf,
182 struct passwd **pwbufp)
187 struct passwd _pwbuf;
198 buf2 = realloc (buf, buflen *= 2);
205 } while ((r = getpwuid_r (uid, &_pwbuf, buf, buflen, pwbufp)) &&
208 if (r == 0 && copy_passwd (pwbuf, &_pwbuf) == -1)
214 #endif /* ndef HAVE_GETPWUID_R */
217 Mono_Posix_Syscall_getpwent (struct Mono_Posix_Syscall__Passwd *pwbuf)
230 if (copy_passwd (pwbuf, pw) == -1) {
237 #ifdef HAVE_FGETPWENT
239 Mono_Posix_Syscall_fgetpwent (FILE *stream, struct Mono_Posix_Syscall__Passwd *pwbuf)
248 pw = fgetpwent (stream);
252 if (copy_passwd (pwbuf, pw) == -1) {
258 #endif /* ndef HAVE_FGETPWENT */