system call is unmount not umount
[unix-history] / usr / src / lib / libc / gen / getpwent.c
CommitLineData
b8f253e8 1/*
196b72db
KB
2 * Copyright (c) 1988 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
96efcec2 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
b8f253e8
KM
16 */
17
2ce81398 18#if defined(LIBC_SCCS) && !defined(lint)
f63a642f 19static char sccsid[] = "@(#)getpwent.c 5.11 (Berkeley) %G%";
196b72db 20#endif /* LIBC_SCCS and not lint */
b8f253e8 21
196b72db
KB
22#include <sys/types.h>
23#include <sys/file.h>
a4b07b23
BJ
24#include <stdio.h>
25#include <pwd.h>
499a4b51 26#include <ndbm.h>
a4b07b23 27
196b72db
KB
28static DBM *_pw_db;
29static FILE *_pw_fp;
30static struct passwd _pw_passwd;
f63a642f 31static int _pw_getfirstkey, _pw_stayopen;
33306bfc 32static char _pw_flag, *_pw_file = _PATH_PASSWD;
cc8dd839 33
352c409f 34#define MAXLINELENGTH 1024
196b72db 35static char line[MAXLINELENGTH];
a4b07b23 36
96efcec2
KB
37struct passwd *
38getpwent()
39{
40 datum key;
41 int rval;
42
43 if (!_pw_db && !_pw_fp && !start_pw())
44 return((struct passwd *)NULL);
45 do {
46 if (_pw_db) {
47 key.dptr = NULL;
48 rval = fetch_pw(key);
49 } else /* _pw_fp */
50 rval = scanpw();
51 } while (rval && _pw_flag != _PW_KEYBYNAME);
cc84a39f
KB
52 if (rval)
53 getpw();
96efcec2
KB
54 return(rval ? &_pw_passwd : (struct passwd *)NULL);
55}
56
57struct passwd *
58getpwnam(nam)
59 char *nam;
60{
61 int rval;
62
63 if (!start_pw())
64 return((struct passwd *)NULL);
65 if (_pw_db) {
66 datum key;
67
68 key.dptr = nam;
69 key.dsize = strlen(nam);
70 rval = fetch_pw(key);
71 } else /* _pw_fp */
cc84a39f 72 for (rval = 0; scanpw();)
96efcec2
KB
73 if (!strcmp(nam, _pw_passwd.pw_name)) {
74 rval = 1;
75 break;
76 }
77 if (!_pw_stayopen)
78 endpwent();
cc84a39f
KB
79 if (rval)
80 getpw();
96efcec2
KB
81 return(rval ? &_pw_passwd : (struct passwd *)NULL);
82}
83
84struct passwd *
85getpwuid(uid)
86 int uid;
87{
88 int rval;
89
90 if (!start_pw())
91 return((struct passwd *)NULL);
92 if (_pw_db) {
93 datum key;
94
95 key.dptr = (char *)&uid;
96 key.dsize = sizeof(uid);
97 rval = fetch_pw(key);
98 } else /* _pw_fp */
cc84a39f 99 for (rval = 0; scanpw();)
96efcec2
KB
100 if (_pw_passwd.pw_uid == uid) {
101 rval = 1;
102 break;
103 }
104 if (!_pw_stayopen)
105 endpwent();
cc84a39f
KB
106 if (rval)
107 getpw();
96efcec2
KB
108 return(rval ? &_pw_passwd : (struct passwd *)NULL);
109}
110
196b72db 111static
96efcec2
KB
112start_pw()
113{
33306bfc
KB
114 char *p;
115
96efcec2 116 if (_pw_db) {
f63a642f 117 _pw_getfirstkey = 1;
96efcec2
KB
118 return(1);
119 }
120 if (_pw_fp) {
121 rewind(_pw_fp);
122 return(1);
123 }
f63a642f
KB
124 if (_pw_db = dbm_open(_pw_file, O_RDONLY, 0)) {
125 _pw_getfirstkey = 1;
96efcec2 126 return(1);
f63a642f 127 }
33306bfc
KB
128 /*
129 * special case; if it's the official password file, look in
130 * the master password file, otherwise, look in the file itself.
131 */
132 p = strcmp(_pw_file, _PATH_PASSWD) ? _pw_file : _PATH_MASTERPASSWD;
133 if (_pw_fp = fopen(p, "r"))
96efcec2
KB
134 return(1);
135 return(0);
136}
137
138setpwent()
139{
140 return(setpassent(0));
141}
142
143setpassent(stayopen)
144 int stayopen;
145{
146 if (!start_pw())
147 return(0);
148 _pw_stayopen = stayopen;
149 return(1);
150}
151
152void
153endpwent()
154{
155 if (_pw_db) {
156 dbm_close(_pw_db);
157 _pw_db = (DBM *)NULL;
158 } else if (_pw_fp) {
159 (void)fclose(_pw_fp);
160 _pw_fp = (FILE *)NULL;
161 }
96efcec2
KB
162}
163
164void
165setpwfile(file)
166 char *file;
167{
168 _pw_file = file;
96efcec2
KB
169}
170
171static
172scanpw()
a4b07b23 173{
196b72db 174 register char *cp;
96efcec2 175 long atol();
352c409f 176 char *fgets(), *strsep(), *index();
196b72db
KB
177
178 for (;;) {
96efcec2 179 if (!(fgets(line, sizeof(line), _pw_fp)))
196b72db 180 return(0);
352c409f 181 /* skip lines that are too big */
96efcec2 182 if (!index(line, '\n')) {
352c409f
KB
183 int ch;
184
185 while ((ch = getc(_pw_fp)) != '\n' && ch != EOF)
186 ;
187 continue;
188 }
96efcec2 189 _pw_passwd.pw_name = strsep(line, ":\n");
196b72db
KB
190 _pw_passwd.pw_passwd = strsep((char *)NULL, ":\n");
191 if (!(cp = strsep((char *)NULL, ":\n")))
192 continue;
193 _pw_passwd.pw_uid = atoi(cp);
194 if (!(cp = strsep((char *)NULL, ":\n")))
195 continue;
196 _pw_passwd.pw_gid = atoi(cp);
96efcec2
KB
197 _pw_passwd.pw_class = strsep((char *)NULL, ":\n");
198 if (!(cp = strsep((char *)NULL, ":\n")))
199 continue;
200 _pw_passwd.pw_change = atol(cp);
201 if (!(cp = strsep((char *)NULL, ":\n")))
202 continue;
203 _pw_passwd.pw_expire = atol(cp);
196b72db
KB
204 _pw_passwd.pw_gecos = strsep((char *)NULL, ":\n");
205 _pw_passwd.pw_dir = strsep((char *)NULL, ":\n");
206 _pw_passwd.pw_shell = strsep((char *)NULL, ":\n");
96efcec2
KB
207 if (!_pw_passwd.pw_shell)
208 continue;
209 return(1);
196b72db
KB
210 }
211 /* NOTREACHED */
a4b07b23
BJ
212}
213
196b72db 214static
96efcec2 215fetch_pw(key)
196b72db 216 datum key;
a4b07b23 217{
96efcec2 218 register char *p, *t;
196b72db 219
96efcec2
KB
220 /*
221 * the .dir file is LOCK_EX locked by programs that are
222 * renaming the various password files.
223 */
224 if (flock(dbm_dirfno(_pw_db), LOCK_SH))
196b72db 225 return(0);
96efcec2 226 if (!key.dptr)
f63a642f
KB
227 if (_pw_getfirstkey) {
228 _pw_getfirstkey = 0;
96efcec2
KB
229 key = dbm_firstkey(_pw_db);
230 } else
231 key = dbm_nextkey(_pw_db);
232 if (key.dptr)
233 key = dbm_fetch(_pw_db, key);
196b72db 234 (void)flock(dbm_dirfno(_pw_db), LOCK_UN);
96efcec2 235 if (!(p = key.dptr))
196b72db 236 return(0);
96efcec2
KB
237 t = line;
238#define EXPAND(e) e = t; while (*t++ = *p++);
239 EXPAND(_pw_passwd.pw_name);
240 EXPAND(_pw_passwd.pw_passwd);
241 bcopy(p, (char *)&_pw_passwd.pw_uid, sizeof(int));
242 p += sizeof(int);
243 bcopy(p, (char *)&_pw_passwd.pw_gid, sizeof(int));
244 p += sizeof(int);
245 bcopy(p, (char *)&_pw_passwd.pw_change, sizeof(time_t));
246 p += sizeof(time_t);
247 EXPAND(_pw_passwd.pw_class);
248 EXPAND(_pw_passwd.pw_gecos);
249 EXPAND(_pw_passwd.pw_dir);
250 EXPAND(_pw_passwd.pw_shell);
251 bcopy(p, (char *)&_pw_passwd.pw_expire, sizeof(time_t));
252 p += sizeof(time_t);
253 _pw_flag = *p;
196b72db 254 return(1);
a4b07b23
BJ
255}
256
3b8a62fc
KB
257#define _MAX_PASSWD_SIZE 50
258static char pwbuf[_MAX_PASSWD_SIZE];
259
96efcec2
KB
260static
261getpw()
196b72db 262{
96efcec2 263 long pos, atol();
33306bfc 264 int fd, n;
96efcec2 265 char *p;
3b8a62fc 266 off_t lseek();
196b72db 267
972b418a
KB
268 if (geteuid())
269 return;
33306bfc
KB
270 /*
271 * special case; if it's the official password file, look in
272 * the master password file, otherwise, look in the file itself.
273 */
274 p = strcmp(_pw_file, _PATH_PASSWD) ? _pw_file : _PATH_MASTERPASSWD;
275 if ((fd = open(p, O_RDONLY, 0)) < 0)
276 return;
96efcec2 277 pos = atol(_pw_passwd.pw_passwd);
33306bfc 278 if (lseek(fd, pos, L_SET) != pos)
96efcec2 279 goto bad;
33306bfc 280 if ((n = read(fd, pwbuf, sizeof(pwbuf) - 1)) < 0)
96efcec2
KB
281 goto bad;
282 pwbuf[n] = '\0';
283 for (p = pwbuf; *p; ++p)
284 if (*p == ':') {
285 *p = '\0';
286 _pw_passwd.pw_passwd = pwbuf;
287 break;
288 }
33306bfc 289bad: (void)close(fd);
02d7fd83 290}