4 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (c) 1998-1999 by Internet Software Consortium.
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #if defined(LIBC_SCCS) && !defined(lint)
21 static const char rcsid
[] = "Id: getpwent_r.c,v 1.8 2005/04/27 04:56:26 sra Exp";
22 #endif /* LIBC_SCCS and not lint */
24 #include <port_before.h>
25 #if !defined(_REENTRANT) || !defined(DO_PTHREADS) || !defined(WANT_IRS_PW)
26 static int getpwent_r_not_required
= 0;
31 #include <sys/types.h>
32 #if (defined(POSIX_GETPWNAM_R) || defined(POSIX_GETPWUID_R))
33 #if defined(_POSIX_PTHREAD_SEMANTICS)
34 /* turn off solaris remapping in <grp.h> */
35 #undef _POSIX_PTHREAD_SEMANTICS
37 #define _POSIX_PTHREAD_SEMANTICS 1
45 #include <port_after.h>
50 copy_passwd(struct passwd
*, struct passwd
*, char *buf
, int buflen
);
53 #ifdef POSIX_GETPWNAM_R
55 __posix_getpwnam_r(const char *login
, struct passwd
*pwptr
,
56 char *buf
, size_t buflen
, struct passwd
**result
) {
59 getpwnam_r(const char *login
, struct passwd
*pwptr
,
60 char *buf
, size_t buflen
, struct passwd
**result
) {
62 struct passwd
*pw
= getpwnam(login
);
70 res
= copy_passwd(pw
, pwptr
, buf
, buflen
);
71 *result
= res
? NULL
: pwptr
;
75 #ifdef POSIX_GETPWNAM_R
77 getpwnam_r(const char *login
, struct passwd
*pwptr
, char *buf
, int buflen
) {
78 struct passwd
*pw
= getpwnam(login
);
84 res
= copy_passwd(pw
, pwptr
, buf
, buflen
);
85 return (res
? NULL
: pwptr
);
90 #ifdef POSIX_GETPWUID_R
92 __posix_getpwuid_r(uid_t uid
, struct passwd
*pwptr
,
93 char *buf
, int buflen
, struct passwd
**result
) {
96 getpwuid_r(uid_t uid
, struct passwd
*pwptr
,
97 char *buf
, size_t buflen
, struct passwd
**result
) {
99 struct passwd
*pw
= getpwuid(uid
);
107 res
= copy_passwd(pw
, pwptr
, buf
, buflen
);
108 *result
= res
? NULL
: pwptr
;
112 #ifdef POSIX_GETPWUID_R
114 getpwuid_r(uid_t uid
, struct passwd
*pwptr
, char *buf
, int buflen
) {
115 struct passwd
*pw
= getpwuid(uid
);
121 res
= copy_passwd(pw
, pwptr
, buf
, buflen
);
122 return (res
? NULL
: pwptr
);
127 * These assume a single context is in operation per thread.
128 * If this is not the case we will need to call irs directly
129 * rather than through the base functions.
133 getpwent_r(struct passwd
*pwptr
, PASS_R_ARGS
) {
134 struct passwd
*pw
= getpwent();
140 res
= copy_passwd(pw
, pwptr
, buf
, buflen
);
141 return (res
? PASS_R_BAD
: PASS_R_OK
);
145 #ifdef PASS_R_ENT_ARGS
146 setpassent_r(int stayopen
, PASS_R_ENT_ARGS
)
148 setpassent_r(int stayopen
)
152 setpassent(stayopen
);
153 #ifdef PASS_R_SET_RESULT
154 return (PASS_R_SET_RESULT
);
159 #ifdef PASS_R_ENT_ARGS
160 setpwent_r(PASS_R_ENT_ARGS
)
167 #ifdef PASS_R_SET_RESULT
168 return (PASS_R_SET_RESULT
);
173 #ifdef PASS_R_ENT_ARGS
174 endpwent_r(PASS_R_ENT_ARGS
)
181 PASS_R_END_RESULT(PASS_R_OK
);
187 fgetpwent_r(FILE *f
, struct passwd
*pwptr
, PASS_R_COPY_ARGS
) {
188 struct passwd
*pw
= fgetpwent(f
);
194 res
= copy_passwd(pw
, pwptr
, PASS_R_COPY
);
195 return (res
? PASS_R_BAD
: PASS_R_OK
);
202 copy_passwd(struct passwd
*pw
, struct passwd
*pwptr
, char *buf
, int buflen
) {
207 /* Find out the amount of space required to store the answer. */
208 len
= strlen(pw
->pw_name
) + 1;
209 len
+= strlen(pw
->pw_passwd
) + 1;
211 len
+= strlen(pw
->pw_class
) + 1;
213 len
+= strlen(pw
->pw_gecos
) + 1;
214 len
+= strlen(pw
->pw_dir
) + 1;
215 len
+= strlen(pw
->pw_shell
) + 1;
222 /* copy fixed atomic values*/
223 pwptr
->pw_uid
= pw
->pw_uid
;
224 pwptr
->pw_gid
= pw
->pw_gid
;
225 #ifdef HAVE_PW_CHANGE
226 pwptr
->pw_change
= pw
->pw_change
;
228 #ifdef HAVE_PW_EXPIRE
229 pwptr
->pw_expire
= pw
->pw_expire
;
234 /* copy official name */
235 n
= strlen(pw
->pw_name
) + 1;
236 strcpy(cp
, pw
->pw_name
);
241 n
= strlen(pw
->pw_passwd
) + 1;
242 strcpy(cp
, pw
->pw_passwd
);
243 pwptr
->pw_passwd
= cp
;
248 n
= strlen(pw
->pw_class
) + 1;
249 strcpy(cp
, pw
->pw_class
);
250 pwptr
->pw_class
= cp
;
255 n
= strlen(pw
->pw_gecos
) + 1;
256 strcpy(cp
, pw
->pw_gecos
);
257 pwptr
->pw_gecos
= cp
;
261 n
= strlen(pw
->pw_dir
) + 1;
262 strcpy(cp
, pw
->pw_dir
);
266 /* copy login shell */
267 n
= strlen(pw
->pw_shell
) + 1;
268 strcpy(cp
, pw
->pw_shell
);
269 pwptr
->pw_shell
= cp
;
274 #else /* PASS_R_RETURN */
275 static int getpwent_r_unknown_system
= 0;
276 #endif /* PASS_R_RETURN */
277 #endif /* !def(_REENTRANT) || !def(DO_PTHREADS) || !def(WANT_IRS_PW) */