#!/usr/bin/env perl
#-*- Mode: perl; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-

# Functions for internet sharing setup.
#
# Copyright (C) 2000-2001 Ximian, Inc.
#
# Authors: Arturo Espinosa <arturo@ximian.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Library General Public License as published
# by the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.

$SCRIPTSDIR = "/usr/share/setup-tool-backends/scripts";
if ($SCRIPTSDIR =~ /^@scriptsdir[@]/)
{
    $SCRIPTSDIR = ".";
    $DOTIN = ".in";
}

require "$SCRIPTSDIR/file.pl$DOTIN";
require "$SCRIPTSDIR/service.pl$DOTIN";
require "$SCRIPTSDIR/network.pl$DOTIN";


sub gst_ishare_ipchains_configured
{
  my ($tools, $kerneltool) = @_;
  my ($ret, $fd, $val);
  
  if ($tools && $kerneltool)
  {
    $fd = &gst_file_run_pipe_read ("ipchains-save");
    if ($fd ne undef)
    {
      $ret = 0;
      while ($val = <$fd>)
      {
        if ($val =~ /^-A forward.*MASQ$/)
        {
          $ret = 1;
          last;
        }
      }
      
      &gst_file_close ($fd);
    }
  }

  return $ret;
}


sub gst_ishare_fwrules_get_ipchains
{
  &gst_ishare_get_linux22_forward_support (\%hash);
  &gst_ishare_get_linux22_forward_support_active (\%hash);

  return \%hash;
}


sub gst_ishare_ipchains_save
{
  my ($ipchains_conf, $interface, $landevs, $overwrite) = @_;
  my ($fd, $dev, $landev, $network, $netmask);
  my (@buff, $line);

  return 0 if !$overwrite;
  
  $fd = &gst_file_run_pipe_read ("ipchains-save");
  @buff = (<$fd>);
  &gst_file_close ($fd);

  foreach $line (@buff)
  {
    $line = "" if $line =~ /^-A forward.*MASQ$/;
  }

  foreach $landev (@$landevs)
  {
    $dev = $$interface{$landev};
    $netmask = $$dev{"netmask"};
    $network = &gst_network_ipv4_calc_subnet ($$dev{"address"}, $netmask);
    push @buff, "-A forward -s $network/$netmask -d 0.0.0.0/0.0.0.0 -j MASQ\n";
  }

  &gst_file_buffer_clean (\@buff);
  return &gst_file_buffer_save (\@buff, $ipchains_conf);
}


sub gst_ishare_dhcp_set_devs
{
  my ($linux_conf, $overwrite, $dev) = @_;

  if ($overwrite) {
    return &gst_replace_join_first_array
        ($linux_conf, "DHCP.interface", " ", " ", $dev);
  }

  return 0;
}


sub gst_ishare_dhcp_conf_add_interface
{
  my ($buff, $address, $netmask, $hwaddr) = @_;
  my ($network, $broadcast, $min, $max, $hostname);

  $hostname = &gst_file_run_backtick ("hostname");
  chomp $hostname;
  $hostname = "server" if $hostname eq "";

  $min = $network   = &gst_network_ipv4_calc_subnet ($address, $netmask);
  $max = $broadcast = &gst_network_ipv4_calc_bcast  ($address, $netmask);

  $max =~ s/([0-9]+)$//;
  $max .= $1 - 1;
                   
  $min =~ s/([0-9]+)$//;
  $min .= $1 + 1;
                   
  push @$buff, "subnet $network netmask $netmask {\n\n";
  push @$buff, "\toption routers       $address;\n";
  push @$buff, "\toption subnet-mask   $netmask;\n\n";
  push @$buff, "\trange  dynamic-bootp $min $max;\n\n";
  push @$buff, "\tdefault-lease-time 21600;\n";
  push @$buff, "\tmax-lease-time     43200;\n\n";
  push @$buff, "\thost $hostname {\n";
  push @$buff, "\t\thardware ethernet $hwaddr;\n";
  push @$buff, "\t\tfixed-address $address;\n";
  push @$buff, "\t}\n";
  push @$buff, "}\n\n";
}


sub gst_ishare_dhcp_set_conf
{
  my ($dhcpd_conf, $overwrite, $interface, $devs) = @_;
  my ($dev, $iface);
  my (@buff, $info);

  return 0 if !$overwrite;

  $info = &gst_network_interfaces_get_info ();
  
  foreach $dev (@$devs)
  {
    $iface = $$interface{$dev};

    &gst_ishare_dhcp_conf_add_interface (\@buff, $$iface{"address"}, $$iface{"netmask"},
                                         $ {$$info{$$iface{"dev"}}}{"hwaddr"});
  }

  &gst_file_buffer_clean (\@buff);
  &gst_file_buffer_save (\@buff, $dhcpd_conf);
}


sub gst_ishare_conf_get
{
  my %dist_attrib;
  my $hash;

  %dist_attrib = &gst_ishare_conf_get_parse_table ();

  $hash = &gst_parse_from_table ($dist_attrib{"fn"},
                                 $dist_attrib{"table"});
  return $hash;
}


sub gst_ishare_fwrules_get
{
  my %dist_attrib;
  my $hash;

  %dist_attrib = &gst_ishare_fwrules_get_parse_table ();

  $hash = &gst_parse_from_table ($dist_attrib{"fn"},
                                 $dist_attrib{"table"});
  return $hash;
}


sub gst_ishare_dhcp_get
{
  my %dist_attrib;
  my $hash;

  %dist_attrib = &gst_ishare_dhcp_get_parse_table ();

  $hash = &gst_parse_from_table ($dist_attrib{"fn"},
                                 $dist_attrib{"table"});
  return $hash;
}


sub gst_ishare_conf_set
{
  my ($values_hash) = @_;
  my (%dist_attrib, $old_hash);

  %dist_attrib = &gst_ishare_conf_get_replace_table ();

  $old_hash = &gst_network_conf_get ();
  $res = &gst_replace_from_table ($dist_attrib{"fn"}, $dist_attrib{"table"},
                                  $values_hash, $old_hash);

  return $res;
}


sub gst_ishare_fwrules_set
{
  my ($interface, $values_hash) = @_;
  my (%dist_attrib, $old_hash);

  %dist_attrib = &gst_ishare_fwrules_get_replace_table ();

  $$values_hash{"interface"} = $interface;
  $res = &gst_replace_from_table ($dist_attrib{"fn"}, $dist_attrib{"table"},
                                  $values_hash, $old_hash);
  delete $$values_hash{"interface"};

  return $res;
}


sub gst_ishare_dhcp_set
{
  my ($interface, $values_hash) = @_;
  my (%dist_attrib, $old_hash);

  %dist_attrib = &gst_ishare_dhcp_get_replace_table ();

  $$values_hash{"interface"} = $interface;
  $res = &gst_replace_from_table ($dist_attrib{"fn"}, $dist_attrib{"table"},
                                  $values_hash, $old_hash);
  delete $$values_hash{"interface"};

  return $res;
}


sub gst_ishare_conf_get_parse_table
{
  my %dist_map =
  (
   "redhat-7.0"   => "mandrake-7.2",
   "redhat-7.1"   => "mandrake-7.2",
   "redhat-7.2"   => "mandrake-7.2",
   "mandrake-7.2" => "mandrake-7.2",
   "debian-2.2"   => "mandrake-7.2",
   "debian-woody" => "mandrake-7.2"
   );

  my %dist_tables =
      (
       "mandrake-7.2" =>
       {
         fn => {},
         table =>
             [
              [ "interface", \&gst_network_interfaces_get ],
              [ "fwrules",   \&gst_ishare_fwrules_get     ],
              [ "dhcp",      \&gst_ishare_dhcp_get        ],
              ]
              }
       );

  my $dist = $dist_map {$gst_dist};
  return %{$dist_tables{$dist}} if $dist;

  &gst_report ("platform_no_table", $gst_dist);
  return undef;
}

sub gst_ishare_fwrules_get_parse_table
{
  my %dist_map =
  (
   "redhat-7.0"   => "mandrake-7.2",
   "redhat-7.1"   => "mandrake-7.2",
   "redhat-7.2"   => "mandrake-7.2",
   "mandrake-7.2" => "mandrake-7.2",
   "debian-2.2"   => "mandrake-7.2",
   "debian-woody" => "mandrake-7.2"
   );

  my %dist_tables =
      (
       "mandrake-7.2" =>
       {
         fn =>
         {
           PROC_IPCHAINS => "/proc/net/ip_fwchains",
           PROC_FORWARD  => "/proc/sys/net/ipv4/ip_forward",
           PROC_MASQ     => "/proc/net/ip_masquerade"
         },
         table =>
             [
              [ "tools",        \&gst_file_tool_installed,        "ipchains"    ],
              [ "kerneltool",   \&gst_file_exists,                PROC_IPCHAINS ],
              [ "configured",   \&gst_ishare_ipchains_configured, "%tools%", "%kerneltool%" ],
              [ "forwarding",   \&gst_file_exists,                PROC_FORWARD  ],
              [ "masquerading", \&gst_file_exists,                PROC_MASQ     ],
              [ "active",       \&gst_parse_kw,                   PROC_FORWARD, "1" ]
              ]
                },
       );

  my $dist = $dist_map {$gst_dist};
  return %{$dist_tables{$dist}} if $dist;

  &gst_report ("platform_no_table", $gst_dist);
  return undef;
}

sub gst_ishare_dhcp_get_parse_table
{
  my %dist_map =
  (
   "redhat-7.0"   => "mandrake-7.2",
   "redhat-7.1"   => "mandrake-7.2",
   "redhat-7.2"   => "mandrake-7.2",
   "mandrake-7.2" => "mandrake-7.2",
   "debian-2.2"   => "debian-2.2",
   "debian-woody" => "debian-2.2"
   );

  my %dist_tables =
      (
       "mandrake-7.2" =>
       {
         fn =>
         {
           DHCPD_CONF    => "/etc/dhcpd.conf",
           DHCPD_SERVICE => "dhcpd",
           LINUX_CONF    => "/etc/conf.linuxconf"
         },
         table =>
             [
              [ "installed",   \&gst_service_sysv_installed,  DHCPD_SERVICE ],
              [ "configured",  \&gst_file_exists,             DHCPD_CONF    ],
              [ "active",      \&gst_service_sysv_get_status, DHCPD_SERVICE ],
              [ "dev",         \&gst_parse_split_first_array, LINUX_CONF, "DHCP.interface",
                                                              "[ \t]+", "[ \t]+" ],
              ]
                },
       "debian-2.2" =>
       {
         fn =>
         {
           DHCPD_CONF    => "/etc/dhcpd.conf",
           DHCPD_SERVICE => "dhcp",
         },
         table =>
             [
              [ "installed",   \&gst_service_sysv_installed,  DHCPD_SERVICE ],
              [ "configured",  \&gst_file_exists,             DHCPD_CONF    ],
              [ "active",      \&gst_service_sysv_get_status, DHCPD_SERVICE ],
              ]
                },
       );

  my $dist = $dist_map {$gst_dist};
  return %{$dist_tables{$dist}} if $dist;

  &gst_report ("platform_no_table", $gst_dist);
  return undef;
}

sub gst_ishare_conf_get_replace_table
{
  my %dist_map =
  (
   "redhat-7.0"   => "mandrake-7.2",
   "redhat-7.1"   => "mandrake-7.2",
   "redhat-7.2"   => "mandrake-7.2",
   "mandrake-7.2" => "mandrake-7.2",
   "debian-2.2"   => "mandrake-7.2",
   "debian-woody" => "mandrake-7.2"
   );

  my %dist_tables =
      (
       "mandrake-7.2" =>
       {
         fn => {},
         table =>
             [
              [ "interface", \&gst_network_interfaces_set, OLD_HASH ],
              [ "fwrules",   \&gst_ishare_fwrules_set,     "%interface%" ],
              [ "dhcp",      \&gst_ishare_dhcp_set,        "%interface%" ]
              ]
                },
       );

  my $dist = $dist_map {$gst_dist};
  return %{$dist_tables{$dist}} if $dist;

  &gst_report ("platform_no_table", $gst_dist);
  return undef;
}

sub gst_ishare_fwrules_get_replace_table
{
  my %dist_map =
  (
   "redhat-7.0"   => "mandrake-7.2",
   "redhat-7.1"   => "mandrake-7.2",
   "redhat-7.2"   => "mandrake-7.2",
   "mandrake-7.2" => "mandrake-7.2",
   "debian-2.2"   => "debian-2.2",
   "debian-woody" => "debian-2.2"
   );

  my %dist_tables =
      (
       "mandrake-7.2" =>
       {
         fn =>
         {
           IPCHAINS_CONF     => "/etc/sysconfig/ipchains",
           IPCHAINS_SERVICE  => "ipchains",
           PROC_FORWARD      => "/proc/sys/net/ipv4/ip_forward",
           SYSCONFIG_NETWORK => "/etc/sysconfig/network"
         },
         table =>
             [
              [ "active",     \&gst_replace_line_first,         PROC_FORWARD ],
              [ "active",     \&gst_replace_sh_bool,            SYSCONFIG_NETWORK, "FORWARD_IPV4" ],
              [ "overwrite",  \&gst_ishare_ipchains_save,       IPCHAINS_CONF, "%interface%", "%landev%" ],
              [ "active",     \&gst_service_sysv_force_status,  [8, IPCHAINS_SERVICE] ],
              ]
                },
       "debian-2.2" =>
       {
         fn =>
         {
           IPCHAINS_CONF     => "/etc/network/ipchains",
           IPCHAINS_SERVICE  => "setup-tools-ipchains",
           PROC_FORWARD      => "/proc/sys/net/ipv4/ip_forward",
           NETWORK_OPTIONS   => "/etc/network/options"
         },
         table =>
             [
              [ "active",     \&gst_replace_sh_bool,             NETWORK_OPTIONS, "ip_forward" ],          
              [ "active",     \&gst_replace_line_first,          PROC_FORWARD ],
              [ "active",     \&gst_service_sysv_install_script, IPCHAINS_SERVICE, "debian_ipchains" ],
              [ "overwrite",  \&gst_ishare_ipchains_save,        IPCHAINS_CONF, "%interface%", "%landev%" ],
              [ "active",     \&gst_service_sysv_force_status,   [5, IPCHAINS_SERVICE] ],
              ]
                },
       );

  my $dist = $dist_map {$gst_dist};
  return %{$dist_tables{$dist}} if $dist;

  &gst_report ("platform_no_table", $gst_dist);
  return undef;
}

sub gst_ishare_dhcp_get_replace_table
{
  my %dist_map =
  (
   "redhat-7.0"   => "mandrake-7.2",
   "redhat-7.1"   => "mandrake-7.2",
   "redhat-7.2"   => "mandrake-7.2",
   "mandrake-7.2" => "mandrake-7.2",
   "debian-2.2"   => "debian-2.2",
   "debian-woody" => "debian-2.2"
   );

  my %dist_tables =
      (
       "mandrake-7.2" =>
       {
         fn =>
         {
           DHCPD_CONF    => "/etc/dhcpd.conf",
           DHCPD_SERVICE => "dhcpd",
           LINUX_CONF    => "/etc/conf.linuxconf"
         },
         table =>
             [
              [ "dev",         \&gst_ishare_dhcp_set_devs,    LINUX_CONF, "%overwrite%" ],
              [ "dev",         \&gst_ishare_dhcp_set_conf,    DHCPD_CONF, "%overwrite%", "%interface%" ],
              [ "active",      \&gst_service_sysv_set_status, [65, DHCPD_SERVICE] ]
              ]
                },
       "debian-2.2" =>
       {
         fn =>
         {
           DHCPD_CONF    => "/etc/dhcpd.conf",
           DHCPD_SERVICE => "dhcp",
         },
         table =>
             [
              [ "dev",         \&gst_ishare_dhcp_set_conf,    DHCPD_CONF, "%overwrite%", "%interface%" ],
              [ "active",      \&gst_replace_sh_bool,         "/etc/init.d/dhcpd", "run_dhcpd", "1", "0" ],
              [ "active",      \&gst_service_sysv_set_status, [20, DHCPD_SERVICE] ]
              ]
              },
       );

  my $dist = $dist_map {$gst_dist};
  return %{$dist_tables{$dist}} if $dist;

  &gst_report ("platform_no_table", $gst_dist);
  return undef;
}
