/*
 * This implements the classic (outdated) FINGER protocol
 * While the protocol has grown to be more complex, this gives a
 * simplified example which can be queried by any FINGER client.
 *
 * We listen on port 79.  For each new connection we accept a line
 * of input.  That line is either a user name, or a blank line meaning
 * we should list everyone.
 *
 */
#include <rtos.h>
#include <net.h>
#include <stdio.h>

/*
 * heartbeat - just thumps periodically and does network stuff
 */
void heartbeat( DWORD param )
{
    do {
        tcp_tick( NULL );
        rt_sleep( 100 );    /* every 100 ms we do another network tick */
    } while ( 1 );
}


#define FINGERPORT 79
#define MAXFINGERD 5

tcp_Socket *fing;
/*
 * implement ONE finger server
 */
void fingerd( DWORD index )
{
    tcp_Socket *s;
    char buffer[ 128 ];

    s = &fing[ index ];

    do {
        /* start listenning */
        tcp_listen( s, FINGERPORT, 0, 0, NULL, 0 );

        /* wait for a connection */
        do {
            rt_sleep( 100 );    /* just waiting */
            if ( tcp_tick( s ) == NULL ) goto reopen;
        } while ( ! sock_established( s ));

        /* get a line of text */
        sock_mode( s, TCP_MODE_ASCII );
        while ( ! sock_dataready( s )) {
            rt_yield();
            if ( tcp_tick( s ) == NULL ) goto reopen;
        }
        sock_gets( s, buffer, sizeof( buffer ));
        rip( buffer );   /* remove CR/LF */

        /* output the results */
        sock_puts( s, "thanks for asking about ");
        sock_puts( s, buffer );

reopen:
        sock_close( s );

        /*
         * and wait for it to close
         */
        while ( tcp_tick( s ) )
            rt_sleep( 100 );

        /* now we are unthreaded */
    } while ( 1 );
}


main()
{

    int i;
    kpreemptive = 1;
    kdebug = 1;
    rt_init(100);
    sock_init();
    cputs("starting...\r\n");

    fing = kcalloc( sizeof( tcp_Socket ), MAXFINGERD );

    rt_newthread( heartbeat, 1,2048, 0, "heartbeat" );

    for ( i = 0 ; i < MAXFINGERD ; ++i )
        rt_newthread( fingerd, i, 2048, 0, "fingerd worker" );
    do {
        /* nothing */
        rt_yield();
    } while ( 1 );
}

