xref: /csrg-svn/lib/libc/gen/getpwent.c (revision 36456)
122095Smckusick /*
236215Sbostic  * Copyright (c) 1988 The Regents of the University of California.
336215Sbostic  * All rights reserved.
436215Sbostic  *
536215Sbostic  * Redistribution and use in source and binary forms are permitted
636215Sbostic  * provided that the above copyright notice and this paragraph are
736215Sbostic  * duplicated in all such forms and that any documentation,
836215Sbostic  * advertising materials, and other materials related to such
936215Sbostic  * distribution and use acknowledge that the software was developed
1036215Sbostic  * by the University of California, Berkeley.  The name of the
1136215Sbostic  * University may not be used to endorse or promote products derived
1236215Sbostic  * from this software without specific prior written permission.
1336215Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1436215Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1536215Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1622095Smckusick  */
1722095Smckusick 
1826560Sdonn #if defined(LIBC_SCCS) && !defined(lint)
19*36456Sbostic static char sccsid[] = "@(#)getpwent.c	5.4 (Berkeley) 12/21/88";
2036215Sbostic #endif /* LIBC_SCCS and not lint */
2122095Smckusick 
2236215Sbostic #include <sys/types.h>
2336215Sbostic #include <sys/file.h>
242019Swnj #include <stdio.h>
252019Swnj #include <pwd.h>
2616416Sralph #include <ndbm.h>
272019Swnj 
2836215Sbostic static DBM *_pw_db;
2936215Sbostic static FILE *_pw_fp;
3036215Sbostic static struct passwd _pw_passwd;
3136215Sbostic static int _pw_set;
3236215Sbostic static char *_pw_file = "/etc/passwd";
332019Swnj 
34*36456Sbostic #define	MAXLINELENGTH	1024
3536215Sbostic static char line[MAXLINELENGTH];
3617759Sserge 
3736215Sbostic static
3836215Sbostic pwscan()
392019Swnj {
4036215Sbostic 	register char *cp;
41*36456Sbostic 	char *fgets(), *strsep(), *index();
4236215Sbostic 
4336215Sbostic 	for (;;) {
4436215Sbostic 		if (!(cp = fgets(line, sizeof(line), _pw_fp)))
4536215Sbostic 			return(0);
46*36456Sbostic 		/* skip lines that are too big */
47*36456Sbostic 		if (!index(cp, '\n')) {
48*36456Sbostic 			int ch;
49*36456Sbostic 
50*36456Sbostic 			while ((ch = getc(_pw_fp)) != '\n' && ch != EOF)
51*36456Sbostic 				;
52*36456Sbostic 			continue;
53*36456Sbostic 		}
5436215Sbostic 		_pw_passwd.pw_name = strsep(cp, ":\n");
5536215Sbostic 		_pw_passwd.pw_passwd = strsep((char *)NULL, ":\n");
5636215Sbostic 		if (!(cp = strsep((char *)NULL, ":\n")))
5736215Sbostic 			continue;
5836215Sbostic 		_pw_passwd.pw_uid = atoi(cp);
5936215Sbostic 		if (!(cp = strsep((char *)NULL, ":\n")))
6036215Sbostic 			continue;
6136215Sbostic 		_pw_passwd.pw_gid = atoi(cp);
6236215Sbostic 		_pw_passwd.pw_gecos = strsep((char *)NULL, ":\n");
6336215Sbostic 		_pw_passwd.pw_dir = strsep((char *)NULL, ":\n");
6436215Sbostic 		_pw_passwd.pw_shell = strsep((char *)NULL, ":\n");
6536215Sbostic 		if (_pw_passwd.pw_shell) {
6636215Sbostic 			_pw_passwd.pw_quota = 0;
6736215Sbostic 			_pw_passwd.pw_comment = "";
6836215Sbostic 			return(1);
6936215Sbostic 		}
7036215Sbostic 	}
7136215Sbostic 	/* NOTREACHED */
722019Swnj }
732019Swnj 
7436215Sbostic static
7536215Sbostic fetchpw(key)
7636215Sbostic 	datum key;
772019Swnj {
7836215Sbostic 	register char *cp, *tp;
7936215Sbostic 
8036215Sbostic 	if (_pw_db == (DBM *)NULL &&
8136215Sbostic 	    (_pw_db = dbm_open(_pw_file, O_RDONLY, 0)) == (DBM *)NULL)
8236215Sbostic 		return(0);
8336215Sbostic 	if (flock(dbm_dirfno(_pw_db), LOCK_SH)) {
8417028Sralph 		dbm_close(_pw_db);
8536215Sbostic 		_pw_db = NULL;
8636215Sbostic 		return(0);
8716416Sralph 	}
8836215Sbostic 	key = dbm_fetch(_pw_db, key);
8936215Sbostic 	(void)flock(dbm_dirfno(_pw_db), LOCK_UN);
9036215Sbostic 	if ((cp = key.dptr) == 0)
9136215Sbostic 		return(0);
9236215Sbostic 
9336215Sbostic 	tp = line;
9436215Sbostic #define	EXPAND(e)	_pw_passwd.e = tp; while (*tp++ = *cp++);
9536215Sbostic 	EXPAND(pw_name);
9636215Sbostic 	EXPAND(pw_passwd);
9736215Sbostic 	bcopy(cp, (char *)&_pw_passwd.pw_uid, sizeof(int));
9836215Sbostic 	cp += sizeof(int);
9936215Sbostic 	bcopy(cp, (char *)&_pw_passwd.pw_gid, sizeof(int));
10036215Sbostic 	cp += sizeof(int);
10136215Sbostic 	bcopy(cp, (char *)&_pw_passwd.pw_quota, sizeof(int));
10236215Sbostic 	cp += sizeof(int);
10336215Sbostic 	EXPAND(pw_comment);
10436215Sbostic 	EXPAND(pw_gecos);
10536215Sbostic 	EXPAND(pw_dir);
10636215Sbostic 	EXPAND(pw_shell);
10736215Sbostic 	return(1);
1082019Swnj }
1092019Swnj 
11036215Sbostic struct passwd *
11136215Sbostic getpwent()
1122019Swnj {
11336215Sbostic 	if (!_pw_fp && !setpwent() || !pwscan())
11436215Sbostic 		return((struct passwd *)NULL);
11536215Sbostic 	return(&_pw_passwd);
1162019Swnj }
1172019Swnj 
1182019Swnj struct passwd *
11936215Sbostic getpwnam(nam)
12036215Sbostic 	char *nam;
1212019Swnj {
12236215Sbostic 	datum key;
1232019Swnj 
12436215Sbostic 	key.dptr = nam;
12536215Sbostic 	key.dsize = strlen(nam);
12636215Sbostic 	if (!fetchpw(key)) {
12736215Sbostic 		if (setpwent())
12836215Sbostic 			while (pwscan())
12936215Sbostic 				if (!strcmp(nam, _pw_passwd.pw_name))
13036215Sbostic 					return(&_pw_passwd);
13136215Sbostic 		return((struct passwd *)NULL);
1322019Swnj 	}
13336215Sbostic 	return(&_pw_passwd);
1342019Swnj }
13516507Sralph 
13636215Sbostic struct passwd *
13736215Sbostic getpwuid(uid)
13836215Sbostic 	uid_t uid;
13936215Sbostic {
14036215Sbostic 	datum key;
14136215Sbostic 
14236215Sbostic 	key.dptr = (char *)&uid;
14336215Sbostic 	key.dsize = sizeof(uid);
14436215Sbostic 	if (!fetchpw(key)) {
14536215Sbostic 		if (setpwent())
14636215Sbostic 			while (pwscan())
14736215Sbostic 				if (_pw_passwd.pw_uid == uid)
14836215Sbostic 					return(&_pw_passwd);
14936215Sbostic 		return((struct passwd *)NULL);
15036215Sbostic 	}
15136215Sbostic 	return(&_pw_passwd);
15236215Sbostic }
15336215Sbostic 
15436215Sbostic void
15516507Sralph setpwfile(file)
15616507Sralph 	char *file;
15716507Sralph {
15817759Sserge 	_pw_file = file;
15936215Sbostic 	_pw_set = 1;
16016507Sralph }
16136215Sbostic 
16236215Sbostic setpwent()
16336215Sbostic {
16436215Sbostic 	if (_pw_set)
16536215Sbostic 		endpwent();
16636215Sbostic 	if (_pw_fp)
16736215Sbostic 		rewind(_pw_fp);
16836215Sbostic 	else if ((_pw_fp = fopen(_pw_file, "r")) == NULL)
16936215Sbostic 		return(0);
17036215Sbostic 	_pw_set = 0;
17136215Sbostic 	return(1);
17236215Sbostic }
17336215Sbostic 
17436215Sbostic void
17536215Sbostic endpwent()
17636215Sbostic {
17736215Sbostic 	if (_pw_fp) {
17836215Sbostic 		(void)fclose(_pw_fp);
17936215Sbostic 		_pw_fp = (FILE *)NULL;
18036215Sbostic 	}
18136215Sbostic 	if (_pw_db) {
18236215Sbostic 		dbm_close(_pw_db);
18336215Sbostic 		_pw_db = (DBM *)NULL;
18436215Sbostic 	}
18536215Sbostic }
186