/* 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 "global.h"
#ifdef RDATE
#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
#define DIFFTIME 2208988800L
#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;
}
#endif /* RDATE */
  
