Flow Control
Pikt scripts run from top to bottom, from beginning to end, unless redirected by one of the flow control constructs. Pikt comes with a panoply of flow control structures, most usual, and a few not so usual. ("The usual" below means that the structure follows the usual C-like or Perl-like behavior.)
STRUCTURE DESCRIPTION
if-elif-else-endif the usual (note that you can use elsif and
elseif, too; also, fi instead of endif)
while-endwhile the usual
repeat-until like a do-while loop, except keep looping
until the exit condition is true (no do-
while, because the "do" keyword is reserved
for another use)
for-endfor the usual
for-in-endfor loop through all the keys in the given
associative array
foreach-endforeach loop through all the keys in the given
associative array
break the usual
continue the usual (note that you can use cont, too)
switch-case-default- the usual
breakswitch- (note that you can use breaksw
endswitch and endsw, too)
again repeat the current rule
leave leave the current rule and
go on to the next
redo reprocess the current input line
next go on to the next input line
skip n skip ahead n input lines, and resume with
the first rule
last terminate input processing, go to the
end section, if any
pause n pause for n seconds
quit go on to the next alarm script
die "<message>" abort the program (and log the reason)
Statement blocks are indicated by a keyword-keyword combination, for example, if-endif or for-endfor (no { or } here).
Some examples follow.
The if-elif-else-endif construct:
rule // set some thresholds
if $alert() =~ "EMERGENCY"
set #procnumlim = 300
elsif $alert() =~ "Urgent"
set #procnumlim = 250
else // if $alert() =~ "ProcessCounts"
set #procnumlim = 250
endif
The while-endwhile construct (also if-elif-else-endif):
rule // for changed scripts, diff and log/mail any changes
if #popen(DIFF, "=diff $hstfil $fil", "r") != #err()
while #read(DIFF) > 0
if #doheader
output mail "changes to $fil:"
output log "(L)" "changes to $fil:"
set #doheader = #false()
fi
output mail $rdlin
output log "(L)" $rdlin
endwhile
do #pclose(DIFF)
else
output mail "can't open process for reading!"
quit
fi
The repeat-until construct:
rule
repeat
=chop($proc)
until $right($proc, 4) eq "perl"
The for-endfor construct:
rule
for #i=1 #i<=#innum() #i+=1
output mail $line[#i]
endfor
The for-in-endfor construct (also if-elif-else-endif):
rule // check for existence of shell
for $u in #members("root", "daemon", "bin", "sys")
if ! -e $shell[$u]
output mail "$u's shell nonexistent!"
fi
endfor
endfor
The foreach-endforeach construct (also if-elif-else-endif):
end
// report new procs not in old proc list
foreach #keys($p, #procs)
if ! #defined(%procs[$p])
output log "=processlistchange_log" "alive: $p"
fi
endforeach
// report old procs not in new proc list
foreach #keys($p, %procs)
if ! #defined(#procs[$p])
output log "=processlistchange_log" "dead: $p"
fi
endforeach
The switch-case-default-breakswitch-endswitch & cont(inue) constructs (also for-endfor & if-elif-else-endif):
rule
for #i=2 #i<=10 #i+=1 // check/fix perms
if $p[#i] eq "." // we don't care
cont
elseif $mid($access,#i,1) ne $p[#i]
switch #i
case 2
=execwait "=chmod u" . $s[#i] . "r $d$name"
breaksw
case 3
=execwait "=chmod u" . $s[#i] . "w $d$name"
breaksw
case 4
=execwait "=chmod u" . $s[#i] . "x $d$name"
breaksw
[... and so on for group & others ...]
endsw
endif
endfor
The again statement (also if-elif-else-endif & pause):
begin // wait until 6 AM
if #hour() < 6
pause 60
again
fi
The leave & next statements (also if-elif-else-endif):
rule
if $level() =~~ "emerg|alert"
&& $inlin =~~ "=redflags"
leave
elsif $inlin =~~ "=yellowflags"
leave
else
next
fi
The redo statement (also if-elif-else-endif, pause & next):
rule // kill $proc
set #p = #pid($proc)
if #p != #err()
exec wait "=kill $text(#p)"
pause 5
redo
else
next
if
The skip statement (also if-elif-else-endif):
rule
if $inlin =~ "^PCI: Bridge:"
skip 4 // skip details
fi
The last statement (also if-elif-else-endif):
rule
if $inlin =~ "error"
last
endif
The quit statement (also if-elif-else-endif):
checkpoint(LA)
set #la = #val($chop($command("=uptime | =awk '{print \$10}'")))
if #la >= (LA)
output log "=logdir/Checkpoint.log"
"quit $alarm(), load average $text(#la, 2)"
quit
fi
The die statement (also if-elif-else-endif):
begin
if #pid($proc) == #err()
die "$proc is not running"
fi
Parentheses around conditions are allowed but are unnecessary (and in certain obscure circumstances can even cause syntax errors; it's best to omit them). Below, the left-hand statement has the same effect as the right-hand:
if <cond> if (<cond>)
elif <cond> elif (<cond>)
while <cond> while (<cond>)
until <cond> until (<cond>)
for <init> <cond> <incr> for (<init> <cond> <incr>)
Refer to the sample alarms.cfg for many more examples.
| | 1st page | next page |