# servers-lib.pl
# Common functions for managing servers

do '../web-lib.pl';
&init_config();
%access = &get_module_acl();

sub list_servers
{
local ($f, @rv);
opendir(DIR, $module_config_directory);
while($f = readdir(DIR)) {
	if ($f =~ /^(\d+)\.serv$/) {
		push(@rv, &get_server($1));
		}
	}
closedir(DIR);
return @rv;
}

# get_server(id)
sub get_server
{
local $serv;
$serv->{'id'} = $_[0];
&read_file("$module_config_directory/$_[0].serv", $serv) || return undef;
return $serv;
}

# save_server(&server)
sub save_server
{
&lock_file("$module_config_directory/$_[0]->{'id'}.serv");
&write_file("$module_config_directory/$_[0]->{'id'}.serv", $_[0]);
chmod(0600, "$module_config_directory/$_[0]->{'id'}.serv");
&unlock_file("$module_config_directory/$_[0]->{'id'}.serv");
}

# delete_server(id)
sub delete_server
{
&lock_file("$module_config_directory/$_[0].serv");
unlink("$module_config_directory/$_[0].serv");
&unlock_file("$module_config_directory/$_[0].serv");
}

# can_use_server(&server)
sub can_use_server
{
return 1 if ($access{'servers'} eq '*');
foreach $s (split(/\s+/, $access{'servers'})) {
	return 1 if ($_[0]->{'host'} eq $s);
	}
return 0;
}

# list_all_groups([&servers])
# Returns a list of all webmin and MSC groups and their members
sub list_all_groups
{
local (@rv, %gmap, $s, $f);

# Add webmin servers groups
foreach $s ($_[0] ? @{$_[0]} : &list_servers()) {
	if ($s->{'group'}) {
		local $grp = $gmap{$s->{'group'}};
		if (!$grp) {
			$gmap{$s->{'group'}} = $grp = { 'name' => $s->{'group'},
							'type' => 0 };
			push(@rv, $grp);
			}
		push(@{$grp->{'members'}}, $s->{'host'});
		}
	}

# Add MSC cluster groups
opendir(DIR, $config{'groups_dir'});
foreach $f (readdir(DIR)) {
	next if ($f eq '.' || $f eq '..');
	local $grp = $gmap{$f};
	if (!$grp) {
		$gmap{$f} = $grp = { 'name' => $f, 'type' => 1 };
		push(@rv, $grp);
		}
	open(GROUP, "$config{'groups_dir'}/$f");
	while(<GROUP>) {
		s/\r|\n//g;
		s/#.*$//;
		if (/(\S*)\[(\d)-(\d+)\](\S*)/) {
			# Expands to multiple hosts
			push(@{$grp->{'members'}}, map { $1.$_.$4 } ($2 .. $3));
			}
		elsif (/(\S+)/) {
			push(@{$grp->{'members'}}, $1);
			}
		}
	close(GROUP);
	}
closedir(DIR);

# Fix up MSC groups that include other groups
while(1) {
	local ($grp, $any);
	foreach $grp (@rv) {
		local @mems;
		foreach $m (@{$grp->{'members'}}) {
			if ($m =~ /^:(.*)$/) {
				push(@mems, @{$gmap{$1}->{'members'}});
				$any++;
				}
			else {
				push(@mems, $m);
				}
			}
		$grp->{'members'} = \@mems;
		}
	last if (!$any);
	}

return @rv;
}

@server_types = ( [ 'caldera', 'OpenLinux' ],
		  [ 'redhat', 'Redhat Linux' ],
		  [ 'suse', 'SuSE Linux' ],
		  [ 'debian', 'Debian Linux' ],
		  [ 'mandrake', 'Mandrake Linux' ],
		  [ 'msc', 'MSC.Linux' ],
		  [ 'cobalt', 'Cobalt Linux' ],
		  [ 'linux', 'Linux' ],
		  [ 'freebsd', 'FreeBSD' ],
		  [ 'solaris', 'Solaris' ],
		  [ 'hpux', 'HP/UX' ],
		  [ 'sco', 'SCO' ],
		  [ 'mac', 'Macintosh' ],
		  [ 'irix', 'IRIX' ],
		  [ 'unknown', $text{'lib_other'} ] );


1;

