home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / internet / tcpipsrc / h / if / MiscCli / c / NetTime next >
Encoding:
Text File  |  1994-06-24  |  7.6 KB  |  268 lines

  1. /***************************************************************************
  2.         Purpose         :       Routines for setting KA9Q's time from the remote host.
  3.                         :       Uses the protocol described in RFC 868.
  4.  ***************************************************************************
  5.                         :       Copyright Giles Todd 1992.  All rights reserved.
  6.                         :       The right of Giles Todd to be identified as the author
  7.                         :       of this work has been asserted by him in accordance
  8.                         :       with the Copyrights, Designs and Patents Act, 1988.
  9.                         :       No restrictions on the use of this module with KA9Q.
  10.  ***************************************************************************/
  11.  
  12. #include        <stdio.h>
  13. #include        <stdlib.h>
  14. #include        <time.h>
  15. #include        "Arc.h"
  16. #include        "domain.h"
  17. #include        "global.h"
  18. #include        "mbuf.h"
  19. #include        "misc.h"
  20. #include        "cmdparse.h"
  21. #include        "socket.h"
  22. #include        "timer.h"
  23. #include        "netuser.h"
  24. #include        "udp.h"
  25.  
  26. int done_set_time = 0;  /* have we set the time since this open?        */
  27.  
  28. #define TIME_PORT 37
  29.  
  30. extern int16 lport;                     /* local port placeholder */
  31. extern int32 wimp_ver;
  32.  
  33. /***************************************************************************
  34.         Static function declarations.
  35.  ***************************************************************************/
  36.  
  37. static int do_server (int argc, char **argv);
  38. static int do_maxcorrect (int argc, char **argv);
  39. static int do_mincorrect (int argc, char **argv);
  40. static int do_read (int argc, char **argv);
  41. static int do_set (int argc, char **argv);
  42.  
  43. /***************************************************************************
  44.         Static data.
  45.  ***************************************************************************/
  46.  
  47. static time_t correction     = 0;                       /* difference in seconds                */
  48.                                                                                         /* between remote and PC clock  */
  49. static int32 server          = 0L;                      /* time server address                  */
  50. static time_t max_correction = 0;                       /* !0 is max correction allowed */
  51. static time_t min_correction = 0;                       /* !0 is min correction allowed */
  52.  
  53. static BOOL set_clock        = FALSE;
  54.  
  55. static struct timer net_time_t;
  56. static struct socket time_socket;
  57.  
  58. static struct cmds time_cmds[] =
  59. {
  60.     "maxcorrect",       do_maxcorrect, 0,       0,      NULLCHAR   ,
  61.     "mincorrect",       do_mincorrect, 0,       0,      NULLCHAR   ,
  62.     "read",                     do_read,           0,   0,      NULLCHAR   ,
  63.     "server",       do_server,     0,   0,      NULLCHAR   ,
  64.     "set",                      do_set,            0,   0,      NULLCHAR   ,
  65.     NULLCHAR   ,
  66. };
  67.  
  68. int dotime (int argc, char *argv[])
  69. {
  70.   return(subcmd(time_cmds, argc, argv));
  71. }
  72.  
  73. /* Display or set the timer server address. */
  74.  
  75. static int do_server(int argc, char *argv[])
  76. {
  77.   int32 n;                                                      /* temporary */
  78.  
  79.   if (argc < 2)
  80.   {
  81.     cwprintf(NULL, "%s\r\n", inet_ntoa(server));
  82.   }
  83.   else if (n = resolve(argv[1]), n == 0)
  84.   {
  85.     cwprintf(NULL, "Time - Bad host %s\r\n", argv[1]);
  86.     return (1);
  87.   }
  88.   else
  89.   {
  90.     server = n;
  91.   }
  92.   return (0);
  93. }
  94.  
  95. static void no_net_time(void *sk)
  96. {
  97.   cwprintf(NULL, "Time - No response from %s\r\n", inet_ntoa(server));
  98.   del_udp((struct socket *) sk);
  99.   set_clock = FALSE;
  100. }
  101.  
  102. time_t RiscTime(time_t *place)
  103. {
  104.   BOOL carry = FALSE;
  105.   char btime[] = "\x00\x00\x00\x00\x6A\x99\x6E\x33\x00";
  106.   char rtime[8], ntime[8], tzname[10];
  107.   int diff, loop, temp, tz;
  108.  
  109.   if (wimp_ver < 300)
  110.     return(time(place));
  111.  
  112.   os_swi2r(0x43048, NULL, NULL, (int *) tzname, &tz);
  113.   rtime[3] = 3;
  114.   os_word(14, &rtime[3]);
  115.   for (loop = 3; loop < 8; loop++)
  116.   {
  117.     temp = rtime[loop] - btime[loop] - carry;
  118.     ntime[loop] = temp & 0xFF;
  119.     carry = ((temp & 0x100) != 0);
  120.   }
  121.   diff = (*((int *) &ntime[4]));
  122.   temp = ((diff / 100) * 256) + (((diff % 100) * 256) + ntime[3]) / 100 + tz / 100;
  123.   if (place)
  124.     *place = temp;
  125.   return(temp);
  126. }
  127.  
  128. static void time_rec(struct socket *lsock, int16 rcvcnt)
  129. {
  130.   int loop;
  131.   struct socket fsocket;        /* socket address       */
  132.   struct mbuf *bp;
  133.   time_t pctime;                        /* PC time                      */
  134.   union
  135.   {
  136.     time_t time;
  137.     char bytes[sizeof (time_t)];
  138.   } result;                                                     /* data from remote     */
  139.  
  140.   if (recv_udp(lsock, &fsocket, &bp) != 4)
  141.   {
  142.     cwprintf(NULL, "TIME: receive failed\r\n");
  143.     stop_timer(&net_time_t);
  144.     del_udp(lsock);
  145.     done_set_time = FALSE;
  146.     return;
  147.   }
  148.   /* Calculate the correction value. */
  149.   loop = 0;
  150.  
  151.   while (pullone(&bp, &result.bytes[3 - loop]) == 1)
  152.     loop++;
  153.  
  154.   result.time -= 2208988800U;           /* adjust epoch */
  155.  
  156.   pctime = RiscTime(NULL);
  157.   pctime = mktime(gmtime(&pctime));
  158.   correction = result.time - pctime;
  159.   cwprintf(NULL, "TIME: correction = %ld seconds\r\n", correction);
  160.   cwprintf(NULL, "Net time   (GMT): %s", asctime(localtime(&result.time)));
  161.   cwprintf(NULL, "Local time (GMT): %s", asctime(localtime(&pctime)));
  162.   stop_timer(&net_time_t);
  163.   del_udp(lsock);
  164.  
  165.   if (set_clock)
  166.   {
  167.     char itime[8];
  168.     int correction_abs;
  169.  
  170.     correction_abs = (int) labs(correction);
  171.  
  172.     if (max_correction && correction_abs > max_correction)
  173.     {
  174.       cwprintf(NULL, "TIME: required correction (%ld) greater than maximum (%ld)\r\n",
  175.       correction, max_correction);
  176.       correction = 0;
  177.       return;
  178.     }
  179.  
  180.     if (min_correction && correction_abs < min_correction)
  181.     {
  182.       cwprintf(NULL, "TIME: required correction (%ld) less than minimum (%ld)\r\n",
  183.       correction, min_correction);
  184.       correction = 0;
  185.       return;
  186.     }
  187.     itime[0] = 3;
  188.     os_word(14, itime);
  189.     time_adj(itime, correction);
  190.     os_swi1(0x43047 /* Territory_SetTime */, (int) itime);
  191.  
  192.     correction = 0;                                             /* no need for a correction now */
  193.     cwprintf(NULL, "TIME: Arc clock reset\r\n");
  194.   }
  195.   set_clock = FALSE;
  196. }
  197.  
  198. /* Read the time from the remote and set the correction value. */
  199.  
  200. static int do_read(int argc, char *argv[])
  201. {
  202.   struct socket lsocket, fsocket;       /* socket address                       */
  203.  
  204.   if (server == 0L)
  205.   {
  206.     cwprintf(NULL, "Time - Bad host %s\r\n", "0.0.0.0");
  207.     return (1);
  208.   }
  209.   if (run_timer(&net_time_t))
  210.   {
  211.     cwprintf(NULL, "Time - Already asking\r\n");
  212.     return (1);
  213.   }
  214.  
  215.   /* Set up the connection. */
  216.  
  217.   fsocket.address = server;
  218.   fsocket.port    = TIME_PORT;
  219.   lsocket.address = ip_addr;      /* our ip address */
  220.   lsocket.port    = lport++;      /* next unused port */
  221.  
  222.   open_udp(&lsocket, (void (*)())time_rec);
  223.   send_udp(&lsocket, &fsocket, 0, 0, 0, 0, 0, 0);
  224.  
  225.   time_socket     = lsocket;
  226.   net_time_t.func = no_net_time;  /* what to call on timeout */
  227.   net_time_t.arg  = (void *) &time_socket;
  228.   set_timer(&net_time_t, 30000);
  229.   start_timer(&net_time_t);
  230.   return(0);
  231. }
  232.  
  233.  
  234. /* Set the Arc's clock from the time server. */
  235.  
  236. static int do_set (int argc, char *argv[])
  237. {
  238.   if (do_read (0, NULL) != 0)
  239.     return (1);
  240.  
  241.   set_clock = TRUE;
  242.  
  243.   return (0);
  244. }
  245.  
  246.  
  247. static int do_maxcorrect(int argc, char *argv[])
  248. {
  249.   if(argc < 2)
  250.   {
  251.     cwprintf(NULL, "TIME: maximum correction: %d\r\n", max_correction);
  252.     return 0;
  253.   }
  254.   max_correction = atoi(argv[1]);
  255.   return 0;
  256. }
  257.  
  258. static int do_mincorrect(int argc, char *argv[])
  259. {
  260.   if(argc < 2)
  261.   {
  262.     cwprintf(NULL, "TIME: minimum correction: %d\r\n", min_correction);
  263.     return 0;
  264.   }
  265.   min_correction = atoi(argv[1]);
  266.   return 0;
  267. }
  268.