/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* bos720 src/bos/usr/bin/sysdumpdev/dumpfmt/sample_table.c.S 1.1         */
/*                                                                        */
/* Licensed Materials - Property of IBM                                   */
/*                                                                        */
/* Restricted Materials of IBM                                            */
/*                                                                        */
/* COPYRIGHT International Business Machines Corp. 1996                   */
/* All Rights Reserved                                                    */
/*                                                                        */
/* US Government Users Restricted Rights - Use, duplication or            */
/* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.      */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
static char sccsid[] = "@(#)68	1.1  src/bos/usr/bin/sysdumpdev/dumpfmt/sample_table.c.S, cmdcrash, bos720 1/11/96 14:47:34";
/*
 * COMPONENT_NAME: (CMDCRASH) Dump Formatter Sample
 *
 * FUNCTIONS: main - format a sample dump table.
 *
 * ORIGINS: 27
 *
 * (C) COPYRIGHT International Business Machines Corp. 1996
 * All Rights Reserved
 * Licensed Materials - Property of IBM
 *
 * US Government Users Restricted Rights - Use, duplication or
 * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
 */

#include <sys/types.h>
#include <sys/dump.h>
#include <stdio.h>
#include <sys/uio.h>
#include "unpack.h"
#include "ketest.h"

extern int get_cdt(int, struct cdt *,int len);

static void help();
static int which_entry();
static void show_entry(int i);
static void show_parms(int len, char * entry);
static void show_buffer(int len, char * entry);

/* memory object file desc. */
int fd;

/* Dump table representation */
struct {
	struct cdt_head _cdt_head;	/* Header */
	struct cdt_entry cde[2];	/* 2 entries */
} tbl;

/*
 * Format a dump table entry (sample)
 *
 * Inputs:
 *	-f <fd>  gives the file descriptor of the memory object containing
 *		 the dump table.  The file must be positioned at the start
 *		 of the dump table.
 *	-l specified if we're in interactive mode (specified by crash).
 */
int
main(int argc, char *argv[])
{
	extern char *optarg;
	char c;
	int rc;
	int interactive = 0;		/* True if called by crash */
	int i;

	/* Get command line arguments. */
	while ((c=getopt(argc,argv,"f:l"))!=(char)EOF) {
		switch(c) {
		    case 'f':
			if (sscanf(optarg,"%d",&fd)!=1) {
			    fprintf(stderr,"Bad file descriptor.\n");
			    help();
			}
			break;
		    case 'l':
			interactive++;
			break;
		    default:
			fprintf(stderr,"Invalid argument.\n");
			help();
		}
	}

	/* We only support interactive mode. */
	if (!interactive) {
		fprintf(stderr,"Only interactive mode is supported now.\n");
		help();
	}

	/* Get dump table structures. */
	if ((rc=get_cdt(fd,(struct cdt *)&tbl,sizeof(tbl))) != 0) {
		/* Couldn't read the header. */
		perror("sample_table:");
		return(1);
	}

	printf("Dump table is %s, with %d entries.\n",tbl.cdt_name,
	  NUM_ENTRIES((struct cdt *)&tbl._cdt_head));

	/* loop, put up menu and do the action. */
	while ((i=which_entry()) != EOF) {
		show_entry(i);
	}

	return 0;
}

static void
help()
{
	fprintf(stderr,"Usage:  sample_table -f <fs> -l\n");
	fprintf(stderr,"Where	-l means interactive mode and is required.\n");
	exit(1);
}

/*
 * Function:  Put up a menu of the dump table entries and accept user input.
 *
 * Output:  Index of entry to show or EOF if done.
 */
static int
which_entry()
{
#define	QUIT 'q'
#define VALID(i) (((i)>=1)&&((i)<=nentries))
	int i, nentries;
	char buf[5];

	nentries = NUM_ENTRIES((struct cdt *)&tbl._cdt_head);

	/* loop til we get a valid response. */
	i = EOF;
	while (i == EOF) {
		/* Display the entries */
		printf("Dump table entries are:\n");
		for (i=0; i<nentries; i++) {
			printf("%d\t%s\n",i+1,tbl.cde[i].d_name);
		}
		printf("-> ");

		/* Get choice. */
		if (fgets(buf,3,stdin) == (char *)NULL) exit(1);

		/* Return EOF for quit ('q') */
		if (*buf == QUIT) return(EOF);

		/* Get the index. */
		if ((sscanf(buf,"%d",&i) != 1) || !VALID(i)) i = EOF;
		else i--; /* index is 0 based. */
	}

	return(i);
}

/*
 * Display an entry.
 *
 * Input:  entry is the entry index to display
 */
static void
show_entry(int entry)
{
	char buf[BUFLEN];
	int i,j;
	int len;

	/* Validate entry number */
	if (entry > 1) {
		fprintf(stderr,"Invalid entry.\n");
		return;
	}

	/* Get the data. */
	if ((len=unpack(fd,entry,(struct cdt *)&tbl,buf)) == -1) {
		perror("unpack");
		fprintf(stderr,"Couldn't unpack dump data.\n");
		return;
	}

	switch(entry) {
	case 0:	show_parms(len,buf); break;
	case 1: show_buffer(len,buf); break;
	default:
		fprintf(stderr,"Internal error!\n");
		exit(1);
	}
}

/*
 * Display entry 0, passed parameters.
 *
 * Inputs:
 *	len = buffer length.
 *	buf = buffer address.
 */
static void
show_parms(int len, char *buf)
{
	struct extparms *epp = (struct extparms *)buf;

	printf("struct extparms:\n");
	printf("  argc = %d\n",epp->argc);
	printf("  argv = %x\n",epp->argv);
	printf("  buf = %x\n",epp->buf);
	printf("  len = %d\n",epp->len);
}

/*
 * Display entry 1, passed test string(s).
 *
 * Inputs:
 *	len = buffer length.
 *	buf = buffer address.
 */
static void
show_buffer(int len, char *buf)
{
	printf("%s\n",buf);
}
