diff --git a/dumper.h b/dumper.h index c792682..48f68a1 100644 --- a/dumper.h +++ b/dumper.h @@ -80,9 +80,13 @@ char *rectypes[] = { #define BtoffWord 0 #define BtlenWord 36 +#define WdoffSSstart 6 /* Start of saveset data */ +#define WdoffSSFmt 6 /* Format of tape */ +#define WdoffSSPtr 7 /* Pointer to saveset name (or 3 or 020 depending on format) */ #define WdoffSSDate 8 /* Saveset date offset (type 1, 6) */ #define WdoffSSName 9 /* Saveset name offset (type 1, 6) */ #define WdoffFLName 6 /* Filename offset (type 2) */ +#define WdoffSSMsg (020+WdoffSSstart) /* Saveset name (unless SSPtr set) */ #define WdoffFDB 134 /* FDB offset (type 2) */ #define WdoffFDB_CTL 01+WdoffFDB /* Control word .FBCTL */ diff --git a/read20.c b/read20.c index 9775287..803d675 100644 --- a/read20.c +++ b/read20.c @@ -519,13 +519,32 @@ void doSaveset (char *block, int contflag) { static char name[102]; static char ss[2]; + long ssfmt, ssptr; long t; if (debug > 10) printf("\nSaveset header:"); tapeno = getfield(block, WdoffTapeNum, BtoffTapeNum, BtlenTapeNum); ssno = getfield(block, WdoffSaveSetNum, BtoffSaveSetNum, BtlenSaveSetNum); - getstring(block, name, WdoffSSName, sizeof(name)); + ssfmt = getfield(block, WdoffSSFmt, BtoffWord, BtlenWord); /* Get format */ + ssptr = getfield(block, WdoffSSPtr, BtoffWord, BtlenWord); /* Get pointer */ + // Check tape format! Otherwise breaks e.g. on Install tapes (which aren't in dumper format). + if ((ssfmt < 4) || (ssfmt > 6)) { + // Formats older than 4 not supported, and 6 was the highest (TOPS-20 v6-7). + // If you want to support older fmts, write the code. :-) + fprintf (stderr, "Bad dumper tape format %012lo\n", ssfmt); + exit(1); + } + + if (verbose) { + printf("Saveset format %ld, name pointer %ld; tape %ld, saveset %ld\n", ssfmt, ssptr, tapeno, ssno); + } + if (ssptr == 0) { + /* If there is no pointer, use default offset: for format 5-6 (T20 v6-7), SS.MSG, otherwise (T20 v4-5) BFMSG */ + getstring(block, name, ssfmt > 4 ? WdoffSSMsg : WdoffSSName, sizeof(name)); + } else { + getstring(block, name, ssptr+WdoffSSstart, sizeof(name)); + } ss[0] = pendstring(); /* superfluous */ (void) strcat(name, ss);