. pci driver now returns devices, even when they have been pci_reserve()d
[minix3.git] / lib / other / getgrent.c
blob63931e5bd867cf3ea0a5fe389135d2a868744e99
1 /* getgrent(), getgrgid(), getgrnam() - group file routines
3 * Author: Kees J. Bot
4 * 31 Jan 1994
5 */
6 #define nil 0
7 #define open _open
8 #define fcntl _fcntl
9 #define read _read
10 #define close _close
11 #include <sys/types.h>
12 #include <grp.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include <unistd.h>
16 #include <fcntl.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. */
33 void endgrent(void)
34 /* Close the group file. */
36 if (grfd >= 0) {
37 (void) close(grfd);
38 grfd= -1;
39 buflen= 0;
43 int setgrent(void)
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);
52 return 0;
55 void setgrfile(const char *file)
56 /* Prepare for reading an alternate group file. */
58 endgrent();
59 grfile= file;
62 static int getline(void)
63 /* Get one line from the group file, return 0 if bad or EOF. */
65 lineptr= grline;
67 do {
68 if (buflen == 0) {
69 if ((buflen= read(grfd, buf, sizeof(buf))) <= 0)
70 return 0;
71 bufptr= buf;
74 if (lineptr == arraylimit(grline)) return 0;
75 buflen--;
76 } while ((*lineptr++ = *bufptr++) != '\n');
78 lineptr= grline;
79 return 1;
82 static char *scan_punct(int punct)
83 /* Scan for a field separator in a line, return the start of the field. */
85 char *field= lineptr;
86 char *last;
88 for (;;) {
89 last= lineptr;
90 if (*lineptr == 0) return nil;
91 if (*lineptr == '\n') break;
92 if (*lineptr++ == punct) break;
93 if (lineptr[-1] == ':') return nil; /* :::,,,:,,,? */
95 *last= 0;
96 return field;
99 struct group *getgrent(void)
100 /* Read one entry from the group file. */
102 char *p;
103 char **mem;
105 /* Open the file if not yet open. */
106 if (grfd < 0 && setgrent() < 0) return nil;
108 /* Until a good line is read. */
109 for (;;) {
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') {
119 do {
120 if ((*mem= scan_punct(',')) == nil) goto again;
121 if (mem < arraylimit(members) - 1) mem++;
122 } while (*lineptr != 0);
124 *mem= nil;
125 return &entry;
126 again:;
130 struct group *getgrgid(_mnx_Gid_t gid)
131 /* Return the group file entry belonging to the user-id. */
133 struct group *gr;
135 endgrent();
136 while ((gr= getgrent()) != nil && gr->gr_gid != gid) {}
137 endgrent();
138 return gr;
141 struct group *getgrnam(const char *name)
142 /* Return the group file entry belonging to the user name. */
144 struct group *gr;
146 endgrent();
147 while ((gr= getgrent()) != nil && strcmp(gr->gr_name, name) != 0) {}
148 endgrent();
149 return gr;