Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
executable file 293 lines (210 sloc) 5.92 KB
#!/usr/bin/perl
use Sys::Hostname;
use Data::Dumper;
use Socket;
########################################
my $configfile = "/etc/mxstartups";
my $rundir = "/run/mariux";
########################################
my $fullhostname = hostname;
my ($hostname) = $fullhostname =~ /^(.*?)\./;
my $packed_ip;
# wait till hostname is resolvable..
while(!($packed_ip=gethostbyname($fullhostname))) {
sleep 1;
}
my $hostip = inet_ntoa($packed_ip);
if(defined $ARGV[0]) {
$rundir = $ARGV[0];
}
unless(-d $rundir and -w $rundir) {
print STDERR "can't write to directory $rundir\n";
exit 1;
}
@lines = read_file($configfile);
my ($host, $user, $script, $ip);
LINE: foreach(@lines) {
unless(($name, $host, $user, $script, $ip) = /^(\S+) (\S+) (\S+) (\S+)\s*(.*?)$/) {
print "format error: '$_'\n";
next;
}
my @hosts = split /[;,]/,$host;
@hosts = expand_hosts(@hosts);
my $match=undef;
foreach my $host (@hosts) {
if($host eq $hostname or $host eq $fullhostname or $hostname =~ /^$host$/ or $fullhostname =~ /^$host$/) {
$match=$host;
}
}
next LINE unless(defined $match);
save_config_mxservice($name, $user, $script);
my @ips = split /\s*[,; ]\s*/,$ip;
my $pip = parse_ips(@ips);
print_ips_cfg($pip);
}
sub read_file {
my $file = shift;
open F, "$file" or die "can't open $file: $!\n";
my @lines=();
my $line="";
my $cont=0;
while(<F>) {
chomp;
next if(/^\s*#/ or /^\s*$/);
$cont=0;
s/#.*$//; # remove comments..
$_ = $line . $_;
if(s/\\\s*$//) {
# line continous in next line..
$cont=1;
}
$line = $_;
unless($cont) {
$line =~ s/\s+/ /g;
push @lines, $line;
$line="";
}
}
return @lines;
}
sub eth_to_net_if_not_exists {
my $dev = shift;
my $net;
my $num;
$dev !~ /^eth/ and return $dev;
-d "/sys/class/net/${dev}" and return $dev;
($num) = $dev =~ /^eth(\d+)$/;
$net = sprintf "net%02d", $num;
-d "/sys/class/net/${net}" and return $net;
return $dev;
}
sub parse_ips {
local $_;
my $H = {};
my $default_device = 'eth0';
foreach(@_) {
my $device = $default_device;
my %ports = ();
my $ip = "-";
my $_todest = undef;
my $addressprefix;
if(/\{(\S+)\}(\S+)/) { # extract device "{device}ip[d:t][..]"
$device = $1;
$_=$2;
}
while((/(\S+)\[(\d+):(\d+)\]/)) { # extract ports
$ports{$3}=$2;
$_=$1;
}
if($_ =~ /(\S+)\:(\S+)/) {
$_todest = $2;
$_ = $1;
}
if (/(\S+)\/(\S+)/) {
$_=$1;
$addressprefix=$2;
} else {
$addressprefix=20;
}
if("$_" eq "-") {
$_ = $fullhostname;
}
unless (defined $_todest) {
$_todest=$_;
}
# printf "ip = $_\n";
# printf "todest = $_todest\n";
if (! ($tmphostname = gethostbyname($_)) ) {
printf STDERR "mxvip::$name *ERROR* Can't resolve '$_'. Skipping.\n";
next;
}
$ip = inet_ntoa($tmphostname);
if (! ($tmphostname = gethostbyname($_todest)) ) {
printf STDERR "mxvip::$name *ERROR* Can't resolve '$_'. Skipping.\n";
next;
}
$_todest = inet_ntoa($tmphostname);
$device = eth_to_net_if_not_exists($device);
$H->{$ip} = { device => $device, addressprefix => $addressprefix, ports => {%ports}, todest => $_todest };
}
return $H;
}
##############################################################################
sub save_config_mxservice {
my ($service, $user, $script) = @_;
my $config = "$rundir/mxservice.$name.cfg";
printf "mxservice::$name creating service-config: $config\n";
open SCRIPT, ">", "$config" or die "can't open $config: $!";
print SCRIPT qq(MX_SRV_USER="$user"\n);
print SCRIPT qq(MX_SRV_SCRIPT="$script"\n);
close SCRIPT or die "can't close $script: $!";
}
##############################################################################
sub print_ips_cfg {
my $H = shift;
my %up = ();
my $i=0;
my $r=0;
my $script = "$rundir/mxvip.$name.cfg";
printf "mxvip::$name creating start script: $script\n";
open SCRIPT, ">", "$script" or die "can't open $script: $!";
foreach my $ip (keys %$H) {
if("$ip" ne "$hostip") {
my $broadcast=join('.',unpack('C*',pack('N',unpack('N',pack('C*',split '\.',$ip)) | (1<<(32-$H->{$ip}->{addressprefix}))-1 )));
print SCRIPT qq(# ip $i\n);
print SCRIPT qq(MX_IP_ADDRESS[$i]="$ip"\n);
print SCRIPT qq(MX_IP_ADDRESSPREFIX[$i]="$H->{$ip}->{addressprefix}"\n);
print SCRIPT qq(MX_IP_BROADCAST[$i]="$broadcast"\n);
print SCRIPT qq(MX_IP_DEVICE[$i]="$H->{$ip}->{device}"\n);
$i++;
$up{$H->{$ip}->{device}}=1;
}
my $j=$i-1;
foreach my $port (keys %{$H->{$ip}->{ports}}) {
print SCRIPT qq(# forward $i :: $r\n);
print SCRIPT qq(MX_FWD_IP[$r]="$j"\n);
print SCRIPT qq(MX_FWD_SRC_IP[$r]="$ip"\n);
print SCRIPT qq(MX_FWD_SRC_PORT[$r]="$H->{$ip}->{ports}->{$port}"\n);
print SCRIPT qq(MX_FWD_DST_IP[$r]="$H->{$ip}->{todest}"\n);
print SCRIPT qq(MX_FWD_DST_PORT[$r]="$port"\n);
$r++;
}
}
close SCRIPT or die "can't close $script: $!";
}
##############################################################################
sub walknetgroup {
my @ng;
&y(\@ng,@_);
sub y {
my ($ary,$m)=@_;
$_=`ypmatch $m netgroup 2>/dev/null`;
foreach ( split ) {
if (/\(/) {
s/[\(\),]//g;
push @$ary, $_;
} else {
foreach ( split ) {
&y($ary,$_);
}
}
}
}
return @ng;
}
sub expand_hosts {
my @oh = @_;
my @hosts = ();
foreach my $host (@oh) {
if($host =~ /^\@(\S+)/) {
push @hosts, walknetgroup($1);
} elsif($host =~ /^(\/\S+)/) {
next unless(-r $1);
push @hosts, expand_hosts(read_file($1));
} else {
push @hosts, $host;
}
}
return @hosts;
}
__DATA__