/*
 * modem - more advanced terminal server
 *       - allows multiple TELNETs in and connect to COMn
 *       - tcp.cfg file must define COM ports with irqs,speeds
 *          eg. com1=4,9600
 */
#include <dos.h>
#include <stdio.h>
#include <rtos.h>
#include <sio.h>
#include <string.h>
#include <mem.h>
#include <telnetd.h>
#include <ftpd.h>
#include <httpd.h>
#include <smtpcli.h>
#include <process.h>
#include <inifile.h>
#include <syslog.h>

#include "webpart.h"


#define MAXCOM 4+1
WORD far *bases = 0x400L;
DWORD speeds[ MAXCOM ] = { 0, 0, 0, 0, 0};
int irqs[ MAXCOM ];
WORD inuse[ MAXCOM ] = { 0,0,0,0,0};
static void (*old_init)(char *name, char *value);
char *emailuserid = NULL;
DWORD sysloghost = 0;
char *syslogname = NULL;
DWORD bytes = 0;
#define EMAILNOTIFY "email.notify"
#define SYSLOGHOST "syslog.host"
char *loginuserid = NULL;
char *loginpassword = NULL;

/********************************************************************/
void init_vars(void)
{
    char *s = "comx";
    char *p;
    int i;
    DWORD speed;

    /* initialize COM ports */

    for ( i = 1 ; i <= 4 ; ++i ) {
        s[3] = '0'+i;

        speeds[i] = GetIniDWORD( "TCP.CFG", s, "speed", 0 );
        irqs[i]   = GetIniDWORD( "TCP.CFG", s, "irq"  , 0 );
    }

    p = GetIniString( "TCP.CFG", "settings", EMAILNOTIFY, "");
    if ( *p ) {
        emailuserid = p;
        cprintf("Configured email userid to %s.\r\n", emailuserid );
    } else {
        emailuserid = NULL;
        kfree( p );
        cprintf("No email userid set.\r\n");
    }

    p = GetIniString( "TCP.CFG", "settings", SYSLOGHOST, "");
    if ( *p ) {
        sysloghost = p;
        cprintf("Configured syslogging to %s.\r\n", sysloghost);
    } else {
        sysloghost = NULL;
        kfree( p );
        cprintf("No syslogging configured.\r\n");
    }

    p = GetIniString( "TCP.CFG","settings","userid","");
    if ( *p ) {
        loginuserid = p;
    } else {
        kfree( p );
        cprintf("No Web login userid specified\r\n");
    }

    p = GetIniString("TCP.CFG","settings","password","");
    if ( *p ) {
        loginpassword = p;
    } else
        kfree( p );

}

/********************************************************************/

void teld_write_string( void *t, char *s )
{
    teld_write( t, s, strlen(s) );
    bytes += strlen( s );
}
/********************************************************************/
/* modem_server - one thread per com port
 */

void modem_server( DWORD comport )
{
#define CBUFSIZ 128
    BYTE ch;
    BYTE buffer[ CBUFSIZ ];
    teld_str *t;
    int i;

    do {
        inuse[ comport ] = 0;
        cprintf("Listenning... com%u\r\n", comport);
        t = teld_listen( 0 );
        cprintf("connection arrived... assigned to com%u\r\n", comport);

        /* if syslog enabled, notify log of change */
        if ( sysloghost )
            syslog( sysloghost, LOG_DAEMON, LOG_ERR, "connection arrived");

        inuse[ comport ] = 1;

        teld_write_string( t, "DEMO TERMSERV\r\nCopyright (c) 1990, 1999 Erick Engelke\r\n");
        rt_sleep( 1000 );
        do {
            /* way to break out */
            if ( kbhit() ) exit( 0 );

            /* look for TELNET arriving chars */
            ch = teld_getc( t );
            if ( ch == 255 ) break;
            if ( ch != 0 ) {
                sio_writebyte( comport, ch );
                bytes++;
            }

            /* look for serial chars coming in, group them for speed */
            for ( i = 0 ; i < BUFSIZ ; ++i ) {
                if ( sio_recv_waiting( comport ) ) {
                    ch = sio_readbyte( comport );
                    buffer[ i ] = ch;
                    bytes++;
                } else break;
            }
            if ( i == CBUFSIZ ) i--;
            if ( i != 0 ) {
                teld_write( t, buffer, i );
                bytes += i;
            }

            rt_yield();
        } while ( 1 );
        teld_close( t );
        cprintf("Connection closed... com%u\r\n", comport);
        /* if syslog enabled, notify log of change */
        if ( sysloghost )
            syslog( sysloghost, LOG_DAEMON, LOG_ERR, "connection closed");

    } while ( 1 );
}

/********************************************************************/
/* main - setup everything then wait for a keystroke
 */
#pragma argsused

void main(int argc, char **argv )
{
    int temp;
    DWORD dummy;

    rt_init( 100 );

    cputs("TERMSERV 1.1\r\n");
    cputs("Copyright (c) 1990, 1999 Erick Engelke\r\n");

    sock_init();

    init_vars();

    kdebug = 1;

    cputs("Press any key to exit\r\n");

    rt_newthread( ftpdthread, 1,2048, 0, "ftpd" );

    for ( temp = 1 ; temp < 4 ; ++temp ) {
        if ( speeds[temp] != 0 ) {
            sio_init( temp, bases[temp-1], irqs[temp], 4096, 4096, NULL, 0 );
            sio_setup( temp, speeds[temp], 8, 0, 1, 1 );
            cprintf("Initializing port COM%u: base=0x%x irq=%u speed=%lu\r\n",
                temp, bases[temp-1], irqs[temp], speeds[temp]);
            rt_newthread( &modem_server, temp, 4096, 0, "modem thread");
        }
    }

#define MAXHTTPD 5
    rt_newthread( collector, 1,2048, 0, "collector" );

    for ( temp = 0 ; temp < MAXHTTPD; ++temp )
        rt_newthread( httpdthread, (DWORD)&user_proc, 2048, 0, "httpd worker" );

    if ( emailuserid != NULL ) {
        cprintf("Sending Email notification to %s\r\n", emailuserid );
        smtp_client( 0, "thisbox", emailuserid, "AUTOSEND: TermServer restarted",
            "The terminal server has restarted");
    }

    /* if syslog enabled, notify log of change */
    if ( sysloghost )
        syslog( sysloghost, LOG_DAEMON, LOG_ERR, "termserver started");

    while ( 1 ) {
        if ( kbhit() ) break;
        rt_sleep( 250 );
    }
    /* let SIO automatically release all the interrupts */
}

