home *** CD-ROM | disk | FTP | other *** search
- /*
- Program: uupoll.c 22 September 1989
- Author: Andrew H. Derbyshire
- 108 Decatur St
- Arlington, MA 02174
- Internet: help@kew.com
- Function: Performs autopoll functions for UUCICO
- Language: Borland C++ 2.0
- Usage: uupoll [-r 0] [-f hhmm] [-i hhmm|0400 ] [-d hhmm]
- [-a hhmm] [-x debug] [-s systems]
-
- Where:
-
- -r 0 specifies that UUCICO is to run into
- passive mode when waiting to poll out
-
- -r 1 specifies that UUCICO will not run in passive
- mode while waiting to poll out, but polling
- out will occur.
-
- -f hhmm is the first time in the day that uuio
- is to poll out. If omitted, polling
- begins after the interval specified with
- -i.
-
- -i hhmm the interval the UUCICO is to poll out
- at. If omitted, a period of 4 hours
- will be used.
-
- -d hhmm Terminate polling after hhmm. Default is
- not to terminate.
-
- -a hhmm Automatically poll actively using the system
- name "any" after any successfully inbound
- poll if hhmm have past since last poll. hhmm
- may be 0000.
-
- In addition, the following flags will be passed
- to UUCICO:
-
- -s system system name to poll. By default,
- UUCICO will be invoked with '-s all'
- followed by '-s any'.
-
- -x n debug level. The default level
- is 1.
-
- */
-
- #include <assert.h>
- #include <ctype.h>
- #include <dos.h>
- #include <limits.h>
- #include <process.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include <conio.h>
- #include <direct.h>
-
- #ifdef __TURBOC__
- #include <alloc.h>
- unsigned _stklen = 2048; /* Reduce memory usage */
- unsigned _heaplen = 2048; /* Reduce memory usage */
- #else
- #ifndef FAMILYAPI
- static int setcbrk(char state);
- #endif
- #endif
-
- #include "getopt.h"
- #include "lib.h"
- #include "timestmp.h"
- #include "ssleep.h"
- #ifdef DEBUG
- #define printmsg(a,b,c) /* printmsg(a,b,c) */
- #include "arpadate.h"
- #include "arpadate.c"
- #endif
-
- typedef int hhmm;
-
- #define hhmm2sec(HHMM) ((time_t)(((HHMM / 100) * 60L) + \
- (time_t)(HHMM % 100)) * 60L)
-
- static int active(char *Rmtname, int debuglevel);
- static void busywork( time_t next);
- static int execute( char *command );
- static time_t nextpoll( hhmm first, hhmm interval );
- static boolean notanumber( char *number);
- static int passive( time_t next, int debuglevel );
- static void usage( char *name );
- static hhmm firstpoll(hhmm interval);
- static void uuxqt( int debuglevel);
-
- static time_t now; /* Current time, updated at start of
- program and by busywork() and
- execute() */
-
- /*--------------------------------------------------------------------*/
- /* m a i n */
- /* */
- /* main program */
- /*--------------------------------------------------------------------*/
-
- main( int argc , char *argv[] )
- {
-
- int option;
- hhmm first = - 1;
- hhmm interval = -1;
- time_t duration = LONG_MAX;
- int nopassive = 2;
- boolean autoforward = TRUE;
- boolean done = FALSE;
- time_t autowait;
- char *Rmtname = NULL;
- int debuglevel = 1;
- int returncode = 0;
-
- #ifndef FAMILYAPI
- boolean cbrk;
- #endif
-
- banner(argv);
- tzset();
- time( &now );
-
- while((option = getopt(argc, argv, "a:d:f:i:s:r:x:")) != EOF)
- switch(option)
- {
-
- /*--------------------------------------------------------------------*/
- /* Automatically poll "any" after an incoming phone call */
- /*--------------------------------------------------------------------*/
-
- case 'a':
- autoforward = TRUE;
- if (notanumber(optarg))
- usage( argv[0] );
- autowait = hhmm2sec( atoi(optarg) );
- break;
-
- /*--------------------------------------------------------------------*/
- /* First time to poll */
- /*--------------------------------------------------------------------*/
-
- case 'f':
- if (notanumber(optarg))
- usage( argv[0] );
- first = atoi(optarg);
- if ( interval == -1 )
- interval = 400;
- break;
-
- /*--------------------------------------------------------------------*/
- /* Interval to poll */
- /*--------------------------------------------------------------------*/
-
- case 'i':
- if (notanumber(optarg))
- usage( argv[0] );
- interval = atoi(optarg);
- nopassive = min(1,nopassive);
- break;
-
- /*--------------------------------------------------------------------*/
- /* Time (duration) to poll */
- /*--------------------------------------------------------------------*/
-
- case 'd':
- if (notanumber(optarg))
- usage( argv[0] );
- duration = atoi(optarg);
- break;
-
- /*--------------------------------------------------------------------*/
- /* System name to poll */
- /*--------------------------------------------------------------------*/
-
- case 's':
- Rmtname = strdup(optarg);
- break;
-
- /*--------------------------------------------------------------------*/
- /* Debug level */
- /*--------------------------------------------------------------------*/
-
- case 'x':
- if (notanumber(optarg))
- usage( argv[0] );
- debuglevel = atoi(optarg);
- break;
-
- /*--------------------------------------------------------------------*/
- /* Passive polling option */
- /*--------------------------------------------------------------------*/
-
- case 'r':
- if (notanumber(optarg))
- usage( argv[0] );
- nopassive = atoi(optarg);
- break;
-
- /*--------------------------------------------------------------------*/
- /* Help */
- /*--------------------------------------------------------------------*/
-
- default:
- case '?':
- usage( argv[0] );
- } /* switch */
-
- /*--------------------------------------------------------------------*/
- /* Terminate with error if too many arguments */
- /*--------------------------------------------------------------------*/
-
- if (optind != argc)
- {
- puts("Extra parameters on command line.");
- usage( argv[0] );
- }
-
- /*--------------------------------------------------------------------*/
- /* Terminate if neither active polling nor passive polling requested */
- /*--------------------------------------------------------------------*/
-
- if ( nopassive == 2 && (first < 0))
- {
- puts("Must specify -r 0, -f hhmm, or -i hhmm");
- usage( argv[0] );
- }
-
- if ( (interval > 0) && (first < 0))
- first = firstpoll(interval);
-
- /*--------------------------------------------------------------------*/
- /* If running under MS-DOS, enable Cntrl-Break. */
- /*--------------------------------------------------------------------*/
-
- #ifndef FAMILYAPI
- #ifdef __TURBOC__
- cbrk = getcbrk(); /* Get original Cntrl-Break setting */
-
- if (!cbrk)
- setcbrk(1); /* Turn it on to allow abort */
- #else /*dmw*/
- cbrk = setcbrk(1); /* Turn it on to allow abort; get previous state */
- printf("BREAK ON has been set\n");
- #endif
- #endif
-
- /*--------------------------------------------------------------------*/
- /* If a quitting internal was specified, convert it to an */
- /* absolute time */
- /*--------------------------------------------------------------------*/
-
- if (duration != LONG_MAX)
- {
- duration = hhmm2sec( duration ) + (now / 60L) * 60L;
- /* Round to next lower minute */
- printf("Will terminate upon completion of first event \
- after %s", ctime(&duration));
- } /* if */
-
- /*--------------------------------------------------------------------*/
- /* Beginning of main loop */
- /*--------------------------------------------------------------------*/
-
- while ( !done && (duration > now))
- {
- time_t next = LONG_MAX;
- time_t autonext = now + autowait;
- time_t wait = 10; /* Time to wait after first panic() */
-
- if (first >= 0)
- next = nextpoll(first,interval);
- else
- next = duration;
-
- while ((now < next) && ! done )
- {
- if (nopassive)
- busywork(next);
- else {
- time_t spin;
- returncode = passive(next,debuglevel);
- if (returncode == 69 ) /* Error in UUCICO? */
- { /* Yes --> Allow time to fix it */
- spin = now + wait; /* Figure next wait */
- wait *= 2 ; /* Double wait for next time */
- busywork( spin > next ? next : spin );
- /* But only wait till next poll */
- } /* if (returncode == 69 ) */
- else {
- wait = 10;
- if ((returncode == 0) && autoforward && (now > autonext))
- {
- returncode = active("any",debuglevel);
- autonext = now + autowait;
- } /* if */
- } /* else */
-
- if ( (now > duration) && (now < next))
- done = TRUE;
- else if ( returncode == 100 )
- done = TRUE;
-
- } /* else */
-
- } /* while */
-
- if ( ! done && (first >= 0) )
- {
- returncode = active(Rmtname,debuglevel);
- if ( returncode == 100 )
- done = TRUE;
- } /* if ( ! done && (first >= 0) ) */
-
- } /* while */
-
- /*--------------------------------------------------------------------*/
- /* End of main loop */
- /*--------------------------------------------------------------------*/
-
- uuxqt( debuglevel ); /* One last call to UUXQT */
-
- #ifndef FAMILYAPI
- if (!cbrk)
- setcbrk(0); /* Restore original Cntrl-Break setting */
- #endif
-
- return(returncode);
- } /* main */
-
-
- /*--------------------------------------------------------------------*/
- /* a c t i v e */
- /* */
- /* Perform an active (outgoing) poll of other hosts */
- /*--------------------------------------------------------------------*/
-
- static active(char *Rmtname, int debuglevel)
- {
- int result;
-
- if (Rmtname == NULL) /* Default? */
- { /* Yes --> do -s all and -s any */
- if (active("all",debuglevel) < 100)
- return active("any",debuglevel);
- else
- return 100;
- }
- else {
- char buf[128];
- sprintf(buf,"uucico -r 1 -s %s -x %d",Rmtname,debuglevel);
- result = execute(buf);
- if ( result == 0 )
- uuxqt( debuglevel );
-
- return result;
- }
- } /* active */
-
- /*--------------------------------------------------------------------*/
- /* b u s y w o r k */
- /* */
- /* Waits for next time to poll without answering the telephone. */
- /* Maybe we should at least beep on the hour? :-) */
- /*--------------------------------------------------------------------*/
-
- static void busywork( time_t next)
- {
- time_t naptime;
- time_t hours, minutes, seconds;
-
- naptime = next - now;
-
- hours = (naptime / 3600) % 24; /* Get pretty time to display... */
- minutes = (naptime / 60) % 60;
- seconds = naptime % 60;
-
- printf("Going to sleep for %02ld:%02ld:%02ld, next poll is %s",
- hours, minutes, seconds, ctime(&next) );
- ssleep( naptime );
-
- time( & now );
- }
-
-
- /*--------------------------------------------------------------------*/
- /* e x e c u t e */
- /* */
- /* Executes a command via a spawn() system call. This avoids */
- /* the storage overhead of COMMAND.COM and returns the actual */
- /* return code from the command executed. */
- /* */
- /* Note that this does not allow quoted command arguments, which */
- /* not a problem for the intended argv[0]s of UUCICO. */
- /*--------------------------------------------------------------------*/
-
- static int execute( char *command )
- {
- char *argv[20];
- int argc = 0;
- int result;
- #ifdef DEBUG
- FILE *stream = NULL;
- #endif
-
- printf("Executing command: %s\n",command);
- #ifdef DEBUG /* ahd */
- stream = fopen("UUPOLL.LOG","a");
- if (stream == NULL)
- {
- perror("UUPOLL.LOG");
- abort();
- } /* if */
- fprintf(stream, "%s: %s\n",arpadate(), command);
- fclose(stream);
- #endif /* DEBUG */
-
- argv[argc] = strtok(command," \t");
-
- while ( argv[argc++] != NULL )
- argv[argc] = strtok( NULL," \t");
- result = spawnvp(P_WAIT , argv[0] , argv );
- if ( result < 0 )
- {
- printf("\a\nCommand \"%s\" failed!\n\a", argv[0]);
- abort();
- }
-
- time( & now );
- return result;
- }
-
- /*--------------------------------------------------------------------*/
- /* n e x t p o l l */
- /* */
- /* Returns next time to poll in seconds */
- /* */
- /* modified 14 October 1990 By Ed Keith. */
- /* modified 4 November 1990 by Drew Derbyshire. */
- /*--------------------------------------------------------------------*/
-
- static time_t nextpoll( hhmm first, hhmm interval )
- {
- time_t sfirst;
- time_t sinterval = hhmm2sec( interval );
- time_t today;
- time_t tomorrow;
- struct tm *time_record; /* Ed K. 10/14/1990 */
-
- time_record = localtime(&now); /* Ed K. 10/14/1990 */
- time_record->tm_sec = 0; /* Ed K. 10/14/1990 */
- time_record->tm_min = 0; /* Ed K. 10/14/1990 */
- time_record->tm_hour= 0; /* Ed K. 10/14/1990 */
- today = mktime(time_record);
- tomorrow = today + 86400;
- sfirst = today + hhmm2sec(first);
-
- while (sfirst < now)
- sfirst += sinterval;
-
- if (sfirst > tomorrow)
- sfirst = tomorrow + hhmm2sec(first);
-
- return sfirst;
- } /* nextpoll */
-
-
- /*--------------------------------------------------------------------*/
- /* f i r s t p o l l */
- /* */
- /* Determine first time to poll if not specified */
- /*--------------------------------------------------------------------*/
-
- static hhmm firstpoll(hhmm interval)
- {
- struct tm *time_record;
- time_t sfirst;
- hhmm first;
-
- time_record = localtime(&now);
- sfirst = ((time_t) time_record->tm_hour * 3600L +
- (time_t) time_record->tm_min * 60L);
- sfirst = sfirst % hhmm2sec(interval);
- first = (hhmm) ((sfirst / 3600L) * 100L + (sfirst % 3600L) / 60L);
-
- printf("First polling time computed to be %-2.2d:%-2.2d\n",
- first / 100, first % 100);
- return first;
- } /* firstpoll */
-
- /*--------------------------------------------------------------------*/
- /* n o t a n u m b e r */
- /* */
- /* Examines string, returns true if non-numeric */
- /*--------------------------------------------------------------------*/
-
- static boolean notanumber( char *start)
- {
- char *number = start;
- while (*number != '\0')
- {
- if (!isdigit(*number))
- {
- printf("Parameter must be numeric, was %s\n",start);
- return TRUE;
- }
- number++;
- }
- return FALSE;
- } /* notanumber */
-
-
- /*--------------------------------------------------------------------*/
- /* p a s s i v e */
- /* */
- /* Invoke UUCICO in passive mode until next active poll (if any). */
- /*--------------------------------------------------------------------*/
-
- static int passive( time_t next, int debuglevel )
- {
- char buf[128]; /* Buffer for execute() commands */
- int result;
- sprintf(buf,"uucico -r 0 -x %d",debuglevel);
-
- if (next > 0) /* Should we poll out? */
- { /* Yes --> Compute time to poll */
- char xnow[5]; /* Current time as a string */
- char then[5]; /* Next time to poll as a string */
- struct tm *tm_now; /* Format time in integer values */
-
- tm_now = localtime(&now); /* Get time broken down */
- sprintf(xnow,"%02d%02d", tm_now->tm_hour, tm_now->tm_min);
-
- /*--------------------------------------------------------------------*/
- /* Format the time to stop polling. Note that to have the */
- /* system actively poll at time x, we compute the window to */
- /* passively poll to end at x-1, since the passive window will */
- /* remain open until x-1 + 59 seconds. */
- /*--------------------------------------------------------------------*/
-
- if ( (next - now) > 120) /* Poll at least two minutes? */
- next--; /* Yes --> End at start of the min */
-
- tm_now = localtime(&next); /* Get time broken down */
- sprintf(then,"%02d%02d", tm_now->tm_hour, tm_now->tm_min);
- strcat(buf," -u Any");
- strcat(buf,xnow);
- strcat(buf,"-");
- strcat(buf,then);
- }
-
- result = execute(buf);
- if ( result == 0 )
- uuxqt( debuglevel );
- return result;
- } /* passive */
-
- /*--------------------------------------------------------------------*/
- /* u u x q t */
- /* */
- /* Execute the UUXQT program to run files received by UUCICO */
- /*--------------------------------------------------------------------*/
-
- static void uuxqt( int debuglevel)
- {
- int result;
- char buf[128]; /* Buffer for execute() commands */
-
- sprintf(buf,"uuxqt -x %d", debuglevel);
- result = execute(buf);
- assert( result == 0 );
- } /* uuxqt */
-
-
- /*--------------------------------------------------------------------*/
- /* u s a g e */
- /* */
- /* Report correct usage of the program and then exit. */
- /*--------------------------------------------------------------------*/
-
- static void usage( char *name )
- {
- printf("Usage:\t%s\
- \t[-a hhmm] [-d hhmm] [-f hhmm] [-i hhmm] \n\
- \t\t[-r 0 | 1] [-s system] [-x n]\n",name);
- exit(4);
- }
-
- #ifndef FAMILYAPI
- #ifndef __TURBOC__
- /*
- s e t c b r k
-
- Enable Cntrl-Break
-
- Written by Dave Watts
- */
-
- static int setcbrk(char state)
- {
- union REGS inregs, outregs;
-
- inregs.x.ax = 0x3302;
- inregs.h.dl = state;
- intdos(&inregs, &outregs);
-
- return outregs.h.dl;
- }
- #endif
- #endif
-