1 /* getgrent(), getgrgid(), getgrnam() - group file routines
11 #include <sys/types.h>
18 #define arraysize(a) (sizeof(a) / sizeof((a)[0]))
19 #define arraylimit(a) ((a) + arraysize(a))
21 static char GROUP
[]= "/etc/group"; /* The group file. */
22 static const char *grfile
; /* Current group file. */
24 static char buf
[1024]; /* Read buffer. */
25 static char grline
[512]; /* One line from the group file. */
26 static struct group entry
; /* Entry to fill and return. */
27 static char *members
[64]; /* Group members with the entry. */
28 static int grfd
= -1; /* Filedescriptor to the file. */
29 static char *bufptr
; /* Place in buf. */
30 static ssize_t buflen
= 0; /* Remaining characters in buf. */
31 static char *lineptr
; /* Place in the line. */
34 /* Close the group file. */
44 /* Open the group file. */
46 if (grfd
>= 0) endgrent();
48 if (grfile
== nil
) grfile
= GROUP
;
50 if ((grfd
= open(grfile
, O_RDONLY
)) < 0) return -1;
51 (void) fcntl(grfd
, F_SETFD
, fcntl(grfd
, F_GETFD
) | FD_CLOEXEC
);
55 void setgrfile(const char *file
)
56 /* Prepare for reading an alternate group file. */
62 static int getline(void)
63 /* Get one line from the group file, return 0 if bad or EOF. */
69 if ((buflen
= read(grfd
, buf
, sizeof(buf
))) <= 0)
74 if (lineptr
== arraylimit(grline
)) return 0;
76 } while ((*lineptr
++ = *bufptr
++) != '\n');
82 static char *scan_punct(int punct
)
83 /* Scan for a field separator in a line, return the start of the field. */
90 if (*lineptr
== 0) return nil
;
91 if (*lineptr
== '\n') break;
92 if (*lineptr
++ == punct
) break;
93 if (lineptr
[-1] == ':') return nil
; /* :::,,,:,,,? */
99 struct group
*getgrent(void)
100 /* Read one entry from the group file. */
105 /* Open the file if not yet open. */
106 if (grfd
< 0 && setgrent() < 0) return nil
;
108 /* Until a good line is read. */
110 if (!getline()) return nil
; /* EOF or corrupt. */
112 if ((entry
.gr_name
= scan_punct(':')) == nil
) continue;
113 if ((entry
.gr_passwd
= scan_punct(':')) == nil
) continue;
114 if ((p
= scan_punct(':')) == nil
) continue;
115 entry
.gr_gid
= strtol(p
, nil
, 0);
117 entry
.gr_mem
= mem
= members
;
118 if (*lineptr
!= '\n') {
120 if ((*mem
= scan_punct(',')) == nil
) goto again
;
121 if (mem
< arraylimit(members
) - 1) mem
++;
122 } while (*lineptr
!= 0);
130 struct group
*getgrgid(_mnx_Gid_t gid
)
131 /* Return the group file entry belonging to the user-id. */
136 while ((gr
= getgrent()) != nil
&& gr
->gr_gid
!= gid
) {}
141 struct group
*getgrnam(const char *name
)
142 /* Return the group file entry belonging to the user name. */
147 while ((gr
= getgrent()) != nil
&& strcmp(gr
->gr_name
, name
) != 0) {}