. service tells you which device it couldn't stat
[minix3.git] / lib / other / getpwent.c
blobf13fbe99a2a019f09db1d2edfaaa85b313234146
1 /* getpwent(), getpwuid(), getpwnam() - password 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 <pwd.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 PASSWD[]= "/etc/passwd"; /* The password file. */
22 static const char *pwfile; /* Current password file. */
24 static char buf[1024]; /* Read buffer. */
25 static char pwline[256]; /* One line from the password file. */
26 static struct passwd entry; /* Entry to fill and return. */
27 static int pwfd= -1; /* Filedescriptor to the file. */
28 static char *bufptr; /* Place in buf. */
29 static ssize_t buflen= 0; /* Remaining characters in buf. */
30 static char *lineptr; /* Place in the line. */
32 void endpwent(void)
33 /* Close the password file. */
35 if (pwfd >= 0) {
36 (void) close(pwfd);
37 pwfd= -1;
38 buflen= 0;
42 int setpwent(void)
43 /* Open the password file. */
45 if (pwfd >= 0) endpwent();
47 if (pwfile == nil) pwfile= PASSWD;
49 if ((pwfd= open(pwfile, O_RDONLY)) < 0) return -1;
50 (void) fcntl(pwfd, F_SETFD, fcntl(pwfd, F_GETFD) | FD_CLOEXEC);
51 return 0;
54 void setpwfile(const char *file)
55 /* Prepare for reading an alternate password file. */
57 endpwent();
58 pwfile= file;
61 static int getline(void)
62 /* Get one line from the password file, return 0 if bad or EOF. */
64 lineptr= pwline;
66 do {
67 if (buflen == 0) {
68 if ((buflen= read(pwfd, buf, sizeof(buf))) <= 0)
69 return 0;
70 bufptr= buf;
73 if (lineptr == arraylimit(pwline)) return 0;
74 buflen--;
75 } while ((*lineptr++ = *bufptr++) != '\n');
77 lineptr= pwline;
78 return 1;
81 static char *scan_colon(void)
82 /* Scan for a field separator in a line, return the start of the field. */
84 char *field= lineptr;
85 char *last;
87 for (;;) {
88 last= lineptr;
89 if (*lineptr == 0) return nil;
90 if (*lineptr == '\n') break;
91 if (*lineptr++ == ':') break;
93 *last= 0;
94 return field;
97 struct passwd *getpwent(void)
98 /* Read one entry from the password file. */
100 char *p;
102 /* Open the file if not yet open. */
103 if (pwfd < 0 && setpwent() < 0) return nil;
105 /* Until a good line is read. */
106 for (;;) {
107 if (!getline()) return nil; /* EOF or corrupt. */
109 if ((entry.pw_name= scan_colon()) == nil) continue;
110 if ((entry.pw_passwd= scan_colon()) == nil) continue;
111 if ((p= scan_colon()) == nil) continue;
112 entry.pw_uid= strtol(p, nil, 0);
113 if ((p= scan_colon()) == nil) continue;
114 entry.pw_gid= strtol(p, nil, 0);
115 if ((entry.pw_gecos= scan_colon()) == nil) continue;
116 if ((entry.pw_dir= scan_colon()) == nil) continue;
117 if ((entry.pw_shell= scan_colon()) == nil) continue;
119 if (*lineptr == 0) return &entry;
123 struct passwd *getpwuid(_mnx_Uid_t uid)
124 /* Return the password file entry belonging to the user-id. */
126 struct passwd *pw;
128 endpwent();
129 while ((pw= getpwent()) != nil && pw->pw_uid != uid) {}
130 endpwent();
131 return pw;
134 struct passwd *getpwnam(const char *name)
135 /* Return the password file entry belonging to the user name. */
137 struct passwd *pw;
139 endpwent();
140 while ((pw= getpwent()) != nil && strcmp(pw->pw_name, name) != 0) {}
141 endpwent();
142 return pw;