home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR3 / KA9Q212.ZIP / NETTIME.C < prev    next >
C/C++ Source or Header  |  1993-07-16  |  11KB  |  401 lines

  1. /****************************************************************************
  2. *    Author        :    G Todd                                                    *
  3. *    Language     :    Borland C++ 3.1                                            *
  4. *    Logfile        :    nettime.c                                                *
  5. *    Project        :    DIS KA9Q.                                                *
  6. *    Date         :    24 Aug 92                                                *
  7. *    Revision     :    1.1        GT    Originate.                                    *
  8. *                :    1.2        MT    "auto", "maxcorrect" and "mincorrect".        *
  9. *    21 Sep 92    :    1.3        MT    Fix correction reports.                        *
  10. *                :            GT    Disable idle timeout while setting the time.*
  11. *    28 Sep 92    :    1.4        GT    Wait for next timer tick after setting the    *
  12. *                :                time.                                        *
  13. *    09 Apr 93    :    1.5        GT    Fix spurious error message from do_set ().    *
  14. *                :                Increase connect timeout.                    *
  15. *                :                Fix smtptick () call.                        *
  16. *    13 Apr 93    :    1.6        GT    Time setting tweaks.                        *
  17. *                :                "time delay" command.                        *
  18. *    08 May 93    :    1.9        GT    Fix warnings.                                *
  19. *****************************************************************************
  20. *    Purpose        :    Routines for setting KA9Q's time from the remote host.    *
  21. *                :    Uses the protocol described in RFC 868.                    *
  22. *****************************************************************************
  23. *                :    Copyright Giles Todd 1992.  All rights reserved.        *
  24. *                :    The right of Giles Todd to be identified as the author    *
  25. *                :    of this work has been asserted by him in accordance        *
  26. *                :    with the Copyrights, Designs and Patents Act, 1988.        *
  27. *                :    No restrictions on the use of this module with KA9Q.    *
  28. *****************************************************************************
  29. $Id: nettime.c 1.9 93/07/16 11:46:57 ROOT_DOS Exp $
  30. ****************************************************************************/
  31.  
  32. #include    <stdio.h>
  33. #include    <time.h>
  34. #include    "global.h"
  35. #include    "mbuf.h"
  36. #include    "cmdparse.h"
  37. #include    "proc.h"
  38. #include    "socket.h"
  39. #include    "timer.h"
  40. #include    "netuser.h"
  41. #include    "commands.h"
  42. #include    "ip.h"
  43. #include    "smtp.h"
  44. #include    "pppfsm.h"
  45.  
  46. #if    defined (time)
  47. #undef    time                                /* remove macro                    */
  48. #endif
  49.  
  50. extern int ext_dokicks(void);
  51.  
  52. int done_set_time = 0;    /* have we set the time since this open?    */
  53.  
  54. /****************************************************************************
  55. *    Static function declarations.                                            *
  56. ****************************************************************************/
  57.  
  58. static int do_auto __ARGS((int argc, char **argv, void *p));
  59. static int do_delay __ARGS((int argc, char **argv, void *p));
  60. static int do_server __ARGS((int argc, char **argv, void *p));
  61. static int do_maxcorrect __ARGS((int argc, char **argv, void *p));
  62. static int do_mincorrect __ARGS((int argc, char **argv, void *p));
  63. static int do_read __ARGS((int argc, char **argv, void *p));
  64. static int do_set __ARGS((int argc, char **argv, void *p));
  65. static void bg_set __ARGS((int s, void *unused, void *p));
  66. static void start_of_connection __ARGS((void));
  67.  
  68. /****************************************************************************
  69. *    Static data.                                                            *
  70. ****************************************************************************/
  71.  
  72. static time_t correction = 0L;                /* difference in seconds         */
  73.                                             /* between remote and PC clock    */
  74. static int32 server = 0L;                    /* time server address            */
  75. static int auto_time_set = 0;                /* set time on PPP open?        */
  76. static struct proc *setting_the_time = NULLPROC;
  77. static int32 delay = 10000L;                /* delay for setting up routes    */
  78. static time_t max_correction = 0;            /* !0 is max correction allowed */
  79. static time_t min_correction = 0;            /* !0 is min correction allowed */
  80. static struct cmds time_cmds[] =
  81.     {
  82.     { "auto",        do_auto,    0,        0,    NULLCHAR },
  83.     { "delay",    do_delay,    0,        0,    NULLCHAR },
  84.     { "maxcorrect",do_maxcorrect,0,    0,    NULLCHAR },
  85.     { "mincorrect",do_mincorrect,0,    0,    NULLCHAR },
  86.     { "read",        do_read,    0,        0,    NULLCHAR },
  87.     { "server",    do_server,    0,        0,    NULLCHAR },
  88.     { "set",        do_set,        0,        0,    NULLCHAR },
  89.     { NULLCHAR }
  90.     };
  91.  
  92.  
  93. /****************************************************************************
  94. *    do_time                                                                    *
  95. *    Time commands driver.                                                    *
  96. ****************************************************************************/
  97.  
  98. int do_time (argc, argv, p)
  99. int argc;
  100. char **argv;
  101. void *p;
  102.     {
  103.     return (subcmd (time_cmds, argc, argv, p));
  104.     }    /* int do_time (argc, argv, p) */
  105.  
  106.  
  107. /****************************************************************************
  108. *    do_server                                                                *
  109. *    Display or set the timer server address.                                *
  110. ****************************************************************************/
  111.  
  112. static int do_server (argc, argv, p)
  113. int argc;
  114. char **argv;
  115. void *p;
  116.     {
  117.     int32 n;                                /* temporary                    */
  118.  
  119.     if (argc < 2)
  120.         {
  121.         tprintf ("%s\n", inet_ntoa (server));
  122.         }
  123.     else if ((n = resolve (argv[1])) == 0)
  124.         {
  125.         tprintf (Badhost, argv[1]);
  126.         return (1);
  127.         }
  128.     else
  129.         server = n;
  130.  
  131.     return (0);
  132.     }    /* static int do_server (argc, argv, p) */
  133.     
  134.  
  135. /****************************************************************************
  136. *    do_read                                                                    *
  137. *    Read the time from the remote and set the correction value.                *
  138. ****************************************************************************/
  139.  
  140. static int do_read (argc, argv, p)
  141. int argc;
  142. char **argv;
  143. void *p;
  144.     {
  145.     struct sockaddr_in fsocket;                /* socket address                */
  146.     int s;                                    /* socket handle                */
  147.     union
  148.         {
  149.         time_t time;
  150.         char bytes[sizeof (time_t)];
  151.         } result;                            /* data from remote                */
  152.     char t;                                    /* temporary                    */
  153.     char *cp;                                /* -> error message                */
  154.     time_t pctime;                            /* PC time                        */
  155.  
  156.     if (server == 0L)
  157.         {
  158.         tprintf (Badhost, "0.0.0.0");
  159.         return (1);
  160.         }
  161.         
  162.     /* Set up the connection. */
  163.  
  164.     fsocket.sin_family = AF_INET;
  165.     fsocket.sin_addr.s_addr = server;
  166.     fsocket.sin_port = IPPORT_TIME;
  167.     s = socket (AF_INET, SOCK_STREAM, 0);
  168.     sockmode (s, SOCK_BINARY);
  169.     alarm (connect_wait_val);                /* set timeout                    */
  170.     if (connect (s, (char *) &fsocket, SOCKSIZE) != 0)
  171.         {
  172.         alarm (0L);
  173.         cp = sockerr (s);
  174.         tprintf ("TIME: %s connect failed: %s\n", psocket (&fsocket),
  175.                  cp != NULLCHAR ? cp : "");
  176.         (void) close_s (s);
  177.         done_set_time = FALSE;
  178.         return (1);
  179.         }
  180.  
  181.     alarm (0L);
  182.  
  183.     /* Try to receive the time. */
  184.  
  185.     if (recv (s, result.bytes, sizeof (result.bytes), 0) !=
  186.         sizeof (result.bytes))
  187.         {
  188.         tprintf ("TIME: receive failed\n");
  189.         close_s (s);
  190.         done_set_time = FALSE;
  191.         return (1);
  192.         }
  193.  
  194.     close_s (s);
  195.  
  196.     /* Calculate the correction value. */
  197.  
  198.     t = result.bytes[0];
  199.     result.bytes[0] = result.bytes[3];
  200.     result.bytes[3] = t;
  201.     t = result.bytes[1];
  202.     result.bytes[1] = result.bytes[2];
  203.     result.bytes[2] = t;
  204.     result.time -= 2208988800L;                /* adjust epoch                    */
  205.         
  206.     pctime = time (NULL);
  207.     correction = result.time - pctime;
  208.     tprintf ("TIME: correction = %ld seconds\n", correction);
  209.     pctime = ka9q_time (NULL);
  210.     tprintf ("Time now (GMT): %s", asctime (gmtime (&pctime)));
  211.     return (0);
  212.     }    /* static int do_read (argc, argv, p) */
  213.  
  214.  
  215. /****************************************************************************
  216. *    do_set                                                                    *
  217. *    Set the PC's clock from the time server.                                *
  218. ****************************************************************************/
  219.  
  220. static int do_set (argc, argv, p)
  221. int argc;
  222. char **argv;
  223. void *p;
  224.     {
  225.     time_t n;                                /* temporary                    */
  226.     int correction_abs;
  227.  
  228.     if (correction == 0L)
  229.         {
  230.         /* Set up the correction. */
  231.  
  232.         if (do_read (0, NULL, NULL) != 0)
  233.             return (1);
  234.             
  235.         }
  236.  
  237.     correction_abs = (int) labs(correction);
  238.  
  239.     if (max_correction && correction_abs > max_correction)
  240.         {
  241.         tprintf("TIME: required correction (%ld) greater than maximum (%ld)\n",
  242.             correction, max_correction);
  243.         correction = 0L;
  244.         return (0);
  245.         }
  246.  
  247.     if (min_correction && correction_abs < min_correction)
  248.         {
  249.         tprintf("TIME: required correction (%ld) less than minimum (%ld)\n",
  250.             correction, min_correction);
  251.         correction = 0L;
  252.         return (0);
  253.         }
  254.  
  255.     n = ka9q_time (NULL);                    /* get tweaked time                */
  256.     (void) stime (&n);                        /* and set the PC clock            */
  257.     log(-1,"PC clock adjusted by %ld at %s (server %s)",
  258.                                     correction, ctime(&n), inet_ntoa(server));
  259.     correction = 0L;                        /* no need for a correction now    */
  260.     tprintf ("TIME: PC clock set\n");
  261.     return (0);
  262.     }    /* static int do_set (argc, argv, p) */
  263.  
  264.  
  265. /****************************************************************************
  266. *    do_delay                                                                *
  267. *    Displays or sets the timer delay.                                        *
  268. ****************************************************************************/
  269.     
  270. static int do_delay (argc, argv, p)
  271. int argc;
  272. char *argv[];
  273. void *p;
  274.     {
  275.     if (argc < 2)
  276.         {
  277.         tprintf ("auto kick delay: %lu\n", delay / 1000L);
  278.         return (0);
  279.         }
  280.  
  281.     delay = atol (argv[1]) * 1000L;            /* set timeout                    */
  282.     return (0);
  283.     }    /* static int do_delay (argc, argv, p) */
  284.     
  285.  
  286. /****************************************************************************
  287. *    ka9q_time                                                                *
  288. *    Replacement for library "time ()" function.  Called by other modules    *
  289. *    via nasty macro substitution.                                            *
  290. ****************************************************************************/
  291.  
  292. time_t ka9q_time (t)
  293. time_t *t;
  294.     {
  295.     time_t rc;                                /* return value                    */
  296.  
  297.     (void) time (&rc);                        /* get the PC's idea            */
  298.     rc += correction;
  299.     if (t != NULL)
  300.         *t = rc;
  301.  
  302.     return (rc);
  303.     }    /* time_t ka9q_time (t) */
  304.  
  305.     
  306. /****************************************************************************
  307. *    do_auto                                                                    *
  308. *    Should we do a 'time set' every time ppp ipcp opens?                     *
  309. ****************************************************************************/
  310.  
  311. static int do_auto (argc, argv, p)
  312. int argc;
  313. char **argv;
  314. void *p;
  315.     {
  316.     return setbool(&auto_time_set, "TIME SET auto mode", argc, argv);
  317.     }
  318.  
  319. int try_set_time (argc, argv, p)
  320. int argc;
  321. char **argv;
  322. void *p;
  323.     {
  324.     struct ppp_s *ppp_p = p;
  325.     
  326.     done_set_time = 1;
  327.     if (!auto_time_set)
  328.         return 0;
  329.     if (setting_the_time == NULLPROC)
  330.         setting_the_time = newproc("set time", 512, bg_set, 0, NULL, ppp_p, 0);
  331.     return 0;
  332.     }
  333.  
  334. static void start_of_connection()
  335.     {
  336.     int32 zero = 0;
  337.     smtptick((void *) zero);
  338.     ext_dokicks();
  339.     }
  340.  
  341. static void bg_set (s, unused, p)
  342. int s;
  343. void *unused;
  344. void *p;
  345.     {
  346.     int32 save_idle_durn = 0L;
  347.     struct ppp_s *ppp_p = p;
  348.     
  349.     pause (delay);
  350.  
  351.     if (ppp_p->idle_durn != 0L)
  352.         {
  353.         /* Stop the PPP idle timer. */
  354.  
  355.         stop_timer (&(ppp_p->idle_timer));
  356.         save_idle_durn = ppp_p->idle_durn;
  357.         ppp_p->idle_durn = 0L;
  358.         }
  359.         
  360.     do_set(0, NULL, NULL);
  361.     setting_the_time = NULLPROC;
  362.     if (save_idle_durn != 0L)
  363.         {
  364.         /* Restart the PPP idle timer. */
  365.         pwait (&Tick);                    /* wait for next timer tick            */
  366.         ppp_p->idle_durn = save_idle_durn;
  367.         set_timer (&(ppp_p->idle_timer), ppp_p->idle_durn);
  368.         start_timer (&(ppp_p->idle_timer));
  369.         }
  370.  
  371.     start_of_connection();
  372.     }
  373.  
  374. static int
  375. do_maxcorrect(argc,argv,p)
  376. int argc;
  377. char *argv[];
  378. void *p;
  379. {
  380.     if(argc < 2){
  381.         tprintf("TIME: maximum correction: %d\n", max_correction);
  382.         return 0;
  383.     }
  384.     max_correction = atoi(argv[1]);
  385.     return 0;
  386. }
  387.  
  388. static int
  389. do_mincorrect(argc,argv,p)
  390. int argc;
  391. char *argv[];
  392. void *p;
  393. {
  394.     if(argc < 2){
  395.         tprintf("TIME: minimum correction: %d\n", min_correction);
  396.         return 0;
  397.     }
  398.     min_correction = atoi(argv[1]);
  399.     return 0;
  400. }
  401.