home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1641 / pwent.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-28  |  6.3 KB  |  305 lines

  1. /*
  2.  * Copyright 1989, 1990, John F. Haugh II
  3.  * All rights reserved.
  4.  *
  5.  * Use, duplication, and disclosure prohibited without
  6.  * the express written permission of the author.
  7.  *
  8.  * Duplication is permitted for non-commercial [ profit making ]
  9.  * purposes provided this and other copyright notices remain
  10.  * intact.
  11.  */
  12.  
  13. #include <stdio.h>
  14. #include <pwd.h>
  15. #include <string.h>
  16. #include "config.h"
  17.  
  18. #ifdef    DBM
  19. #include <dbm.h>
  20. #endif
  21.  
  22. #ifndef    lint
  23. static    char    _sccsid[] = "@(#)pwent.c    2.2    11:48:02    7/22/90";
  24. #endif
  25.  
  26. #define    SBUFSIZ    64
  27. #define    NFIELDS    7
  28.  
  29. static    FILE    *pwdfp;
  30. static    char    pwdbuf[BUFSIZ];
  31. static    char    *pwdfile = "/etc/passwd";
  32. #ifdef    DBM
  33. static    int    dbmopened;
  34. static    int    dbmerror;
  35. #endif
  36. static    char    *pwdfields[NFIELDS];
  37. static    struct    passwd    pwent;
  38.  
  39. /*
  40.  * sgetpwent - convert a string to a (struct passwd)
  41.  *
  42.  * sgetpwent() parses a string into the parts required for a password
  43.  * structure.  Strict checking is made for the UID and GID fields and
  44.  * presence of the correct number of colons.  Any failing tests result
  45.  * in a NULL pointer being returned.
  46.  */
  47.  
  48. struct    passwd    *sgetpwent (buf)
  49. char    *buf;
  50. {
  51.     int    i;
  52.     char    *cp;
  53.  
  54.     /*
  55.      * Copy the string to a static buffer so the pointers into
  56.      * the password structure remain valid.
  57.      */
  58.  
  59.     strncpy (pwdbuf, buf, BUFSIZ);
  60.     pwdbuf[BUFSIZ-1] = '\0';
  61.  
  62.     /*
  63.      * Save a pointer to the start of each colon separated
  64.      * field.  The fields are converted into NUL terminated strings.
  65.      */
  66.  
  67.     for (cp = pwdbuf, i = 0;i < NFIELDS && cp;i++) {
  68.         pwdfields[i] = cp;
  69.         if (cp = strchr (cp, ':'))
  70.             *cp++ = 0;
  71.     }
  72.  
  73.     /*
  74.      * There must be exactly NFIELDS colon separated fields or
  75.      * the entry is invalid.  Also, the UID and GID must be non-blank.
  76.      */
  77.  
  78.     if (i != NFIELDS || *pwdfields[2] == '\0' || *pwdfields[3] == '\0')
  79.         return 0;
  80.  
  81.     /*
  82.      * Each of the fields is converted the appropriate data type
  83.      * and the result assigned to the password structure.  If the
  84.      * UID or GID does not convert to an integer value, a NULL
  85.      * pointer is returned.
  86.      */
  87.  
  88.     pwent.pw_name = pwdfields[0];
  89.     pwent.pw_passwd = pwdfields[1];
  90.     if ((pwent.pw_uid = strtol (pwdfields[2], &cp, 10)) == 0 && *cp)
  91.         return 0;
  92.  
  93.     if ((pwent.pw_gid = strtol (pwdfields[3], &cp, 10)) == 0 && *cp)
  94.         return 0;
  95.  
  96.     if (cp = strchr (pwent.pw_passwd, ',')) {
  97.         pwent.pw_age = cp + 1;
  98.         *cp = '\0';
  99.     }
  100.     pwent.pw_gecos = pwdfields[4];
  101.     pwent.pw_dir = pwdfields[5];
  102.     pwent.pw_shell = pwdfields[6];
  103.  
  104.     return (&pwent);
  105. }
  106. #ifdef FGETPWENT
  107. /*
  108.  * fgetpwent - get a password file entry from a stream
  109.  *
  110.  * fgetpwent() reads the next line from a password file formatted stream
  111.  * and returns a pointer to the password structure for that line.
  112.  */
  113.  
  114. struct    passwd    *fgetpwent (fp)
  115. FILE    *fp;
  116. {
  117.     char    buf[BUFSIZ];
  118.  
  119.     while (fgets (buf, BUFSIZ, fp) != (char *) 0) {
  120.         buf[strlen (buf) - 1] = '\0';
  121.         return (sgetpwent (buf));
  122.     }
  123.     return 0;
  124. }
  125. #endif
  126. #ifdef    GETPWENT
  127.  
  128. /*
  129.  * endpwent - close a password file
  130.  *
  131.  * endpwent() closes the password file if open.
  132.  */
  133.  
  134. int    endpwent ()
  135. {
  136.     if (pwdfp)
  137.         if (fclose (pwdfp))
  138.             return -1;
  139.  
  140.     return 0;
  141. }
  142.  
  143. /*
  144.  * getpwent - get a password entry from the password file
  145.  *
  146.  * getpwent() opens the password file, if not already opened, and reads
  147.  * a single entry.  NULL is returned if any errors are encountered reading
  148.  * the password file.
  149.  */
  150.  
  151. struct    passwd    *getpwent ()
  152. {
  153.     if (! pwdfp && setpwent ())
  154.         return 0;
  155.  
  156.     return fgetpwent (pwdfp);
  157. }
  158.  
  159. /*
  160.  * getpwuid - locate the password entry for a given UID
  161.  *
  162.  * getpwuid() locates the first password file entry for the given UID.
  163.  * If there is a valid DBM file, the DBM files are queried first for
  164.  * the entry.  Otherwise, a linear search is begun of the password file
  165.  * searching for an entry which matches the provided UID.
  166.  */
  167.  
  168. struct    passwd    *getpwuid (uid)
  169. int    uid;
  170. {
  171.     struct    passwd    *pwd;
  172. #ifdef    DBM
  173.     datum    key;
  174.     datum    content;
  175.  
  176.     /*
  177.      * Attempt to open the DBM files if they have never been opened
  178.      * and an error has never been returned.
  179.      */
  180.  
  181.     if (! dbmerror && ! dbmopened)
  182.         if (dbminit (pwdfile) == 0)
  183.             dbmopened = 1;
  184.         else
  185.             dbmerror = 1;
  186.  
  187.     /*
  188.      * If the DBM file are now open, create a key for this UID and
  189.      * try to fetch the entry from the database.  A matching record
  190.      * will be unpacked into a static structure and returned to
  191.      * the user.
  192.      */
  193.  
  194.     if (dbmopened) {
  195.         pwent.pw_uid = uid;
  196.         key.dsize = sizeof pwent.pw_uid;
  197.         key.dptr = (char *) &pwent.pw_uid;
  198.         content = fetch (key);
  199.         if (content.dptr != 0) {
  200.             memcpy (pwdbuf, content.dptr, content.dsize);
  201.             pw_unpack (pwdbuf, content.dsize, &pwent);
  202.             return &pwent;
  203.         }
  204.     }
  205. #endif
  206.     /*
  207.      * Rewind the database and begin searching for an entry which
  208.      * matches the UID.  Return the entry when a match is found.
  209.      */
  210.  
  211.     if (setpwent ())
  212.         return 0;
  213.  
  214.     while (pwd = getpwent ())
  215.         if (pwd->pw_uid == uid)
  216.             return pwd;
  217.  
  218.     return 0;
  219. }
  220.  
  221. struct    passwd    *getpwnam (name)
  222. char    *name;
  223. {
  224.     struct    passwd    *pwd;
  225. #ifdef    DBM
  226.     datum    key;
  227.     datum    content;
  228.  
  229.     /*
  230.      * Attempt to open the DBM files if they have never been opened
  231.      * and an error has never been returned.
  232.      */
  233.  
  234.     if (! dbmerror && ! dbmopened)
  235.         if (dbminit (pwdfile) == 0)
  236.             dbmopened = 1;
  237.         else
  238.             dbmerror = 1;
  239.  
  240.     /*
  241.      * If the DBM file are now open, create a key for this UID and
  242.      * try to fetch the entry from the database.  A matching record
  243.      * will be unpacked into a static structure and returned to
  244.      * the user.
  245.      */
  246.  
  247.     if (dbmopened) {
  248.         key.dsize = strlen (name);
  249.         key.dptr = name;
  250.         content = fetch (key);
  251.         if (content.dptr != 0) {
  252.             memcpy (pwdbuf, content.dptr, content.dsize);
  253.             pw_unpack (pwdbuf, content.dsize, &pwent);
  254.             return &pwent;
  255.         }
  256.     }
  257. #endif
  258.     /*
  259.      * Rewind the database and begin searching for an entry which
  260.      * matches the name.  Return the entry when a match is found.
  261.      */
  262.  
  263.     if (setpwent ())
  264.         return 0;
  265.  
  266.     while (pwd = getpwent ())
  267.         if (strcmp (pwd->pw_name, name) == 0)
  268.             return pwd;
  269.  
  270.     return 0;
  271. }
  272.  
  273. /*
  274.  * setpwent - open the password file
  275.  *
  276.  * setpwent() opens the system password file, and the DBM password files
  277.  * if they are present.  The system password file is rewound if it was
  278.  * open already.
  279.  */
  280.  
  281. int    setpwent ()
  282. {
  283.     if (! pwdfp) {
  284.         if (! (pwdfp = fopen (pwdfile, "r")))
  285.             return -1;
  286.     } else {
  287.         if (fseek (pwdfp, 0L, 0) != 0)
  288.             return -1;
  289.     }
  290. #ifdef    DBM
  291.     /*
  292.      * Attempt to open the DBM files if they have never been opened
  293.      * and an error has never been returned.
  294.      */
  295.  
  296.     if (! dbmerror && ! dbmopened)
  297.         if (dbminit (pwdfile) == 0)
  298.             dbmopened = 1;
  299.         else
  300.             dbmerror = 1;
  301. #endif
  302.     return 0;
  303. }
  304. #endif
  305.