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 >
C/C++ Source or Header  |  1990-12-28  |  7KB  |  325 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.4    23:41:33    10/28/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.     } else
  100.         pwent.pw_age = "";
  101.  
  102.     pwent.pw_gecos = pwdfields[4];
  103.     pwent.pw_dir = pwdfields[5];
  104.     pwent.pw_shell = pwdfields[6];
  105.  
  106.     return (&pwent);
  107. }
  108. #ifdef FGETPWENT
  109. /*
  110.  * fgetpwent - get a password file entry from a stream
  111.  *
  112.  * fgetpwent() reads the next line from a password file formatted stream
  113.  * and returns a pointer to the password structure for that line.
  114.  */
  115.  
  116. struct    passwd    *fgetpwent (fp)
  117. FILE    *fp;
  118. {
  119.     char    buf[BUFSIZ];
  120.  
  121.     while (fgets (buf, BUFSIZ, fp) != (char *) 0) {
  122.         buf[strlen (buf) - 1] = '\0';
  123.         return (sgetpwent (buf));
  124.     }
  125.     return 0;
  126. }
  127. #endif
  128. #ifdef    GETPWENT
  129.  
  130. /*
  131.  * endpwent - close a password file
  132.  *
  133.  * endpwent() closes the password file if open.
  134.  */
  135.  
  136. int    endpwent ()
  137. {
  138.     if (pwdfp)
  139.         if (fclose (pwdfp))
  140.             return -1;
  141.  
  142.     return 0;
  143. }
  144.  
  145. /*
  146.  * getpwent - get a password entry from the password file
  147.  *
  148.  * getpwent() opens the password file, if not already opened, and reads
  149.  * a single entry.  NULL is returned if any errors are encountered reading
  150.  * the password file.
  151.  */
  152.  
  153. struct    passwd    *getpwent ()
  154. {
  155.     if (! pwdfp && setpwent ())
  156.         return 0;
  157.  
  158.     return fgetpwent (pwdfp);
  159. }
  160.  
  161. /*
  162.  * getpwuid - locate the password entry for a given UID
  163.  *
  164.  * getpwuid() locates the first password file entry for the given UID.
  165.  * If there is a valid DBM file, the DBM files are queried first for
  166.  * the entry.  Otherwise, a linear search is begun of the password file
  167.  * searching for an entry which matches the provided UID.
  168.  */
  169.  
  170. struct    passwd    *getpwuid (uid)
  171. int    uid;
  172. {
  173.     struct    passwd    *pwd;
  174. #ifdef    DBM
  175.     datum    key;
  176.     datum    content;
  177.  
  178.     /*
  179.      * Attempt to open the DBM files if they have never been opened
  180.      * and an error has never been returned.
  181.      */
  182.  
  183.     if (! dbmerror && ! dbmopened) {
  184.         char    dbmfiles[BUFSIZ];
  185.  
  186.         strcpy (dbmfiles, pwdfile);
  187.         strcat (dbmfiles, ".pag");
  188.  
  189.         if (access (dbmfiles, 0) || dbminit (pwdfile))
  190.             dbmerror = 1;
  191.         else
  192.             dbmopened = 1;
  193.     }
  194.  
  195.     /*
  196.      * If the DBM file are now open, create a key for this UID and
  197.      * try to fetch the entry from the database.  A matching record
  198.      * will be unpacked into a static structure and returned to
  199.      * the user.
  200.      */
  201.  
  202.     if (dbmopened) {
  203.         pwent.pw_uid = uid;
  204.         key.dsize = sizeof pwent.pw_uid;
  205.         key.dptr = (char *) &pwent.pw_uid;
  206.         content = fetch (key);
  207.         if (content.dptr != 0) {
  208.             memcpy (pwdbuf, content.dptr, content.dsize);
  209.             pw_unpack (pwdbuf, content.dsize, &pwent);
  210.             return &pwent;
  211.         }
  212.     }
  213. #endif
  214.     /*
  215.      * Rewind the database and begin searching for an entry which
  216.      * matches the UID.  Return the entry when a match is found.
  217.      */
  218.  
  219.     if (setpwent ())
  220.         return 0;
  221.  
  222.     while (pwd = getpwent ())
  223.         if (pwd->pw_uid == uid)
  224.             return pwd;
  225.  
  226.     return 0;
  227. }
  228.  
  229. struct    passwd    *getpwnam (name)
  230. char    *name;
  231. {
  232.     struct    passwd    *pwd;
  233. #ifdef    DBM
  234.     datum    key;
  235.     datum    content;
  236.  
  237.     /*
  238.      * Attempt to open the DBM files if they have never been opened
  239.      * and an error has never been returned.
  240.      */
  241.  
  242.     if (! dbmerror && ! dbmopened) {
  243.         char    dbmfiles[BUFSIZ];
  244.  
  245.         strcpy (dbmfiles, pwdfile);
  246.         strcat (dbmfiles, ".pag");
  247.  
  248.         if (access (dbmfiles, 0) || dbminit (pwdfile))
  249.             dbmerror = 1;
  250.         else
  251.             dbmopened = 1;
  252.     }
  253.  
  254.     /*
  255.      * If the DBM file are now open, create a key for this UID and
  256.      * try to fetch the entry from the database.  A matching record
  257.      * will be unpacked into a static structure and returned to
  258.      * the user.
  259.      */
  260.  
  261.     if (dbmopened) {
  262.         key.dsize = strlen (name);
  263.         key.dptr = name;
  264.         content = fetch (key);
  265.         if (content.dptr != 0) {
  266.             memcpy (pwdbuf, content.dptr, content.dsize);
  267.             pw_unpack (pwdbuf, content.dsize, &pwent);
  268.             return &pwent;
  269.         }
  270.     }
  271. #endif
  272.     /*
  273.      * Rewind the database and begin searching for an entry which
  274.      * matches the name.  Return the entry when a match is found.
  275.      */
  276.  
  277.     if (setpwent ())
  278.         return 0;
  279.  
  280.     while (pwd = getpwent ())
  281.         if (strcmp (pwd->pw_name, name) == 0)
  282.             return pwd;
  283.  
  284.     return 0;
  285. }
  286.  
  287. /*
  288.  * setpwent - open the password file
  289.  *
  290.  * setpwent() opens the system password file, and the DBM password files
  291.  * if they are present.  The system password file is rewound if it was
  292.  * open already.
  293.  */
  294.  
  295. int    setpwent ()
  296. {
  297.     if (! pwdfp) {
  298.         if (! (pwdfp = fopen (pwdfile, "r")))
  299.             return -1;
  300.     } else {
  301.         if (fseek (pwdfp, 0L, 0) != 0)
  302.             return -1;
  303.     }
  304. #ifdef    DBM
  305.     /*
  306.      * Attempt to open the DBM files if they have never been opened
  307.      * and an error has never been returned.
  308.      */
  309.  
  310.     if (! dbmerror && ! dbmopened) {
  311.         char    dbmfiles[BUFSIZ];
  312.  
  313.         strcpy (dbmfiles, pwdfile);
  314.         strcat (dbmfiles, ".pag");
  315.  
  316.         if (access (dbmfiles, 0) || dbminit (pwdfile))
  317.             dbmerror = 1;
  318.         else
  319.             dbmopened = 1;
  320.     }
  321. #endif
  322.     return 0;
  323. }
  324. #endif
  325.