home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Source Code 1992 March
/
Source_Code_CD-ROM_Walnut_Creek_March_1992.iso
/
usenet
/
altsrcs
/
2
/
2288
/
pwent.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-12-28
|
7KB
|
325 lines
/*
* Copyright 1989, 1990, John F. Haugh II
* All rights reserved.
*
* Use, duplication, and disclosure prohibited without
* the express written permission of the author.
*
* Duplication is permitted for non-commercial [ profit making ]
* purposes provided this and other copyright notices remain
* intact.
*/
#include <stdio.h>
#include <pwd.h>
#include <string.h>
#include "config.h"
#ifdef DBM
#include <dbm.h>
#endif
#ifndef lint
static char _sccsid[] = "@(#)pwent.c 2.4 23:41:33 10/28/90";
#endif
#define SBUFSIZ 64
#define NFIELDS 7
static FILE *pwdfp;
static char pwdbuf[BUFSIZ];
static char *pwdfile = "/etc/passwd";
#ifdef DBM
static int dbmopened;
static int dbmerror;
#endif
static char *pwdfields[NFIELDS];
static struct passwd pwent;
/*
* sgetpwent - convert a string to a (struct passwd)
*
* sgetpwent() parses a string into the parts required for a password
* structure. Strict checking is made for the UID and GID fields and
* presence of the correct number of colons. Any failing tests result
* in a NULL pointer being returned.
*/
struct passwd *sgetpwent (buf)
char *buf;
{
int i;
char *cp;
/*
* Copy the string to a static buffer so the pointers into
* the password structure remain valid.
*/
strncpy (pwdbuf, buf, BUFSIZ);
pwdbuf[BUFSIZ-1] = '\0';
/*
* Save a pointer to the start of each colon separated
* field. The fields are converted into NUL terminated strings.
*/
for (cp = pwdbuf, i = 0;i < NFIELDS && cp;i++) {
pwdfields[i] = cp;
if (cp = strchr (cp, ':'))
*cp++ = 0;
}
/*
* There must be exactly NFIELDS colon separated fields or
* the entry is invalid. Also, the UID and GID must be non-blank.
*/
if (i != NFIELDS || *pwdfields[2] == '\0' || *pwdfields[3] == '\0')
return 0;
/*
* Each of the fields is converted the appropriate data type
* and the result assigned to the password structure. If the
* UID or GID does not convert to an integer value, a NULL
* pointer is returned.
*/
pwent.pw_name = pwdfields[0];
pwent.pw_passwd = pwdfields[1];
if ((pwent.pw_uid = strtol (pwdfields[2], &cp, 10)) == 0 && *cp)
return 0;
if ((pwent.pw_gid = strtol (pwdfields[3], &cp, 10)) == 0 && *cp)
return 0;
if (cp = strchr (pwent.pw_passwd, ',')) {
pwent.pw_age = cp + 1;
*cp = '\0';
} else
pwent.pw_age = "";
pwent.pw_gecos = pwdfields[4];
pwent.pw_dir = pwdfields[5];
pwent.pw_shell = pwdfields[6];
return (&pwent);
}
#ifdef FGETPWENT
/*
* fgetpwent - get a password file entry from a stream
*
* fgetpwent() reads the next line from a password file formatted stream
* and returns a pointer to the password structure for that line.
*/
struct passwd *fgetpwent (fp)
FILE *fp;
{
char buf[BUFSIZ];
while (fgets (buf, BUFSIZ, fp) != (char *) 0) {
buf[strlen (buf) - 1] = '\0';
return (sgetpwent (buf));
}
return 0;
}
#endif
#ifdef GETPWENT
/*
* endpwent - close a password file
*
* endpwent() closes the password file if open.
*/
int endpwent ()
{
if (pwdfp)
if (fclose (pwdfp))
return -1;
return 0;
}
/*
* getpwent - get a password entry from the password file
*
* getpwent() opens the password file, if not already opened, and reads
* a single entry. NULL is returned if any errors are encountered reading
* the password file.
*/
struct passwd *getpwent ()
{
if (! pwdfp && setpwent ())
return 0;
return fgetpwent (pwdfp);
}
/*
* getpwuid - locate the password entry for a given UID
*
* getpwuid() locates the first password file entry for the given UID.
* If there is a valid DBM file, the DBM files are queried first for
* the entry. Otherwise, a linear search is begun of the password file
* searching for an entry which matches the provided UID.
*/
struct passwd *getpwuid (uid)
int uid;
{
struct passwd *pwd;
#ifdef DBM
datum key;
datum content;
/*
* Attempt to open the DBM files if they have never been opened
* and an error has never been returned.
*/
if (! dbmerror && ! dbmopened) {
char dbmfiles[BUFSIZ];
strcpy (dbmfiles, pwdfile);
strcat (dbmfiles, ".pag");
if (access (dbmfiles, 0) || dbminit (pwdfile))
dbmerror = 1;
else
dbmopened = 1;
}
/*
* If the DBM file are now open, create a key for this UID and
* try to fetch the entry from the database. A matching record
* will be unpacked into a static structure and returned to
* the user.
*/
if (dbmopened) {
pwent.pw_uid = uid;
key.dsize = sizeof pwent.pw_uid;
key.dptr = (char *) &pwent.pw_uid;
content = fetch (key);
if (content.dptr != 0) {
memcpy (pwdbuf, content.dptr, content.dsize);
pw_unpack (pwdbuf, content.dsize, &pwent);
return &pwent;
}
}
#endif
/*
* Rewind the database and begin searching for an entry which
* matches the UID. Return the entry when a match is found.
*/
if (setpwent ())
return 0;
while (pwd = getpwent ())
if (pwd->pw_uid == uid)
return pwd;
return 0;
}
struct passwd *getpwnam (name)
char *name;
{
struct passwd *pwd;
#ifdef DBM
datum key;
datum content;
/*
* Attempt to open the DBM files if they have never been opened
* and an error has never been returned.
*/
if (! dbmerror && ! dbmopened) {
char dbmfiles[BUFSIZ];
strcpy (dbmfiles, pwdfile);
strcat (dbmfiles, ".pag");
if (access (dbmfiles, 0) || dbminit (pwdfile))
dbmerror = 1;
else
dbmopened = 1;
}
/*
* If the DBM file are now open, create a key for this UID and
* try to fetch the entry from the database. A matching record
* will be unpacked into a static structure and returned to
* the user.
*/
if (dbmopened) {
key.dsize = strlen (name);
key.dptr = name;
content = fetch (key);
if (content.dptr != 0) {
memcpy (pwdbuf, content.dptr, content.dsize);
pw_unpack (pwdbuf, content.dsize, &pwent);
return &pwent;
}
}
#endif
/*
* Rewind the database and begin searching for an entry which
* matches the name. Return the entry when a match is found.
*/
if (setpwent ())
return 0;
while (pwd = getpwent ())
if (strcmp (pwd->pw_name, name) == 0)
return pwd;
return 0;
}
/*
* setpwent - open the password file
*
* setpwent() opens the system password file, and the DBM password files
* if they are present. The system password file is rewound if it was
* open already.
*/
int setpwent ()
{
if (! pwdfp) {
if (! (pwdfp = fopen (pwdfile, "r")))
return -1;
} else {
if (fseek (pwdfp, 0L, 0) != 0)
return -1;
}
#ifdef DBM
/*
* Attempt to open the DBM files if they have never been opened
* and an error has never been returned.
*/
if (! dbmerror && ! dbmopened) {
char dbmfiles[BUFSIZ];
strcpy (dbmfiles, pwdfile);
strcat (dbmfiles, ".pag");
if (access (dbmfiles, 0) || dbminit (pwdfile))
dbmerror = 1;
else
dbmopened = 1;
}
#endif
return 0;
}
#endif