Viewing file: cfengine-lib.pl (22.98 KB) -rwxr-xr-x Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
# cfengine-lib.pl # Functions for parsing the cfengine config file
BEGIN { push(@INC, ".."); }; use WebminCore; &init_config();
@known_sections = ( 'groups', 'control', 'homeservers', 'binservers', 'mailserver', 'mountables', 'broadcast', 'resolve', 'defaultroute', 'directories', 'miscmounts', 'files', 'ignore', 'tidy', 'required', 'links', 'disable', 'shellcommands', 'editfiles', 'processes', 'copy' ); @known_sections = sort { $text{"section_$a"} cmp $text{"section_$b"} } @known_sections;
@known_cfd_sections = ( 'control', 'groups', 'admit', 'deny' ); @known_cfd_sections = sort { $text{"section_$a"} cmp $text{"section_$b"} } @known_cfd_sections;
$cfengine_conf = $config{'cfengine_conf'} ? $config{'cfengine_conf'} : "$config{'cfengine_dir'}/cfengine.conf"; $cfd_conf = $config{'cfd_conf'} ? $config{'cfd_conf'} : "$config{'cfengine_dir'}/cfd.conf"; $cfrun_hosts = $config{'cfrun_hosts'} ? $config{'cfrun_hosts'} : "$config{'cfengine_dir'}/cfrun.hosts";
# get_config() # Parses the cfengine.conf file into a list of sections, each containing # a list of classes, each containing options for the section type. sub get_config { if (!scalar(@get_config_cache)) { @get_config_cache = &get_config_file($cfengine_conf); } return \@get_config_cache; }
# get_cfd_config() # Parses the cfd.conf file sub get_cfd_config { if (!scalar(@get_cfd_config_cache)) { @get_cfd_config_cache = &get_config_file($cfd_conf); } return \@get_cfd_config_cache; }
# get_config_file(file) # Parses on specified cfengine config file sub get_config_file { # Parse file into tokens local $lnum = 0; local @toks; open(CONFIG, $_[0]); while(<CONFIG>) { s/\r|\n//g; s/(^|\s+)#.*$//g; local ($s, $q) = &split_str($_); local $i; for($i=0; $i<@$s; $i++) { push(@toks, [ $s->[$i], $lnum, $q->[$i] ]); } $lnum++; } close(CONFIG); # Parse tokens into the config local (@rv, $sec, $cls, $i); push(@rv, { 'type' => 'dummy', # dummy record so that config is never empty 'index' => 0, 'line' => -1, 'eline' => -1, 'file' => $_[0] } ); for($i=0; $i<@toks; $i++) { local $t = $toks[$i]; if ($t->[0] =~ /^(\S+)::$/) { # Start of a class $cls = { 'name' => $1, 'type' => 'class', 'index' => scalar(@{$sec->{'cls'}}), 'line' => $t->[1], 'eline' => $t->[1], 'file' => $_[0] }; $sec->{'eline'} = $t->[1]; push(@{$sec->{'cls'}}, $cls); } elsif ($t->[0] =~ /^(\S+):$/) { # Start of a section $sec = { 'name' => $1, 'type' => 'section', 'index' => scalar(@rv), 'cls' => [ ], 'line' => $t->[1], 'eline' => $t->[1], 'file' => $_[0] }; undef($cls); push(@rv, $sec); } else { # Some kind of text within a class .. create all:: if needed if (!$sec) { &error("Unknown directive at line ", ($t->[1]+1)," in $_[0]"); } if (!$cls) { $cls = { 'name' => 'any', 'type' => 'class', 'implied' => 1, 'index' => scalar(@{$sec->{'cls'}}), 'line' => $t->[1], 'eline' => $t->[1], 'file' => $_[0] }; push(@{$sec->{'cls'}}, $cls); }
if ($i+2 < @toks && $toks[$i+1]->[0] eq '=' && $toks[$i+2]->[0] eq '(') { # A definition with multiple values local $def = { 'name' => $t->[0], 'line' => $t->[1], 'file' => $_[0] }; $i += 3; while($i < @toks && $toks[$i]->[0] ne ')') { push(@{$def->{'values'}}, $toks[$i]->[0]); push(@{$def->{'valuequotes'}}, $toks[$i]->[2]); push(@{$def->{'valuequoted'}}, "e_str($toks[$i]->[0], $toks[$i]->[2])); $i++; } $sec->{'eline'} = $cls->{'eline'} = $toks[$i]->[1]; push(@{$cls->{'defs'}}, $def); } elsif ($t->[0] eq '{') { # A { } quoted list local $list = { 'line' => $t->[1], 'file' => $_[0] }; $i++; while($i < @toks && $toks[$i]->[0] ne '}') { push(@{$list->{'values'}}, $toks[$i]->[0]); push(@{$list->{'valuelines'}}, $toks[$i]->[1]); push(@{$list->{'valuequotes'}}, $toks[$i]->[2]); push(@{$list->{'valuequoted'}}, "e_str($toks[$i]->[0], $toks[$i]->[2])); $i++; } $sec->{'eline'} = $cls->{'eline'} = $toks[$i]->[1]; push(@{$cls->{'lists'}}, $list); } else { # A single value push(@{$cls->{'values'}}, $t->[0]); push(@{$cls->{'valuelines'}}, $t->[1]); push(@{$cls->{'valuequotes'}}, $t->[2]); push(@{$cls->{'valuequoted'}}, "e_str($t->[0], $t->[2])); $sec->{'eline'} = $cls->{'eline'} = $t->[1]; } } }
# Expand import: sections local @imps = &find("import", \@rv); foreach $i (@imps) { foreach $c (@{$i->{'cls'}}) { next if ($c->{'name'} ne 'any'); # XXX only do 'any::' foreach $v (@{$c->{'values'}}) { local $fn = $v; if ($fn !~ /^\//) { # Assume relative to current config file $fn = "$config{'cfengine_dir'}/$fn"; } local @inc = &get_config_file($fn); map { $_->{'index'} += scalar(@rv) } @inc; push(@rv, @inc); } } }
return @rv; }
# find(name, &config) sub find { local ($c, @rv); foreach $c (@{$_[1]}) { push(@rv, $c) if ($c->{'name'} eq $_[0]); } return wantarray ? @rv : $rv[0]; }
# find_value(name, &config) sub find_value { local @f = &find($_[0], $_[1]); return wantarray ? () : undef if (!@f); return wantarray ? @{$f[0]->{'values'}} : $f[0]->{'values'}->[0]; }
# save_directive(&config, &old, &new) # Updates or adds an entire class or section to the config file sub save_directive { local $file = $_[1] ? $_[1]->{'file'} : $_[0]->[0]->{'file'}; local $lref = &read_file_lines($file); local @lines = &directive_lines($_[2]) if ($_[2]); if ($_[1]) { splice(@$lref, $_[1]->{'line'}, $_[1]->{'eline'} - $_[1]->{'line'} + 1, @lines); } else { splice(@$lref, $_[0]->[@{$_[0]}-1]->{'eline'}+1, 0, @lines); } }
# swap_directives(&config, &directive1, &directive2) # Swaps two directives in the config file sub swap_directives { local $lref = &read_file_lines($_[1]->{'file'}); local @lines1 = @$lref[$_[1]->{'line'} .. $_[1]->{'eline'}]; local @lines2 = @$lref[$_[2]->{'line'} .. $_[2]->{'eline'}]; if ($_[1]->{'line'} < $_[2]->{'line'}) { splice(@$lref, $_[2]->{'line'}, scalar(@lines2), @lines1); splice(@$lref, $_[1]->{'line'}, scalar(@lines1), @lines2); } elsif ($_[1]->{'line'} > $_[2]->{'line'}) { splice(@$lref, $_[1]->{'line'}, scalar(@lines1), @lines2); splice(@$lref, $_[2]->{'line'}, scalar(@lines2), @lines1); } }
# directive_lines(§ion|&class) # Returns an array of the lines for some section or class sub directive_lines { local (@rv, $d, $l, $i); if ($_[0]->{'type'} eq 'section') { push(@rv, "$_[0]->{'name'}:"); if (defined($_[0]->{'text'})) { return (@rv, split(/\n/, $_[0]->{'text'})); } foreach $c (@{$_[0]->{'cls'}}) { push(@rv, &directive_lines($c)); } } elsif ($_[0]->{'type'} eq 'class') { local $id = $_[0]->{'implied'} ? "\t" : "\t\t"; push(@rv, "\t$_[0]->{'name'}::") if (!$_[0]->{'implied'}); if (defined($_[0]->{'text'})) { return (@rv, split(/\n/, $_[0]->{'text'})); } foreach $d (@{$_[0]->{'defs'}}) { local @v; local $i; for($i=0; $i<@{$d->{'values'}}; $i++) { push(@v, "e_str($d->{'values'}->[$i], $d->{'valuequotes'}->[$i])); } push(@rv, "$id$d->{'name'} = ( ".join(" ", @v)." )"); } foreach $l (@{$_[0]->{'lists'}}) { push(@rv, $id."{"); push(@rv, &value_lines($l->{'values'}, $l->{'valuelines'}, $l->{'valuequotes'}, $id)); push(@rv, $id."}"); } push(@rv, &value_lines($_[0]->{'values'}, $_[0]->{'valuelines'}, $_[0]->{'valuequotes'}, $id)); } return @rv; }
# value_lines(&values, &lines, "es, indent) sub value_lines { local @lines; local $i; for($i=0; $i<@{$_[0]}; $i++) { local $l = $_[1]->[$i] - $_[1]->[0]; if ($lines[$l] eq "") { $lines[$l] = $_[3]; } else { $lines[$l] .= " "; } $lines[$l] .= "e_str($_[0]->[$i], $_[2]->[$i]); } return @lines; }
# quote_str(string, quote) sub quote_str { if (defined($_[1])) { return $_[1].$_[0].$_[1]; } elsif ($_[0] =~ /^\S+$/) { return $_[0]; } elsif ($_[0] !~ /"/) { return "\"$_[0]\""; } elsif ($_[0] !~ /'/) { return "'$_[0]'"; } else { return "`$_[0]`"; } }
# split_str(string) sub split_str { local (@rv, @qu); local $str = $_[0]; while($str =~ /^\s*(")([^"]*)"(.*)$/s || $str =~ /^\s*(')([^"]*)'(.*)$/s || $str =~ /^\s*(`)([^"]*)`(.*)$/s || $str =~ /^\s*()(\S+)(.*)$/s) { push(@qu, $1); push(@rv, $2); $str = $3; } return ( \@rv, \@qu ); }
# get_cfrun_hosts() sub get_cfrun_hosts { local (@hosts, %opts); open(HOSTS, $cfrun_hosts); while(<HOSTS>) { s/\r|\n//g; s/#.*$//; if (/^\s*(\S+)\s*=\s*(.*)/) { $opts{$1} = $2; } elsif (/^\s*(\S+)\s*(.*)/) { push(@hosts, [ $1, $2] ); } } close(HOSTS); return ( \@hosts, \%opts ); }
# save_cfrun_hosts(&hosts, &opts) sub save_cfrun_hosts { open(HOSTS, ">$cfrun_hosts"); foreach $o (keys %{$_[1]}) { print HOSTS $o,"=".$_[1]->{$o},"\n"; } foreach $h (@{$_[0]}) { print HOSTS $h->[0]," ",$h->[1],"\n"; } close(HOSTS); }
# show_classes_table(&config, cfd, readonly) sub show_classes_table { if (@{$_[0]}) { &show_button($_[1]) if (!$_[2]); print "<table border width=100%>\n"; print "<tr $tb> ", ($_[1] ? "" : "<td><b>$text{'index_active'}</b></td>"), "<td><b>$text{'index_section'}</b></td> ", "<td><b>$text{'index_classes'}</b></td> ", "<td><b>$text{'index_details'}</b></td> </tr>\n"; local $s; local %active; foreach $s (@{$_[0]}) { foreach $c (@{$s->{'cls'}}) { if ($s->{'name'} eq 'control') { local ($as) = &find("actionsequence", $c->{'defs'}); local $cc = $c->{'name'} eq 'any' ? 2 : 1; map { s/\..*$//; $active{$_} = $cc if ($cc > $active{$_}) } @{$as->{'values'}} if ($as); } } } foreach $s (@{$_[0]}) { next if ($s->{'name'} =~ /^import/); local (@clist, @dlist); foreach $c (@{$s->{'cls'}}) { push(@clist, $_[2] ? $c->{'name'} : "<a href='edit_class.cgi?cfd=$_[1]&idx=$s->{'index'}&cidx=$c->{'index'}'>$c->{'name'}</a>"); local $desc; if ($s->{'name'} eq 'links') { local @l = &parse_links($c); if (@l > 1) { $desc = &text('index_links2', scalar(@l)); } elsif (@l) { $desc = &text('index_links', "<tt>$l[0]->{'_linkfrom'}</tt>", "<tt>$l[0]->{'_linkto'}</tt>"); } } elsif ($s->{'name'} eq 'directories' || $s->{'name'} eq 'files' || $s->{'name'} eq 'disable' || $s->{'name'} eq 'shellcommands' || $s->{'name'} eq 'tidy' || $s->{'name'} eq 'required' || $s->{'name'} eq 'disks') { local @dirs = &parse_directories($c); if (@dirs > 1) { $desc = &text('index_'.$s->{'name'}.'2', scalar(@dirs)); } elsif (@dirs) { $desc = &text('index_'.$s->{'name'}, "<tt>$dirs[0]->{'_dir'}</tt>"); } } elsif ($s->{'name'} eq 'control' && $_[1]) { local ($cmd) = &find("cfrunCommand", $c->{'defs'}); if ($cmd) { $desc = &text('index_cfrun', "<tt>$cmd->{'values'}->[0]</tt>"); } } elsif ($s->{'name'} eq 'control' && !$_[1]) { local ($as) = &find("actionsequence", $c->{'defs'}); if ($as) { local @v = @{$as->{'values'}}; if (@v > 1) { $desc = &text('index_control2', scalar(@v)); } else { $desc = &text('index_control', "<tt>$v[0]</tt>"); } } } elsif ($s->{'name'} eq 'editfiles') { local @files = map { $_->{'values'}->[0] } @{$c->{'lists'}}; if (@files > 1) { $desc = &text('index_editfiles2', scalar(@files)); } elsif (@files) { $desc = &text('index_editfiles', "<tt>$files[0]</tt>"); } } elsif ($s->{'name'} eq 'grant' || $s->{'name'} eq 'admit' || $s->{'name'} eq 'deny') { local @dirs = grep { /\// } @{$c->{'values'}}; if (@dirs > 1) { $desc = &text('index_'.$s->{'name'}.'2', scalar(@dirs)); } elsif (@dirs) { $desc = &text('index_'.$s->{'name'}, "<tt>$dirs[0]</tt>"); } } elsif ($s->{'name'} eq 'groups' || $s->{'name'} eq 'classes') { local @grs = map { $_->{'name'} } @{$c->{'defs'}}; if (@grs) { $desc = &text('index_groups', join(", ", map { "<tt>$_</tt>" } @grs)); } } elsif ($s->{'name'} eq 'copy') { local @copies = &parse_directories($c); if (@copies > 1) { $desc = &text('index_copy2', scalar(@copies)); } elsif (@copies) { $desc = &text('index_copy', "<tt>$copies[0]->{'_dir'}</tt>", "<tt>$copies[0]->{'dest'}</tt>"); } } elsif ($s->{'name'} eq 'ignore') { $desc = &text('index_ignore', scalar(@{$c->{'values'}})); } elsif ($s->{'name'} eq "processes") { local @procs = grep { !$_->{'_options'} } &parse_processes($c); if (@procs > 1) { $desc = &text('index_procs2', scalar(@procs)); } elsif (@procs) { $desc = &text('index_procs', "<tt>$procs[0]->{'_match'}</tt>"); } } elsif ($s->{'name'} eq 'miscmounts') { local @mnts = &parse_miscmounts($c); if (@mnts > 1) { $desc = &text('index_misc2', scalar(@mnts)); } elsif (@mnts) { $desc = &text('index_misc', "<tt>$mnts[0]->{'_src'}</tt>"); } } elsif ($s->{'name'} eq 'defaultroute') { $desc = &text('index_route', "<tt>$c->{'values'}->[0]</tt>"); } $desc = " " if (!$desc); push(@dlist, $desc); } next if (!@clist);
local $t = $text{"section_".$s->{'name'}."_".$_[1]}; $t = $text{"section_".$s->{'name'}} if (!$t); print "<tr $cb>\n"; if (!$_[1]) { printf "<td rowspan=%d valign=top>\n", scalar(@clist); local $a = $active{$s->{'name'}}; print $s->{'name'} =~ /^control/ ? "<br>" : $a == 0 ? "<font color=#ff0000>$text{'no'}</font>" : $a == 1 ? "<font color=#333333>$text{'index_maybe'}</font>" : $text{'yes'}; print "</td>\n"; } printf "<td rowspan=%d valign=top>\n", scalar(@clist); print "<table cellpadding=0 cellspacing=0 width=100%><tr>\n"; print "<td>",$t ? "$t ($s->{'name'})" : $s->{'name'},"</td>\n"; print "<td align=right>\n"; #if ($s eq $_[0]->[@{$_[0]}-1]) { # print "<img src=images/gap.gif>"; # } #else { # print "<a href='down.cgi?cfd=$_[1]&idx=$s->{'index'}'>", # "<img src=images/down.gif border=0></a>"; # } #if ($s eq $_[0]->[0]) { # print "<img src=images/gap.gif>"; # } #else { # print "<a href='up.cgi?cfd=$_[1]&idx=$s->{'index'}'>", # "<img src=images/up.gif border=0></a>"; # } if (!$_[2]) { print "<a href='edit_class.cgi?cfd=$_[1]&idx=$s->{'index'}&new=1'>$text{'index_cadd'}</a></td>\n"; } print "</tr></table></td>\n";
for($i=0; $i<@clist; $i++) { print "<tr $cb>\n" if ($i != 0); print "<td>$clist[$i]</td>\n"; print "<td>$dlist[$i]</td>\n"; print "</tr>\n" if ($i == 0); } } print "</table>\n"; } elsif ($_[1]) { print "<p><b>$text{'cfd_none'}</b><p>\n"; } else { print "<p><b>$text{'index_none'}</b><p>\n"; } &show_button($_[1]) if (!$_[2]); }
# show_button(cfd) sub show_button { print "<form action=edit_class.cgi>\n"; print "<input type=hidden name=cfd value='$_[1]'>\n"; print "<input type=submit name=new value='$text{'index_add'}'>\n"; print "<select name=type>\n"; local $s; foreach $s ($_[0] ? @known_cfd_sections : @known_sections) { local $tt = $text{"type_".$s."_".$_[0]}; $tt = $text{"type_".$s} if (!$tt); next if (!$tt); local $t = $text{"section_".$s."_".$_[0]}; $t = $text{"section_".$s} if (!$t); print "<option value=$s>$t ($s)\n"; } print "</select></form>\n";
}
# parse_links(&cls) sub parse_links { local (@rv, $v); foreach $v (@{$_[0]->{'values'}}) { if ($v =~ /^(\S+)=(\S+)$/) { if (defined($rv[$#rv]->{$1})) { $rv[$#rv]->{$1} .= "\0$2"; } else { $rv[$#rv]->{$1} = $2; } } elsif ($v =~ /^[\+\-]>!?$/) { $rv[$#rv]->{'_linktype'} = $v; } else { if (!@rv || $rv[$#rv]->{'_linkfrom'} && $rv[$#rv]->{'_linkto'}) { push(@rv, { '_linkfrom' => $v } ); } else { $rv[$#rv]->{'_linkto'} = $v; } } } return @rv; } # unparse_links(&cls, link, ...) sub unparse_links { local $cls = shift(@_); local ($l, $vl = 0, @values, @valuelines); foreach $l (@_) { push(@values, $l->{'_linkfrom'}, $l->{'_linktype'}, $l->{'_linkto'}); push(@valuelines, $vl, $vl, $vl); foreach $k (keys %$l) { if ($k !~ /^_/) { local $z; foreach $z (split(/\0/, $l->{$k})) { push(@values, "$k=$z"); push(@valuelines, $vl); } } } $vl++; } $cls->{'values'} = \@values; $cls->{'valuelines'} = \@valuelines; $cls->{'valuequotes'} = [ ]; }
# parse_directories(&cls) sub parse_directories { local (@rv, $v); foreach $v (@{$_[0]->{'values'}}) { if ($v =~ /^(\S+)=(\S+)$/) { if (defined($rv[$#rv]->{$1})) { $rv[$#rv]->{$1} .= "\0$2"; } else { $rv[$#rv]->{$1} = $2; } } else { push(@rv, { '_dir' => $v } ); } } return @rv; }
# unparse_directories(&cls, dir, ...) sub unparse_directories { local $cls = shift(@_); local ($d, $vl = 0, @values, @valuelines); foreach $d (@_) { push(@values, $d->{'_dir'}); push(@valuelines, $vl); foreach $k (keys %$d) { if ($k !~ /^_/) { local $z; foreach $z (split(/\0/, $d->{$k})) { push(@values, "$k=$z"); push(@valuelines, $vl); } } } $vl++; } $cls->{'values'} = \@values; $cls->{'valuelines'} = \@valuelines; $cls->{'valuequotes'} = [ ]; return @rv; }
# parse_processes(&cls, &optionstr) sub parse_processes { local (@rv, $v, $i); for($i=0; $i<@{$_[0]->{'values'}}; $i++) { $v = $_[0]->{'values'}->[$i]; if ($v =~ /^(\S+)=(\S+)$/) { if (defined($rv[$#rv]->{$1})) { $rv[$#rv]->{$1} .= "\0$2"; } else { $rv[$#rv]->{$1} = $2; } } elsif ($v eq "restart") { $rv[$#rv]->{'_restart'} = $_[0]->{'values'}->[++$i]; } elsif ($v eq "SetOptionString") { push(@rv, { '_options' => $_[0]->{'values'}->[++$i] } ); } else { push(@rv, { '_match' => $v } ); } } return @rv; }
# unparse_processes(&cls, match, ...) sub unparse_processes { local $cls = shift(@_); local ($d, $vl = 0, @values, @valuelines, @valuequotes); foreach $d (@_) { if ($d->{'_options'}) { push(@values, "SetOptionString", $d->{'_options'}); push(@valuelines, $vl, $vl); push(@valuequotes, "", '"'); } else { push(@values, $d->{'_match'}); push(@valuelines, $vl); push(@valuequotes, '"'); foreach $k (keys %$d) { if ($k !~ /^_/) { local $z; foreach $z (split(/\0/, $d->{$k})) { push(@values, "$k=$z"); push(@valuelines, $vl); push(@valuequotes, ""); } } } if ($d->{'_restart'}) { push(@values, "restart", $d->{'_restart'}); push(@valuelines, $vl, $vl); push(@valuequotes, "", '"'); } } $vl++; } $cls->{'values'} = \@values; $cls->{'valuelines'} = \@valuelines; $cls->{'valuequotes'} = \@valuequotes; return @rv; }
# unparse_shellcommands(&cls, dir, ...) sub unparse_shellcommands { local $cls = shift(@_); local ($d, $vl = 0, @values, @valuelines, @valuequotes); foreach $d (@_) { push(@values, $d->{'_dir'}); push(@valuelines, $vl); push(@valuequotes, $d->{'_dir'} !~ /"/ ? '"' : $d->{'_dir'} !~ /'/ ? "'" : "`"); foreach $k (keys %$d) { if ($k !~ /^_/) { local $z; foreach $z (split(/\0/, $d->{$k})) { push(@values, "$k=$z"); push(@valuelines, $vl); push(@valuequotes, undef); } } } $vl++; } $cls->{'values'} = \@values; $cls->{'valuelines'} = \@valuelines; $cls->{'valuequotes'} = \@valuequotes; return @rv; }
# parse_miscmounts(&cls) sub parse_miscmounts { local (@rv, $v); foreach $v (@{$_[0]->{'values'}}) { if ($v =~ /^(\S+)=(\S+)$/) { if (defined($rv[$#rv]->{$1})) { $rv[$#rv]->{$1} .= "\0$2"; } else { $rv[$#rv]->{$1} = $2; } } elsif ($v !~ /\//) { $rv[$#rv]->{'mode'} = $v; } else { if (@rv && $rv[$#rv]->{'_src'} && !$rv[$#rv]->{'_dest'}) { $rv[$#rv]->{'_dest'} = $v; } else { push(@rv, { '_src' => $v } ); } } } return @rv; }
# unparse_miscmounts(&cls, dir, ...) sub unparse_miscmounts { local $cls = shift(@_); local ($d, $vl = 0, @values, @valuelines); foreach $d (@_) { push(@values, $d->{'_src'}, $d->{'_dest'}); push(@valuelines, $vl, $vl); foreach $k (keys %$d) { if ($k !~ /^_/) { local $z; foreach $z (split(/\0/, $d->{$k})) { push(@values, "$k=$z"); push(@valuelines, $vl); } } } $vl++; } $cls->{'values'} = \@values; $cls->{'valuelines'} = \@valuelines; $cls->{'valuequotes'} = [ ]; return @rv; }
# list_cfengine_hosts() # Returns a list of all webmin hosts running cfengine known to this module sub list_cfengine_hosts { local (@rv, $f); local $hdir = "$module_config_directory/hosts"; opendir(DIR, $hdir); foreach $f (readdir(DIR)) { if ($f =~ /^(\S+)\.host$/) { local %host = ( 'id', $1 ); &read_file("$hdir/$f", \%host); push(@rv, \%host); } } closedir(DIR); return @rv; }
# list_servers() # Returns a list of all servers from the webmin servers module that can be # managed, plus this server sub list_servers { local @servers = &foreign_call("servers", "list_servers"); return ( { 'id' => 0, 'desc' => $text{'this_server'}, 'type' => 'unknown' }, grep { $_->{'user'} } @servers ); }
# server_name(&server) sub server_name { return $_[0]->{'desc'} ? $_[0]->{'desc'} : $_[0]->{'host'}; }
# save_cfengine_host(&host) # Add or update a managed host sub save_cfengine_host { local $hdir = "$module_config_directory/hosts"; mkdir($hdir, 0700); &write_file("$hdir/$_[0]->{'id'}.host", $_[0]); }
# delete_cfengine_host(&host) sub delete_cfengine_host { unlink("$module_config_directory/hosts/$_[0]->{'id'}.host"); }
# cfengine_host_version(&server) sub cfengine_host_version { local $out = &remote_eval($_[0]->{'host'}, "cfengine", '`$config{"cfengine"} -V 2>&1`'); return $out =~ /cfengine-(\S+)/ || $out =~ /GNU\s+(\S+)/ ? $1 : undef; }
# show_run_form() sub show_run_form { print "<tr> <td><b>$text{'run_dry'}</b></td>\n"; print "<td><input type=radio name=dry value=1> $text{'yes'}\n"; print "<td><input type=radio name=dry value=0 checked> $text{'no'}</td>\n";
print "<td><b>$text{'run_noifc'}</b></td>\n"; print "<td><input type=radio name=noifc value=0 checked> $text{'yes'}\n"; print "<td><input type=radio name=noifc value=1> $text{'no'}</td> </tr>\n";
print "<tr> <td><b>$text{'run_nomnt'}</b></td>\n"; print "<td><input type=radio name=nomnt value=0 checked> $text{'yes'}\n"; print "<td><input type=radio name=nomnt value=1> $text{'no'}</td>\n";
print "<td><b>$text{'run_nocmd'}</b></td>\n"; print "<td><input type=radio name=nocmd value=0 checked> $text{'yes'}\n"; print "<td><input type=radio name=nocmd value=1> $text{'no'}</td> </tr>\n";
print "<tr> <td><b>$text{'run_notidy'}</b></td>\n"; print "<td><input type=radio name=notidy value=0 checked> $text{'yes'}\n"; print "<td><input type=radio name=notidy value=1> $text{'no'}</td>\n";
print "<td><b>$text{'run_nolinks'}</b></td>\n"; print "<td><input type=radio name=nolinks value=0 checked> $text{'yes'}\n"; print "<td><input type=radio name=nolinks value=1> $text{'no'}</td> </tr>\n";
print "<tr> <td><b>$text{'run_verbose'}</b></td>\n"; print "<td><input type=radio name=verbose value=1 checked> $text{'yes'}\n"; print "<td><input type=radio name=verbose value=0> $text{'no'}</td>\n"; }
# get_cfengine_version(&dummy) sub get_cfengine_version { local $out = `$config{'cfengine'} -V 2>&1`; ${$_[0]} = $out; return $out =~ /cfengine-(\S+)/ || $out =~ /GNU\s+(\S+)/ ? $1 : undef; }
1;
|