Commit Diff


commit - 38d647e04720e44516cc6b829b52496a74d448c4
commit + f30026c9297ef435341371a469abf189ca4d1622
blob - f81cb3ff68b813f8a5b3f8aad0648e8c2901e3bd
blob + 2274d20c9966d4dbd4e1448a7f7453a4976f8f73
--- und64.c
+++ und64.c
@@ -166,26 +166,38 @@ usage(void)
 
 /* write data starting at block address 'ba' out to a file at 'path' */
 int
-writefile(const char *path, blkaddr ba)
+writefile(const char *path, blkaddr ba, int *pn)
 {
 	struct datablk *db;
 	FILE *f;
+	size_t sz;
+	int n;
 
 	if ((f = fopen(path, "w")) == NULL) {
 		warn("%s", path);
 		return 1;
 	}
 
-	while (ba.track != 0) {
+	sz = sizeof db->db_data;
+	for (n = 0; ba.track != 0; n++) {
 		db = image + blkoff(ba);
 
-		if (fwrite(db->db_data, sizeof db->db_data, 1, f) == 0) {
+		if (db->db_next.track == 0		/* last block? */
+		    && db->db_next.sector > 0)		/* sanity check */
+			sz = db->db_next.sector - 1;	/* off by 1? -o- */
+		if (fwrite(db->db_data, 1, sz, f) != sz) {
 			warn("write");
 			break;
 		}
 
 		ba = db->db_next;
 	}
+	if (ba.sector < 1) {
+		warnx("%s: %s: last 'next sector' field invalid (%d)",
+		    imgfile, path, (int)ba.sector);
+	}
+	if (pn != NULL)
+		*pn = n;
 
 	fclose(f);
 	return 0;
@@ -251,7 +263,7 @@ extract(int nfiles, char *files[])
 	struct direntry *de;
 	blkaddr ba;
 	char *s;
-	int i, j, r = 0;
+	int i, j, n, r = 0;
 	ftype t;
 
 	dh = image + blkoff(hdrloc);
@@ -293,7 +305,11 @@ extract(int nfiles, char *files[])
 			if (vflag)
 				printf("%s\n", s);
 
-			r |= writefile(s, de->de_data);
+			r |= writefile(s, de->de_data, &n);
+			if (n != fromw(de->de_nblocks)) {
+				warnx("%s: %s: %d blocks instead of %d",
+				    imgfile, s, n, (int)fromw(de->de_nblocks));
+			}
 		}
 
 		ba = db->db_next;