Sync usage with man page.
[netbsd-mini2440.git] / external / bsd / libbind / dist / irs / getgrent_r.c
blob951880c900890995f41a009ae8d9221e2596967e
1 /* $NetBSD$ */
3 /*
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: getgrent_r.c,v 1.7 2005/04/27 04:56:24 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 getgrent_r_not_required = 0;
27 #else
28 #include <errno.h>
29 #include <string.h>
30 #include <stdio.h>
31 #include <sys/types.h>
32 #if (defined(POSIX_GETGRNAM_R) || defined(POSIX_GETGRGID_R)) && \
33 defined(_POSIX_PTHREAD_SEMANTICS)
34 /* turn off solaris remapping in <grp.h> */
35 #define _UNIX95
36 #undef _POSIX_PTHREAD_SEMANTICS
37 #include <grp.h>
38 #define _POSIX_PTHREAD_SEMANTICS 1
39 #else
40 #include <grp.h>
41 #endif
42 #include <sys/param.h>
43 #include <port_after.h>
45 #ifdef GROUP_R_RETURN
47 static int
48 copy_group(struct group *, struct group *, char *buf, int buflen);
50 /* POSIX 1003.1c */
51 #ifdef POSIX_GETGRNAM_R
52 int
53 __posix_getgrnam_r(const char *name, struct group *gptr,
54 char *buf, int buflen, struct group **result) {
55 #else
56 int
57 getgrnam_r(const char *name, struct group *gptr,
58 char *buf, size_t buflen, struct group **result) {
59 #endif
60 struct group *ge = getgrnam(name);
61 int res;
63 if (ge == NULL) {
64 *result = NULL;
65 return (0);
68 res = copy_group(ge, gptr, buf, buflen);
69 *result = res ? NULL : gptr;
70 return (res);
73 #ifdef POSIX_GETGRNAM_R
74 struct group *
75 getgrnam_r(const char *name, struct group *gptr,
76 char *buf, int buflen) {
77 struct group *ge = getgrnam(name);
78 int res;
80 if (ge == NULL)
81 return (NULL);
82 res = copy_group(ge, gptr, buf, buflen);
83 return (res ? NULL : gptr);
85 #endif /* POSIX_GETGRNAM_R */
87 /* POSIX 1003.1c */
88 #ifdef POSIX_GETGRGID_R
89 int
90 __posix_getgrgid_r(gid_t gid, struct group *gptr,
91 char *buf, int buflen, struct group **result) {
92 #else /* POSIX_GETGRGID_R */
93 int
94 getgrgid_r(gid_t gid, struct group *gptr,
95 char *buf, size_t buflen, struct group **result) {
96 #endif /* POSIX_GETGRGID_R */
97 struct group *ge = getgrgid(gid);
98 int res;
100 if (ge == NULL) {
101 *result = NULL;
102 return (0);
105 res = copy_group(ge, gptr, buf, buflen);
106 *result = res ? NULL : gptr;
107 return (res);
110 #ifdef POSIX_GETGRGID_R
111 struct group *
112 getgrgid_r(gid_t gid, struct group *gptr,
113 char *buf, int buflen) {
114 struct group *ge = getgrgid(gid);
115 int res;
117 if (ge == NULL)
118 return (NULL);
120 res = copy_group(ge, gptr, buf, buflen);
121 return (res ? NULL : gptr);
123 #endif
126 * These assume a single context is in operation per thread.
127 * If this is not the case we will need to call irs directly
128 * rather than through the base functions.
131 GROUP_R_RETURN
132 getgrent_r(struct group *gptr, GROUP_R_ARGS) {
133 struct group *ge = getgrent();
134 int res;
136 if (ge == NULL) {
137 return (GROUP_R_BAD);
140 res = copy_group(ge, gptr, buf, buflen);
141 return (res ? GROUP_R_BAD : GROUP_R_OK);
144 GROUP_R_SET_RETURN
145 setgrent_r(GROUP_R_ENT_ARGS) {
147 setgrent();
148 #ifdef GROUP_R_SET_RESULT
149 return (GROUP_R_SET_RESULT);
150 #endif
153 GROUP_R_END_RETURN
154 endgrent_r(GROUP_R_ENT_ARGS) {
156 endgrent();
157 GROUP_R_END_RESULT(GROUP_R_OK);
161 #if 0
162 /* XXX irs does not have a fgetgrent() */
163 GROUP_R_RETURN
164 fgetgrent_r(FILE *f, struct group *gptr, GROUP_R_ARGS) {
165 struct group *ge = fgetgrent(f);
166 int res;
168 if (ge == NULL)
169 return (GROUP_R_BAD);
171 res = copy_group(ge, gptr, buf, buflen);
172 return (res ? GROUP_R_BAD : GROUP_R_OK);
174 #endif
176 /* Private */
178 static int
179 copy_group(struct group *ge, struct group *gptr, char *buf, int buflen) {
180 char *cp;
181 int i, n;
182 int numptr, len;
184 /* Find out the amount of space required to store the answer. */
185 numptr = 1; /*%< NULL ptr */
186 len = (char *)ALIGN(buf) - buf;
187 for (i = 0; ge->gr_mem[i]; i++, numptr++) {
188 len += strlen(ge->gr_mem[i]) + 1;
190 len += strlen(ge->gr_name) + 1;
191 len += strlen(ge->gr_passwd) + 1;
192 len += numptr * sizeof(char*);
194 if (len > buflen) {
195 errno = ERANGE;
196 return (ERANGE);
199 /* copy group id */
200 gptr->gr_gid = ge->gr_gid;
202 cp = (char *)ALIGN(buf) + numptr * sizeof(char *);
204 /* copy official name */
205 n = strlen(ge->gr_name) + 1;
206 strcpy(cp, ge->gr_name);
207 gptr->gr_name = cp;
208 cp += n;
210 /* copy member list */
211 gptr->gr_mem = (char **)ALIGN(buf);
212 for (i = 0 ; ge->gr_mem[i]; i++) {
213 n = strlen(ge->gr_mem[i]) + 1;
214 strcpy(cp, ge->gr_mem[i]);
215 gptr->gr_mem[i] = cp;
216 cp += n;
218 gptr->gr_mem[i] = NULL;
220 /* copy password */
221 n = strlen(ge->gr_passwd) + 1;
222 strcpy(cp, ge->gr_passwd);
223 gptr->gr_passwd = cp;
224 cp += n;
226 return (0);
228 #else /* GROUP_R_RETURN */
229 static int getgrent_r_unknown_system = 0;
230 #endif /* GROUP_R_RETURN */
231 #endif /* !def(_REENTRANT) || !def(DO_PTHREADS) || !def(WANT_IRS_PW) */
232 /*! \file */