home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / EXTRAS / UUCODE / UUPC / TEST / UPC12ES4.ZIP / UTIL / uupoll.c < prev   
Encoding:
C/C++ Source or Header  |  1993-11-07  |  37.4 KB  |  1,040 lines

  1. /*--------------------------------------------------------------------*/
  2. /*    Program:    uupoll.c              22 September 1989             */
  3. /*    Author:     Andrew H. Derbyshire                                */
  4. /*                Kendra Electronic Wonderworks                       */
  5. /*                P.O. Box 132                                        */
  6. /*                Arlington, MA 02174                                 */
  7. /*    Internet:   help@kew.com                                        */
  8. /*    Function:   Performs autopoll functions for UUCICO              */
  9. /*    Language:   Borland C++ 3.1                                     */
  10. /*--------------------------------------------------------------------*/
  11.  
  12. /*--------------------------------------------------------------------*/
  13. /*       Changes Copyright (c) 1989-1993 by Kendra Electronic         */
  14. /*       Wonderworks.                                                 */
  15. /*                                                                    */
  16. /*       All rights reserved except those explicitly granted by       */
  17. /*       the UUPC/extended license agreement.                         */
  18. /*--------------------------------------------------------------------*/
  19.  
  20. /*--------------------------------------------------------------------*/
  21. /*    Usage:      uupoll [-r 0] [-f hhmm] [-i hhmm|0400 ]             */
  22. /*                       [-d hhmm] [-e hhmm]                          */
  23. /*                       [-a hhmm] [-x debug] [-s systems]            */
  24. /*                       [-c hhmm] [-C command] [-B command]          */
  25. /*                                                                    */
  26. /*                Where:                                              */
  27. /*                                                                    */
  28. /*                -r 0     specifies that UUCICO is to run            */
  29. /*                         into passive mode when waiting to          */
  30. /*                         poll out                                   */
  31. /*                                                                    */
  32. /*                -r 1     specifies that UUCICO will not run         */
  33. /*                         in passive mode while waiting to           */
  34. /*                         poll out, but polling out will             */
  35. /*                         occur.                                     */
  36. /*                                                                    */
  37. /*                -f hhmm  is the first time in the day that          */
  38. /*                         UUCICO is to poll out.  If omitted,        */
  39. /*                         polling begins after the interval          */
  40. /*                         specified with -i.                         */
  41. /*                                                                    */
  42. /*                -i hhmm  the interval the UUCICO is to poll         */
  43. /*                         out at.  If omitted, a period of 4         */
  44. /*                         hours will be used.                        */
  45. /*                                                                    */
  46. /*                -d hhmm  Terminate polling after hhmm.              */
  47. /*                         Default is not to terminate.               */
  48. /*                                                                    */
  49. /*                -e hhmm  Terminate polling at hhmm                  */
  50. /*                         Default is not to terminate.               */
  51. /*                                                                    */
  52. /*                -a hhmm  Automatically poll actively using the      */
  53. /*                         system name "any" after any                */
  54. /*                         successful inbound poll if hhmm have       */
  55. /*                         past since last poll.  hhmm may be         */
  56. /*                         0000.                                      */
  57. /*                                                                    */
  58. /*                -c hhmm  Run a command at hhmm to clean the UUPC    */
  59. /*                         spool at this time every day.  Default is  */
  60. /*                         never.                                     */
  61. /*                                                                    */
  62. /*                -C cmd   Run command 'cmd' at the specified by      */
  63. /*                         -c.  The default is UUCLEAN.               */
  64. /*                                                                    */
  65. /*                -B cmd   Run command cmd before each active call    */
  66. /*                         out to batch up any work.  Default is      */
  67. /*                         run nothing.                              */
  68. /*                                                                    */
  69. /*                In addition, the following flags will be passed     */
  70. /*                to UUCICO:                                          */
  71. /*                                                                    */
  72. /*                -s system      system name to poll.  By default,    */
  73. /*                               UUCICO will be invoked with          */
  74. /*                               '-s all' followed by '-s any'.       */
  75. /*                                                                    */
  76. /*                -x n           debug level.   The default level     */
  77. /*                               is 1.                                */
  78. /*--------------------------------------------------------------------*/
  79.  
  80. /*--------------------------------------------------------------------*/
  81. /*                          RCS Information                           */
  82. /*--------------------------------------------------------------------*/
  83.  
  84. /*
  85.  *    $Id: uupoll.c 1.18 1993/11/06 17:56:09 rhg Exp $
  86.  *
  87.  *    $Log: uupoll.c $
  88.  * Revision 1.18  1993/11/06  17:56:09  rhg
  89.  * Drive Drew nuts by submitting cosmetic changes mixed in with bug fixes
  90.  *
  91.  * Revision 1.17  1993/10/28  00:18:10  ahd
  92.  * Drop unneeded tzset() call
  93.  *
  94.  * Revision 1.16  1993/10/16  15:13:17  ahd
  95.  * Call UUXQT in sync mode
  96.  *
  97.  * Revision 1.16  1993/10/16  15:13:17  ahd
  98.  * Call UUXQT in sync mode
  99.  *
  100.  * Revision 1.15  1993/10/12  01:31:06  ahd
  101.  * Normalize comments to PL/I style
  102.  *
  103.  * Revision 1.14  1993/09/27  00:45:20  ahd
  104.  * Make command syncs to get around bug in execute() under OS/2
  105.  *
  106.  * Revision 1.13  1993/09/20  04:41:54  ahd
  107.  * OS/2 2.x support
  108.  *
  109.  * Revision 1.12  1993/07/31  16:26:01  ahd
  110.  * Changes in support of Robert Denny's Windows support
  111.  *
  112.  * Revision 1.11  1993/07/19  02:52:11  ahd
  113.  * Up memory access room
  114.  *
  115.  * Revision 1.10  1993/06/06  15:04:05  ahd
  116.  * Allow for batch command to run before regularly scheduled poll out
  117.  *
  118.  * Revision 1.9  1993/05/13  01:39:04  ahd
  119.  * Additional fix for correctly handling UUCLEAN once and only once daily
  120.  *
  121.  * Revision 1.8  1993/05/11  03:25:17  ahd
  122.  * Don't loop when sleeping for autoclean -- get it over with
  123.  *
  124.  * Revision 1.7  1993/04/14  10:29:53  ahd
  125.  * Correct invalid exit time if both -e and -f flags specified
  126.  *
  127.  * Revision 1.6  1993/04/10  21:25:16  dmwatt
  128.  * Add Windows/NT support
  129.  *
  130.  * Revision 1.6  1993/04/10  21:25:16  dmwatt
  131.  * Add Windows/NT support
  132.  *
  133.  * Revision 1.5  1993/04/04  04:57:01  ahd
  134.  * Return exit code of UUCICO upon exit
  135.  *
  136.  * Revision 1.4  1993/03/06  23:04:54  ahd
  137.  * Add cr after auto-clean message
  138.  *
  139.  * Revision 1.3  1992/11/20  12:41:01  ahd
  140.  * Fix TZ change bug
  141.  *
  142.  * Revision 1.2  1992/11/15  04:45:46  ahd
  143.  * Correct polling for days time zone changes
  144.  *
  145.  * Revision 1.1  1992/11/15  04:29:22  ahd
  146.  * Initial revision
  147.  *
  148.  * Revision 1.1  1992/04/27  00:30:13  ahd
  149.  * Initial revision
  150.  *
  151.  */
  152.  
  153. static const char rcsid[] =
  154.          "$Id: uupoll.c 1.18 1993/11/06 17:56:09 rhg Exp $";
  155.  
  156. /*--------------------------------------------------------------------*/
  157. /*                        System include file                         */
  158. /*--------------------------------------------------------------------*/
  159.  
  160. #include <ctype.h>
  161. #include <dos.h>
  162. #include <limits.h>
  163. #include <process.h>
  164. #include <stdio.h>
  165. #include <stdlib.h>
  166. #include <string.h>
  167. #include <time.h>
  168. #include <conio.h>
  169. #include <direct.h>
  170. #include <signal.h>           /* Ctrl-Break handler               */
  171.  
  172. #if  defined(WIN32) || defined(FAMILYAPI) || defined(_Windows) || defined(__OS2__)
  173. #define NOCBREAK
  174. #elif defined(__TURBOC__)
  175. #include <alloc.h>
  176. unsigned _stklen = 3172;            /* Reduce memory usage           */
  177. unsigned _heaplen = 2048;           /* Reduce memory usage           */
  178. #else
  179. static int setcbrk(char state);
  180. #endif
  181.  
  182. /*--------------------------------------------------------------------*/
  183. /*                    UUPC/extended include files                     */
  184. /*--------------------------------------------------------------------*/
  185.  
  186. #include "getopt.h"
  187. #include "lib.h"
  188. #include "timestmp.h"
  189. #include "ssleep.h"
  190. #include "arpadate.h"
  191. #include "safeio.h"
  192. #include "dater.h"
  193. #include "execute.h"
  194.  
  195. /*--------------------------------------------------------------------*/
  196. /*                        Typedefs and macros                         */
  197. /*--------------------------------------------------------------------*/
  198.  
  199. typedef int hhmm;
  200.  
  201. /*--------------------------------------------------------------------*/
  202. /*                  Prototypes and global variables                   */
  203. /*--------------------------------------------------------------------*/
  204.  
  205.  void
  206. #ifdef __TURBOC__
  207. __cdecl
  208. #endif
  209.  Catcher( int sig );
  210.  
  211. static active(char *Rmtname, int debuglevel, const char *logname);
  212.  
  213. static void    busywork( time_t next);
  214.  
  215. static int runCommand( char *command, const boolean sync);
  216.  
  217. static time_t  nextpoll( hhmm first, hhmm interval );
  218.  
  219. static boolean     notanumber( char *number);
  220.  
  221. static void    usage( char *name );
  222.  
  223.  static int passive( time_t next,
  224.                      int debuglevel,
  225.                      const char *logname,
  226.                      const char *modem );
  227.  
  228. static hhmm    firstpoll(hhmm interval);
  229.  
  230. static void    uuxqt( const int debuglevel, const boolean sync);
  231.  
  232. static time_t LifeSpan( time_t duration, time_t stoptime );
  233.  
  234. static time_t now;            /* Current time, updated at start of
  235.                                  program and by busywork() and
  236.                                  runCommand()                        */
  237.  
  238. currentfile();
  239.  
  240. /*--------------------------------------------------------------------*/
  241. /*    m a i n                                                         */
  242. /*                                                                    */
  243. /*    main program                                                    */
  244. /*--------------------------------------------------------------------*/
  245.  
  246.  void main( int argc , char *argv[] )
  247.  {
  248.  
  249.    int option;
  250.    hhmm first = - 1;
  251.    hhmm interval = -1;
  252.    hhmm stoptime = -1;
  253.    hhmm duration = -1;
  254.    hhmm autowait = -1;
  255.    hhmm cleanup  = -1;
  256.    time_t cleannext = LONG_MAX;
  257.  
  258.    time_t exittime;
  259.    int nopassive = 2;
  260.    boolean done = FALSE;
  261.    char *Rmtname = NULL;
  262.    char *CleanCommand = "uuclean";
  263.    char *logname = NULL;
  264.    char *modem   = NULL;
  265.    char *batchCommand   = NULL;
  266.    int returnCode = 0;
  267.  
  268. #ifndef NOCBREAK
  269.    boolean cbrk;
  270. #endif
  271.  
  272.    banner(argv);
  273.  
  274.    if (!configure( B_UUPOLL ))
  275.       panic();
  276.  
  277.    time( &now );
  278.  
  279.     if( signal( SIGINT, Catcher ) == SIG_ERR )
  280.     {
  281.         fprintf( stderr, "uupoll: Couldn't set SIGINT\n" );
  282.         panic();
  283.     }
  284.  
  285.    while((option = getopt(argc, argv, "m:a:B:c:C:d:e:f:l:i:s:r:x:")) != EOF)
  286.    switch(option)
  287.    {
  288.  
  289. /*--------------------------------------------------------------------*/
  290. /*       Automatically poll "any" after an incoming phone call        */
  291. /*--------------------------------------------------------------------*/
  292.  
  293.       case 'a':
  294.          if (notanumber(optarg))
  295.             usage( argv[0] );
  296.          autowait = (hhmm) hhmm2sec( atoi(optarg) );
  297.          break;
  298.  
  299. /*--------------------------------------------------------------------*/
  300. /*                    Batching command to execute                     */
  301. /*--------------------------------------------------------------------*/
  302.  
  303.       case 'B':
  304.          batchCommand = optarg;
  305.          break;
  306.  
  307. /*--------------------------------------------------------------------*/
  308. /*                         First time to poll                         */
  309. /*--------------------------------------------------------------------*/
  310.  
  311.       case 'f':
  312.          if (notanumber(optarg))
  313.             usage( argv[0] );
  314.          first = atoi(optarg);
  315.          if ( interval == -1 )
  316.             interval = 400;
  317.          break;
  318.  
  319. /*--------------------------------------------------------------------*/
  320. /*                         First time to clean                        */
  321. /*--------------------------------------------------------------------*/
  322.  
  323.       case 'c':
  324.          if (notanumber(optarg))
  325.             usage( argv[0] );
  326.          cleanup = atoi(optarg);
  327.          break;
  328.  
  329. /*--------------------------------------------------------------------*/
  330. /*                    Clean-up command to execute                     */
  331. /*--------------------------------------------------------------------*/
  332.  
  333.       case 'C':
  334.          CleanCommand = optarg;
  335.          break;
  336.  
  337. /*--------------------------------------------------------------------*/
  338. /*                          UUCICO log file                           */
  339. /*--------------------------------------------------------------------*/
  340.  
  341.       case 'l':
  342.          logname = optarg;
  343.          break;
  344.  
  345.  
  346. /*--------------------------------------------------------------------*/
  347. /*                            Input modem                             */
  348. /*--------------------------------------------------------------------*/
  349.  
  350.       case 'm':
  351.          modem = optarg;
  352.          break;
  353.  
  354. /*--------------------------------------------------------------------*/
  355. /*                          Interval to poll                          */
  356. /*--------------------------------------------------------------------*/
  357.  
  358.       case 'i':
  359.          if (notanumber(optarg))
  360.             usage( argv[0] );
  361.          interval = atoi(optarg);
  362.          nopassive = min(1,nopassive);
  363.          break;
  364.  
  365. /*--------------------------------------------------------------------*/
  366. /*                      Duration to poll                              */
  367. /*--------------------------------------------------------------------*/
  368.  
  369.       case 'e':
  370.          if (notanumber(optarg))
  371.             usage( argv[0] );
  372.          stoptime = atoi(optarg);
  373.          break;
  374.  
  375. /*--------------------------------------------------------------------*/
  376. /*                      Time to exit                                  */
  377. /*--------------------------------------------------------------------*/
  378.  
  379.       case 'd':
  380.          if (notanumber(optarg))
  381.             usage( argv[0] );
  382.          duration = atoi(optarg);
  383.          break;
  384.  
  385.  
  386. /*--------------------------------------------------------------------*/
  387. /*                        System name to poll                         */
  388. /*--------------------------------------------------------------------*/
  389.  
  390.       case 's':
  391.          Rmtname = strdup(optarg);
  392.          break;
  393.  
  394. /*--------------------------------------------------------------------*/
  395. /*                            Debug level                             */
  396. /*--------------------------------------------------------------------*/
  397.  
  398.       case 'x':
  399.          if (notanumber(optarg))
  400.             usage( argv[0] );
  401.          debuglevel = atoi(optarg);
  402.          break;
  403.  
  404. /*--------------------------------------------------------------------*/
  405. /*                       Passive polling option                       */
  406. /*--------------------------------------------------------------------*/
  407.  
  408.       case 'r':
  409.          if (notanumber(optarg))
  410.             usage( argv[0] );
  411.          nopassive = atoi(optarg);
  412.          break;
  413.  
  414. /*--------------------------------------------------------------------*/
  415. /*                                Help                                */
  416. /*--------------------------------------------------------------------*/
  417.  
  418.       default:
  419.       case '?':
  420.          usage( argv[0] );
  421.    } /* switch */
  422.  
  423. /*--------------------------------------------------------------------*/
  424. /*             Terminate with error if too many arguments             */
  425. /*--------------------------------------------------------------------*/
  426.  
  427.    if (optind != argc)
  428.    {
  429.       puts("Extra parameters on command line.");
  430.       usage( argv[0] );
  431.    }
  432.  
  433. /*--------------------------------------------------------------------*/
  434. /*       Terminate if neither active polling nor passive polling      */
  435. /*       requested                                                    */
  436. /*--------------------------------------------------------------------*/
  437.  
  438.    if ( nopassive == 2 && (first < 0))
  439.    {
  440.       puts("Must specify -r 0, -f hhmm, or -i hhmm");
  441.       usage( argv[0] );
  442.    }
  443.  
  444. /*--------------------------------------------------------------------*/
  445. /*                        Compute time to exit                        */
  446. /*--------------------------------------------------------------------*/
  447.  
  448.    exittime = LifeSpan( duration, stoptime );
  449.  
  450. /*--------------------------------------------------------------------*/
  451. /*                   Comput first time to poll out                    */
  452. /*--------------------------------------------------------------------*/
  453.  
  454.    if ( (interval > 0) && (first < 0))
  455.       first = firstpoll(interval);
  456.  
  457. /*--------------------------------------------------------------------*/
  458. /*            If running under MS-DOS, enable Cntrl-Break.            */
  459. /*--------------------------------------------------------------------*/
  460.  
  461. #ifndef NOCBREAK
  462. #if defined(__TURBOC__)
  463.  
  464.    cbrk = getcbrk();                /* Get original Cntrl-Break setting */
  465.  
  466.    if (!cbrk)
  467.       setcbrk(1);                   /* Turn it on to allow abort      */
  468.  
  469. #else /*dmw*/
  470.  
  471.    cbrk = setcbrk(1);      /* Turn it on to allow abort; get previous state */
  472.  
  473. #endif
  474. #endif
  475.  
  476. /*--------------------------------------------------------------------*/
  477. /*          Determine first time to perform clean-up, if any          */
  478. /*--------------------------------------------------------------------*/
  479.  
  480.       if (cleanup >= 0)
  481.       {
  482.          cleannext = nextpoll(cleanup, 2400);
  483.          printf("Automatic cleanup via \"%s\" scheduled for %s",
  484.                   CleanCommand, ctime(&cleannext));
  485.       }
  486.  
  487. /*--------------------------------------------------------------------*/
  488. /*                       Beginning of main loop                       */
  489. /*--------------------------------------------------------------------*/
  490.  
  491.    while ( !done && (exittime > now))
  492.    {
  493.       time_t next = LONG_MAX;
  494.       time_t autonext  = now + autowait;
  495.       time_t wait = 10;      /* Time to wait after first panic()    */
  496.       returnCode = 0;
  497.  
  498. /*--------------------------------------------------------------------*/
  499. /*        Determine length of passive poll or wasting of time         */
  500. /*--------------------------------------------------------------------*/
  501.  
  502.       if (first >= 0)
  503.       {
  504.          next = nextpoll(first,interval);
  505.          if ( next > exittime )
  506.             next = exittime;
  507.       }
  508.       else
  509.          next = exittime;
  510.  
  511. /*--------------------------------------------------------------------*/
  512. /*              Disable OS/2 undelete support if desired              */
  513. /*--------------------------------------------------------------------*/
  514.  
  515.    if ( !bflag[ F_UNDELETE ] )
  516.       putenv( "DELDIR=");
  517.  
  518. /*--------------------------------------------------------------------*/
  519. /*    Begin passive polling (with optional active calls system        */
  520. /*    "any") until next active poll or exit time is reached.          */
  521. /*--------------------------------------------------------------------*/
  522.  
  523.       while ((now < next) && ! done )
  524.       {
  525.  
  526.          if ( cleannext <= now )
  527.          {
  528.             printf("Performing auto-clean with command: %s\n",
  529.                      CleanCommand );
  530.             if (runCommand( CleanCommand, FALSE ))
  531.                printerr( CleanCommand );
  532.             cleannext = nextpoll(cleanup,  2400);
  533.          }
  534.  
  535.          if (nopassive)
  536.             busywork(next < cleannext ? next : cleannext);
  537.          else {
  538.             time_t spin;
  539.             returnCode = passive(next < cleannext ? next : cleannext ,
  540.                                  debuglevel, logname , modem );
  541.  
  542.             if (returnCode == 69 )  /* Error in UUCICO?              */
  543.             {                       /* Yes --> Allow time to fix it  */
  544.                spin = now + wait;   /* Figure next wait              */
  545.                wait *= 2 ;          /* Double wait for next time     */
  546.                busywork( spin > next ? next : spin );
  547.                                     /* But only wait till next poll  */
  548.             } /* if (returnCode == 69 ) */
  549.             else {
  550.                wait = 10;
  551.  
  552.                if (returnCode == 0)
  553.                {
  554.                   boolean poll  =  (autowait != -1) &&
  555.                                    (now >= autonext) &&
  556.                                    (now < next);
  557.  
  558.                   uuxqt( debuglevel, TRUE );
  559.  
  560.                   if ( poll )
  561.                   {
  562.                      returnCode = active("any", debuglevel, logname);
  563.                      autonext = now + autowait;
  564.                   } /* if */
  565.  
  566.                }  /* if (returnCode == 0) */
  567.  
  568.             } /* else */
  569.  
  570.             if ( (now > exittime) && (now < next))
  571.                done = TRUE;
  572.             else if ( returnCode == 100 )
  573.                done = TRUE;
  574.  
  575.          } /* else */
  576.  
  577.       } /* while */
  578.  
  579. /*--------------------------------------------------------------------*/
  580. /*                      Actively poll if needed                       */
  581. /*--------------------------------------------------------------------*/
  582.  
  583.       if ( ! done && (first >= 0) )
  584.       {
  585.          if ( batchCommand != NULL )
  586.          {
  587.             returnCode = runCommand( batchCommand, TRUE );
  588.             if ( returnCode != 0 )
  589.             {
  590.                printmsg(0,
  591.                         "%s exited with %d status, UUPOLL exiting",
  592.                         batchCommand,
  593.                         returnCode);
  594.                break;
  595.             }
  596.          }
  597.  
  598.          returnCode = active(Rmtname,debuglevel,logname);
  599.  
  600.          if ( returnCode == 100 )
  601.             done = TRUE;
  602.  
  603.       } /* if ( ! done && (first >= 0) ) */
  604.  
  605.    } /* while */
  606.  
  607. /*--------------------------------------------------------------------*/
  608. /*                          End of main loop                          */
  609. /*--------------------------------------------------------------------*/
  610.  
  611.    uuxqt( debuglevel, TRUE  );   /* One last call to UUXQT            */
  612.  
  613. #ifndef NOCBREAK
  614.    if (!cbrk)
  615.       setcbrk(0);                /* Restore original Cntrl-Break setting */
  616. #endif
  617.  
  618.    printmsg(2,"UUPOLL exiting with return code %d", returnCode );
  619.  
  620.    exit(returnCode);
  621.  } /* main */
  622.  
  623. /*--------------------------------------------------------------------*/
  624. /*    L i f e  S p a n                                                */
  625. /*                                                                    */
  626. /*    Compute time to run program                                     */
  627. /*--------------------------------------------------------------------*/
  628.  
  629. static time_t LifeSpan( time_t duration, time_t stoptime )
  630. {
  631.    time_t exittime = LONG_MAX;
  632.    struct tm  *time_record;
  633.    time_t quit;
  634.  
  635. /*--------------------------------------------------------------------*/
  636. /*             Compute relative quitting time, if desired             */
  637. /*--------------------------------------------------------------------*/
  638.  
  639.    if (duration != -1)
  640.       exittime = hhmm2sec( duration ) + (now / 60L) * 60L;
  641.  
  642. /*--------------------------------------------------------------------*/
  643. /*    Compute absolute quitting time, if desired.  Must terminate     */
  644. /*    before midnight unless relative time was given as well, in      */
  645. /*    which case it must terminate before relative time would         */
  646. /*    expire.                                                         */
  647. /*--------------------------------------------------------------------*/
  648.  
  649.    if (stoptime != -1)
  650.    {
  651.  
  652. /*--------------------------------------------------------------------*/
  653. /*               Compute the absolute termination time                */
  654. /*--------------------------------------------------------------------*/
  655.  
  656.       time_record = localtime(&now);
  657.       time_record->tm_sec = 0;
  658.       time_record->tm_min = (int) (stoptime % 100);
  659.       time_record->tm_hour= (int) (stoptime / 100);
  660.       quit = mktime(time_record);
  661.  
  662.       if ( quit < now )             /* Number should be in future    */
  663.          quit += hhmm2sec( 2400 );
  664.  
  665. /*--------------------------------------------------------------------*/
  666. /*              Compute default relative time, if needed              */
  667. /*--------------------------------------------------------------------*/
  668.  
  669.       if ( duration == -1 )
  670.       {
  671.          time_record->tm_min = 0;
  672.          time_record->tm_hour= 24;
  673.          exittime = mktime(time_record);
  674.       }
  675.  
  676. /*--------------------------------------------------------------------*/
  677. /*                  Determine if we should use time                   */
  678. /*--------------------------------------------------------------------*/
  679.  
  680.       if ( exittime < quit )
  681.       {
  682.  
  683.          printf("*** Exiting ***\tProgram was to execute until %s",
  684.                      ctime(&quit));
  685.  
  686.          printf("\t\twhich would exceed retirement at %s",
  687.                      ctime(&exittime));
  688.          exit(10);
  689.  
  690.       } /* if ( exittime < now ) */
  691.       else
  692.          exittime = quit;
  693.  
  694.    } /* else if (stoptime != -1) */
  695.  
  696.    if (exittime != LONG_MAX)
  697.       printf("Will terminate upon completion of first event after %s",
  698.               ctime(&exittime));
  699.  
  700.    return exittime;
  701.  
  702. } /* LifeSpan */
  703.  
  704. /*--------------------------------------------------------------------*/
  705. /*    a c t i v e                                                     */
  706. /*                                                                    */
  707. /*    Perform an active (outgoing) poll of other hosts                */
  708. /*--------------------------------------------------------------------*/
  709.  
  710.  static active(char *Rmtname, int debuglevel, const char *logname)
  711.  {
  712.    int result;
  713.  
  714.    if (Rmtname == NULL)             /* Default?                       */
  715.    {                                /* Yes --> do -s all and -s any   */
  716.       if (active("all",debuglevel, logname ) < 100)
  717.          return active("any",debuglevel, logname);
  718.       else
  719.          return 100;
  720.    }
  721.    else {
  722.       char buf[128];
  723.       sprintf(buf,"uucico -r 1 -s %s -x %d",Rmtname,debuglevel);
  724.  
  725.       if ( logname != NULL )
  726.          strcat( strcat( buf, " -l ") , logname );
  727.  
  728.       result = runCommand(buf, TRUE);
  729.       if ( result == 0 )
  730.          uuxqt( debuglevel, TRUE );
  731.  
  732.       printmsg(2,"active: Return code = %d", result );
  733.  
  734.       return result;
  735.    }
  736.  } /* active */
  737.  
  738. /*--------------------------------------------------------------------*/
  739. /*    b u s y w o r k                                                 */
  740. /*                                                                    */
  741. /*    Waits for next time to poll without answering the telephone.    */
  742. /*    Maybe we should at least beep on the hour?  :-)                 */
  743. /*--------------------------------------------------------------------*/
  744.  
  745. static void busywork( time_t next)
  746. {
  747.    time_t naptime;
  748.    time_t hours, minutes, seconds;
  749.  
  750.    naptime = next - now;
  751.  
  752.    hours   = (naptime / 3600) % 24;    /* Get pretty time to display... */
  753.    minutes = (naptime / 60) % 60;
  754.    seconds = naptime % 60;
  755.  
  756.    printf("Going to sleep for %02ld:%02ld:%02ld, next poll is %s",
  757.              hours, minutes, seconds, ctime(&next) );
  758.    ssleep( naptime );
  759.  
  760.    time( & now );
  761. }
  762.  
  763.  
  764. /*--------------------------------------------------------------------*/
  765. /*    r u n C o m m a n d                                             */
  766. /*                                                                    */
  767. /*    Executes a command via a spawn() system call.  This avoids      */
  768. /*    the storage overhead of COMMAND.COM and returns the actual      */
  769. /*    return code from the command executed.                          */
  770. /*                                                                    */
  771. /*    Note that this does not allow quoted command arguments, which   */
  772. /*    not a problem for the intended argv[0]s of UUCICO.              */
  773. /*--------------------------------------------------------------------*/
  774.  
  775.  static int runCommand( char *command, const boolean sync)
  776.  {
  777.    int result;
  778.  
  779. #ifdef DEBUG
  780.    FILE *stream = NULL;
  781. #endif
  782.  
  783.    printf("Executing command: %s\n",command);
  784. #ifdef DEBUG                  /* ahd */
  785.    stream = fopen("UUPOLL.LOG","a");
  786.    if (stream == NULL)
  787.    {
  788.       printerr("UUPOLL.LOG");
  789.       panic();
  790.    } /* if */
  791.    fprintf(stream, "%s: %s\n",arpadate(), command);
  792.    fclose(stream);
  793. #endif /* DEBUG */
  794.  
  795.    result = executeCommand( command, NULL, NULL, sync, FALSE );
  796.  
  797.    if ( result < 0 )
  798.    {
  799.       printf("\a\nCommand \"%s\" failed completely.\n\a", command);
  800.       panic();
  801.    }
  802.  
  803.    time( & now );
  804.  
  805.    return result;
  806. } /* runCommand */
  807.  
  808. /*--------------------------------------------------------------------*/
  809. /*    n e x t p o l l                                                 */
  810. /*                                                                    */
  811. /*    Returns next time to poll in seconds                            */
  812. /*                                                                    */
  813. /*    modified 14 October 1990 By Ed Keith.                           */
  814. /*    modified 4 November 1990 by Drew Derbyshire.                    */
  815. /*--------------------------------------------------------------------*/
  816.  
  817. static time_t nextpoll( hhmm first, hhmm interval )
  818. {
  819.    time_t sfirst;
  820.    time_t sinterval = hhmm2sec( interval );
  821.    time_t today;
  822.    time_t tomorrow;
  823.    struct tm  *time_record;   /* Ed K. 10/14/1990 */
  824.  
  825.    time_record = localtime(&now); /* Ed K. 10/14/1990 */
  826.    time_record->tm_sec = 0;   /* Ed K. 10/14/1990 */
  827.    time_record->tm_min = 0;   /* Ed K. 10/14/1990 */
  828.    time_record->tm_hour= 0;   /* Ed K. 10/14/1990 */
  829.    today = mktime(time_record);
  830.  
  831. /*--------------------------------------------------------------------*/
  832. /*    We could just add hhmm2sec(2400) (24 hours) except this         */
  833. /*    doesn't work during days when we do a daylight savings          */
  834. /*    shift.  So we let the run time library compute midnight.        */
  835. /*--------------------------------------------------------------------*/
  836.  
  837.    time_record->tm_hour = 23;   /* Advance to midnight     */
  838.    time_record->tm_min  = 59;
  839.    tomorrow = mktime(time_record) + 60;   /* Add a minute to 23:59   */
  840.  
  841.    sfirst = today + hhmm2sec(first);
  842.  
  843.    while (sfirst <= now)         /* Insure we never return "now" for next */
  844.       sfirst += sinterval;
  845.  
  846. /*--------------------------------------------------------------------*/
  847. /*    Since we restart the polling of each day anew, reset the        */
  848. /*    next poll time based if it is after midnight.  Note the         */
  849. /*    funny double compare, which handles the stricter of the two     */
  850. /*    tests for "tomorrow".                                           */
  851. /*--------------------------------------------------------------------*/
  852.  
  853.    if ((sfirst > tomorrow) || (sfirst > (today + hhmm2sec(2400))))
  854.       sfirst = tomorrow + hhmm2sec(first);
  855.  
  856.    return sfirst;
  857.  
  858. } /* nextpoll */
  859.  
  860.  
  861. /*--------------------------------------------------------------------*/
  862. /*    f i r s t p o l l                                               */
  863. /*                                                                    */
  864. /*    Determine first time to poll if not specified                   */
  865. /*--------------------------------------------------------------------*/
  866.  
  867. static hhmm firstpoll(hhmm interval)
  868. {
  869.    struct tm  *time_record;
  870.    time_t sfirst;
  871.    hhmm first;
  872.  
  873.    time_record = localtime(&now);
  874.    sfirst = ((time_t) time_record->tm_hour * 3600L +
  875.              (time_t) time_record->tm_min * 60L);
  876.    sfirst  = sfirst % hhmm2sec(interval);
  877.    first = (hhmm) ((sfirst / 3600L) * 100L + (sfirst % 3600L) / 60L);
  878.  
  879.    printf("First polling time computed to be %-2.2d:%-2.2d\n",
  880.          first / 100, first % 100);
  881.  
  882.    return first;
  883.  
  884. } /* firstpoll */
  885.  
  886. /*--------------------------------------------------------------------*/
  887. /*    n o t a n u m b e r                                             */
  888. /*                                                                    */
  889. /*    Examines string, returns true if non-numeric                    */
  890. /*--------------------------------------------------------------------*/
  891.  
  892.  static boolean notanumber( char *start)
  893.  {
  894.    char *number = start;
  895.    while (*number != '\0')
  896.    {
  897.       if (!isdigit(*number))
  898.       {
  899.          printf("Parameter must be numeric, was %s\n",start);
  900.          return TRUE;
  901.       }
  902.       number++;
  903.    }
  904.    return FALSE;
  905.  } /* notanumber */
  906.  
  907.  
  908. /*--------------------------------------------------------------------*/
  909. /*    p a s s i v e                                                   */
  910. /*                                                                    */
  911. /*    Invoke UUCICO in passive mode until next active poll (if any).  */
  912. /*--------------------------------------------------------------------*/
  913.  
  914.  static int passive( time_t next,
  915.                      int debuglevel,
  916.                      const char *logname,
  917.                      const char *modem )
  918.  {
  919.    char buf[128];             /* Buffer for runCommand() commands     */
  920.    time_t seconds = (next - now + 59);
  921.    time_t minutes;
  922.    int result;
  923.  
  924.    if ( seconds > SHRT_MAX)
  925.       seconds = (SHRT_MAX / 3600) * 3600;
  926.  
  927.    minutes = seconds / 60;
  928.  
  929.    sprintf(buf,"uucico -r 0 -x %d -d %02ld%02ld",
  930.                debuglevel,
  931.                minutes / 60, minutes % 60);
  932.  
  933.    if ( logname != NULL )
  934.       strcat( strcat( buf, " -l ") , logname );
  935.  
  936.    if ( modem != NULL )
  937.       strcat( strcat( buf, " -m ") , modem );
  938.  
  939.    result = runCommand(buf, TRUE);
  940.  
  941.    printmsg(2,"passive: Return code = %d", result );
  942.    return result;
  943.  
  944.  } /* passive */
  945.  
  946. /*--------------------------------------------------------------------*/
  947. /*    u u x q t                                                       */
  948. /*                                                                    */
  949. /*    Execute the UUXQT program to run files received by UUCICO       */
  950. /*--------------------------------------------------------------------*/
  951.  
  952.  static void uuxqt( const int debuglevel, const boolean sync)
  953.  {
  954.    int result;
  955.    char buf[128];             /* Buffer for runCommand() commands     */
  956.  
  957.    sprintf(buf,"uuxqt -x %d", debuglevel);
  958.  
  959.    result = runCommand( buf, sync );
  960.  
  961.    if ( result != 0 )
  962.    {
  963.       printf("UUXQT failed with a return code of %d\n",result);
  964.       panic();
  965.    } /* if ( result != 0 ) */
  966.  
  967.    if ( ! sync )
  968.       ssleep(10);
  969.  
  970.  } /* uuxqt */
  971.  
  972. /*--------------------------------------------------------------------*/
  973. /*    C a t c h e r                                                   */
  974. /*                                                                    */
  975. /*    Catch Ctrl-Break                                                */
  976. /*--------------------------------------------------------------------*/
  977.  
  978. #ifdef __TURBOC__
  979. #pragma argsused
  980. #elif _MSC_VER >= 700
  981. #pragma warning(disable:4100)   /* suppress unref'ed formal param. warnings */
  982. #endif
  983.  
  984.  void
  985. #ifdef __TURBOC__
  986. __cdecl
  987. #endif
  988.  Catcher( int sig )
  989.  {
  990.  
  991.     safeout("uupoll: Program aborted by user\r\n");
  992.  
  993.     _exit(100);
  994.  } /* Catcher */
  995.  
  996. #if _MSC_VER >= 700
  997. #pragma warning(default:4100)   /* restore unref'ed formal param. warnings */
  998. #endif
  999.  
  1000. /*--------------------------------------------------------------------*/
  1001. /*    u s a g e                                                       */
  1002. /*                                                                    */
  1003. /*    Report correct usage of the program and then exit.              */
  1004. /*--------------------------------------------------------------------*/
  1005.  
  1006.  static void usage( char *name )
  1007.  {
  1008.  
  1009.    printf("Usage:\t%s"
  1010.           "\t[-a hhmm] [-d hhmm | -e hhmm] [-f hhmm] [-i hhmm]\n"
  1011.           "\t\t[-l logname] [-c hhmm] [-C command]\n"
  1012.           "\t\t[-r 0 | 1] [-s system] [-x n]\n",name);
  1013.    exit(4);
  1014.  
  1015.  } /* usage */
  1016.  
  1017. #if !defined(NOCBREAK) && !defined(__TURBOC__)
  1018.  
  1019. /*--------------------------------------------------------------------*/
  1020. /*    s e t c b r k                                                   */
  1021. /*                                                                    */
  1022. /*    Enable Cntrl-Break                                              */
  1023. /*                                                                    */
  1024. /*    Written by Dave Watt                                            */
  1025. /*--------------------------------------------------------------------*/
  1026.  
  1027. static int setcbrk(char state)
  1028. {
  1029.    union REGS inregs, outregs;
  1030.  
  1031.    inregs.x.ax = 0x3302;
  1032.    inregs.h.dl = state;
  1033.    intdos(&inregs, &outregs);
  1034.  
  1035.    return outregs.h.dl;
  1036.  
  1037. } /* setcbrk */
  1038.  
  1039. #endif
  1040.