home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2286 / mkpasswd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-28  |  6.4 KB  |  291 lines

  1. /*
  2.  * Copyright 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 "config.h"
  14. #include <stdio.h>
  15. #include <fcntl.h>
  16. #include <pwd.h>
  17. #ifdef    BSD
  18. #include <strings.h>
  19. #else
  20. #include <string.h>
  21. #endif
  22.  
  23. #if !defined(DBM)
  24. #error "What you are trying to do?  You have to have a DBM of some kind ..."
  25. #endif
  26.  
  27. #ifdef    DBM
  28. #include <dbm.h>
  29. #endif
  30.  
  31. #ifndef    lint
  32. static    char    sccsid[] = "@(#)mkpasswd.c    2.3    08:56:25    11/5/90";
  33. static    char    copyright[] = "Copyright 1990, John F. Haugh II";
  34. #endif
  35.  
  36. char    *CANT_OPEN =    "%s: cannot open file %s\n";
  37. char    *CANT_OVERWRITE = "%s: cannot overwrite file %s\n";
  38. char    *CANT_CREATE =    "%s: cannot create %s\n";
  39. char    *DBM_OPEN_ERR =    "%s: cannot open DBM files for %s\n";
  40. char    *PARSE_ERR =    "%s: error parsing line\n\"%s\"\n";
  41. char    *LINE_TOO_LONG = "%s: the beginning with \"%.16s ...\" is too long\n";
  42. char    *ADD_NAME =    "adding key for name \"%s\"\n";
  43. char    *ADD_NAME_ERR =    "%s: error adding entry for \"%s\"\n";
  44. char    *ADD_UID =    "adding key for uid %d, name \"%s\"\n";
  45. char    *ADD_UID_ERR =    "%s: error adding entry for uid %d, name \"%s\"\n";
  46. char    *INFO =        "added %d entries, longest was %d\n";
  47. char    *USAGE =    "Usage: %s [ -v ] [ -f ] file\n";
  48.  
  49. char    *Progname;
  50. int    vflg = 0;
  51. int    fflg = 0;
  52.  
  53. void    usage();
  54.  
  55. extern    char    *malloc();
  56. extern    struct    passwd    *sgetpwent();
  57.  
  58. /*
  59.  * mkpasswd - create DBM files for /etc/passwd-like input file
  60.  *
  61.  * mkpasswd takes an an argument the name of a file in /etc/passwd format
  62.  * and creates a DBM file keyed by user ID and name.  The output files have
  63.  * the same name as the input file, with .dir and .pag appended.
  64.  */
  65.  
  66. int
  67. main (argc, argv)
  68. int    argc;
  69. char    **argv;
  70. {
  71.     extern    int    optind;
  72.     extern    char    *optarg;
  73.     FILE    *pwfp;            /* File pointer for password file     */
  74.     char    *pwfile;        /* Name of password file              */
  75.     char    *pwdir;            /* Name of .dir file                  */
  76.     char    *pwpag;            /* Name of .pag file                  */
  77.     char    *cp;            /* Temporary character pointer        */
  78.     int    flag;            /* Flag for command line option       */
  79.     int    fd;            /* File descriptor of open DBM file   */
  80.     int    cnt = 0;        /* Number of entries in database      */
  81.     int    longest = 0;        /* Longest entry in database          */
  82.     int    errors = 0;        /* Count of errors processing file    */
  83.     char    buf[BUFSIZ];        /* Input line from password file      */
  84.     char    dbmbuf[BUFSIZ];        /* Place to build DBM record          */
  85.     struct    passwd    *passwd;    /* Pointer to password file entry     */
  86.     datum    key;            /* Info for DBM key data              */
  87.     datum    content;        /* Info for DBM record data           */
  88.  
  89.     /*
  90.      * Figure out what my name is.  I will use this later ...
  91.      */
  92.  
  93.     if (Progname = strrchr (argv[0], '/'))
  94.         Progname++;
  95.     else
  96.         Progname = argv[0];
  97.  
  98.     /*
  99.      * Figure out what the flags might be ...
  100.      */
  101.  
  102.     while ((flag = getopt (argc, argv, "fv")) != EOF) {
  103.         switch (flag) {
  104.             case 'v':
  105.                 vflg++;
  106.                 break;
  107.             case 'f':
  108.                 fflg++;
  109.                 break;
  110.             default:
  111.                 usage ();
  112.         }
  113.     }
  114.  
  115.     /*
  116.      * The last and only remaining argument must be the file name
  117.      */
  118.  
  119.     if (argc - 1 != optind)
  120.         usage ();
  121.  
  122.     pwfile = argv[optind];
  123.  
  124.     if (! (pwfp = fopen (pwfile, "r"))) {
  125.         fprintf (stderr, CANT_OPEN, Progname, pwfile);
  126.         exit (1);
  127.     }
  128.  
  129.     /*
  130.      * Make the filenames for the two DBM files.
  131.      */
  132.  
  133.     pwdir = malloc (strlen (pwfile) + 5);    /* space for .dir file */
  134.     strcat (strcpy (pwdir, pwfile), ".dir");
  135.  
  136.     pwpag = malloc (strlen (pwfile) + 5);    /* space for .pag file */
  137.     strcat (strcpy (pwpag, pwfile), ".pag");
  138.  
  139.     /*
  140.      * Remove existing files if requested.
  141.      */
  142.  
  143.     if (fflg) {
  144.         (void) unlink (pwdir);
  145.         (void) unlink (pwpag);
  146.     }
  147.  
  148.     /*
  149.      * Create the two DBM files - it is an error for these files
  150.      * to have existed already.
  151.      */
  152.  
  153.     if (access (pwdir, 0) == 0) {
  154.         fprintf (stderr, CANT_OVERWRITE, Progname, pwdir);
  155.         exit (1);
  156.     }
  157.     if (access (pwpag, 0) == 0) {
  158.         fprintf (stderr, CANT_OVERWRITE, Progname, pwpag);
  159.         exit (1);
  160.     }
  161.  
  162.     umask (0);
  163.     if ((fd = open (pwdir, O_RDWR|O_CREAT|O_EXCL, 0644)) == -1) {
  164.         fprintf (stderr, CANT_CREATE, Progname, pwdir);
  165.         exit (1);
  166.     } else
  167.         close (fd);
  168.  
  169.     if ((fd = open (pwpag, O_RDWR|O_CREAT|O_EXCL, 0644)) == -1) {
  170.         fprintf (stderr, CANT_CREATE, Progname, pwpag);
  171.         unlink (pwdir);
  172.         exit (1);
  173.     } else
  174.         close (fd);
  175.  
  176.     /*
  177.      * Now the DBM database gets initialized
  178.      */
  179.  
  180. #ifdef    DBM
  181.     if (dbminit (pwfile) == -1) {
  182.         fprintf (stderr, DBM_OPEN_ERR, Progname, pwfile);
  183.         exit (1);
  184.     }
  185. #endif
  186.  
  187.     /*
  188.      * Read every line in the password file and convert it into a
  189.      * data structure to be put in the DBM database files.
  190.      */
  191.  
  192.     while (fgets (buf, BUFSIZ, pwfp) != NULL) {
  193.  
  194.         /*
  195.          * Get the next line and strip off the trailing newline
  196.          * character.  Very long lines are fatal errors.
  197.          */
  198.  
  199.         buf[BUFSIZ-1] = '\0';
  200.         if (! (cp = strchr (buf, '\n'))) {
  201.             fprintf (stderr, LINE_TOO_LONG, Progname, buf);
  202.             exit (1);
  203.         }
  204.         *cp = '\0';
  205.  
  206.         /*
  207.          * Parse the password file line into a (struct passwd).
  208.          * Erroneous lines cause error messages, but that's
  209.          * all.  YP lines are ignored completely.
  210.          */
  211.  
  212.         if (buf[0] == '-' || buf[0] == '+')
  213.             continue;
  214.  
  215.         if (! (passwd = sgetpwent (buf))) {
  216.             fprintf (stderr, PARSE_ERR, Progname, buf);
  217.             errors++;
  218.             continue;
  219.         }
  220.  
  221.         /*
  222.          * Pack the (struct passwd) into a buffer and build
  223.          * the content structure for the DBM.
  224.          */
  225.  
  226.         content.dsize = pw_pack (passwd, dbmbuf);
  227.         content.dptr = dbmbuf;
  228.  
  229.         /*
  230.          * Store the record using the name as the key
  231.          */
  232.  
  233.         key.dsize = strlen (passwd->pw_name);
  234.         key.dptr = passwd->pw_name;
  235.         if (vflg)
  236.             printf (ADD_NAME, passwd->pw_name);
  237. #ifdef    DBM
  238.         if (store (key, content)) {
  239.             fprintf (stderr, ADD_NAME_ERR, Progname,
  240.                     passwd->pw_name);
  241.             errors++;
  242.         }
  243. #endif
  244.  
  245.         /*
  246.          * Store the record using the UID as the key
  247.          */
  248.  
  249.         key.dsize = sizeof passwd->pw_uid;
  250.         key.dptr = (char *) &passwd->pw_uid;
  251.         if (vflg)
  252.             printf (ADD_UID, passwd->pw_uid, passwd->pw_name);
  253. #ifdef    DBM
  254.         if (store (key, content)) {
  255.             fprintf (stderr, ADD_UID_ERR, Progname,
  256.                     passwd->pw_uid, passwd->pw_name);
  257.             errors++;
  258.         }
  259. #endif
  260.         /*
  261.          * Update the longest record and record count
  262.          */
  263.  
  264.         if (content.dsize > longest)
  265.             longest = content.dsize;
  266.         cnt++;
  267.     }
  268.  
  269.     /*
  270.      * Tell the user how things went ...
  271.      */
  272.  
  273.     if (vflg)
  274.         printf (INFO, cnt, longest);
  275.  
  276.     exit (errors);
  277.     /*NOTREACHED*/
  278. }
  279.  
  280. /*
  281.  * usage - print error message and exit
  282.  */
  283.  
  284. void
  285. usage ()
  286. {
  287.     fprintf (stderr, USAGE, Progname);
  288.     exit (1);
  289.     /*NOTREACHED*/
  290. }
  291.