#!/usr/local/bin/perl
# sshd-lib.pl
# Common functions for the ssh daemon config file

do '../web-lib.pl';
&init_config();
require '../ui-lib.pl';

# Get version information
&read_file("$module_config_directory/version", \%version);

# get_sshd_config()
# Returns a reference to an array of SSHD config file options
sub get_sshd_config
{
local @rv = ( { 'dummy' => 1,
		'indent' => 0,
		'file' => $config{'sshd_config'},
		'line' => -1,
		'eline' => -1 } );
local $lnum = 0;
open(CONF, $config{'sshd_config'});
while(<CONF>) {
	s/\r|\n//g;
	s/^\s*#.*$//g;
	local ($name, @values) = split(/\s+/, $_);
	if ($name) {
		local $dir = { 'name' => $name,
			       'values' => \@values,
			       'file' => $config{'sshd_config'},
			       'line' => $lnum };
		push(@rv, $dir);
		}
	$lnum++;
	}
close(CONF);
return \@rv;
}

# find_value(name, &config)
sub find_value
{
foreach $c (@{$_[1]}) {
	if (lc($c->{'name'}) eq lc($_[0])) {
		return wantarray ? @{$c->{'values'}} : $c->{'values'}->[0];
		}
	}
return wantarray ? ( ) : undef;
}

# find(value, &config)
sub find
{
local @rv;
foreach $c (@{$_[1]}) {
	if (lc($c->{'name'}) eq lc($_[0])) {
		push(@rv, $c);
		}
	}
return wantarray ? @rv : $rv[0];
}

# save_directive(name, &config, [value*])
sub save_directive
{
local @o = &find($_[0], $_[1]);
local @n = grep { defined($_) } @_[2..@_-1];
local $lref = &read_file_lines($_[1]->[0]->{'file'});
local $id = ("\t" x $_[1]->[0]->{'indent'});
local $i;
for($i=0; $i<@o || $i<@n; $i++) {
	if ($o[$i] && $n[$i]) {
		# Replacing a line
		$lref->[$o[$i]->{'line'}] = "$id$_[0] $n[$i]";
		}
	elsif ($o[$i]) {
		# Removing a line
		splice(@$lref, $o[$i]->{'line'}, 1);
		foreach $c (@{$_[1]}) {
			if ($c->{'line'} > $o[$i]->{'line'}) {
				$c->{'line'}--;
				}
			}
		}
	elsif ($n[$i]) {
		# Adding a line
		local $ll = $_[1]->[@{$_[1]}-1]->{'line'};
		splice(@$lref, $ll+1, 0, "$id$_[0] $n[$i]");
		}
	}
}

# scmd(double)
sub scmd
{
if ($cmd_count % 2 == 0) {
	print "<tr>\n";
	}
elsif ($_[0]) {
	print "<td colspan=2></td> </tr>\n";
	print "<tr>\n";
	$cmd_count = 0;
	}
$cmd_count += ($_[0] ? 2 : 1);
}

# ecmd()
sub ecmd
{
if ($cmd_count % 2 == 0) {
	print "</tr>\n";
	}
}

# get_client_config()
# Returns a list of structures, one for each host
sub get_client_config
{
local @rv = ( { 'dummy' => 1,
		'indent' => 0,
		'file' => $config{'client_config'},
		'line' => -1,
		'eline' => -1 } );
local $host;
local $lnum = 0;
open(CLIENT, $config{'client_config'});
while(<CLIENT>) {
	s/\r|\n//g;
	s/^\s*#.*$//g;
	s/^\s*//g;
	local ($name, @values) = split(/\s+/, $_);
	if (lc($name) eq 'host') {
		# Start of new host
		$host = { 'name' => $name,
			  'values' => \@values,
			  'file' => $config{'client_config'},
			  'line' => $lnum,
			  'eline' => $lnum,
			  'members' => [ { 'dummy' => 1,
					   'indent' => 1,
					   'file' => $config{'client_config'},
					   'line' => $lnum } ] };
		push(@rv, $host);
		}
	elsif ($name) {
		# A directive inside a host
		local $dir = { 'name' => $name,
			       'values' => \@values,
			       'file' => $config{'client_config'},
			       'line' => $lnum };
		push(@{$host->{'members'}}, $dir);
		$host->{'eline'} = $lnum;
		}
	$lnum++;
	}
close(CLIENT);
return \@rv;
}

# create_host(&host)
sub create_host
{
local $lref = &read_file_lines($config{'client_config'});
$_[0]->{'line'} = $_[0]->{'eline'} = scalar(@$lref);
push(@$lref, "Host ".join(" ", @{$_[0]->{'values'}}));
$_[0]->{'members'} = [ { 'dummy' => 1,
			 'indent' => 1,
			 'file' => $config{'client_config'},
			 'line' => $_[0]->{'line'} } ];
}

# modify_host(&host)
sub modify_host
{
local $lref = &read_file_lines($config{'client_config'});
$lref->[$_[0]->{'line'}] = "Host ".join(" ", @{$_[0]->{'values'}});
}

# delete_host(&host)
sub delete_host
{
local $lref = &read_file_lines($config{'client_config'});
splice(@$lref, $_[0]->{'line'}, $_[0]->{'eline'} - $_[0]->{'line'} + 1);
}

1;

