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