commit 59d0d2fdf82e3618635248def8d573afb2980d65
Author: Tim Woodall <tim@woodall.me.uk>
Date:   Sun Sep 29 19:21:06 2024 +0100

    Handle dumps of over 2^32 blocks
    
      DUMP: Can't open /etc/mtab for dump table information: No such file or directory
      DUMP: Can't open /etc/fstab for dump table information: No such file or directory
      DUMP: Date of this level 0 dump: Fri Sep 27 22:04:19 2024
      DUMP: Dumping /dev/loop2 (an unlisted file system) to /dev/null
      DUMP: Label: none
      DUMP: Writing 10 Kilobyte records
      DUMP: mapping (Pass I) [regular files]
      DUMP: mapping (Pass II) [directories]
      DUMP: estimated 5379195388 blocks.
      DUMP: Volume 1 started with block 1 at: Fri Sep 27 22:04:19 2024
      DUMP: dumping (Pass III) [directories]
      DUMP: dumping (Pass IV) [regular files]
      DUMP: 1.89% done at 339312 kB/s, finished in 4:19
      DUMP: 3.79% done at 339490 kB/s, finished in 4:14
      DUMP: 6.07% done at 362527 kB/s, finished in 3:52
      DUMP: 8.37% done at 375206 kB/s, finished in 3:38
      DUMP: 10.67% done at 382810 kB/s, finished in 3:29
      DUMP: 12.98% done at 387849 kB/s, finished in 3:21
      DUMP: 15.28% done at 391466 kB/s, finished in 3:14
      DUMP: 17.59% done at 394185 kB/s, finished in 3:07
      DUMP: 19.89% done at 396329 kB/s, finished in 3:01
      DUMP: 22.20% done at 398014 kB/s, finished in 2:55
      DUMP: 24.50% done at 399426 kB/s, finished in 2:49
      DUMP: 26.81% done at 400584 kB/s, finished in 2:43
      DUMP: 29.12% done at 401577 kB/s, finished in 2:38
      DUMP: 31.42% done at 402411 kB/s, finished in 2:32
      DUMP: 33.73% done at 403147 kB/s, finished in 2:27
      DUMP: 36.03% done at 403781 kB/s, finished in 2:22
      DUMP: 38.34% done at 404354 kB/s, finished in 2:16
      DUMP: 40.64% done at 404845 kB/s, finished in 2:11
      DUMP: 42.95% done at 405282 kB/s, finished in 2:06
      DUMP: 45.25% done at 405669 kB/s, finished in 2:01
      DUMP: 47.55% done at 406030 kB/s, finished in 1:55
      DUMP: 49.86% done at 406351 kB/s, finished in 1:50
      DUMP: 52.16% done at 406642 kB/s, finished in 1:45
      DUMP: 54.46% done at 406907 kB/s, finished in 1:40
      DUMP: 56.77% done at 407173 kB/s, finished in 1:35
      DUMP: 59.07% done at 407404 kB/s, finished in 1:30
      DUMP: 61.38% done at 407615 kB/s, finished in 1:24
      DUMP: 63.68% done at 407823 kB/s, finished in 1:19
      DUMP: 65.99% done at 408010 kB/s, finished in 1:14
      DUMP: 68.30% done at 408193 kB/s, finished in 1:09
      DUMP: 70.61% done at 408405 kB/s, finished in 1:04
      DUMP: 72.92% done at 408602 kB/s, finished in 0:59
      DUMP: 75.24% done at 408798 kB/s, finished in 0:54
      DUMP: 77.55% done at 408982 kB/s, finished in 0:49
      DUMP: 79.87% done at 409158 kB/s, finished in 0:44
      DUMP: 82.18% done at 409319 kB/s, finished in 0:39
      DUMP: 84.50% done at 409477 kB/s, finished in 0:33
      DUMP: 86.81% done at 409621 kB/s, finished in 0:28
      DUMP: 89.12% done at 409760 kB/s, finished in 0:23
      DUMP: 91.44% done at 409888 kB/s, finished in 0:18
      DUMP: 93.75% done at 410015 kB/s, finished in 0:13
      DUMP: 96.04% done at 410007 kB/s, finished in 0:08
      DUMP: 98.35% done at 410122 kB/s, finished in 0:03
      DUMP: Closing /dev/null
      DUMP: Volume 1 completed at: Sat Sep 28 01:42:52 2024
      DUMP: Volume 1 5379195370 blocks (5253120.48MB)
      DUMP: Volume 1 took 3:38:33
      DUMP: Volume 1 transfer rate: 410218 kB/s
      DUMP: 5379195370 blocks (5253120.48MB) on 1 volume(s)
      DUMP: finished in 13113 seconds, throughput 410218 kBytes/sec
      DUMP: Date of this level 0 dump: Fri Sep 27 22:04:19 2024
      DUMP: Date this dump completed:  Sat Sep 28 01:42:52 2024
      DUMP: Average transfer rate: 410218 kB/s
      DUMP: DUMP IS DONE

--- a/common/indexer_test.c
+++ b/common/indexer_test.c
@@ -43,8 +43,6 @@ int tapeno;
 struct slave slaves[SLAVES+1];
 struct slave *slp;
 
-union u_spcl u_spcl;
-
 #ifdef __linux__
 struct struct_ext2_filsys test_fs;
 struct ext2_super_block test_super;
@@ -122,7 +120,7 @@ dump_inode(Indexer *indexer, struct stat
 	dinode.di_ctime = buf->st_ctime;
 	dinode.di_blocks = buf->st_blocks;
 
-	spcl.c_tapea++;
+	u_spcl_c_tapea_add(1);
 
 	indexer->addInode(&dinode, buf->st_ino, 0);
 }
@@ -150,7 +148,7 @@ dump_walk(Indexer *indexer, const char *
 
 	//if (first) {
 	//	spcl.c_volume = 1;
-	//	spcl.c_tapea = 1;
+	//	u_spcl_c_tapea_set(1)
 	//	indexer->addDirEntry(&direct, direct.d_ino);
 	//	dump_inode(indexer, &bufroot);
 	//}
--- a/common/slave.h
+++ b/common/slave.h
@@ -25,14 +25,14 @@ struct req {
 #define SLAVES 3		/* 1 slave writing, 1 reading, 1 for slack */
 
 struct slave {
-	int tapea;		/* header number at start of this chunk */
-	int count;		/* count to next header (used for TS_TAPE */
+	long tapea;		/* header number at start of this chunk */
+	long count;		/* count to next header (used for TS_TAPE */
 				/* after EOT) */
 	int inode;		/* inode that we are currently dealing with */
 	int fd;			/* FD for this slave */
 	int pid;		/* PID for this slave */
 	int sent;		/* 1 == we've sent this slave requests */
-	int firstrec;		/* record number of this block */
+	long firstrec;		/* record number of this block */
 	char (*tblock)[TP_BSIZE]; /* buffer for data blocks */
 	struct req *req;	/* buffer for requests */
 };
--- a/common/sqlite_indexer.c
+++ b/common/sqlite_indexer.c
@@ -292,8 +292,8 @@ sqlite_close()
 		uuid_unparse_lower(fs->super->s_uuid, uuid);
 		strftime(ts, sizeof ts, "%FT%T", gmtime((const time_t *) &now));
 		snprintf(buffer, sizeof buffer,
-				"update backup set end_dt = '%s', blocks=%d, volumes=%d where fs_uuid='%s'",
-				ts, spcl.c_tapea, spcl.c_volume, uuid);
+				"update backup set end_dt = '%s', blocks=%ld, volumes=%d where fs_uuid='%s'",
+				ts, u_spcl_c_tapea(), spcl.c_volume, uuid);
 
 		EXEC(db, buffer);
 	}
@@ -408,8 +408,8 @@ sqlite_addInode(struct dinode *dp, dump_
 	// se linux?...
 
 	snprintf(buffer, sizeof buffer,
-		"insert into inode(backup_id, ino, is_deleted, mode, nlink, uid, gid, rdev, size, atime, mtime, ctime, has_xattr, has_acl, volume, recno) values(1, %d, '%s', %d, %d, %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', %d, %d)\n",
-		ino, "N", dp->di_mode, dp->di_nlink, dp->di_uid, dp->di_gid, dp->di_rdev, dp->di_size, ats, mts, cts, (dp->di_extraisize == 0) ? "N" : "Y", (dp->di_file_acl != 0) ? "Y" : "N", spcl.c_volume, spcl.c_tapea);
+		"insert into inode(backup_id, ino, is_deleted, mode, nlink, uid, gid, rdev, size, atime, mtime, ctime, has_xattr, has_acl, volume, recno) values(1, %d, '%s', %d, %d, %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', %d, %lld)\n",
+		ino, "N", dp->di_mode, dp->di_nlink, dp->di_uid, dp->di_gid, dp->di_rdev, dp->di_size, ats, mts, cts, (dp->di_extraisize == 0) ? "N" : "Y", (dp->di_file_acl != 0) ? "Y" : "N", spcl.c_volume, u_spcl_c_tapea());
 
 	EXEC(db, buffer);
 
--- a/compat/include/protocols/dumprestore.h
+++ b/compat/include/protocols/dumprestore.h
@@ -93,7 +93,7 @@ extern union u_spcl {
 		int32_t	c_date;		    /* date of this dump */
 		int32_t	c_ddate;	    /* date of previous dump */
 		int32_t	c_volume;	    /* dump volume number */
-		u_int32_t c_tapea;	    /* logical block of this record */
+		u_int32_t c_tapea_lo;	    /* logical block of this record */
 		dump_ino_t c_inumber;	    /* number of inode */
 		int32_t	c_magic;	    /* magic number (see above) */
 		int32_t	c_checksum;	    /* record checksum */
@@ -114,16 +114,24 @@ extern union u_spcl {
 		char	c_dev[NAMELEN];	    /* name of dumpped device */
 		char	c_host[NAMELEN];    /* name of dumpped host */
 		int32_t	c_flags;	    /* additional information */
-		int32_t	c_firstrec;	    /* first record on volume */
+		u_int32_t	c_firstrec_lo; /* first record on volume */
 		int32_t	c_ntrec;	    /* blocksize on volume */
-                int32_t	c_extattributes;    /* additional inode info */
-                int32_t	c_spare[30];	    /* reserved for future uses */
+		int32_t	c_extattributes;    /* additional inode info */
+		u_int32_t	c_tapea_hi; /* top 32 bits of c_tapea */
+		u_int32_t	c_firstrec_hi; /* top 32 bits of c_firstrec */
+		int32_t	c_spare[28];	    /* reserved for future uses */
 	} s_spcl;
 } u_spcl;
 #define spcl u_spcl.s_spcl
 #define c_addr c_data.s_addrs
 #define c_inos c_data.s_inos
 
+extern long u_spcl_c_tapea();
+extern void u_spcl_c_tapea_add(uint64_t inc);
+extern void u_spcl_c_tapea_set(uint64_t v);
+extern long u_spcl_c_firstrec(const struct s_spcl *buf);
+extern void u_spcl_c_firstrec_set(uint64_t v);
+
 /*
  * special record types
  */
--- a/compat/lib/dumprestore.c
+++ b/compat/lib/dumprestore.c
@@ -3,3 +3,24 @@
 union u_spcl u_spcl;
 union u_data u_data;
 
+long u_spcl_c_tapea() {
+  return spcl.c_tapea_lo | (((uint64_t)spcl.c_tapea_hi) << 32);
+}
+
+void u_spcl_c_tapea_set(uint64_t v) {
+  spcl.c_tapea_lo = v & 0xffffffffull;
+  spcl.c_tapea_hi = v >> 32;
+}
+
+void u_spcl_c_tapea_add(uint64_t inc) {
+  u_spcl_c_tapea_set(u_spcl_c_tapea() + inc);
+}
+
+long u_spcl_c_firstrec(const struct s_spcl *buf) {
+  return buf->c_firstrec_lo | (((uint64_t)buf->c_firstrec_hi) << 32);
+}
+
+void u_spcl_c_firstrec_set(uint64_t v) {
+  spcl.c_firstrec_lo = v & 0xffffffffull;
+  spcl.c_firstrec_hi = v >> 32;
+}
--- a/dump/dump.h
+++ b/dump/dump.h
@@ -98,7 +98,7 @@ extern int	compressed;	/* if set, dump i
 extern long long bytes_written;/* total bytes written to tape */
 extern long	uncomprblks;	/* uncompressed blocks written to tape */
 extern int	notify;		/* notify operator flag */
-extern int	blockswritten;	/* number of blocks written on current tape */
+extern long 	blockswritten;	/* number of blocks written on current tape */
 extern int	tapeno;		/* current tape number */
 extern time_t	tstart_writing;	/* when started writing the first tape block */
 extern time_t	tend_writing;	/* after writing the last tape block */
--- a/dump/main.c
+++ b/dump/main.c
@@ -130,7 +130,7 @@ int	compressed = 0;	/* if set, dump is t
 long long bytes_written = 0;/* total bytes written to tape */
 long	uncomprblks = 0;	/* uncompressed blocks written to tape */
 int	notify = 0;		/* notify operator flag */
-int	blockswritten = 0;	/* number of blocks written on current tape */
+long	blockswritten = 0;	/* number of blocks written on current tape */
 int	tapeno = 0;		/* current tape number */
 time_t	tstart_writing;	/* when started writing the first tape block */
 time_t	tend_writing;	/* after writing the last tape block */
@@ -997,18 +997,18 @@ main(int argc, char *argv[])
 	 * at least the data in the last partial record makes it to tape.
 	 * Also make sure we write at least 1 trailer block.
 	 */
-	for (i = ntrec - (spcl.c_tapea % ntrec); i; --i)
+	for (i = ntrec - (u_spcl_c_tapea() % ntrec); i; --i)
 		writeheader(maxino - 1);
 
 	tnow = trewind();
 
 	if (pipeout || fifoout)
-		msg("%d blocks (%.2fMB)\n", spcl.c_tapea,
-			((double)spcl.c_tapea * TP_BSIZE / 1048576));
+		msg("%ld blocks (%.2fMB)\n", u_spcl_c_tapea(),
+			((double)u_spcl_c_tapea() * TP_BSIZE / 1048576));
 	else
-		msg("%d blocks (%.2fMB) on %d volume(s)\n",
-		    spcl.c_tapea,
-		    ((double)spcl.c_tapea * TP_BSIZE / 1048576),
+		msg("%ld blocks (%.2fMB) on %d volume(s)\n",
+		    u_spcl_c_tapea(),
+		    ((double)u_spcl_c_tapea() * TP_BSIZE / 1048576),
 		    spcl.c_volume);
 
 	/* report dump performance, avoid division by zero */
@@ -1017,7 +1017,7 @@ main(int argc, char *argv[])
 	else
 		msg("finished in %ld seconds, throughput %ld kBytes/sec\n",
 		    tend_writing - tstart_writing,
-		    spcl.c_tapea / (tend_writing - tstart_writing));
+		    u_spcl_c_tapea() / (tend_writing - tstart_writing));
 
 	putdumptime(diskparam);
 	msg("Date of this level %s dump: %s", level,
@@ -1027,9 +1027,9 @@ main(int argc, char *argv[])
 	msg("Average transfer rate: %ld kB/s\n", xferrate / tapeno);
 	if (compressed) {
 		long tapekb = bytes_written / 1024;
-		double rate = .0005 + (double) spcl.c_tapea / tapekb;
-		msg("Wrote %dkB uncompressed, %ldkB compressed, %1.3f:1\n",
-			spcl.c_tapea, tapekb, rate);
+		double rate = .0005 + (double) u_spcl_c_tapea() / tapekb;
+		msg("Wrote %ldkB uncompressed, %ldkB compressed, %1.3f:1\n",
+			u_spcl_c_tapea(), tapekb, rate);
 	}
 
 	indexer->close();
--- a/dump/tape.c
+++ b/dump/tape.c
@@ -101,7 +101,7 @@ extern	int cartridge;
 char	*nexttape;
 extern  pid_t rshpid;
 int 	eot_code = 1;
-long long tapea_bytes = 0;	/* bytes_written at start of current volume */
+long tapea_bytes = 0;	/* bytes_written at start of current volume */
 int magtapeout;		/* output is really a tape */
 
 static	ssize_t dump_atomic_read (int, char *, size_t);
@@ -129,7 +129,7 @@ struct slave *slp;
 char	(*nextblock)[TP_BSIZE];
 
 static time_t tstart_volume;	/* time of volume start */
-static int tapea_volume;	/* value of spcl.c_tapea at volume start */
+static long tapea_volume;	/* value of spcl.c_tapea at volume start */
 
 int master;		/* pid of master, for sending error signals */
 int tenths;		/* length of tape overhead per block written */
@@ -247,9 +247,9 @@ writerec(const void *dp, int isspcl)
 
 	nextblock++;
 	if (isspcl)
-		lastspclrec = spcl.c_tapea;
+		lastspclrec = u_spcl_c_tapea();
 	trecno++;
-	spcl.c_tapea++;
+	u_spcl_c_tapea_add(1);
 	if (trecno >= ntrec)
 		flushtape();
 }
@@ -267,7 +267,7 @@ dumpblock(blk64_t blkno, int size, int u
 		slp->req[trecno].count = avail;
 		slp->req[trecno].uninit = uninit;
 		trecno += avail;
-		spcl.c_tapea += avail;
+		u_spcl_c_tapea_add(avail);
 		if (trecno >= ntrec)
 			flushtape();
 		dblkno += avail << (tp_bshift - dev_bshift);
@@ -317,14 +317,14 @@ time_t
 do_stats(void)
 {
 	time_t tnow, ttaken;
-	int blocks;
+	long blocks;
 
 	tnow = time(NULL);
 	ttaken = tnow - tstart_volume;
-	blocks = spcl.c_tapea - tapea_volume;
+	blocks = u_spcl_c_tapea() - tapea_volume;
 	msg("Volume %d completed at: %s", tapeno, ctime(&tnow));
 	if (! compressed)
-		msg("Volume %d %d blocks (%.2fMB)\n", tapeno,
+		msg("Volume %d %ld blocks (%.2fMB)\n", tapeno,
 			blocks, ((double)blocks * TP_BSIZE / 1048576));
 	if (ttaken > 0) {
 		long volkb = (bytes_written - tapea_bytes) / 1024;
@@ -336,7 +336,7 @@ do_stats(void)
 		xferrate += txfrate;
 		if (compressed) {
 			double rate = .0005 + (double) blocks / (double) volkb;
-			msg("Volume %d %dkB uncompressed, %ldkB compressed,"
+			msg("Volume %d %ldkB uncompressed, %ldkB compressed,"
 				" %1.3f:1\n",
 				tapeno, blocks, volkb, rate);
 		}
@@ -362,7 +362,7 @@ mktimeest(time_t tnow)
 		(void)snprintf(msgbuf, sizeof(msgbuf),
 			"%3.2f%% done at %ld kB/s, finished in %d:%02d\n",
 			(blockswritten * 100.0) / tapesize,
-			(spcl.c_tapea - tapea_volume) / (tnow - tstart_volume),
+			(u_spcl_c_tapea() - tapea_volume) / (tnow - tstart_volume),
 			(int)(deltat / 3600), (int)((deltat % 3600) / 60));
 	else
 		(void)snprintf(msgbuf, sizeof(msgbuf),
@@ -468,8 +468,8 @@ flushtape(void)
 					blks++;
 		}
 	}
-	slp->count = lastspclrec + blks + 1 - spcl.c_tapea;
-	slp->tapea = spcl.c_tapea;
+	slp->count = lastspclrec + blks + 1 - u_spcl_c_tapea();
+	slp->tapea = u_spcl_c_tapea();
 	slp->firstrec = lastfirstrec + ntrec;
 	slp->inode = curino;
 	nextblock = slp->tblock;
@@ -594,11 +594,12 @@ rollforward(void)
 {
 	struct req *p, *q = NULL, *prev;
 	struct slave *tslp;
-	int i, size, savedtapea, got;
+	int i, size, got;
+	long savedtapea;
 	union u_spcl *ntb, *otb;
 	struct slave_results returned;
 #ifdef __linux__
-	int blks;
+	long blks;
 	long lastfirstrec;
 #endif
 	tslp = &slaves[SLAVES];
@@ -644,10 +645,10 @@ rollforward(void)
 			q->count = 1;
 			trecno = 0;
 			nextblock = tslp->tblock;
-			savedtapea = spcl.c_tapea;
-			spcl.c_tapea = slp->tapea;
+			savedtapea = u_spcl_c_tapea();
+			u_spcl_c_tapea_set(slp->tapea);
 			startnewtape(0);
-			spcl.c_tapea = savedtapea;
+			u_spcl_c_tapea_set(savedtapea);
 			lastspclrec = savedtapea - 1;
 		}
 		size = (char *)ntb - (char *)q;
@@ -727,7 +728,7 @@ rollforward(void)
 	}
 
 	slp->firstrec = lastfirstrec + ntrec;
-	slp->count = lastspclrec + blks + 1 - spcl.c_tapea;
+	slp->count = lastspclrec + blks + 1 - u_spcl_c_tapea();
 	slp->inode = curino;
 	asize += tenths + returned.clen / density;
 	blockswritten += ntrec;
@@ -795,7 +796,7 @@ startnewtape(int top)
 #endif	/* __linux__ */
 
 	parentpid = getpid();
-	tapea_volume = spcl.c_tapea;
+	tapea_volume = u_spcl_c_tapea();
 	tapea_bytes = bytes_written;
 	tstart_volume = time(NULL);
 
@@ -935,7 +936,7 @@ restore_check_point:
 		 * measure firstrec in TP_BSIZE units since restore doesn't
 		 * know the correct ntrec value...
 		 */
-		spcl.c_firstrec = slp->firstrec;
+		u_spcl_c_firstrec_set(slp->firstrec);
 		spcl.c_volume++;
 		spcl.c_type = TS_TAPE;
 		spcl.c_flags |= DR_NEWHEADER;
@@ -944,8 +945,8 @@ restore_check_point:
 			spcl.c_flags |= DR_COMPRESSED;
 		writeheader((dump_ino_t)slp->inode);
 		spcl.c_flags &=~ DR_NEWHEADER;
-		msg("Volume %d started with block %d at: %s", tapeno,
-		    spcl.c_tapea, ctime(&tstart_volume));
+		msg("Volume %d started with block %ld at: %s", tapeno,
+		    u_spcl_c_tapea(), ctime(&tstart_volume));
 		if (tapeno > 1)
 			msg("Volume %d begins with blocks from inode %d\n",
 				tapeno, slp->inode);
--- a/restore/tape.c
+++ b/restore/tape.c
@@ -684,18 +684,18 @@ gethdr:
 #endif /* !HAVE_ZLIB && !HAVE_BZLIB */
 	}
 	Dprintf(stdout, "read %ld recs, tape starts with %ld\n",
-		tpblksread - 1, (long)tmpbuf.c_firstrec);
+		tpblksread - 1, u_spcl_c_firstrec(&tmpbuf));
 	if (tmpbuf.c_type == TS_TAPE && (tmpbuf.c_flags & DR_NEWHEADER)) {
 		if (!wantnext) {
-			tpblksread = tmpbuf.c_firstrec + 1;
+			tpblksread = u_spcl_c_firstrec(&tmpbuf) + 1;
 			for (i = tmpbuf.c_count; i > 0; i--)
 				readtape(buf);
-		} else if (tmpbuf.c_firstrec > 0 &&
-			   tmpbuf.c_firstrec < tpblksread - 1) {
+		} else if (u_spcl_c_firstrec(&tmpbuf) > 0 &&
+			   u_spcl_c_firstrec(&tmpbuf) < tpblksread - 1) {
 			/*
 			 * -1 since we've read the volume header
 			 */
-			i = tpblksread - tmpbuf.c_firstrec - 1;
+			i = tpblksread - u_spcl_c_firstrec(&tmpbuf) - 1;
 			Dprintf(stderr, "Skipping %ld duplicate record%s.\n",
 				(long)i, i > 1 ? "s" : "");
 			while (--i >= 0)
@@ -1427,7 +1427,9 @@ loop:
 			curfile.name, blksread);
 	}
 	if (curblk > 0) {
-		(*fill)((char *)buf, (size_t)((curblk * TP_BSIZE) + size));
+ 		size_t bytes = (size_t)((curblk * TP_BSIZE) + size);
+ 		(*fill)((char *)buf, pos, bytes);
+		pos += bytes;
 		last_write_was_hole = 0;
 	}
 	if (size > 0) {
@@ -2739,7 +2741,7 @@ converthead(struct s_spcl *buf)
 			int32_t	c_date;
 			int32_t	c_ddate;
 			int32_t	c_volume;
-			int32_t	c_tapea;
+			u_int32_t	c_tapea_lo;
 			u_int16_t c_inumber;
 			int32_t	c_magic;
 			int32_t	c_checksum;
@@ -2772,7 +2774,53 @@ converthead(struct s_spcl *buf)
 		if (checksum((int *)buf) == FAIL)
 			return (FAIL);
 		if (Bcvt)
-			swabst((u_char *)"8i4s1l29i528bi192b4i", (u_char *)buf);
+			/*
+			 * We are byteswapping a u_spcl.s_spcl here from dumprestore.h
+				8 <<	swap 8 terms
+				i <<	c_type
+					c_date
+					c_ddate
+					c_volume
+					c_tapea_lo
+					c_inumber
+					c_magic
+					c_checksum
+				4 <<	swap 4 terms
+				s	di_mode		(new_bsd_inode)
+					di_nlink
+					oldids[2]
+				1 <<    swap 1 term
+				l	di_size
+				29 <<	swap 29 terms
+				i	di_atime	0
+					di_mtime	2
+					di_ctime	4
+					di_db[NDADDR]	6
+					di_ib[NIADDR]	18
+					di_flags	21
+					di_blocks	22
+					di_gen		23
+					di_uid		24
+					di_gid		25
+					di_spare[2]	26	(end of new_bsd_inode)
+					c_count		29
+				528 <<	swap 528 terms
+				b	c_data	0
+					c_label	512
+				192 <<	swap 192 terms
+				b <<    c_filesys	0
+					c_dev		64
+					c_host		128
+				6 <<	swap 6 terms
+				i <<	c_flags
+					c_firstrec
+					c_ntrec
+					c_extattributes
+					c_tapea_hi
+					c_firstrec_hi
+				c_spare[28] not swapped.
+			*/
+			swabst((u_char *)"8i4s1l29i528bi192b6i", (u_char *)buf);
 		goto good;
 	}
 	memcpy(&u_ospcl.s_ospcl, buf, TP_BSIZE);
@@ -2784,7 +2832,8 @@ converthead(struct s_spcl *buf)
 		buf->c_date = u_ospcl.s_ospcl.c_date;
 		buf->c_ddate = u_ospcl.s_ospcl.c_ddate;
 		buf->c_volume = u_ospcl.s_ospcl.c_volume;
-		buf->c_tapea = u_ospcl.s_ospcl.c_tapea;
+		buf->c_tapea_lo = u_ospcl.s_ospcl.c_tapea_lo;
+		buf->c_tapea_hi = 0;
 		buf->c_inumber = u_ospcl.s_ospcl.c_inumber;
 		buf->c_checksum = u_ospcl.s_ospcl.c_checksum;
 		buf->c_magic = u_ospcl.s_ospcl.c_magic;
@@ -2813,9 +2862,11 @@ converthead(struct s_spcl *buf)
 		memcpy(&i64, &u_ospcl.dummy[904], sizeof(i64));
 		buf->c_ddate = i64;
 		memcpy(&i64, &u_ospcl.dummy[912], sizeof(i64));
-		buf->c_tapea = i64;
+		buf->c_tapea_lo = i64;
+		buf->c_tapea_hi = 0;	// Did we have 64 bits here really?
 		memcpy(&i64, &u_ospcl.dummy[920], sizeof(i64));
-		buf->c_firstrec = i64;
+		buf->c_firstrec_lo = i64;
+		buf->c_firstrec_hi = 0;
 		buf->c_ntrec = 0;
 		buf->c_extattributes = 0;
 		buf->c_flags |= DR_NEWINODEFMT;
@@ -2924,9 +2975,9 @@ accthdr(struct s_spcl *header)
 	if (header->c_type == TS_TAPE) {
 		fprintf(stderr, "Volume header (%s inode format) ",
 		    oldinofmt ? "old" : "new");
-		if (header->c_firstrec)
-			fprintf(stderr, "begins with record %d",
-				header->c_firstrec);
+		if (u_spcl_c_firstrec(header))
+			fprintf(stderr, "begins with record %ld",
+				u_spcl_c_firstrec(header));
 		fprintf(stderr, "\n");
 		previno = 0x7fffffff;
 		return;
@@ -3415,12 +3466,12 @@ ReReadInodeFromTape(dump_ino_t theino)
 		gethead(&spcl);
 	} while (!(spcl.c_inumber == theino && spcl.c_type == TS_INODE && spcl.c_date == dumpdate));
 
-	tpblksread = spcl.c_tapea + spcl.c_volume;
+	tpblksread = u_spcl_c_tapea() + spcl.c_volume;
 #ifdef DEBUG_QFA
 	fprintf(stderr, "DEBUG: %ld reads\n", cntloop);
 	fprintf(stderr, "DEBUG: bufsize %d\n", bufsize);
 	fprintf(stderr, "DEBUG: ntrec %d\n", ntrec);
-	fprintf(stderr, "DEBUG: tapea %u\n", spcl.c_tapea);
+	fprintf(stderr, "DEBUG: tapea %ld\n", u_spcl_c_tapea());
 	fprintf(stderr, "DEBUG: tpblksread %ld\n", tpblksread);
 #endif
 	findinode(&spcl);
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -25,7 +25,7 @@ libcommon_la_LIBADD = \
 check_PROGRAMS = indexer_test
 
 indexer_test_SOURCES = indexer_test.c
-indexer_test_LDADD = libcommon.la
+indexer_test_LDADD = libcommon.la ../compat/lib/libcompat.la
 
 # Disabled due to missing transform_test.c -- it was accidentally not added.
 # We can re-add when someone re-implements the test code :(.
