Skip to content

Commit c676d01

Browse files
committed
Update DUMPER tool for MINI-DUMPER format "version 0".
1 parent d756320 commit c676d01

File tree

3 files changed

+109
-45
lines changed

3 files changed

+109
-45
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@ dump
2929
check
3030
constantinople
3131
dumper
32+
mini-dumper
3233
linum
3334
tendmp

Makefile

+4-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ OBJS = pdp10-opc.o info.o dis.o symbols.o \
1616
UTILS = cat36 itsarc magdmp magfrm dskdmp dump \
1717
macdmp macro-tapes tape-dir harscntopbm palx cross \
1818
ipak kldcp klfedr scrmbl unscr tvpic tito dart od10 \
19-
constantinople dumper linum tendmp
19+
constantinople dumper mini-dumper linum tendmp
2020

2121
all: dis10 $(UTILS) check
2222

@@ -80,6 +80,9 @@ dart: dart.o dec.o $(OBJS) libwords.a
8080
dumper: dumper.o $(OBJS) libwords.a
8181
$(CC) $(CFLAGS) $^ -o $@
8282

83+
mini-dumper: dumper
84+
ln -f $< $@
85+
8386
od10: od10.o $(OBJS) libwords.a
8487
$(CC) $(CFLAGS) $^ -o $@
8588

dumper.c

+104-44
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
along with this program. If not, see <http://www.gnu.org/licenses/>. */
1515

1616
#include <time.h>
17+
#include <ctype.h>
1718
#include <utime.h>
1819
#include <stdio.h>
1920
#include <errno.h>
@@ -42,7 +43,9 @@ static const char *type_name[] =
4243

4344
#define MAX 518
4445
static word_t block[MAX];
46+
static word_t *data = &block[6];
4547
static int extract = 0;
48+
static word_t tape_flags = 0;
4649

4750
static FILE *list;
4851
static FILE *info;
@@ -58,8 +61,7 @@ static int tape_number;
5861
static int file_number;
5962
static int page_number;
6063
static int record_number;
61-
static int bfmsg = 3;
62-
static int format = 4;
64+
static int format;
6365

6466
/*
6567
Format:
@@ -167,7 +169,7 @@ close_file (void)
167169
utimes (file_path, timestamp);
168170
}
169171

170-
/* Convert WAITS file name to an acceptable Unix name. */
172+
/* Convert TENEX file name to an acceptable Unix name. */
171173
static char *
172174
mangle (char *string)
173175
{
@@ -184,6 +186,18 @@ mangle (char *string)
184186
return string;
185187
}
186188

189+
static char *
190+
upcase (char *string)
191+
{
192+
char *p = string;
193+
while (*p)
194+
{
195+
*p = toupper (*p);
196+
p++;
197+
}
198+
return string;
199+
}
200+
187201
static char *
188202
find (char **string, const char *required, char *fail)
189203
{
@@ -216,7 +230,7 @@ find (char **string, const char *required, char *fail)
216230
/* Convert a file name from the command line to a TOPS-20 file name. */
217231
static const char *
218232
unmangle (char *file_name, char *device, char *name,
219-
int protection, const char *author)
233+
int protection, const char *author, int *generation)
220234
{
221235
char original_name[100];
222236
char *directories[100];
@@ -230,28 +244,36 @@ unmangle (char *file_name, char *device, char *name,
230244
*d = find (&name, "/", NULL);
231245
while (*d++ != NULL);
232246

233-
if (d - directories > 1 && format == 0)
247+
if (d - directories > 2 && format == 0)
234248
return "TENEX doesn't support subdirectories";
235249

236250
file = find (&name, ".", name);
237251
type = find (&name, ".;", name);
238252
version = find (&name, ";", name);
253+
if (version)
254+
{
255+
char *end;
256+
long x = strtol (version, &end, 10);
257+
if (end > version)
258+
*generation = x;
259+
}
239260

240261
if (device)
241262
file_name += sprintf (file_name, "%s:", device);
242263
if (directories[0] != NULL)
243264
{
244265
file_name += sprintf (file_name, "<");
245266
for (d = &directories[0]; *d != NULL; d++, sep = ".")
246-
file_name += sprintf (file_name, "%s%s", sep, *d);
267+
file_name += sprintf (file_name, "%s%s", sep, upcase (*d));
247268
file_name += sprintf (file_name, ">");
248269
}
249270
if (file)
250-
file_name += sprintf (file_name, "%s", file);
271+
file_name += sprintf (file_name, "%s", upcase (file));
272+
file_name += sprintf (file_name, ".");
251273
if (type)
252-
file_name += sprintf (file_name, ".%s", type);
253-
if (version)
254-
file_name += sprintf (file_name, "%c%s", format == 0 ? ';' : '.', version);
274+
file_name += sprintf (file_name, "%s", upcase (type));
275+
file_name += sprintf (file_name, "%c%u",
276+
format == 0 ? ';' : '.', *generation);
255277
file_name += sprintf (file_name, ";P%06o", protection);
256278
if (author)
257279
file_name += sprintf (file_name, ";A%s", author);
@@ -409,11 +431,11 @@ read_tape_header (FILE *f, word_t word)
409431

410432
word = read_record (f, word);
411433

412-
//fprintf (stderr, "006: %012llo format\n", block[6]);
434+
//fprintf (stderr, "006: %012llo format\n", data[0]);
413435

414-
read_asciz (name, &block[9]);
436+
read_asciz (name, &data[3]);
415437
fprintf (stderr, "DUMPER tape #%d, %s, ", right (block[2]), name);
416-
print_timestamp (stderr, block[8]);
438+
print_timestamp (stderr, data[2]);
417439
fputc ('\n', stderr);
418440

419441
return word;
@@ -428,7 +450,7 @@ read_file (int offset)
428450
if (offset != 0206)
429451
return;
430452

431-
read_asciz (name, &block[6]);
453+
read_asciz (name, &data[0]);
432454
p = strchr (name, ';');
433455
if (p)
434456
*p = 0;
@@ -440,7 +462,7 @@ read_file (int offset)
440462
(block[offset + 011] >> 24) & 077);
441463

442464
#if 0
443-
fprintf (stderr, "006: %012llo file name\n", block[6]);
465+
fprintf (stderr, "006: %012llo file name\n", data[0]);
444466
fprintf (stderr, "Timestamp, last write: ");
445467
print_timestamp (stderr, block[offset + 5]);
446468
fputc ('\n', stderr);
@@ -529,28 +551,42 @@ write_asciz (const char *string, word_t *data)
529551
}
530552

531553
static void
532-
write_record (FILE *f, int type, word_t flags)
554+
write_mark (void)
555+
{
556+
tape_flags = START_FILE;
557+
}
558+
559+
static void
560+
write_record (FILE *f, int type)
533561
{
534562
word_t checksum = 0;
535563
int i;
536564

537-
fprintf (stderr, "\nWrite record %s", type_name[type]);
565+
if (tape_flags & START_FILE)
566+
fprintf (debug, "\nWrite mark");
567+
568+
fprintf (debug, "\nWrite record %s", type_name[type]);
569+
570+
memset (block, 0, 6 * sizeof (word_t));
538571

539-
block[1] = 0;
540572
block[2] = (saveset_number << 18) | tape_number;
573+
if (format > 0)
574+
block[2] |= saveset_number;
541575
block[3] = page_number;
542-
fprintf (stderr, ", page %d", page_number);
576+
fprintf (debug, ", page %d, record %d", page_number, record_number);
543577
if (0)
544578
block[3] |= file_number << 18;
545579
block[4] = (-type) & 0777777777777LL;
546580
block[5] = record_number++;
547581

548582
for (i = 0; i < MAX; i++)
549583
checksum = sum (checksum, block[i]);
550-
block[0] = (checksum ^ 0777777777777LL) | START_RECORD | flags;
584+
block[0] = (checksum ^ 0777777777777LL) | START_RECORD | tape_flags;
585+
tape_flags = 0;
551586

552-
for (i = 0; i < MAX; i++)
553-
write_word (f, block[i]);
587+
write_word (f, block[0]);
588+
for (i = 1; i < MAX; i++)
589+
write_word (f, block[i] & 0777777777777LL);
554590

555591
memset (block, 0, sizeof block);
556592
}
@@ -562,7 +598,7 @@ get_page (FILE *f)
562598
int ok = 0;
563599
int i;
564600

565-
memset (block + 6, 0, 512 * sizeof (word_t));
601+
memset (data, 0, 512 * sizeof (word_t));
566602

567603
/* If the first word indicates EOF, return "no page".
568604
In other cases, return a partial or full page. */
@@ -571,7 +607,7 @@ get_page (FILE *f)
571607
word = get_word (f);
572608
if (word == -1)
573609
return ok;
574-
block[6 + i] = word;
610+
data[i] = word;
575611
ok = 1;
576612
}
577613

@@ -607,11 +643,11 @@ write_file (FILE *f, char *name)
607643
generation = 1;
608644
author = "OPERATOR";
609645

610-
error = unmangle (file_name, device, name, protection, author);
646+
error = unmangle (file_name, device, name, protection, author, &generation);
611647
if (error)
612-
fprintf (debug, "\nERROR: Bad file name \"%s\": %s", file_name, error);
648+
fprintf (stderr, "\nERROR: Bad file name \"%s\": %s", file_name, error);
613649
else
614-
fprintf (debug, "\nFILE: %s", file_name);
650+
fprintf (list, "\n %s", file_name);
615651

616652
memset (fdb, 0, sizeof fdb);
617653
//000 //header word
@@ -626,67 +662,83 @@ write_file (FILE *f, char *name)
626662
fdb[013] = tops20_timestamp (st.st_ctime); //timestamp: creation
627663
fdb[014] = tops20_timestamp (st.st_mtime); //timestamp: last user write
628664
fdb[015] = tops20_timestamp (st.st_atime); //timestamp: last nonwrite access
629-
630-
write_asciz (file_name, block + 6);
631-
memcpy (block + 0206, fdb, sizeof fdb);
665+
write_asciz (file_name, data);
666+
memcpy (data + 0200, fdb, sizeof fdb);
632667
page_number = 0;
633-
write_record (f, FLHD, 0);
668+
write_record (f, FLHD);
634669

635670
while (get_page (input))
636671
{
637-
write_record (f, DATA, 0);
672+
write_record (f, DATA);
638673
page_number++;
639674
}
640675
fclose (input);
641676

642-
memcpy (block + 6, fdb, sizeof fdb);
677+
memcpy (data, fdb, sizeof fdb);
643678
page_number = 0;
644-
write_record (f, FLTR, 0);
679+
write_record (f, FLTR);
680+
if (format == 0)
681+
write_mark ();
645682
}
646683

647684
static void
648685
write_usr (FILE *f)
649686
{
650-
write_record (f, USR, 0);
687+
write_record (f, USR);
651688
}
652689

653690
static void
654691
write_tape (FILE *f)
655692
{
656-
int i;
657693
struct word_format *tmp = input_word_format;
658694
input_word_format = output_word_format;
659695
output_word_format = tmp;
696+
int i, bfmsg = 0;
660697

661698
if (f == NULL)
662699
f = stdout;
663700

664701
saveset_number = 0;
665702
tape_number = 1;
666703
file_number = 1;
667-
record_number = 1;
668704

669-
block[6] = format;
670-
block[7] = bfmsg;
671-
block[8] = tops20_timestamp (time (NULL));
672-
write_asciz ("Saveset name", block + 6 + bfmsg);
673-
write_record (f, TPHD, START_FILE);
705+
if (format == 0)
706+
{
707+
record_number = 2;
708+
}
709+
else
710+
{
711+
record_number = 1;
712+
data[bfmsg++] = format;
713+
bfmsg++;
714+
data[bfmsg++] = tops20_timestamp (time (NULL));
715+
data[1] = bfmsg;
716+
}
717+
write_asciz ("Saveset name", data + bfmsg);
718+
719+
write_record (f, TPHD);
720+
if (format == 0)
721+
{
722+
write_mark ();
723+
record_number++;
724+
}
674725

675726
for (i = 0; i < file_argc; i++)
676727
{
677728
write_file (f, file_argv[i]);
678729
file_number++;
679730
}
680731

681-
write_record (f, TPTR, 0);
732+
write_record (f, TPTR);
733+
write_mark ();
682734
flush_word (f);
683735
}
684736

685737
static void
686738
usage (const char *x)
687739
{
688740
fprintf (stderr,
689-
"Usage: %s -c|-t|-x [-v789] [-Wformat] [-Cdir] [-f file]\n", x);
741+
"Usage: %s -c|-t|-x [-v0123456] [-Wformat] [-Cdir] [-f file]\n", x);
690742
usage_word_format ();
691743
exit (1);
692744
}
@@ -716,6 +768,14 @@ main (int argc, char **argv)
716768
list = stdout;
717769
info = debug = stderr;
718770

771+
/* If the program is called mini-something, default to mini-dumper
772+
format. Otherwise go with format 4 which is acceptable to a wide
773+
range of DUMPER versions. */
774+
if (strncasecmp (argv[0], "mini", 4) == 0)
775+
format = 0;
776+
else
777+
format = 4;
778+
719779
while ((opt = getopt (argc, argv, "ctvx012379f:W:C:")) != -1)
720780
{
721781
switch (opt)

0 commit comments

Comments
 (0)