home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
High Voltage Shareware
/
high1.zip
/
high1
/
DIR3
/
KA9Q212.ZIP
/
NETTIME.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-16
|
11KB
|
401 lines
/****************************************************************************
* Author : G Todd *
* Language : Borland C++ 3.1 *
* Logfile : nettime.c *
* Project : DIS KA9Q. *
* Date : 24 Aug 92 *
* Revision : 1.1 GT Originate. *
* : 1.2 MT "auto", "maxcorrect" and "mincorrect". *
* 21 Sep 92 : 1.3 MT Fix correction reports. *
* : GT Disable idle timeout while setting the time.*
* 28 Sep 92 : 1.4 GT Wait for next timer tick after setting the *
* : time. *
* 09 Apr 93 : 1.5 GT Fix spurious error message from do_set (). *
* : Increase connect timeout. *
* : Fix smtptick () call. *
* 13 Apr 93 : 1.6 GT Time setting tweaks. *
* : "time delay" command. *
* 08 May 93 : 1.9 GT Fix warnings. *
*****************************************************************************
* Purpose : Routines for setting KA9Q's time from the remote host. *
* : Uses the protocol described in RFC 868. *
*****************************************************************************
* : Copyright Giles Todd 1992. All rights reserved. *
* : The right of Giles Todd to be identified as the author *
* : of this work has been asserted by him in accordance *
* : with the Copyrights, Designs and Patents Act, 1988. *
* : No restrictions on the use of this module with KA9Q. *
*****************************************************************************
$Id: nettime.c 1.9 93/07/16 11:46:57 ROOT_DOS Exp $
****************************************************************************/
#include <stdio.h>
#include <time.h>
#include "global.h"
#include "mbuf.h"
#include "cmdparse.h"
#include "proc.h"
#include "socket.h"
#include "timer.h"
#include "netuser.h"
#include "commands.h"
#include "ip.h"
#include "smtp.h"
#include "pppfsm.h"
#if defined (time)
#undef time /* remove macro */
#endif
extern int ext_dokicks(void);
int done_set_time = 0; /* have we set the time since this open? */
/****************************************************************************
* Static function declarations. *
****************************************************************************/
static int do_auto __ARGS((int argc, char **argv, void *p));
static int do_delay __ARGS((int argc, char **argv, void *p));
static int do_server __ARGS((int argc, char **argv, void *p));
static int do_maxcorrect __ARGS((int argc, char **argv, void *p));
static int do_mincorrect __ARGS((int argc, char **argv, void *p));
static int do_read __ARGS((int argc, char **argv, void *p));
static int do_set __ARGS((int argc, char **argv, void *p));
static void bg_set __ARGS((int s, void *unused, void *p));
static void start_of_connection __ARGS((void));
/****************************************************************************
* Static data. *
****************************************************************************/
static time_t correction = 0L; /* difference in seconds */
/* between remote and PC clock */
static int32 server = 0L; /* time server address */
static int auto_time_set = 0; /* set time on PPP open? */
static struct proc *setting_the_time = NULLPROC;
static int32 delay = 10000L; /* delay for setting up routes */
static time_t max_correction = 0; /* !0 is max correction allowed */
static time_t min_correction = 0; /* !0 is min correction allowed */
static struct cmds time_cmds[] =
{
{ "auto", do_auto, 0, 0, NULLCHAR },
{ "delay", do_delay, 0, 0, NULLCHAR },
{ "maxcorrect",do_maxcorrect,0, 0, NULLCHAR },
{ "mincorrect",do_mincorrect,0, 0, NULLCHAR },
{ "read", do_read, 0, 0, NULLCHAR },
{ "server", do_server, 0, 0, NULLCHAR },
{ "set", do_set, 0, 0, NULLCHAR },
{ NULLCHAR }
};
/****************************************************************************
* do_time *
* Time commands driver. *
****************************************************************************/
int do_time (argc, argv, p)
int argc;
char **argv;
void *p;
{
return (subcmd (time_cmds, argc, argv, p));
} /* int do_time (argc, argv, p) */
/****************************************************************************
* do_server *
* Display or set the timer server address. *
****************************************************************************/
static int do_server (argc, argv, p)
int argc;
char **argv;
void *p;
{
int32 n; /* temporary */
if (argc < 2)
{
tprintf ("%s\n", inet_ntoa (server));
}
else if ((n = resolve (argv[1])) == 0)
{
tprintf (Badhost, argv[1]);
return (1);
}
else
server = n;
return (0);
} /* static int do_server (argc, argv, p) */
/****************************************************************************
* do_read *
* Read the time from the remote and set the correction value. *
****************************************************************************/
static int do_read (argc, argv, p)
int argc;
char **argv;
void *p;
{
struct sockaddr_in fsocket; /* socket address */
int s; /* socket handle */
union
{
time_t time;
char bytes[sizeof (time_t)];
} result; /* data from remote */
char t; /* temporary */
char *cp; /* -> error message */
time_t pctime; /* PC time */
if (server == 0L)
{
tprintf (Badhost, "0.0.0.0");
return (1);
}
/* Set up the connection. */
fsocket.sin_family = AF_INET;
fsocket.sin_addr.s_addr = server;
fsocket.sin_port = IPPORT_TIME;
s = socket (AF_INET, SOCK_STREAM, 0);
sockmode (s, SOCK_BINARY);
alarm (connect_wait_val); /* set timeout */
if (connect (s, (char *) &fsocket, SOCKSIZE) != 0)
{
alarm (0L);
cp = sockerr (s);
tprintf ("TIME: %s connect failed: %s\n", psocket (&fsocket),
cp != NULLCHAR ? cp : "");
(void) close_s (s);
done_set_time = FALSE;
return (1);
}
alarm (0L);
/* Try to receive the time. */
if (recv (s, result.bytes, sizeof (result.bytes), 0) !=
sizeof (result.bytes))
{
tprintf ("TIME: receive failed\n");
close_s (s);
done_set_time = FALSE;
return (1);
}
close_s (s);
/* Calculate the correction value. */
t = result.bytes[0];
result.bytes[0] = result.bytes[3];
result.bytes[3] = t;
t = result.bytes[1];
result.bytes[1] = result.bytes[2];
result.bytes[2] = t;
result.time -= 2208988800L; /* adjust epoch */
pctime = time (NULL);
correction = result.time - pctime;
tprintf ("TIME: correction = %ld seconds\n", correction);
pctime = ka9q_time (NULL);
tprintf ("Time now (GMT): %s", asctime (gmtime (&pctime)));
return (0);
} /* static int do_read (argc, argv, p) */
/****************************************************************************
* do_set *
* Set the PC's clock from the time server. *
****************************************************************************/
static int do_set (argc, argv, p)
int argc;
char **argv;
void *p;
{
time_t n; /* temporary */
int correction_abs;
if (correction == 0L)
{
/* Set up the correction. */
if (do_read (0, NULL, NULL) != 0)
return (1);
}
correction_abs = (int) labs(correction);
if (max_correction && correction_abs > max_correction)
{
tprintf("TIME: required correction (%ld) greater than maximum (%ld)\n",
correction, max_correction);
correction = 0L;
return (0);
}
if (min_correction && correction_abs < min_correction)
{
tprintf("TIME: required correction (%ld) less than minimum (%ld)\n",
correction, min_correction);
correction = 0L;
return (0);
}
n = ka9q_time (NULL); /* get tweaked time */
(void) stime (&n); /* and set the PC clock */
log(-1,"PC clock adjusted by %ld at %s (server %s)",
correction, ctime(&n), inet_ntoa(server));
correction = 0L; /* no need for a correction now */
tprintf ("TIME: PC clock set\n");
return (0);
} /* static int do_set (argc, argv, p) */
/****************************************************************************
* do_delay *
* Displays or sets the timer delay. *
****************************************************************************/
static int do_delay (argc, argv, p)
int argc;
char *argv[];
void *p;
{
if (argc < 2)
{
tprintf ("auto kick delay: %lu\n", delay / 1000L);
return (0);
}
delay = atol (argv[1]) * 1000L; /* set timeout */
return (0);
} /* static int do_delay (argc, argv, p) */
/****************************************************************************
* ka9q_time *
* Replacement for library "time ()" function. Called by other modules *
* via nasty macro substitution. *
****************************************************************************/
time_t ka9q_time (t)
time_t *t;
{
time_t rc; /* return value */
(void) time (&rc); /* get the PC's idea */
rc += correction;
if (t != NULL)
*t = rc;
return (rc);
} /* time_t ka9q_time (t) */
/****************************************************************************
* do_auto *
* Should we do a 'time set' every time ppp ipcp opens? *
****************************************************************************/
static int do_auto (argc, argv, p)
int argc;
char **argv;
void *p;
{
return setbool(&auto_time_set, "TIME SET auto mode", argc, argv);
}
int try_set_time (argc, argv, p)
int argc;
char **argv;
void *p;
{
struct ppp_s *ppp_p = p;
done_set_time = 1;
if (!auto_time_set)
return 0;
if (setting_the_time == NULLPROC)
setting_the_time = newproc("set time", 512, bg_set, 0, NULL, ppp_p, 0);
return 0;
}
static void start_of_connection()
{
int32 zero = 0;
smtptick((void *) zero);
ext_dokicks();
}
static void bg_set (s, unused, p)
int s;
void *unused;
void *p;
{
int32 save_idle_durn = 0L;
struct ppp_s *ppp_p = p;
pause (delay);
if (ppp_p->idle_durn != 0L)
{
/* Stop the PPP idle timer. */
stop_timer (&(ppp_p->idle_timer));
save_idle_durn = ppp_p->idle_durn;
ppp_p->idle_durn = 0L;
}
do_set(0, NULL, NULL);
setting_the_time = NULLPROC;
if (save_idle_durn != 0L)
{
/* Restart the PPP idle timer. */
pwait (&Tick); /* wait for next timer tick */
ppp_p->idle_durn = save_idle_durn;
set_timer (&(ppp_p->idle_timer), ppp_p->idle_durn);
start_timer (&(ppp_p->idle_timer));
}
start_of_connection();
}
static int
do_maxcorrect(argc,argv,p)
int argc;
char *argv[];
void *p;
{
if(argc < 2){
tprintf("TIME: maximum correction: %d\n", max_correction);
return 0;
}
max_correction = atoi(argv[1]);
return 0;
}
static int
do_mincorrect(argc,argv,p)
int argc;
char *argv[];
void *p;
{
if(argc < 2){
tprintf("TIME: minimum correction: %d\n", min_correction);
return 0;
}
min_correction = atoi(argv[1]);
return 0;
}