/* Internet rdate client
 * Author: Brian Teravskis, WD0EFL
 * Date: 03/30/92
 *
 * Based on RFC868 Time Protocol
 *
 * Added local hour offset - Doug Crompton 10/28/92
 * and subcommand menu for possible future commands
 */
#include <stdio.h>
#include <string.h>
#include "global.h"
#include "mbuf.h"
#include "socket.h"
#include "session.h"
#include "proc.h"
#include "netuser.h"
#include "commands.h"
#include "tty.h"
#include "timer.h"
#include <time.h>
#include "cmdparse.h"

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

static void rdate_timeout __ARGS((void *));
static int rdate_offset=0;

static int dordateserver __ARGS((int argc,char *argv[],void *p));
static int dordateoff __ARGS((int argc,char *argv[],void *p));

static struct cmds rdatecmds[] = {
	"server", dordateserver, 512, 2,
	"rdate server <address>",

	"offset", dordateoff, 0, 0,
	NULLCHAR,

	NULLCHAR,
};

int
dordate(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	return subcmd(rdatecmds,argc,argv,p);
}

static int
dordateserver(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	struct sockaddr_in sock;
    int s,i_state;
	struct mbuf *bp;
	struct timer *t;
	time_t rtime, raw_time;

	if((sock.sin_addr.s_addr = resolve(argv[1])) == 0){
		log(-1,"RDATE:Host %s unknown\n",argv[1]);
		return 1;
	}
	sock.sin_family = AF_INET;
	sock.sin_port = IPPORT_TIME;

	/* Open connection to time server */
	if((s = socket(AF_INET,SOCK_STREAM,0)) == -1) {
		log(-1,"RDATE:Can't create socket");
		return 1;
	}
	sockmode(s,SOCK_BINARY);

	/* Set timeout timer */
	t = (struct timer *)callocw(1, sizeof(struct timer));
	t->func = rdate_timeout;
	t->arg = (void *) &s;
	set_timer(t,RDATETIMEOUT*1000L);
	start_timer(t);

	/* Connect to time server */
	if(connect(s,(char *)&sock,sizeof(sock)) == -1){
		/* Connect failed */
		stop_timer(t);
		free(t);
		log(s,"RDATE: Connect failed");
		close_s(s);
		return 1;
	}
	/* Successful connect, stop timout timer */
	stop_timer(t);
	free(t);
	/* Get time info sent by server */
	recv_mbuf(s,&bp,0,NULLCHAR,(int *)0);
	rtime = (time_t)pull32(&bp);
	/* Convert 1900 start date to 1970 start date */
	rtime -= DIFFTIME;
	raw_time=rtime;
	rtime += (rdate_offset*3600L);
	/* Set the system time */
    i_state = dirps();
    stime(&rtime);
    restore(i_state);
    log(s,"RDATE:Clock set to %s from %s\n",ctime(&rtime),argv[1]);
	printf("\nTime received from %s - %s",argv[1],ctime(&raw_time));
	printf("System time set to %s\n",ctime(&rtime));
	free_q(&bp);
	close_s(s);
	return 0;
} /* dordate */

/*
 * Close socket after timeout on connect
 */
static void
rdate_timeout(arg)
void *arg;
{
	int     *s;

	s = (int *)arg;
	close_s(*s);
} /* rdate_timeout */

/* Set time offset */
static int
dordateoff(argc, argv,p)
int argc;
char *argv[];
void *p;
{
	if(argc < 2) {
		tprintf("Usage: 'rdate offset <+-hours>' - Current Offset %d Hours\n",rdate_offset);
		return 0 ;
	}
	
	rdate_offset = atoi(argv[1]);
	return 0;
}

