Add declaretion of addinitgroups and readdinitgroups.
[glibc.git] / grp / compat-initgroups.c
blob585c4aecbbcc600aa80fd43da4caebbc21b92c7c
1 /* Prototype for the setgrent functions we use here. */
2 typedef enum nss_status (*set_function) (void);
4 /* Prototype for the endgrent functions we use here. */
5 typedef enum nss_status (*end_function) (void);
7 /* Prototype for the setgrent functions we use here. */
8 typedef enum nss_status (*get_function) (struct group *, char *,
9 size_t, int *);
11 static enum nss_status
12 compat_call (service_user *nip, const char *user, gid_t group, long int *start,
13 long int *size, gid_t **groupsp, long int limit, int *errnop)
15 struct group grpbuf;
16 size_t buflen = __sysconf (_SC_GETGR_R_SIZE_MAX);
17 char *tmpbuf;
18 enum nss_status status;
19 set_function setgrent_fct;
20 get_function getgrent_fct;
21 end_function endgrent_fct;
22 gid_t *groups = *groupsp;
24 getgrent_fct = __nss_lookup_function (nip, "getgrent_r");
25 if (getgrent_fct == NULL)
26 return NSS_STATUS_UNAVAIL;
28 setgrent_fct = __nss_lookup_function (nip, "setgrent");
29 if (setgrent_fct)
31 status = DL_CALL_FCT (setgrent_fct, ());
32 if (status != NSS_STATUS_SUCCESS)
33 return status;
36 endgrent_fct = __nss_lookup_function (nip, "endgrent");
38 tmpbuf = __alloca (buflen);
42 while ((status = DL_CALL_FCT (getgrent_fct,
43 (&grpbuf, tmpbuf, buflen, errnop)),
44 status == NSS_STATUS_TRYAGAIN)
45 && *errnop == ERANGE)
47 buflen *= 2;
48 tmpbuf = __alloca (buflen);
51 if (status != NSS_STATUS_SUCCESS)
52 goto done;
54 if (grpbuf.gr_gid != group)
56 char **m;
58 for (m = grpbuf.gr_mem; *m != NULL; ++m)
59 if (strcmp (*m, user) == 0)
61 /* Matches user. Insert this group. */
62 if (__builtin_expect (*start == *size, 0))
64 /* Need a bigger buffer. */
65 gid_t *newgroups;
66 long int newsize;
68 if (limit > 0 && *size == limit)
69 /* We reached the maximum. */
70 goto done;
72 if (limit <= 0)
73 newsize = 2 * *size;
74 else
75 newsize = MIN (limit, 2 * *size);
77 newgroups = realloc (groups, newsize * sizeof (*groups));
78 if (newgroups == NULL)
79 goto done;
80 *groupsp = groups = newgroups;
81 *size = newsize;
84 groups[*start] = grpbuf.gr_gid;
85 *start += 1;
87 break;
91 while (status == NSS_STATUS_SUCCESS);
93 done:
94 if (endgrent_fct)
95 DL_CALL_FCT (endgrent_fct, ());
97 return NSS_STATUS_SUCCESS;