[comp.lang.icon] cron.icn

ron@mlfarm.com (Ronald Florence) (04/18/91)

A friend who takes a mail/news feed from us with an ms-dos system
wanted to be able to poll when he was on-the-road.  I know next to
nothing about ms-dos, don't want to learn about things like TSRs, and
Icon is the only language our systems share.  This was the quick &
dirty solution.  The busy-loops are dumb (I anticipate flames), but
Icon tables made this fun.

I'd urge NOT running this code on a multi-tasking system like Unix,
unless you're interested in seeing how high your system load can
reach.
--

Ronald Florence			ron@mlfarm.com


#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	cron.icn
# This archive created: Thu Apr 18 10:25:34 1991
# By:	Ronald Florence (Maple Lawn Farm, Stonington, CT)
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'cron.icn'
then
	echo shar: "will not over-write existing file 'cron.icn'"
else
cat << \SHAR_EOF > 'cron.icn'
############################################################################
#
#	Name:	cron.icn
#
#	Title:	Cron Daemon
#
#	Author:	Ronald Florence (ron@mlfarm.com)
#
#	Date:	18 April 1991
#
#	Version: 1.0
#
############################################################################
#
#  This program provides a crude cron daemon for ms-dos or other
#  single-tasking systems.  If a scheduled command fails, it is 
#  retried at a specified interval.
#  
#    usage: cron [-r] [-c cmd] [-t tries] [-i interval] 0-23 [0-59]
#           cron < cron-table [ > cron.log ]
#  
#  The command-line usage invokes a single command at a specified time.
#  The -r option runs the daemon continuously.  Defaults for the command,
#  interval, and retries can be specified in the code.  The second usage 
#  reads an ascii table in the following format:
#  
#     # hour  minute  interval  retries   command
#        0      15       5         3      uuio | mail postmaster
#        1      35       0         0      rnews *.nws
#        6      30       2         2      make coffee
#  
#  Lines beginning with `#' in the table are treated as comments.
#
############################################################################
#
#  Link: options
#  Bugs: This busy-loop should NOT be run on multi-tasking systems.
#        Commands scheduled at conflicting times may not be invoked.
#        The cron-table is not compatible with Unix cron tables.
#
############################################################################

link options

procedure main(arg)

  usage := ["usage: cron [-r] [-c cmd] [-t tries] [-i interval] 0-23 [0-59]",
	    "       cron < cron-table"]

  default_cmd := "uuio"
  default_interval := 5
  default_retries := 3

  cmd := table(0)
  interval := table(0)
  retries := table(0)

  if *arg > 0 then {
    opts := options(arg, "c:i+t+r")
    h := integer(arg[1])
    m := integer(arg[2]) | 0
    (/h | h < 0 | h > 23 | m < 0 | m > 59 ) & { every write(!usage); exit(-1) }
    t := h * 3600 + m * 60
    cmd[t] := \opts["c"] | default_cmd
    interval[t] := \opts["i"] | default_interval
    retries[t] := \opts["t"] | default_retries
  }
  else every s := !&input do s ? {
    ="#" & next
    tmp := []
    while tab(upto(&digits)) \4 do put(tmp,tab(many(&digits)))
    t := pop(tmp) * 3600 + pop(tmp) * 60
    interval[t] := pop(tmp)
    retries[t] := pop(tmp)
    cmd[t] := (tab(many(' \t')), tab(0))
  }
  
  write(&errout, "time\tint\tret\tcommand")
  write(&errout, "-------------------------------")
  every t := key(cmd) do 
    write(&errout, right(t/3600, 2, "0"), ":", left((t % 3600)/60, 2, "0"),
	  "\t", interval[t], "\t", retries[t], "\t", cmd[t])

  while t := now() do (t = key(cmd)) & {
    try := 0
    repeat {
      (system(cmd[t]) = 0) & { 
	write(cmd[t], " completed ", &dateline)
	while t = now()
	break 
      }
      write(cmd[t], " FAILED ", &dateline)
      ((try +:= 1) >= retries[t]) & break
      repoll := now() + interval[t] * 60
      while repoll > now()
    }
    (*arg = 0) | \opts["r"] | exit(try)
  }
end

procedure now()
  time := []
  &clock ? while tab(upto(&digits)) do put(time,tab(many(&digits)))
  return time[1] * 60 * 60 + time[2] * 60 + time[3]
end
SHAR_EOF
if test 3218 -ne "`wc -c < 'cron.icn'`"
then
	echo shar: "error transmitting 'cron.icn'" '(should have been 3218 characters)'
fi
fi
exit 0
#	End of shell archive
--

Ronald Florence			ron@mlfarm.com