[RFC] bb_getgrouplist implementation
Tito
farmatito at tiscali.it
Mon Sep 15 21:23:19 UTC 2008
Hi to all,
i'm thinking about a getgrouplist implementation for busybox.
To use for example in id, but maybe also other applets could
use it. So far I have two different versions based on the same
algoritm but I'm unable to decide which is the right way to go
or if I'm on a dead end.
Hints, critics comments are welcome..........
Ciao,
Tito
gid_t *bb_getgrouplist_malloc(uid_t uid, int *ngrp)
Usage example:
int ngrp = 0;
gid_t grplist * = bb_getgrouplist_malloc(uid, &ngrp);
for (int i = 0; i < ngrp; i++) {
printf("%d ", grplist[i]);
}
free(grp_list);
llist_t *bb_getgrouplist_malloc(uid_t uid)
Usage example:
list_t * grplist = bb_getgrouplist_malloc(uid);
while (grplist) {
gid_t *gid = llist_pop(&grplist);
printf("%d ", *gid);
free(gid);
}
free(grplist);
----------------------------------------------------------------------------------------------------------
gid_t *bb_getgrouplist_malloc(uid_t uid, int *ngrp)
{
FILE *group_file;
struct passwd *pwd;
struct group *grp;
gid_t *group_list = NULL;
/* Counter for mallocing memory */
int n = 1;
char *line;
/* Default for error conditions */
*ngrp = 0;
pwd = getpwuid(uid);
group_file = fopen_or_warn(bb_path_group_file, "r");
if (group_file && pwd) {
/* Add the already known gid to the list */
group_list = (gid_t *) xmalloc(sizeof(gid_t));
memcpy(&group_list[0], &(pwd->pw_gid), sizeof(gid_t));
*ngrp = 1;
/* Walk through /etc/group */
while ((line = xmalloc_fgetline(group_file)) != NULL) {
/* Get the group name token and obtain a struct group */
/* rather than try to parse the whole line */
/* This should not fail unless group is removed after */
/* we read the line. We can ignore it */
grp = getgrnam(strtok(line, ":"));
/* Check if we have this one already */
if (grp && grp->gr_gid != pwd->pw_gid) {
/* Walk through the group members */
while (*(grp->gr_mem)) {
/* Are we a member of this group? */
if (!strcmp(pwd->pw_name, *(grp->gr_mem))) {
/* Found, realloc the needed space */
group_list = xrealloc(group_list, ++n * sizeof(gid_t));
/* Copy the gid to the list */
memcpy(&group_list[n - 1], &(grp->gr_gid), sizeof(gid_t));
/* No need to continue the search */
break;
}
(grp->gr_mem)++;
}
}
free(line);
}
*ngrp = n;
/* Clean up */
fclose(group_file);
}
return group_list;
}
llist_t *bb_getgrouplist_malloc(uid_t uid)
{
FILE *group_file;
struct passwd *pwd;
struct group *grp;
llist_t *group_list = NULL;
char *line;
pwd = getpwuid(uid);
group_file = fopen_or_warn(bb_path_group_file, "r");
if (group_file && pwd) {
/* Add the already known gid to the list */
llist_add_to_end(&group_list, memcpy(xmalloc(sizeof(gid_t)), &(pwd->pw_gid), sizeof(gid_t)));
/* Walk through /etc/group */
while ((line = xmalloc_fgetline(group_file)) != NULL) {
/* Get the group name token and obtain a struct group */
/* rather than try to parse the whole line */
/* This should not fail unless group is removed after */
/* we read the line. We can ignore it */
grp = getgrnam(strtok(line, ":"));
/* Check if we have this one already */
if (grp && grp->gr_gid != pwd->pw_gid) {
/* Walk through the group members */
while (*(grp->gr_mem)) {
/* Are we a member of this group? */
if (!strcmp(pwd->pw_name, *(grp->gr_mem))) {
/* Found, add the gid to the list */
llist_add_to_end(&group_list, memcpy(xmalloc(sizeof(gid_t)), &(grp->gr_gid), sizeof(gid_t)));
/* No need to continue the search, cannot be list member twice */
break;
}
/* Next group member */
(grp->gr_mem)++;
}
}
/* Clean up */
free(line);
}
/* Clean up */
fclose(group_file);
}
/* return list or NULL on error */
return group_list;
}
More information about the busybox
mailing list