/*                            Online-o-meter
 *                   Online Timer/Cost Meter for Amiga 
 *                      © E.F.Pritchard 1994,1995.
 *                              *FREEWARE*
 *        See Online-o-meter documentation for more information
 */

/* Online2NComm.c -- Convert Online-o-Meter style Log File to NComm one */

#include <exec/devices.h>
#include <devices/timer.h>
#include <dos/dos.h>
#include <dos/datetime.h>
#include <utility/date.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/timer.h>
#include <proto/utility.h>

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

struct Library *TimerBase = NULL;
struct timerequest *tr;
struct RDArgs *args = NULL;
BPTR input = 0,
     output = 0;
UBYTE buffer[100];

#define NUMARGS 2
#define TEMPLATE "INPUT,OUTPUT"

extern VOID clean_exit(LONG);
extern VOID Convert2NComm(VOID);

#ifdef LATTICE
int CXBRK(void) {return 0;}
int chkabort(void) { return(0); }
#endif

UBYTE VersTag[] = "\0$VER: Online2NComm 1.0 (" __DATE__ ")";

/*------------------------------------------------------------------------*/
/* NAME
 *      DupFileHandle -- Duplicate a Console FileHandle.
 *
 * SYNOPSIS
 *      duplicate = DupFileHandle( fh )
 *      BPTR        DupFileHandle( BPTR );
 *
 * FUNCTION
 *      Duplicates an open Console FileHandle, opening it as MODE_OLDFILE.
 *
 * INPUTS
 *      fh - AmigaDOS FileHandle to Duplicate. MUST be a valid Console
 *           FileHandle, anything else may crash the system or have
 *           undefined results.
 *
 * RESULT
 *      duplicate - another FileHandle to the Console, or NULL if clone
 *                  failed. Must be closed in the same way as any other 
 *                  FileHandle.
 *
 * NOTES
 *      Based on an example in the Amiga GURU book by Ralph Babel.
 */
BPTR DupFileHandle(BPTR fh)
{
  struct MsgPort *old = 
    SetConsoleTask((struct MsgPort *)
		   ((struct FileHandle *)BADDR(fh))->fh_Type);
  BPTR duplicate = Open("CONSOLE:",MODE_OLDFILE);

  (VOID)SetConsoleTask(old);

  return duplicate;
}

/*------------------------------------------------------------------------*/
VOID main(int argc, char **argv)
{
  STRPTR result;
  LONG rc;
  LONG argarray[NUMARGS];
  memset(argarray,'\0',sizeof(LONG)*NUMARGS);

  if(!Cli())
     exit(RETURN_FAIL);

  /* Open timer device for time arithmetic functions */
  if( OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)tr,0) ) {
    Printf("Couldn't open %s.",TIMERNAME);
    exit(RETURN_FAIL);
  }
  TimerBase = (struct Library *)tr->tr_node.io_Device;

  /* Process the arguments */
  if(!(args = ReadArgs(TEMPLATE,argarray,NULL))) {
    Printf("Bad Args.\n");
    clean_exit(RETURN_WARN);
  }

  /* Sort out input */
  if(!argarray[0]) {
    /* Use Input() */
    input = DupFileHandle(Input());
  }
  else {
    /* Use File */
    if(!(input = Open((STRPTR)argarray[0],MODE_OLDFILE))) {
      Printf("Can't open file %s for input.\n",argarray[0]);
      clean_exit(RETURN_WARN);
    }
  }

  /* Sort out output */
  if(!argarray[1]) {
    /* Use Output() */
    output = DupFileHandle(Output());
  }
  else {
    /* Use File */
    if(!(output = Open((STRPTR)argarray[1],MODE_NEWFILE))) {
      Printf("Can't open file %s for output.\n",argarray[1]);
      clean_exit(RETURN_WARN);
    }
  }  

  memset(buffer,'\0',sizeof(UBYTE)*100);
    
  /* Read lines and convert */
  while((result = FGets(input,buffer,100)) == buffer) {
    
    /* Do quick check to see if legal line */
    if(strlen(buffer) == 79 &&
       /* Convert */
       buffer[44] == '-' &&
       buffer[66] == ':')
      Convert2NComm();

    if(CheckSignal(SIGBREAKF_CTRL_C)) {
      Printf("***Break\n");
      break;
    }
  }

  if( !result && (rc = IoErr()) != 0 ) {
    PrintFault(rc,"Error Reading from input file");
    clean_exit(RETURN_WARN);
  }

  clean_exit(RETURN_OK);
}

/*------------------------------------------------------------------------*/
/* Convert Online-o-Meter style entry to NComm style */
VOID Convert2NComm(VOID)
{
  struct DateTime dt = {{0},FORMAT_DOS,0,NULL,NULL,NULL};
  struct ClockData cd;
  UWORD hours,mins,secs;
  struct timeval tv1 = {0,0},tv2 = {0,0};
  extern char *__montbl[], *__daytbl[];

  /* Point to Date & Time Portions and NULL terminate them */
  dt.dat_StrDate = &buffer[42];
  buffer[51] = '\0';
  dt.dat_StrTime = &buffer[52];
  buffer[60] = '\0';

  FPutC(output,(LONG)'\n');
  Flush(output);

  Write(output,buffer,40);
  Flush(output);

  FPuts(output,"\n------------------------------------------------\nLogin:  ");

  /* Convert O-o-M date to NComm one */
  if(StrToDate(&dt)) {

    tv1.tv_secs = 
      (dt.dat_Stamp.ds_Days * 24 * 3600) + 
	(dt.dat_Stamp.ds_Minute * 60) + 
	  (dt.dat_Stamp.ds_Tick / TICKS_PER_SECOND);

    Amiga2Date(tv1.tv_secs,&cd);
    FPrintf(output,"%s %s %02lu %02lu:%02lu:%02lu %lu\n",
	    __daytbl[cd.wday],
	    __montbl[cd.month-1],
	    cd.mday,
	    cd.hour,
	    cd.min,
	    cd.sec,
	    cd.year);

    /* Now Convert Time Elapsed to Time Logged out */
    sscanf(&buffer[61],"%hu:%hu:%hu",&hours,&mins,&secs);
    tv2.tv_secs = secs + ((hours * 3600) + (mins * 60));

    AddTime(&tv2,&tv1);

    Amiga2Date(tv2.tv_secs,&cd);
    FPrintf(output,"Logout: %s %s %02lu %02lu:%02lu:%02lu %lu\n",
	    __daytbl[cd.wday],
	    __montbl[cd.month-1],
	    cd.mday,
	    cd.hour,
	    cd.min,
	    cd.sec,
	    cd.year);

    /* Print Elapsed time */
    FPrintf(output,"Time Online: %02lu:%02lu:%02lu\n",
	    hours,mins,secs);
  }
  
  Flush(output);
}

/*------------------------------------------------------------------------*/
VOID clean_exit(LONG rc)
{
  if(output)
    Close(output);

  if(input)
    Close(input);

  if(args)
    FreeArgs(args);

  if(TimerBase)
    CloseDevice((struct IORequest *)tr);

  exit(rc);
}
