TIP: Click on subject to list as thread! ANSI
echo: 4dos
to: All
from: Jasen Betts
date: 2003-12-20 13:33:06
subject: new! improved!

Hi All.
 here it is: (happy holidays)

Mark, to enable logging by default change where it says "set LOGGING=0"
to "set LOGGING=2" (or 1 or 3 - see below)


:! SCHED.BTM                             VERSION 1.1  20-dec-2003
:!
:! Sched is by Jasen Betts, it is based on a btm program called Dayboot1
:! which was developed by Gerald Miller and Jasen Betts which was based
:! on a btm program by Klaus Meinhard called Xbootex
:!
:!
:!
:!
{at}goto start

:: lines containing : and ! together appear in the "help" listing
:: they may occur anywhere in this file.

:!
:!       this is not the Dayboot1.btm you've used before
:!
:!                THE DATA FORMAT IS DIFFERENT
:!
:!   you will have to hand-edit the file to to new format
:!   it's not that hard to do, see the notes below for converting
:!   Dayboot1 rules to Sched rules, or writing new rules.
:!
:!
:!        S C H E D U L I N G   R U L E S
:!
:!
:!  Pnn  periodical every nn days
:!          tries to have exactly nn days between runs; compensates for late
:!          runs. This is like the "plus rule" of Dayboot1.
:!
:!
:!          Eg.  P7  would do something the same day every week, except if
:!          it was delayed one time to by not booting on the scheduled day
:!          it would run it the next day but then return back to doing it
:!          the same day as it was originally
:!
:!
:!  Wnn  Wait nn days
:!           runs after nn days (midnights actually) have passed
:!           since the last run, (this is the "normal" Dayboot1 behavior)
:!           if it gets delayed once it stays delayed
:!
:!  Dnn  day-of-month
:!           runs only on day NN of the month
:!           negative numbers count from the end of the month
:!
:!  Mnn  month
:!          runs only during month nn (can list multiple months)
:!          (a combination of D and M rules may be an appropriate replacement
:!          for a +365 Dayboot1 rule)
:!
:!  A    ask
:!         prompt confirmation before running
:!          (this is the ASK=YES of Dayboot1)
:!
:!  Rnn  random
:!          run with nn% probability
:!
:!  Nn   Day(s) of week
:!          only run on the given days of the week, multiple day-numbers
:!          may appear after the N (Sunday is 0, Monday is 1, Tuesday is 2,
:!          etc.
:!
:!  Rnn  random
:!          run with nn% probability
:!
:!  O    Option
:!          this rule causes the contents of the
:!          program name field to be used to set program options
:!          setting an option only effects the lines below it.
:!
:!
:!                S O M E   E X A M P L E   R U L E S
:!
:!      Description                   Rule
:!
:!   everyday                         W1
:!   JB's birthday                    M6D27
::    (1970)
:!   GM's birthday                    M11D22
::    (1945) [Jesus, he's older than dirt!]
:!   KM's birthday                    M9D26
::    (1946)
:!   first day of each season         M3M6M9M12D1
:!   once a week                      P7
:!   every two weeks                  P14
:!   every three weeks                P21
:!   weekdays (Mon thru Fri)          N12345
:!   weekends (sun is 0,sat is 6)     N06
:!   again after 4 days               W4
:!   20 percent of the time           R20
:!   first monday of the month        D1D2D3D4D5D6D7N1
:!   last sunday of the month         D-1D-2D-3D-4D-5D-6D-7N0
:!   any friday the thirteenth        D13N5
:!   always use this option           O
:!   this option on sunday only       ON0
:!
:!
:! Documnted Options
:!
:!  SILENCE=Y       - never beep before asking  (rule A)
:!  SILENCE=1       - beep before the first ask only
:!  RAPID=Y         - don't delay after running progs
:!  LOGGING=1       - log execution of programs
:!  LOGGING=2       - log also non-ececutio if user says no when asked
:!  LOGGING=3       - log also setting of options
:!  ASKWAIT=/Wnn    - to set the timeout for ask
:!  ASKDEFAULT=N    - assume no response to ask means No instead of Yes
:!
:! (other options could have effects but they probably won't be desirable
:! effects)
:!
:! CONVERTING FROM DAYBOOT1
:!
:! create a new sched.dat file and append the Dayboot1.dat file to it
:! (copy sched.dat + Dayboot1.dat)
:! then edit the file to fix the fields up.
:!
:! the last-run and program name fileds can stay the same
:! (but the programs name field is now wider) the after-days field has been
:! replaced by the rules field, the other fields are no longer present -
:! the program didn't use them anyway
:!
:! nnnn  the normal Dayboot1 after_days rule is the W rule
:!       so repalce nnnn in after_days with Wnnnn in RULE
:! +nnn  the +nnnn rule is now the P rule (use Pnnnn)
:! +365  the +365 / +366 rules no longer exist. use instead a
:!       combination of the M ans D rules (like the example JB's Birthday
:!       (june 27)
:!
:!
:!      I N S T A L A T I O N
:!
:!
:! call SCHED from your AUTOEXEC.BAT file
:! (or from some other automatic daily task)
:!
:! network users note: sched needs write access to the %TEMP dorectory,
:! its data file and to its instalation directory.
:!
:!
:!
:!      4 D O S   V E R S I O N
:!
:! This .BTM was created and tested for use with 4DOS version 6.02B.
:! and version 7.02A it will not with with earlier versions of 4dos.
:!
:!
:!
:!      R E V I S I O N   H I S T O R Y
:!
:!
:!  2-Dec-03  JB  Original release
:!
:!  4-6 Dec   GM  Some spelling and punctuation and capitalisation in this
:!                documentation sectiion, changed the color scheme,
:!                interaction added to the data-file writing.
:!  4-10 Dec  JB  some tidying, standardising of case in the code
:!                trimming of redundant and duplicated code, fix to a bug
:!                in RULE_A and a few cosmetic bugs.
:!  12  Dec  MFL  (Mark Lewis) logging to a file
:!  15 DCec   JB  "optionising" logging, options ASKWAIT and ASKDEFAULT
:!
:!
:!
:!  Gerald Miller        Jasen Betts            Mark Lewis
:!  Fidonet 1:342/512    Fidonet 3:640/1042     Fidonet 1:XXX/XXX
:!
:!  XXXXXXXXXXXX         Jasen_betts{at}f1042.     XXXXXXXXXX
:!  XXXXXXXXXXXX         n640.z3.fidonet.org    XXXXXXXXXX
:!
:!
:!     L E G A L   S T U F F
:!
:! This program is in the public domain
:!
:! As a user you are responsible for determining the usefulness for any
:! particular purpose of this software.
:!
:! This is free software as such you are entitled to a full refund of the
:! purchase price if you are not completely satisfied :)
:!
:! if you modify it and it breaks, you get to keep the pieces.
:!
:! Any addresses listed in this file are only to be used for contacting the
:! authors the purpose of discussing this program.
:!
:!  Enjoy!

:: check 4dos version

:start
 {at}echo off
 {at}if "%_4VER" ge "6" {at}goto goodver
 {at}echo This batch file requires 4dos version 6 or greater
 {at}goto eof

:goodver
  *setlocal %+ *unalias *

  break on
  on break goto END
  if "%TEMP" eq "" set TEMP=C:\

:: set some variables to refer to files...

:: Datafile gets the name and location of this program but a .DAT extension
  set DATAFILE=%{at}PATH[%{at}SEARCH[%0]]%{at}UPPER[%{at}NAME[%0]].DAT

:: [mfl] LOGFILE is like DATAFILE but with .log extension
  set LOGFILE=%{at}PATH[%{at}SEARCH[%0]]%{at}UPPER[%{at}NAME[%0]].LOG

:: what the head of each log line looks like
  set LOGHEAD=%%_TIME%%  %{at}UPPER[%{at}NAME[%0]]:

:: default logging level
  set LOGGING=0

  set ASKDEFAULT=Y

::  User parameters
 if [%1]==[-?] .or. [%1]==[/?] .or. [%1]==[?] .or. %=
[%1]==[-h] .or. [%1]==[/h] .or. [%1]==[h] .or. %=
[%1]==[-H] .or. [%1]==[/H] .or. [%1]==[H] goto USAGE

::  DF is local date format.
set DF=%{at}REPLACE[2,D,%{at}REPLACE[20,YY,%{at}REPLACE[1,M,%{at}MAKEDATE[14936]]]]

if "%1"=="HELP" .or. "/HELP"=="%1"
.or. "%1"=="-HELP" %=
 ( *ffind  /VMKT"%{at}char[58]!" %_BATCHNAME | *list %+ goto usage )

:: [mfl] start logging...
  IF %LOGGING ge 1 gosub startlog

::  Is the file SCHED.DAT there?

  iff not exist %DATAFILE then
    set tempfile=%DATAFILE

    if [%1]==[DATAFILE] .or. [/DATAFILE]==[%1] .or. [%1]==[-DATAFILE] %=
      goto blankfile

    gosub tempmsg
    color bri red on bla
    echo    ERROR: The %DATAFILE data file was not found!
    color bri cya on bla
    echo.
      inkey /c/K"YNQ[esc][enter]" `Create an empty ` %DATAFILE %=
       ` [Y/N/Q] ?` %%ink
    echo.
    iff "%ink" eq "Y" .or. "%ink" eq
"{at}28" then
      goto blankfile
    elseiff "%ink" eq "N" .or. "%ink" eq
"Q" then
      echo The %DATAFILE data file was NOT created!
      delay 5
    endiff
    goto fin
:blankfile
    echos An empty %DATAFILE (with only the header) will now be created;
    echo after which
    echos you will have to edit and supply the correct data in the proper
    echo format...

    if %LOGGING ge 1 %=
       echo   %LOGHEAD Creating new data file %DATAFILE >> %LOGFILE
    gosub tempfile
    goto fin
  endiff


  iff [%1]==[DATAFILE] .or. [/DATAFILE]==[%1] .or. [%1]==[-DATAFILE] then
    gosub tempmsg
    color bri red on bla %+
    echos     Not overwriting %DATAFILE - it already exists! %+
    color bri gre on bla %+ echo. %+ echo. %+
    echo  If you wish to OVERWRITE %DATAFILE, you will have to type "YES!".
    color bri cya on bla %+
    echo. %+   input /c Overwrite %DATAFILE:  %%inp
    echo.
    if "%inp" eq "YES!" or then goto blankfile
    echo  The %{at}DATAFILE data file was NOT overwritten!
    goto fin
  endiff

::  If Sched did it's job today already or it's before
::  00:01 am, do nothing. In this case, the "start" time is 00:01 am....
::  Change the %do_time variable to suit your requirements.
  set LASTDATE=%{at}DATE[%{at}FILEDATE[%DATAFILE]]
  set TODAY=%{at}DATE[%_DATE]
  set DO_TIME=00:01

  iff %{at}EVAL[%LASTDATE - %TODAY] eq 0 .or. %{at}EVAL[%{at}TIME[%_TIME] - %=
  %{at}TIME[%DO_TIME]] le 0 then
    gosub tempmsg
    color bri red on bri whi
    echos There is nothing to do today because it's all been done!
    color bri cya on bla

:: logging addition by mfl
    if %LOGGING ge 1 %=
      echo ! %LOGHEEAD% Nothing to do because it's all been done! >> %logfile
    goto fin
  endiff
  unset LASTDATE DO_TIME

:: number of days in this month - used for negatives in the D rule
set MONTHDAYS=33-%{at}day[%{at}MAKEDATE[%{at}eval[%{at}DATE[%_DATE]-%{at}day[%_DATE]+33]]]
set MONTHDAYS=%{at}EVAL[%MONTHDAYS]

::  Read Sched.DAT, look at which programs to run today, copy info to
::  UNIQUE.TMP and update Sched.DAT

:: Tempfile in the system "temp" directory
  set TEMPFILE=%{at}UNIQUE[%TEMP]

gosub tempfile

set LINENO=0
do L in  {at}%DATAFILE

  set LINENO=%{at}INC[%LINENO]

  if %LINENO lt 3 ( gosub dateconvert %+ iterate )

  set PROG=%{at}INSTR[0,45,%L]
  set RULES=%{at}INSTR[55,,%L]

::  Convert last-run to local format
  set DATE=%{at}INSTR[46,8,%L]
  set LAST=%DATECONVERSION

  if "%PROG" == "" return



:: parse the rules string into separate variables for each rule type

  unset /q R V RULE_ RULE_P RULE_W RULE_D RULE_M RULE_A RULE_R RULE_N RULE_O

    set RULE=%[RULES].
    do while "%RULE" ne ""
     set X=%{at}INSTR[0,1,%RULE]
     set RULE=%{at}INSTR[1,99,%RULE]

     iff %{at}index[+-0123456789,%[x]] ne -1 then
        set V=%[V]%[X]
     else

        if "%V" == "" set V=0
        if "%[RULE_%R]" ne "" set V= %V
        set RULE_%R=%[RULE_%R]%V
        set V=
        SET R=%{at}UPPER[%[X]]
     endiff
  enddo

  if %RULE_ == 0 set RULE_=
  unset /q X V R RULE

  set RUNDATE=%_DATE

  gosub interpret_rules

  echo %{at}FORMAT[-45.45,%PROG]³%{at}FORMAT[-8.8,%LAST ]³%RULES>>%TEMPFILE
  unset /q PROG RULES RUNDATE LAST
  unset /q RULE_ RULE_P RULE_W RULE_D RULE_M RULE_A RULE_R RULE_N RULE_O

 enddo


  unset /q NEXT DATECONVERSION
  move/q/u %TEMPFILE %DATAFILE >& nul
    iff "%ITEM" gt "0" then
      do M=1 to %ITEM
        echo. %+ echo.
        color bri gre on bla
        echos %{at}UPPER[%0] program Execution:
        color bri cya on bla
        echo  %{at}UPPER[%[RUN%M]]
        echo.
        if %LOGGING ge 1 echo   %LOGHEAD% Executing %[RUN%M]... >> %LOGFILE
        call %[RUN%M]
        {at}echo off
      enddo
    endiff

    echo.
    color bri red on bla
    echos %{at}UPPER[%0] END
    color bri cya on bla
    echo.

:END
    color bri cya on bla
    if "%ITEM" ne "" if "%RAPID"=="" delay 5
    if exist %TEMPFILE del/q %TEMPFILE > nul
:fin
    endlocal
    color bri cya on bla
    quit

:dateconvert

if %LINENO == 1 return
set ORIG=%{at}INSTR[46,8,%L]

iff %ORIG == %DF then
  set DATECONVERSION=%%DATE
else
::  Build a date conversion expression in a variable...
  set DATECONVERSION=%=
%%{at}INSTR[%{at}index[%ORIG,%{at}INSTR[0,2,%DF]],2,%%DATE]%{at}INSTR[2,1,%DF]%=
%%{at}INSTR[%{at}index[%ORIG,%{at}INSTR[3,2,%DF]],2,%%DATE]%{at}INSTR[5,1,%DF]%=
%%{at}INSTR[%{at}index[%ORIG,%{at}INSTR[6,2,%DF]],2,%%DATE]
echo.
echo  Converting date format from %ORIG to %DF using expression:
echo.
set DATECONVERSION

    if %LOGGING ge 1 %=
       echo   %LOGHEAD date format conversion %ORIG `=>` %DF  >> %LOGFILE%
endiff
unset ORIG DF
return

:interpret_rules

::  Implementation of the rules
::
:: note for programmers:
:: don't use shortcuts like %_DOW %_DAY %_MONTH, insteead use an expression
:: of _DATE  like %{at}DOW[%_DATE] that way SET _DATE=... can be used for
:: debugging purposes instead of fiddling with the system date...

iff "%RULE_W" gt "0" then
   if %{at}EVAL[%TODAY-%{at}DATE[0%LAST]] lt %{at}word[0,%RULE_W] return
endiff

iff "%RULE_P" gt "0" then
  if %{at}EVAL[%TODAY-%{at}DATE[0%LAST]] lt %{at}word[0,%RULE_P] return
  if "%LAST" ne "" set RUNDATE=%{at}MAKEDATE[ %{at}EVAL[
%{at}DATE[%LAST] + %=
  ( %TODAY - %{at}DATE[%LAST] ) \ %RULE_P * %RULE_P] ]
endiff

iff "%RULE_R" gt "0" then
  set RULE_R=%{at}word[0,%RULE_R]
  if %{at}random[0,99] ge %RULE_R return
endiff

iff "%RULE_D" ne "" then
  for D in (%RULE_D) do set X=%[X] %{at}IF[%d gt 0,%d,%{at}EVAL[%D+1+%MONTHDAYS]]
  if %{at}index[ %[X] , %{at}DAY[%_DATE] ] == -1 return
endiff

iff "%RULE_M" gt "0" then
  if %{at}index[ %RULE_M , %{at}MONTH[%_DATE] ] == -1 return
endiff

iff "%RULE_N" ne "" then
  if %{at}index[%RULE_N,%{at}EVAL[(2+%TODAY) %% 7]] == -1 return
endiff

iff "%RULE_A" ne "" then
   iff "%SILENT" ne "Y" then
      beep 294 2 330 2 277 2 294 2 330 2 277 2 294 2 330 2 277 2 294 2
      beep 330 2 0 2 139 2 165 2 196 2 233 2 277 2 466 2 554 2 659 2
      beep 784 2 932 2
   endiff
   if "%SILENT" == "1" then set SILENT=Y
   set X=%ASKDEFAULT
   scrput %_row %{at}EVAL[17+%{at}LEN[%PROG]] bri yel on bla %[X]
   color bri cya on bla %+ echos `Execute `
   color bri yel on bla %+ echos %prog
   color bri cya on bla %+ echos ` [Y/N] ? `
   color bri yel on bla %+ inkey /c/K"YN[esc][enter]" %ASKWAIT `` %%X
   echo. %+ echo.
   if "%[X]" == "{at}28" set X=%ASKDEFAULT
   iff "%[X]" ne "Y" then
     if %LOGGING ge 2 echo   %LOGHEAD% user canceled %PROG >>  %LOGFILE%
     return
   endiff
 endiff

 IFF "%RULE_O" ne "" THEN
   iff %LOGGING ge 3 then
      echo   %LOGHEAD% setting option %PROG >>  %LOGFILE%
   elseiff "%{at}instr[0,8,%PROG]" == "LOGGING=" then
     gosub startlog
   endiff

   set %PROG
   goto nilrun

 ENDIFF
  set ITEM=%{at}INC[%ITEM]
  set RUN%ITEM=%PROG
:nilrun
  set LAST=%RUNDATE
:norun

return

:tempmsg
  echo. %+ echo. %+ color bri yel on bla %+
  echo  %{at}UPPER[%0] message:
return


:tempfile
::   0123456789012345678901234567890123456789012345678901234567890
echo PATH\PROGRAM TO RUN                          ³LAST RUN³ RULE >%TEMPFILE
echo ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅ%DF%ÅÄÄÄÄÄÄÄÄÄ >>%TEMPFILE
return

:startlog
  set DD=   JanFebMarAprMayJunJulAugSepOctNovDec
  set DY=%{at}DOW[%_DATE] %{at}DAY[%_DATE] %{at}SUBSTR[%DD%,%{at}EVAL[%{at}MONTH[%_DATE]%=
          * 3],3] %{at}SUBSTR[%{at}YEAR[%_DATE],2,2]
     echo. >> %LOGFILE%
     echo ----------  %dy, %{at}UPPER[%{at}FILENAME[%0]] Process >> %LOGFILE%
 unset dd dy
return


:USAGE
    color bri cya on bla
    text
  ÚÄÄÄÄÄÄHÄIÄNÄTÄSÄÄÄPÄAÄGÄEÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
  ³ SCHED                   Once a day program execution with many options  ³
  ³                         (selectable intervals, ask before execution).   ³
  ³                         For more info see the full help. (sched /help)  ³
  ³                                                                         ³
  ³                         SCHED.DAT is the data file for SCHED.BTM,       ³
  ³                         where you can enter your progs and parameters.  ³
  ³                         It _must_ be in your path or the root dir of    ³
  ³                         your boot drive.                                ³
  ³                                                                         ³
  ³                         SCHED should be CALLed from autoexec.bat        ³
  ³                         or executed atleast once daily in some other way³
  ³                                                                         ³
  ³ Optional parameters:                                                    ³
  ³                                                                         ³
  ³               (none)    run tasks as described above                    ³
  ³  /H /?         (etc)    show this hint page                             ³
  ³                                                                         ³
  ³  DATAFILE               create a blank data/config file                 ³
  ³                                                                         ³
  ³  HELP                   view the program notes, history, and rule help  ³
  ³                         (many pages of help)                            ³
endtext
echos   À%{at}REPEAT[Ä,73]Ù
:EOF

 -=> Bye <=-

---
* Origin: As King Arthur said: Some days it all seems so feudal. (3:640/1042)
SEEN-BY: 633/267 270
@PATH: 640/1042 531 954 774/605 123/500 106/2000 633/267

SOURCE: echomail via fidonet.ozzmosis.com

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.