home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 12 / CD_ASCQ_12_0294.iso / vrac / atrgf30.zip / ATRGF.CMD next >
OS/2 REXX Batch file  |  1993-11-08  |  43KB  |  1,025 lines

  1. /*
  2. program: atrgf.cmd
  3. type:    REXXSAA-OS/2, version 2.x
  4. purpose: execute command at specified time
  5. version: 3.0
  6. date:    1991-05-24
  7. changed: 1991-07-26, RGF, streamlined the code a little bit..., added colors
  8.          1992-06-01, RGF, adapted for 32bit OS/2
  9.          1993-08-02, RGF, bug fixed on /E-switch: would not take starting day
  10.                           into account (reported by Steve Hoiness,
  11.                                         <76077.3121@compuserve.com>)
  12.          1993-09-20, RGF, changed the definition of ANSI-color-sequences; gets them from
  13.                           procedure ScrColor.CMD
  14.          1993-11-08, RGF use ANSI-color-sequences in all places;
  15.                          added black and white option (/B) to suppress ANSI-colors on output;
  16.                          added option (/M) to execute a program, if it was supposed to be
  17.                                executed between midnight and the time atrgf was invoked,
  18.                                suggested by sktoni@uta.fi (Tommi Nieminen);
  19.                          bug fixed on daynames, used date-number if daynames were given 
  20.                                individually
  21.  
  22.  
  23. author:  Rony G. Flatscher,
  24.          Wirtschaftsuniversität/Vienna
  25.          RONY@AWIWUW11.BITNET
  26.          Rony.Flatscher@wu-wien.ac.at
  27.  
  28. needs:   all RxUtil-functions loaded, DATERGF.CMD, DATE2STR.CMD, SCRCOLOR.CMD
  29.  
  30. usage:   ATRGF [/B] [/M] [/W] [/T] time command
  31.          ATRGF [/B] [/M] [/W] [/T] time /NE:dayordate command
  32.          ATRGF [/B] [/M] [/W] [/T] time /E:dayordate command
  33.          ATRGF [/B] [/M] [/W] [/T] [time] /I:time command
  34.  
  35.          see enclosed Tutorial "RGFSHOW.CMD" and syntax below
  36.  
  37.  
  38. All rights reserved, copyrighted 1991-1993, no guarantee that it works without
  39. errors, etc. etc.
  40.  
  41. donated to the public domain granted that you are not charging anything (money
  42. etc.) for it and derivates based upon it, as you did not write it,
  43. etc. if that holds you may bundle it with commercial programs too
  44.  
  45. you may freely distribute this program, granted that no changes are made
  46. to it and that the accompanying tutorial "RGFSHOW.CMD" is being distributed
  47. together with ATRGF.CMD, DATERGF.CMD, DATE2STR.CMD, SCRCOLOR.CMD, TIMEIT.CMD
  48.  
  49. Please, if you find an error, post me a message describing it, I will
  50. try to fix and rerelease it to the net.
  51.  
  52. procedures:
  53.     CHECK_TIME          check and parse time into hh:mm
  54.     SHOW_DURATION       show duration of command
  55.     DURATION            format elapsed seconds into time
  56.     NEXT_DATE           produce next date
  57.     NEXT_DAY            produce next week-day
  58.     SCHEDULE_IT         schedule command
  59.     SHOW_SLEEP_EXECUTE  show next invocation, sleep until it and execute command
  60.  
  61.  
  62. usage:   ATRGF [/W] [/T] [/B] [/M] time command
  63.          ATRGF [/W] [/T] [/B] [/M] time /NE:dayordate command
  64.          ATRGF [/W] [/T] [/B] [/M] time /E:dayordate command
  65.          ATRGF [/W] [/T] [/B] [/M] [time] /I:time command
  66.  
  67. syntax:
  68.     COMMAND ..... any command as entered thru the keyboard to start
  69.                   a program
  70.     TIME ........ on input 24hour- (military) or 12hour-format allowed,
  71.                   output will be allways in 24hour-format (military, computer)
  72.     DAYORDATE ... DAY[-DAY]|DATE[-DATE][,...]
  73.                   DAY .... 2 letter digit (MO, TU, WE, TH, FR, SA, SU)
  74.                   DATE ... 1-2 digits (1-31)
  75.                   more than one day or date must be delimited by a comma
  76.  
  77. flags:
  78.     /W  ......... execute ATRGF.CMD in a separate Window
  79.     /T  ......... Testmode
  80.     /B  ......... show output in black and white (don't attach ANSI-color-codes
  81.                   to strings)
  82.     /M  ......... execute command, if it can be scheduled between midnight and
  83.                   time of first invocation of ATRGF
  84.  
  85.     /NE: ........ NExt dayordate
  86.     /E:  ........ Every dayordate
  87.     /I:  ........ every time-Interval
  88.  
  89. */
  90.  
  91. SIGNAL ON HALT
  92. SIGNAL ON ERROR
  93. SIGNAL ON FAILURE    NAME ERROR
  94. SIGNAL ON NOTREADY   NAME ERROR
  95. SIGNAL ON NOVALUE    NAME ERROR
  96. SIGNAL ON SYNTAX     NAME ERROR
  97.  
  98. /* check whether RxFuncs are loaded, if not, load them */
  99. IF RxFuncQuery('SysLoadFuncs') THEN
  100. DO
  101.     /* load the load-function */
  102.     CALL RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'       
  103.  
  104.     /* load the Sys* utilities */
  105.     CALL SysLoadFuncs                                                 
  106. END
  107.  
  108. glob. = ''                      /* default for empty subscripts */
  109.  
  110. /* analyse switches */
  111. arg_1 = ARG(1)
  112.  
  113. switches = " "
  114. /* four optional switches to checked for */
  115. DO 4                            
  116.    tmp = arg_1
  117.    PARSE VAR arg_1 left "/"switch arg_1
  118.    switch_char = LEFT(TRANSLATE(switch), 1)
  119.  
  120.    IF left <> "" | switch_char = "I" THEN
  121.    DO
  122.       arg_1 = tmp
  123.       LEAVE
  124.    END
  125.    switches = switches || switch_char
  126. END 
  127.  
  128. /* check whether switches are valid */
  129. IF VERIFY(switches, "BMWT ") <> 0 THEN
  130.    CALL stop_it "unknown switch in [" || ARG(1) || "]."
  131.  
  132. switch_text = ""
  133.  
  134. IF POS("B", switches) > 0 THEN          /* only black and white output, no colors */
  135.    switch_text = switch_text "/B"
  136. ELSE
  137. DO
  138.    /* get screen-colors */
  139.    PARSE VALUE ScrColor() WITH glob.eScrNorm    glob.eScrInv,
  140.                                glob.eTxtNorm    glob.eTxtInf,
  141.                                glob.eTxtHi      glob.eTxtAla,
  142.                                glob.eTxtNormInv glob.eTxtInfInv,
  143.                                glob.eTxtHiInv   glob.eTxtAlaInv .
  144. END
  145.  
  146.  
  147. /* sleep & execute command in a separate window ? */
  148. bExecuteInSeparateWindow = (POS("W", switches) > 0)
  149.  
  150.  
  151. /* execute command once if it could be scheduled in between midnight and time of
  152.    starting ATRGF ? */
  153. glob.bExecuteIfBetweenMidnightAndNow = (POS("M", switches) > 0)
  154.  
  155.  
  156. /* switch to testmode ? */
  157. glob.bTestmode = (POS("T", switches) > 0)
  158. IF glob.bTestmode THEN
  159.    switch_text = switch_text "/T"
  160.  
  161.  
  162. IF arg_1 = '' | arg_1 = '?' THEN SIGNAL usage
  163.  
  164. /* defaults */
  165. glob.executions = 0                            /* number of executions so far */
  166. glob.format_date = "%yyyy-%mm-%dd"             /* format string for dates */
  167. glob.daynames = "MO TU WE TH FR SA SU"         /* valid daynames */
  168.  
  169. glob.argument = STRIP(arg_1)                   /* get rid of leading & trailing blanks */
  170. glob.argument.upp = TRANSLATE(glob.argument)  /* get arguments in uppercase    */
  171.  
  172. CALL say_c
  173.  
  174. IF bExecuteInSeparateWindow THEN
  175. DO                       /* TITLE:     */
  176.    '@START /C /WIN /MIN  "ATRGF 'ARG(1)'" /PGM atrgf' switch_text arg_1  /* start a new window */
  177.    EXIT        /* end the program */
  178. END
  179.  
  180. CALL proceed
  181. EXIT
  182. /*  end of main-routine */
  183.  
  184.  
  185.  
  186. /******************************************/
  187. /* parse time, additional switch, command */
  188. PROCEED: PROCEDURE EXPOSE glob. 
  189.  
  190.     word1 = WORD(glob.argument.upp, 1)
  191.     
  192.     PARSE VAR word1 hours ':' minutes
  193.     time_in_hand = (DATATYPE(hours,'N'))    /* First argument a time-argument? */
  194.     
  195.     IF time_in_hand THEN
  196.        glob.eTim =  check_time(word1)            /* check time & get 24hourformat */
  197.     ELSE
  198.     DO /* no time given, therefore interval, starting immediately */
  199.        IF POS("/I:", word1) = 0 THEN
  200.           CALL stop_it  "wrong syntax; '/I:' expected."
  201.     END
  202.     
  203.     /* prepare initialization data */
  204.     /* get current date and time */
  205.     PARSE VALUE DATE("S") TIME("L") WITH glob.eStart.eDat glob.eStart.eTim
  206.     
  207.     IF glob.bExecuteIfBetweenMidnightAndNow THEN
  208.     DO
  209.        glob.eStartOriginal.eDat = glob.eStart.eDat
  210.        glob.eStartOriginal.eTim = glob.eStart.eTim
  211.     
  212.        tmp = DATERGF(DATE("S"), "-", DATERGF("1", "SECR"))
  213.        PARSE VAR tmp glob.eLast.eDat glob.eLast.eTim
  214.        glob.eStart.eDat = glob.eLast.eDat 
  215.        glob.eStart.eTim = glob.eLast.eTim 
  216.     END
  217.     ELSE
  218.     DO
  219.        glob.eLast.eDat = glob.eStart.eDat
  220.        glob.eLast.eTim = glob.eStart.eTim
  221.     END
  222.     
  223.     word2 = WORD(glob.argument.upp,2)     /* get parameter, if any */
  224.     
  225.     SELECT
  226.        WHEN (POS("/I:", word2) > 0) | \time_in_hand THEN    /* Interval ? */
  227.             DO
  228.                glob.type = 1
  229.                PARSE VAR glob.argument.upp . "/I:" glob.interval .
  230.                PARSE VAR glob.argument . "/" . glob.command
  231.                glob.interval = check_time(glob.interval)
  232.     
  233.                /* decimal fraction of interval */
  234.                glob.interval.fract = DATERGF(glob.interval, "F")
  235.     
  236.                IF glob.eTim = '' THEN         /* no start time given = start immediately */
  237.                DO
  238.                    tmp = DATERGF(glob.eStart.eDat glob.eStart.eTim, "+", glob.interval.fract)
  239.                    glob.eNext.eDat = WORD(tmp, 1)
  240.     
  241.                    IF WORDS(tmp) > 1 THEN glob.eNext.eTim = SUBSTR(WORD(tmp, 2),1,5)
  242.                    ELSE glob.eNext.eTim = "00:00"
  243.                END
  244.                ELSE      /* starting time is given */
  245.                DO
  246.                    IF glob.eStart.eTim > glob.eTim THEN /* start tomorrow, as it is already later than specified time */
  247.                    DO
  248.                       glob.eNext.eDat = DATERGF(glob.eStart.eDat, "+", 1)
  249.                       glob.eNext.eTim = glob.eTim
  250.                    END
  251.                    ELSE     /* start today at specified time */
  252.                    DO
  253.                       glob.eNext.eDat = glob.eStart.eDat
  254.                       glob.eNext.eTim = glob.eTim
  255.                    END
  256.                END
  257.     
  258.                CALL schedule_it
  259.             END
  260.     
  261.        WHEN (POS("/NE:", word2) > 0) THEN   /* start on next date_or_day ? */
  262.             DO
  263.                glob.type = 2
  264.                PARSE VAR glob.argument.upp . "/NE:" dayordate .
  265.                PARSE VAR glob.argument . "/" . glob.command
  266.     
  267.                IF DATATYPE(dayordate, 'N') THEN     /* numeric */
  268.                   IF dayordate < 1 | dayordate > 31 THEN
  269.                       CALL stop_it  dayordate": invalid day-number for date"
  270.                   ELSE
  271.                   DO
  272.                        glob.eNext_date = dayordate % 1    /* get rid of leading 0 */
  273.                        glob.eNext_date_string = glob.eNext_date /* string to show */
  274.                        glob.eNext_date_no = 1             /* no. of dates */
  275.                        glob.eNext.eDat = next_date(glob.eNext_date_no, glob.eLast.eDat)
  276.                   END
  277.                ELSE         /* weekday given */
  278.                DO
  279.                    dayindex = WORDPOS(dayordate, glob.daynames)
  280.                    IF dayindex = 0 THEN
  281.                       CALL stop_it  dayordate": invalid dayname"
  282.  
  283.                    glob.eNext_day = dayindex
  284.                    glob.eNext_day_string = dayordate     /* string to show */
  285.                    glob.eNext_day_no = 1                 /* no. of days */
  286.                    glob.eNext.eDat = next_day(glob.eNext_day_no, glob.eLast.eDat)
  287.                END
  288.     
  289.                glob.eNext.eTim = glob.eTim
  290.     
  291.                CALL schedule_it
  292.                CALL show_duration
  293.             END
  294.     
  295.        WHEN (POS("/E:", word2) > 0) THEN    /* start on every date_or_day ? */
  296.             DO
  297.                glob.type = 3
  298.                PARSE VAR glob.argument.upp . "/E:" dayordate .
  299.                PARSE VAR glob.argument . "/" . glob.command
  300.     
  301.                /* Parse days or dates to execute command */
  302.                DO WHILE dayordate <> ''
  303.                   PARSE VAR dayordate tmp1 ',' dayordate
  304.                   PARSE VAR tmp1 day_start '-' day_end
  305.     
  306.                   /* day or date ? */
  307.                   IF DATATYPE(day_start, 'N') THEN     /* numeric */
  308.                   DO
  309.                      IF day_start < 1 | day_start > 31 THEN
  310.                          CALL stop_it  day_start": invalid date"
  311.  
  312.                      data_type = 1          /* date */
  313.                   END
  314.                   ELSE      /* weekday in hand */
  315.                   DO
  316.                      IF WORDPOS(day_start, glob.daynames) = 0 THEN
  317.                         CALL stop_it  day_start": invalid dayname"
  318.  
  319.                      data_type = 2          /* day */
  320.                   END
  321.     
  322.                   IF day_end = '' THEN      /* no interval */
  323.                   DO
  324.                      IF data_type = 1 THEN  /* date in hand */
  325.                      DO
  326.                         tmp = day_start % 1         /* get rid of possible leading 0 */
  327.                         glob.tmp = 'x'             /* next invocation */
  328.                      END
  329.                      ELSE                   /* dayname in hand */
  330.                      DO
  331.                         tmp = day_start             /* keep day-name, bugfix */
  332.                         glob.tmp = 'x'             /* next invocation on dayname */
  333.                      END
  334.                   END
  335.                   ELSE           /* interval in hand */
  336.                   DO
  337.                      IF data_type = 1 THEN       /* first token was a date: 1-31 */
  338.                      DO
  339.                         IF \DATATYPE(day_end, 'N') | day_end < 1 | day_end > 31 THEN
  340.                                CALL stop_it  day_start'-'day_end": invalid date"
  341.     
  342.                         IF day_end < day_start THEN         /* wrap around end of month ? */
  343.                         DO
  344.     
  345.                            day_start = day_start % 1            /* get rid of leading 0 */
  346.                            DO WHILE day_start < 32
  347.                               glob.day_start = 'x'           /* next invocation */
  348.                               day_start = day_start + 1
  349.                            END
  350.                            day_start = 1
  351.                         END
  352.     
  353.                         day_start = day_start % 1      /* get rid of leading 0 */
  354.                         DO WHILE day_start <= day_end
  355.                            glob.day_start = 'x'       /* next invocation */
  356.                            day_start = day_start + 1
  357.                         END
  358.                      END
  359.                      ELSE                /* first token was a day: MO-SU */
  360.                      DO
  361.                         dayindex_end = WORDPOS(day_end, glob.daynames)
  362.                         IF dayindex_end = 0 THEN
  363.                            CALL stop_it  day_start'-'day_end": invalid dayname"
  364.  
  365.                         dayindex_start = WORDPOS(day_start, glob.daynames)
  366.     
  367.                         IF dayindex_end < dayindex_start THEN    /* wrap around end of week ? */
  368.                         DO
  369.                            DO WHILE dayindex_start < 8
  370.                               tmp = WORD(glob.daynames, dayindex_start)
  371.                               glob.tmp = 'x'    /* next invocation */
  372.                               dayindex_start = dayindex_start + 1
  373.                            END
  374.                            dayindex_start = 1
  375.                         END
  376.     
  377.                         DO WHILE dayindex_start <= dayindex_end
  378.                            tmp = WORD(glob.daynames, dayindex_start)
  379.                            glob.tmp = 'x'       /* next invocation */
  380.                            dayindex_start = dayindex_start + 1
  381.                         END
  382.                      END
  383.                   END
  384.                END
  385.     
  386.                /* prepare ordered demo-values and invocation string */
  387.                /* prepare ordered invocation days */
  388.                glob.eNext_day_no = 0
  389.                DO i = 1 TO 7
  390.                   tmp = WORD(glob.daynames, i)
  391.                   IF glob.tmp <> '' THEN
  392.                   DO
  393.                      IF glob.eNext_day <> '' THEN
  394.                      DO
  395.                         glob.eNext_day = glob.eNext_day i
  396.                         glob.eNext_day_string = glob.eNext_day_string', 'tmp
  397.                      END
  398.                      ELSE   /* first day-element */
  399.                      DO
  400.                         glob.eNext_day = i
  401.                         glob.eNext_day_string = tmp      /* string to show */
  402.                      END
  403.                      glob.eNext_day_no = glob.eNext_day_no + 1
  404.                   END
  405.                END
  406.                IF glob.eNext_day_no = 0 THEN glob.eNext_day_no = ''
  407.     
  408.                /* prepare ordered invocation dates */
  409.                glob.eNext_date_no = 0
  410.                DO i = 1 TO 31
  411.                   IF glob.i <> '' THEN
  412.                   DO
  413.                      IF glob.eNext_date <> '' THEN
  414.                      DO
  415.                         glob.eNext_date = glob.eNext_date i
  416.                         IF (value_inhand + 1) = i THEN
  417.                             value_inhand = i
  418.                         ELSE
  419.                         DO
  420.                            IF value_last_used <> value_inhand THEN
  421.                            DO
  422.                               glob.eNext_date_string = glob.eNext_date_string||'-'||value_inhand||', '||i
  423.                               value_inhand = i
  424.                               value_last_used = i
  425.                            END
  426.                            ELSE
  427.                            DO
  428.                               glob.eNext_date_string = glob.eNext_date_string||', '||i
  429.                               value_inhand = i
  430.                               value_last_used = i
  431.                            END
  432.                         END
  433.                      END
  434.                      ELSE   /* first date-element */
  435.                      DO
  436.                         glob.eNext_date = i
  437.                         glob.eNext_date_string = i       /* string to show */
  438.                         value_inhand = i
  439.                         value_last_used = i
  440.                      END
  441.                      glob.eNext_date_no = glob.eNext_date_no + 1
  442.                   END
  443.                END
  444.     
  445.                IF glob.eNext_date_no = 0 THEN glob.eNext_date_no = ''
  446.                ELSE
  447.                   IF value_last_used <> value_inhand THEN     /* interval left ? */
  448.                   DO
  449.                      glob.eNext_date_string = glob.eNext_date_string||'-'||value_inhand
  450.                      value_inhand = 0
  451.                   END
  452.     
  453.                CALL schedule_it
  454.             END
  455.     
  456.        OTHERWISE                            /* start once on given time ? */
  457.             DO
  458.                glob.type = 4
  459.                PARSE VAR glob.argument . glob.command
  460.     
  461.                CALL schedule_it
  462.                CALL show_duration
  463.             END
  464.     END
  465.     
  466.     RETURN
  467. /* end of PROCEED routine ********************************************************/
  468.  
  469.  
  470.  
  471. /* parse & check time, return 24hour clock */
  472. CHECK_TIME: PROCEDURE EXPOSE glob. 
  473.     PARSE UPPER ARG tmp
  474.     time24 = 1                  /* starting with 24 hour time in mind */
  475.     time12 = POS('M', tmp)      /* AM or PM ? */
  476.     IF time12 > 0 THEN
  477.     DO
  478.       time24 = 0                /* 12 hour time in hand */
  479.       letter = SUBSTR(tmp, time12 - 1, 1)
  480.       IF \((letter = 'A') | letter = 'P') THEN
  481.          CALL stop_it  ARG(1)': not a valid AM/PM-time'
  482.  
  483.       tmp = SUBSTR(tmp, 1, time12 - 2)  /* remove ?M */
  484.     END
  485.  
  486.     PARSE VAR tmp hours ':' minutes ':' seconds
  487.  
  488.     SELECT
  489.       WHEN hours = '' THEN hours = 0
  490.  
  491.       WHEN \datatype(hours,'N') THEN     /* no numeric type */
  492.               CALL stop_it  ARG(1)": hours are not numeric"
  493.  
  494.       WHEN (hours < 0) | (hours > 23) THEN      /* out of range    */
  495.               CALL stop_it  ARG(1)": hours out of range"
  496.  
  497.       OTHERWISE NOP
  498.     END
  499.  
  500.     SELECT
  501.       WHEN minutes = '' THEN minutes = 0
  502.  
  503.       WHEN \datatype(minutes,'N') THEN     /* no numeric type */
  504.               CALL stop_it  ARG(1)": minutes are not numeric"
  505.  
  506.       WHEN (minutes < 0) | (minutes > 59) THEN /* out of range    */
  507.               CALL stop_it  ARG(1)": minutes out of range"
  508.  
  509.       OTHERWISE NOP
  510.     END
  511.  
  512.     /* ignore seconds, if any */
  513.  
  514.     IF \time24 THEN             /* received a 12hour time, adjust it to 24hour time */
  515.     DO
  516.        IF (letter = 'A') & (hours = 12) THEN hours = 0
  517.        ELSE IF ((letter = 'P') & (hours < 12)) THEN hours = hours + 12
  518.     END
  519.  
  520.     RETURN RIGHT(hours,2,'0')':'RIGHT(minutes,2,'0')
  521. /* end of CHECK_TIME **********************************************************/
  522.  
  523.  
  524.  
  525. /* produce next date for /NE: or /E: flags */
  526. NEXT_DATE:
  527.     date_index = ARG(1)         /* index for date-string */
  528.     last_dat = ARG(2)           /* last date to look-up */
  529.     date_index = date_index + 1
  530.  
  531.     IF date_index > glob.eNext_date_no THEN
  532.        date_index = 1
  533.  
  534.     next_dat_to_produce = WORD(glob.eNext_date, date_index)
  535.  
  536.     digits = SUBSTR(last_dat, 7, 2)
  537.     eom = SUBSTR(DATERGF(last_dat, "ME"), 7, 2)
  538.  
  539.     /* already last date of month in hand ? If so, next month must be chosen */
  540.     IF digits = eom THEN digits = 99    /* already last date of month in hand ?*/
  541.  
  542.     /* next date within same month ? */
  543.     IF digits < next_dat_to_produce THEN
  544.     DO
  545.         /* already last date in month ? */
  546.         IF next_dat_to_produce < eom THEN       /* o.k. for producing new date */
  547.            result = SUBSTR(last_dat, 1, 6) || RIGHT(next_dat_to_produce,2,'0')
  548.         ELSE                                    /* date is last day of month */
  549.            result = SUBSTR(last_dat, 1, 6) || eom
  550.     END
  551.     ELSE      /* date of following month */
  552.     DO
  553.        tmp = DATERGF(last_dat, "ME", "1")       /* first date of next month */
  554.        last_day = DATERGF(tmp, "ME")            /* end of next month */
  555.  
  556.        IF next_dat_to_produce < SUBSTR(last_day, 7, 2) THEN
  557.             result = SUBSTR(tmp, 1, 6) || RIGHT(next_dat_to_produce,2,'0')
  558.        ELSE result = last_day
  559.     END
  560.  
  561.     RETURN result               /* return next date and actual date_index */
  562. /* end of NEXT_DATE ***********************************************************/
  563.  
  564.  
  565.  
  566. /* produce next day for /NE: or /E: flags */
  567. NEXT_DAY:
  568.     day_index = ARG(1)          /* index for date-string */
  569.     last_dat = ARG(2)
  570.     day_index = day_index + 1
  571.  
  572.     IF day_index > glob.eNext_day_no THEN
  573.        day_index = 1
  574.  
  575.     next_day_to_produce = WORD(glob.eNext_day, day_index)
  576.  
  577.     IF DATERGF(last_dat, "DI") < next_day_to_produce THEN
  578.        result = DATERGF(last_dat, "WB", next_day_to_produce-1)
  579.     ELSE
  580.        result = DATERGF(last_dat, "WE", next_day_to_produce)
  581.  
  582.     RETURN result               /* return next date and actual day_index */
  583. /* end of NEXT_DAY ************************************************************/
  584.  
  585.  
  586.  
  587.  
  588. /* show-duration, if execution just took place once */
  589. SHOW_DURATION: PROCEDURE EXPOSE glob. 
  590.     CALL say_c
  591.     IF glob.bTestmode = 0 THEN
  592.     DO
  593.        CALL say_c " execution started:" glob.eTxtHi || RIGHT(DATERGF(glob.eLast.eDat, "DN")||',',12),
  594.             DATE2STR(glob.eLast.eDat, glob.format_date) SUBSTR(glob.eLast.eTim,1,5)
  595.  
  596.        tmp = "   execution ended:" || glob.eTxtHi   
  597.        IF glob.eLast.eDat <> glob.eEnded.eDat THEN
  598.           tmp = tmp RIGHT(DATERGF(glob.eEnded.eDat, "DN")||',',12) DATE2STR(glob.eEnded.eDat, glob.format_date)
  599.        ELSE
  600.           tmp = tmp RIGHT('',12) RIGHT('', LENGTH(DATE2STR(glob.eEnded.eDat, glob.format_date)))
  601.  
  602.        CALL say_c tmp  SUBSTR(glob.eEnded.eTim,1,5) glob.eTxtInf || "(duration:" glob.eTxtHi ||,
  603.             glob.eEnded.eDuration || glob.eTxtInf || ")"
  604.     END
  605.     ELSE
  606.     DO
  607.        x = glob.eTxtHi || RIGHT('',12) 'ATRGF: *** Test mode ***'
  608.        tmp = " execution started:"
  609.        CALL say_c tmp x
  610.        tmp = "   execution ended:"
  611.        CALL say_c tmp x
  612.     END
  613.     RETURN
  614. /* end of SHOW_DURATION ******************************************************/
  615.  
  616.  
  617.  
  618.  
  619. /* format elapsed seconds into time DURATION */
  620. CALC_DURATION: PROCEDURE EXPOSE glob. 
  621.  
  622.     fraction = DATERGF(ARG(1), "SECR")
  623.  
  624.     IF fraction >= 1 THEN tmp = fraction % 1 glob.eTxtInf || "day(s)" glob.eTxtHi || DATERGF(DATERGF(ARG(1), "SECR"), "FR")
  625.     ELSE tmp = DATERGF(DATERGF(ARG(1), "SECR"), "FR")
  626.  
  627.     RETURN tmp
  628. /* end of duration ************************************************************/
  629.  
  630.  
  631.  
  632.  
  633. /* calculate waiting time, before executing command */
  634. SCHEDULE_IT: PROCEDURE EXPOSE glob. 
  635.     SELECT
  636.        WHEN glob.type = 1 THEN      /* interval */
  637.             DO FOREVER
  638.                IF glob.bTestmode = 0 THEN
  639.                   glob.eTo_wait_sec = DATERGF(glob.eNext.eDat glob.eNext.eTim, "-S", DATE("S") TIME("L"))
  640.                ELSE
  641.                   glob.eTo_wait_sec = DATERGF(glob.eNext.eDat glob.eNext.eTim, "-S", glob.eLast.eDat glob.eLast.eTim)
  642.  
  643.                nul = TIME("R")                          /* reset timer */
  644.  
  645.                /* increment next execution until seconds to wait become positive */
  646.                DO WHILE glob.eTo_wait_sec < 0 & glob.bTestmode = 0
  647.                   tmp = DATERGF(glob.eNext.eDat glob.eNext.eTim, "+", glob.interval.fract)
  648.                   glob.eNext.eDat = WORD(tmp, 1)       /* get next date */
  649.  
  650.                   IF WORDS(tmp) > 1 THEN glob.eNext.eTim = SUBSTR(WORD(tmp, 2),1,5) /* get next time */
  651.                   ELSE glob.eNext.eTim = "00:00"
  652.  
  653.                   glob.eTo_wait_sec = DATERGF(glob.eNext.eDat glob.eNext.eTim, "-S", DATE("S") TIME("L"))
  654.                   nul = TIME("R")                       /* reset timer */
  655.                END
  656.  
  657.                glob.eTo_wait_sec = DATERGF(glob.eTo_wait_sec,"SEC")
  658.                CALL show_sleep_execute
  659.  
  660.                tmp = DATERGF(glob.eLast.eDat glob.eLast.eTim, "+", glob.interval.fract)
  661.                glob.eNext.eDat = WORD(tmp, 1)          /* get date */
  662.  
  663.                IF WORDS(tmp) > 1 THEN glob.eNext.eTim = SUBSTR(WORD(tmp, 2),1,5)  /* get next time */
  664.                ELSE glob.eNext.eTim = "00:00"
  665.             END
  666.  
  667.        WHEN glob.type = 2 THEN      /* Next day or date */
  668.             DO
  669.                IF glob.bTestmode = 0 THEN
  670.                   glob.eTo_wait_sec = DATERGF(DATERGF(glob.eNext.eDat glob.eNext.eTim, "-S", DATE("S") TIME("L")), "SEC")
  671.                ELSE
  672.                   glob.eTo_wait_sec = DATERGF(DATERGF(glob.eNext.eDat glob.eNext.eTim, "-S", glob.eLast.eDat glob.eLast.eTim), "SEC")
  673.  
  674.                nul = TIME("R")
  675.                CALL show_sleep_execute
  676.             END
  677.  
  678.        WHEN glob.type = 3 THEN      /* every given day or date */
  679.             DO
  680.                dates_todo = glob.eNext_date_no > 0
  681.                days_todo = glob.eNext_day_no > 0
  682.  
  683.                glob.eNext.eTim = glob.eTim            /* standard execution time */
  684.  
  685.                x1 = glob.eLast.eDat
  686.  
  687.                IF \glob.bExecuteIfBetweenMidnightAndNow THEN
  688.                   x1 = datergf(x1, "-", 1)              /* make sure, that invocation is possible on same day too */
  689.  
  690.                DO FOREVER
  691.                   IF dates_todo THEN    /* find first date after present one */
  692.                   DO
  693.                      di = DATERGF(x1, "D")              /* get day-portion of date */
  694.  
  695.                      /* if already last day of month, set index to last element */
  696.                      IF SUBSTR(DATERGF(x1, "ME"), 7,2) = di THEN
  697.                         tmp = glob.eNext_date_no
  698.                      ELSE
  699.                      DO                                 /* search for next date to produce */
  700.                         tmp = 1
  701.  
  702.                         DO FOREVER
  703.                            tmp0 = WORD(glob.eNext_date, tmp)
  704.                            IF tmp0 = '' | tmp0 > di THEN LEAVE
  705.                            tmp = tmp + 1
  706.                         END
  707.                         tmp = tmp - 1
  708.                      END
  709.  
  710.                      tmp1_date = next_date(tmp, x1)
  711.                   END
  712.                   ELSE tmp1_date = "99991231"
  713.  
  714.                   IF days_todo THEN                     /* find first date after present one */
  715.                   DO
  716.                      di = DATERGF(x1, "DI")
  717.                      tmp = 1
  718.  
  719.                      DO FOREVER
  720.                         tmp0 = WORD(glob.eNext_day, tmp)
  721.                         IF tmp0 = '' | tmp0 > di THEN LEAVE
  722.                         tmp = tmp + 1
  723.                      END
  724.                      tmp = tmp - 1
  725.  
  726.                      tmp2_date = next_day(tmp, x1)
  727.                   END
  728.                   ELSE tmp2_date = "99991231"
  729.  
  730.                   IF tmp1_date <= tmp2_date THEN        /* next to schedule: date */
  731.                       glob.eNext.eDat = tmp1_date
  732.                   ELSE                                  /* next to schedule: day */
  733.                       glob.eNext.eDat = tmp2_date
  734.  
  735.                   IF glob.bTestmode = 0 THEN           /* do it for real ? */
  736.                      glob.eTo_wait_sec = DATERGF(glob.eNext.eDat glob.eNext.eTim, "-S", DATE("S") TIME("L"))
  737.                   ELSE                                  /* test ATRGF, show next invocation */
  738.                      glob.eTo_wait_sec = DATERGF(glob.eNext.eDat glob.eNext.eTim, "-S", glob.eLast.eDat glob.eLast.eTim)
  739.  
  740.                   nul = TIME("R")                       /* reset timer */
  741.  
  742.                   IF glob.eTo_wait_sec < 0 THEN        /* execution lasted longer than next scheduled date! */
  743.                      x1 = glob.eNext.eDat              /* get next date to execute */
  744.                   ELSE
  745.                   DO
  746.                      glob.eTo_wait_sec = DATERGF(glob.eTo_wait_sec, "SEC")
  747.                      CALL show_sleep_execute
  748.                      x1 = glob.eLast.eDat
  749.                   END
  750.                END
  751.  
  752.             END
  753.  
  754.        OTHERWISE                     /* today or the next day */
  755.             DO
  756.                glob.eNext.eTim = glob.eTim
  757.  
  758.                IF glob.eNext.eTim <= glob.eLast.eTim THEN /* execution on next day */
  759.                   glob.eNext.eDat = DATERGF(glob.eStart.eDat, "+", 1)
  760.                ELSE
  761.                   glob.eNext.eDat = glob.eStart.eDat      /* execution on same day */
  762.  
  763.                glob.eTo_wait_sec = DATERGF(DATERGF(glob.eNext.eDat glob.eNext.eTim, "-S", DATE("S") TIME("L")), "SEC")
  764.                nul = TIME("R")
  765.  
  766.                CALL show_sleep_execute
  767.             END
  768.     END
  769.     RETURN
  770. /* end of SCHEDULE_IT *********************************************************/
  771.  
  772.  
  773.  
  774.  
  775. /* show time-table, sleep & execute passed command */
  776. SHOW_SLEEP_EXECUTE: PROCEDURE EXPOSE glob. 
  777.     CALL say_c
  778.  
  779.     IF glob.bExecuteIfBetweenMidnightAndNow THEN
  780.     DO
  781.        CALL say_c "           started:" glob.eTxtHi || RIGHT(DATERGF(glob.eStartOriginal.eDat, "DN")||',',12),
  782.                               DATE2STR(glob.eStartOriginal.eDat, glob.format_date) glob.eStartOriginal.eTim
  783.        CALL say_c glob.eTxtAla || "           switch:  /M, therefore pretending:"
  784.     END
  785.  
  786.  
  787.     CALL say_c "           started:" glob.eTxtHi || RIGHT(DATERGF(glob.eStart.eDat, "DN")||',',12),
  788.                            DATE2STR(glob.eStart.eDat, glob.format_date) glob.eStart.eTim
  789.  
  790.     IF glob.eStart.eDat <> glob.eLast.eDat | glob.eStart.eTim <> glob.eLast.eTim THEN
  791.     DO
  792.        CALL say_c
  793.        CALL say_c "    last execution:" glob.eTxtHi || RIGHT(DATERGF(glob.eLast.eDat, "DN")||',',12),
  794.                 DATE2STR(glob.eLast.eDat, glob.format_date) SUBSTR(glob.eLast.eTim,1,5) 
  795.  
  796.        IF glob.bTestmode = 0 THEN
  797.        DO
  798.           tmp = "   execution ended:"
  799.           IF glob.eLast.eDat <> glob.eEnded.eDat THEN
  800.              tmp2 = RIGHT(DATERGF(glob.eEnded.eDat, "DN")||',',12) DATE2STR(glob.eEnded.eDat, glob.format_date)
  801.           ELSE
  802.              tmp2 = RIGHT('',12) RIGHT('', LENGTH(DATE2STR(glob.eEnded.eDat, glob.format_date)))
  803.  
  804.           tmp = tmp glob.eTxtHi || tmp2
  805.           CALL say_c tmp  SUBSTR(glob.eEnded.eTim,1,5) glob.eTxtInf || "(duration:",
  806.                    glob.eTxtHi || glob.eEnded.eDuration || glob.eTxtInf || ")"
  807.        END
  808.        ELSE
  809.        DO
  810.           x = RIGHT('',12) '*** Test mode ***'
  811.           tmp = " execution started:"
  812.           CALL say_c tmp x
  813.           tmp = "   execution ended:"
  814.           CALL say_c tmp x
  815.        END
  816.     END
  817.  
  818.     CALL say_c
  819.     CALL say_c "    next execution:" glob.eTxtHi || RIGHT(DATERGF(glob.eNext.eDat, "DN") || ',',12),
  820.              DATE2STR(glob.eNext.eDat, glob.format_date) glob.eNext.eTim 
  821.  
  822.     IF glob.bExecuteIfBetweenMidnightAndNow THEN
  823.        glob.eTo_wait_sec = 0
  824.  
  825.     tmp = calc_duration(glob.eTo_wait_sec)
  826.  
  827.     CALL say_c "      time to wait:" RIGHT("",12) glob.eTxtHi || tmp 
  828.     CALL say_c
  829.  
  830.     tmp = glob.eTxtAla
  831.     IF glob.type = 2 THEN           /* NEXT-date */
  832.        tmp = tmp || RIGHT("on next",12)
  833.     ELSE                             /* EVERY-date */
  834.        tmp = tmp || RIGHT("on EVERY",12)
  835.  
  836.     IF glob.eNext_date_no > 0 THEN
  837.        CALL say_c " execution date(s):" tmp glob.eTxtHi || glob.eNext_date_string 
  838.  
  839.     IF glob.eNext_day_no > 0 THEN
  840.        CALL say_c "  execution day(s):" tmp glob.eTxtHi || glob.eNext_day_string 
  841.  
  842.     IF glob.interval <> '' THEN
  843.        CALL say_c "execution interval:" glob.eTxtAla || RIGHT("EVERY",12) || glob.eTxtHi  glob.interval 
  844.  
  845.     IF glob.executions > 0 THEN
  846.        CALL say_c " executions so far:" glob.eTxtHi || glob.executions glob.eTxtInf || "time(s)"
  847.  
  848.     CALL say_c
  849.     CALL say_c "command to execute: [" || glob.eTxtHi || glob.command || glob.eTxtInf || "]"
  850.     CALL say_c
  851.  
  852.     IF glob.bTestmode > 0 THEN      /* testing mode */
  853.     DO
  854.        IF glob.type = 1 | glob.type = 3 THEN
  855.        DO
  856.           CALL say_c '             ATRGF: *** Test mode ***'
  857.           CALL say_c '                    Hit return to get next invocation date'
  858.           CALL say_c '                    OR '
  859.           CALL say_c '                    Enter EXIT to end testing mode'
  860.           PULL x
  861.           /* looping mode? If so, exit from here */
  862.           IF x = 'EXIT' & (glob.type = 1 | glob.type = 3) THEN EXIT
  863.        END
  864.  
  865.        glob.eLast.eDat = glob.eNext.eDat
  866.        glob.eLast.eTim = glob.eNext.eTim
  867.     END
  868.     ELSE
  869.     DO
  870.        x = glob.eTo_wait_sec - TIME("R")  /* deduct time needed to arrive at this position */
  871.        if x < 0 THEN x = 0
  872.        x = (x + 0.5) % 1                /* result must be an integer */
  873.        CALL SysSleep x                  /* seconds to sleep */
  874.        CALL say_c
  875.        PARSE VALUE DATE("S") TIME("L") TIME("R") WITH glob.eLast.eDat glob.eLast.eTim .
  876.  
  877.        'CALL 'glob.command             /* execute command */
  878.     END
  879.  
  880.     IF glob.bExecuteIfBetweenMidnightAndNow THEN
  881.     DO
  882.        glob.eStart.eDat = glob.eStartOriginal.eDat 
  883.        glob.eStart.eTim = glob.eStartOriginal.eTim 
  884.  
  885.        glob.eLast.eDat  = glob.eStartOriginal.eDat
  886.        glob.eLast.eTim  = glob.eStartOriginal.eTim
  887.     
  888.        glob.bExecuteIfBetweenMidnightAndNow = 0
  889.     END
  890.  
  891.     /* get actual date, time and elapsed time */
  892.     PARSE VALUE DATE("S") TIME("L") TIME("R") WITH glob.eEnded.eDat glob.eEnded.eTim tmp
  893.  
  894.     glob.eEnded.eDuration = calc_duration(tmp)
  895.     glob.executions = glob.executions + 1
  896.     RETURN
  897. /* end of SHOW_SLEEP_EXECUTE *************************************************/
  898.  
  899.  
  900.  
  901. USAGE:
  902.    CALL say_c
  903.    CALL say_c glob.eTxtHi || 'ATRGF:' || glob.eTxtInf || '   execute command at specified time'
  904.    CALL say_c
  905.    CALL say_c
  906.    CALL say_c 'usage:' || glob.eTxtHi || '   ATRGF [/B] [/M] [/W] [/T] time command'
  907.    CALL say_c glob.eTxtHi || '         ATRGF [/B] [/W] [/M] [/T] time /NE:dayordate command'
  908.    CALL say_c glob.eTxtHi || '         ATRGF [/B] [/W] [/M] [/T] time /E:dayordate command'
  909.    CALL say_c glob.eTxtHi || '         ATRGF [/B] [/W] [/M] [/T] [time] /I:time command'glob.eTxtInf
  910.    CALL say_c
  911.    CALL say_c '         see enclosed Tutorial "RGFSHOW.CMD" and syntax below'
  912.    CALL say_c
  913.    CALL say_c 'syntax:'
  914.    CALL say_c glob.eTxtHi || '   COMMAND' || glob.eTxtInf || ' ..... any command as entered thru the keyboard to start'
  915.    CALL say_c '                 a program'
  916.    CALL say_c glob.eTxtHi || '   TIME' || glob.eTxtInf || ' ........ on input 24hour- (military) or 12hour-format allowed,'
  917.    CALL say_c '                 output will be allways in 24hour-format (military, computer)'
  918.    CALL say_c glob.eTxtHi || '   DAYORDATE' || glob.eTxtInf || ' ... ' || glob.eTxtHi || 'DAY[-DAY]|DATE[-DATE][,...]'
  919.    CALL say_c glob.eTxtHi || '                 DAY' || glob.eTxtInf || ' .... 2 letter digit (' || glob.eTxtHi || 'MO' || glob.eTxtInf ||,
  920.            ', ' || glob.eTxtHi || 'TU' || glob.eTxtInf || ',' glob.eTxtHi || 'WE' || glob.eTxtInf || ', ' ||,
  921.            glob.eTxtHi || 'TH' || glob.eTxtInf || ', ' || glob.eTxtHi || 'FR' || glob.eTxtInf || ', ' || glob.eTxtHi ||,
  922.            'SA' || glob.eTxtInf || ',' || glob.eTxtHi || 'SU' || glob.eTxtInf || ')'
  923.    CALL say_c glob.eTxtHi || '                 DATE' || glob.eTxtInf || ' ... 1-2 digits (' || glob.eTxtHi || '1-31' || glob.eTxtInf || ')'
  924.    CALL say_c '                 more than one day or date must be delimited by a comma'
  925.    CALL say_c
  926.    CALL say_c '   flags:'
  927.    CALL say_c glob.eTxtHi || '   /B' || glob.eTxtInf || '  ......... show output in' glob.eTxtHi || 'b' || glob.eTxtInf || 'lack/white (no ANSI-colors)'
  928.    CALL say_c glob.eTxtHi || '   /M' || glob.eTxtInf || '  ......... execute command immediately, if scheduling between' glob.eTxtHi ||,
  929.                             'm' || glob.eTxtInf || 'idnight'
  930.    CALL say_c '                 and the time of first invocation of ATRGF itself is possible'
  931.    CALL say_c glob.eTxtHi || '   /W' || glob.eTxtInf || '  ......... execute ATRGF.CMD in a separate ' || glob.eTxtHi || 'W' || glob.eTxtInf || 'indow'
  932.    CALL say_c glob.eTxtHi || '   /T' || glob.eTxtInf || '  ......... ' || glob.eTxtHi || 'T' || glob.eTxtInf || 'est mode'
  933.    CALL say_c glob.eTxtHi || '   /NE:' || glob.eTxtInf || ' ........ ' || glob.eTxtHi || 'ne' || glob.eTxtInf || 'xt dayordate'
  934.    CALL say_c glob.eTxtHi || '   /E:' || glob.eTxtInf || '  ........ ' || glob.eTxtHi || 'e' || glob.eTxtInf || 'very dayordate'
  935.    CALL say_c glob.eTxtHi || '   /I:' || glob.eTxtInf || '  ........ every time-' || glob.eTxtHi || 'i' || glob.eTxtInf || 'nterval'
  936.    CALL say_c
  937.    CALL say_c 'examples:'
  938.    CALL say_c
  939.    CALL say_c glob.eTxtHi || '    ATRGF 00:00 copy *.* a:'glob.eTxtInf
  940.    CALL say_c '          ... copy all files at midnight to drive A:'
  941.    CALL say_c
  942.    CALL say_c glob.eTxtHi || '    ATRGF 17:00 "beep & @echo Hey, time to go home! & PAUSE"'glob.eTxtInf
  943.    CALL say_c '          ... at 5:00pm beep, show message and wait for keystroke'
  944.    CALL say_c
  945.    CALL say_c glob.eTxtHi || '    ATRGF 20:30 /NE:FR back_it_up'glob.eTxtInf
  946.    CALL say_c '          ... call "BACK_IT_UP" at 8:30pm on ' || glob.eTxtHi || 'ne' || glob.eTxtInf || 'xt friday'
  947.    CALL say_c
  948.    CALL say_c glob.eTxtHi || '    ATRGF 20:30 /NE:31 back_it_up'glob.eTxtInf
  949.    CALL say_c '          ... call "BACK_IT_UP" at 8:30pm on the ' || glob.eTxtHi || 'ne' || glob.eTxtInf || 'xt last day of month'
  950.    CALL say_c
  951.    CALL say_c glob.eTxtHi || '    ATRGF 20:30 /E:1-31 back_it_up'glob.eTxtInf
  952.    CALL say_c '          ... call "BACK_IT_UP" at 8:30pm on ' || glob.eTxtHi || 'e' || glob.eTxtInf || 'very day'
  953.    CALL say_c
  954.    CALL say_c glob.eTxtHi || '    ATRGF 20:30 /E:FR,1,15,31 back_it_up'glob.eTxtInf
  955.    CALL say_c '          ... call "BACK_IT_UP" at 8:30pm on ' || glob.eTxtHi || 'e' || glob.eTxtInf || 'very friday, on every'
  956.    CALL say_c '              first, 15th and last day in a month'
  957.    CALL say_c
  958.    CALL say_c glob.eTxtHi || '    ATRGF 17:00 /E:MO-FR "beep & @echo Hey, time to go home! & PAUSE"'glob.eTxtInf
  959.    CALL say_c '          ... at 5:00pm beep, show message and wait for keystroke mondays'
  960.    CALL say_c '              thru fridays (executing command forever on given DAYORDATE)'
  961.    CALL say_c
  962.    CALL say_c glob.eTxtHi || '    ATRGF 00:00 /I:00:05 MOVE_IT.CMD -v'glob.eTxtInf
  963.    CALL say_c '          ... starting at midnight, execute every 5 minutes (' || glob.eTxtHi || 'i' || glob.eTxtInf || 'nterval)'
  964.    CALL say_c '              "move_it.cmd" with the parameter "-v"'
  965.    CALL say_c
  966.    CALL say_c glob.eTxtHi || '    ATRGF /I:00:05 MOVE_IT.CMD -v'glob.eTxtInf
  967.    CALL say_c '          ... call every 5 minutes (' || glob.eTxtHi || 'i' || glob.eTxtInf || 'nterval) "move_it.cmd" with'
  968.    CALL say_c '              the parameter "-v"'
  969.    CALL say_c
  970.    CALL say_c glob.eTxtHi || '    ATRGF /W 20:30 /E:FR-MO,15,31-1 back_it_up'glob.eTxtInf
  971.    CALL say_c '          ... call "BACK_IT_UP" at 8:30pm on ' || glob.eTxtHi || 'e' || glob.eTxtInf || 'very friday, saturday,'
  972.    CALL say_c '              sunday, monday, on ' || glob.eTxtHi || 'e' || glob.eTxtInf || 'very, first, 15th and last day in a month,'
  973.    CALL say_c '              execute in a separate ' || glob.eTxtHi || 'w' || glob.eTxtInf || 'indow'
  974.    CALL say_c
  975.    CALL say_c glob.eTxtHi || '    ATRGF /T 20:30 /E:FR-MO,15,31-1 back_it_up'glob.eTxtInf
  976.    CALL say_c '          ... ' || glob.eTxtHi || 't' || glob.eTxtInf || 'esting of command; show invocation dates'
  977.    CALL say_c
  978.    CALL say_c glob.eTxtHi || '    ATRGF /W /T 20:30 /E:FR-MO,15,31-1 back_it_up'glob.eTxtInf
  979.    CALL say_c '          ... ' || glob.eTxtHi || 't' || glob.eTxtInf || 'esting of command; show invocation dates; use a separate'
  980.    CALL say_c '              ' || glob.eTxtHi || 'w' || glob.eTxtInf || 'indow for it'
  981.    CALL say_c
  982.    CALL say_c glob.eTxtHi || '    ATRGF /B'glob.eTxtInf
  983.    CALL say_c '          ... show usage of ATRGF in black and white (no colors on output)'
  984.    CALL say_c
  985.    CALL say_c glob.eTxtHi || '    ATRGF /M /W 8:00 /E:MO back_it_up'glob.eTxtInf
  986.    CALL say_c '          ... call "BACK_IT_UP" at 8:00am on ' || glob.eTxtHi || 'e' || glob.eTxtInf || 'very monday, execute in a'
  987.    CALL say_c '              separate ' || glob.eTxtHi || 'w' || glob.eTxtInf || 'indow; if ATRGF was started on ' || glob.eTxtHi || 'monday'  || glob.eTxtInf || ' at 9am'
  988.    CALL say_c '              (in fact after 8am), the command will still (!) be executed,'
  989.    CALL say_c '              because of the ' || glob.eTxtHi ||  '/M' || glob.eTxtInf ||  '-switch ' || glob.eTxtHi ||  '!!!'
  990.  
  991.    CALL say_c
  992.    EXIT
  993. /***************************************************/
  994.  
  995. SAY_C: PROCEDURE EXPOSE glob. 
  996.    SAY glob.eTxtInf || ARG(1) || glob.eScrNorm
  997.    RETURN
  998.  
  999. HALT:
  1000.     CALL say_c
  1001.     CALL say_c glob.eTxtAla || "ATRGF: User interrupted program."
  1002.     EXIT
  1003.  
  1004. ERROR:
  1005.    myrc        = RC
  1006.    errorlineno = SIGL
  1007.    errortext   = ERRORTEXT(myrc)
  1008.    errortype   = CONDITION("C")
  1009.    problem     = "Cause: Probably caused by a user-interrupt while in INTERPRET-statement."
  1010.    CALL stop_it myrc":" errortext "in line # ["errorlineno"] REXX-SIGNAL: ["errortype"] ===>" problem
  1011.  
  1012. /*
  1013.    User pressed ctl-c or closed session
  1014. */
  1015. HALT:
  1016.    CALL STOP_IT "User interrupted program."
  1017.  
  1018. /*
  1019.    Clean up and close open files
  1020. */
  1021. STOP_IT:
  1022.    IF ARG(1) <> "" THEN CALL say_c  glob.eTxtAla || "ATRGF:"  glob.eTxtAlaInv || ARG(1)
  1023.    EXIT -1
  1024.  
  1025.