home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / atrgf31.zip / ATrgf.cmd next >
OS/2 REXX Batch file  |  1996-04-19  |  44KB  |  1,064 lines

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