/*
 * main.c
 *  dump convert main program
 * 
 *  Copyright (C) 2004 IBM Deutschland Entwicklung GmbH, IBM Corporation
 *   
 *  Author(s): Michael Holzheu
 */

#include <stdio.h>
#include <getopt.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "vm_dump.h"
#include "lkcd_dump.h"

#define STRINGIFY_1(x)                  #x
#define STRINGIFY(x)                    STRINGIFY_1(x)

#define RELEASE_STRING   STRINGIFY(S390_TOOLS_RELEASE)

static struct option longopts[] = {
	{"file",required_argument,0,'f'},
	{"help",no_argument,0,'h'},
	{"version",no_argument,0,'v'},
	{"output",required_argument,0,'o'},
	{0,0,0,0}
};

#define OPTSTRING "f:o:vh"
extern char *optarg;

/* Version info */
static const char version_text[] = "vmconvert: vmdump converter tool version "RELEASE_STRING;

/* Copyright notice */
static const char copyright_notice[] = "Copyright (C) 2004 "
                                       "IBM Deutschland Entwicklung GmbH, "
                                       "IBM Corporation";
/* Usage information */
static const char usage_text[] = \
"Usage: vmconvert -f <vmdump> [-o <outputfile>]\n" \
"\n" \
"Convert a vmdump into a lkcd (linux kernel crash dumps) dump.\n" \
"\n" \
"-h, --help                 Print this help, then exit\n" \
"-v, --version              Print version information, then exit\n" \
"-f, --file VMDUMPFILE      The vmdump file VMDUMPFILE, which should be converted\n" \
"-o, --output OUTPUTFILE    The converted lkcd dump file OUTPUTFILE";

/* Globals */
char inputFileName[1024];
char outputFileName[1024] = "dump.lkcd";
	
void 
parseOpts(int argc, char* argv[])
{
	int  inputFileSet = 0;
	int c, longIndex;
	while((c = getopt_long(argc, argv, OPTSTRING, longopts,
                               &longIndex)) != -1) {
                switch (c) {
                	case 'f':
                		strcpy(inputFileName, optarg);
                		inputFileSet = 1;
                		break;
                	case 'o':
                		strcpy(outputFileName, optarg);
                		break;
                	case 'h':
                		printf("%s\n", usage_text);
                		exit(0);
                	case 'v':
                		printf("%s\n", version_text);
                		printf("%s\n", copyright_notice);
                		exit(0);
                	default:
                		exit(1);
                }
        }
        if(!inputFileSet){
        	printf("%s: input file required - use '-f' option!\n",argv[0]);	
        	exit(1);
        }
}
	
int
main(int argc, char* argv[])
{
	struct stat s;
	
	parseOpts(argc,argv);

	/* Check if output file already exists */	
	if(stat(outputFileName,&s) == 0){
		char answer[100];
		printf("%s: overwrite file '%s'? ",argv[0],outputFileName);
		scanf("%s",answer);
		if((strcmp(answer,"y") != 0) && (strcmp(answer,"yes") != 0))
			exit(0);
	}

	/* Do the conversion */
	try {
		switch(VMDump::getDumpType(inputFileName)){
			case Dump::DT_VM64:
			{
				VMDump64* vmdump;
				LKCDDump64* lkcddump;
				
				vmdump = new VMDump64(inputFileName);
				vmdump->printInfo();
				lkcddump = new LKCDDump64(vmdump, vmdump->getRegisterContent());
				lkcddump->writeDump(outputFileName);
				break;
			}
			case Dump::DT_VM32:
			{
				VMDump32* vmdump;
				LKCDDump32* lkcddump;
				 
				vmdump = new VMDump32(inputFileName);
				vmdump->printInfo();
				lkcddump = new LKCDDump32(vmdump, vmdump->getRegisterContent());
				lkcddump->writeDump(outputFileName);
				break;
			}
			default:
				throw DumpException("This is not a vmdump");
		}
	} catch (DumpException ex) {
		printf("\n%s: %s\n",argv[0],ex.what());
		fflush(stdout);
		return 1;
	}
	printf("'%s' has been written successfully.\n",outputFileName);
	return 0;
}
