From 81840b81a53b005f344d6809be287026577a8928 Mon Sep 17 00:00:00 2001 From: etienne Date: Wed, 7 May 2003 12:13:19 +0000 Subject: Initial revision --- FugueConfig.pm | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 FugueConfig.pm (limited to 'FugueConfig.pm') diff --git a/FugueConfig.pm b/FugueConfig.pm new file mode 100644 index 0000000..c05d8f7 --- /dev/null +++ b/FugueConfig.pm @@ -0,0 +1,137 @@ +package FugueConfig; + +use Sys::Hostname; +use strict; + + +my $rsh = $ENV{"RSH"}; +$rsh = "rsh" unless defined $rsh; + +# apply cpp to a fugue config file and open resulting pipe +sub open { + + my $file = shift; + if (system("which cpp > /dev/null")) { + print "cpp command can't be located\n"; + return undef; + } elsif (not -f $file) { + print "No such file '$file'\n"; + return undef; + } elsif (not -r $file) { + print "'$file' is unreadable\n"; + return undef; + } + open (FD, "cpp -traditional $file |") or return undef; + return \*FD; + +} # end open + +# basic parsing of a cpped fugue config file; each element of the returned +# array describes a non-empty line, according to the following format : +# +# [type, host, agent_name, command, [command_options]] +# +# where 'type' can take one of the following values 'comment', 'global', +# local', 'begin', and 'end'. +# a 'comment' type will be followed by an single field +# +sub parse { + + my $file = shift; + my $fd = &FugueConfig::open($file); + return undef unless $fd; + my @data; + my %appname; + my $line = 0; + while(<$fd>) { + $line++; + # empty lines + if (/^\s*$/) { + next; + # comments + } elsif (/^\s*\#.*$/) { + push(@data, ['comment', $_]); + } else { + my ($type, $host, $name, $command, @param) = + m/^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.*)\#*.*$/ ; + #print "t=$type h=$host n=$name c=$command p=".join(' ', @param)."\n"; + if (not defined $type) { + warn ("*** FugueConfig::parse WARNING : ". + "syntax error at line $line : \n\t=> $_\n"); + next; + } + unless ($type eq 'global' or $type eq 'local' or + $type eq 'begin' or $type eq 'end') { + warn ("*** FugueConfig::parse WARNING : ". + "unknown command type '$type' at line $line. Ignored.\n"); + next; + } + if ($appname{$name}) { + warn ("*** FugueConfig::parse WARNING : ". + "at line $line at least 2 agents have the same name '$name'; ". + "skipping all but the first\n"); + next; + } + $appname{$name} = 1 if $type eq 'global' or $type eq 'local'; + push(@data, [$type, $host, $name, $command, [@param]]); + + } + } + close(1, $fd); + return @data; + +} # end parse + + +# launch an named ivy agent on a given host and on a given ivy bus +# return its pid. +sub launchAgent { + + my ($appname, $host, $command, $options, $bus) = @_; + my @options = @$options if ref($options) eq 'ARRAY'; + push(@options, -b => $bus) if $bus; + my $command_opt = $command.' '.join(' ', @options); + my $pid = fork; + warn ("*** FugueConfig::launchAgent WARNING: Could not fork!\n"), return + unless defined $pid; + + if ($pid) { + # parent + print "*** FugueConfig::launchAgent INFO: $host: launching $appname agent ". + "with \'$command_opt\' (pid=$pid)\n"; + return ($pid); + } else { + # child + my $awk_command = "awk -W interactive '{print \"$appname  \", \$0;}'"; + if ($host eq 'localhost' or $host eq hostname() ) { + exec "$command_opt 2>&1 | $awk_command" or + warn "*** FugueConfig::launchAgent WARNING: Error executing $command\n"; + } else { + exec "$rsh -n $host '$command_opt' 2>&1 | $awk_command " + or warn "*** FugueConfig::launchAgent WARNING: Error executing ". + "$command on $host\n"; + } + } + +} # end launchAgent + + +# launch a given command (not an ivy agent) on a given host +sub launchCommand { + my ($type, $host, $command, $options) = @_; + my @options = @$options if ref($options) eq 'ARRAY'; + my $command_opt = $command.' '.join(' ', @options); + print "*** FugueConfig::launchCommand INFO: $host: launching command ". + "\'$command_opt\'\n"; + my $awk_command = "awk -W interactive '{print \"$type  \", \$0;}'"; + if ($host eq 'localhost' or $host eq hostname() ) { + $command = "$command_opt | $awk_command "; + } else { + $command = "$rsh $host '$command_opt' | $awk_command "; + } +# print "$HEADER launching command $command\n"; + system ($command); + +} # end launchCommand + +1 -- cgit v1.1