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 endifThe 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 fiThe 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] endforThe 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 endforThe 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 endforeachThe 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 endforThe again statement (also if-elif-else-endif & pause):
begin // wait until 6 AM if #hour() < 6 pause 60 again fiThe leave & next statements (also if-elif-else-endif):
rule if $level() =~~ "emerg|alert" && $inlin =~~ "=redflags" leave elsif $inlin =~~ "=yellowflags" leave else next fiThe 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 ifThe skip statement (also if-elif-else-endif):
rule if $inlin =~ "^PCI: Bridge:" skip 4 // skip details fiThe last statement (also if-elif-else-endif):
rule if $inlin =~ "error" last endifThe 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 fiThe 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.
prev page | 1st page | next page |