forked from Stichting-MINIX-Research-Foundation/minix
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgetpwent.c
More file actions
142 lines (119 loc) · 3.21 KB
/
Copy pathgetpwent.c
File metadata and controls
142 lines (119 loc) · 3.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/* getpwent(), getpwuid(), getpwnam() - password file routines
*
* Author: Kees J. Bot
* 31 Jan 1994
*/
#define open _open
#define fcntl _fcntl
#define read _read
#define close _close
#include <sys/types.h>
#include <pwd.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#define arraysize(a) (sizeof(a) / sizeof((a)[0]))
#define arraylimit(a) ((a) + arraysize(a))
static char PASSWD[]= "/etc/passwd"; /* The password file. */
static const char *pwfile; /* Current password file. */
static char buf[1024]; /* Read buffer. */
static char pwline[256]; /* One line from the password file. */
static struct passwd entry; /* Entry to fill and return. */
static int pwfd= -1; /* Filedescriptor to the file. */
static char *bufptr; /* Place in buf. */
static ssize_t buflen= 0; /* Remaining characters in buf. */
static char *lineptr; /* Place in the line. */
void endpwent(void)
/* Close the password file. */
{
if (pwfd >= 0) {
(void) close(pwfd);
pwfd= -1;
buflen= 0;
}
}
int setpwent(void)
/* Open the password file. */
{
if (pwfd >= 0) endpwent();
if (pwfile == NULL) pwfile= PASSWD;
if ((pwfd= open(pwfile, O_RDONLY)) < 0) return -1;
(void) fcntl(pwfd, F_SETFD, fcntl(pwfd, F_GETFD) | FD_CLOEXEC);
return 0;
}
void setpwfile(const char *file)
/* Prepare for reading an alternate password file. */
{
endpwent();
pwfile= file;
}
static int getline(void)
/* Get one line from the password file, return 0 if bad or EOF. */
{
lineptr= pwline;
do {
if (buflen == 0) {
if ((buflen= read(pwfd, buf, sizeof(buf))) <= 0)
return 0;
bufptr= buf;
}
if (lineptr == arraylimit(pwline)) return 0;
buflen--;
} while ((*lineptr++ = *bufptr++) != '\n');
lineptr= pwline;
return 1;
}
static char *scan_colon(void)
/* Scan for a field separator in a line, return the start of the field. */
{
char *field= lineptr;
char *last;
for (;;) {
last= lineptr;
if (*lineptr == 0) return NULL;
if (*lineptr == '\n') break;
if (*lineptr++ == ':') break;
}
*last= 0;
return field;
}
struct passwd *getpwent(void)
/* Read one entry from the password file. */
{
char *p;
/* Open the file if not yet open. */
if (pwfd < 0 && setpwent() < 0) return NULL;
/* Until a good line is read. */
for (;;) {
if (!getline()) return NULL; /* EOF or corrupt. */
if ((entry.pw_name= scan_colon()) == NULL) continue;
if ((entry.pw_passwd= scan_colon()) == NULL) continue;
if ((p= scan_colon()) == NULL) continue;
entry.pw_uid= strtol(p, NULL, 0);
if ((p= scan_colon()) == NULL) continue;
entry.pw_gid= strtol(p, NULL, 0);
if ((entry.pw_gecos= scan_colon()) == NULL) continue;
if ((entry.pw_dir= scan_colon()) == NULL) continue;
if ((entry.pw_shell= scan_colon()) == NULL) continue;
if (*lineptr == 0) return &entry;
}
}
struct passwd *getpwuid(uid_t uid)
/* Return the password file entry belonging to the user-id. */
{
struct passwd *pw;
endpwent();
while ((pw= getpwent()) != NULL && pw->pw_uid != uid) {}
endpwent();
return pw;
}
struct passwd *getpwnam(const char *name)
/* Return the password file entry belonging to the user name. */
{
struct passwd *pw;
endpwent();
while ((pw= getpwent()) != NULL && strcmp(pw->pw_name, name) != 0) {}
endpwent();
return pw;
}