crontab/mirc — File Browser
crontabmircv0.8 / crontabmircv0.8 / crontab.mrc
crontab.mrc — 11.89 KB — Download this file
alias -l _me return crontab
alias -l _ver return 0.8
alias -l _dep return mirc 6.0 0 clp 1.1.9 0
alias -l __mirc return $version
alias __crontab return $_ver
on *:signal:deps:if ($2 iswm $_me) { .signal re-deps $1 $_me $_dep }
on *:signal:rollcall:if ($2 iswm $_me) { .signal re-rollcall $1 $_me $_ver }
alias -l compare {
if ($0 != 3) return 0
if (!$regex($2,^[<>=]=?$)) return 0
var %i 0, %n = $numtok($1,46), %m = $numtok($3,46), %n = $iif(%m > %n,%m,%n), %p = $1, %q = $3, %r, %s, %t
while (%i < %n) {
inc %i
%t = $regsub($gettok($1,%i,46),[a-zA-Z],,%r)
%t = $regsub($gettok($3,%i,46),[a-zA-Z],,%s)
%t = $calc($len(%r) - $len(%s))
if (%t) {
if (%t > 0) %q = $puttok(%q,$+($str(0,%t),$gettok(%q,%i,46)),%i,46)
else %p = $puttok(%p,$+($str(0,$calc(0- %t)),$gettok(%p,%i,46)),%i,46)
}
}
return $iif(%p $2 %q,1,0)
}
on *:signal:INIT:{
if ($2 iswm $_me) {
%crontab.signalto = $1
crontab
}
}
alias -l crontab.reinit {
if (%crontab.signalto) {
.signal REINIT $_me %crontab.signalto $1-
unset %crontab.signalto
}
}
alias -l e echo -s crontab: $1-
alias crontab {
if (!$0) {
var %f, %i, %n, %req, %t
e $_me $_ver starting
e . checking dependencies
%req = $_dep
%i = 1
while (%i < $numtok(%req,32)) {
var %module, %need, %have
%module = $gettok(%req,%i,32)
%need = $gettok(%req,$calc(%i +1),32)
%have = $__ [ $+ [ $gettok(%req,%i,32) ] ]
e . . $+(%module %need,...) $iif(%have,%have,not found)
if (!%have) { %have = 0 }
if ($compare(%have,<,%need)) {
if ($gettok(%req,$calc(%i +2),32)) { e WARNING %module %need or better not found, functionnality may be reduced }
else {
e ERROR $_me $_ver requires %module %need or better, aborting.
%f = $findfile($mircdir,$+(%module,.mrc),1,99)
if (%f) { e . i have found $nopath(%f) in $nofile(%f) but it was not loaded or it has been modified, /load -rs $+(",%f,") might fix this error. }
crontab.reinit 0
return
}
}
inc %i 3
}
e . dependencies okay
crontab.init
crontab.reinit 1
return
}
var %clp = $clp($1-,--die,cron.die,--exec,cron.exec,-e --edit,cron.edit,-l --list,cron.list,-h --help --man,cron.man,--sync --resync,cron.sync)
if (!%clp) {
e error while parsing parms
crontab.reinit 0 clp error
return
}
if (%cron.sync) {
e resynchronizing timer
crontab.vars
.timercrontab -o $+(%cron.hrs,:,%cron.mins) 1 0 crontab --exec
e . next check scheduled at $timer(crontab).time
return
}
if (%cron.exec) {
var %comp, %event, %field, %field1, %field2, %field3, %field4, %field5, %field.i 0, %match, %range0, %range1, %step, %token, %i 0, %j, %m, %n
%n = $hmatch(crontab,*,0)
while (%i < %n) {
inc %i
%event = $replace($hget(crontab,%i),$chr(9),$chr(32))
if ((#* iswm %event) || (!$len(%event)) || (!$crontab.validate(%event))) continue
:1
%field1 = $gettok(%event,1,32)
%field2 = $gettok(%event,2,32)
%field3 = $gettok(%event,4,32)
%field4 = $gettok(%event,3,32)
%field5 = $gettok(%event,5,32)
if ($regex(%field1,^@((year|annual|month|week|dai|hour)ly|midnight)$)) {
if (%field1 == @hourly) {
%event = 0 * * * * $gettok(%event,2-,32)
goto 1
}
if ($regex(%field1,^@(daily|midnight)$)) {
%event = 0 0 * * * $gettok(%event,2-,32)
goto 1
}
if (%field1 == @weekly) {
%event = 0 0 * * 0 $gettok(%event,2-,32)
goto 1
}
if (%field1 == @monthly) {
%event = 0 0 1 * * $gettok(%event,2-,32)
goto 1
}
if ($regex(%field1,^@(year|annual)ly$)) {
%event = 0 0 1 1 * $gettok(%event,2-,32)
goto 1
}
}
%field3 = $replace(%field3,jan,1,feb,2,mar,3,apr,4,may,5,jun,6,jul,7,aug,8,sep,9,oct,10,nov,11,dec,12)
%field5 = $replace(%field5,sun,0,mon,1,tue,2,wed,3,thu,4,fri,5,sat,6,7,0)
%field.i = 0
%match = 0
while (%field.i < 5) {
inc %field.i
%comp = %cron. [ $+ [ $gettok(mins.hrs.month.day.dow,%field.i,46) ] ]
%field = %field [ $+ [ %field.i ] ]
%j = 0
%m = $numtok(%field,44)
while (%j < %m) {
inc %j
%token = $gettok(%field,%j,44)
if ($regex(%token,^\*+$)) {
inc %match
break
}
if ($regex(%token,^\d+$)) {
if (%token == %comp) {
inc %match
break
}
continue
}
%step = $gettok(%token,2,47)
if ($regex(%token,^\d+/\d+$)) {
if ($calc(%comp % %step) == $calc($gettok(%token,1,47) % %step)) {
inc %match
break
}
continue
}
if ($regex(%token,^\*/\d+$)) {
if (%step // %comp) {
inc %match
break
}
continue
}
%range0 = $gettok(%token,1,45)
%range1 = $gettok($gettok(%token,2,45),1,47)
if ($regex(%token,^\d+-\d+(/\d+)?$)) {
if (%range0 < %range1) {
if ($regex(%token,^\d+-\d+$)) {
if ((%comp >= %range0) && (%comp <= %range1)) {
inc %match
break
}
continue
}
else {
if ((%comp >= %range0) && (%comp <= $gettok(%range1,1,47)) && ($calc(%range0 % %step) == $calc(%comp % %step))) {
inc %match
break
}
continue
}
}
else {
if ($regex(%token,^\d+-\d+$)) {
if ((%comp >= %range0) || (%comp <= %range1)) {
inc %match
break
}
continue
}
else {
if ((%comp >= %range0) || (%comp <= $gettok(%range1,1,47)) && ($calc(%range0 % %step) == $calc(%comp % %step))) {
inc %match
break
}
continue
}
}
}
}
if ((%field.i < 4) && (%match < %field.i)) break
}
if (%match > 3) .timer -o 1 0 $gettok(%event,6-,32)
}
crontab.vars
.timercrontab -o $+(%cron.hrs,:,%cron.mins) 1 0 crontab --exec
return
}
if (%cron.die) {
crontab.die
return
}
if (%cron.edit) {
dialog $iif($dialog(crontab.e),-v,-m) crontab.e crontab.e
return
}
if (%cron.list) {
var %i 0, %n = $hmatch(crontab,*,0)
echo -s $+(--crontab,$str(-,20))
while (%i < %n) {
inc %i
if ($hget(crontab,%i)) echo -s $hget(crontab,%i)
}
echo -s $+(--crontab,$str(-,20))
return
}
if (%cron.man) {
crontab.man
return
}
}
alias -l crontab.die {
e freeing resources
e . stopping timer
.timercrontab* off
e . freeing hash table
hfree -w crontab*
e . unsetting variables
unset %cron.*
if ($window(@crontab)) {
e . closing manual
window -c @crontab
}
e done
}
alias -l crontab.init {
var %cron.validated, %i 0, %n, %t
e . making cron table
hfree -w crontab
hmake crontab 10
if ($isfile(crontab.sav)) {
e . loading events from crontab.sav
hload -n crontab crontab.sav
%n = $hmatch(crontab,*,0)
e . . %n lines loaded
e . validating events
while (%i < %n) {
inc %i
%t = $hget(crontab,%i)
if (#* iswm %t) { continue }
if (!$len(%t)) { continue }
if ($crontab.validate(%t)) { inc %cron.validated }
else e . . WARNING, bogus event: %t
}
e . . %cron.validated events validated
}
e . setting vars
%cron.day = $asctime(dd)
%cron.month = $asctime(mm)
%cron.dow = $replace($asctime(ddd),sun,0,mon,1,tue,2,wed,3,thu,4,fri,5,sat,6)
crontab.vars
e . starting timer
.timercrontab -o $+(%cron.hrs,:,%cron.mins) 1 0 crontab --exec
e ready
return
}
alias -l crontab.man {
if ($isfile(crontab.txt)) {
window -adk @crontab
filter -cpfw crontab.txt @crontab *
}
}
alias -l crontab.validate {
var %regex.in = $replace($1-,$chr(9),$chr(32)), %regex, %regex1, %regex2, %regex3, %regex4, %regex5, %e, %f 0, %i 0, %j 0, %m 0, %n, %p
tokenize 32 %regex.in
if ($regex($1,^@((year|annual|month|week|dai|hour)ly|midnight)$) && ($len($2))) return $true
%regex1 = ^((\*)|(([0-5]?\d)(-[0-5]?\d)?))(/\d+)?$
%regex2 = ^((\*)|((([01]?\d)|(2[0-3]))(-(([01]?\d)|(2[0-3])))?))(/\d+)?$
%regex3 = ^((\*)|((([012]?\d)|(3[01]))(-(([012]?\d)|(3[01])))?))(/\d+)?$
%regex4 = ^((\*)|((((0?[1-9])|(1[0-2]))|jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)(-(((0?[1-9])|(1[0-2]))|jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec))?))(/\d+)?$
%regex5 = ^((\*)|(([0-7]|mon|tue|wed|thu|fri|sat|sun)(-([0-7]|mon|tue|wed|thu|fri|sat|sun))?))(/\d+)?$
while (%j < 5) {
inc %j
%p = $ [ $+ [ %j ] ]
%regex = %regex [ $+ [ %j ] ]
%n = $numtok(%p,44)
inc %m %n
%e = 0
%i = 0
while (%i < %n) {
inc %i
if ($regex($lower($gettok(%p,%i,44)),%regex)) inc %e
}
inc %f %e
}
return $iif((%f == %m) && ($len($6)),$true,$false)
}
alias -l crontab.vars {
var %t = $calc($ctime +60)
%cron.hrs = $asctime(%t,HH)
%cron.mins = $asctime(%t,nn)
if (!$calc(%cron.mins + %cron.hrs)) {
%cron.day = $asctime(%t,dd)
%cron.month = $asctime(%t,mm)
%cron.dow = $calc(($pos(sumotuwethfrsa,$left($asctime(%t,ddd),2)) -1) /2)
}
}
on *:dialog:crontab.e:init:0:{
var %i 0, %n = $hmatch(crontab,*,0), %t
did -a crontab.e 2 Enter your crontab events in the space below. Blank lines or lines that begin with a hash (#) are ignored. Separate fields with a space or a tab (ctrl+i). $crlf $+ Syntax is: MIN HOUR DAY MONTH DAYOFWEEK COMMAND
while (%i < %n) {
inc %i
%t = $hget(crontab,%i)
if (%t) did -a crontab.e 1 %t $+ $crlf
}
if (!$isfile(crontab.txt)) {
did -h crontab.e 3
did -bv crontab.e 4
}
}
on *:dialog:crontab.e:sclick:3:crontab.man
on *:dialog:crontab.e:sclick:999:{
var %i 0, %n = $hmatch(crontab,*,0), %t
while (%i < %n) {
inc %i
hdel crontab %i
}
%i = 0
%n = $did(1).lines
while (%i < %n) {
inc %i
%t = $did(1,%i)
if ($len(%t)) {
if (#* !iswm %t) {
if (!$crontab.validate(%t)) e WARNING, bogus event: %t
}
; we add bogus events as well so that is shows up next time the user edits the crontab
hadd crontab %i %t
}
}
; for some reason, the first item is written last with hsave -n, so we use filter as a workaround
filter -cif crontab.e 1 crontab.sav *
}
dialog crontab.e {
title "crontab"
size -1 -1 640 480
edit "", 1, 5 60 630 390, return multi hsbar vsbar autohs
text "", 2, 5 5 630 40
link "manual", 3, 595 45 40 15
text "manual", 4, 595 45 40 15, hide
button "&Cancel", 998, 510 455 60 20, cancel
button "&OK", 999, 575 455 60 20, ok
}
menu status {
$_me $_ver
.&edit crontab:crontab -e
.&list crontab:crontab -l
.-
.$iif($isfile(crontab.txt),&manual):crontab -h
.-
.$iif(%cron.mins,&restart,&start):crontab
.$needsync:crontab --resync
.$iif(%cron.mins,sto&p):crontab --die
.-
.unload =(:{
if ($input(Would you really like to unload 'crontab'?,qy)) {
crontab.die
unload -rs crontab.mrc
}
else var %t $input(Good!,o,Thank you)
}
}
alias -l needsync {
var %t = $timer(crontab).time
if (!%t) return
var %sched = $calc($gettok(%t,1,58) *60+ $gettok(%t,2,58)), %now = $calc($gettok($time,1,58) *60+ $gettok($time,2,58))
if ($calc(%sched - %now) != 1) return res&ync (scheduled %t $+ , now $gettok($time,1-2,58) $+ )
}