#include <rtos.h>
#include <net.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

#define SMTPHOST   "SMTP.HOSTNAME"
#define SMTPGATE   "SMTP.GATEWAY"
#define SMTPLOG    "SMTP.LOG"

static DWORD defaultgate = 0L;
static char *hostname = NULL;
static char *smtplogfile = NULL;

static void (*oldinit)(char*,char*);
static void newinit( char *directive, char *value )
{
    if (!stricmp( directive, SMTPHOST ))
        hostname = kstrdup( value );
    else if (!stricmp( directive, SMTPLOG ))
        smtplogfile = kstrdup( value );
    else if (!stricmp( directive, SMTPGATE ))
        defaultgate = inet_addr( value );
    else
        if (oldinit) (*oldinit)( directive, value );
}
static void (*oldpost)(void);

static void newpostinit( void )
{
    char *buffer;

    buffer = kcalloc( 128 , 1 );
    if ( hostname == NULL ) {
#ifdef __DJGPP__   /* using Watt-32 lib */
        if (reverse_resolve_ip4 (gethostid(), buffer))
#else
        if ( reverse_addr_lookup( gethostid(), buffer ))
#endif
            hostname = kstrdup( buffer );
        else
            rt_halt("no hostname set, smtp.hostname=... in TCP.CFG and reverse addr lookup failed");
    }
    kfree( buffer );
    if ( oldpost ) (*oldpost)();
}

#ifdef __DJGPP__
__attribute__((constructor))
#endif

static void smtp_init( void )
{
    oldinit = usr_init;
    usr_init = newinit;
    oldpost = usr_post_init;
    usr_post_init = newpostinit;
}

#if defined(__TURBOC__) || defined(__BORLANDC__)
#pragma startup smtp_init 100
#endif

static void smtplog( char *direction, char *value )
{
    FILE *f;
    if ( smtplogfile != NULL ) {
        dos_enter();
        if ( (f = fopen( smtplogfile, "at")) != NULL ) {
            fprintf( f, "%s %s\n", direction, value );
            fclose( f );
        }
        dos_exit();
    }
}

static int getres( tcp_Socket *s, char *buffer )
{
    buffer[3] = 0;
    do {
        if ( tcp_tick( s ) == NULL ) return( 600 );
        if ( !sock_dataready( s ) ) continue;
        sock_gets( s, buffer, 128 );
    } while ( buffer[3] != ' ');
    smtplog( "<<<", buffer );
    return( atoi( buffer ));
}
static void sendline( tcp_Socket *s, char *cmd, char *arg1, char *arg2 )
{
    char buffer[ 128 ];

    if ( tcp_tick( s ) == NULL ) return;
    strcpy( buffer, cmd );
    if ( arg1 != NULL ) strcat( buffer, arg1 );
    if ( arg2 != NULL ) strcat( buffer, arg2 );

    sock_puts( s, buffer );
    smtplog( ">>>", buffer );
}

#define SMTPPORT 25

int smtp_client( DWORD host, char *from, char *to, char *subject, char *msg )
{
    int x;
    tcp_Socket *s;
    char buffer[ 256 ];
    int result = -1;

    s = kcalloc( sizeof( tcp_Socket ), 1 );
    if ( s == NULL ) return( -4 );

    if ( host == 0 ) host = defaultgate;
    if ( host == 0 ) rt_halt("no smtp gateway set (smtp.gateway=... in TCP.CFG)");
    if ( hostname == NULL )
        rt_halt("no hostname set for SMTP");


    if ( ! tcp_open( s, 0, host , SMTPPORT, NULL )) return( -3 );

    sock_mode( s, TCP_MODE_ASCII );

    while ( 1 ) {
        /* expect 220 welcome */
        if ( getres( s, buffer ) != 220 ) break;

        sendline( s, "HELO ", hostname, NULL );
        if ( getres( s , buffer ) != 250 ) break;

        strcpy( buffer, from );
        if ( strchr( buffer, '@')== NULL ) {
            strcat( buffer, "@");
            strcat( buffer, hostname );
        }
        sendline( s, "mail from: <", buffer, ">" );
        if ( getres( s, buffer ) != 250 ) break;

        strcpy( buffer, to );
        if ( strchr( buffer, '@') == NULL ) {
            strcat( buffer, "@");
            strcat( buffer, hostname );
        }
        sendline( s, "rcpt to: <", buffer, ">" );
        if ( getres( s, buffer ) != 250 ) break;

        sendline( s, "data", NULL, NULL );
        if ( getres( s, buffer ) != 354 ) break;

        if ( strchr( from , '@'))
            sendline( s, "From: ", from, NULL);
        sendline( s, "To: ", to , NULL );
        sendline( s, "Subject: ", subject, NULL );
        smtplog( ">>>", "...message body...");
        sock_puts( s, "");

        sock_puts( s, msg);
        sock_puts(s,".");
        if ( getres( s, buffer ) == 250 ) result = 0;
        break;
    }
    sendline( s, "QUIT", NULL, NULL );
    getres( s, buffer );
    sock_close( s );

    sock_wait_closed( s, 3, NULL, &x );
sock_err:
    sock_abort( s );
    kfree( s );
    return( result );
}


