/*
    nullidentd.c

    Copyright 1999 Brian Young <bayoung@acm.org>

    Licensed under the GPL, see the file COPYING included with this distribution.
*/

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>

#include "version.h"

#define SESSION_TIMEOUT 20

#define MAX_RESPONSE 200
#define MAX_REQUEST 100
#define MAX_USERID 50

void usage()
{
    fprintf( stderr, "nullidentd -- version %s\n", VERSION );
    fprintf( stderr, "Copyright 1999 Brian Young <bayoung@acm.org>\n" );
    fprintf( stderr, "usage: nullidentd [userid]\n" );
}

int write_response( int fd, char *response, int len )
{
    int		retval;
    int		byteswritten = 0;

    while( byteswritten < len ) {
	retval = write( fd, response + byteswritten, len - byteswritten );
	if( retval <= 0 ) {
	    /* error */
	    return 0;
	}
	byteswritten += retval;
    }

    /* success */
    return 1;
}

int read_request( int fd, char *request, int maxlen )
{
    int		retval;
    char	c;
    int		bytesread = 0;

    /* read until \n */
    while( bytesread < maxlen - 1 ) {
	if( read( fd, &c, 1 ) != 1 ) {
	    /* error */
	    return 0;
	}
	if( c == '\n' ) {
	    /* end of line */
	    break;
	}

	request[bytesread] = c;
	bytesread += 1;
    }

    if( bytesread > 0 && request[bytesread-1] == '\r' ) {
	/* strip trailing \r */
	bytesread -= 1;
    }
    /* null terminate */
    request[bytesread] = '\0';

    /* success */
    return 1;
}

void session_timeout( int foo )
{
    exit( 0 );
}

int main( int argc, const char *argv[] )
{
    const char *	userid = "foobar";
    char		c;
    int			infd;
    int			outfd;
    int			response_len;
    char		response[MAX_RESPONSE];
    char		request[MAX_REQUEST];

    if( getgid() == 0 ) {
	fprintf( stderr, "Group id is root, exitting.\n" );
	return 1;
    }
    if( getuid() == 0 ) {
	fprintf( stderr, "User id is root, exiting.\n" );
	return 1;
    }

    if( argc > 2 ) {
	usage();
	return 1;
    }

    if( argc == 2 ) {
	/* userid parameter specified */
	userid = argv[1];
	if( strlen( userid ) > MAX_USERID ) {
	    fprintf( stderr, "Userid parameter is too long.\n" );
	    return 1;
	}
    }

    infd = fileno( stdin );
    outfd = fileno( stdout );

    // set the session timeout
    signal( SIGALRM, session_timeout );
    alarm( SESSION_TIMEOUT );

    for( ;; ) {
	/* read the request */
	if( !read_request( infd, request, MAX_REQUEST ) ) {
	    /* error or timed out */
	    goto done;
	}

	/* format the response */
	response_len = snprintf( response, sizeof( response ), "%.20s : USERID : UNIX : %.20s\r\n", request, userid );

	/* send the line */
	if( !write_response( outfd, response, response_len ) ) {
	    goto done;
	}
    }

done:
    return 0;
}

