/* Subject: v08i080: Public-domain getpw*(3) routines Newsgroups: mod.sources Approved: mirror!rs 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 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} */ /* minorly customized by ERS for the MiNT library */ #include #include #include #include #include static char *pwdfile = "/etc/passwd"; /* default passwd file */ static FILE *fp = NULL; static struct passwd curentry; /* static data to return */ static int nextent __PROTO((void)); void setpwfile (cp) char *cp; { endpwent(); if(cp) pwdfile = cp; } void setpwent () { if (fp) rewind (fp); #ifdef atarist else if ((fp = fopen (pwdfile, "rt")) == NULL) #else else if ((fp = fopen (pwdfile, "r")) == NULL) #endif { #ifdef VERBOSE fprintf (stderr, "setpwent: %s non-existant or unreadable.\n", pwdfile); #endif } } void endpwent () { if (fp) { fclose (fp); fp = NULL; } } struct passwd *getpwent () { if (! fp ) { setpwent(); if (! fp ) return (NULL); } if (! nextent ()) return (NULL); else return (& curentry); } struct passwd *getpwuid (uid) register int uid; { setpwent (); while (nextent ()) if (curentry.pw_uid == uid) return (& curentry); return (NULL); } struct passwd *getpwnam (name) register char *name; { setpwent (); while (nextent ()) if (strcmp (curentry.pw_name, name) == 0) return (& curentry); return (NULL); } #ifdef atarist static char savbuf[256]; /* BUFSIZ seems bigger than necessary! */ #else static char savbuf[BUFSIZ]; #endif static int nextent () { register char *cp; if (! fp ) { setpwent (); if (! fp ) return (0); } while (fgets (savbuf, sizeof(savbuf), fp) != NULL) { for (cp = savbuf; *cp && *cp != ':'; cp++) ; curentry.pw_name = savbuf; *cp++ = '\0'; curentry.pw_passwd = cp; for (; *cp && *cp != ':'; cp++) ; *cp++ = '\0'; curentry.pw_uid = atoi (cp); for (; *cp && *cp != ':'; cp++) ; *cp++ = '\0'; curentry.pw_gid = atoi (cp); for (; *cp && *cp != ':'; cp++) ; *cp++ = '\0'; curentry.pw_gecos = cp; for (; *cp && *cp != ':'; cp++) ; *cp++ = '\0'; curentry.pw_dir = cp; for (; *cp && *cp != ':'; cp++) ; *cp++ = '\0'; curentry.pw_shell = cp; for (; *cp && *cp != ':' && *cp != '\n'; cp++) ; *cp++ = '\0'; return (1); } return (0); } #ifdef TEST main (argc, argv) int argc; char **argv; { struct passwd *pwd; if (argc > 1) setpwfile (argv[1]); setpwent (); while ((pwd = getpwent ()) != NULL) { printf ("%s:\n\t%s\n\t%d\n\t%d\n\t%s\n\t%s\n\t%s\n", pwd->pw_name, pwd->pw_passwd, pwd->pw_uid, pwd->pw_gid, pwd->pw_gecos, pwd->pw_dir, pwd->pw_shell); } endpwent (); if (pwd = getpwnam ("operator")) printf ("%s:\n\t%s\n\t%d\n\t%d\n\t%s\n\t%s\n\t%s\n", pwd->pw_name, pwd->pw_passwd, pwd->pw_uid, pwd->pw_gid, pwd->pw_gecos, pwd->pw_dir, pwd->pw_shell); if (pwd = getpwuid (1)) printf ("%s:\n\t%s\n\t%d\n\t%d\n\t%s\n\t%s\n\t%s\n", pwd->pw_name, pwd->pw_passwd, pwd->pw_uid, pwd->pw_gid, pwd->pw_gecos, pwd->pw_dir, pwd->pw_shell); } #endif