Skip to content

Commit b73c576

Browse files
committed
Imlement getgrgid_r/getgrnam_r
Contributed by medmed
1 parent 9a35264 commit b73c576

File tree

6 files changed

+250
-3
lines changed

6 files changed

+250
-3
lines changed

include/grp.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,12 @@ __EXTERN struct group * getgrent __P ((void));
4343
__EXTERN struct group * fgetgrent __P ((FILE *f));
4444
#endif /* __USE_SVID */
4545

46-
__EXTERN struct group * getgrgid __P ((int gid));
46+
__EXTERN struct group * getgrgid __P ((__gid_t gid));
4747
__EXTERN struct group * getgrnam __P ((const char *name));
4848

49+
int getgrgid_r(__gid_t gid, struct group *grp, char *buf, size_t buflen, struct group **result);
50+
int getgrnam_r(const char *name, struct group *grp, char *buf, size_t buflen, struct group **result);
51+
4952
#ifdef __USE_BSD
5053
__EXTERN int initgroups __P ((const char* __user, __gid_t __group));
5154
__EXTERN int setgroups __P ((size_t __count, const __gid_t* __groups));

pwdgrp/SRCFILES

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,7 @@ SRCFILES = \
1515
getpwuid.c \
1616
getpwuid_r.c \
1717
grp.c \
18+
getgrgid_r.c \
19+
getgrnam_r.c \
1820
initgroups.c \
1921
putpwent.c

pwdgrp/getgrgid_r.c

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
*
3+
* MMedour - 2024/06/24 - getgrgid_r & getgrnam_r draft c implementation and validation
4+
*
5+
*/
6+
7+
#include <string.h>
8+
#include <stdio.h>
9+
#include <stdlib.h>
10+
#include <unistd.h>
11+
#include <grp.h>
12+
#include <errno.h>
13+
14+
int getgrgid_r(gid_t gid, struct group *grp, char *buf, size_t buflen, struct group **result)
15+
{
16+
char **mem_ptr;
17+
struct group *g;
18+
size_t gr_size, len, mem_array_counter, mem_array_pos;
19+
20+
if (grp == NULL || buf == NULL)
21+
{
22+
__set_errno(EINVAL);
23+
*result = NULL;
24+
return -1;
25+
}
26+
27+
g = getgrgid(gid);
28+
29+
if (g == NULL)
30+
{
31+
*result = NULL;
32+
return -1;
33+
}
34+
35+
/* Get the size needed to store getgrgid */
36+
gr_size = 0;
37+
gr_size += strlen(g->gr_name) + 1;
38+
gr_size += strlen(g->gr_passwd) + 1;
39+
40+
mem_array_counter = 0;
41+
for (mem_ptr = g->gr_mem; *mem_ptr; mem_ptr++)
42+
{
43+
gr_size += strlen(*mem_ptr) + 1;
44+
mem_array_counter++;
45+
}
46+
gr_size += (mem_array_counter + 1) * (sizeof(char*));
47+
48+
if (gr_size > buflen)
49+
{
50+
__set_errno(ERANGE);
51+
*result = NULL;
52+
return -1;
53+
}
54+
55+
grp->gr_gid = g->gr_gid;
56+
57+
gr_size = 0;
58+
grp->gr_mem = (char**)&buf[gr_size];
59+
gr_size += (mem_array_counter + 1) * (sizeof(char*));
60+
61+
grp->gr_name = &buf[gr_size];
62+
len = strlen(g->gr_name) + 1;
63+
memcpy(&buf[gr_size], g->gr_name, len);
64+
gr_size += len;
65+
66+
grp->gr_passwd = &buf[gr_size];
67+
len = strlen(g->gr_passwd) + 1;
68+
memcpy(&buf[gr_size], g->gr_passwd, len);
69+
gr_size += len;
70+
71+
mem_array_pos = 0;
72+
for (mem_ptr = g->gr_mem; *mem_ptr; mem_ptr++)
73+
{
74+
len = strlen(*mem_ptr) + 1;
75+
memcpy(&buf[gr_size], *mem_ptr, len);
76+
grp->gr_mem[mem_array_pos] = &buf[gr_size];
77+
mem_array_pos++;
78+
gr_size += len;
79+
}
80+
grp->gr_mem[mem_array_pos] = NULL;
81+
82+
*result = grp;
83+
return 0;
84+
}

pwdgrp/getgrnam_r.c

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
*
3+
* MMedour - 2024/06/24 - getgrgid_r & getgrnam_r draft c implementation and validation
4+
*
5+
*/
6+
7+
#include <string.h>
8+
#include <stdio.h>
9+
#include <stdlib.h>
10+
#include <unistd.h>
11+
#include <grp.h>
12+
#include <errno.h>
13+
14+
int getgrnam_r(const char *name, struct group *grp, char *buf, size_t buflen, struct group **result)
15+
{
16+
char **mem_ptr;
17+
struct group *g;
18+
size_t gr_size, len, mem_array_counter, mem_array_pos;
19+
20+
if (grp == NULL || buf == NULL)
21+
{
22+
__set_errno(EINVAL);
23+
*result = NULL;
24+
return -1;
25+
}
26+
27+
g = getgrnam(name);
28+
29+
if (g == NULL)
30+
{
31+
*result = NULL;
32+
return -1;
33+
}
34+
35+
/* Get the size needed to store getgrgid */
36+
gr_size = 0;
37+
gr_size += strlen(g->gr_name) + 1;
38+
gr_size += strlen(g->gr_passwd) + 1;
39+
40+
mem_array_counter = 0;
41+
for (mem_ptr = g->gr_mem; *mem_ptr; mem_ptr++)
42+
{
43+
gr_size += strlen(*mem_ptr) + 1;
44+
mem_array_counter++;
45+
}
46+
gr_size += (mem_array_counter + 1) * (sizeof(char*));
47+
48+
if (gr_size > buflen)
49+
{
50+
__set_errno(ERANGE);
51+
*result = NULL;
52+
return -1;
53+
}
54+
55+
grp->gr_gid = g->gr_gid;
56+
57+
gr_size = 0;
58+
grp->gr_mem = (char**)&buf[gr_size];
59+
gr_size += (mem_array_counter + 1) * (sizeof(char*));
60+
61+
grp->gr_name = &buf[gr_size];
62+
len = strlen(g->gr_name) + 1;
63+
memcpy(&buf[gr_size], g->gr_name, len);
64+
gr_size += len;
65+
66+
grp->gr_passwd = &buf[gr_size];
67+
len = strlen(g->gr_passwd) + 1;
68+
memcpy(&buf[gr_size], g->gr_passwd, len);
69+
gr_size += len;
70+
71+
mem_array_pos = 0;
72+
for(mem_ptr = g->gr_mem;*mem_ptr;mem_ptr++)
73+
{
74+
len = strlen(*mem_ptr) + 1;
75+
memcpy(&buf[gr_size], *mem_ptr, len);
76+
grp->gr_mem[mem_array_pos] = &buf[gr_size];
77+
mem_array_pos++;
78+
gr_size += len;
79+
}
80+
grp->gr_mem[mem_array_pos] = NULL;
81+
82+
*result = grp;
83+
return 0;
84+
}

pwdgrp/grp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ struct group *getgrent(void)
6161
} /* End of getgrent() */
6262

6363
/* Get first group with matching numerical group ID from file */
64-
struct group *getgrgid(int gid)
64+
struct group *getgrgid(gid_t gid)
6565
{
6666
setgrent();
6767

pwdgrp/test-grp.c

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,70 @@
44
#include <unistd.h>
55
#include <stdlib.h>
66
#include <stdio.h>
7+
#include <errno.h>
8+
9+
static int test_getgrnam_r(const char *name)
10+
{
11+
struct group groupbuf;
12+
char **group1mem;
13+
struct group *group;
14+
char *buf;
15+
long size;
16+
gid_t gid;
17+
char *end;
18+
19+
printf ("group %s:\n", name);
20+
size = sysconf (_SC_GETGR_R_SIZE_MAX);
21+
if (size == -1) {
22+
fprintf (stderr, "error: could not get _SC_GETGR_R_SIZE_MAX\n");
23+
return 0;
24+
}
25+
26+
buf = malloc ((size_t) size);
27+
if (buf == NULL) {
28+
fprintf (stderr, "error: malloc() failed\n");
29+
return 0;
30+
}
31+
32+
gid = (gid_t)strtol(name, &end, 10);
33+
if (*end == '\0')
34+
{
35+
if (getgrgid_r (gid, &groupbuf, buf, (size_t) size, &group) != 0) {
36+
fprintf (stderr,
37+
"error: getgrgid_r failed with errno=%d\n", errno);
38+
free (buf);
39+
return 0;
40+
}
41+
} else
42+
{
43+
if (getgrnam_r (name, &groupbuf, buf, (size_t) size, &group) != 0) {
44+
fprintf (stderr,
45+
"error: getgrnam_r failed with errno=%d\n", errno);
46+
free (buf);
47+
return 0;
48+
}
49+
}
50+
51+
if (group == NULL) {
52+
fprintf (stderr, "error: group not found: %s\n", name);
53+
free (buf);
54+
return 0;
55+
}
56+
57+
printf ("###\tgroup->gr_gid -> %d\n", group->gr_gid);
58+
printf ("###\tgroup->gr_name -> %s\n", group->gr_name);
59+
printf ("###\tgroup->gr_passwd -> %s\n", group->gr_passwd);
60+
printf ("###\tgroup->gr_mem ->\n");
61+
62+
for(group1mem = group->gr_mem; *group1mem != NULL; group1mem++)
63+
{
64+
printf ("###\t\t -> %s\n", *group1mem);
65+
}
66+
67+
free (buf);
68+
return 1;
69+
}
70+
771

872
int
973
main (int argc, char *argv[])
@@ -37,5 +101,15 @@ main (int argc, char *argv[])
37101
}
38102
}
39103

40-
exit (my_passwd && my_group ? EXIT_SUCCESS : EXIT_FAILURE);
104+
if (my_passwd == NULL || my_group == NULL)
105+
return EXIT_FAILURE;
106+
107+
if (argc >= 2)
108+
{
109+
printf("\n");
110+
if (!test_getgrnam_r(argv[1]))
111+
return EXIT_FAILURE;
112+
}
113+
114+
return EXIT_SUCCESS;
41115
}

0 commit comments

Comments
 (0)