[mod.sources] v08i080: Public-domain getpw*

sources-request@mirror.UUCP (02/28/87)

Submitted by: emoryu1!emoryu2!arnold (Arnold D. Robbins)
Mod.sources: Volume 8, Issue 80
Archive-name: getpw

Here is public domain re-implementation of the getpwent(3) routines. I have
not included a manual page, since every Unix system has one. I also haven't
even bothered to include a <pwd.h> file; you should be able to use the one
on your system.

There is one additional routine: 
	setpwfile (file)
	char *file;
which will cause the routines to find password records from a file besides
/etc/passwd.  This is useful should you need to use saved password files,
for instance in doing Unix accounting, where you wish to keep info around on
old accounts, but take the old accounts out of the live password file.
(Can you guess why I just whipped these up?)

To switch files, call setpwfile as the very first thing, or call endpwent(),
then setpwfile ("/some/file").

Anyway, I hope this is useful to somene out there.

Arnold Robbins
arnold@emoryu1.{CSNET, UUCP, ARPA, BITNET}
#! /bin/sh
# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
# If all goes well, you will see the message "End of shell archive."
# Contents:  getpw.c
PATH=/bin:/usr/bin:/usr/ucb; export PATH
echo shar: extracting "'getpw.c'" '(2658 characters)'
if test -f 'getpw.c' ; then 
  echo shar: will not over-write existing file "'getpw.c'"
else
sed 's/^X//' >getpw.c <<'@//E*O*F getpw.c//'
X#include <stdio.h>
X#include <pwd.h>
X
Xstatic char *pwdfile = "/etc/passwd";	/* default passwd file */
Xstatic FILE *fp = NULL;
Xstatic struct passwd curentry;		/* static data to return */
X
Xvoid setpwfile (cp)
Xchar *cp;
X{
X	pwdfile = cp;
X}
X
Xint setpwent ()
X{
X	if (fp)
X		rewind (fp);
X	else if ((fp = fopen (pwdfile, "r")) == NULL)
X	{
X#ifdef VERBOSE
X		fprintf (stderr,
X			"setpwent: %s non-existant or unreadable.\n", pwdfile);
X#endif
X		return (0);
X	}
X	return (1);
X}
X
Xint endpwent ()
X{
X	if (fp)
X	{
X		fclose (fp);
X		fp = NULL;
X	}
X	return 1;
X}
X
Xstruct passwd *getpwent ()
X{
X	if (! fp && ! setpwent ())
X		return (NULL);
X
X	if (! nextent ())
X		return (NULL);
X	else
X		return (& curentry);
X}
X
Xstruct passwd *getpwuid (uid)
Xregister int uid;
X{
X	if (! setpwent ())
X		return (NULL);
X
X	while (nextent ())
X		if (curentry.pw_uid == uid)
X			return (& curentry);
X
X	return (NULL);
X}
X
Xstruct passwd *getpwnam (name)
Xregister char *name;
X{
X	if (! setpwent ())
X		return (NULL);
X
X	while (nextent ())
X		if (strcmp (curentry.pw_name, name) == 0)
X			return (& curentry);
X
X	return (NULL);
X}
X
Xstatic char savbuf[BUFSIZ];
X		
Xstatic int nextent ()
X{
X	register char *cp;
X
X	if (! fp && ! setpwent ())
X		return (0);
X
X	while (fgets (savbuf, sizeof(savbuf), fp) != NULL)
X	{
X		for (cp = savbuf; *cp && *cp != ':'; cp++)
X			;
X		curentry.pw_name = savbuf;
X		*cp++ = '\0';
X		curentry.pw_passwd = cp;
X		for (; *cp && *cp != ':'; cp++)
X			;
X		*cp++ = '\0';
X		curentry.pw_uid = atoi (cp);
X		for (; *cp && *cp != ':'; cp++)
X			;
X		*cp++ = '\0';
X		curentry.pw_gid = atoi (cp);
X		for (; *cp && *cp != ':'; cp++)
X			;
X		*cp++ = '\0';
X		curentry.pw_gecos = cp;
X		for (; *cp && *cp != ':'; cp++)
X			;
X		*cp++ = '\0';
X		curentry.pw_dir = cp;
X		for (; *cp && *cp != ':'; cp++)
X			;
X		*cp++ = '\0';
X		curentry.pw_shell = cp;
X		for (; *cp && *cp != ':' && *cp != '\n'; cp++)
X			;
X		*cp++ = '\0';
X		return (1);
X	}
X	return (0);
X}
X
X#ifdef TEST
Xmain (argc, argv)
Xint argc;
Xchar **argv;
X{
X	struct passwd *pwd;
X
X	if (argc > 1)
X		setpwfile (argv[1]);
X
X	setpwent ();
X	while ((pwd = getpwent ()) != NULL)
X	{
X		printf ("%s:\n\t%s\n\t%d\n\t%d\n\t%s\n\t%s\n\t%s\n",
X			pwd->pw_name,
X			pwd->pw_passwd,
X			pwd->pw_uid,
X			pwd->pw_gid,
X			pwd->pw_gecos,
X			pwd->pw_dir,
X			pwd->pw_shell);
X	}
X	endpwent ();
X
X	if (pwd = getpwnam ("operator"))
X		printf ("%s:\n\t%s\n\t%d\n\t%d\n\t%s\n\t%s\n\t%s\n",
X			pwd->pw_name,
X			pwd->pw_passwd,
X			pwd->pw_uid,
X			pwd->pw_gid,
X			pwd->pw_gecos,
X			pwd->pw_dir,
X			pwd->pw_shell);
X
X	if (pwd = getpwuid (1))
X		printf ("%s:\n\t%s\n\t%d\n\t%d\n\t%s\n\t%s\n\t%s\n",
X			pwd->pw_name,
X			pwd->pw_passwd,
X			pwd->pw_uid,
X			pwd->pw_gid,
X			pwd->pw_gecos,
X			pwd->pw_dir,
X			pwd->pw_shell);
X}
X#endif
@//E*O*F getpw.c//
if test 2658 -ne "`wc -c <'getpw.c'`"; then
    echo shar: error transmitting "'getpw.c'" '(should have been 2658 characters)'
fi
fi # end of overwriting check
echo shar: "End of shell archive."
exit 0