home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1704 / pwent.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-28  |  6.6 KB  |  323 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.3    01:08:16    8/3/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.         char    dbmfiles[BUFSIZ];
  183.  
  184.         strcpy (dbmfiles, pwdfile);
  185.         strcat (dbmfiles, ".pag");
  186.  
  187.         if (access (dbmfiles, 0) || dbminit (pwdfile))
  188.             dbmerror = 1;
  189.         else
  190.             dbmopened = 1;
  191.     }
  192.  
  193.     /*
  194.      * If the DBM file are now open, create a key for this UID and
  195.      * try to fetch the entry from the database.  A matching record
  196.      * will be unpacked into a static structure and returned to
  197.      * the user.
  198.      */
  199.  
  200.     if (dbmopened) {
  201.         pwent.pw_uid = uid;
  202.         key.dsize = sizeof pwent.pw_uid;
  203.         key.dptr = (char *) &pwent.pw_uid;
  204.         content = fetch (key);
  205.         if (content.dptr != 0) {
  206.             memcpy (pwdbuf, content.dptr, content.dsize);
  207.             pw_unpack (pwdbuf, content.dsize, &pwent);
  208.             return &pwent;
  209.         }
  210.     }
  211. #endif
  212.     /*
  213.      * Rewind the database and begin searching for an entry which
  214.      * matches the UID.  Return the entry when a match is found.
  215.      */
  216.  
  217.     if (setpwent ())
  218.         return 0;
  219.  
  220.     while (pwd = getpwent ())
  221.         if (pwd->pw_uid == uid)
  222.             return pwd;
  223.  
  224.     return 0;
  225. }
  226.  
  227. struct    passwd    *getpwnam (name)
  228. char    *name;
  229. {
  230.     struct    passwd    *pwd;
  231. #ifdef    DBM
  232.     datum    key;
  233.     datum    content;
  234.  
  235.     /*
  236.      * Attempt to open the DBM files if they have never been opened
  237.      * and an error has never been returned.
  238.      */
  239.  
  240.     if (! dbmerror && ! dbmopened) {
  241.         char    dbmfiles[BUFSIZ];
  242.  
  243.         strcpy (dbmfiles, pwdfile);
  244.         strcat (dbmfiles, ".pag");
  245.  
  246.         if (access (dbmfiles, 0) || dbminit (pwdfile))
  247.             dbmerror = 1;
  248.         else
  249.             dbmopened = 1;
  250.     }
  251.  
  252.     /*
  253.      * If the DBM file are now open, create a key for this UID and
  254.      * try to fetch the entry from the database.  A matching record
  255.      * will be unpacked into a static structure and returned to
  256.      * the user.
  257.      */
  258.  
  259.     if (dbmopened) {
  260.         key.dsize = strlen (name);
  261.         key.dptr = name;
  262.         content = fetch (key);
  263.         if (content.dptr != 0) {
  264.             memcpy (pwdbuf, content.dptr, content.dsize);
  265.             pw_unpack (pwdbuf, content.dsize, &pwent);
  266.             return &pwent;
  267.         }
  268.     }
  269. #endif
  270.     /*
  271.      * Rewind the database and begin searching for an entry which
  272.      * matches the name.  Return the entry when a match is found.
  273.      */
  274.  
  275.     if (setpwent ())
  276.         return 0;
  277.  
  278.     while (pwd = getpwent ())
  279.         if (strcmp (pwd->pw_name, name) == 0)
  280.             return pwd;
  281.  
  282.     return 0;
  283. }
  284.  
  285. /*
  286.  * setpwent - open the password file
  287.  *
  288.  * setpwent() opens the system password file, and the DBM password files
  289.  * if they are present.  The system password file is rewound if it was
  290.  * open already.
  291.  */
  292.  
  293. int    setpwent ()
  294. {
  295.     if (! pwdfp) {
  296.         if (! (pwdfp = fopen (pwdfile, "r")))
  297.             return -1;
  298.     } else {
  299.         if (fseek (pwdfp, 0L, 0) != 0)
  300.             return -1;
  301.     }
  302. #ifdef    DBM
  303.     /*
  304.      * Attempt to open the DBM files if they have never been opened
  305.      * and an error has never been returned.
  306.      */
  307.  
  308.     if (! dbmerror && ! dbmopened) {
  309.         char    dbmfiles[BUFSIZ];
  310.  
  311.         strcpy (dbmfiles, pwdfile);
  312.         strcat (dbmfiles, ".pag");
  313.  
  314.         if (access (dbmfiles, 0) || dbminit (pwdfile))
  315.             dbmerror = 1;
  316.         else
  317.             dbmopened = 1;
  318.     }
  319. #endif
  320.     return 0;
  321. }
  322. #endif
  323.