#!/usr/bin/tclsh
#globals and procedures##
#time specific variables
set tm [lindex $argv 0]
array set alarms {
ten "600000"
five "300000"
two "120000"
one "60000"
interval "3000"
}
#stateful variables array
array set flag {
10 0
5 0
2 0
1 0
}
#recursive controller,better with more controlled
#and flexible tests than the switch.
proc WakeUp {} {
global flag alarms activetime tm
switch -exact -- $activetime [expr [clock seconds] - $alarms(ten) / 1000] {
set flag(10) 1
return 0
} [expr [clock seconds] - $alarms(five) / 1000] {
set flag(five) 1
return 0
} [expr [clock seconds] - $alarms(two) / 1000] {
set flag(two) 1
return 0
} [expr [clock seconds] - $alarms(ten) / 1000] {
set flag(one) 1
return 0
}
#final check
if {[clock seconds] >= $activetime} {
set flag(one) 1
return 0
}
#recall/reset if nothing else
set activetime [clock scan "today" -base [clock scan $tm]]
after $alarms(interval) {WakeUp}
}
#trace handler for time-state.
proc alarmHandler {var val op} {
global flag alarms
if {[string compare $val "ten"] == 0} {
send_warning $val
after $alarms(five) {uplevel #0 "set flag(ten) 0"}
return $val
} elseif {[string compare $val "five"] == 0} {
send_warning $val
after $alarms(two) {uplevel #0 "set flag(five) 0"}
return $val
} elseif {[string compare $val "two"] == 0} {
send_warning $val
after $alarms(one) {uplevel #0 "set flag(two) 0"}
return $val
} elseif {[string compare $val "one"] == 0} {
send_warning $val
after $alarms(one) {uplevel #0 "set flag(one) 0"}
return $val
}
return 0
}
#uses the op of who and a static declaration to
#warn the user. tcl is not big on ascii art.
#you could check out tk for a popup. it would
#be trivial to code.
proc send_warning {v} {
global user flag
set out [exec who]
for {set x 0} {$x <= [llength $out]} {incr x 5} {
if {[string compare $user [lindex $out $x]] == 0} {
puts "\n\n*******************USER:$user*******************************************"
puts "Please logout $user, you are in alarm cycle at $v minute intervals"
puts "*******************WARNING:$v minutes till next check*******************\r\n"
}
}
#kludge for trace termination
#sometimes traces seem to die with older
#pre 8.4 tcl..
if {![llength [trace info variable flag]]} {
puts "NO trace detected :: reinit called.."
uplevel #0 {trace add variable flag write {alarmHandler}}
return 1
}
return 0
}
#idiot check and main()
#give the time you are excused
#in this form->say 5:30pm? = "17:30:00"
if {![string length [lindex $argv 0]]} {
error "You must give me a base time in hour:minute:second format!!"
}
#the user who calls the script is the
#user searched for in send_warning
set user $env(USER)
#every day the given time needs to be changed
#do this in WakeUp
set activetime [clock scan "today" -base [clock scan $tm]]
#our event code below
trace add variable flag write {alarmHandler}
WakeUp
vwait forever