/* Internet Time Server
 * Author: Brian K. Teravskis, WD0EFL
 * Date: 02/15/92
 *
 * Based on RFC868 Time Protocol
 */
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "global.h"
#include "mbuf.h"
#include "hardware.h"
#include "socket.h"
#include "session.h"
#include "proc.h"
#include "commands.h"

#ifdef __GNUC__
#define DIFFTIME 2208988800LU
#else
#define DIFFTIME 2208988800
#endif
#define IPPORT_TIME 37

static int Stime = -1;	/* Prototype socket for service */

static void timeserver __ARGS((int s,void *unused,void *p));

/* Start up time server */
int
#ifdef PROTOTYPES
time1(int argc,char **argv,void *p)
#else
time1(argc,argv,p)
int argc;
char *argv[];
void *p;
#endif
{
	struct sockaddr_in lsocket;
	int s;

	if(Stime != -1){
		return 0;
	}
	psignal(Curproc,0);	/* Don't keep the parser waiting */
	chname(Curproc,"Time listener");

	lsocket.sin_family = AF_INET;
	lsocket.sin_addr.s_addr = INADDR_ANY;
	lsocket.sin_port = IPPORT_TIME;

	Stime = socket(AF_INET,SOCK_STREAM,0);
	bind(Stime,(char *)&lsocket,sizeof(lsocket));
	listen(Stime,1);
	for(;;){
		if((s = accept(Stime,NULLCHAR,(int *)NULL)) == -1)
			break;	/* Service is shutting down */

		/* Spawn a server */
		newproc("timeserver",512,timeserver,s,NULL,NULL,0);
	} /* for (;;;) */
	return 0;
} /* time1 */



/*
 * Serve up the time to the connected client
 */
static void
timeserver(s,unused,p)
int s;
void *unused;
void *p;
{
	struct mbuf	*bp;
	char	datetime[4];

	sockmode(s,SOCK_BINARY);
	sockowner(s,Curproc);
	log(s,"Open Time");
	/*
	 * Change 1970 start time to 1900 start time, and put
	 * it in network order
	 */
	put32(datetime,(int32)(time((time_t *)0)+DIFFTIME));

	/* enqueue for transmission */
	bp = qdata(datetime,sizeof(int32));
	/* Send time data */
	if(send_mbuf(s,bp,0,NULLCHAR,0) == -1)
		log(s,"Time Failed");

	close_s(s);
	log(s,"Close Time");
} /* timeserver */

/* Stop the time server */
int
#ifdef PROTOTYPES
time0(int argc,char **argv,void *p)
#else
time0(argc,argv,p)
int argc;
char *argv[];
void *p;
#endif
{
	close_s(Stime);
	Stime = -1;
	return 0;
} /* time0 */
