--- tarsnap-1.0.29/keygen/keygen.c	2011-01-23 23:34:37.000000000 -0800
+++ tarsnap-1.0.30/keygen/keygen.c	2011-08-11 17:17:28.000000000 -0700
@@ -127,7 +127,8 @@
 
 	/*
 	 * It doesn't make sense to specify --passphrase-mem if we're not
-	 * using a passphrase. */
+	 * using a passphrase.
+	 */
 	if ((maxmem != 0) && (passphrased == 0))
 		usage();
 
@@ -136,11 +137,20 @@
 		fprintf(stderr, "User name too long: %s\n", C.user);
 		exit(1);
 	}
+	if (strlen(C.user) == 0) {
+		fprintf(stderr, "User name must be non-empty\n");
+		exit(1);
+	}
 
+	/* Sanity-check the machine name. */
 	if (strlen(C.name) > 255) {
 		fprintf(stderr, "Machine name too long: %s\n", C.name);
 		exit(1);
 	}
+	if (strlen(C.name) == 0) {
+		fprintf(stderr, "Machine name must be non-empty\n");
+		exit(1);
+	}
 
 	/* Get a password. */
 	if (tarsnap_readpass(&C.passwd, "Enter tarsnap account password",
--- tarsnap-1.0.29/keymgmt/keymgmt.c	2011-01-22 22:50:06.000000000 -0800
+++ tarsnap-1.0.30/keymgmt/keymgmt.c	2011-05-24 16:38:40.000000000 -0700
@@ -127,7 +127,8 @@
 
 	/*
 	 * It doesn't make sense to specify --passphrase-mem if we're not
-	 * using a passphrase. */
+	 * using a passphrase.
+	 */
 	if ((maxmem != 0) && (passphrased == 0))
 		usage();
 
--- tarsnap-1.0.29/keymgmt/tarsnap-keymgmt.1	2011-01-19 20:32:50.000000000 -0800
+++ tarsnap-1.0.30/keymgmt/tarsnap-keymgmt.1	2011-08-15 09:16:00.000000000 -0700
@@ -44,22 +44,23 @@
 .Pp
 The
 .Fl -recover
-command requires either
+command requires either (1)
 .Fl d
-(archive deleting),
+(archive deleting), (2)
 .Fl w
-(archive creating), or
+(archive creating), or (3)
 .Fl -nuke
 keys.
 The
 .Fl -fsck
-command requires either
-.Fl d
-(archive deleting) keys or
-.Fl r
-(archive reading) and
+command requires either (1) both
 .Fl w
-(archive writing) keys; while the
+(archive writing) and
+.Fl r
+(archive reading) keys, or (2)
+.Fl d
+(archive deleting) keys.
+The
 .Fl -fsck-prune
 command requires
 .Fl d
--- tarsnap-1.0.29/keyregen/keyregen.c	2011-02-02 03:46:11.000000000 -0800
+++ tarsnap-1.0.30/keyregen/keyregen.c	2011-05-29 21:51:29.000000000 -0700
@@ -77,7 +77,7 @@
 	uint64_t dummy;
 
 #ifdef NEED_WARN_PROGNAME
-	warn_progname = "tarsnap-keygen";
+	warn_progname = "tarsnap-rekeygen";
 #endif
 
 	/*
@@ -142,7 +142,8 @@
 
 	/*
 	 * It doesn't make sense to specify --passphrase-mem if we're not
-	 * using a passphrase. */
+	 * using a passphrase.
+	 */
 	if ((maxmem != 0) && (passphrased == 0))
 		usage();
 
@@ -151,11 +152,20 @@
 		fprintf(stderr, "User name too long: %s\n", C.user);
 		exit(1);
 	}
+	if (strlen(C.user) == 0) {
+		fprintf(stderr, "User name must be non-empty\n");
+		exit(1);
+	}
 
+	/* Sanity-check the machine name. */
 	if (strlen(C.name) > 255) {
 		fprintf(stderr, "Machine name too long: %s\n", C.name);
 		exit(1);
 	}
+	if (strlen(C.name) == 0) {
+		fprintf(stderr, "Machine name must be non-empty\n");
+		exit(1);
+	}
 
 	/* Get a password. */
 	if (tarsnap_readpass(&C.passwd, "Enter tarsnap account password",
--- tarsnap-1.0.29/lib/crypto/crypto.h	2011-01-22 22:34:00.000000000 -0800
+++ tarsnap-1.0.30/lib/crypto/crypto.h	2011-05-29 17:45:31.000000000 -0700
@@ -85,7 +85,7 @@
 typedef struct crypto_session_internal CRYPTO_SESSION;
 
 /**
- * crypto_entropy_init():
+ * crypto_entropy_init(void):
  * Initialize the PRNG.
  */
 int crypto_entropy_init(void);
@@ -98,7 +98,7 @@
 int crypto_entropy_read(uint8_t *, size_t);
 
 /**
- * crypto_keys_init():
+ * crypto_keys_init(void):
  * Initialize the key cache.  Note that crypto_entropy_init MUST be called
  * before this function.
  */
@@ -147,7 +147,7 @@
 
 /**
  * crypto_hash_data_key_2(key, keylen, data0, len0, data1, len1, buf):
- * Hash the concatentation of two buffers with the provided HMAC-SHA256 key.
+ * Hash the concatenation of two buffers with the provided HMAC-SHA256 key.
  */
 void crypto_hash_data_key_2(const uint8_t *, size_t,
     const uint8_t *, size_t, const uint8_t *, size_t, uint8_t[32]);
@@ -237,7 +237,7 @@
 
 /**
  * crypto_session_init(pub, priv, nonce, mkey, encr_write, auth_write,
- *     encr_read, auth_read, proofs):
+ *     encr_read, auth_read):
  * Compute K = ${pub}^(2^258 + ${priv}), mkey = MGF1(nonce || K, 48), and
  * return a CRYPTO_SESSION with encryption and authentication write and read
  * keys constructed from HMAC(mkey, (encr|auth)_(write|read)).
--- tarsnap-1.0.29/lib/crypto/crypto_entropy.c	2011-01-19 20:32:50.000000000 -0800
+++ tarsnap-1.0.30/lib/crypto/crypto_entropy.c	2011-05-29 17:45:45.000000000 -0700
@@ -154,7 +154,7 @@
 }
 
 /**
- * crypto_entropy_init():
+ * crypto_entropy_init(void):
  * Initialize the PRNG.
  */
 int
--- tarsnap-1.0.29/lib/crypto/crypto_file.c	2011-01-22 15:56:03.000000000 -0800
+++ tarsnap-1.0.30/lib/crypto/crypto_file.c	2011-05-29 17:45:55.000000000 -0700
@@ -23,7 +23,7 @@
 static int keygen(void);
 
 /**
- * crypto_file_init_keys():
+ * crypto_file_init_keys(void):
  * Initialize the keys cached by crypto_file.
  */
 int
--- tarsnap-1.0.29/lib/crypto/crypto_hash.c	2011-01-19 20:32:50.000000000 -0800
+++ tarsnap-1.0.30/lib/crypto/crypto_hash.c	2011-07-28 21:06:38.000000000 -0700
@@ -24,7 +24,7 @@
 
 /**
  * crypto_hash_data_key_2(key, keylen, data0, len0, data1, len1, buf):
- * Hash the concatentation of two buffers with the provided HMAC-SHA256 key.
+ * Hash the concatenation of two buffers with the provided HMAC-SHA256 key.
  */
 void
 crypto_hash_data_key_2(const uint8_t * key, size_t keylen,
--- tarsnap-1.0.29/lib/crypto/crypto_internal.h	2011-01-19 20:32:50.000000000 -0800
+++ tarsnap-1.0.30/lib/crypto/crypto_internal.h	2011-05-29 17:46:06.000000000 -0700
@@ -27,7 +27,7 @@
 struct crypto_hmac_key * crypto_keys_lookup_HMAC(int);
 
 /**
- * crypto_keys_server_import_root():
+ * crypto_keys_server_import_root(void):
  * Import the public part of the server root key.
  */
 int crypto_keys_server_import_root(void);
@@ -86,7 +86,7 @@
 int crypto_keys_subr_generate_HMAC(struct crypto_hmac_key **);
 
 /**
- * crypto_file_init_keys():
+ * crypto_file_init_keys(void):
  * Initialize the keys cached by crypto_file.
  */
 int crypto_file_init_keys(void);
--- tarsnap-1.0.29/lib/crypto/crypto_keys.c	2011-01-30 09:31:34.000000000 -0800
+++ tarsnap-1.0.30/lib/crypto/crypto_keys.c	2011-05-30 06:02:18.000000000 -0700
@@ -112,7 +112,7 @@
 }
 
 /**
- * crypto_keys_init():
+ * crypto_keys_init(void):
  * Initialize the key cache.
  */
 int
@@ -505,7 +505,7 @@
 		keys &= ~CRYPTO_KEYMASK_HMAC_NAME;
 	}
 
-	/* Chunkfication parameters HMAC key. */
+	/* Chunkification parameters HMAC key. */
 	if (keys & CRYPTO_KEYMASK_HMAC_CPARAMS) {
 		if (crypto_keys_subr_generate_HMAC(&keycache.hmac_cparams))
 			goto err0;
@@ -646,7 +646,7 @@
 
 /**
  * crypto_keys_lookup_HMAC(key):
- * Return the requested HMAC key
+ * Return the requested HMAC key.
  */
 struct crypto_hmac_key *
 crypto_keys_lookup_HMAC(int key)
--- tarsnap-1.0.29/lib/crypto/crypto_keys_server.c	2011-01-22 22:40:46.000000000 -0800
+++ tarsnap-1.0.30/lib/crypto/crypto_keys_server.c	2011-05-29 17:46:25.000000000 -0700
@@ -49,7 +49,7 @@
 };
 
 /**
- * crypto_keys_server_import_root():
+ * crypto_keys_server_import_root(void):
  * Import the public part of the server root key.
  */
 int
--- tarsnap-1.0.29/lib/crypto/crypto_session.c	2011-01-19 20:32:50.000000000 -0800
+++ tarsnap-1.0.30/lib/crypto/crypto_session.c	2011-04-21 12:45:47.000000000 -0700
@@ -51,7 +51,7 @@
 	memcpy(MGFbuf + 32, K, CRYPTO_DH_PUBLEN);
 	crypto_MGF1(MGFbuf, 32 + CRYPTO_DH_PUBLEN, mkey, 48);
 
-	/* Allocate space for session key stucture. */
+	/* Allocate space for session key structure. */
 	if ((CS = malloc(sizeof(struct crypto_session_internal))) == NULL)
 		goto err0;
 
--- tarsnap-1.0.29/lib/crypto/sha256.c	2011-01-19 20:32:50.000000000 -0800
+++ tarsnap-1.0.30/lib/crypto/sha256.c	2011-07-28 21:09:46.000000000 -0700
@@ -171,7 +171,7 @@
 	RNDr(S, W, 62, 0xbef9a3f7);
 	RNDr(S, W, 63, 0xc67178f2);
 
-	/* 4. Mix local working variables into global state */
+	/* 4. Mix local working variables into global state. */
 	for (i = 0; i < 8; i++)
 		state[i] += S[i];
 
@@ -201,12 +201,12 @@
 	 */
 	be32enc_vect(len, ctx->count, 8);
 
-	/* Add 1--64 bytes so that the resulting length is 56 mod 64 */
+	/* Add 1--64 bytes so that the resulting length is 56 mod 64. */
 	r = (ctx->count[1] >> 3) & 0x3f;
 	plen = (r < 56) ? (56 - r) : (120 - r);
 	SHA256_Update(ctx, PAD, (size_t)plen);
 
-	/* Add the terminating bit-count */
+	/* Add the terminating bit-count. */
 	SHA256_Update(ctx, len, 8);
 }
 
@@ -215,10 +215,10 @@
 SHA256_Init(SHA256_CTX * ctx)
 {
 
-	/* Zero bits processed so far */
+	/* Zero bits processed so far. */
 	ctx->count[0] = ctx->count[1] = 0;
 
-	/* Magic initialization constants */
+	/* Magic initialization constants. */
 	ctx->state[0] = 0x6A09E667;
 	ctx->state[1] = 0xBB67AE85;
 	ctx->state[2] = 0x3C6EF372;
@@ -229,7 +229,7 @@
 	ctx->state[7] = 0x5BE0CD19;
 }
 
-/* Add bytes into the hash */
+/* Add bytes into the hash. */
 void
 SHA256_Update(SHA256_CTX * ctx, const void *in, size_t len)
 {
@@ -237,38 +237,42 @@
 	uint32_t r;
 	const unsigned char *src = in;
 
-	/* Number of bytes left in the buffer from previous updates */
+	/* Return immediately if we have nothing to do. */
+	if (len == 0)
+		return;
+
+	/* Number of bytes left in the buffer from previous updates. */
 	r = (ctx->count[1] >> 3) & 0x3f;
 
-	/* Convert the length into a number of bits */
+	/* Convert the length into a number of bits. */
 	bitlen[1] = ((uint32_t)len) << 3;
 	bitlen[0] = (uint32_t)(len >> 29);
 
-	/* Update number of bits */
+	/* Update number of bits. */
 	if ((ctx->count[1] += bitlen[1]) < bitlen[1])
 		ctx->count[0]++;
 	ctx->count[0] += bitlen[0];
 
-	/* Handle the case where we don't need to perform any transforms */
+	/* Handle the case where we don't need to perform any transforms. */
 	if (len < 64 - r) {
 		memcpy(&ctx->buf[r], src, len);
 		return;
 	}
 
-	/* Finish the current block */
+	/* Finish the current block. */
 	memcpy(&ctx->buf[r], src, 64 - r);
 	SHA256_Transform(ctx->state, ctx->buf);
 	src += 64 - r;
 	len -= 64 - r;
 
-	/* Perform complete blocks */
+	/* Perform complete blocks. */
 	while (len >= 64) {
 		SHA256_Transform(ctx->state, src);
 		src += 64;
 		len -= 64;
 	}
 
-	/* Copy left over data into buffer */
+	/* Copy left over data into buffer. */
 	memcpy(ctx->buf, src, len);
 }
 
@@ -280,13 +284,13 @@
 SHA256_Final(unsigned char digest[32], SHA256_CTX * ctx)
 {
 
-	/* Add padding */
+	/* Add padding. */
 	SHA256_Pad(ctx);
 
-	/* Write the hash */
+	/* Write the hash. */
 	be32enc_vect(digest, ctx->state, 32);
 
-	/* Clear the context state */
+	/* Clear the context state. */
 	memset((void *)ctx, 0, sizeof(*ctx));
 }
 
--- tarsnap-1.0.29/lib/datastruct/patricia.c	2011-01-19 20:32:51.000000000 -0800
+++ tarsnap-1.0.30/lib/datastruct/patricia.c	2011-05-29 17:47:14.000000000 -0700
@@ -49,7 +49,7 @@
  *
  * In some applications it may be preferable to eliminate variable-length
  * memory allocations entirely and provide the same size of memory allocation
- * to each node; if this is done, it would almost certainly be desireable to
+ * to each node; if this is done, it would almost certainly be desirable to
  * reduce MAXSLEN further, e.g., to (2 * sizeof(void *) - 3) so that each
  * node would be of size (4 * sizeof(void *)).
  */
@@ -241,7 +241,7 @@
 }
 
 /*
- * Recusively free the tree.
+ * Recursively free the tree.
  */
 static void
 free_internal(struct pnode * n)
@@ -260,7 +260,7 @@
 }
 
 /**
- * patricia_init():
+ * patricia_init(void):
  * Create a Patricia tree to be used for mapping arbitrary-length keys to
  * records.  Return NULL on failure.
  */
@@ -335,7 +335,7 @@
 			 * Split the node *np after mlen bytes and a number
 			 * of bits based on mask.  Leave *np pointing to the
 			 * upper of the two nodes (because we will continue
-			 * by traversing into the so-far-nonexistant child
+			 * by traversing into the so-far-nonexistent child
 			 * of the new node).
 			 */
 			/* Create the lower of the new nodes. */
@@ -468,7 +468,7 @@
 
 /**
  * patricia_foreach(tree, func, cookie):
- * Traverse the tree in lexographical order of stored keys, and call
+ * Traverse the tree in lexicographical order of stored keys, and call
  * func(cookie, key, keylen, rec) for each (key, record) pair.  Stop the
  * traversal early if func returns a non-zero value; return zero, the
  * non-zero value returned by func, or (-1) if an error occurs in the
@@ -507,7 +507,7 @@
 patricia_free(PATRICIA * P)
 {
 
-	/* Behave consistenly with free(NULL). */
+	/* Behave consistently with free(NULL). */
 	if (P == NULL)
 		return;
 
--- tarsnap-1.0.29/lib/datastruct/patricia.h	2011-01-19 20:32:51.000000000 -0800
+++ tarsnap-1.0.30/lib/datastruct/patricia.h	2011-05-29 17:47:08.000000000 -0700
@@ -10,7 +10,7 @@
 typedef struct patricia_internal PATRICIA;
 
 /**
- * patricia_init():
+ * patricia_init(void):
  * Create a Patricia tree to be used for mapping arbitrary-length keys to
  * records.  Return NULL on failure.
  */
@@ -42,7 +42,7 @@
 
 /**
  * patricia_foreach(tree, func, cookie):
- * Traverse the tree in lexographical order of stored keys, and call
+ * Traverse the tree in lexicographical order of stored keys, and call
  * func(cookie, key, keylen, rec) for each (key, record) pair.  Stop the
  * traversal early if func returns a non-zero value; return zero, the
  * non-zero value returned by func, or (-1) if an error occurs in the
--- tarsnap-1.0.29/lib/datastruct/rwhashtab.c	2011-01-19 20:32:51.000000000 -0800
+++ tarsnap-1.0.30/lib/datastruct/rwhashtab.c	2011-05-24 23:19:13.000000000 -0700
@@ -37,21 +37,20 @@
 };
 
 static int rwhashtab_enlarge(RWHASHTAB * H);
-static size_t rwhashtab_search(RWHASHTAB * H, void ** ht, size_t size,
-    const uint8_t * key);
+static size_t rwhashtab_search(RWHASHTAB * H, const uint8_t * key);
 
-/* Enlarge the table by a factor of 2, and rehash */
+/* Enlarge the table by a factor of 2, and rehash. */
 static int
 rwhashtab_enlarge(RWHASHTAB * H)
 {
-	void ** htnew;
+	void ** htnew, ** htold;
 	void * rec;
-	size_t newsize;
+	size_t newsize, oldsize;
 	size_t htposold, htposnew;
 
 	/*
 	 * Compute new size, and make sure the new table size in bytes
-	 * doesn't overflow
+	 * doesn't overflow.
 	 */
 	newsize = H->cursize * 2;
 	if (newsize > SIZE_MAX / sizeof(void *)) {
@@ -59,27 +58,30 @@
 		return (-1);
 	}
 
-	/* Allocate and zero the new space */
-	htnew = malloc(newsize * sizeof(void *));
-	if (htnew == NULL)
+	/* Allocate and zero the new space. */
+	if ((htnew = malloc(newsize * sizeof(void *))) == NULL)
 		return (-1);
 	for (htposnew = 0; htposnew < newsize; htposnew++)
 		htnew[htposnew] = NULL;
 
-	/* Rehash into new table */
-	for (htposold = 0; htposold < H->cursize; htposold++) {
-		rec = H->ht[htposold];
+	/* Attach new space to hash table. */
+	htold = H->ht;
+	H->ht = htnew;
+	oldsize = H->cursize;
+	H->cursize = newsize;
+
+	/* Rehash into new table. */
+	for (htposold = 0; htposold < oldsize; htposold++) {
+		rec = htold[htposold];
 		if (rec != NULL) {
-			htposnew = rwhashtab_search(H, htnew, newsize,
+			htposnew = rwhashtab_search(H,
 			    (uint8_t *)rec + H->keyoffset);
-			htnew[htposnew] = rec;
+			H->ht[htposnew] = rec;
 		}
 	}
 
-	/* Update fields in H and free now-unused memory. */
-	free(H->ht);
-	H->ht = htnew;
-	H->cursize = newsize;
+	/* Free now-unused memory. */
+	free(htold);
 
 	/* Success! */
 	return (0);
@@ -90,12 +92,12 @@
  * Return the position of the record or of the first NULL found.
  */
 static size_t
-rwhashtab_search(RWHASHTAB * H, void ** ht, size_t size, const uint8_t * key)
+rwhashtab_search(RWHASHTAB * H, const uint8_t * key)
 {
 	size_t htpos;
 	uint8_t hashbuf[32];
 
-	/* Compute the hash of the record key */
+	/* Compute the hash of the record key. */
 	if (crypto_hash_data_2(CRYPTO_KEY_HMAC_SHA256, H->randbuf, 32,
 	    key, H->keylength, hashbuf)) {
 		warn0("Programmer error: "
@@ -103,8 +105,8 @@
 		abort();
 	}
 
-	/* Compute starting hash location */
-	htpos = le64dec(hashbuf) & (size - 1);
+	/* Compute starting hash location. */
+	htpos = le64dec(hashbuf) & (H->cursize - 1);
 
 	/*
 	 * Search.  This is not an endless loop since the table isn't
@@ -112,16 +114,16 @@
 	 */
 	do {
 		/* Is the space empty? */
-		if (ht[htpos] == NULL)
+		if (H->ht[htpos] == NULL)
 			return (htpos);
 
 		/* Do we have the right key? */
-		if (memcmp((uint8_t *)(ht[htpos]) + H->keyoffset,
+		if (memcmp((uint8_t *)(H->ht[htpos]) + H->keyoffset,
 		    key, H->keylength) == 0)
 			return (htpos);
 
-		/* Move to the next table entry */
-		htpos = (htpos + 1) & (size - 1);
+		/* Move to the next table entry. */
+		htpos = (htpos + 1) & (H->cursize - 1);
 	} while (1);
 }
 
@@ -137,7 +139,7 @@
 	RWHASHTAB * H;
 	size_t i;
 
-	/* Sanity check */
+	/* Sanity check. */
 	if (keylength == 0)
 		return (NULL);
 
@@ -156,14 +158,14 @@
 		return (NULL);
 	}
 
-	/* Allocate space for pointers to records */
+	/* Allocate space for pointers to records. */
 	H->ht = malloc(H->cursize * sizeof(void *));
 	if (H->ht == NULL) {
 		free(H);
 		return (NULL);
 	}
 
-	/* All of the entries are empty */
+	/* All of the entries are empty. */
 	for (i = 0; i < H->cursize; i++)
 		H->ht[i] = NULL;
 
@@ -200,14 +202,13 @@
 	 * Search for the record, to see if it is already present and/or
 	 * where it should be inserted.
 	 */
-	htpos = rwhashtab_search(H, H->ht, H->cursize,
-	    (uint8_t *)rec + H->keyoffset);
+	htpos = rwhashtab_search(H, (uint8_t *)rec + H->keyoffset);
 
 	/* Already present? */
 	if (H->ht[htpos] != NULL)
 		return (1);
 
-	/* Insert the record */
+	/* Insert the record. */
 	H->ht[htpos] = rec;
 	H->numentries += 1;
 	return (0);
@@ -223,10 +224,10 @@
 {
 	size_t htpos;
 
-	/* Search */
-	htpos = rwhashtab_search(H, H->ht, H->cursize, key);
+	/* Search. */
+	htpos = rwhashtab_search(H, key);
 
-	/* Return the record, or NULL if not present */
+	/* Return the record, or NULL if not present. */
 	return (H->ht[htpos]);
 }
 
@@ -261,11 +262,11 @@
 rwhashtab_free(RWHASHTAB * H)
 {
 
-	/* Behave consistenly with free(NULL). */
+	/* Behave consistently with free(NULL). */
 	if (H == NULL)
 		return;
 
-	/* Free everything */
+	/* Free everything. */
 	free(H->ht);
 	free(H);
 }
--- tarsnap-1.0.29/lib/netpacket/netpacket_op.c	2011-01-30 09:41:47.000000000 -0800
+++ tarsnap-1.0.30/lib/netpacket/netpacket_op.c	2011-08-07 08:27:00.000000000 -0700
@@ -23,6 +23,9 @@
 /* Maximum number of times we'll try to reconnect. */
 #define MAXRECONNECTS	10
 
+/* As above, except the server doesn't seem to be around at all. */
+#define MAXRECONNECTS_AWOL	1
+
 /* Time to wait between each attempt. */
 static int reconnect_wait[MAXRECONNECTS + 1] = {
     0, 0, 1, 2, 4, 8, 15, 30, 60, 90, 90
@@ -235,10 +238,10 @@
 	/* We're not reading a packet any more, if we ever were. */
 	NPC->reading = 0;
 
-	/* Have we lost out connection / failed to connect too many times? */
+	/* Have we lost our connection / failed to connect too many times? */
 	NPC->ndrops += 1;
-	if ((NPC->ndrops > 10) ||
-	    (NPC->serveralive == 0 && NPC->ndrops > 1)) {
+	if ((NPC->ndrops > MAXRECONNECTS) ||
+	    (NPC->serveralive == 0 && NPC->ndrops > MAXRECONNECTS_AWOL)) {
 		warn0("Too many network failures");
 		goto err0;
 	}
@@ -502,6 +505,9 @@
 		NPC->pending_current = next;
 	}
 
+	/* Free string allocated by strdup. */
+	free(NPC->useragent);
+
 	/* Free the cookie. */
 	free(NPC);
 
@@ -516,6 +522,7 @@
 		NPC->pending_current = next;
 	}
 
+	free(NPC->useragent);
 	free(NPC);
 
 	/* Failure! */
--- tarsnap-1.0.29/lib/netpacket/packets.txt	2011-01-19 20:32:51.000000000 -0800
+++ tarsnap-1.0.30/lib/netpacket/packets.txt	2011-04-21 12:51:50.000000000 -0700
@@ -546,7 +546,7 @@
 A status value of 3 will only ever be sent in response to a DIRECTORY
 request, not to a DIRECTORY_D request.
 
-The files returned are the first nfiles files after start in lexographical
+The files returned are the first nfiles files after start in lexicographical
 order.
 
 The value hmac is HMACR(0xd0 || nonce || [packet minus final hmac]), where
--- tarsnap-1.0.29/lib/netproto/netproto.c	2011-01-19 20:32:51.000000000 -0800
+++ tarsnap-1.0.30/lib/netproto/netproto.c	2011-04-21 12:48:58.000000000 -0700
@@ -155,7 +155,7 @@
 
 	/*
 	 * Our wake-up call is happening right now; record that there is no
-	 * pending callback so that we don't try to unregister it when the
+	 * pending callback so that we don't try to deregister it when the
 	 * connection is closed later.
 	 */
 	C->sleepcookie.handle = -1;
--- tarsnap-1.0.29/lib/netproto/netproto.h	2011-01-19 20:32:51.000000000 -0800
+++ tarsnap-1.0.30/lib/netproto/netproto.h	2011-04-21 12:49:41.000000000 -0700
@@ -24,7 +24,7 @@
 
 /**
  * netproto_connect(useragent, callback, cookie):
- * Create a socket, connect to the tarsnap server, and perform the neccesary
+ * Create a socket, connect to the tarsnap server, and perform the necessary
  * key exchange.  Return a network protocol connection cookie; note that
  * this cookie must not be used until the callback is called.
  */
--- tarsnap-1.0.29/lib/netproto/netproto_connect.c	2011-01-19 20:32:51.000000000 -0800
+++ tarsnap-1.0.30/lib/netproto/netproto_connect.c	2011-04-21 12:49:53.000000000 -0700
@@ -191,7 +191,7 @@
 
 /**
  * netproto_connect(useragent, callback, cookie):
- * Create a socket, connect to the tarsnap server, and perform the neccesary
+ * Create a socket, connect to the tarsnap server, and perform the necessary
  * key exchange.  Return a network protocol connection cookie; note that
  * this cookie must not be used until the callback is called.
  */
--- tarsnap-1.0.29/lib/netproto/netproto_keyexchange.c	2011-01-30 09:22:58.000000000 -0800
+++ tarsnap-1.0.30/lib/netproto/netproto_keyexchange.c	2011-04-21 12:49:19.000000000 -0700
@@ -354,7 +354,7 @@
 
 	/*-
 	 * NOTE: We could construct the session keys, and compute and send
-	 * the proof of key posession in dh_received instead of here; doing
+	 * the proof of key possession in dh_received instead of here; doing
 	 * so would reduce the bandwidth used since the two messages of 256
 	 * and 32 bytes would be coalesced into a single TCP/IP packet, but
 	 * it would slow down the connection setup since it would prevent the
--- tarsnap-1.0.29/lib/netproto/netproto_packet.c	2011-01-19 20:32:51.000000000 -0800
+++ tarsnap-1.0.30/lib/netproto/netproto_packet.c	2011-05-24 23:20:24.000000000 -0700
@@ -90,7 +90,7 @@
 		goto err1;
 	}
 
-	/* Decrypt header in-place */
+	/* Decrypt header in-place. */
 	crypto_session_decrypt(RC->C->keys, RC->header, RC->header, 37);
 
 	/* Decode packet length. */
--- tarsnap-1.0.29/lib/network/network.h	2011-01-19 20:32:50.000000000 -0800
+++ tarsnap-1.0.30/lib/network/network.h	2011-06-20 00:04:06.000000000 -0700
@@ -27,7 +27,7 @@
 #define NETWORK_STATUS_MAX	6
 
 /**
- * network_init():
+ * network_init(void):
  * Initialize the network subsystem.
  */
 int network_init(void);
@@ -106,7 +106,7 @@
     network_callback *, void *);
 
 /**
- * network_write(fd, buf, buflen, timeo, callback, cookie):
+ * network_read(fd, buf, buflen, to0, to1, callback, cookie):
  * Asynchronously write data from the provided buffer to ${fd}, and call
  * callback(cookie, status) where status is a NETWORK_STATUS_* value.  Time
  * out if no data can be written for a period of time to0, or if the complete
@@ -166,7 +166,7 @@
 void network_getselectstats(double *, double *, double *, double *);
 
 /**
- * network_fini():
+ * network_fini(void):
  * Free resources associated with the network subsystem.
  */
 void network_fini(void);
--- tarsnap-1.0.29/lib/network/network_buf.c	2011-01-19 20:32:50.000000000 -0800
+++ tarsnap-1.0.30/lib/network/network_buf.c	2011-06-20 00:04:25.000000000 -0700
@@ -260,7 +260,7 @@
 }
 
 /**
- * network_write(fd, buf, buflen, timeo, callback, cookie):
+ * network_read(fd, buf, buflen, to0, to1, callback, cookie):
  * Asynchronously write data from the provided buffer to ${fd}, and call
  * callback(cookie, status) where status is a NETWORK_STATUS_* value.  Time
  * out if no data can be written for a period of time to0, or if the complete
--- tarsnap-1.0.29/lib/network/network_connect.c	2011-01-19 20:32:50.000000000 -0800
+++ tarsnap-1.0.30/lib/network/network_connect.c	2011-04-21 12:50:09.000000000 -0700
@@ -126,7 +126,7 @@
 	 * If FreeBSD's net.inet.ip.portrange.randomized sysctl is set to 1
 	 * (the default value) FreeBSD sometimes reuses a source port faster
 	 * than might naively be expected.  This doesn't cause any problems
-	 * except if the pf filewall is running on the source system; said
+	 * except if the pf firewall is running on the source system; said
 	 * firewall detects the packet as belonging to an expired connection
 	 * and drops it.  This would be fine, except that the FreeBSD kernel
 	 * doesn't merely drop the packet when a firewall blocks an outgoing
--- tarsnap-1.0.29/lib/network/network_select.c	2011-01-19 20:32:50.000000000 -0800
+++ tarsnap-1.0.30/lib/network/network_select.c	2011-08-14 13:15:16.000000000 -0700
@@ -91,7 +91,8 @@
 		cplen = nlen;
 	else
 		cplen = clen;
-	memcpy(nbuf, *ptr, cplen * size);
+	if (cplen > 0)
+		memcpy(nbuf, *ptr, cplen * size);
 
 	/* Zero any uninitialized buffer contents. */
 	memset((void *)((char *)nbuf + cplen * size), 0,
@@ -206,7 +207,7 @@
 }
 
 /**
- * network_init():
+ * network_init(void):
  * Initialize the network subsystem and return a cookie.
  */
 int
@@ -730,7 +731,7 @@
 }
 
 /**
- * network_fini():
+ * network_fini(void):
  * Free resources associated with the network subsystem.
  */
 void
--- tarsnap-1.0.29/lib/scryptenc/scryptenc.c	2011-01-19 20:32:50.000000000 -0800
+++ tarsnap-1.0.30/lib/scryptenc/scryptenc.c	2011-08-07 08:21:43.000000000 -0700
@@ -317,7 +317,7 @@
 /**
  * scryptdec_buf(inbuf, inbuflen, outbuf, outlen, passwd, passwdlen,
  *     maxmem, maxmemfrac, maxtime):
- * Decrypt inbuflen bytes fro inbuf, writing the result into outbuf and the
+ * Decrypt inbuflen bytes from inbuf, writing the result into outbuf and the
  * decrypted data length to outlen.  The allocated length of outbuf must
  * be at least inbuflen.
  */
@@ -473,7 +473,7 @@
 	int rc;
 
 	/*
-	 * Read the first 7 bytes of the file; all future version of scrypt
+	 * Read the first 7 bytes of the file; all future versions of scrypt
 	 * are guaranteed to have at least 7 bytes of header.
 	 */
 	if (fread(header, 7, 1, infile) < 1) {
@@ -490,7 +490,7 @@
 		return (8);
 
 	/*
-	 * Read another 89 bytes of the file; version 0 of the srypt file
+	 * Read another 89 bytes of the file; version 0 of the scrypt file
 	 * format has a 96-byte header.
 	 */
 	if (fread(&header[7], 89, 1, infile) < 1) {
--- tarsnap-1.0.29/lib/scryptenc/scryptenc_cpuperf.c	2011-01-19 20:32:51.000000000 -0800
+++ tarsnap-1.0.30/lib/scryptenc/scryptenc_cpuperf.c	2011-08-07 08:24:39.000000000 -0700
@@ -156,7 +156,7 @@
 			break;
 	} while (1);
 
-	/* Could how many scryps we can do before the next tick. */
+	/* Count how many scrypts we can do before the next tick. */
 	if (getclocktime(&st))
 		return (2);
 	do {
--- tarsnap-1.0.29/lib/util/dirutil.c	2011-01-19 20:32:50.000000000 -0800
+++ tarsnap-1.0.30/lib/util/dirutil.c	2011-05-24 23:16:52.000000000 -0700
@@ -74,7 +74,7 @@
 			return (-1);
 		}
 
-		/* Directory does not exist; try to create it */
+		/* Directory does not exist; try to create it. */
 		if (mkdir(dirname, 0777)) {
 			warnp("mkdir(%s)", dirname);
 			return (-1);
--- tarsnap-1.0.29/lib/util/readpass.c	2011-01-19 20:32:50.000000000 -0800
+++ tarsnap-1.0.30/lib/util/readpass.c	2011-04-24 01:43:03.000000000 -0700
@@ -69,13 +69,13 @@
 	if ((usingtty = isatty(fileno(readfrom))) != 0) {
 		if (tcgetattr(fileno(readfrom), &term_old)) {
 			warnp("Cannot read terminal settings");
-			goto err1;
+			goto err2;
 		}
 		memcpy(&term, &term_old, sizeof(struct termios));
 		term.c_lflag = (term.c_lflag & ~ECHO) | ECHONL;
 		if (tcsetattr(fileno(readfrom), TCSANOW, &term)) {
 			warnp("Cannot set terminal settings");
-			goto err1;
+			goto err2;
 		}
 	}
 
@@ -87,7 +87,7 @@
 	/* Read the password. */
 	if (fgets(passbuf, MAXPASSLEN, readfrom) == NULL) {
 		warnp("Cannot read password");
-		goto err2;
+		goto err3;
 	}
 
 	/* Confirm the password if necessary. */
@@ -96,7 +96,7 @@
 			fprintf(stderr, "%s: ", confirmprompt);
 		if (fgets(confpassbuf, MAXPASSLEN, readfrom) == NULL) {
 			warnp("Cannot read password");
-			goto err2;
+			goto err3;
 		}
 		if (strcmp(passbuf, confpassbuf)) {
 			fprintf(stderr,
@@ -127,14 +127,18 @@
 	/* Success! */
 	return (0);
 
-err2:
+err3:
 	/* Reset terminal settings if necessary. */
 	if (usingtty)
 		tcsetattr(fileno(readfrom), TCSAFLUSH, &term_old);
-err1:
+err2:
 	/* Close /dev/tty if we opened it. */
 	if (readfrom != stdin)
 		fclose(readfrom);
+err1:
+	/* Zero any stored passwords. */
+	memset(passbuf, 0, MAXPASSLEN);
+	memset(confpassbuf, 0, MAXPASSLEN);
 
 	/* Failure! */
 	return (-1);
--- tarsnap-1.0.29/lib/util/sigquit.c	2011-01-19 20:32:50.000000000 -0800
+++ tarsnap-1.0.30/lib/util/sigquit.c	2011-05-24 23:23:39.000000000 -0700
@@ -32,7 +32,7 @@
 }
 
 /**
- * termios_restore():
+ * termios_restore(void):
  * Restore the saved tc_saved termios state.
  */
 static void
@@ -72,7 +72,7 @@
 }
 
 /**
- * sigquit_init():
+ * sigquit_init(void):
  * Prepare to catch SIGQUIT and ^Q, and zero sigquit_received.
  */
 int
--- tarsnap-1.0.29/lib/util/sigquit.h	2011-01-19 20:32:50.000000000 -0800
+++ tarsnap-1.0.30/lib/util/sigquit.h	2011-05-24 23:24:21.000000000 -0700
@@ -7,7 +7,7 @@
 sig_atomic_t sigquit_received;
 
 /**
- * sigquit_init():
+ * sigquit_init(void):
  * Prepare to catch SIGQUIT and zero sigquit_received.
  */
 int sigquit_init(void);
--- tarsnap-1.0.29/libarchive/archive.h	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive.h	2011-05-30 06:14:50.000000000 -0700
@@ -245,7 +245,7 @@
  * will change the format code to indicate the extended format that
  * was used).  In other cases, it's because different tools have
  * modified the archive and so different parts of the archive
- * actually have slightly different formts.  (Both tar and cpio store
+ * actually have slightly different formats.  (Both tar and cpio store
  * format codes in each entry, so it is quite possible for each
  * entry to be in a different format.)
  */
@@ -492,7 +492,7 @@
 
 /*-
  * To create an archive:
- *   1) Ask archive_write_new for a archive writer object.
+ *   1) Ask archive_write_new for an archive writer object.
  *   2) Set any global properties.  In particular, you should set
  *      the compression and format to use.
  *   3) Call archive_write_open to open the file (most people
--- tarsnap-1.0.29/libarchive/archive_check_magic.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_check_magic.c	2011-05-08 13:48:23.000000000 -0700
@@ -60,7 +60,7 @@
 	/* Cause a breakpoint exception  */
 	DebugBreak();
 #endif
-	*(char *)0 = 1;	/* Deliberately segfault and force a coredump. */
+	*(volatile char *)0 = 1;	/* Deliberately segfault and force a coredump. */
 	_exit(1);	/* If that didn't work, just exit with an error. */
 }
 
--- tarsnap-1.0.29/libarchive/archive_entry.h	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_entry.h	2011-08-08 13:01:16.000000000 -0700
@@ -425,7 +425,7 @@
  *      be written.
  *   4. Call archive_entry_linkify(resolver, NULL) until
  *      no more entries are returned.
- *   5. Call archive_entry_link_resolver_free(resolver) to free resources.
+ *   5. Call archive_entry_linkresolver_free(resolver) to free resources.
  *
  * The entries returned have their hardlink and size fields updated
  * appropriately.  If an entry is passed in that does not refer to
@@ -475,7 +475,7 @@
  *           linkify(l2) => l1
  *           linkify(NULL) => l2   (at end, you retrieve remaining links)
  *    As the name suggests, this strategy is used by newer cpio variants.
- *    It's noticably more complex for the archiver, slightly more complex
+ *    It's noticeably more complex for the archiver, slightly more complex
  *    for the dearchiver than the tar strategy, but makes it straightforward
  *    to restore a file using any link by simply continuing to scan until
  *    you see a link that is stored with a body.  In contrast, the tar
--- tarsnap-1.0.29/libarchive/archive_entry_private.h	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_entry_private.h	2011-06-19 17:55:10.000000000 -0700
@@ -97,10 +97,15 @@
 	 */
 
 	/*
-	 * Read archive_entry_copy_stat.c for an explanation of why I
-	 * don't just use "struct stat" instead of "struct aest" here
-	 * and why I have this odd pointer to a separately-allocated
-	 * struct stat.
+	 * We have a "struct aest" for holding file metadata rather than just
+	 * a "struct stat" because on some platforms the "struct stat" has
+	 * fields which are too narrow to hold the range of possible values;
+	 * we don't want to lose information if we read an archive and write
+	 * out another (e.g., in "tar -cf new.tar @old.tar").
+	 *
+	 * The "stat" pointer points to some form of platform-specific struct
+	 * stat; it is declared as a void * rather than a struct stat * as
+	 * some platforms have multiple varieties of stat structures.
 	 */
 	void *stat;
 	int  stat_valid; /* Set to 0 whenever a field in aest changes. */
--- tarsnap-1.0.29/libarchive/archive_read.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_read.c	2011-08-08 13:53:11.000000000 -0700
@@ -70,6 +70,7 @@
 	if (!inited) {
 		av.archive_finish = _archive_read_finish;
 		av.archive_close = _archive_read_close;
+		inited = 1;
 	}
 	return (&av);
 }
@@ -169,7 +170,6 @@
 	a = (struct archive_read *)_a;
 	__archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC,
 	    ARCHIVE_STATE_NEW, "archive_read_set_filter_options");
-	filter = a->filter;
 	len = 0;
 	for (filter = a->filter; filter != NULL; filter = filter->upstream) {
 		bidder = filter->bidder;
@@ -474,7 +474,7 @@
 	best_bid = -1;
 	best_bid_slot = -1;
 
-	/* Set up a->format and a->pformat_data for convenience of bidders. */
+	/* Set up a->format for convenience of bidders. */
 	a->format = &(a->formats[0]);
 	for (i = 0; i < slots; i++, a->format++) {
 		if (a->format->bid) {
@@ -729,7 +729,7 @@
 	if (a->format->read_data == NULL) {
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
 		    "Internal error: "
-		    "No format_read_data_block function registered");
+		    "No format->read_data function registered");
 		return (ARCHIVE_FATAL);
 	}
 
@@ -959,7 +959,7 @@
  * possible.
  *
  * Mostly, this code returns pointers directly into the block of data
- * provided by the client_read routine.  It can do this unless the
+ * provided by the client's read routine.  It can do this unless the
  * request would split across blocks.  In that case, we have to copy
  * into an internal buffer to combine reads.
  */
@@ -1229,10 +1229,8 @@
 	 * have to use ordinary reads to finish out the request.
 	 */
 	while (request > 0) {
-		const void* dummy_buffer;
 		ssize_t bytes_read;
-		dummy_buffer = __archive_read_ahead(filter->archive,
-		    1, &bytes_read);
+		(void)__archive_read_ahead(filter->archive, 1, &bytes_read);
 		if (bytes_read < 0)
 			return (bytes_read);
 		if (bytes_read == 0) {
--- tarsnap-1.0.29/libarchive/archive_read_disk.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_read_disk.c	2011-08-08 11:36:26.000000000 -0700
@@ -47,6 +47,7 @@
 	if (!inited) {
 		av.archive_finish = _archive_read_finish;
 		av.archive_close = _archive_read_close;
+		inited = 1;
 	}
 	return (&av);
 }
--- tarsnap-1.0.29/libarchive/archive_read_disk_set_standard_lookup.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_read_disk_set_standard_lookup.c	2011-06-07 15:50:14.000000000 -0700
@@ -186,6 +186,8 @@
 lookup_uname_helper(struct name_cache *cache, id_t id)
 {
 	struct passwd	pwent, *result;
+	char * nbuff;
+	size_t nbuff_size;
 	int r;
 
 	if (cache->buff_size == 0) {
@@ -206,10 +208,12 @@
 		 * we just double it and try again.  Because the buffer
 		 * is kept around in the cache object, we shouldn't
 		 * have to do this very often. */
-		cache->buff_size *= 2;
-		cache->buff = realloc(cache->buff, cache->buff_size);
-		if (cache->buff == NULL)
+		nbuff_size = cache->buff_size * 2;
+		nbuff = realloc(cache->buff, nbuff_size);
+		if (nbuff == NULL)
 			break;
+		cache->buff = nbuff;
+		cache->buff_size = nbuff_size;
 	}
 	if (r != 0) {
 		archive_set_error(cache->archive, errno,
@@ -234,6 +238,8 @@
 lookup_gname_helper(struct name_cache *cache, id_t id)
 {
 	struct group	grent, *result;
+	char * nbuff;
+	size_t nbuff_size;
 	int r;
 
 	if (cache->buff_size == 0) {
@@ -252,10 +258,12 @@
 		/* ERANGE means our buffer was too small, but POSIX
 		 * doesn't tell us how big the buffer should be, so
 		 * we just double it and try again. */
-		cache->buff_size *= 2;
-		cache->buff = realloc(cache->buff, cache->buff_size);
-		if (cache->buff == NULL)
+		nbuff_size = cache->buff_size * 2;
+		nbuff = realloc(cache->buff, nbuff_size);
+		if (nbuff == NULL)
 			break;
+		cache->buff = nbuff;
+		cache->buff_size = nbuff_size;
 	}
 	if (r != 0) {
 		archive_set_error(cache->archive, errno,
--- tarsnap-1.0.29/libarchive/archive_read_extract.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_read_extract.c	2011-08-12 08:59:26.000000000 -0700
@@ -73,7 +73,10 @@
 			archive_set_error(&a->archive, ENOMEM, "Can't extract");
 			return (NULL);
 		}
-		archive_write_disk_set_standard_lookup(a->extract->ad);
+		if (archive_write_disk_set_standard_lookup(a->extract->ad)) {
+			archive_set_error(&a->archive, ENOMEM, "Can't extract");
+			return (NULL);
+		}
 		a->cleanup_archive_extract = archive_read_extract_cleanup;
 	}
 	return (a->extract);
@@ -106,7 +109,7 @@
 		r = ARCHIVE_WARN;
 	if (r != ARCHIVE_OK)
 		/* If _write_header failed, copy the error. */
- 		archive_copy_error(&a->archive, ad);
+		archive_copy_error(&a->archive, ad);
 	else
 		/* Otherwise, pour data into the entry. */
 		r = copy_data(_a, ad);
@@ -115,7 +118,7 @@
 		r2 = ARCHIVE_WARN;
 	/* Use the first message. */
 	if (r2 != ARCHIVE_OK && r == ARCHIVE_OK)
- 		archive_copy_error(&a->archive, ad);
+		archive_copy_error(&a->archive, ad);
 	/* Use the worst error return. */
 	if (r2 < r)
 		r = r2;
@@ -144,6 +147,8 @@
 	int r;
 
 	extract = get_extract((struct archive_read *)ar);
+	if (extract == NULL)
+		return (ARCHIVE_FATAL);
 	for (;;) {
 		r = archive_read_data_block(ar, &buff, &size, &offset);
 		if (r == ARCHIVE_EOF)
--- tarsnap-1.0.29/libarchive/archive_read_support_compression_compress.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_read_support_compression_compress.c	2011-06-26 02:25:33.000000000 -0700
@@ -229,8 +229,8 @@
 
 	/* XXX MOVE THE FOLLOWING OUT OF INIT() XXX */
 
-	code = getbits(self, 8); /* Skip first signature byte. */
-	code = getbits(self, 8); /* Skip second signature byte. */
+	(void)getbits(self, 8); /* Skip first signature byte. */
+	(void)getbits(self, 8); /* Skip second signature byte. */
 
 	code = getbits(self, 8);
 	state->maxcode_bits = code & 0x1f;
--- tarsnap-1.0.29/libarchive/archive_read_support_format_ar.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_read_support_format_ar.c	2011-06-26 02:23:39.000000000 -0700
@@ -136,7 +136,6 @@
 static int
 archive_read_format_ar_bid(struct archive_read *a)
 {
-	struct ar *ar;
 	const void *h;
 
 	if (a->archive.archive_format != 0 &&
@@ -144,8 +143,6 @@
 	    ARCHIVE_FORMAT_AR)
 		return(0);
 
-	ar = (struct ar *)(a->format->data);
-
 	/*
 	 * Verify the 8-byte file signature.
 	 * TODO: Do we need to check more than this?
--- tarsnap-1.0.29/libarchive/archive_read_support_format_empty.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_read_support_format_empty.c	2011-06-26 02:22:15.000000000 -0700
@@ -61,10 +61,9 @@
 static int
 archive_read_format_empty_bid(struct archive_read *a)
 {
-	const void *h;
 	ssize_t avail;
 
-	h = __archive_read_ahead(a, 1, &avail);
+	(void)__archive_read_ahead(a, 1, &avail);
 	if (avail != 0)
 		return (-1);
 	return (1);
--- tarsnap-1.0.29/libarchive/archive_read_support_format_iso9660.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_read_support_format_iso9660.c	2011-06-22 04:14:25.000000000 -0700
@@ -393,7 +393,7 @@
 
 	/* Note: The "warn" return is just to inform the options
 	 * supervisor that we didn't handle it.  It will generate
-	 * a suitable error if noone used this option. */
+	 * a suitable error if no one used this option. */
 	return (ARCHIVE_WARN);
 }
 
@@ -440,13 +440,6 @@
 	iso9660->volume_size = iso9660->logical_block_size
 	    * (uint64_t)toi(h + SVD_volume_space_size_offset, 4);
 
-#if DEBUG
-	fprintf(stderr, "Joliet UCS-2 level %d with "
-			"logical block size:%d, volume size:%d\n",
-			iso9660->seenJoliet,
-			iso9660->logical_block_size, iso9660->volume_size);
-#endif
-
 	/* Store the root directory in the pending list. */
 	file = parse_file_info(iso9660, NULL, h + SVD_root_directory_record_offset);
 	add_entry(iso9660, file);
@@ -774,7 +767,7 @@
 #if 0 /* untested code, is it at all useful on Joliet? */
 		/* trim trailing first version and dot from filename.
 		 *
-		 * Remember we where in UTF-16BE land!
+		 * Remember we were in UTF-16BE land!
 		 * SEPARATOR 1 (.) and SEPARATOR 2 (;) are both
 		 * 16 bits big endian characters on Joliet.
 		 *
@@ -906,7 +899,7 @@
 					    * iso9660->logical_block_size
 					    + toi(data + 8, 4);
 					file->ce_size = toi(data + 16, 4);
-					/* If the result is rediculous,
+					/* If the result is ridiculous,
 					 * ignore it. */
 					if (file->ce_offset + file->ce_size
 					    > iso9660->volume_size) {
--- tarsnap-1.0.29/libarchive/archive_read_support_format_mtree.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_read_support_format_mtree.c	2011-08-08 13:08:57.000000000 -0700
@@ -98,7 +98,7 @@
 
 	struct archive_entry_linkresolver *resolver;
 
-	off_t			 cur_size, cur_offset;
+	off_t			 cur_size;
 };
 
 static int	cleanup(struct archive_read *);
@@ -398,7 +398,6 @@
 
 	global = NULL;
 	last_entry = NULL;
-	r = ARCHIVE_OK;
 
 	for (counter = 1; ; ++counter) {
 		len = readline(a, mtree, &p, 256);
@@ -1148,28 +1147,43 @@
 	int base, digit, sign;
 
 	base = 10;
-	limit = INT64_MAX / base;
-	last_digit_limit = INT64_MAX % base;
 
 	if (**p == '-') {
 		sign = -1;
+		limit = ((uint64_t)(INT64_MAX) + 1) / base;
+		last_digit_limit = ((uint64_t)(INT64_MAX) + 1) % base;
 		++(*p);
-	} else
+	} else {
 		sign = 1;
+		limit = INT64_MAX / base;
+		last_digit_limit = INT64_MAX % base;
+	}
 
 	l = 0;
 	digit = **p - '0';
 	while (digit >= 0 && digit < base) {
-		if (l > limit || (l == limit && digit > last_digit_limit)) {
-			l = UINT64_MAX; /* Truncate on overflow. */
-			break;
-		}
+		if (l > limit || (l == limit && digit > last_digit_limit))
+			return (sign < 0) ? INT64_MIN : INT64_MAX;
 		l = (l * base) + digit;
 		digit = *++(*p) - '0';
 	}
 	return (sign < 0) ? -l : l;
 }
 
+/* Parse a hex digit. */
+static int
+parsehex(char c)
+{
+	if (c >= '0' && c <= '9')
+		return c - '0';
+	else if (c >= 'a' && c <= 'f')
+		return c - 'a';
+	else if (c >= 'A' && c <= 'F')
+		return c - 'A';
+	else
+		return -1;
+}
+
 /*
  * Note that this implementation does not (and should not!) obey
  * locale settings; you cannot simply substitute strtol here, since
@@ -1182,38 +1196,25 @@
 	int base, digit, sign;
 
 	base = 16;
-	limit = INT64_MAX / base;
-	last_digit_limit = INT64_MAX % base;
 
 	if (**p == '-') {
 		sign = -1;
+		limit = ((uint64_t)(INT64_MAX) + 1) / base;
+		last_digit_limit = ((uint64_t)(INT64_MAX) + 1) % base;
 		++(*p);
-	} else
+	} else {
 		sign = 1;
+		limit = INT64_MAX / base;
+		last_digit_limit = INT64_MAX % base;
+	}
 
 	l = 0;
-	if (**p >= '0' && **p <= '9')
-		digit = **p - '0';
-	else if (**p >= 'a' && **p <= 'f')
-		digit = **p - 'a' + 10;
-	else if (**p >= 'A' && **p <= 'F')
-		digit = **p - 'A' + 10;
-	else
-		digit = -1;
+	digit = parsehex(**p);
 	while (digit >= 0 && digit < base) {
-		if (l > limit || (l == limit && digit > last_digit_limit)) {
-			l = UINT64_MAX; /* Truncate on overflow. */
-			break;
-		}
+		if (l > limit || (l == limit && digit > last_digit_limit))
+			return (sign < 0) ? INT64_MIN : INT64_MAX;
 		l = (l * base) + digit;
-		if (**p >= '0' && **p <= '9')
-			digit = **p - '0';
-		else if (**p >= 'a' && **p <= 'f')
-			digit = **p - 'a' + 10;
-		else if (**p >= 'A' && **p <= 'F')
-			digit = **p - 'A' + 10;
-		else
-			digit = -1;
+		digit = parsehex(*++(*p));
 	}
 	return (sign < 0) ? -l : l;
 }
--- tarsnap-1.0.29/libarchive/archive_read_support_format_tar.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_read_support_format_tar.c	2011-08-08 13:04:54.000000000 -0700
@@ -368,7 +368,7 @@
 }
 
 /*
- * The function invoked by archive_read_header().  This
+ * The function invoked by archive_read_next_header().  This
  * just sets up a few things and then calls the internal
  * tar_read_header() function below.
  */
@@ -593,7 +593,7 @@
 		return (bytes);
 	if (bytes < 512) {  /* Short read or EOF. */
 		/* Try requesting just one byte and see what happens. */
-		h = __archive_read_ahead(a, 1, &bytes);
+		(void)__archive_read_ahead(a, 1, &bytes);
 		if (bytes == 0) {
 			/*
 			 * The archive ends at a 512-byte boundary but
@@ -896,7 +896,7 @@
 		return (ARCHIVE_FATAL);
 	}
 
- 	/* Read the body into the string. */
+	/* Read the body into the string. */
 	padded_size = (size + 511) & ~ 511;
 	src = __archive_read_ahead(a, padded_size, NULL);
 	if (src == NULL)
@@ -1200,7 +1200,7 @@
     struct archive_entry *entry, char *attr)
 {
 	size_t attr_length, l, line_length;
-	char *line, *p;
+	char *p;
 	char *key, *value;
 	int err, err2;
 
@@ -1216,7 +1216,7 @@
 		/* Parse decimal length field at start of line. */
 		line_length = 0;
 		l = attr_length;
-		line = p = attr; /* Record start of line. */
+		p = attr; /* Record start of line. */
 		while (l>0) {
 			if (*p == ' ') {
 				p++;
@@ -1828,7 +1828,7 @@
  * Beginning with GNU tar 1.15, sparse files are stored using
  * information in the pax extended header.  The GNU tar maintainers
  * have gone through a number of variations in the process of working
- * out this scheme; furtunately, they're all numbered.
+ * out this scheme; fortunately, they're all numbered.
  *
  * Sparse format 0.0 uses attribute GNU.sparse.numblocks to store the
  * number of blocks, and GNU.sparse.offset/GNU.sparse.numbytes to
@@ -2193,7 +2193,7 @@
 
 	/* Ensure pax_entry buffer is big enough. */
 	if (tar->pax_entry_length <= length) {
-		wchar_t *old_entry = tar->pax_entry;
+		wchar_t *old_entry;
 
 		if (tar->pax_entry_length <= 0)
 			tar->pax_entry_length = 1024;
--- tarsnap-1.0.29/libarchive/archive_read_support_format_zip.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_read_support_format_zip.c	2011-06-11 13:05:25.000000000 -0700
@@ -900,7 +900,7 @@
 	if (offset != zip->extra_length)
 	{
 		fprintf(stderr,
-		    "Extra data field contents do not match reported size!");
+		    "Extra data field contents do not match reported size!\n");
 	}
 #endif
 }
--- tarsnap-1.0.29/libarchive/archive_string.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_string.c	2011-08-06 17:48:04.000000000 -0700
@@ -99,6 +99,9 @@
 struct archive_string *
 __archive_string_ensure(struct archive_string *as, size_t s)
 {
+	char *p;
+	size_t new_length;
+
 	/* If buffer is already big enough, don't reallocate. */
 	if (as->s && (s <= as->buffer_length))
 		return (as);
@@ -112,18 +115,17 @@
 	 */
 	if (as->buffer_length < 32)
 		/* Start with a minimum 32-character buffer. */
-		as->buffer_length = 32;
+		new_length = 32;
 	else if (as->buffer_length < 8192)
 		/* Buffers under 8k are doubled for speed. */
-		as->buffer_length += as->buffer_length;
+		new_length = as->buffer_length + as->buffer_length;
 	else {
 		/* Buffers 8k and over grow by at least 25% each time. */
-		size_t old_length = as->buffer_length;
-		as->buffer_length += as->buffer_length / 4;
-		/* Be safe: If size wraps, release buffer and return NULL. */
-		if (as->buffer_length < old_length) {
-			free(as->s);
-			as->s = NULL;
+		new_length = as->buffer_length + as->buffer_length / 4;
+		/* Be safe: If size wraps, fail. */
+		if (new_length < as->buffer_length) {
+			/* On failure, wipe the string and return NULL. */
+			__archive_string_free(as);
 			return (NULL);
 		}
 	}
@@ -132,12 +134,18 @@
 	 * grow the buffer.  In any case, we have to grow it enough to
 	 * hold the request.
 	 */
-	if (as->buffer_length < s)
-		as->buffer_length = s;
+	if (new_length < s)
+		new_length = s;
 	/* Now we can reallocate the buffer. */
-	as->s = (char *)realloc(as->s, as->buffer_length);
-	if (as->s == NULL)
+	p = (char *)realloc(as->s, new_length);
+	if (p == NULL) {
+		/* On failure, wipe the string and return NULL. */
+		__archive_string_free(as);
 		return (NULL);
+	}
+
+	as->s = p;
+	as->buffer_length = new_length;
 	return (as);
 }
 
@@ -289,18 +297,17 @@
 {
 	wchar_t *ws, *dest;
 	int wc, wc2;/* Must be large enough for a 21-bit Unicode code point. */
-	const char *src;
+	const char *src, *end;
 	int n;
-	int err;
 
 	ws = (wchar_t *)malloc((as->length + 1) * sizeof(wchar_t));
 	if (ws == NULL)
 		__archive_errx(1, "Out of memory");
-	err = 0;
 	dest = ws;
 	src = as->s;
+	end = as->s + as->buffer_length;
 	while (*src != '\0') {
-		n = utf8_to_unicode(&wc, src, 8);
+		n = utf8_to_unicode(&wc, src, end - src);
 		if (n == 0)
 			break;
 		if (n < 0) {
@@ -313,7 +320,7 @@
 			 * has translated UTF16 to UTF8 without combining
 			 * surrogates; rebuild the full code point before
 			 * continuing. */
-			n = utf8_to_unicode(&wc2, src, 8);
+			n = utf8_to_unicode(&wc2, src, end - src);
 			if (n < 0) {
 				free(ws);
 				return (NULL);
--- tarsnap-1.0.29/libarchive/archive_string_sprintf.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_string_sprintf.c	2011-08-16 12:01:35.000000000 -0700
@@ -60,11 +60,14 @@
 static void
 append_int(struct archive_string *as, intmax_t d, unsigned base)
 {
+	uintmax_t ud;
+
 	if (d < 0) {
 		archive_strappend_char(as, '-');
-		d = -d;
-	}
-	append_uint(as, d, base);
+		ud = (d == INTMAX_MIN) ? (uintmax_t)(INTMAX_MAX) + 1 : (uintmax_t)(-d);
+	} else
+		ud = d;
+	append_uint(as, ud, base);
 }
 
 
--- tarsnap-1.0.29/libarchive/archive_windows.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_windows.c	2011-05-30 05:59:16.000000000 -0700
@@ -276,7 +276,7 @@
 		if (sizeof(root) -3 < len)
 			return (0);
 		root[0] = root[1] = L'\\';
-		wcsncpy(root + 2, path1 + 8 , len);
+		wcsncpy(root + 2, path1 + 8, len);
 		/* root : "\\Server\Share\" */
 		root[2 + len] = L'\0';
 	} else if (wcsncmp(path1, L"\\\\?\\", 4) == 0) {
@@ -1106,7 +1106,7 @@
 {
 
 	if (!ctx->valid)
-	return;
+		return;
 
 	CryptHashData(ctx->hash, buf, (DWORD)len, 0);
 }
--- tarsnap-1.0.29/libarchive/archive_windows.h	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_windows.h	2011-05-30 06:04:22.000000000 -0700
@@ -334,7 +334,7 @@
 #define WIFEXITED(sts)		((sts & 0x100) == 0)
 #define WEXITSTATUS(sts)	(sts & 0x0FF)
 
-/* Convertion a Win32 API error code */
+/* Convert a Win32 API error code */
 extern void _dosmaperr(unsigned long);
 
 /* Message digest function */
--- tarsnap-1.0.29/libarchive/archive_write.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_write.c	2011-08-08 11:36:15.000000000 -0700
@@ -29,7 +29,7 @@
 /*
  * This file contains the "essential" portions of the write API, that
  * is, stuff that will essentially always be used by any client that
- * actually needs to write a archive.  Optional pieces have been, as
+ * actually needs to write an archive.  Optional pieces have been, as
  * far as possible, separated out into separate files to reduce
  * needlessly bloating statically-linked clients.
  */
@@ -80,6 +80,7 @@
 		av.archive_write_header = _archive_write_header;
 		av.archive_write_finish_entry = _archive_write_finish_entry;
 		av.archive_write_data = _archive_write_data;
+		inited = 1;
 	}
 	return (&av);
 }
@@ -315,7 +316,6 @@
 	struct archive_write *a = (struct archive_write *)_a;
 	int ret;
 
-	ret = ARCHIVE_OK;
 	__archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
 	    ARCHIVE_STATE_NEW, "archive_write_open");
 	archive_clear_error(&a->archive);
--- tarsnap-1.0.29/libarchive/archive_write_disk.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_write_disk.c	2011-08-08 11:36:37.000000000 -0700
@@ -205,7 +205,7 @@
 
 /*
  * Default mode for dirs created automatically (will be modified by umask).
- * Note that POSIX specifies 0777 for implicity-created dirs, "modified
+ * Note that POSIX specifies 0777 for implicitly-created dirs, "modified
  * by the process' file creation mask."
  */
 #define	DEFAULT_DIR_MODE 0777
@@ -273,7 +273,7 @@
 #endif
 	/*
 	 * XXX At this point, symlinks should not be hit, otherwise
-	 * XXX a race occured.  Do we want to check explicitly for that?
+	 * XXX a race occurred.  Do we want to check explicitly for that?
 	 */
 	if (lstat(a->name, &a->st) == 0) {
 		a->pst = &a->st;
@@ -296,6 +296,7 @@
 		av.archive_write_finish_entry = _archive_write_finish_entry;
 		av.archive_write_data = _archive_write_data;
 		av.archive_write_data_block = _archive_write_data_block;
+		inited = 1;
 	}
 	return (&av);
 }
@@ -455,7 +456,11 @@
 #ifdef HAVE_FCHDIR
 	/* If we changed directory above, restore it here. */
 	if (a->restore_pwd >= 0) {
-		fchdir(a->restore_pwd);
+		r = fchdir(a->restore_pwd);
+		if (r != 0) {
+			archive_set_error(&a->archive, errno, "chdir() failure");
+			ret = ARCHIVE_FATAL;
+		}
 		close(a->restore_pwd);
 		a->restore_pwd = -1;
 	}
@@ -612,7 +617,7 @@
 			a->fd_offset = a->offset;
 			a->archive.file_position = a->offset;
 			a->archive.raw_position = a->offset;
- 		}
+		}
 		bytes_written = write(a->fd, buff, bytes_to_write);
 		if (bytes_written < 0) {
 			archive_set_error(&a->archive, errno, "Write failed");
@@ -967,7 +972,7 @@
 		 */
 		int r = 0;
 		/*
-		 * The SECURE_SYMLINK logic has already removed a
+		 * The SECURE_SYMLINKS logic has already removed a
 		 * symlink to a dir if the client wants that.  So
 		 * follow the symlink if we're creating a dir.
 		 */
@@ -1501,7 +1506,7 @@
 		++alen;
 		if (*p == '\\')
 			l = 1;
-		/* Rewrite the path name if its character is a unusable. */
+		/* Rewrite the path name if its next character is unusable. */
 		if (*p == ':' || *p == '*' || *p == '?' || *p == '"' ||
 		    *p == '<' || *p == '>' || *p == '|')
 			*p = '_';
@@ -1661,8 +1666,6 @@
 	mode_t mode_final, mode;
 	int r;
 
-	r = ARCHIVE_OK;
-
 	/* Check for special names and just skip them. */
 	slash = strrchr(path, '/');
 	if (slash == NULL)
@@ -2210,22 +2213,25 @@
 	 * to read the current flags from disk. XXX
 	 */
 	ret = ARCHIVE_OK;
+
+	/* Read the current file flags. */
+	if (ioctl(myfd, EXT2_IOC_GETFLAGS, &oldflags) < 0)
+		goto fail;
+
 	/* Try setting the flags as given. */
-	if (ioctl(myfd, EXT2_IOC_GETFLAGS, &oldflags) >= 0) {
-		newflags = (oldflags & ~clear) | set;
-		if (ioctl(myfd, EXT2_IOC_SETFLAGS, &newflags) >= 0)
-			goto cleanup;
-		if (errno != EPERM)
-			goto fail;
-	}
+	newflags = (oldflags & ~clear) | set;
+	if (ioctl(myfd, EXT2_IOC_SETFLAGS, &newflags) >= 0)
+		goto cleanup;
+	if (errno != EPERM)
+		goto fail;
+
 	/* If we couldn't set all the flags, try again with a subset. */
-	if (ioctl(myfd, EXT2_IOC_GETFLAGS, &oldflags) >= 0) {
-		newflags &= ~sf_mask;
-		oldflags &= sf_mask;
-		newflags |= oldflags;
-		if (ioctl(myfd, EXT2_IOC_SETFLAGS, &newflags) >= 0)
-			goto cleanup;
-	}
+	newflags &= ~sf_mask;
+	oldflags &= sf_mask;
+	newflags |= oldflags;
+	if (ioctl(myfd, EXT2_IOC_SETFLAGS, &newflags) >= 0)
+		goto cleanup;
+
 	/* We couldn't set the flags, so report the failure. */
 fail:
 	archive_set_error(&a->archive, errno,
--- tarsnap-1.0.29/libarchive/archive_write_disk_set_standard_lookup.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_write_disk_set_standard_lookup.c	2011-08-14 13:43:21.000000000 -0700
@@ -86,6 +86,11 @@
 {
 	struct bucket *ucache = malloc(cache_size * sizeof(struct bucket));
 	struct bucket *gcache = malloc(cache_size * sizeof(struct bucket));
+	if (ucache == NULL || gcache == NULL) {
+		free(ucache);
+		free(gcache);
+		return (ARCHIVE_FATAL);
+	}
 	memset(ucache, 0, cache_size * sizeof(struct bucket));
 	memset(gcache, 0, cache_size * sizeof(struct bucket));
 	archive_write_disk_set_group_lookup(a, gcache, lookup_gid, cleanup);
--- tarsnap-1.0.29/libarchive/archive_write_set_compression_compress.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_write_set_compression_compress.c	2011-05-30 06:16:31.000000000 -0700
@@ -114,7 +114,7 @@
 		    const void *, size_t);
 
 /*
- * Allocate, initialize and return a archive object.
+ * Allocate, initialize and return an archive object.
  */
 int
 archive_write_set_compression_compress(struct archive *_a)
@@ -200,7 +200,7 @@
  * Output the given code.
  * Inputs:
  * 	code:	A n_bits-bit integer.  If == -1, then EOF.  This assumes
- *		that n_bits =< (long)wordsize - 1.
+ *		that n_bits <= (long)wordsize - 1.
  * Outputs:
  * 	Outputs code to the file.
  * Assumptions:
--- tarsnap-1.0.29/libarchive/archive_write_set_compression_gzip.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_write_set_compression_gzip.c	2011-05-30 06:16:24.000000000 -0700
@@ -87,7 +87,7 @@
 
 
 /*
- * Allocate, initialize and return a archive object.
+ * Allocate, initialize and return an archive object.
  */
 int
 archive_write_set_compression_gzip(struct archive *_a)
--- tarsnap-1.0.29/libarchive/archive_write_set_compression_none.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_write_set_compression_none.c	2011-06-22 04:07:48.000000000 -0700
@@ -225,7 +225,6 @@
 		block_length = state->buffer_size - state->avail;
 
 		/* Tricky calculation to determine size of last block */
-		target_block_length = block_length;
 		if (a->bytes_in_last_block <= 0)
 			/* Default or Zero: pad to full block */
 			target_block_length = a->bytes_per_block;
--- tarsnap-1.0.29/libarchive/archive_write_set_compression_program.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_write_set_compression_program.c	2011-05-30 06:15:31.000000000 -0700
@@ -83,7 +83,7 @@
 		    const void *, size_t);
 
 /*
- * Allocate, initialize and return a archive object.
+ * Allocate, initialize and return an archive object.
  */
 int
 archive_write_set_compression_program(struct archive *_a, const char *cmd)
--- tarsnap-1.0.29/libarchive/archive_write_set_compression_xz.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_write_set_compression_xz.c	2011-05-30 06:15:28.000000000 -0700
@@ -89,7 +89,7 @@
 
 
 /*
- * Allocate, initialize and return a archive object.
+ * Allocate, initialize and return an archive object.
  */
 int
 archive_write_set_compression_xz(struct archive *_a)
--- tarsnap-1.0.29/libarchive/archive_write_set_format_ar.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_write_set_format_ar.c	2011-05-30 05:59:32.000000000 -0700
@@ -191,7 +191,7 @@
 		ar->is_strtab = 1;
 		buff[AR_name_offset] = buff[AR_name_offset + 1] = '/';
 		/*
-		 * For archive string table, only ar_size filed should
+		 * For archive string table, only ar_size field should
 		 * be set.
 		 */
 		goto size;
@@ -502,7 +502,7 @@
 	len = s;
 	h = p;
 
-	/* Negative values in ar header are meaningless , so use 0. */
+	/* Negative values in ar header are meaningless, so use 0. */
 	if (v < 0) {
 		while (len-- > 0)
 			*p++ = '0';
--- tarsnap-1.0.29/libarchive/archive_write_set_format_pax.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_write_set_format_pax.c	2011-08-16 12:01:59.000000000 -0700
@@ -171,18 +171,17 @@
 static char *
 format_int(char *t, int64_t i)
 {
-	int sign;
+	uint64_t ui;
 
-	if (i < 0) {
-		sign = -1;
-		i = -i;
-	} else
-		sign = 1;
+	if (i < 0) 
+		ui = (i == INT64_MIN) ? (uint64_t)(INT64_MAX) + 1 : (uint64_t)(-i);
+	else
+		ui = i;
 
 	do {
-		*--t = "0123456789"[i % 10];
-	} while (i /= 10);
-	if (sign < 0)
+		*--t = "0123456789"[ui % 10];
+	} while (ui /= 10);
+	if (i < 0)
 		*--t = '-';
 	return (t);
 }
@@ -546,7 +545,7 @@
 		/* We have an all-ASCII path; we'd like to just store
 		 * it in the ustar header if it will fit.  Yes, this
 		 * duplicates some of the logic in
-		 * write_set_format_ustar.c
+		 * archive_write_set_format_ustar.c
 		 */
 		if (strlen(path) <= 100) {
 			/* Fits in the old 100-char tar name field. */
@@ -1138,7 +1137,7 @@
  *
  * Joerg Schilling has argued that this is unnecessary because, in
  * practice, if the pax extended attributes get extracted as regular
- * files, noone is going to bother reading those attributes to
+ * files, no one is going to bother reading those attributes to
  * manually restore them.  Based on this, 'star' uses
  * /tmp/PaxHeader/'basename' as the ustar header name.  This is a
  * tempting argument, in part because it's simpler than the SUSv3
@@ -1212,15 +1211,11 @@
 static int
 archive_write_pax_finish(struct archive_write *a)
 {
-	struct pax *pax;
-	int r;
 
 	if (a->compressor.write == NULL)
 		return (ARCHIVE_OK);
 
-	pax = (struct pax *)a->format_data;
-	r = write_nulls(a, 512 * 2);
-	return (r);
+	return (write_nulls(a, 512 * 2));
 }
 
 static int
--- tarsnap-1.0.29/libarchive/archive_write_set_format_ustar.c	2011-01-19 20:32:49.000000000 -0800
+++ tarsnap-1.0.30/libarchive/archive_write_set_format_ustar.c	2011-05-30 06:05:44.000000000 -0700
@@ -303,7 +303,7 @@
 			 * The only feasible separator is a final '/';
 			 * this would result in a non-empty prefix and
 			 * an empty name, which POSIX doesn't
-			 * explicity forbid, but it just feels wrong.
+			 * explicitly forbid, but it just feels wrong.
 			 */
 			archive_set_error(&a->archive, ENAMETOOLONG,
 			    "Pathname too long");
--- tarsnap-1.0.29/pkg/README	2011-01-19 20:32:50.000000000 -0800
+++ tarsnap-1.0.30/pkg/README	2011-04-24 00:26:28.000000000 -0700
@@ -27,13 +27,17 @@
 sha256sums= lines so that you get the latest version of tarsnap.
 
 There may be a newer version of the PKGBUILD file at
-  http://aur.archlinux.org/packages.php?ID=22963
+  http://www.archlinux.org/packages/community/i686/tarsnap/
+  http://www.archlinux.org/packages/community/x86_64/tarsnap/
+(in fact, those probably have identical PKGBUILD files).
 
 Slackware
 ---------
 
 There is a SlackBuild for tarsnap (possibly an earlier version) at
-  http://slackbuilds.org/repository/12.2/system/tarsnap/
+  http://slackbuilds.org/repository/${VER}/system/tarsnap/
+for VER = 12.2 and 13.1 (and possibly other versions by the time
+you read this).
 
 FreeBSD
 -------
--- tarsnap-1.0.29/pkg/archlinux/PKGBUILD	2011-01-19 20:32:50.000000000 -0800
+++ tarsnap-1.0.30/pkg/archlinux/PKGBUILD	2011-04-24 00:24:48.000000000 -0700
@@ -1,23 +1,29 @@
-# Contributor: Aaron Schaefer <aaron@elasticdog.com>
+# $Id$
+# Maintainer: Jelle van der Waa <jelle vd waa.nl>
+
 pkgname=tarsnap
-pkgver=1.0.25
+pkgver=1.0.29
 pkgrel=1
 pkgdesc='An online encrypted snapshotted backup service'
 arch=('i686' 'x86_64')
 url='http://www.tarsnap.com/'
 license=('custom')
-depends=('bzip2' 'openssl')
+depends=('bzip2' 'openssl' 'xz>=5.0.0')
 makedepends=('e2fsprogs')
 source=("https://www.tarsnap.com/download/$pkgname-autoconf-$pkgver.tgz")
-md5sums=('862403c3a79db9657d7ff9c898238e81')
-sha256sums=('086787dd9d9985590c17848454e7b4e31327c3a70065c5f2611b1e0a1fddb087')
+md5sums=('0e5ef12a92fb651b51159b1ad52317f6')
+sha256sums=('747510459e4af0ebbb6e267c159aa019f9337d1e07bd9a94f1aa1498081b7598')
 
 build() {
   cd "$srcdir/$pkgname-autoconf-$pkgver"
 
   ./configure --prefix=/usr --sysconfdir="/etc/$pkgname"
-  make || return 1
-  make DESTDIR="$pkgdir/" install || return 1
+  make
+}
+
+package() {
+  cd "$srcdir/$pkgname-autoconf-$pkgver"
 
+  make DESTDIR="$pkgdir" install
   install -D -m644 COPYING "$pkgdir/usr/share/licenses/$pkgname/COPYING"
 }
--- tarsnap-1.0.29/pkg/debian/changelog	2011-02-01 13:29:47.000000000 -0800
+++ tarsnap-1.0.30/pkg/debian/changelog	2011-08-16 13:25:41.000000000 -0700
@@ -1,3 +1,8 @@
+tarsnap (1.0.30) unstable; urgency=low
+
+  * New version of tarsnap brings many minor bug fixes.
+
+ -- Colin Percival <cperciva@tarsnap.com>  Tue, 16 Aug 2011 20:25:12 +0000
 tarsnap (1.0.29) unstable; urgency=low
 
   * New version of tarsnap adds tarsnap-recrypt utility for re-encrypting
--- tarsnap-1.0.29/pkg/debian/control	2011-01-19 20:32:50.000000000 -0800
+++ tarsnap-1.0.30/pkg/debian/control	2011-05-24 02:41:34.000000000 -0700
@@ -2,12 +2,12 @@
 Section: net
 Priority: extra
 Maintainer: Mads Sulau Joergensen <mads@sulau.dk>
-Build-Depends: debhelper (>= 5), e2fslibs-dev, zlib1g-dev, libssl-dev, libbz2-dev
+Build-Depends: debhelper (>= 5), e2fslibs-dev, zlib1g-dev, libssl-dev, libbz2-dev, libattr1-dev, libacl1-dev
 Standards-Version: 3.7.2
 
 Package: tarsnap
 Architecture: any
-Depends: ${shlibs:Depends}, zlib1g
+Depends: ${shlibs:Depends}
 Description: tarsnap is an online encrypted snapshotted backup service
  Tarsnap is an encrypted snapshotted online backup service for BSD, 
  Linux, OpenSolaris, and OS X.
--- tarsnap-1.0.29/pkg/debian/rules	2011-01-19 20:32:50.000000000 -0800
+++ tarsnap-1.0.30/pkg/debian/rules	2011-05-24 02:42:08.000000000 -0700
@@ -17,7 +17,7 @@
 config.status: configure
 	dh_testdir
 	
-	./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr --sysconfdir=/etc --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info CFLAGS="$(CFLAGS)" LDFLAGS="-Wl,-z,defs"
+	./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr --sysconfdir=/etc --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info --enable-xattr --enable-acl --with-bz2lib CFLAGS="$(CFLAGS)" LDFLAGS="-Wl,-z,defs"
 
 build: build-stamp
 
--- tarsnap-1.0.29/recrypt/recrypt.c	2011-02-02 05:31:44.000000000 -0800
+++ tarsnap-1.0.30/recrypt/recrypt.c	2011-05-08 14:23:18.000000000 -0700
@@ -223,36 +223,23 @@
 	int rc;
 
 	/* Make sure that nblist is a subset of oblist. */
-	i = j = 0;
-	do {
-		/* If we've hit the end of nblist, we're fine. */
-		if (j == nblistlen)
-			break;
-
-		/* If we've hit the end of oblist, it's missing something. */
-		if (i == oblistlen)
-			goto notsubset;
-
-		/* Compare the two block names we're looking at. */
-		rc = cmpblock(&oblist[i], &nblist[j]);
-
-		/* If the block from oblist is >, we're missing something. */
-		if (rc > 0)
-			goto notsubset;
+	for (i = j = 0; j < nblistlen; i++) {
+		/*
+		 * If we've hit the end of oblist or the next block in oblist
+		 * is greater than the next block in nblist, there's at least
+		 * one block in nblist which is not in oblist.
+		 */
+		if ((i == oblistlen) ||
+		    ((rc = cmpblock(&oblist[i], &nblist[j])) > 0)) {
+			warn0("New machine has data not in old machine!"
+			    "  Cannot continue.");
+			exit(1);
+		}
 
-		/* Advance the new block list pointer if blocks are ==. */
+		/* If we've matched this new block, advance the pointer. */
 		if (rc == 0)
 			j++;
-
-		/* Move on to the nest block. */
-		i++;
-		continue;
-
-notsubset:
-		/* The new block list has something not in the old list. */
-		warn0("New machine has data not in old machine!  Cannot continue.");
-		exit(1);
-	} while (1);
+	}
 
 	/* If the lists are identical, we have nothing to do. */
 	if (oblistlen == nblistlen) {
--- tarsnap-1.0.29/recrypt/tarsnap-recrypt.1	2011-02-02 05:07:42.000000000 -0800
+++ tarsnap-1.0.30/recrypt/tarsnap-recrypt.1	2011-05-12 06:15:10.000000000 -0700
@@ -30,7 +30,7 @@
 The key file
 .Ar new-key-file
 must have been generated by
-.Xr tarsnap-keyregen
+.Xr tarsnap-keyregen 1
 with
 .Ar old-key-file .
 .Pp
--- tarsnap-1.0.29/tar/bsdtar.1	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/bsdtar.1	2011-04-22 16:13:38.000000000 -0700
@@ -595,7 +595,7 @@
 Extract files as sparse files.
 For every block on disk, check first if it contains only NULL bytes and seek
 over it otherwise.
-This works similiar to the conv=sparse option of dd.
+This works similar to the conv=sparse option of dd.
 .It Fl s Ar pattern
 Modify file or archive member names according to
 .Pa pattern .
@@ -603,10 +603,10 @@
 old is a basic regular expression.
 If it doesn't apply, the pattern is skipped.
 new is the replacement string of the matched part.
-~ is substituted with the match, \1 to \9 with the content of
+~ is substituted with the match, \e1 to \e9 with the contents of
 the corresponding captured group.
 The optional trailing g specifies that matching should continue
-after the matched part and stopped on the first unmatched pattern.
+after the matched part and stop on the first unmatched pattern.
 The optional trailing s specifies that the pattern applies to the value
 of symbolic links.
 The optional trailing p specifies that after a successful substitution
--- tarsnap-1.0.29/tar/bsdtar.c	2011-01-22 22:51:12.000000000 -0800
+++ tarsnap-1.0.30/tar/bsdtar.c	2011-08-02 01:54:08.000000000 -0700
@@ -267,6 +267,10 @@
 			/* libarchive doesn't need this; just ignore it. */
 			break;
 		case 'C': /* GNU tar */
+			if (strlen(bsdtar->optarg) == 0)
+				bsdtar_errc(bsdtar, 1, 0,
+				    "Meaningless option: -C ''");
+
 			set_chdir(bsdtar, bsdtar->optarg);
 			break;
 		case 'c': /* SUSv2 */
@@ -550,7 +554,13 @@
 			bsdtar->extract_flags |= ARCHIVE_EXTRACT_OWNER;
 			break;
 		case OPTION_STRIP_COMPONENTS: /* GNU tar 1.15 */
-			bsdtar->strip_components = atoi(bsdtar->optarg);
+			errno = 0;
+			bsdtar->strip_components = strtol(bsdtar->optarg,
+			    NULL, 0);
+			if (errno)
+				bsdtar_errc(bsdtar, 1, 0,
+				    "Invalid --strip-components argument: %s",
+				    bsdtar->optarg);
 			break;
 		case 'T': /* GNU tar */
 			bsdtar->names_from_file = bsdtar->optarg;
@@ -684,6 +694,10 @@
 	    (strlen(bsdtar->tapenames[0]) > 1023))
 		bsdtar_errc(bsdtar, 1, 0,
 		    "Cannot create an archive with a name > 1023 characters");
+	if ((bsdtar->mode == 'c') &&
+	    (strlen(bsdtar->tapenames[0]) == 0))
+		bsdtar_errc(bsdtar, 1, 0,
+		    "Cannot create an archive with an empty name");
 	if ((bsdtar->cachedir == NULL) &&
 	    (bsdtar->mode == 'c' || bsdtar->mode == 'd' ||
 	     bsdtar->mode == OPTION_RECOVER ||
@@ -760,6 +774,7 @@
 		if (realpath(bsdtar->cachedir, cachedir) == NULL)
 			bsdtar_errc(bsdtar, 1, errno, "realpath(%s)",
 			    bsdtar->cachedir);
+		free(bsdtar->cachedir);
 		bsdtar->cachedir = cachedir;
 	}
 
@@ -1522,7 +1537,7 @@
 needarg:
 	/* Option needs an argument. */
 	bsdtar_errc(bsdtar, 1, 0,
-	    "Argument requried for configuration file option: %s", conf_opt);
+	    "Argument required for configuration file option: %s", conf_opt);
 
 badopt:
 	/* No such option. */
--- tarsnap-1.0.29/tar/bsdtar.h	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/bsdtar.h	2011-05-07 00:34:51.000000000 -0700
@@ -48,7 +48,7 @@
 	const char	**tapenames; /* -f tapename */
 	size_t		  ntapes;
 	const char	 *homedir;
-	const char	 *cachedir; /* --cachedir */
+	char		 *cachedir; /* --cachedir */
 	dev_t		  cachedir_dev;
 	ino_t		  cachedir_ino;
 	int		  cachecrunch; /* --lowmem / --verylowmem */
--- tarsnap-1.0.29/tar/bsdtar_cygwin.h	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/bsdtar_cygwin.h	2011-05-30 06:07:29.000000000 -0700
@@ -32,7 +32,7 @@
 extern "C" {
 #endif
 
-/* a foward declaration, of sorts */
+/* a forward declaration, of sorts */
 typedef struct bsdtar * struct_bsdtar_p;
 
 extern int	bsdtar_is_privileged(struct bsdtar *bsdtar);
--- tarsnap-1.0.29/tar/bsdtar_platform.h	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/bsdtar_platform.h	2011-04-22 16:02:36.000000000 -0700
@@ -87,10 +87,10 @@
 #endif
 
 /*
- * Include "dirent.h" (or it's equivalent on several different platforms).
+ * Include "dirent.h" (or its equivalent on several different platforms).
  *
  * This is slightly modified from the GNU autoconf recipe.
- * In particular, FreeBSD includes d_namlen in it's dirent structure,
+ * In particular, FreeBSD includes d_namlen in its dirent structure,
  * so my configure script includes an explicit test for the d_namlen
  * field.
  */
--- tarsnap-1.0.29/tar/bsdtar_windows.c	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/bsdtar_windows.c	2011-05-30 05:59:02.000000000 -0700
@@ -268,7 +268,7 @@
 		if (sizeof(root) -3 < len)
 			return (0);
 		root[0] = root[1] = L'\\';
-		wcsncpy(root + 2, path1 + 8 , len);
+		wcsncpy(root + 2, path1 + 8, len);
 		/* root : "\\Server\Share\" */
 		root[2 + len] = L'\0';
 	} else if (wcsncmp(path1, L"\\\\?\\", 4) == 0) {
--- tarsnap-1.0.29/tar/ccache/ccache.h	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/ccache/ccache.h	2011-04-21 12:53:27.000000000 -0700
@@ -21,7 +21,7 @@
  * ${sb}, to the multitape with write cookie ${cookie}.  Look up the file in
  * the chunkification cache ${cache}, and set ${fullentry} to a non-zero
  * value iff the cache can provide at least sb->st_size bytes of the archive
- * entry.  Return a cookie which can be passed to either ccahe_entry_write
+ * entry.  Return a cookie which can be passed to either ccache_entry_write
  * or ccache_entry_start depending upon whether ${fullentry} is zero or not.
  */
 CCACHE_ENTRY * ccache_entry_lookup(CCACHE *, const char *,
--- tarsnap-1.0.29/tar/ccache/ccache_entry.c	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/ccache/ccache_entry.c	2011-08-07 08:21:06.000000000 -0700
@@ -53,7 +53,7 @@
 	if (cce->hittrailer)
 		goto done;
 
-	/* Do we need to expand the allocate space? */
+	/* Do we need to expand the allocated space? */
 	if (ccr->nch >= ccr->nchalloc) {
 		/* Double the allocated memory. */
 		if (ccr->nchalloc)
--- tarsnap-1.0.29/tar/ccache/ccache_internal.h	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/ccache/ccache_internal.h	2011-08-08 13:05:57.000000000 -0700
@@ -59,7 +59,7 @@
 	/* Immediately following each record is suffix[]. */
 };
 /**
- * After all of the cache_record_external and suffix[] pairs, the
+ * After all of the ccache_record_external and suffix[] pairs, the
  * struct chunkheader chp[] and uint8_t ztrailer[] data is stored in the
  * same order.
  */
--- tarsnap-1.0.29/tar/chunks/chunks_directory.c	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/chunks/chunks_directory.c	2011-04-20 00:36:46.000000000 -0700
@@ -176,7 +176,7 @@
 	    (size_t)(sb.st_size - sizeof(struct chunkstats_external)) /
 	    sizeof(struct chunkdata_external);
 
-	/* Make sure we we don't get an integer overflow. */
+	/* Make sure we don't get an integer overflow. */
 	if (numchunks >= SIZE_MAX / sizeof(struct chunkdata)) {
 		warn0("on-disk directory is too large: %s", s);
 		goto err2;
--- tarsnap-1.0.29/tar/chunks/chunks_internal.h	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/chunks/chunks_internal.h	2011-08-08 13:42:11.000000000 -0700
@@ -20,7 +20,7 @@
 	size_t zlen;		/* Compressed length of chunk. */
 	size_t nrefs;		/* Number of existing tapes using this. */
 	size_t ncopies;		/* Number of copies of this chunk. */
-	size_t ncopies_ctape;	/* Used by chunks_fsck only. */
+	size_t ncopies_ctape;	/* Used by chunks_stats only. */
 	int flags;		/* See CHDATA_* flags. */
 };
 
--- tarsnap-1.0.29/tar/chunks/chunks_stats_internal.c	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/chunks/chunks_stats_internal.c	2011-05-24 23:14:53.000000000 -0700
@@ -96,7 +96,7 @@
 	s.s_len = stats->s_len + stats_extra->s_len;
 	s.s_zlen = stats->s_zlen + stats_extra->s_zlen;
 
-	/* Stringify values, */
+	/* Stringify values. */
 	if (tarsnap_opt_humanize_numbers) {
 		if ((s_lenstr = humansize(s.s_len)) == NULL)
 			goto err0;
--- tarsnap-1.0.29/tar/cmdline.c	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/cmdline.c	2011-05-30 05:54:18.000000000 -0700
@@ -197,7 +197,7 @@
  *
  * TODO: If we want to support arbitrary command-line options from -T
  * input (as GNU tar does), we may need to extend this to handle option
- * words from sources other than argv/arc.  I'm not really sure if I
+ * words from sources other than argv/argc.  I'm not really sure if I
  * like that feature of GNU tar, so it's certainly not a priority.
  */
 
--- tarsnap-1.0.29/tar/glue/archive_multitape.c	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/glue/archive_multitape.c	2011-04-20 00:36:56.000000000 -0700
@@ -118,7 +118,7 @@
  * Open the multitape tape ${tapename} for writing and associate it with the
  * archive $a$.  If ${printstats} is non-zero, print archive statistics when
  * the tape is closed.  If ${dryrun} is non-zero, perform a dry run.  Return
- * a cookie which which can be passed to the multitape layer.
+ * a cookie which can be passed to the multitape layer.
  */
 void *
 archive_write_open_multitape(struct archive * a, uint64_t machinenum,
--- tarsnap-1.0.29/tar/glue/archive_multitape.h	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/glue/archive_multitape.h	2011-04-20 00:37:12.000000000 -0700
@@ -14,7 +14,7 @@
  * Open the multitape tape ${tapename} for writing and associate it with the
  * archive $a$.  If ${printstats} is non-zero, print archive statistics when
  * the tape is closed.  If ${dryrun} is non-zero, perform a dry run.  Return
- * a cookie which which can be passed to the multitape layer.
+ * a cookie which can be passed to the multitape layer.
  */
 void * archive_write_open_multitape(struct archive *, uint64_t, const char *,
     const char *, int argc, char ** argv, int, int);
--- tarsnap-1.0.29/tar/matching.c	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/matching.c	2011-05-26 15:57:08.000000000 -0700
@@ -122,20 +122,21 @@
 add_pattern(struct bsdtar *bsdtar, struct match **list, const char *pattern)
 {
 	struct match *match;
+	size_t len;
 
-	match = malloc(sizeof(*match) + strlen(pattern) + 1);
+	len = strlen(pattern);
+	match = malloc(sizeof(*match) + len + 1);
 	if (match == NULL)
 		bsdtar_errc(bsdtar, 1, errno, "Out of memory");
 	strcpy(match->pattern, pattern);
 	/* Both "foo/" and "foo" should match "foo/bar". */
-	if (match->pattern[strlen(match->pattern)-1] == '/')
-		match->pattern[strlen(match->pattern)-1] = '\0';
+	if (len && match->pattern[len - 1] == '/')
+		match->pattern[len - 1] = '\0';
 	match->next = *list;
 	*list = match;
 	match->matches = 0;
 }
 
-
 int
 excluded(struct bsdtar *bsdtar, const char *pathname)
 {
--- tarsnap-1.0.29/tar/multitape/chunkify.c	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/multitape/chunkify.c	2011-06-22 04:19:06.000000000 -0700
@@ -19,7 +19,7 @@
 	uint32_t p;		/* Modulus */
 	uint32_t pp;		/* - p^(-1) mod 2^32 */
 	uint32_t ar;		/* alpha * 2^32 mod p */
-	uint32_t * cm;		/* Coefficent map modulo p */
+	uint32_t * cm;		/* Coefficient map modulo p */
 	uint32_t htlen;		/* Size of hash table in 2-word entries */
 	uint32_t blen;		/* Length of buf[] */
 	uint32_t w;		/* Minimum substring length; size of b[] */
@@ -48,7 +48,7 @@
 static uint32_t isqrt(uint32_t x);
 static void chunkify_start(CHUNKIFIER * c);
 
-/* Returns nonzero iff n is prime */
+/* Returns nonzero iff n is prime. */
 static int
 isprime(uint32_t n)
 {
@@ -136,15 +136,15 @@
 {
 	uint32_t i;
 
-	/* No entries in the hash table */
+	/* No entries in the hash table. */
 	for (i = 0; i < c->htlen; i++)
 		c->ht[i * 2] = - c->htlen;
 
-	/* Nothing in the queue waiting to be added to the table, either */
+	/* Nothing in the queue waiting to be added to the table, either. */
 	for (i = 0; i < c->w; i++)
 		c->b[i] = c->p;
 
-	/* No bytes input yet */
+	/* No bytes input yet. */
 	c->akr = (- c->p) % c->p;
 	c->yka = 0;
 	c->k = 0;
@@ -255,7 +255,7 @@
 	c->p = nextprime(pmin + (c->p % isqrt(c->mu)));
 	/* c->p <= 1431655739 < 1431655765 = floor(2^32 / 3) */
 
-	/* Compute pp = - p^(-1) mod 2^32 */
+	/* Compute pp = - p^(-1) mod 2^32. */
 	c->pp = ((2 * c->p + 4) & 8) - c->p;	/* pp = - 1/p mod 2^4 */
 	c->pp *= 2 + c->p * c->pp;		/* pp = - 1/p mod 2^8 */
 	c->pp *= 2 + c->p * c->pp;		/* pp = - 1/p mod 2^16 */
@@ -273,7 +273,7 @@
 	}
 
 	/*
-	 * Prepare for incoming data
+	 * Prepare for incoming data.
 	 */
 	chunkify_start(c);
 
@@ -283,7 +283,7 @@
 	return (c);
 
 err:
-	/* free(NULL) is safe, so it doesn't matter where we jumped from */
+	/* free(NULL) is safe, so it doesn't matter where we jumped from. */
 	free(c->buf);
 	free(c->ht);
 	free(c->b);
@@ -301,7 +301,7 @@
 	int rc;
 
 	for (i = 0; i < buflen; i++) {
-		/* Add byte to buffer */
+		/* Add byte to buffer. */
 		c->buf[c->k] = buf[i];
 
 		/* k := k + 1 */
@@ -327,14 +327,14 @@
 			continue;
 
 		/*
-		 * Update state to add new character
+		 * Update state to add new character.
 		 */
 
 		/* y_k(a) := y_k(a) + a^k * x_k mod p */
-		/* yka <= p * (2 + p / (2^32 - p)) <= p * 2.5 < 2^31 + p*/
+		/* yka <= p * (2 + p / (2^32 - p)) <= p * 2.5 < 2^31 + p */
 		c->yka += mmul(c->akr, c->cm[buf[i]], c->p, c->pp);
 
-		/* Each step reduces yka by p iff yka >= p */
+		/* Each step reduces yka by p iff yka >= p. */
 		c->yka -= c->p & (((c->yka - c->p) >> 31) - 1);
 		c->yka -= c->p & (((c->yka - c->p) >> 31) - 1);
 
@@ -358,7 +358,7 @@
 			if (c->k - c->ht[2 * htpos] - 1 >= 2 * c->r)
 				break;
 
-			/* Move to the next position in the table */
+			/* Move to the next position in the table. */
 			htpos = (htpos + 1) & (c->htlen - 1);
 		} while (1);
 
@@ -375,7 +375,7 @@
 				break;
 			}
 
-			/* Move to the next position in the table */
+			/* Move to the next position in the table. */
 			htpos = (htpos + 1) & (c->htlen - 1);
 		} while (1);
 
@@ -406,16 +406,16 @@
 {
 	int rc;
 
-	/* If we haven't started the chunk yet, don't end it either */
+	/* If we haven't started the chunk yet, don't end it either. */
 	if (c->k == 0)
 		return (0);
 
-	/* Process the chunk */
+	/* Process the chunk. */
 	rc = (c->chunkdone)(c->cookie, c->buf, c->k);
 	if (rc)
 		return (rc);
 
-	/* Prepare for more input */
+	/* Prepare for more input. */
 	chunkify_start(c);
 
 	return (0);
@@ -429,7 +429,7 @@
 	if (c == NULL)
 		return;
 
-	/* Free everything */
+	/* Free everything. */
 	free(c->buf);
 	free(c->ht);
 	free(c->b);
--- tarsnap-1.0.29/tar/multitape/multitape_fsck.c	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/multitape/multitape_fsck.c	2011-04-21 12:53:51.000000000 -0700
@@ -164,7 +164,7 @@
 	if (storage_directory_read(machinenum, 'm', 0, &flist, &nfiles))
 		goto err0;
 
-	/* Allocate space for nfiles tapemetadat structures. */
+	/* Allocate space for nfiles tapemetadata structures. */
 	if ((mdats = malloc(nfiles * sizeof(struct tapemetadata *))) == NULL)
 		goto err1;
 	nvalids = 0;
--- tarsnap-1.0.29/tar/multitape/multitape_internal.h	2011-01-31 05:54:33.000000000 -0800
+++ tarsnap-1.0.30/tar/multitape/multitape_internal.h	2011-04-24 00:42:32.000000000 -0700
@@ -121,7 +121,7 @@
  * Read and parse metadata for the archive named ${tapename}.  If ${C} is
  * non-NULL, call chunks_stats_extrastats on ${C} and the length of the
  * metadata file.  If ${quiet}, don't print any warnings about corrupt or
- * missing files. Return 0 on success, 1 if the metadata file does not
+ * missing files.  Return 0 on success, 1 if the metadata file does not
  * exist, 2 if the metadata file is corrupt, or -1 on error.
  */
 int multitape_metadata_get_byname(STORAGE_R *, CHUNKS_S *,
--- tarsnap-1.0.29/tar/multitape/multitape_metadata.c	2011-01-31 06:04:39.000000000 -0800
+++ tarsnap-1.0.30/tar/multitape/multitape_metadata.c	2011-04-24 00:42:45.000000000 -0700
@@ -403,7 +403,7 @@
  * Read and parse metadata for the archive named ${tapename}.  If ${C} is
  * non-NULL, call chunks_stats_extrastats on ${C} and the length of the
  * metadata file.  If ${quiet}, don't print any warnings about corrupt or
- * missing files. Return 0 on success, 1 if the metadata file does not
+ * missing files.  Return 0 on success, 1 if the metadata file does not
  * exist, 2 if the metadata file is corrupt, or -1 on error.
  */
 int multitape_metadata_get_byname(STORAGE_R * S, CHUNKS_S * C,
--- tarsnap-1.0.29/tar/multitape/multitape_metaindex.c	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/multitape/multitape_metaindex.c	2011-08-14 13:59:01.000000000 -0700
@@ -87,17 +87,20 @@
 	/* Copy values into buffer. */
 	le32enc(p, mind->hindexlen);
 	p += 4;
-	memcpy(p, mind->hindex, mind->hindexlen);
+	if (mind->hindexlen > 0)
+		memcpy(p, mind->hindex, mind->hindexlen);
 	p += mind->hindexlen;
 
 	le32enc(p, mind->cindexlen);
 	p += 4;
-	memcpy(p, mind->cindex, mind->cindexlen);
+	if (mind->cindexlen > 0)
+		memcpy(p, mind->cindex, mind->cindexlen);
 	p += mind->cindexlen;
 
 	le32enc(p, mind->tindexlen);
 	p += 4;
-	memcpy(p, mind->tindex, mind->tindexlen);
+	if (mind->tindexlen > 0)
+		memcpy(p, mind->tindex, mind->tindexlen);
 	p += mind->tindexlen;
 
 	/* Compute hash of tape name. */
@@ -222,9 +225,11 @@
 
 	if (buflen < mind->hindexlen)
 		goto corrupt0;
-	if ((mind->hindex = malloc(mind->hindexlen)) == NULL)
+	if (((mind->hindex = malloc(mind->hindexlen)) == NULL) &&
+	    (mind->hindexlen > 0))
 		goto err1;
-	memcpy(mind->hindex, buf, mind->hindexlen);
+	if (mind->hindexlen > 0)
+		memcpy(mind->hindex, buf, mind->hindexlen);
 	buf += mind->hindexlen;
 	buflen -= mind->hindexlen;
 
@@ -237,9 +242,11 @@
 
 	if (buflen < mind->cindexlen)
 		goto corrupt1;
-	if ((mind->cindex = malloc(mind->cindexlen)) == NULL)
+	if (((mind->cindex = malloc(mind->cindexlen)) == NULL) &&
+	    (mind->cindexlen > 0))
 		goto err2;
-	memcpy(mind->cindex, buf, mind->cindexlen);
+	if (mind->cindexlen > 0)
+		memcpy(mind->cindex, buf, mind->cindexlen);
 	buf += mind->cindexlen;
 	buflen -= mind->cindexlen;
 
@@ -252,9 +259,11 @@
 
 	if (buflen < mind->tindexlen)
 		goto corrupt2;
-	if ((mind->tindex = malloc(mind->tindexlen)) == NULL)
+	if (((mind->tindex = malloc(mind->tindexlen)) == NULL) &&
+	    (mind->tindexlen > 0))
 		goto err3;
-	memcpy(mind->tindex, buf, mind->tindexlen);
+	if (mind->tindexlen > 0)
+		memcpy(mind->tindex, buf, mind->tindexlen);
 	buf += mind->tindexlen;
 	buflen -= mind->tindexlen;
 
--- tarsnap-1.0.29/tar/multitape/multitape_read.c	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/multitape/multitape_read.c	2011-08-14 13:30:34.000000000 -0700
@@ -198,15 +198,15 @@
 		if (readlen > buflen - bufpos)
 			readlen = buflen - bufpos;
 
+		/* Stop looping if we have no more data. */
+		if (readlen == 0)
+			break;
+
 		/* Mark the data as consumed. */
 		S->chunkpos += readlen;
 
 		/* Copy into the correct position in our buffer. */
 		memcpy(buf + bufpos, readbuf, readlen);
-
-		/* Stop looping if we have no more data. */
-		if (readlen == 0)
-			break;
 	}
 
 	/* Success (or perhaps EOF). */
--- tarsnap-1.0.29/tar/multitape/multitape_write.c	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/multitape/multitape_write.c	2011-05-08 14:30:03.000000000 -0700
@@ -46,7 +46,7 @@
 	uint64_t machinenum;	/* Machine number. */
 	char * cachedir;	/* Cache directory. */
 	time_t ctime;		/* Archive creation time. */
-	int argc;		/* Number of commmand-line arguments. */
+	int argc;		/* Number of command-line arguments. */
 	char ** argv;		/* Command-line arguments. */
 	int stats_enabled;	/* Stats printed on close. */
 	int eof;		/* Tape is truncated at current position. */
--- tarsnap-1.0.29/tar/storage/storage.h	2011-01-23 21:23:46.000000000 -0800
+++ tarsnap-1.0.30/tar/storage/storage.h	2011-04-21 12:54:52.000000000 -0700
@@ -47,7 +47,7 @@
  * malloc a buffer.  Invoke ${callback}(${cookie}, status, b, blen) when
  * complete, where ${status} is 0, 1, 2, or -1 as per storage_read_file,
  * ${b} is the buffer into which the data was read (which will be ${buf} if
- * that value was non-NUL) and ${blen} is the length of the file.
+ * that value was non-NULL) and ${blen} is the length of the file.
  */
 int storage_read_file_callback(STORAGE_R *, uint8_t *, size_t, char,
     const uint8_t[32], int(*)(void *, int, uint8_t *, size_t), void *);
@@ -60,7 +60,7 @@
 
 /**
  * storage_write_start(machinenum, lastseq, seqnum, dryrun):
- * Start a write transaction, presuming that ${lastseq} is the the sequence
+ * Start a write transaction, presuming that ${lastseq} is the sequence
  * number of the last committed transaction, or zeroes if there is no
  * previous transaction; and store the sequence number of the new transaction
  * into ${seqnum}.  If ${dryrun} is nonzero, perform a dry run.
@@ -108,7 +108,7 @@
 
 /**
  * storage_delete_start(machinenum, lastseq, seqnum):
- * Start a delete transaction, presuming that ${lastseq} is the the sequence
+ * Start a delete transaction, presuming that ${lastseq} is the sequence
  * number of the last committed transaction, or zeroes if there is no
  * previous transaction; and store the sequence number of the new transaction
  * into ${seqnum}.
@@ -149,7 +149,7 @@
 
 /**
  * storage_delete_free(S):
- * Free any memory allocated as part of the delete transcation associated
+ * Free any memory allocated as part of the delete transaction associated
  * with the cookie ${S}; the transaction will not be committed.
  */
 void storage_delete_free(STORAGE_D *);
--- tarsnap-1.0.29/tar/storage/storage_delete.c	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/storage/storage_delete.c	2011-04-21 12:54:35.000000000 -0700
@@ -50,7 +50,7 @@
 
 /**
  * storage_delete_start(machinenum, lastseq, seqnum):
- * Start a delete transaction, presuming that ${lastseq} is the the sequence
+ * Start a delete transaction, presuming that ${lastseq} is the sequence
  * number of the last committed transaction, or zeroes if there is no
  * previous transaction; and store the sequence number of the new transaction
  * into ${seqnum}.
@@ -337,7 +337,7 @@
 
 /**
  * storage_delete_free(S):
- * Free any memory allocated as part of the delete transcation associated
+ * Free any memory allocated as part of the delete transaction associated
  * with the cookie ${S}; the transaction will not be committed.
  */
 void
--- tarsnap-1.0.29/tar/storage/storage_directory.c	2011-01-26 01:50:49.000000000 -0800
+++ tarsnap-1.0.30/tar/storage/storage_directory.c	2011-08-14 13:14:07.000000000 -0700
@@ -198,8 +198,8 @@
 		}
 		if ((flist_new = malloc(C->nfiles_alloc * 32)) == NULL)
 			goto err0;
-
-		memcpy(flist_new, C->flist, C->nfiles * 32);
+		if (C->nfiles > 0)
+			memcpy(flist_new, C->flist, C->nfiles * 32);
 		free(C->flist);
 		C->flist = flist_new;
 	}
--- tarsnap-1.0.29/tar/storage/storage_read.c	2011-01-23 22:54:19.000000000 -0800
+++ tarsnap-1.0.30/tar/storage/storage_read.c	2011-04-21 12:55:05.000000000 -0700
@@ -150,7 +150,7 @@
  * malloc a buffer.  Invoke ${callback}(${cookie}, status, b, blen) when
  * complete, where ${status} is 0, 1, 2, or -1 as per storage_read_file,
  * ${b} is the buffer into which the data was read (which will be ${buf} if
- * that value was non-NUL) and ${blen} is the length of the file.
+ * that value was non-NULL) and ${blen} is the length of the file.
  */
 int
 storage_read_file_callback(STORAGE_R * S, uint8_t * buf, size_t buflen,
--- tarsnap-1.0.29/tar/storage/storage_transaction.c	2011-02-01 12:56:25.000000000 -0800
+++ tarsnap-1.0.30/tar/storage/storage_transaction.c	2011-05-30 05:55:03.000000000 -0700
@@ -142,8 +142,8 @@
 	C.whichkey = whichkey;
 
 	/*
-	 * As the server to cancel any in-progress transaction; if it asks us
-	 * to go away and come back later, sleep 1 second and then poke it
+	 * Ask the server to cancel any in-progress transaction; if it asks
+	 * us to go away and come back later, sleep 1 second and then poke it
 	 * again.
 	 */
 	do {
--- tarsnap-1.0.29/tar/storage/storage_write.c	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/storage/storage_write.c	2011-04-21 12:54:04.000000000 -0700
@@ -118,7 +118,7 @@
 
 /**
  * storage_write_start(machinenum, lastseq, seqnum, dryrun):
- * Start a write transaction, presuming that ${lastseq} is the the sequence
+ * Start a write transaction, presuming that ${lastseq} is the sequence
  * number of the last committed transaction, or zeroes if there is no
  * previous transaction; and store the sequence number of the new transaction
  * into ${seqnum}.  If ${dryrun} is nonzero, perform a dry run.
@@ -463,7 +463,7 @@
 			goto err0;
 	}
 
-	/* Succes! */
+	/* Success! */
 	return (0);
 
 err0:
--- tarsnap-1.0.29/tar/subst.c	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/subst.c	2011-07-28 21:02:17.000000000 -0700
@@ -153,7 +153,8 @@
 	new_str = malloc(old_len + len + 1);
 	if (new_str == NULL)
 		bsdtar_errc(bsdtar, 1, errno, "Out of memory");
-	memcpy(new_str, *str, old_len);
+	if (*str != NULL)
+		memcpy(new_str, *str, old_len);
 	memcpy(new_str + old_len, append, len);
 	new_str[old_len + len] = '\0';
 	free(*str);
@@ -174,7 +175,8 @@
 	new_str = malloc(old_len + strlen(append) + 1);
 	if (new_str == NULL)
 		bsdtar_errc(bsdtar, 1, errno, "Out of memory");
-	memcpy(new_str, *str, old_len);
+	if (*str != NULL)
+		memcpy(new_str, *str, old_len);
 	strcpy(new_str + old_len, append);
 	free(*str);
 	*str = new_str;
--- tarsnap-1.0.29/tar/tarsnap.1-man.in	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/tarsnap.1-man.in	2011-04-22 16:13:38.000000000 -0700
@@ -595,7 +595,7 @@
 Extract files as sparse files.
 For every block on disk, check first if it contains only NULL bytes and seek
 over it otherwise.
-This works similiar to the conv=sparse option of dd.
+This works similar to the conv=sparse option of dd.
 .It Fl s Ar pattern
 Modify file or archive member names according to
 .Pa pattern .
@@ -603,10 +603,10 @@
 old is a basic regular expression.
 If it doesn't apply, the pattern is skipped.
 new is the replacement string of the matched part.
-~ is substituted with the match, \1 to \9 with the content of
+~ is substituted with the match, \e1 to \e9 with the contents of
 the corresponding captured group.
 The optional trailing g specifies that matching should continue
-after the matched part and stopped on the first unmatched pattern.
+after the matched part and stop on the first unmatched pattern.
 The optional trailing s specifies that the pattern applies to the value
 of symbolic links.
 The optional trailing p specifies that after a successful substitution
--- tarsnap-1.0.29/tar/tarsnap.1-mdoc.in	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/tarsnap.1-mdoc.in	2011-04-22 16:13:38.000000000 -0700
@@ -595,7 +595,7 @@
 Extract files as sparse files.
 For every block on disk, check first if it contains only NULL bytes and seek
 over it otherwise.
-This works similiar to the conv=sparse option of dd.
+This works similar to the conv=sparse option of dd.
 .It Fl s Ar pattern
 Modify file or archive member names according to
 .Pa pattern .
@@ -603,10 +603,10 @@
 old is a basic regular expression.
 If it doesn't apply, the pattern is skipped.
 new is the replacement string of the matched part.
-~ is substituted with the match, \1 to \9 with the content of
+~ is substituted with the match, \e1 to \e9 with the contents of
 the corresponding captured group.
 The optional trailing g specifies that matching should continue
-after the matched part and stopped on the first unmatched pattern.
+after the matched part and stop on the first unmatched pattern.
 The optional trailing s specifies that the pattern applies to the value
 of symbolic links.
 The optional trailing p specifies that after a successful substitution
--- tarsnap-1.0.29/tar/tree.c	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/tree.c	2011-08-11 17:38:00.000000000 -0700
@@ -183,6 +183,8 @@
 	struct tree_entry *te;
 
 	te = malloc(sizeof(*te));
+	if (te == NULL)
+		abort();
 	memset(te, 0, sizeof(*te));
 	te->next = t->stack;
 	t->stack = te;
@@ -203,6 +205,7 @@
 tree_append(struct tree *t, const char *name, size_t name_length)
 {
 	char *p;
+	size_t size_needed;
 
 	if (t->buff != NULL)
 		t->buff[t->dirname_length] = '\0';
@@ -211,12 +214,16 @@
 		name_length--;
 
 	/* Resize pathname buffer as needed. */
-	while (name_length + 1 + t->dirname_length >= t->buff_length) {
-		t->buff_length *= 2;
+	size_needed = name_length + 1 + t->dirname_length;
+	if (t->buff_length < size_needed) {
 		if (t->buff_length < 1024)
 			t->buff_length = 1024;
+		while (t->buff_length < size_needed)
+			t->buff_length *= 2;
 		t->buff = realloc(t->buff, t->buff_length);
 	}
+	if (t->buff == NULL)
+		abort();
 	p = t->buff + t->dirname_length;
 	t->path_length = t->dirname_length + name_length;
 	/* Add a separating '/' if it's needed. */
@@ -249,6 +256,8 @@
 	struct tree *t;
 
 	t = malloc(sizeof(*t));
+	if (t == NULL)
+		abort();
 	memset(t, 0, sizeof(*t));
 	tree_append(t, path, strlen(path));
 #ifdef HAVE_FCHDIR
@@ -348,9 +357,9 @@
 	 * violation.  Just crash now. */
 	if (t->visit_type == TREE_ERROR_FATAL) {
 		const char *msg = "Unable to continue traversing"
-		    " directory heirarchy after a fatal error.";
+		    " directory hierarchy after a fatal error.\n";
 		write(2, msg, strlen(msg));
-		*(int *)0 = 1; /* Deliberate SEGV; NULL pointer dereference. */
+		*(volatile int *)0 = 1; /* Deliberate SEGV; NULL pointer dereference. */
 		exit(1); /* In case the SEGV didn't work. */
 	}
 
@@ -363,8 +372,17 @@
 	while (t->stack != NULL) {
 		/* If there's an open dir, get the next entry from there. */
 		while (t->d != NULL) {
+			errno = 0;
 			de = readdir(t->d);
 			if (de == NULL) {
+				if (errno) {
+					/* If readdir fails, we're screwed. */
+					closedir(t->d);
+					t->d = NULL;
+					t->visit_type = TREE_ERROR_FATAL;
+					return (t->visit_type);
+				}
+				/* Reached end of directory. */
 				closedir(t->d);
 				t->d = NULL;
 			} else if (de->d_name[0] == '.'
@@ -641,9 +659,11 @@
 /*
  * Terminate the traversal and release any resources.
  */
-void
+int
 tree_close(struct tree *t)
 {
+	int rc = 0;
+
 	/* Release anything remaining in the stack. */
 	while (t->stack != NULL)
 		tree_pop(t);
@@ -652,16 +672,18 @@
 	/* chdir() back to where we started. */
 #ifdef HAVE_FCHDIR
 	if (t->initialDirFd >= 0) {
-		fchdir(t->initialDirFd);
+		rc = fchdir(t->initialDirFd);
 		close(t->initialDirFd);
 		t->initialDirFd = -1;
 	}
 #elif defined(_WIN32) && !defined(__CYGWIN__)
 	if (t->initialDir != NULL) {
-		chdir(t->initialDir);
+		rc = chdir(t->initialDir);
 		free(t->initialDir);
 		t->initialDir = NULL;
 	}
 #endif
 	free(t);
+
+	return (rc);
 }
--- tarsnap-1.0.29/tar/tree.h	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/tree.h	2011-08-02 09:17:02.000000000 -0700
@@ -54,7 +54,7 @@
 
 /* Initiate/terminate a tree traversal. */
 struct tree *tree_open(const char * /* pathname */);
-void tree_close(struct tree *);
+int tree_close(struct tree *);
 
 /*
  * tree_next() returns Zero if there is no next entry, non-zero if
--- tarsnap-1.0.29/tar/write.c	2011-01-19 20:32:48.000000000 -0800
+++ tarsnap-1.0.30/tar/write.c	2011-08-02 09:20:28.000000000 -0700
@@ -287,7 +287,7 @@
 	    &bsdtar->cachedir_dev, &bsdtar->cachedir_ino))
 		bsdtar_errc(bsdtar, 1, 0, archive_error_string(a));
 
-	/* Read the chunkfication cache. */
+	/* Read the chunkification cache. */
 	if (bsdtar->cachecrunch < 2) {
 		bsdtar->chunk_cache = ccache_read(bsdtar->cachedir);
 		if (bsdtar->chunk_cache == NULL)
@@ -367,6 +367,12 @@
 					bsdtar->return_value = 1;
 					goto cleanup;
 				}
+				if (*arg == '\0') {
+					bsdtar_warnc(bsdtar, 0,
+					    "Meaningless argument for -C: ''");
+					bsdtar->return_value = 1;
+					goto cleanup;
+				}
 			}
 			set_chdir(bsdtar, arg);
 		} else {
@@ -457,7 +463,13 @@
 archive_names_from_file_helper(struct bsdtar *bsdtar, const char *line)
 {
 	if (bsdtar->next_line_is_dir) {
-		set_chdir(bsdtar, line);
+		if (*line != '\0')
+			set_chdir(bsdtar, line);
+		else {
+			bsdtar_warnc(bsdtar, 0,
+			    "Meaningless argument for -C: ''");
+			bsdtar->return_value = 1;
+		}
 		bsdtar->next_line_is_dir = 0;
 	} else if (!bsdtar->option_null && strcmp(line, "-C") == 0)
 		bsdtar->next_line_is_dir = 1;
@@ -771,7 +783,7 @@
 		 * If the user did not specify --insane-filesystems, do not
 		 * cross into a new filesystem which is known to be synthetic.
 		 * Note that we will archive synthetic filesystems if we are
-		 * explcitly told to do so.
+		 * explicitly told to do so.
 		 */
 		if ((bsdtar->option_insane_filesystems == 0) &&
 		    (dev_recorded == 1) &&
@@ -797,7 +809,7 @@
 
 		/*
 		 * If user has asked us not to cross mount points,
-		 * then don't descend into into a dir on a different
+		 * then don't descend into a dir on a different
 		 * device.
 		 */
 		if (!dev_recorded) {
@@ -946,7 +958,8 @@
 			fprintf(stderr, "\n");
 	}
 	archive_entry_free(entry);
-	tree_close(tree);
+	if (tree_close(tree))
+		bsdtar_errc(bsdtar, 1, 0, "Error traversing directory tree");
 }
 
 /*
