/*
 * dumpinfo  -- display dump header info
 *
 * THIS IS A TEST PROGRAM, NOT A PART OF DUMP OR RESTORE PROGRAM.
 *
 * So far only compiled on a DYNIX/ptx system, not build under ccs. 
 *
 */

/*
 * $Copyright:	$
 * Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989, 1990 
 * Sequent Computer Systems, Inc.   All rights reserved.
 *  
 * This software is furnished under a license and may be used
 * only in accordance with the terms of that license and with the
 * inclusion of the above copyright notice.   This software may not
 * be provided or otherwise made available to, or used by, any
 * other person.  No title to or ownership of the software is
 * hereby transferred.
 *
 */

#ident	"$Header: dumpinfo.c 1.1 90/01/23 $"

#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/ufsinode.h>
#include <sys/param.h>
#include <dumprestore.h>

int fd;			/* file descriptor for dump file/device */
char *tbf;		/* data buffer */
union u_spcl buf;	/* dump tape header sruct */

extern char *ctime();

main(argc, argv)
	int argc;
	char *argv[];
{
	int i;

	/* verify proper usage */

	if (argc != 2) {
		fprintf(stderr, "Usage: %s <file/device>\n", argv[0]);
		exit(1);
	}

	get_buffer();	/* allocate tape buffer */

	/* open input file/device */

	if ((fd = open(argv[1], O_RDONLY, 0)) == -1) {
		fprintf(stderr, "Cannot open '%s'\n", argv[1]);
		perror(argv[1]);
		exit(1);
	}

	/* read buffer */

	i = read(fd, tbf, NTREC*TP_BSIZE);

	if (i < 0) {
		perror("read failed");
		exit(1);
	}

	if (i != (NTREC * TP_BSIZE)) {
		printf("Read %d bytes, max read would have been %d\n",
			NTREC*TP_BSIZE);
		if (i < TP_BSIZE) {
			printf("Wanted at least %d bytes.\n", TP_BSIZE);
			exit(1);
		}
	}
	
	/* Display info. */

	display();

	printf("done\n");
	exit(0);
}

get_buffer()	/* Allocate buffer space. */
{
        static char *savebuf = (char *)NULL;

        savebuf = (char *)malloc((NTREC * TP_BSIZE)+(CLBYTES-1));
        if (savebuf == NULL) {
                fprintf(stderr, "Cannot malloc buffer space.\n");
                exit(1);
        }

        tbf = (char *)(((int)savebuf + (CLBYTES-1)) &~ (CLBYTES-1));
}

display()
{
	char *p;

	(void) memset((char *) &buf, NULL, (long) TP_BSIZE);
	(void) memcpy((char *) &buf, tbf, TP_BSIZE);

	file_type();

	printf("c_level: %d", buf.s_spcl.c_level);
	printf("   (level of this dump)\n");

	if (buf.s_spcl.c_date == 0) {
		printf("d_date:  0 [the epoch]\n");
	} else {
		p = ctime(&buf.s_spcl.c_date);
		p[24] = 0;
		printf("c_date:  %s", p);
	}
	printf("   (date of this dump)\n");

	if (buf.s_spcl.c_ddate == 0) {
		printf("c_ddate: 0 [the epoch]\n");
	} else {
		p = ctime(&buf.s_spcl.c_ddate);
		p[24] = 0;
		printf("c_ddate: %s", p);
	}
	printf("   (date of privious dump)\n");
	printf("c_volume: %d", buf.s_spcl.c_volume);
	printf("   (dump volume number)\n");
	printf("c_tapea: 0x%x", buf.s_spcl.c_tapea);
	printf("   (logical block of this record)\n");
	printf("c_inumber: 0x%x", buf.s_spcl.c_inumber);
	printf("   (number of inode)\n");
	printf("c_checksum: 0x%x", buf.s_spcl.c_checksum);
	printf("   (record checksum)\n");

	if (buf.s_spcl.c_type != TS_TAPE)
		return;

	show_names();
}

file_type()
{
	switch(buf.s_spcl.c_type) {
	case TS_TAPE:
		printf("Tape type: TS_TAPE");
		printf("   (dump tape header)\n");
		break;
	case TS_INODE:
		printf("Tape type: TS_INODE");
		printf("   (beginning of file record)\n");
		break;
	case TS_ADDR:
		printf("Tape type: TS_ADDR");
		printf("   (continuation of file record)\n");
		break;
	case TS_BITS:
		printf("Tape type: TS_BITS");
		printf("   (map of inodes on tape)\n");
		break;
	case TS_CLRI:
		printf("Tape type: TS_CLRI");
		printf("   (map of inodes deleted since last dump)\n");
		break;
	case TS_END:
		printf("Tape type: TS_END");
		printf("   (end of volume marker)\n");
		break;
	default:
		printf("Unknown tape type.\n");
		printf("c_type is 0x%x\n", buf.s_spcl.c_type);
		exit(1);
	}
}

show_names()
{
	char *p;
	int i;

	/* dump label */

	p = &buf.s_spcl.c_label[0];
	printf("c_label: ");

	while (*p && p < &buf.s_spcl.c_label[LBLSIZE]) {
		putchar(*p);
		p++;
	}
	printf("\n   (dump label)\n");

	/* name of dumpped file system */

	p = &buf.s_spcl.c_filesys[0];
	printf("c_filesys: ");

	while (*p && p < &buf.s_spcl.c_filesys[NAMELEN]) {
		putchar(*p);
		p++;
	}
	printf("\n   (name of dumpped file system)\n");

	/* name of dumpped device */

	p = &buf.s_spcl.c_dev[0];
	printf("c_dev: ");

	while (*p && p < &buf.s_spcl.c_dev[NAMELEN]) {
		putchar(*p);
		p++;
	}
	printf("\n   (name of dumpped device)\n");

	/* name of dumpped host */

	p = &buf.s_spcl.c_host[0];
	printf("c_host: ");

	while (*p && p < &buf.s_spcl.c_host[NAMELEN]) {
		putchar(*p);
		p++;
	}
	printf("\n   (name of dumpped host)\n");
}
