source: trunk/minix/lib/other/getgrent.c@ 10

Last change on this file since 10 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 3.3 KB
RevLine 
[9]1/* getgrent(), getgrgid(), getgrnam() - group file routines
2 *
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>
17
18#define arraysize(a) (sizeof(a) / sizeof((a)[0]))
19#define arraylimit(a) ((a) + arraysize(a))
20
21static char GROUP[]= "/etc/group"; /* The group file. */
22static const char *grfile; /* Current group file. */
23
24static char buf[1024]; /* Read buffer. */
25static char grline[512]; /* One line from the group file. */
26static struct group entry; /* Entry to fill and return. */
27static char *members[64]; /* Group members with the entry. */
28static int grfd= -1; /* Filedescriptor to the file. */
29static char *bufptr; /* Place in buf. */
30static ssize_t buflen= 0; /* Remaining characters in buf. */
31static char *lineptr; /* Place in the line. */
32
33void endgrent(void)
34/* Close the group file. */
35{
36 if (grfd >= 0) {
37 (void) close(grfd);
38 grfd= -1;
39 buflen= 0;
40 }
41}
42
43int setgrent(void)
44/* Open the group file. */
45{
46 if (grfd >= 0) endgrent();
47
48 if (grfile == nil) grfile= GROUP;
49
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;
53}
54
55void setgrfile(const char *file)
56/* Prepare for reading an alternate group file. */
57{
58 endgrent();
59 grfile= file;
60}
61
62static int getline(void)
63/* Get one line from the group file, return 0 if bad or EOF. */
64{
65 lineptr= grline;
66
67 do {
68 if (buflen == 0) {
69 if ((buflen= read(grfd, buf, sizeof(buf))) <= 0)
70 return 0;
71 bufptr= buf;
72 }
73
74 if (lineptr == arraylimit(grline)) return 0;
75 buflen--;
76 } while ((*lineptr++ = *bufptr++) != '\n');
77
78 lineptr= grline;
79 return 1;
80}
81
82static char *scan_punct(int punct)
83/* Scan for a field separator in a line, return the start of the field. */
84{
85 char *field= lineptr;
86 char *last;
87
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; /* :::,,,:,,,? */
94 }
95 *last= 0;
96 return field;
97}
98
99struct group *getgrent(void)
100/* Read one entry from the group file. */
101{
102 char *p;
103 char **mem;
104
105 /* Open the file if not yet open. */
106 if (grfd < 0 && setgrent() < 0) return nil;
107
108 /* Until a good line is read. */
109 for (;;) {
110 if (!getline()) return nil; /* EOF or corrupt. */
111
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);
116
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);
123 }
124 *mem= nil;
125 return &entry;
126 again:;
127 }
128}
129
130struct group *getgrgid(_mnx_Gid_t gid)
131/* Return the group file entry belonging to the user-id. */
132{
133 struct group *gr;
134
135 endgrent();
136 while ((gr= getgrent()) != nil && gr->gr_gid != gid) {}
137 endgrent();
138 return gr;
139}
140
141struct group *getgrnam(const char *name)
142/* Return the group file entry belonging to the user name. */
143{
144 struct group *gr;
145
146 endgrent();
147 while ((gr= getgrent()) != nil && strcmp(gr->gr_name, name) != 0) {}
148 endgrent();
149 return gr;
150}
Note: See TracBrowser for help on using the repository browser.