commit f30026c9297ef435341371a469abf189ca4d1622 from: Sven M. Hallberg date: Thu Jun 4 11:16:34 2026 UTC und64: honor size of last block The last block is indicated by a null track field in its "next block address" header. The sector field then appears to hold the length of the block data plus one. 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;