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

# Time configurator. Designed to be architecture- and distribution independent.
#
# Copyright (C) 2000-2001 Ximian, Inc.
#
# Authors: Chema Celorio <chema@ximian.com>
#          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.

# Best viewed with 100 columns of width.


BEGIN {
  $SCRIPTSDIR = "/usr/share/setup-tool-backends/scripts";
  if ($SCRIPTSDIR =~ /^@scriptsdir[@]/)
  {
      $SCRIPTSDIR = ".";
      $DOTIN = ".in";
  }
  
  require "$SCRIPTSDIR/ishare.pl$DOTIN";
  require "$SCRIPTSDIR/general.pl$DOTIN";
  require "$SCRIPTSDIR/platform.pl$DOTIN";
  require "$SCRIPTSDIR/util.pl$DOTIN";
  require "$SCRIPTSDIR/file.pl$DOTIN";
  require "$SCRIPTSDIR/xml.pl$DOTIN";
}


# --- Tool information --- #

$name = "internetsharing";
$version = "1.4.2";
@platforms = ("redhat-7.0", "redhat-7.1", "redhat-7.2",
              
              "mandrake-7.2");

$description =<<"end_of_description;";
       Sets up firewall rules for a basic internet sharing (masq)
       network.
end_of_description;


# --- XML parsing --- #

# Scan XML from standard input to an internal tree.

sub xml_parse
{
  my ($tree, %hash, $elem);
  
  # Scan XML to tree.

  $tree = &gst_xml_scan ();

  # Walk the tree recursively and extract configuration parameters.
  # This is the top level - find and enter the "networking" tag.

  while ($elem = shift @$tree)
  {
    if   ($elem eq "internetsharing") { &xml_parse_internetsharing (shift @$tree, \%hash); }
    else { &gst_report ("xml_unexp_tag", $elem); shift @$tree; }
  }

  return (\%hash);
}


sub xml_parse_internetsharing
{
  my ($tree, $hash) = @_;
  my ($elem, %interface);
  
  shift @$tree;  # Skip attributes.
  
  while ($elem = shift @$tree)
  {
      if    ($elem eq "fwrules")   { $$hash{"fwrules"} = &xml_parse_fwrules (shift @$tree);        }
      elsif ($elem eq "dhcp")      { $$hash{"dhcp"}    = &xml_parse_dhcp    (shift @$tree);        }
      elsif ($elem eq "interface") { &gst_network_xml_parse_interface (shift @$tree, \%interface); }
      else  { &gst_report ("xml_unexp_tag", $elem); shift @$tree; }
  }
  
  $$hash{"interface"} = \%interface unless scalar keys %interface == 0;
}


sub xml_parse_fwrules
{
  my ($tree) = @_;
  my ($elem, $hash, $landevs);

  $hash = {};
  $landevs = [];
  shift @$tree;  # Skip attributes.

  while ($elem = shift @$tree)
  {
      if    ($elem eq "tools")        { $$hash{"tools"}        = &gst_xml_get_pcdata (shift @$tree); }
      elsif ($elem eq "kerneltool")   { $$hash{"kerneltool"}   = &gst_xml_get_pcdata (shift @$tree); }
      elsif ($elem eq "configured")   { $$hash{"configured"}   = &gst_xml_get_pcdata (shift @$tree); }
      elsif ($elem eq "forwarding")   { $$hash{"forwarding"}   = &gst_xml_get_pcdata (shift @$tree); }
      elsif ($elem eq "masquerading") { $$hash{"masquerading"} = &gst_xml_get_pcdata (shift @$tree); }
      elsif ($elem eq "overwrite")    { $$hash{"overwrite"}    = &gst_xml_get_pcdata (shift @$tree); }
      elsif ($elem eq "active")       { $$hash{"active"}       = &gst_xml_get_pcdata (shift @$tree); }
      elsif ($elem eq "landev")       { push @$landevs, &gst_xml_get_pcdata (shift @$tree); }
      else  { &gst_report ("xml_unexp_tag", $elem); shift @$tree; }
  }

  $$hash{"landev"} = $landevs;

  return $hash;
}


sub xml_parse_dhcp
{
  my ($tree) = @_;
  my ($elem, $hash, $devs);

  $hash = {};
  $devs = [];
  shift @$tree;  # Skip attributes.

  while ($elem = shift @$tree)
  {
      if    ($elem eq "installed")    { $$hash{"installed"}  = &gst_xml_get_pcdata (shift @$tree); }
      elsif ($elem eq "configured")   { $$hash{"configured"} = &gst_xml_get_pcdata (shift @$tree); }
      elsif ($elem eq "overwrite")    { $$hash{"overwrite"}  = &gst_xml_get_pcdata (shift @$tree); }
      elsif ($elem eq "active")       { $$hash{"active"}     = &gst_xml_get_pcdata (shift @$tree); }
      elsif ($elem eq "dev")          { push @$devs, &gst_xml_get_pcdata (shift @$tree); }
      else  { &gst_report ("xml_unexp_tag", $elem); shift @$tree; }
  }

  $$hash{"dev"} = $devs;

  return $hash;
}


# --- XML printing --- #


sub xml_print
{
  my ($h) = @_;

  &gst_xml_print_begin ();
  &gst_xml_print_hash ($$h{"fwrules"}, "fwrules");
  &gst_xml_print_hash ($$h{"dhcp"},    "dhcp");
  &gst_xml_print_hash_hash ($$h{"interface"}, "interface");
  &gst_xml_print_end ();
}

# Main operations

sub get
{
  my $hash;
  
  $hash = &gst_ishare_conf_get ();

  &gst_report_end ();
  &xml_print ($hash);
}


sub get_interfaces
{
  my $hash;

  $hash = &gst_network_interfaces_get ();
  
  &gst_report_end ();
  &gst_xml_print_begin ();
  &gst_xml_print_hash_hash ($hash, "interface");
  &gst_xml_print_end ();
}


sub set
{
  my $hash;

  $hash = &xml_parse ();
  &gst_ishare_conf_set ($hash);
  &gst_report_end ();
}


# --- Filter config: XML in, XML out --- #


sub filter
{
  my $hash;

  $hash = &xml_parse ();
  &gst_report_end ();
  &xml_print ($hash);
}

# --- Main --- #

# get, set and filter are special cases that don't need more parameters than a ref to their function.
# Read general.pl.in:gst_run_directive to know about the format of this hash.

$directives = {
  "get"            => [ \&get,    [], "" ],
  "set"            => [ \&set,    [], "" ],
  "filter"         => [ \&filter, [], "" ],
  "get_interfaces" => [ \&get_interfaces, [], "Get the interface tags only." ]
    };

$tool = &gst_init ($name, $version, $description, $directives, @ARGV);
&gst_platform_ensure_supported ($tool, @platforms);
&gst_run ($tool);

