// $Id: cio.c,v 1.25 2011/07/08 21:50:30 lpoulsen Exp $
// Copyright (C) 2004 by AFAR Communications Inc, Santa Barbara, CA 93117 USA
// Copyright (C) 2001 Wi_LAN Technologies, Inc
//
// Character I/O for ECONSOLE - masks differences between Linux and Windows
//
// $Log: cio.c,v $
// Revision 1.25  2011/07/08 21:50:30  lpoulsen
// Eliminate (almost all) use of debug_level, use debug_flags instead.
//
// Revision 1.24  2011/05/06 22:15:14  lpoulsen
// Preparing for ECON 04.07 release
//
// Revision 1.23  2011/02/22 00:02:23  lpoulsen
// Show device table after F4 disconnect
// Clear device table before new discovery
// Use device type = 0x8086 for PCs
//
// Revision 1.22  2010/12/28 20:06:20  lpoulsen
// Fix old bug in filelen(handle) (which had needed a workaround in epacket.c)
//
// Revision 1.21  2010/12/22 17:36:33  lpoulsen
// Select/Deselect list of ranges
// Expand to up to 511 radios
// Protocol fixes
//
// Revision 1.20  2008/08/05 23:58:37  lpoulsen
// User interface updates.
//
// Revision 1.19  2008/07/11 17:10:27  lpoulsen
// Resolve compiler warnings.
//
// Revision 1.18  2008/07/11 16:28:46  lpoulsen
// Econ 4.00 release candidate supports UPDATE and SELECT commands.
//
// Revision 1.17  2008/06/10 00:06:10  lpoulsen
// New -X option is now working
// Updated -I and -O implementation
//
// Revision 1.16  2008/05/31 00:35:09  lpoulsen
// Econ 4.x preview - now with command shell
//
// Revision 1.15  2008/05/10 01:17:37  lpoulsen
// Making econ -x filename work (not yet complete)
//
// Revision 1.14  2006/06/06 02:03:29  lpoulsen
// First attempt at compiling on MAC OS X
//
// Revision 1.13  2004/07/13 18:37:22  lpoulsen
// Fix bug where F3 or F4 did not send CLOSE_REQUEST
//
// Revision 1.12  2004/07/13 16:58:43  lpoulsen
// Clean up textual layout with indent
//
// Revision 1.11  2003/03/11 01:14:13  lpoulsen
// Correct compile errors found in Calgary.
//
// Revision 1.10  2002/10/16 16:59:47  mourlouk
// Improved way of retrieving MAC addresses - VAL support
//
// Revision 1.8  2002/05/21 19:52:27  lpoulsen
// Fix for PSR int236: Econsole uses 100% CPU
//     Code inspection confirmed that the thread that reads from the
//     console terminal has set the TTY to always return immediately
//     from a read. After changing the TTY mode to return only if
//     a character was received or 200 ms passed, CPU usage has
//     dropped to the expected minimal amount.
// Also some readability cleanup.
//
// Revision 1.7  2002/04/19 19:04:44  mourlouk
//   Econ Release 1.15 - It fixes a bug that was introduced in version 1.13
//   (econ unable to read properly multiple MAC addresses)
//
// Revision 1.6  2001/11/13 01:23:33  lpoulsen
// Remove compiler warnings
//
// Revision 1.5  2001/11/13 00:38:51  mourlouk
// ....................
//
// Revision 1.4  2001/11/12 23:06:48  mourlouk
// making happy compiler (II)
//
// Revision 1.3  2001/11/12 22:52:32  mourlouk
// making compiler happy (I)
//
// Revision 1.2  2001/10/30 01:07:45  lpoulsen
// Add "module ID" statement, audit trail generator and copyright line
// Remove "win_or_linux.h" and use a -D in Linux makefile instead.
//
//
#include <stdio.h>
#include <time.h>
#include "afartype.h"
#include "epacket.h"
#include "util.h"
#include "cio.h"
#include "ucon.h"

// Imported variables
extern char console_in_filename[];
extern FILE *console_in_file;

extern int isLocalCommand(const char *line);

#ifdef LINUX
#include <unistd.h>
#include "cio_linux.h"
#else
#include "cio_windows.h"
#endif

// all the reads are blocked - unless EOF 
int
read_from_keyboard(unsigned char *data, int max_data_size)
{
    int ch;

  ReadNext:
    ch = a_getch();

    if (econ_phase != ECON_CONNECTED)            // We received GO_AWAY
        return 0;               // this value will exit the READ thread

    if (isNormalChar(ch))
    {
        data[0] = ch;
        return 1;
    }
    // else is a special key
    switch (ch)
    {
    case F1_KEY:
        break;
    case F2_KEY:
        break;
    case F3_KEY:
        // terminate the session
        terminate_session(0, ES_F3_KEY);
        return 0;
        break;
    case F4_KEY:
        // terminate the session
        terminate_session(0, ES_F4_KEY);
        return 0;
        break;
    case F5_KEY:
        break;
    case F6_KEY:
        break;
    case F7_KEY:
        break;
    case ESC_KEY:
        break;
    case UNKNOWN_KEY:
        break;                  // don't print a diagnostic message, 
        // since is not considered as an error

    }
    goto ReadNext;
}

int
read_from_file(unsigned char *data, int max_data_size)
{
    static int linecount;
    char line[128];

    if (console_in_file == NULL)  // file not opened yet

    {
        if ((console_in_file = fopen(console_in_filename, "r")) == NULL)
        {
            printf("Error: Unable to open input file [%s]\n\r",
                   console_in_filename);
            printf("Please verify the file exist and it is not corrupted.\n\r");
            console_in_file = NULL;
            terminate(-1, FILE_FAILURE);
        }
        linecount = 0;
    }

    while (!feof(console_in_file))
    {
        //res = WaitForSingleObject(Prompt_Arrived, PROMPT_TIMEOUT);    
        if (fgets(line, 128, console_in_file) == NULL)
        {
            if (!feof(console_in_file))
            {
                printf("----- %s file %s at line %d.\n",
                       "Error while reading from input",
                       console_in_filename, linecount);
                printf("      Unable to proceed\n");
                fclose(console_in_file);
                console_in_file = NULL;
                return -1;
            }
            else
            {
                fclose(console_in_file);
                console_in_file = NULL;
                return 0;
            }
        }
        else
        {
            int ll = strlen(line);
            linecount++;

            while (line[ll - 1] < ' ') {
                ll--;
                line [ll] = 0;
            }
            line[ll] = '\r';
            line[ll+1] = 0;

            strcpy((void *) data, line);
#if 0
            if (debug_level >= 1)
                printf("[read %d bytes from file: %s]\n",
                       strlen(line), line);
#endif
            return strlen(line);
        }
    }

    if (feof(console_in_file))
    {
        fclose(console_in_file);
        console_in_file = NULL;
        linecount = 0;
        data = NULL;
        return 0;
    }
    // Normally we will never reach this point
    // So this is just to keep the compiler happy
    return 0;
}


boolean
fileExist(char *filename)
{
    FILE *in_file = fopen(filename, "r");

    if (in_file != NULL)
    {
        fclose(in_file);
        return TRUE;
    }
    else
        return FALSE;
}

uint32
filelen(char *filename)
{
    long position;
    int result;

    FILE *stream = fopen(filename, "r");
    if (stream != NULL)
    {
        result = fseek(stream, 0L, SEEK_END);
        if (result)
        {
            printf("Error: fseek SEEK_END failed ...\n");
            return -1;
        }
        else
        {
            position = ftell(stream);
            fclose(stream);
            return (position);
        }
    }
    else
        return -1;
}
