/***********************************************************
 * Simple time server                                      *
 * demonstration for an iterative server                   *
 * Verteilte Systeme II Kapitel 6                          *
 ***********************************************************
 * 1998 by Frank Kargl (frank.kargl@rz.uni-ulm.de)         *
 ***********************************************************
 * Usage: sts <port> (default port = 1099)                 *
 ***********************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define DEFPORT 1099

/***********************************************************
 *                                                         *
 * Function:                                               *
 * void usage(char* name)                                  *
 * print usage message                                     *
 * Parameters:                                             * 
 *  name - name of executable                              *
 * Return:                                                 *
 *  -                                                      *
 *                                                         *
 ***********************************************************/

void usage(char* name) {
    printf("%s - a simple time server\n", name);
    printf("Usage: %s <port> (default port = %d)\n", name, DEFPORT);
    exit(1);
}

int main(int argc, char** argv) {
    
    int lsocket;			/* listen socket */
    int asocket;			/* accept socket */
    int port = DEFPORT;			/* port to use */
    struct sockaddr_in servaddr;	/* server address */
    struct sockaddr_in cliaddr;		/* client address */
    int cliaddr_len;			/* length of client address */
    int ret;				/* generic return value */
    time_t utime;			/* UTC time */
    char* timeptr;			/* buffer for timestring */

    /* check for port */
    if (argc == 2) {
	port = atoi(argv[1]);
    } else if (argc != 1) {
	usage(argv[0]);
    }
    
    /* open listen socket */
    lsocket = socket(AF_INET, SOCK_STREAM, 0);
    if (lsocket == -1) {
	perror("Can't open lsocket");
	exit(1);
    }
    
    /* bind socket to port */
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(port);
    ret = bind(lsocket, (struct sockaddr*) &servaddr, sizeof(servaddr));
    if (ret == -1) {
	perror("Can't bind lsocket");
	exit(1);
    }
    
    /* listen to socket */
    ret = listen(lsocket, 10);
    if (ret == -1) {
	perror("Can't listen to lsocket");
	exit(1);
    }
    
    /* iterative server loop */
    while (1) {
	
	/* accept connection */
	cliaddr_len = sizeof(cliaddr);
	asocket = accept(lsocket, (struct sockaddr*) &cliaddr, &cliaddr_len);
	if (ret == -1) {
	    perror("Can't accept on lsocket");
	    exit(1);
	}
 
	/* "log" connection */
	printf("Connection from %s, port %d\n",
	       	inet_ntoa(cliaddr.sin_addr),
		ntohs(cliaddr.sin_port));
	
	/* get timestring */
	utime = time(NULL);
	timeptr = ctime(&utime);
	
	/* send timestring to client */
	write(asocket, timeptr, strlen(timeptr));
	
	/* close socket */
	close(asocket);

    }
    
    /* when do we close lsocket ? */
    /* propably should catch signal or so */

}
