Thu Jun 18 21:59:24 2009 UTC ()
remove duplicated code by merging the insecure and secure database handling.
add warning flag.


(christos)
diff -r1.24 -r1.25 src/usr.sbin/pwd_mkdb/pwd_mkdb.8
diff -r1.41 -r1.42 src/usr.sbin/pwd_mkdb/pwd_mkdb.c

cvs diff -r1.24 -r1.25 src/usr.sbin/pwd_mkdb/pwd_mkdb.8 (expand / switch to context diff)
--- src/usr.sbin/pwd_mkdb/pwd_mkdb.8 2009/06/18 17:46:24 1.24
+++ src/usr.sbin/pwd_mkdb/pwd_mkdb.8 2009/06/18 21:59:24 1.25
@@ -1,4 +1,4 @@
-.\"	$NetBSD: pwd_mkdb.8,v 1.24 2009/06/18 17:46:24 christos Exp $
+.\"	$NetBSD: pwd_mkdb.8,v 1.25 2009/06/18 21:59:24 christos Exp $
 .\"
 .\" Copyright (c) 1991, 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -37,7 +37,7 @@
 .Nd generate the password databases
 .Sh SYNOPSIS
 .Nm
-.Op Fl BLpsv
+.Op Fl BLpsvw
 .Op Fl c Ar cachesize
 .Op Fl d Ar directory
 .Op Fl u Ar username
@@ -123,6 +123,8 @@
 was run.
 .It Fl v
 Mention when a version change occurs.
+.It Fl w
+Print a warning if the system is using old style databases.
 .El
 .Pp
 The two databases differ in that the secure version contains the user's

cvs diff -r1.41 -r1.42 src/usr.sbin/pwd_mkdb/pwd_mkdb.c (expand / switch to context diff)
--- src/usr.sbin/pwd_mkdb/pwd_mkdb.c 2009/06/18 17:46:24 1.41
+++ src/usr.sbin/pwd_mkdb/pwd_mkdb.c 2009/06/18 21:59:24 1.42
@@ -1,4 +1,4 @@
-/*	$NetBSD: pwd_mkdb.c,v 1.41 2009/06/18 17:46:24 christos Exp $	*/
+/*	$NetBSD: pwd_mkdb.c,v 1.42 2009/06/18 21:59:24 christos Exp $	*/
 
 /*
  * Copyright (c) 2000, 2009 The NetBSD Foundation, Inc.
@@ -91,7 +91,7 @@
   Copyright (c) 1991, 1993, 1994\
  The Regents of the University of California.  All rights reserved.");
 __SCCSID("from: @(#)pwd_mkdb.c	8.5 (Berkeley) 4/20/94");
-__RCSID("$NetBSD: pwd_mkdb.c,v 1.41 2009/06/18 17:46:24 christos Exp $");
+__RCSID("$NetBSD: pwd_mkdb.c,v 1.42 2009/06/18 21:59:24 christos Exp $");
 #endif /* not lint */
 
 #if HAVE_NBTOOL_CONFIG_H
@@ -146,53 +146,116 @@
 #define	FILE_SECURE	0x02
 #define	FILE_ORIG	0x04
 
+
+struct pwddb {
+	DB *db;
+	char dbname[MAX(MAXPATHLEN, LINE_MAX * 2)];
+	const char *fname;
+	uint32_t rversion;
+	uint32_t wversion;
+};
+
 static char	*pname;				/* password file name */
 static char	prefix[MAXPATHLEN];
 static char	oldpwdfile[MAX(MAXPATHLEN, LINE_MAX * 2)];
-static char	pwd_db_tmp[MAX(MAXPATHLEN, LINE_MAX * 2)];
-static char	pwd_Sdb_tmp[MAX(MAXPATHLEN, LINE_MAX * 2)];
 static int 	lorder = BYTE_ORDER;
 static int	clean;
+static int	verbose;
+static int	warning;
+static struct pwddb sdb, idb;
 
+
 void	bailout(void) __attribute__((__noreturn__));
 void	cp(const char *, const char *, mode_t);
-int	deldbent(DB *, const char *, int, void *);
+int	deldbent(struct pwddb *, int, void *);
 void	error(const char *);
-int	getdbent(DB *, const char *, int, void *, struct passwd **, uint32_t);
+int	getdbent(struct pwddb *, int, void *, struct passwd **);
 void	inconsistancy(void);
 void	install(const char *, const char *);
 int	main(int, char **);
-void	putdbents(DB *, struct passwd *, const char *, int, const char *, int,
-    int, int, uint32_t);
-void	putyptoken(DB *, const char *);
+void	putdbents(struct pwddb *, struct passwd *, const char *, int, int, int,
+    int);
+void	putyptoken(struct pwddb *);
 void	rm(const char *);
 int	scan(FILE *, struct passwd *, int *, int *);
 void	usage(void) __attribute__((__noreturn__));
 void	wr_error(const char *);
-void	checkversion(uint32_t, uint32_t);
+void	checkversion(struct pwddb *);
 uint32_t getversion(const char *);
-void	setversion(DB *, uint32_t);
+void	setversion(struct pwddb *);
 
 #define SWAP(sw) \
     ((sizeof(sw) == 2 ? (typeof(sw))bswap16((uint16_t)sw) : \
     (sizeof(sw) == 4 ? (typeof(sw))bswap32((uint32_t)sw) : \
     (sizeof(sw) == 8 ? (typeof(sw))bswap64((uint64_t)sw) : (abort(), 0)))))
 
+static void
+closedb(struct pwddb *db)
+{
+    if ((*db->db->close)(db->db) < 0)
+	    wr_error(db->dbname);
+}
+
+static void
+opendb(struct pwddb *db, const char *dbname, const char *username,
+    uint32_t req_version, int flags, int perm)
+{
+	char buf[MAXPATHLEN];
+
+	(void)snprintf(db->dbname, sizeof(db->dbname), "%s%s.tmp", prefix,
+	    dbname);
+
+	if (username != NULL) {
+		snprintf(buf, sizeof(buf), "%s%s", prefix, dbname);
+		cp(buf, db->dbname, perm);
+	}
+
+	db->db = dbopen(db->dbname, flags, perm, DB_HASH, &openinfo);
+	if (db->db == NULL)
+		error(db->dbname);
+
+	db->fname = dbname;
+	db->rversion = getversion(dbname);
+	if (req_version == ~0U)
+		db->wversion = db->rversion;
+	else
+		db->wversion = req_version;
+
+	if (warning && db->rversion == 0 && db->wversion == 0) {
+		warnx("Database %s is a version %u database.",
+		    db->fname, db->rversion);
+		warnx("Use %s -V 1 to upgrade once you've recompiled "
+		    "all your binaries.", getprogname());
+	}
+	if (verbose)
+		fprintf(stderr, "%s: %s version %u requested %u\n",
+		    getprogname(), db->fname, db->rversion, db->wversion);
+
+	if (db->wversion != db->rversion) {
+		if (username != NULL)
+			checkversion(db);
+		else if (verbose) {
+		    fprintf(stderr, "%s: changing %s from version "
+			"%u to version %u\n",
+			getprogname(), db->fname,
+			db->rversion, db->wversion);
+		}
+	}
+	setversion(db);
+}
+
 int
 main(int argc, char *argv[])
 {
-	int ch, makeold, tfd, lineno, found, rv, hasyp, secureonly, verbose;
+	int ch, makeold, tfd, lineno, found, rv, hasyp, secureonly;
 	struct passwd pwd, *tpwd;
 	char *username;
-	DB *dp, *edp;
 	FILE *fp, *oldfp;
 	sigset_t set;
 	int dbflg, uid_dbflg, newuser, olduid, flags;
-	char buf[MAXPATHLEN];
 	struct stat st;
 	u_int cachesize;
-	uint32_t version, req_version;
-	uint32_t sversion, req_sversion;
+	uint32_t req_version;
 
 	prefix[0] = '\0';
 	makeold = 0;
@@ -202,12 +265,12 @@
 	secureonly = 0;
 	found = 0;
 	newuser = 0;
-	dp = NULL;
 	cachesize = 0;
 	verbose = 0;
-	req_version = req_sversion = ~0U;
+	warning = 0;
+	req_version = ~0U;
 
-	while ((ch = getopt(argc, argv, "BLc:d:psu:V:v")) != -1)
+	while ((ch = getopt(argc, argv, "BLc:d:psu:V:vw")) != -1)
 		switch (ch) {
 		case 'B':			/* big-endian output */
 			lorder = BIG_ENDIAN;
@@ -231,13 +294,16 @@
 			username = optarg;
 			break;
 		case 'V':
-			req_sversion = req_version = (uint32_t)atoi(optarg);
+			req_version = (uint32_t)atoi(optarg);
 			if (req_version > 1)
 				err(1, "Unknown version %u\n", req_version);
 			break;
 		case 'v':
 			verbose++;
 			break;
+		case 'w':
+			warning++;
+			break;
 		case '?':
 		default:
 			usage();
@@ -297,62 +363,15 @@
 
 	/* Open the temporary insecure password database. */
 	if (!secureonly) {
-		(void)snprintf(pwd_db_tmp, sizeof(pwd_db_tmp), "%s%s.tmp",
-		    prefix, _PATH_MP_DB);
-		if (username != NULL) {
-			snprintf(buf, sizeof(buf), "%s" _PATH_MP_DB, prefix);
-			cp(buf, pwd_db_tmp, PERM_INSECURE);
-		}
-		dp = dbopen(pwd_db_tmp, flags, PERM_INSECURE, DB_HASH,
-		    &openinfo);
-		if (dp == NULL)
-			error(pwd_db_tmp);
+		opendb(&idb, _PATH_MP_DB, username, req_version,
+		    flags, PERM_INSECURE);
 		clean |= FILE_INSECURE;
-		version = getversion(_PATH_MP_DB);
-		if (req_version == ~0U)
-			req_version = version;
-		if (verbose)
-			fprintf(stderr, "%s: " _PATH_MP_DB
-			    " version %u requested %u\n",
-			    getprogname(), version, req_version);
-		if (username != NULL && req_version != version)
-			checkversion(req_version, version);
-		else if (req_version != version) {
-			if (verbose)
-				fprintf(stderr, "%s: changing " _PATH_MP_DB
-				    " from version %u to version %u\n",
-				    getprogname(), version, req_version);
-			setversion(dp, req_version);
-		}
 	}
+		 
 
 	/* Open the temporary encrypted password database. */
-	(void)snprintf(pwd_Sdb_tmp, sizeof(pwd_Sdb_tmp), "%s%s.tmp", prefix,
-		_PATH_SMP_DB);
-	if (username != NULL) {
-		snprintf(buf, sizeof(buf), "%s" _PATH_SMP_DB, prefix);
-		cp(buf, pwd_Sdb_tmp, PERM_SECURE);
-	}
-	edp = dbopen(pwd_Sdb_tmp, flags, PERM_SECURE, DB_HASH, &openinfo);
-	if (!edp)
-		error(pwd_Sdb_tmp);
+	opendb(&sdb, _PATH_SMP_DB, username, req_version, flags, PERM_SECURE);
 	clean |= FILE_SECURE;
-	sversion = getversion(_PATH_SMP_DB);
-	if (verbose)
-		fprintf(stderr, "%s: " _PATH_SMP_DB
-		    " version %u requested %u\n",
-		    getprogname(), sversion, req_version);
-	if (req_sversion == ~0U)
-		req_sversion = sversion;
-	if (username != NULL)
-		checkversion(req_sversion, sversion);
-	else if (req_sversion != sversion) {
-		if (verbose)
-			fprintf(stderr, "%s: changing " _PATH_SMP_DB
-			    " from version %u to version %u\n",
-			    getprogname(), sversion, req_sversion);
-		setversion(edp, req_sversion);
-	}
 
 	/*
 	 * Open file for old password file.  Minor trickiness -- don't want to
@@ -379,8 +398,7 @@
 		/*
 		 * Determine if this is a new entry.
 		 */
-		if (getdbent(edp, pwd_Sdb_tmp, _PW_KEYBYNAME, username, &tpwd,
-		    sversion))
+		if (getdbent(&sdb, _PW_KEYBYNAME, username, &tpwd))
 			newuser = 1;
 		else {
 			newuser = 0;
@@ -428,8 +446,8 @@
 
 			/* Write the database entry out. */
 			if (!secureonly)
-				putdbents(dp, &pwd, "*", flags, pwd_db_tmp,
-				    lineno, dbflg, uid_dbflg, req_version);
+				putdbents(&idb, &pwd, "*", flags, lineno, dbflg,
+				    uid_dbflg);
 			continue;
 		} else if (strcmp(username, pwd.pw_name) != 0)
 			continue;
@@ -444,8 +462,7 @@
 		 * Ensure that the text file and database agree on
 		 * which line the record is from.
 		 */
-		rv = getdbent(edp, pwd_Sdb_tmp, _PW_KEYBYNUM, &lineno, &tpwd,
-		    sversion);
+		rv = getdbent(&sdb, _PW_KEYBYNUM, &lineno, &tpwd);
 		if (newuser) {
 			if (rv == 0)
 				inconsistancy();
@@ -458,14 +475,12 @@
 			 * record for the old UID only if it has the
 			 * same username.
 			 */
-			if (!getdbent(edp, pwd_Sdb_tmp, _PW_KEYBYUID, &olduid,
-			    &tpwd, sversion)) {
+			if (!getdbent(&sdb, _PW_KEYBYUID, &olduid, &tpwd)) {
 				if (strcmp(username, tpwd->pw_name) == 0) {
 					if (!secureonly)
-						deldbent(dp, pwd_db_tmp,
-						    _PW_KEYBYUID, &olduid);
-					deldbent(edp, pwd_Sdb_tmp,
-					    _PW_KEYBYUID, &olduid);
+						deldbent(&idb, _PW_KEYBYUID,
+						    &olduid);
+					deldbent(&sdb, _PW_KEYBYUID, &olduid);
 				}
 			} else
 				inconsistancy();
@@ -476,17 +491,16 @@
 		 * the username doesn't match then be sure not to overwrite
 		 * it.
 		 */
-		if (!getdbent(edp, pwd_Sdb_tmp, _PW_KEYBYUID, &pwd.pw_uid,
-		    &tpwd, sversion))
+		if (!getdbent(&sdb, _PW_KEYBYUID, &pwd.pw_uid, &tpwd))
 			if (strcmp(username, tpwd->pw_name) != 0)
 				uid_dbflg = R_NOOVERWRITE;
 
 		/* Write the database entries out */
 		if (!secureonly)
-			putdbents(dp, &pwd, "*", flags, pwd_db_tmp, lineno,
-			    dbflg, uid_dbflg, req_version);
-		putdbents(edp, &pwd, pwd.pw_passwd, flags, pwd_Sdb_tmp,
-		    lineno, dbflg, uid_dbflg, req_sversion);
+			putdbents(&idb, &pwd, "*", flags, lineno, dbflg,
+			    uid_dbflg);
+		putdbents(&sdb, &pwd, pwd.pw_passwd, flags, lineno, dbflg,
+		    uid_dbflg);
 
 		found = 1;
 		if (!makeold)
@@ -496,11 +510,10 @@
 	if (!secureonly) {
 		/* Store YP token if needed. */
 		if (hasyp)
-			putyptoken(dp, pwd_db_tmp);
+			putyptoken(&idb);
 
 		/* Close the insecure database. */
-		if ((*dp->close)(dp) < 0)
-			wr_error(pwd_db_tmp);
+		closedb(&idb);
 	}
 
 	/*
@@ -510,25 +523,24 @@
 	if (username == NULL) {
 		rewind(fp);
 		for (lineno = 0; scan(fp, &pwd, &flags, &lineno);)
-			putdbents(edp, &pwd, pwd.pw_passwd, flags, pwd_Sdb_tmp,
-			    lineno, dbflg, uid_dbflg, req_sversion);
+			putdbents(&sdb, &pwd, pwd.pw_passwd, flags,
+			    lineno, dbflg, uid_dbflg);
 
 		/* Store YP token if needed. */
 		if (hasyp)
-			putyptoken(edp, pwd_Sdb_tmp);
+			putyptoken(&sdb);
 	} else if (!found) {
 		warnx("user `%s' not found in password file", username);
 		bailout();
 	}
 
 	/* Close the secure database. */
-	if ((*edp->close)(edp) < 0)
-		wr_error(pwd_Sdb_tmp);
+	closedb(&sdb);
 
 	/* Install as the real password files. */
 	if (!secureonly)
-		install(pwd_db_tmp, _PATH_MP_DB);
-	install(pwd_Sdb_tmp, _PATH_SMP_DB);
+		install(idb.dbname, idb.fname);
+	install(sdb.dbname, sdb.fname);
 
 	/* Install the V7 password file. */
 	if (makeold) {
@@ -682,9 +694,9 @@
 	if ((clean & FILE_ORIG) != 0)
 		rm(oldpwdfile);
 	if ((clean & FILE_SECURE) != 0)
-		rm(pwd_Sdb_tmp);
+		rm(sdb.dbname);
 	if ((clean & FILE_INSECURE) != 0)
-		rm(pwd_db_tmp);
+		rm(idb.dbname);
 
 	exit(EXIT_FAILURE);
 }
@@ -695,17 +707,17 @@
 	DBT data, key;
 	int ret;
 	uint32_t version = 0;
-	DB *dp;
+	DB *db;
 
-	dp = dbopen(fname, O_RDONLY, PERM_INSECURE, DB_HASH, NULL);
-	if (dp == NULL) {
+	db = dbopen(fname, O_RDONLY, PERM_INSECURE, DB_HASH, NULL);
+	if (db == NULL) {
 		warn("Cannot open database %s", fname);
 		bailout();
 	}
 	key.data = __UNCONST("VERSION");
 	key.size = strlen((const char *)key.data) + 1;
 
-	switch (ret = (*dp->get)(dp, &key, &data, 0)) {
+	switch (ret = (*db->get)(db, &key, &data, 0)) {
 	case -1:	/* Error */
 		warn("Cannot get VERSION record from database");
 		goto out;
@@ -717,37 +729,41 @@
 		memcpy(&version, data.data, sizeof(version));
 		/*FALLTHROUGH*/
 	case 1:
-		(*dp->close)(dp);
+		if (ret == 1)
+			warnx("Database %s has no version info", fname);
+		(*db->close)(db);
 		return version;
 	default:
 		warnx("internal error db->get returns %d", ret);
 		goto out;
 	}
 out:
-	(*dp->close)(dp);
+	(*db->close)(db);
 	bailout();
 }
 
 void
-setversion(DB *dp, uint32_t version)
+setversion(struct pwddb *db)
 {
 	DBT data, key;
 	key.data = __UNCONST("VERSION");
 	key.size = strlen((const char *)key.data) + 1;
 
-	data.data = &version;
+	data.data = &db->wversion;
 	data.size = sizeof(uint32_t);
 
-	if ((*dp->put)(dp, &key, &data, R_NOOVERWRITE) == -1)
-		wr_error("setversion");
+	if ((*db->db->put)(db->db, &key, &data, R_NOOVERWRITE) != 0) {
+		warn("Can't write VERSION record to %s", db->dbname);
+		bailout();
+	}
 }
 
 void
-checkversion(uint32_t req_version, uint32_t version)
+checkversion(struct pwddb *db)
 {
 	(void)fprintf(stderr, "%s: you cannot change a single "
 	    "record from version %u to version %u\n", getprogname(),
-	    version, req_version);
+	    db->rversion, db->wversion);
 	bailout();
 }
 
@@ -767,8 +783,8 @@
 #define	COMPACT(e)	for (t = e; (*p++ = *t++) != '\0';)
 
 void
-putdbents(DB *dp, struct passwd *pw, const char *passwd, int flags,
-      const char *fn, int lineno, int dbflg, int uid_dbflg, uint32_t version)
+putdbents(struct pwddb *db, struct passwd *pw, const char *passwd, int flags,
+      int lineno, int dbflg, int uid_dbflg)
 {
 	struct passwd pwd;
 	char buf[MAX(MAXPATHLEN, LINE_MAX * 2)], tbuf[1024], *p;
@@ -788,14 +804,14 @@
 
 #define WRITEPWTIMEVAR(pwvar) \
 	do { \
-		if (version == 0 && \
+		if (db->wversion == 0 && \
 		    sizeof(pwvar) == sizeof(uint64_t)) { \
 			uint32_t tmp = (uint32_t)pwvar; \
 			if (lorder != BYTE_ORDER) \
 				tmp = SWAP(tmp); \
 			memmove(p, &tmp, sizeof(tmp)); \
 			p += sizeof(tmp); \
-		} else if (version == 1 && \
+		} else if (db->wversion == 1 && \
 		    sizeof(pwvar) == sizeof(uint32_t)) { \
 			uint64_t tmp = pwvar; \
 			if (lorder != BYTE_ORDER) \
@@ -836,8 +852,8 @@
 	len = strlen(pwd.pw_name);
 	memmove(tbuf + 1, pwd.pw_name, len);
 	key.size = len + 1;
-	if ((*dp->put)(dp, &key, &data, dbflg) == -1)
-		wr_error(fn);
+	if ((*db->db->put)(db->db, &key, &data, dbflg) == -1)
+		wr_error(db->dbname);
 
 	/* Store insecure by number. */
 	tbuf[0] = _PW_KEYBYNUM;
@@ -846,19 +862,19 @@
 		x = SWAP(x);
 	memmove(tbuf + 1, &x, sizeof(x));
 	key.size = sizeof(x) + 1;
-	if ((*dp->put)(dp, &key, &data, dbflg) == -1)
-		wr_error(fn);
+	if ((*db->db->put)(db->db, &key, &data, dbflg) == -1)
+		wr_error(db->dbname);
 
 	/* Store insecure by uid. */
 	tbuf[0] = _PW_KEYBYUID;
 	memmove(tbuf + 1, &pwd.pw_uid, sizeof(pwd.pw_uid));
 	key.size = sizeof(pwd.pw_uid) + 1;
-	if ((*dp->put)(dp, &key, &data, uid_dbflg) == -1)
-		wr_error(fn);
+	if ((*db->db->put)(db->db, &key, &data, uid_dbflg) == -1)
+		wr_error(db->dbname);
 }
 
 int
-deldbent(DB *dp, const char *fn, int type, void *keyp)
+deldbent(struct pwddb *db, int type, void *keyp)
 {
 	char tbuf[1024];
 	DBT key;
@@ -884,14 +900,13 @@
 		break;
 	}
 
-	if ((rv = (*dp->del)(dp, &key, 0)) == -1)
-		wr_error(fn);
+	if ((rv = (*db->db->del)(db->db, &key, 0)) == -1)
+		wr_error(db->dbname);
 	return (rv);
 }
 
 int
-getdbent(DB *dp, const char *fn, int type, void *keyp, struct passwd **tpwd,
-    uint32_t version)
+getdbent(struct pwddb *db, int type, void *keyp, struct passwd **tpwd)
 {
 	static char buf[MAX(MAXPATHLEN, LINE_MAX * 2)];
 	static struct passwd pwd;
@@ -921,10 +936,10 @@
 		break;
 	}
 
-	if ((rv = (*dp->get)(dp, &key, &data, 0)) == 1)
+	if ((rv = (*db->db->get)(db->db, &key, &data, 0)) == 1)
 		return (rv);
 	if (rv == -1)
-		error(pwd_Sdb_tmp);
+		error(db->dbname);
 
 	p = (char *)data.data;
 
@@ -942,7 +957,7 @@
 
 #define READPWTIMEVAR(pwvar) \
 	do { \
-		if (version == 0 && \
+		if (db->rversion == 0 && \
 		    sizeof(pwvar) == sizeof(uint64_t)) { \
 			uint32_t tmp; \
 			memcpy(&tmp, p, sizeof(tmp)); \
@@ -951,7 +966,7 @@
 				pwvar = SWAP(tmp); \
 			else \
 				pwvar = tmp; \
-		} else if (version == 1 && \
+		} else if (db->rversion == 1 && \
 		    sizeof(pwvar) == sizeof(uint32_t)) { \
 			uint64_t tmp; \
 			memcpy(&tmp, p, sizeof(tmp)); \
@@ -995,7 +1010,7 @@
 }
 
 void
-putyptoken(DB *dp, const char *fn)
+putyptoken(struct pwddb *db)
 {
 	DBT data, key;
 
@@ -1004,8 +1019,8 @@
 	data.data = (u_char *)NULL;
 	data.size = 0;
 
-	if ((*dp->put)(dp, &key, &data, R_NOOVERWRITE) == -1)
-		wr_error(fn);
+	if ((*db->db->put)(db->db, &key, &data, R_NOOVERWRITE) == -1)
+		wr_error(db->dbname);
 }
 
 void
@@ -1013,7 +1028,7 @@
 {
 
 	(void)fprintf(stderr,
-	    "Usage: %s [-BLpsv] [-c cachesize] [-d directory] [-u user] "
+	    "Usage: %s [-BLpsvw] [-c cachesize] [-d directory] [-u user] "
 	    "[-V version] file\n",
 	    getprogname());
 	exit(EXIT_FAILURE);