home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1990, John F. Haugh II
- * All rights reserved.
- *
- * Use, duplication, and disclosure prohibited without
- * the express written permission of the author.
- *
- * Duplication is permitted for non-commercial [ profit making ]
- * purposes provided this and other copyright notices remain
- * intact.
- */
-
- #include "config.h"
- #include <stdio.h>
- #include <fcntl.h>
- #include <pwd.h>
- #ifdef BSD
- #include <strings.h>
- #else
- #include <string.h>
- #endif
-
- #if !defined(DBM)
- #error "What you are trying to do? You have to have a DBM of some kind ..."
- #endif
-
- #ifdef DBM
- #include <dbm.h>
- #endif
-
- #ifndef lint
- static char sccsid[] = "@(#)mkpasswd.c 2.3 08:56:25 11/5/90";
- static char copyright[] = "Copyright 1990, John F. Haugh II";
- #endif
-
- char *CANT_OPEN = "%s: cannot open file %s\n";
- char *CANT_OVERWRITE = "%s: cannot overwrite file %s\n";
- char *CANT_CREATE = "%s: cannot create %s\n";
- char *DBM_OPEN_ERR = "%s: cannot open DBM files for %s\n";
- char *PARSE_ERR = "%s: error parsing line\n\"%s\"\n";
- char *LINE_TOO_LONG = "%s: the beginning with \"%.16s ...\" is too long\n";
- char *ADD_NAME = "adding key for name \"%s\"\n";
- char *ADD_NAME_ERR = "%s: error adding entry for \"%s\"\n";
- char *ADD_UID = "adding key for uid %d, name \"%s\"\n";
- char *ADD_UID_ERR = "%s: error adding entry for uid %d, name \"%s\"\n";
- char *INFO = "added %d entries, longest was %d\n";
- char *USAGE = "Usage: %s [ -v ] [ -f ] file\n";
-
- char *Progname;
- int vflg = 0;
- int fflg = 0;
-
- void usage();
-
- extern char *malloc();
- extern struct passwd *sgetpwent();
-
- /*
- * mkpasswd - create DBM files for /etc/passwd-like input file
- *
- * mkpasswd takes an an argument the name of a file in /etc/passwd format
- * and creates a DBM file keyed by user ID and name. The output files have
- * the same name as the input file, with .dir and .pag appended.
- */
-
- int
- main (argc, argv)
- int argc;
- char **argv;
- {
- extern int optind;
- extern char *optarg;
- FILE *pwfp; /* File pointer for password file */
- char *pwfile; /* Name of password file */
- char *pwdir; /* Name of .dir file */
- char *pwpag; /* Name of .pag file */
- char *cp; /* Temporary character pointer */
- int flag; /* Flag for command line option */
- int fd; /* File descriptor of open DBM file */
- int cnt = 0; /* Number of entries in database */
- int longest = 0; /* Longest entry in database */
- int errors = 0; /* Count of errors processing file */
- char buf[BUFSIZ]; /* Input line from password file */
- char dbmbuf[BUFSIZ]; /* Place to build DBM record */
- struct passwd *passwd; /* Pointer to password file entry */
- datum key; /* Info for DBM key data */
- datum content; /* Info for DBM record data */
-
- /*
- * Figure out what my name is. I will use this later ...
- */
-
- if (Progname = strrchr (argv[0], '/'))
- Progname++;
- else
- Progname = argv[0];
-
- /*
- * Figure out what the flags might be ...
- */
-
- while ((flag = getopt (argc, argv, "fv")) != EOF) {
- switch (flag) {
- case 'v':
- vflg++;
- break;
- case 'f':
- fflg++;
- break;
- default:
- usage ();
- }
- }
-
- /*
- * The last and only remaining argument must be the file name
- */
-
- if (argc - 1 != optind)
- usage ();
-
- pwfile = argv[optind];
-
- if (! (pwfp = fopen (pwfile, "r"))) {
- fprintf (stderr, CANT_OPEN, Progname, pwfile);
- exit (1);
- }
-
- /*
- * Make the filenames for the two DBM files.
- */
-
- pwdir = malloc (strlen (pwfile) + 5); /* space for .dir file */
- strcat (strcpy (pwdir, pwfile), ".dir");
-
- pwpag = malloc (strlen (pwfile) + 5); /* space for .pag file */
- strcat (strcpy (pwpag, pwfile), ".pag");
-
- /*
- * Remove existing files if requested.
- */
-
- if (fflg) {
- (void) unlink (pwdir);
- (void) unlink (pwpag);
- }
-
- /*
- * Create the two DBM files - it is an error for these files
- * to have existed already.
- */
-
- if (access (pwdir, 0) == 0) {
- fprintf (stderr, CANT_OVERWRITE, Progname, pwdir);
- exit (1);
- }
- if (access (pwpag, 0) == 0) {
- fprintf (stderr, CANT_OVERWRITE, Progname, pwpag);
- exit (1);
- }
-
- umask (0);
- if ((fd = open (pwdir, O_RDWR|O_CREAT|O_EXCL, 0644)) == -1) {
- fprintf (stderr, CANT_CREATE, Progname, pwdir);
- exit (1);
- } else
- close (fd);
-
- if ((fd = open (pwpag, O_RDWR|O_CREAT|O_EXCL, 0644)) == -1) {
- fprintf (stderr, CANT_CREATE, Progname, pwpag);
- unlink (pwdir);
- exit (1);
- } else
- close (fd);
-
- /*
- * Now the DBM database gets initialized
- */
-
- #ifdef DBM
- if (dbminit (pwfile) == -1) {
- fprintf (stderr, DBM_OPEN_ERR, Progname, pwfile);
- exit (1);
- }
- #endif
-
- /*
- * Read every line in the password file and convert it into a
- * data structure to be put in the DBM database files.
- */
-
- while (fgets (buf, BUFSIZ, pwfp) != NULL) {
-
- /*
- * Get the next line and strip off the trailing newline
- * character. Very long lines are fatal errors.
- */
-
- buf[BUFSIZ-1] = '\0';
- if (! (cp = strchr (buf, '\n'))) {
- fprintf (stderr, LINE_TOO_LONG, Progname, buf);
- exit (1);
- }
- *cp = '\0';
-
- /*
- * Parse the password file line into a (struct passwd).
- * Erroneous lines cause error messages, but that's
- * all. YP lines are ignored completely.
- */
-
- if (buf[0] == '-' || buf[0] == '+')
- continue;
-
- if (! (passwd = sgetpwent (buf))) {
- fprintf (stderr, PARSE_ERR, Progname, buf);
- errors++;
- continue;
- }
-
- /*
- * Pack the (struct passwd) into a buffer and build
- * the content structure for the DBM.
- */
-
- content.dsize = pw_pack (passwd, dbmbuf);
- content.dptr = dbmbuf;
-
- /*
- * Store the record using the name as the key
- */
-
- key.dsize = strlen (passwd->pw_name);
- key.dptr = passwd->pw_name;
- if (vflg)
- printf (ADD_NAME, passwd->pw_name);
- #ifdef DBM
- if (store (key, content)) {
- fprintf (stderr, ADD_NAME_ERR, Progname,
- passwd->pw_name);
- errors++;
- }
- #endif
-
- /*
- * Store the record using the UID as the key
- */
-
- key.dsize = sizeof passwd->pw_uid;
- key.dptr = (char *) &passwd->pw_uid;
- if (vflg)
- printf (ADD_UID, passwd->pw_uid, passwd->pw_name);
- #ifdef DBM
- if (store (key, content)) {
- fprintf (stderr, ADD_UID_ERR, Progname,
- passwd->pw_uid, passwd->pw_name);
- errors++;
- }
- #endif
- /*
- * Update the longest record and record count
- */
-
- if (content.dsize > longest)
- longest = content.dsize;
- cnt++;
- }
-
- /*
- * Tell the user how things went ...
- */
-
- if (vflg)
- printf (INFO, cnt, longest);
-
- exit (errors);
- /*NOTREACHED*/
- }
-
- /*
- * usage - print error message and exit
- */
-
- void
- usage ()
- {
- fprintf (stderr, USAGE, Progname);
- exit (1);
- /*NOTREACHED*/
- }
-