diff -ru tarsnap-autoconf-1.0.30/config.h.in tarsnap-autoconf-1.0.31/config.h.in
--- tarsnap-autoconf-1.0.30/config.h.in	2011-08-24 22:02:37.000000000 -0700
+++ tarsnap-autoconf-1.0.31/config.h.in	2011-11-17 02:54:50.000000000 -0800
@@ -303,6 +303,9 @@
 /* Define to 1 if you have the `mknod' function. */
 #undef HAVE_MKNOD
 
+/* Define to 1 if you have the `mmap' function. */
+#undef HAVE_MMAP
+
 /* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
 #undef HAVE_NDIR_H
 
diff -ru tarsnap-autoconf-1.0.30/configure tarsnap-autoconf-1.0.31/configure
--- tarsnap-autoconf-1.0.30/configure	2011-08-24 22:02:39.000000000 -0700
+++ tarsnap-autoconf-1.0.31/configure	2011-11-17 02:54:52.000000000 -0800
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for tarsnap 1.0.30.
+# Generated by GNU Autoconf 2.68 for tarsnap 1.0.31.
 #
 # Report bugs to <cperciva@tarsnap.com>.
 #
@@ -560,8 +560,8 @@
 # Identity of this package.
 PACKAGE_NAME='tarsnap'
 PACKAGE_TARNAME='tarsnap'
-PACKAGE_VERSION='1.0.30'
-PACKAGE_STRING='tarsnap 1.0.30'
+PACKAGE_VERSION='1.0.31'
+PACKAGE_STRING='tarsnap 1.0.31'
 PACKAGE_BUGREPORT='cperciva@tarsnap.com'
 PACKAGE_URL=''
 
@@ -736,8 +736,7 @@
 LDFLAGS
 LIBS
 CPPFLAGS
-CPP
-CPPFLAGS'
+CPP'
 
 
 # Initialize some variables set by options.
@@ -1280,7 +1279,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures tarsnap 1.0.30 to adapt to many kinds of systems.
+\`configure' configures tarsnap 1.0.31 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1351,7 +1350,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of tarsnap 1.0.30:";;
+     short | recursive ) echo "Configuration of tarsnap 1.0.31:";;
    esac
   cat <<\_ACEOF
 
@@ -1451,7 +1450,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-tarsnap configure 1.0.30
+tarsnap configure 1.0.31
 generated by GNU Autoconf 2.68
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -2282,7 +2281,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by tarsnap $as_me 1.0.30, which was
+It was created by tarsnap $as_me 1.0.31, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
@@ -3213,7 +3212,7 @@
 
 # Define the identity of the package.
  PACKAGE='tarsnap'
- VERSION='1.0.30'
+ VERSION='1.0.31'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -3264,7 +3263,7 @@
 _ACEOF
 
 
-$as_echo "#define TARVERSION \"1.0.30\"" >>confdefs.h
+$as_echo "#define TARVERSION \"1.0.31\"" >>confdefs.h
 
 
 $as_echo "#define TSSERVER \"betatest\"" >>confdefs.h
@@ -7819,6 +7818,19 @@
 done
 
 
+# Check for mmap so we can work around its absence on Minix
+for ac_func in mmap
+do :
+  ac_fn_c_check_func "$LINENO" "mmap" "ac_cv_func_mmap"
+if test "x$ac_cv_func_mmap" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_MMAP 1
+_ACEOF
+
+fi
+done
+
+
 # FreeBSD's nl_langinfo supports an option to specify whether the
 # current locale uses month/day or day/month ordering.  It makes the
 # output a little prettier...
@@ -8944,7 +8956,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by tarsnap $as_me 1.0.30, which was
+This file was extended by tarsnap $as_me 1.0.31, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -9010,7 +9022,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-tarsnap config.status 1.0.30
+tarsnap config.status 1.0.31
 configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
Only in tarsnap-autoconf-1.0.30/keygen: Makefile
diff -ru tarsnap-autoconf-1.0.30/keygen/keygen.c tarsnap-autoconf-1.0.31/keygen/keygen.c
--- tarsnap-autoconf-1.0.30/keygen/keygen.c	2011-08-24 22:02:31.000000000 -0700
+++ tarsnap-autoconf-1.0.31/keygen/keygen.c	2011-11-17 02:54:49.000000000 -0800
@@ -68,7 +68,6 @@
 	struct register_internal C;
 	const char * keyfilename;
 	FILE * keyfile;
-	struct stat sb;
 	NETPACKET_CONNECTION * NPC;
 	int passphrased;
 	uint64_t maxmem;
@@ -164,67 +163,33 @@
 	 * avoid registering with the server if we won't be able to create
 	 * the key file later.
 	 */
-	if ((keyfile = fopen(keyfilename, "a")) == NULL) {
+	if ((keyfile = keyfile_write_open(keyfilename)) == NULL) {
 		warnp("Cannot create %s", keyfilename);
 		exit(1);
 	}
 
-	/* Lock the key file to safeguard against simultaneous keygen runs. */
-#ifdef HAVE_LOCKF
-	while (lockf(fileno(keyfile), F_LOCK, 0)) {
-#else
-	while (flock(fileno(keyfile), LOCK_EX)) {
-#endif
-		/* Retry on EINTR. */
-		if (errno == EINTR)
-			continue;
-
-		warnp("Cannot lock file: %s", keyfilename);
-		exit(1);
-	}
-
-	/*
-	 * Make sure that the file is currently empty, i.e., that we're not
-	 * writing to a preexisting key file.
-	 */
-	if (fstat(fileno(keyfile), &sb)) {
-		warnp("fstat(%s)", keyfilename);
-		exit(1);
-	}
-	if (sb.st_size > 0) {
-		warn0("Key file already exists, not overwriting: %s",
-		    keyfilename);
-		exit(1);
-	}
-
-	/* Set the permissions on the key file to 0600. */
-	if (fchmod(fileno(keyfile), S_IRUSR | S_IWUSR)) {
-		warnp("Cannot set permissions on key file: %s", keyfilename);
-		exit(1);
-	}
-
 	/* Initialize entropy subsystem. */
 	if (crypto_entropy_init()) {
 		warnp("Entropy subsystem initialization failed");
-		exit(1);
+		goto err1;
 	}
 
 	/* Initialize key cache. */
 	if (crypto_keys_init()) {
 		warnp("Key cache initialization failed");
-		exit(1);
+		goto err1;
 	}
 
 	/* Generate keys. */
 	if (crypto_keys_generate(CRYPTO_KEYMASK_USER)) {
 		warnp("Error generating keys");
-		exit(1);
+		goto err1;
 	}
 
 	/* Initialize network layer. */
 	if (network_init()) {
 		warnp("Network layer initialization failed");
-		exit(1);
+		goto err1;
 	}
 
 	/*
@@ -237,19 +202,19 @@
 
 	/* Open netpacket connection. */
 	if ((NPC = netpacket_open(USERAGENT)) == NULL)
-		goto err1;
+		goto err2;
 
 	/* Ask the netpacket layer to send a request and get a response. */
 	if (netpacket_op(NPC, callback_register_send, &C))
-		goto err1;
+		goto err2;
 
 	/* Run event loop until an error occurs or we're done. */
 	if (network_spin(&C.done))
-		goto err1;
+		goto err2;
 
 	/* Close netpacket connection. */
 	if (netpacket_close(NPC))
-		goto err1;
+		goto err2;
 
 	/*
 	 * If we didn't respond to a challenge, the server's response must
@@ -257,14 +222,14 @@
 	 */
 	if ((C.donechallenge == 0) && (C.status != 1)) {
 		netproto_printerr(NETPROTO_STATUS_PROTERR);
-		exit(1);
+		goto err1;
 	}
 
 	/* The machine number should be -1 iff the status is nonzero. */
 	if (((C.machinenum == (uint64_t)(-1)) && (C.status == 0)) ||
 	    ((C.machinenum != (uint64_t)(-1)) && (C.status != 0))) {
 		netproto_printerr(NETPROTO_STATUS_PROTERR);
-		exit(1);
+		goto err1;
 	}
 
 	/* Parse status returned by server. */
@@ -284,8 +249,7 @@
 		break;
 	default:
 		netproto_printerr(NETPROTO_STATUS_PROTERR);
-		warnp("Error registering with server");
-		exit(1);
+		goto err2;
 	}
 
 	/* Shut down the network event loop. */
@@ -293,7 +257,7 @@
 
 	/* Exit with a code of 1 if we couldn't register. */
 	if (C.machinenum == (uint64_t)(-1))
-		exit(1);
+		goto err1;
 
 	/* If the user wants to passphrase the keyfile, get the passphrase. */
 	if (passphrased != 0) {
@@ -301,7 +265,7 @@
 		    "Please enter passphrase for keyfile encryption",
 		    "Please confirm passphrase for keyfile encryption", 1)) {
 			warnp("Error reading password");
-			exit(1);
+			goto err1;
 		}
 	} else {
 		passphrase = NULL;
@@ -310,19 +274,21 @@
 	/* Write keys to file. */
 	if (keyfile_write_file(keyfile, C.machinenum,
 	    CRYPTO_KEYMASK_USER, passphrase, maxmem, 1.0))
-		exit(1);
+		goto err1;
 
 	/* Close the key file. */
 	if (fclose(keyfile)) {
 		warnp("Error closing key file");
-		exit(1);
+		goto err1;
 	}
 
 	/* Success! */
 	return (0);
 
-err1:
+err2:
 	warnp("Error registering with server");
+err1:
+	unlink(keyfilename);
 	exit(1);
 }
 
Only in tarsnap-autoconf-1.0.30/keymgmt: Makefile
Only in tarsnap-autoconf-1.0.30/keyregen: Makefile
diff -ru tarsnap-autoconf-1.0.30/keyregen/keyregen.c tarsnap-autoconf-1.0.31/keyregen/keyregen.c
--- tarsnap-autoconf-1.0.30/keyregen/keyregen.c	2011-08-24 22:02:31.000000000 -0700
+++ tarsnap-autoconf-1.0.31/keyregen/keyregen.c	2011-11-17 02:54:49.000000000 -0800
@@ -69,7 +69,6 @@
 	const char * keyfilename;
 	const char * oldkeyfilename;
 	FILE * keyfile;
-	struct stat sb;
 	NETPACKET_CONNECTION * NPC;
 	int passphrased;
 	uint64_t maxmem;
@@ -179,55 +178,21 @@
 	 * avoid registering with the server if we won't be able to create
 	 * the key file later.
 	 */
-	if ((keyfile = fopen(keyfilename, "a")) == NULL) {
+	if ((keyfile = keyfile_write_open(keyfilename)) == NULL) {
 		warnp("Cannot create %s", keyfilename);
 		exit(1);
 	}
 
-	/* Lock the key file to safeguard against simultaneous keygen runs. */
-#ifdef HAVE_LOCKF
-	while (lockf(fileno(keyfile), F_LOCK, 0)) {
-#else
-	while (flock(fileno(keyfile), LOCK_EX)) {
-#endif
-		/* Retry on EINTR. */
-		if (errno == EINTR)
-			continue;
-
-		warnp("Cannot lock file: %s", keyfilename);
-		exit(1);
-	}
-
-	/*
-	 * Make sure that the file is currently empty, i.e., that we're not
-	 * writing to a preexisting key file.
-	 */
-	if (fstat(fileno(keyfile), &sb)) {
-		warnp("fstat(%s)", keyfilename);
-		exit(1);
-	}
-	if (sb.st_size > 0) {
-		warn0("Key file already exists, not overwriting: %s",
-		    keyfilename);
-		exit(1);
-	}
-
-	/* Set the permissions on the key file to 0600. */
-	if (fchmod(fileno(keyfile), S_IRUSR | S_IWUSR)) {
-		warnp("Cannot set permissions on key file: %s", keyfilename);
-		exit(1);
-	}
-
 	/* Initialize entropy subsystem. */
 	if (crypto_entropy_init()) {
 		warnp("Entropy subsystem initialization failed");
-		exit(1);
+		goto err1;
 	}
 
 	/* Initialize key cache. */
 	if (crypto_keys_init()) {
 		warnp("Key cache initialization failed");
-		exit(1);
+		goto err1;
 	}
 
 	/*
@@ -242,7 +207,7 @@
 	    CRYPTO_KEYMASK_HMAC_NAME |
 	    CRYPTO_KEYMASK_HMAC_CPARAMS)) {
 		warnp("Error reading old key file");
-		exit(1);
+		goto err1;
 	}
 
 	/*
@@ -254,13 +219,13 @@
 	    ~CRYPTO_KEYMASK_HMAC_NAME &
 	    ~CRYPTO_KEYMASK_HMAC_CPARAMS)) {
 		warnp("Error generating keys");
-		exit(1);
+		goto err1;
 	}
 
 	/* Initialize network layer. */
 	if (network_init()) {
 		warnp("Network layer initialization failed");
-		exit(1);
+		goto err1;
 	}
 
 	/*
@@ -273,19 +238,19 @@
 
 	/* Open netpacket connection. */
 	if ((NPC = netpacket_open(USERAGENT)) == NULL)
-		goto err1;
+		goto err2;
 
 	/* Ask the netpacket layer to send a request and get a response. */
 	if (netpacket_op(NPC, callback_register_send, &C))
-		goto err1;
+		goto err2;
 
 	/* Run event loop until an error occurs or we're done. */
 	if (network_spin(&C.done))
-		goto err1;
+		goto err2;
 
 	/* Close netpacket connection. */
 	if (netpacket_close(NPC))
-		goto err1;
+		goto err2;
 
 	/*
 	 * If we didn't respond to a challenge, the server's response must
@@ -293,14 +258,14 @@
 	 */
 	if ((C.donechallenge == 0) && (C.status != 1)) {
 		netproto_printerr(NETPROTO_STATUS_PROTERR);
-		exit(1);
+		goto err1;
 	}
 
 	/* The machine number should be -1 iff the status is nonzero. */
 	if (((C.machinenum == (uint64_t)(-1)) && (C.status == 0)) ||
 	    ((C.machinenum != (uint64_t)(-1)) && (C.status != 0))) {
 		netproto_printerr(NETPROTO_STATUS_PROTERR);
-		exit(1);
+		goto err1;
 	}
 
 	/* Parse status returned by server. */
@@ -320,8 +285,7 @@
 		break;
 	default:
 		netproto_printerr(NETPROTO_STATUS_PROTERR);
-		warnp("Error registering with server");
-		exit(1);
+		goto err2;
 	}
 
 	/* Shut down the network event loop. */
@@ -329,7 +293,7 @@
 
 	/* Exit with a code of 1 if we couldn't register. */
 	if (C.machinenum == (uint64_t)(-1))
-		exit(1);
+		goto err1;
 
 	/* If the user wants to passphrase the keyfile, get the passphrase. */
 	if (passphrased != 0) {
@@ -337,7 +301,7 @@
 		    "Please enter passphrase for keyfile encryption",
 		    "Please confirm passphrase for keyfile encryption", 1)) {
 			warnp("Error reading password");
-			exit(1);
+			goto err1;
 		}
 	} else {
 		passphrase = NULL;
@@ -346,19 +310,21 @@
 	/* Write keys to file. */
 	if (keyfile_write_file(keyfile, C.machinenum,
 	    CRYPTO_KEYMASK_USER, passphrase, maxmem, 1.0))
-		exit(1);
+		goto err1;
 
 	/* Close the key file. */
 	if (fclose(keyfile)) {
 		warnp("Error closing key file");
-		exit(1);
+		goto err1;
 	}
 
 	/* Success! */
 	return (0);
 
-err1:
+err2:
 	warnp("Error registering with server");
+err1:
+	unlink(keyfilename);
 	exit(1);
 }
 
diff -ru tarsnap-autoconf-1.0.30/lib/crypto/crypto.h tarsnap-autoconf-1.0.31/lib/crypto/crypto.h
--- tarsnap-autoconf-1.0.30/lib/crypto/crypto.h	2011-08-24 22:02:31.000000000 -0700
+++ tarsnap-autoconf-1.0.31/lib/crypto/crypto.h	2011-11-17 02:54:49.000000000 -0800
@@ -109,7 +109,7 @@
  * Import keys from the provided buffer into the key cache.  Ignore any keys
  * not specified in the mask ${keys}.
  */
-int crypto_keys_import(uint8_t *, size_t, int);
+int crypto_keys_import(const uint8_t *, size_t, int);
 
 /**
  * crypto_keys_missing(keys):
diff -ru tarsnap-autoconf-1.0.30/lib/crypto/crypto_internal.h tarsnap-autoconf-1.0.31/lib/crypto/crypto_internal.h
--- tarsnap-autoconf-1.0.30/lib/crypto/crypto_internal.h	2011-08-24 22:02:31.000000000 -0700
+++ tarsnap-autoconf-1.0.31/lib/crypto/crypto_internal.h	2011-11-17 02:54:49.000000000 -0800
@@ -36,19 +36,19 @@
  * crypto_keys_subr_import_RSA_priv(key, buf, buflen):
  * Import the specified RSA private key from the provided buffer.
  */
-int crypto_keys_subr_import_RSA_priv(RSA **, uint8_t *, size_t);
+int crypto_keys_subr_import_RSA_priv(RSA **, const uint8_t *, size_t);
 
 /**
  * crypto_keys_subr_import_RSA_pub(key, buf, buflen):
  * Import the specified RSA public key from the provided buffer.
  */
-int crypto_keys_subr_import_RSA_pub(RSA **, uint8_t *, size_t);
+int crypto_keys_subr_import_RSA_pub(RSA **, const uint8_t *, size_t);
 
 /**
  * crypto_keys_subr_import_HMAC(key, buf, buflen):
  * Import the specified HMAC key from the provided buffer.
  */
-int crypto_keys_subr_import_HMAC(struct crypto_hmac_key **, uint8_t *,
+int crypto_keys_subr_import_HMAC(struct crypto_hmac_key **, const uint8_t *,
     size_t);
 
 /**
diff -ru tarsnap-autoconf-1.0.30/lib/crypto/crypto_keys.c tarsnap-autoconf-1.0.31/lib/crypto/crypto_keys.c
--- tarsnap-autoconf-1.0.30/lib/crypto/crypto_keys.c	2011-08-24 22:02:31.000000000 -0700
+++ tarsnap-autoconf-1.0.31/lib/crypto/crypto_keys.c	2011-11-17 02:54:49.000000000 -0800
@@ -155,9 +155,9 @@
  * not specified in the mask ${keys}.
  */
 int
-crypto_keys_import(uint8_t * buf, size_t buflen, int keys)
+crypto_keys_import(const uint8_t * buf, size_t buflen, int keys)
 {
-	struct keyheader * kh;
+	const struct keyheader * kh;
 	uint32_t len;
 
 	/* Loop until we've processed all the provided data. */
@@ -169,7 +169,7 @@
 		}
 
 		/* Parse header. */
-		kh = (struct keyheader *)buf;
+		kh = (const struct keyheader *)buf;
 		buf += sizeof(struct keyheader);
 		buflen -= sizeof(struct keyheader);
 
diff -ru tarsnap-autoconf-1.0.30/lib/crypto/crypto_keys_subr.c tarsnap-autoconf-1.0.31/lib/crypto/crypto_keys_subr.c
--- tarsnap-autoconf-1.0.30/lib/crypto/crypto_keys_subr.c	2011-08-24 22:02:31.000000000 -0700
+++ tarsnap-autoconf-1.0.31/lib/crypto/crypto_keys_subr.c	2011-11-17 02:54:49.000000000 -0800
@@ -30,7 +30,7 @@
  * x[0] || x[1] || x[2] ... x[31]
  */
 
-static int import_BN(BIGNUM **, uint8_t **, size_t *);
+static int import_BN(BIGNUM **, const uint8_t **, size_t *);
 static int export_BN(BIGNUM *, uint8_t **, size_t *, uint32_t *);
 
 /**
@@ -39,7 +39,7 @@
  * pointer, and adjust the remaining buffer length.
  */
 static int
-import_BN(BIGNUM ** bn, uint8_t ** buf, size_t * buflen)
+import_BN(BIGNUM ** bn, const uint8_t ** buf, size_t * buflen)
 {
 	uint32_t len;
 	uint8_t * bnbuf;
@@ -161,7 +161,7 @@
  * Import the specified RSA private key from the provided buffer.
  */
 int
-crypto_keys_subr_import_RSA_priv(RSA ** key, uint8_t * buf, size_t buflen)
+crypto_keys_subr_import_RSA_priv(RSA ** key, const uint8_t * buf, size_t buflen)
 {
 
 	/* Free any existing key. */
@@ -212,7 +212,7 @@
  * Import the specified RSA public key from the provided buffer.
  */
 int
-crypto_keys_subr_import_RSA_pub(RSA ** key, uint8_t * buf, size_t buflen)
+crypto_keys_subr_import_RSA_pub(RSA ** key, const uint8_t * buf, size_t buflen)
 {
 
 	/* Free any existing key. */
@@ -251,8 +251,8 @@
  * Import the specified HMAC key from the provided buffer.
  */
 int
-crypto_keys_subr_import_HMAC(struct crypto_hmac_key ** key, uint8_t * buf,
-    size_t buflen)
+crypto_keys_subr_import_HMAC(struct crypto_hmac_key ** key,
+    const uint8_t * buf, size_t buflen)
 {
 
 	/* Free any existing key. */
diff -ru tarsnap-autoconf-1.0.30/lib/crypto/crypto_scrypt-nosse.c tarsnap-autoconf-1.0.31/lib/crypto/crypto_scrypt-nosse.c
--- tarsnap-autoconf-1.0.30/lib/crypto/crypto_scrypt-nosse.c	2011-08-24 22:02:31.000000000 -0700
+++ tarsnap-autoconf-1.0.31/lib/crypto/crypto_scrypt-nosse.c	2011-11-17 02:54:49.000000000 -0800
@@ -273,7 +273,7 @@
 	if ((errno = posix_memalign(&XY0, 64, 256 * r + 64)) != 0)
 		goto err1;
 	XY = (uint32_t *)(XY0);
-#ifndef MAP_ANON
+#if !defined(MAP_ANON) || !defined(HAVE_MMAP)
 	if ((errno = posix_memalign(&V0, 64, 128 * r * N)) != 0)
 		goto err2;
 	V = (uint32_t *)(V0);
@@ -285,13 +285,13 @@
 	if ((XY0 = malloc(256 * r + 64 + 63)) == NULL)
 		goto err1;
 	XY = (uint32_t *)(((uintptr_t)(XY0) + 63) & ~ (uintptr_t)(63));
-#ifndef MAP_ANON
+#if !defined(MAP_ANON) || !defined(HAVE_MMAP)
 	if ((V0 = malloc(128 * r * N + 63)) == NULL)
 		goto err2;
 	V = (uint32_t *)(((uintptr_t)(V0) + 63) & ~ (uintptr_t)(63));
 #endif
 #endif
-#ifdef MAP_ANON
+#if defined(MAP_ANON) && defined(HAVE_MMAP)
 	if ((V0 = mmap(NULL, 128 * r * N, PROT_READ | PROT_WRITE,
 #ifdef MAP_NOCORE
 	    MAP_ANON | MAP_PRIVATE | MAP_NOCORE,
@@ -316,7 +316,7 @@
 	PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen);
 
 	/* Free memory. */
-#ifdef MAP_ANON
+#if defined(MAP_ANON) && defined(HAVE_MMAP)
 	if (munmap(V0, 128 * r * N))
 		goto err2;
 #else
diff -ru tarsnap-autoconf-1.0.30/lib/crypto/crypto_scrypt-sse.c tarsnap-autoconf-1.0.31/lib/crypto/crypto_scrypt-sse.c
--- tarsnap-autoconf-1.0.30/lib/crypto/crypto_scrypt-sse.c	2011-08-24 22:02:31.000000000 -0700
+++ tarsnap-autoconf-1.0.31/lib/crypto/crypto_scrypt-sse.c	2011-11-17 02:54:49.000000000 -0800
@@ -301,7 +301,7 @@
 	if ((errno = posix_memalign(&XY0, 64, 256 * r + 64)) != 0)
 		goto err1;
 	XY = (uint32_t *)(XY0);
-#ifndef MAP_ANON
+#if !defined(MAP_ANON) || !defined(HAVE_MMAP)
 	if ((errno = posix_memalign(&V0, 64, 128 * r * N)) != 0)
 		goto err2;
 	V = (uint32_t *)(V0);
@@ -313,13 +313,13 @@
 	if ((XY0 = malloc(256 * r + 64 + 63)) == NULL)
 		goto err1;
 	XY = (uint32_t *)(((uintptr_t)(XY0) + 63) & ~ (uintptr_t)(63));
-#ifndef MAP_ANON
+#if !defined(MAP_ANON) || !defined(HAVE_MMAP)
 	if ((V0 = malloc(128 * r * N + 63)) == NULL)
 		goto err2;
 	V = (uint32_t *)(((uintptr_t)(V0) + 63) & ~ (uintptr_t)(63));
 #endif
 #endif
-#ifdef MAP_ANON
+#if defined(MAP_ANON) && defined(HAVE_MMAP)
 	if ((V0 = mmap(NULL, 128 * r * N, PROT_READ | PROT_WRITE,
 #ifdef MAP_NOCORE
 	    MAP_ANON | MAP_PRIVATE | MAP_NOCORE,
@@ -344,7 +344,7 @@
 	PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen);
 
 	/* Free memory. */
-#ifdef MAP_ANON
+#if defined(MAP_ANON) && defined(HAVE_MMAP)
 	if (munmap(V0, 128 * r * N))
 		goto err2;
 #else
diff -ru tarsnap-autoconf-1.0.30/lib/datastruct/patricia.c tarsnap-autoconf-1.0.31/lib/datastruct/patricia.c
--- tarsnap-autoconf-1.0.30/lib/datastruct/patricia.c	2011-08-24 22:02:31.000000000 -0700
+++ tarsnap-autoconf-1.0.31/lib/datastruct/patricia.c	2011-11-17 02:54:49.000000000 -0800
@@ -448,7 +448,7 @@
 			if (keylen == 0) {
 				/* Is there a record here? */
 				if (n->left != NULL)
-					return ((void **)&n->left);
+					return ((void **)(void *)&n->left);
 				else
 					return (NULL);
 			}
diff -ru tarsnap-autoconf-1.0.30/lib/keyfile/keyfile.c tarsnap-autoconf-1.0.31/lib/keyfile/keyfile.c
--- tarsnap-autoconf-1.0.30/lib/keyfile/keyfile.c	2011-08-24 22:02:31.000000000 -0700
+++ tarsnap-autoconf-1.0.31/lib/keyfile/keyfile.c	2011-11-17 02:54:49.000000000 -0800
@@ -3,6 +3,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 
+#include <fcntl.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
@@ -20,7 +21,8 @@
  * Key file format:
  * keyfile == (rawkeyfile | textkeyfile)
  * textkeyfile == line*
- * line == commentline | base64line
+ * line == blankline | commentline | base64line
+ * blankline == EOL
  * commentline == "#" char* EOL
  * base64line == [a-zA-Z0-9+/=]+ EOL
  * EOL = "\n" | "\r" | "\r\n"
@@ -31,8 +33,9 @@
  * rawlinechecksum == byte{6}
  * where rawlinechecksum is the first 6 bytes of SHA256(rawlinedata).
  *
- * After ignoring any commentlines, converting base64lines to rawlinedatas,
- * and concatenating them together, a textkeyfile becomes a tarsnapkeyfile.
+ * After ignoring any blanklines and commentlines, converting base64lines to
+ * rawlinedatas, and concatenating them together, a textkeyfile becomes a
+ * tarsnapkeyfile.
  *
  * tarsnapkeyfile == scryptkeyfile | cookedkeyfile
  * scryptkeyfile == scrypt(cookedkeyfile)
@@ -47,14 +50,19 @@
  * 3. A base64-encoded encrypted key file.
  */
 
-static int read_raw(uint8_t *, size_t, uint64_t *, const char *, int);
-static int read_plaintext(uint8_t *, size_t, uint64_t *, const char *, int);
-static int read_encrypted(uint8_t *, size_t, uint64_t *, const char *, int);
-static int read_base256(uint8_t *, size_t, uint64_t *, const char *, int);
-static int read_base64(uint8_t *, size_t, uint64_t *, const char *, int);
+static int read_raw(const uint8_t *, size_t,
+    uint64_t *, const char *, int);
+static int read_plaintext(const uint8_t *, size_t,
+    uint64_t *, const char *, int);
+static int read_encrypted(const uint8_t *, size_t,
+    uint64_t *, const char *, int);
+static int read_base256(const uint8_t *, size_t,
+    uint64_t *, const char *, int);
+static int read_base64(const char *, size_t,
+    uint64_t *, const char *, int);
 
 static int
-read_raw(uint8_t * keybuf, size_t keylen, uint64_t * machinenum,
+read_raw(const uint8_t * keybuf, size_t keylen, uint64_t * machinenum,
     const char * filename, int keys)
 {
 
@@ -80,7 +88,7 @@
 }
 
 static int
-read_plaintext(uint8_t * keybuf, size_t keylen, uint64_t * machinenum,
+read_plaintext(const uint8_t * keybuf, size_t keylen, uint64_t * machinenum,
     const char * filename, int keys)
 {
 
@@ -105,7 +113,7 @@
 }
 
 static int
-read_encrypted(uint8_t * keybuf, size_t keylen, uint64_t * machinenum,
+read_encrypted(const uint8_t * keybuf, size_t keylen, uint64_t * machinenum,
     const char * filename, int keys)
 {
 	char * pwprompt;
@@ -141,7 +149,7 @@
 
 	/* Decrypt the key file. */
 	rc = scryptdec_buf(keybuf, keylen, deckeybuf, &deckeylen,
-	    passwd, strlen(passwd), 0, 0.5, 86400.0);
+	    (const uint8_t *)passwd, strlen(passwd), 0, 0.5, 86400.0);
 	if (rc != 0) {
 		switch (rc) {
 		case 1:
@@ -216,7 +224,7 @@
 }
 
 static int
-read_base256(uint8_t * keybuf, size_t keylen, uint64_t * machinenum,
+read_base256(const uint8_t * keybuf, size_t keylen, uint64_t * machinenum,
     const char * filename, int keys)
 {
 
@@ -241,7 +249,7 @@
 }
 
 static int
-read_base64(uint8_t * keybuf, size_t keylen, uint64_t * machinenum,
+read_base64(const char * keybuf, size_t keylen, uint64_t * machinenum,
     const char * filename, int keys)
 {
 	uint8_t * decbuf;
@@ -283,8 +291,8 @@
 			goto err1;
 		}
 
-		/* If this isn't a comment line, base-64 decode it. */
-		if (keybuf[0] != '#') {
+		/* If this isn't a comment or blank line, base-64 decode it. */
+		if ((llen > 0) && (keybuf[0] != '#')) {
 			if (b64decode(keybuf, llen, &decbuf[decpos], &len))
 				goto err2;
 
@@ -394,7 +402,7 @@
 		}
 	} else {
 		/* Otherwise, try to base64 decode it. */
-		if (read_base64(keybuf, sb.st_size,
+		if (read_base64((const char *)keybuf, sb.st_size,
 		    machinenum, filename, keys)) {
 			if (errno)
 				warnp("Error parsing key file: %s", filename);
@@ -432,17 +440,11 @@
 	FILE * f;
 
 	/* Create key file. */
-	if ((f = fopen(filename, "w")) == NULL) {
+	if ((f = keyfile_write_open(filename)) == NULL) {
 		warnp("Cannot create %s", filename);
 		goto err0;
 	}
 
-	/* Set the permissions on the key file to 0600. */
-	if (fchmod(fileno(f), S_IRUSR | S_IWUSR)) {
-		warnp("Cannot set permissions on key file: %s", filename);
-		goto err2;
-	}
-
 	/* Write keys. */
 	if (keyfile_write_file(f, machinenum, keys, passphrase,
 	    maxmem, cputime))
@@ -467,6 +469,40 @@
 }
 
 /**
+ * keyfile_write_open(filename):
+ * Open a key file for writing.  Avoid race conditions.  Return a FILE *.
+ */
+FILE *
+keyfile_write_open(const char * filename)
+{
+	FILE * f;
+	int fd;
+
+	/* Attempt to create the file. */
+	if ((fd = open(filename, O_WRONLY | O_CREAT | O_EXCL,
+	    S_IRUSR | S_IWUSR)) == -1) {
+		/* Special error message for EEXIST. */
+		if (errno == EEXIST)
+			warn0("Key file already exists, not overwriting: %s",
+			    filename);
+		goto err0;
+	}
+
+	/* Wrap the fd into a FILE. */
+	if ((f = fdopen(fd, "w")) == NULL)
+		goto err1;
+
+	/* Success! */
+	return (f);
+
+err1:
+	close(fd);
+err0:
+	/* Failure! */
+	return (NULL);
+}
+
+/**
  * keyfile_write_file(f, machinenum, keys, passphrase, maxmem, cputime):
  * Write a key file for the specified machine containing the specified keys.
  * If passphrase is non-NULL, use up to cputime seconds and maxmem bytes of
@@ -483,7 +519,7 @@
 	uint8_t * encrbuf;
 	int rc;
 	uint8_t linebuf256[54];
-	uint8_t linebuf64[73];
+	char linebuf64[73];
 	size_t writepos;
 	size_t linelen;
 	uint8_t hbuf[32];
@@ -516,7 +552,7 @@
 
 		/* Encrypt. */
 		switch ((rc = scryptenc_buf(tskeybuf, tskeylen, encrbuf,
-		    passphrase, strlen(passphrase),
+		    (uint8_t *)passphrase, strlen(passphrase),
 		    maxmem, (maxmem != 0) ? 0.5 : 0.125, cputime))) {
 		case 0:
 			/* Success! */
diff -ru tarsnap-autoconf-1.0.30/lib/keyfile/keyfile.h tarsnap-autoconf-1.0.31/lib/keyfile/keyfile.h
--- tarsnap-autoconf-1.0.30/lib/keyfile/keyfile.h	2011-08-24 22:02:31.000000000 -0700
+++ tarsnap-autoconf-1.0.31/lib/keyfile/keyfile.h	2011-11-17 02:54:49.000000000 -0800
@@ -20,6 +20,12 @@
 int keyfile_write(const char *, uint64_t, int, char *, size_t, double);
 
 /**
+ * keyfile_write_open(filename):
+ * Open a key file for writing.  Avoid race conditions.  Return a FILE *.
+ */
+FILE * keyfile_write_open(const char *);
+
+/**
  * keyfile_write_file(f, machinenum, keys, passphrase, maxmem, cputime):
  * Write a key file for the specified machine containing the specified keys.
  * If passphrase is non-NULL, use up to cputime seconds and maxmem bytes of
diff -ru tarsnap-autoconf-1.0.30/lib/netproto/netproto_keyexchange.c tarsnap-autoconf-1.0.31/lib/netproto/netproto_keyexchange.c
--- tarsnap-autoconf-1.0.30/lib/netproto/netproto_keyexchange.c	2011-08-24 22:02:31.000000000 -0700
+++ tarsnap-autoconf-1.0.31/lib/netproto/netproto_keyexchange.c	2011-11-17 02:54:49.000000000 -0800
@@ -196,8 +196,8 @@
 	    namelen_sent, KC))
 		goto err2;
 	KC->refcount++;
-	if (network_writeq_add(KC->C->Q, KC->useragent, KC->useragentlen,
-	    &KC->timeout, name_sent, KC))
+	if (network_writeq_add(KC->C->Q, (const uint8_t *)KC->useragent,
+	    KC->useragentlen, &KC->timeout, name_sent, KC))
 		goto err2;
 
 	/* Success! */
diff -ru tarsnap-autoconf-1.0.30/lib/network/network_cork.c tarsnap-autoconf-1.0.31/lib/network/network_cork.c
--- tarsnap-autoconf-1.0.30/lib/network/network_cork.c	2011-08-24 22:02:31.000000000 -0700
+++ tarsnap-autoconf-1.0.31/lib/network/network_cork.c	2011-11-17 02:54:49.000000000 -0800
@@ -25,7 +25,8 @@
  * XXX defined, but seems to be broken; we use autoconf to detect OS X and
  * XXX define BROKEN_TCP_NOPUSH.  On Cygwin, TCP_NOPUSH is defined, but
  * XXX using it produces a ENOPROTOOPT error; we define BROKEN_TCP_NOPUSH
- * XXX in this case, too.
+ * XXX in this case, too.  On Minix, TCP_NODELAY fails with ENOSYS; since
+ * XXX corking occurs for performance reasons only, we ignore this errno.
  */
 
 /* Macro to simplify setting options. */
@@ -35,7 +36,8 @@
 	val = value;							\
 	if (setsockopt(fd, IPPROTO_TCP, opt, &val, sizeof(int))) {	\
 		if ((errno != ETIMEDOUT) &&				\
-		    (errno != ECONNRESET)) {				\
+		    (errno != ECONNRESET) &&				\
+		    (errno != ENOSYS)) {				\
 			warnp("setsockopt(%s, %d)", #opt, val);		\
 			goto err0;					\
 		}							\
diff -ru tarsnap-autoconf-1.0.30/lib/network/network_select.c tarsnap-autoconf-1.0.31/lib/network/network_select.c
--- tarsnap-autoconf-1.0.30/lib/network/network_select.c	2011-08-24 22:02:31.000000000 -0700
+++ tarsnap-autoconf-1.0.31/lib/network/network_select.c	2011-11-17 02:54:49.000000000 -0800
@@ -299,13 +299,13 @@
 		 * the reallocations fails, we may end up with some buffers
 		 * being allocated extra space; but this is harmless.
 		 */
-		if (recalloc((void **)&N.writers, N.alloclen, newalloclen,
+		if (recalloc((void *)&N.writers, N.alloclen, newalloclen,
 		    sizeof(struct network_callback_internal)))
 			goto err0;
-		if (recalloc((void **)&N.readers, N.alloclen, newalloclen,
+		if (recalloc((void *)&N.readers, N.alloclen, newalloclen,
 		    sizeof(struct network_callback_internal)))
 			goto err0;
-		if (recalloc((void **)&N.waiters, N.alloclen, newalloclen,
+		if (recalloc((void *)&N.waiters, N.alloclen, newalloclen,
 		    sizeof(struct network_callback_internal)))
 			goto err0;
 
@@ -483,6 +483,7 @@
 	int ntimeouts = 0;
 	double tokensecs;
 
+restart:
 	/* Get current time. */
 	if (gettimeofday(&curtime, NULL)) {
 		warnp("gettimeofday()");
@@ -601,9 +602,16 @@
 	selectstats_select();
 	while ((nready = select(N.maxfd + 1, &readfds, &writefds,
 	    NULL, &timeout)) == -1) {
-		/* EINTR is harmless. */
+		/*
+		 * EINTR is harmless, but on linux (contrary to POSIX!) it is
+		 * documented as rendering the fd sets and timeout undefined.
+		 * Go back to the start of the function and regenerate all of
+		 * those (we can't just save and restore them in case some
+		 * time passed before the signal arrived and the select call
+		 * was interrupted).
+		 */
 		if (errno == EINTR)
-			continue;
+			goto restart;
 
 		/* Anything else is an error. */
 		warnp("select()");
diff -ru tarsnap-autoconf-1.0.30/lib/util/b64encode.c tarsnap-autoconf-1.0.31/lib/util/b64encode.c
--- tarsnap-autoconf-1.0.30/lib/util/b64encode.c	2011-08-24 22:02:31.000000000 -0700
+++ tarsnap-autoconf-1.0.31/lib/util/b64encode.c	2011-11-17 02:54:49.000000000 -0800
@@ -56,7 +56,7 @@
  * input ${in} is not valid base-64 encoded text.
  */
 int
-b64decode(char * in, size_t inlen, uint8_t * out, size_t * outlen)
+b64decode(const char * in, size_t inlen, uint8_t * out, size_t * outlen)
 {
 	uint32_t t;
 	size_t deadbytes = 0;
diff -ru tarsnap-autoconf-1.0.30/lib/util/b64encode.h tarsnap-autoconf-1.0.31/lib/util/b64encode.h
--- tarsnap-autoconf-1.0.30/lib/util/b64encode.h	2011-08-24 22:02:31.000000000 -0700
+++ tarsnap-autoconf-1.0.31/lib/util/b64encode.h	2011-11-17 02:54:49.000000000 -0800
@@ -19,6 +19,6 @@
  * of space; but ${outlen} might be less than this.  Return non-zero if the
  * input ${in} is not valid base-64 encoded text.
  */
-int b64decode(char *, size_t, uint8_t *, size_t *);
+int b64decode(const char *, size_t, uint8_t *, size_t *);
 
 #endif /* !_B64ENCODE_H_ */
Only in tarsnap-autoconf-1.0.30/libarchive: Makefile
diff -ru tarsnap-autoconf-1.0.30/libarchive/archive_read_support_compression_bzip2.c tarsnap-autoconf-1.0.31/libarchive/archive_read_support_compression_bzip2.c
--- tarsnap-autoconf-1.0.30/libarchive/archive_read_support_compression_bzip2.c	2011-08-24 22:02:31.000000000 -0700
+++ tarsnap-autoconf-1.0.31/libarchive/archive_read_support_compression_bzip2.c	2011-11-17 02:54:49.000000000 -0800
@@ -185,7 +185,7 @@
 
 	state = (struct private_data *)calloc(sizeof(*state), 1);
 	out_block = (unsigned char *)malloc(out_block_size);
-	if (self == NULL || state == NULL || out_block == NULL) {
+	if (state == NULL || out_block == NULL) {
 		archive_set_error(&self->archive->archive, ENOMEM,
 		    "Can't allocate data for bzip2 decompression");
 		free(out_block);
@@ -210,12 +210,11 @@
 bzip2_filter_read(struct archive_read_filter *self, const void **p)
 {
 	struct private_data *state;
-	size_t read_avail, decompressed;
+	size_t decompressed;
 	const char *read_buf;
 	ssize_t ret;
 
 	state = (struct private_data *)self->data;
-	read_avail = 0;
 
 	if (state->eof) {
 		*p = NULL;
@@ -344,11 +343,12 @@
 					  "Failed to clean up decompressor");
 			ret = ARCHIVE_FATAL;
 		}
+		state->valid = 0;
 	}
 
 	free(state->out_block);
 	free(state);
-	return (ARCHIVE_OK);
+	return (ret);
 }
 
 #endif /* HAVE_BZLIB_H */
diff -ru tarsnap-autoconf-1.0.30/libarchive/archive_read_support_format_iso9660.c tarsnap-autoconf-1.0.31/libarchive/archive_read_support_format_iso9660.c
--- tarsnap-autoconf-1.0.30/libarchive/archive_read_support_format_iso9660.c	2011-08-24 22:02:31.000000000 -0700
+++ tarsnap-autoconf-1.0.31/libarchive/archive_read_support_format_iso9660.c	2011-11-17 02:54:49.000000000 -0800
@@ -678,7 +678,7 @@
 	if (bytes_read == 0)
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 		    "Truncated input file");
-	if (buff == NULL)
+	if (*buff == NULL)
 		return (ARCHIVE_FATAL);
 	if (bytes_read > iso9660->entry_bytes_remaining)
 		bytes_read = iso9660->entry_bytes_remaining;
diff -ru tarsnap-autoconf-1.0.30/libarchive/archive_util.c tarsnap-autoconf-1.0.31/libarchive/archive_util.c
--- tarsnap-autoconf-1.0.30/libarchive/archive_util.c	2011-08-24 22:02:31.000000000 -0700
+++ tarsnap-autoconf-1.0.31/libarchive/archive_util.c	2011-11-17 02:54:49.000000000 -0800
@@ -201,7 +201,7 @@
  *      but character '-' cannot be used for the first character.
  *      (Regular expression is [a-z][-a-z]+)
  *
- *    - For a specfic format/filter, using the format name with ':'.
+ *    - For a specific format/filter, using the format name with ':'.
  *        e.g  "zip:compression=9"
  *        (This "compression=9" option entry is for "zip" format only)
  *
diff -ru tarsnap-autoconf-1.0.30/libarchive/archive_write_set_compression_none.c tarsnap-autoconf-1.0.31/libarchive/archive_write_set_compression_none.c
--- tarsnap-autoconf-1.0.30/libarchive/archive_write_set_compression_none.c	2011-08-24 22:02:31.000000000 -0700
+++ tarsnap-autoconf-1.0.31/libarchive/archive_write_set_compression_none.c	2011-11-17 02:54:49.000000000 -0800
@@ -208,11 +208,10 @@
 	ssize_t target_block_length;
 	ssize_t bytes_written;
 	int ret;
-	int ret2;
 	struct archive_none *state;
 
 	state = (struct archive_none *)a->compressor.data;
-	ret = ret2 = ARCHIVE_OK;
+	ret = ARCHIVE_OK;
 	if (a->client_writer == NULL) {
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
 		    "No write callback is registered?  "
diff -ru tarsnap-autoconf-1.0.30/pkg/debian/changelog tarsnap-autoconf-1.0.31/pkg/debian/changelog
--- tarsnap-autoconf-1.0.30/pkg/debian/changelog	2011-08-24 22:02:32.000000000 -0700
+++ tarsnap-autoconf-1.0.31/pkg/debian/changelog	2011-11-17 02:54:49.000000000 -0800
@@ -1,3 +1,10 @@
+tarsnap (1.0.31) unstable; urgency=low
+
+  * New version of tarsnap fixes security vulnerabilities relating to key
+    file creation on multi-user systems, plus several minor enhancements
+    and bug fixes.
+
+ -- Colin Percival <cperciva@tarsnap.com>  Thu, 17 Nov 2011 10:52:59 +0000
 tarsnap (1.0.30) unstable; urgency=low
 
   * New version of tarsnap brings many minor bug fixes.
Only in tarsnap-autoconf-1.0.30/recrypt: Makefile
diff -ru tarsnap-autoconf-1.0.30/recrypt/recrypt.c tarsnap-autoconf-1.0.31/recrypt/recrypt.c
--- tarsnap-autoconf-1.0.30/recrypt/recrypt.c	2011-08-24 22:02:32.000000000 -0700
+++ tarsnap-autoconf-1.0.31/recrypt/recrypt.c	2011-11-17 02:54:49.000000000 -0800
@@ -656,8 +656,8 @@
 		/* We have a new last sequence number. */
 		memcpy(nlastseq, nseqnum, 32);
 
-		/* We're done this group. */
-		printf(" done.\n");
+		/* We've done this group. */
+		printf(". done.\n");
 	}
 
 	/* Open the old cache directory... */
diff -ru tarsnap-autoconf-1.0.30/recrypt/tarsnap-recrypt.1-man tarsnap-autoconf-1.0.31/recrypt/tarsnap-recrypt.1-man
--- tarsnap-autoconf-1.0.30/recrypt/tarsnap-recrypt.1-man	2011-08-24 22:02:32.000000000 -0700
+++ tarsnap-autoconf-1.0.31/recrypt/tarsnap-recrypt.1-man	2011-11-17 02:54:49.000000000 -0800
@@ -34,7 +34,7 @@
 \fIold-key-file\fP.
 .PP
 \fB\%tarsnap-recrypt\fP
-checkpoints its progress after every 1-2 GB of data is
+checkpoints its progress after every 1-2 GB of data that it has
 copied; if it is interrupted it can be re-run and it will
 attempt to continue.
 .PP
diff -ru tarsnap-autoconf-1.0.30/recrypt/tarsnap-recrypt.1-mdoc tarsnap-autoconf-1.0.31/recrypt/tarsnap-recrypt.1-mdoc
--- tarsnap-autoconf-1.0.30/recrypt/tarsnap-recrypt.1-mdoc	2011-08-24 22:02:32.000000000 -0700
+++ tarsnap-autoconf-1.0.31/recrypt/tarsnap-recrypt.1-mdoc	2011-11-17 02:54:49.000000000 -0800
@@ -35,7 +35,7 @@
 .Ar old-key-file .
 .Pp
 .Nm
-checkpoints its progress after every 1-2 GB of data is
+checkpoints its progress after every 1-2 GB of data that it has
 copied; if it is interrupted it can be re-run and it will
 attempt to continue.
 .Pp
Only in tarsnap-autoconf-1.0.30/tar: Makefile
diff -ru tarsnap-autoconf-1.0.30/tar/bsdtar.c tarsnap-autoconf-1.0.31/tar/bsdtar.c
--- tarsnap-autoconf-1.0.30/tar/bsdtar.c	2011-08-24 22:02:32.000000000 -0700
+++ tarsnap-autoconf-1.0.31/tar/bsdtar.c	2011-11-17 02:54:49.000000000 -0800
@@ -202,6 +202,14 @@
 		exit(1);
 
 	/*
+	 * Make stdout line-buffered (if possible) so that operations such as
+	 * "tarsnap --list-archives | more" will run more smoothly.  The only
+	 * downside to this is a slight performance cost; but we don't write
+	 * enough data to stdout for that to matter.
+	 */
+	setvbuf(stdout, NULL, _IONBF, 0);
+
+	/*
 	 * Unless specified otherwise, we consider ourselves to be
 	 * constructing a snapshot of the disk as it is right now.
 	 */
diff -ru tarsnap-autoconf-1.0.30/tar/ccache/ccache_read.c tarsnap-autoconf-1.0.31/tar/ccache/ccache_read.c
--- tarsnap-autoconf-1.0.30/tar/ccache/ccache_read.c	2011-08-24 22:02:32.000000000 -0700
+++ tarsnap-autoconf-1.0.31/tar/ccache/ccache_read.c	2011-11-17 02:54:49.000000000 -0800
@@ -186,9 +186,11 @@
 	struct ccache_internal * C;
 	struct ccache_read_internal R;
 	struct ccache_record * ccr;
+#ifdef HAVE_MMAP
 	struct stat sb;
 	off_t fpos;
 	long int pagesize;
+#endif
 	size_t i;
 	uint8_t N[4];
 
@@ -248,6 +250,7 @@
 		C->trailerusage += ccr->tzlen;
 	}
 
+#ifdef HAVE_MMAP
 	/* Obtain page size, since mmapped regions must be page-aligned. */
 	if ((pagesize = sysconf(_SC_PAGESIZE)) == -1) {
 		warnp("sysconf(_SC_PAGESIZE)");
@@ -280,9 +283,20 @@
 		warnp("mmap(%s)", R.s);
 		goto err5;
 	}
+	R.data = (uint8_t *)C->data + (fpos % pagesize);
+#else
+	/* Allocate space. */
+	C->datalen = R.datalen;
+	if (((C->data = malloc(C->datalen)) == NULL) && (C->datalen > 0))
+		goto err5;
+	if (fread(C->data, C->datalen, 1, R.f) != 1) {
+		warnp("fread(%s)", R.s);
+		goto err6;
+	}
+	R.data = (uint8_t *)C->data;
+#endif
 
 	/* Iterate through the tree reading chunk headers and trailers. */
-	R.data = (uint8_t *)C->data + (fpos % pagesize);
 	if (patricia_foreach(C->tree, callback_read_data, &R)) {
 		warnp("Error reading cache: %s", R.s);
 		goto err6;
@@ -306,8 +320,12 @@
 	return (C);
 
 err6:
+#ifdef HAVE_MMAP
 	if (C->datalen > 0)
 		munmap(C->data, C->datalen);
+#else
+	free(C->data);
+#endif
 err5:
 	free(R.sbuf);
 	patricia_foreach(C->tree, callback_free, NULL);
@@ -343,8 +361,12 @@
 	patricia_free(C->tree);
 
 	/* Unmap memory. */
+#ifdef HAVE_MMAP
 	if (C->datalen > 0 && munmap(C->data, C->datalen))
 		warnp("munmap failed on cache data");
+#else
+	free(C->data);
+#endif
 
 	/* Free the cache. */
 	free(C);
diff -ru tarsnap-autoconf-1.0.30/tar/config_freebsd.h tarsnap-autoconf-1.0.31/tar/config_freebsd.h
--- tarsnap-autoconf-1.0.30/tar/config_freebsd.h	2011-08-24 22:02:32.000000000 -0700
+++ tarsnap-autoconf-1.0.31/tar/config_freebsd.h	2011-11-17 02:54:49.000000000 -0800
@@ -77,6 +77,7 @@
 #define	HAVE_MEMMOVE 1
 #define	HAVE_MEMORY_H 1
 #define	HAVE_MEMSET 1
+#define	HAVE_MMAP 1
 #if __FreeBSD_version >= 450002 /* nl_langinfo introduced */
 #define	HAVE_NL_LANGINFO 1
 #endif
diff -ru tarsnap-autoconf-1.0.30/tar/multitape/multitape_fsck.c tarsnap-autoconf-1.0.31/tar/multitape/multitape_fsck.c
--- tarsnap-autoconf-1.0.30/tar/multitape/multitape_fsck.c	2011-08-24 22:02:32.000000000 -0700
+++ tarsnap-autoconf-1.0.31/tar/multitape/multitape_fsck.c	2011-11-17 02:54:49.000000000 -0800
@@ -372,6 +372,9 @@
 
 	/* Iterate through the archives. */
 	for (file = 0; file < nmdat; file++) {
+		/* Print progress. */
+		fprintf(stdout, "  Archive %zu/%zu...\n", file + 1, nmdat);
+
 		/* Skip deleted metadata. */
 		if (mdatlist[file] == NULL)
 			continue;
diff -ru tarsnap-autoconf-1.0.30/tar/tarsnap.1-man.in tarsnap-autoconf-1.0.31/tar/tarsnap.1-man.in
--- tarsnap-autoconf-1.0.30/tar/tarsnap.1-man.in	2011-08-24 22:02:32.000000000 -0700
+++ tarsnap-autoconf-1.0.31/tar/tarsnap.1-man.in	2011-11-17 02:54:49.000000000 -0800
@@ -296,6 +296,11 @@
 In mode print-stats, if
 \fIarchive-name\fP
 is *, statistics will be printed for every archive.
+In the print-stats and d modes,
+\fB\-f\fP \fIarchive-name\fP
+can be specified multiple times, in which case the operation
+(printing statistics, or deletion) will be performed for each
+of the specified archives.
 .PP
 Note that each archive created must have a different name; consequently
 many users find it useful to include timestamps in archive names when
diff -ru tarsnap-autoconf-1.0.30/tar/tarsnap.1-mdoc.in tarsnap-autoconf-1.0.31/tar/tarsnap.1-mdoc.in
--- tarsnap-autoconf-1.0.30/tar/tarsnap.1-mdoc.in	2011-08-24 22:02:32.000000000 -0700
+++ tarsnap-autoconf-1.0.31/tar/tarsnap.1-mdoc.in	2011-11-17 02:54:49.000000000 -0800
@@ -289,6 +289,11 @@
 In mode print-stats, if
 .Ar archive-name
 is *, statistics will be printed for every archive.
+In the print-stats and d modes,
+.Fl f Ar archive-name
+can be specified multiple times, in which case the operation
+(printing statistics, or deletion) will be performed for each
+of the specified archives.
 .Pp
 Note that each archive created must have a different name; consequently
 many users find it useful to include timestamps in archive names when
diff -ru tarsnap-autoconf-1.0.30/tar/write.c tarsnap-autoconf-1.0.31/tar/write.c
--- tarsnap-autoconf-1.0.30/tar/write.c	2011-08-24 22:02:32.000000000 -0700
+++ tarsnap-autoconf-1.0.31/tar/write.c	2011-11-17 02:54:49.000000000 -0800
@@ -103,21 +103,6 @@
 /* Size of buffer for holding file data prior to writing. */
 #define FILEDATABUFLEN	65536
 
-/* Fixed size of uname/gname caches. */
-#define	name_cache_size 101
-
-static const char * const NO_NAME = "(noname)";
-
-struct name_cache {
-	int	probes;
-	int	hits;
-	size_t	size;
-	struct {
-		id_t id;
-		const char *name;
-	} cache[name_cache_size];
-};
-
 static int		 append_archive(struct bsdtar *, struct archive *,
 			     struct archive *ina, void * cookie);
 static int		 append_archive_filename(struct bsdtar *,
@@ -855,7 +840,7 @@
 		 * If this file/dir is flagged "nodump" and we're
 		 * honoring such flags, skip this file/dir.
 		 */
-#ifdef HAVE_STRUCT_STAT_ST_FLAGS
+#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
 		/* BSD systems store flags in struct stat */
 		if (bsdtar->option_honor_nodump &&
 		    (lst->st_flags & UF_NODUMP))
