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

# Shares configurator. Designed to be architecture and distribution independent.
#
# Copyright (C) 2000-2001 Ximian, Inc.
#
# Authors: Hans Petter Jansson <hpj@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.

# Configuration files affected:
#
# /etc/resolv.conf
# /etc/host.conf
# /etc/hosts
# /etc/sysconfig/network
# /etc/rc.config
# /etc/smb.conf

# Running programs affected:
#
# smbd
# nmbd
# ifconfig: check current interfaces and activate/deactivate.


BEGIN {
  $SCRIPTSDIR = "/usr/share/setup-tool-backends/scripts";
  if ($SCRIPTSDIR =~ /^@scriptsdir[@]/)
  {
      $SCRIPTSDIR = ".";
      $DOTIN = ".in";
  }
  
  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";
  require "$SCRIPTSDIR/filesys.pl$DOTIN";
  require "$SCRIPTSDIR/network.pl$DOTIN";
  require "$SCRIPTSDIR/share.pl$DOTIN";
}

# --- Tool information --- #

$name = "shares";
$version = "1.4.2";
@platforms = ("redhat-5.2", "redhat-6.0", "redhat-6.1", "redhat-6.2", "redhat-7.0", "redhat-7.1",
              "redhat-7.2", "redhat-8.0", "redhat-9",
              "openna-1.0",
              "mandrake-7.1", "mandrake-7.2", "mandrake-9.0", "mandrake-9.1", "mandrake-9.2",
              "mandrake-10.0", "mandrake-10.1",
              "blackpanther-4.0",
              "debian-3.0", "debian-3.1", "debian-4.0", "debian-testing",
              "suse-7.0", "suse-9.0",
              "turbolinux-7.0", "fedora-1", "fedora-2", "fedora-3",
              "pld-1.0", "pld-1.1", "pld-1.99",
              "conectiva-9", "conectiva-10",
              "slackware-9.1.0", "slackware-10.0.0", "slackware-10.1.0", "slackware-10.2.0",
              "gentoo", "vlos-1.2", "freebsd-5", "rpath");

$description =<<"end_of_description;";
       Configures network shares for import or export.
end_of_description;

# --- XML parsing ---

# Scan XML from standard input to an internal tree.

sub xml_parse
{
  my $tree;
  my $config = {};
  # Scan XML to tree.

  $tree = &gst_xml_scan;

  # Walk the tree recursively and extract configuration parameters.
  while (@$tree)
  {
    if ($$tree[0] eq "shares") { &xml_parse_shares ($$tree[1], $config); }

    shift @$tree;
    shift @$tree;
  }

  return($config);
}

# <shares>...</shares>

sub xml_parse_shares
{
  my ($tree, $config) = @_;

  shift @$tree;  # Skip attributes.

  while (@$tree)
  {
    if    ($$tree[0] eq "imports")    { &xml_parse_imports ($$tree[1], $config); }
    elsif ($$tree[0] eq "exports")    { &xml_parse_exports ($$tree[1], $config); }
    elsif ($$tree[0] eq "workgroup")  { $$config{"smb_config"}{"workgroup"}  = $$tree[1][2]; }
    elsif ($$tree[0] eq "winsuse")    { $$config{"smb_config"}{"winsuse"}    = $$tree[1][2]; }
    elsif ($$tree[0] eq "winsserver") { $$config{"smb_config"}{"winsserver"} = $$tree[1][2]; }
    elsif ($$tree[0] eq "smbdesc")    { $$config{"smb_config"}{"smbdesc"}    = $$tree[1][2]; }
    shift @$tree;
    shift @$tree;
  }
}

# <imports>...</imports>

sub xml_parse_imports
{
  my ($tree, $config) = @_;
  my $table;

  $table = &gst_filesys_table_new ();

  shift @$tree;  # Skip attributes.

  while (@$tree)
  {
    if ($$tree[0] eq "import") { &xml_parse_import ($$tree[1], $table); }

    shift @$tree;
    shift @$tree;
  }

  $$config{'imports'} = $table;
}

# <exports>...</exports>

sub xml_parse_exports
{
  my ($tree, $config) = @_;
  my ($smb_table, $nfs_table);

  $smb_table = &gst_share_smb_table_new ();
  $nfs_table = &gst_share_nfs_table_new ();

  shift @$tree;  # Skip attributes.

  while (@$tree)
  {
    if ($$tree[0] eq "export") { &xml_parse_export ($$tree[1], $smb_table, $nfs_table); }

    shift @$tree;
    shift @$tree;
  }

  $$config{'smb_exports'} = $smb_table;
  $$config{'nfs_exports'} = $nfs_table;
}

# <import>...</import>

sub xml_parse_import
{
  my ($tree, $table) = @_;
  my $type = "", $host = "", $path = "", $comment = "", $user = "",
     $password = "", $mounted = 0, $detected = 0, $point = "", $listed = 0;

  my $info = &gst_filesys_info_new ();

  $type = $$tree[0]->{type};
  shift @$tree;

  while (@$tree)
  {
    if    ($$tree[0] eq "host")     { $host     = &gst_xml_get_word  ($$tree[1]); }
    elsif ($$tree[0] eq "path")     { $path     = &gst_xml_get_word  ($$tree[1]); }
    elsif ($$tree[0] eq "user")     { $user     = &gst_xml_get_text  ($$tree[1]); }
    elsif ($$tree[0] eq "password") { $password = &gst_xml_get_text  ($$tree[1]); }
    elsif ($$tree[0] eq "comment")  { $comment  = &gst_xml_get_text  ($$tree[1]); }
    elsif ($$tree[0] eq "point")    { $point    = &gst_xml_get_word  ($$tree[1]); }
    elsif ($$tree[0] eq "mounted")  { $mounted  = &gst_xml_get_state ($$tree[1]); }
    elsif ($$tree[0] eq "detected") { $detected = &gst_xml_get_state ($$tree[1]); }
    elsif ($$tree[0] eq "listed")   { $listed   = &gst_xml_get_state ($$tree[1]); }

    shift @$tree;
    shift @$tree;
  }

  &gst_filesys_info_set_network_host ($info, $host);
  &gst_filesys_info_set_network_path ($info, $path);
#  &gst_filesys_info_set_comment      ($info, $comment);
  &gst_filesys_info_set_permanent    ($info, $listed);
  &gst_filesys_info_set_mounted      ($info, $mounted);
  &gst_filesys_info_set_detected     ($info, $detected);
  &gst_filesys_info_set_point        ($info, $point);

  if ($type eq "nfs")
  {
    &gst_filesys_info_set_fs         ($info, "nfs");
    &gst_filesys_info_set_option     ($info, "soft", "");
    &gst_filesys_info_remove_option  ($info, "hard");
  }
  else
  {
    &gst_filesys_info_set_fs         ($info, "smbfs");
    &gst_filesys_info_set_option     ($info, "username", ($user eq "")     ? " " : $user);
    &gst_filesys_info_set_option     ($info, "password", ($password eq "") ? " " : $password);
  }

  &gst_filesys_table_add ($table, $info);
}

# <export>...</export>

sub xml_parse_export
{
  my ($tree, $smb_table, $nfs_table) = @_;
  my $type = "";
  my $info;

  $type = $$tree[0]->{type};
  shift @$tree;
  
  if ($type eq "nfs")
  {
    my $path = "";
    my $client_table = &gst_share_nfs_client_table_new ();

    $info = gst_share_nfs_info_new ();

    while (@$tree)
    {
      if    ($$tree[0] eq "path")       { $path = &gst_xml_get_pcdata ($$tree[1]);     }
      elsif ($$tree[0] eq "allow")      { &xml_parse_allow ($$tree[1], $client_table); }

      shift @$tree;
      shift @$tree;
    }
    
    if ($path ne "")
    {
      &gst_share_nfs_info_set_point        ($info, $path);
      &gst_share_nfs_info_set_client_table ($info, $client_table);
      &gst_share_nfs_table_add             ($nfs_table, $info);
    }
  }
  elsif ($type eq "smb")
  {
    my $name = "", $path = "", $comment = "", $enabled = 0, $browseable = 0,
       $public = 0, $writeable = 0;

    $info = gst_share_smb_info_new ();

    while (@$tree)
    {
      if    ($$tree[0] eq "name")       { $name       = &gst_xml_get_word   ($$tree[1]); }
      elsif ($$tree[0] eq "path")       { $path       = &gst_xml_get_pcdata ($$tree[1]); }
      elsif ($$tree[0] eq "comment")    { $comment    = &gst_xml_get_text   ($$tree[1]); }
      elsif ($$tree[0] eq "enabled")    { $enabled    = &gst_xml_get_state  ($$tree[1]); }
      elsif ($$tree[0] eq "browse")     { $browseable = &gst_xml_get_state  ($$tree[1]); }
      elsif ($$tree[0] eq "public")     { $public     = &gst_xml_get_state  ($$tree[1]); }
      elsif ($$tree[0] eq "write")      { $writeable  = &gst_xml_get_state  ($$tree[1]); }

      shift @$tree;
      shift @$tree;
    }

    if ($path ne "")
    {
      &gst_share_smb_info_set_name    ($info, $name);
      &gst_share_smb_info_set_point   ($info, $path);
      &gst_share_smb_info_set_comment ($info, $comment);
      &gst_share_smb_info_set_enabled ($info, $enabled);
      &gst_share_smb_info_set_browse  ($info, $browseable);
      &gst_share_smb_info_set_public  ($info, $public);
      &gst_share_smb_info_set_write   ($info, $writeable);
      &gst_share_smb_table_add        ($smb_table, $info);
    }
  }
  else
  {
    # Unsupported share type.
    
    return;
  }
}

sub xml_parse_allow
{
  my ($tree, $client_table) = @_;
  my $pattern = "";
  my $write = 0;

  shift @$tree;  # No attributes.

  while (@$tree)
  {
    if    ($$tree[0] eq "pattern") { $pattern = &gst_xml_get_word  ($$tree[1]); }
    elsif ($$tree[0] eq "write")   { $write   = &gst_xml_get_state ($$tree[1]); }

    shift @$tree;
    shift @$tree;
  }

  my $info = &gst_share_nfs_client_info_new ();
  &gst_share_nfs_client_info_set_pattern ($info, $pattern);
  &gst_share_nfs_client_info_set_write   ($info, $write);
  &gst_share_nfs_client_table_add        ($client_table, $info);
}

# --- XML printing --- #

sub xml_print_import_common  # filesys_info
{
  my ($fsinfo) = @_;
  my ($host, $path, $point);

  $point = &gst_filesys_info_get_point        ($fsinfo);
  $host  = &gst_filesys_info_get_network_host ($fsinfo);
  $path  = &gst_filesys_info_get_network_path ($fsinfo);

  &gst_xml_print_pcdata    ("host",     $host);
  &gst_xml_print_pcdata    ("path",     $path);
  &gst_xml_print_pcdata    ("point",    $point);
  &gst_xml_print_state_tag ("listed",   &gst_filesys_info_get_permanent ($fsinfo));
  &gst_xml_print_state_tag ("mounted",  &gst_filesys_info_get_mounted   ($fsinfo));
  &gst_xml_print_state_tag ("detected", &gst_filesys_info_get_detected  ($fsinfo));
}

sub xml_print_import_nfs
{
  my ($fsinfo) = @_;

  &gst_xml_print_vspace ();
  &gst_xml_print_line ("<import type='nfs'>");
  &gst_xml_enter ();

  &xml_print_import_common ($fsinfo);

  &gst_xml_leave ();
  &gst_xml_print_line ("</import>");
  &gst_xml_print_vspace ();
}

sub xml_print_import_smb
{
  my ($fsinfo) = @_;
  my ($user, $password);

  $user     = &gst_filesys_info_get_option ($fsinfo, "username");
  $user     = "" if ($user =~ /^ +$/);
  $password = &gst_filesys_info_get_option ($fsinfo, "password");
  $password = "" if ($password =~ /^ +$/);

  &gst_xml_print_vspace ();
  &gst_xml_print_line ("<import type='smb'>");
  &gst_xml_enter ();

  &xml_print_import_common ($fsinfo);
  if ($user ne "")     { &gst_xml_print_pcdata ("user",     $user); }
  if ($password ne "") { &gst_xml_print_pcdata ("password", $password); }

  &gst_xml_leave ();
  &gst_xml_print_line ("</import>");
  &gst_xml_print_vspace ();
}

sub xml_print_export_nfs
{
  my ($info) = @_;
  my $client_table;

  $client_table = &gst_share_nfs_info_get_client_table ($info);

  &gst_xml_print_vspace ();
  &gst_xml_print_line ("<export type='nfs'>");
  &gst_xml_enter ();

  &gst_xml_print_pcdata ("name", "unknown");
  &gst_xml_print_pcdata ("path", &gst_share_nfs_info_get_point ($info));

  for $client (@$client_table)
  {
    &gst_xml_container_enter ("allow");
    &gst_xml_print_pcdata    ("pattern", &gst_share_nfs_client_info_get_pattern ($client));
    &gst_xml_print_state_tag ("write",   &gst_share_nfs_client_info_get_write   ($client));
    &gst_xml_container_leave ();
  }

  &gst_xml_leave ();
  &gst_xml_print_line ("</export>");
  &gst_xml_print_vspace ();
}

sub xml_print_export_smb
{
  my ($info) = @_;

  &gst_xml_print_vspace ();
  &gst_xml_print_line ("<export type='smb'>");
  &gst_xml_enter ();

  &gst_xml_print_pcdata    ("name",       &gst_share_smb_info_get_name    ($info));
  &gst_xml_print_pcdata    ("path",       &gst_share_smb_info_get_point   ($info));
  &gst_xml_print_pcdata    ("comment",    &gst_share_smb_info_get_comment ($info));
  &gst_xml_print_state_tag ("enabled",    &gst_share_smb_info_get_enabled ($info));
  &gst_xml_print_state_tag ("browse",     &gst_share_smb_info_get_browse  ($info));
  &gst_xml_print_state_tag ("public",     &gst_share_smb_info_get_public  ($info));
  &gst_xml_print_state_tag ("write",      &gst_share_smb_info_get_write   ($info));

  &gst_xml_leave ();
  &gst_xml_print_line ("</export>");
  &gst_xml_print_vspace ();
}

sub xml_print
{
  my ($config) = @_;
  my ($tools, $smb_config, $import_table, $smb_export_table, $nfs_export_table, $i);

  $tools            = $$config{"tools"};
  $smb_config       = $$config{"smb_config"};
  $import_table     = $$config{"imports"};
  $smb_export_table = $$config{"smb_exports"};
  $nfs_export_table = $$config{"nfs_exports"};

  &gst_xml_print_begin ();

  foreach $i (keys (%$tools))
  {
    &gst_xml_print_pcdata ($i, $$tools{$i});
  }
  &gst_xml_print_vspace ();

  foreach $i (keys (%$smb_config))
  {
    &gst_xml_print_pcdata ($i, $$smb_config{$i});
  }
  &gst_xml_print_vspace ();

  if (scalar @$import_table)
  {
    &gst_xml_container_enter ("imports");

    foreach $i (@$import_table)
    {
      my ($fs);
      
      $fs = &gst_filesys_info_get_fs ($i);
      
      if    ($fs eq "nfs")   { &xml_print_import_nfs ($i); }
      elsif ($fs eq "smbfs") { &xml_print_import_smb ($i); }
      else                   { next; }
    }
    
    &gst_xml_container_leave ();
    &gst_xml_print_vspace ();
  }

  if (scalar @$smb_export_table || scalar @$nfs_export_table)
  {
    &gst_xml_container_enter ("exports");
    
    foreach $i (@$smb_export_table)
    {
      &xml_print_export_smb ($i);
    }

    foreach $i (@$nfs_export_table)
    {
      &xml_print_export_nfs ($i);
    }

    &gst_xml_container_leave ();
  }

  &gst_xml_print_end ();
}

# Misc

sub remove_shares_from_filesys_table
{
  my ($table) = @_;
  my @ltable = @$table;  # We need a shallow copy.

  for $info (@ltable)
  {
    my $fs = &gst_filesys_info_get_fs ($info);

    if ($fs eq "smbfs" || $fs eq "nfs")
    {
      &gst_filesys_table_remove ($table, $info);
    }
  }
}

# Configuration handling.

sub gst_installed_daemons_parse_table
{
  my %dist_map =
    (
     "redhat-5.2"   => "redhat-6.2",
     "redhat-6.0"   => "redhat-6.2",
     "redhat-6.1"   => "redhat-6.2",
     "redhat-6.2"   => "redhat-6.2",
     "redhat-7.0"   => "redhat-6.2",
     "redhat-7.1"   => "redhat-6.2",
     "redhat-7.2"   => "redhat-6.2",
     "redhat-8.0"   => "redhat-6.2",
     "redhat-9"     => "redhat-6.2",
     "openna-1.0"   => "redhat-6.2",
     "mandrake-7.1" => "redhat-6.2",
     "mandrake-7.2" => "redhat-6.2",
     "mandrake-9.0" => "redhat-6.2",
     "mandrake-9.1" => "redhat-6.2",
     "mandrake-9.2" => "redhat-6.2",
     "mandrake-10.0" => "redhat-6.2",
     "mandrake-10.1" => "redhat-6.2",
     "blackpanther-4.0" => "redhat-6.2",
     "conectiva-9"  => "redhat-6.2", 
     "conectiva-10" => "redhat-6.2", 
     "debian-3.0"     => "debian-2.2",
     "debian-3.1"     => "debian-2.2",
     "debian-4.0"     => "debian-2.2",
     "debian-testing" => "debian-2.2",
     "suse-7.0"     => "redhat-6.2",
     "suse-9.0"     => "suse-9.0",
     "suse-9.1"     => "suse-9.0",
     "turbolinux-7.0"  => "redhat-6.2",
     "pld-1.0"      => "redhat-6.2",
     "pld-1.1"      => "redhat-6.2",
     "pld-1.99"     => "redhat-6.2",
     "fedora-1"     => "redhat-6.2",
     "fedora-2"     => "redhat-6.2",
     "fedora-3"     => "redhat-6.2",
     "rpath"        => "redhat-6.2",
     "vine-3.0"     => "redhat-6.2",
     "vine-3.1"     => "redhat-6.2",
     "slackware-9.1.0" => "slackware-9.1.0",
     "slackware-10.0.0" => "slackware-9.1.0",
     "slackware-10.1.0" => "slackware-9.1.0",
     "slackware-10.2.0" => "slackware-9.1.0",
     "gentoo"       => "gentoo",
     "vlos-1.2"     => "gentoo",
     "freebsd-5"    => "freebsd-5",
     "freebsd-6"    => "freebsd-5",
    );

  my %dist_table =
    (
     "redhat-6.2" => {
       table => [
         [ "smbuse",        \&gst_service_sysv_get_status_any, "smbd", "nmbd" ],
         [ "smbinstalled",  \&gst_service_sysv_installed,      "smb" ],
         [ "nfsuse",        \&gst_service_sysv_get_status,     "rpc.nfsd" ],
         [ "nfsinstalled",  \&gst_service_installed,           "nfsserver" ],
       ]},

     "debian-2.2" => {
       table => [
         [ "smbuse",        \&gst_service_sysv_get_status_any, "smbd", "nmbd" ],
         [ "smbinstalled",  \&gst_service_sysv_installed,      "samba" ],
         [ "nfsuse",        \&gst_service_sysv_get_status,     "rpc.nfsd" ],
         [ "nfsinstalled",  \&gst_service_list_any_installed,  "nfs-user-server", "nfs-kernel-server" ],
       ]},

     "suse-9.0" => {
       table => [
         [ "smbuse",        \&gst_service_get_status,         "smb" ],
         [ "smbinstalled",  \&gst_service_installed,          "smb" ],
         [ "nfsuse",        \&gst_service_sysv_get_status,    "rpc.nfsd" ],
         [ "nfsinstalled",  \&gst_service_installed,          "nfsserver" ],
       ]},

     "slackware-9.1.0" => {
       table => [
         [ "smbuse",        \&gst_service_sysv_get_status_any, "smbd", "nmbd" ],
         [ "smbinstalled",  \&gst_service_installed,           "/etc/rc.d/rc.samba" ],
         [ "nfsuse",        \&gst_service_sysv_get_status,     "rpc.nfsd" ],
         [ "nfsinstalled",  \&gst_service_installed,           "/etc/rc.d/rc.nfsd" ],
       ]},

     "gentoo" => {
       table => [
         [ "smbuse",        \&gst_service_gentoo_get_status,  "samba" ],
         [ "smbinstalled",  \&gst_service_installed,          "samba" ],
         [ "nfsuse",        \&gst_service_sysv_get_status,    "rpc.nfsd" ],
         [ "nfsinstalled",  \&gst_service_installed,          "nfs" ],
       ]},

     "freebsd-5" => {
       table => [
         [ "smbuse",        \&gst_service_rcng_get_status, "smbd" ],
         [ "smbinstalled",  \&gst_service_installed,       "samba" ],
         # FIXME: How's the nfs stuff in FreeBSD?
       ]},
    );

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

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

sub get_installed_daemons
{
  my ($hash, %dist_attrib);

  %dist_attrib = &gst_installed_daemons_parse_table ();
  $hash = &gst_parse_from_table (undef, $dist_attrib{"table"});
  return $hash;
}

#sub get_configured_imports
#{
#  my ($imports, $listed_imports, $mounted_imports);

#  $listed_imports  = &gst_filesys_fstab_parse (&distro_file ("fstab"));
#  $mounted_imports = &gst_filesys_mtab_parse  (&distro_file ("mtab"));

#  &gst_filesys_table_set_permanent_true ($listed_imports);
#  &gst_filesys_table_set_mounted_true   ($mounted_imports);

#  $imports = &gst_filesys_table_merge_superset ($mounted_imports, $listed_imports);
#  return $imports;
#}

sub get_distro_files
{
  my ($smb_comb, $exports);

  %dist_attrib = &gst_network_get_parse_table ();
  $smb_conf    = $dist_attrib{"fn"}{"SMB_CONF"};

  # This is pretty standard
  $exports     = "/etc/exports";

  return ($smb_conf, $exports);
}

sub get_configured_exports
{
  my ($smb_exports, $nfs_exports);
  my (%dist_attrib, $smb_conf, $exports);

  ($smb_conf, $exports) = &get_distro_files ();
  
  $smb_exports = &gst_share_parse_smb_conf    ($smb_conf);
  $nfs_exports = &gst_share_parse_nfs_exports ($exports);

  return ($smb_exports, $nfs_exports);
}

sub get_smb_config
{
  my ($smb_conf, $exports);
  my %config;

  ($smb_conf, $exports) = &get_distro_files ();

  $$config{"workgroup"}  = &gst_parse_ini ($smb_conf, "global", "workgroup");
  $$config{"smbdesc"}    = &gst_parse_ini ($smb_conf, "global", "server string");
  $$config{"winsserver"} = &gst_parse_ini ($smb_conf, "global", "wins server");
  $$config{"winsuse"}    = &gst_parse_ini_bool ($smb_conf, "global", "wins support");

  return $config;
}

# Top-level actions.

sub get
{
  my ($tools, $smb_config, $imports, $smb_exports, $nfs_exports);
  my $config = {};

  $tools = &get_installed_daemons ();
  $smb_settings = &get_smb_config ();
#  $imports = &get_configured_imports ();
  ($smb_exports, $nfs_exports) = &get_configured_exports ();

  $$config{"tools"}       = $tools;
  $$config{"smb_config"}  = $smb_settings;
  $$config{"imports"}     = $imports;
  $$config{"smb_exports"} = $smb_exports;
  $$config{"nfs_exports"} = $nfs_exports;

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

sub set
{
  my $config;
#  my ($fs, $fs_no_shares, $fs_new_shares);
  my ($smb_conf, $exports);
#  my $imports;

  ($smb_conf, $exports) = &get_distro_files ();

  $config = &xml_parse ();

#  $imports = $$config{"imports"};
#  for $import (@$imports)
#  {
#    &gst_filesys_info_settings_to_options ($import);
#  }

#  $fs = &gst_filesys_fstab_parse (&distro_file ("fstab"));
#  &gst_filesys_table_set_permanent_true ($fs);

#  $fs_no_shares = &gst_filesys_table_dup ($fs);
#  &remove_shares_from_filesys_table ($fs_no_shares);

#  $fs_new_shares = &gst_filesys_table_merge_superset ($$config{"imports"}, $fs_no_shares);
#  $fs_new_shares = &gst_filesys_table_merge_subset ($fs_new_shares, $fs);

#  &gst_filesys_fstab_replace     (&distro_file ("fstab"),    $fs_new_shares);

  &gst_replace_ini ($smb_conf, "global", "workgroup",     $$config{"smb_config"}{"workgroup"});
  &gst_replace_ini ($smb_conf, "global", "server string", $$config{"smb_config"}{"smbdesc"});
  &gst_replace_ini ($smb_conf, "global", "wins server",   $$config{"smb_config"}{"winsserver"});
  &gst_replace_ini_bool ($smb_conf, "global", "wins support", $$config{"smb_config"}{"winsuse"});

  &gst_share_replace_smb_conf    ($smb_conf, $$config{"smb_exports"});
  &gst_share_replace_nfs_exports ($exports,  $$config{"nfs_exports"});

#  &gst_filesys_mount_sync_all (&distro_file ("fstab"), &distro_file ("mtab"), $$config{"imports"});

  &gst_report_end ();
}

sub filter
{
  my $config;

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

sub scan
{
  my %config;

  $config{"imports"} = &gst_share_scan_network_imports ();
  &gst_report_end ();
  &xml_print (\%config);
}

sub get_network_conf
{
  my ($hash, $ifaces, $i, @arr);

  $ifaces = &gst_network_interfaces_get_info ();

  foreach $i (keys %$ifaces)
  {
    if (($$ifaces{$i}{"enabled"} == 1)
        && ($$ifaces{$i}{"dev"} ne "lo"))
    {
      $$ifaces{$i}{"network"} = &gst_network_ipv4_calc_subnet ($$ifaces{$i}{"addr"},
                                                               $$ifaces{$i}{"mask"});
      push @arr, $$ifaces{$i};
    }
  }

  # network interface stuff
  $hash = &gst_network_conf_get ();
  &gst_report_end ();

  &gst_xml_print_begin ("network-conf");
  &network_xml_print_statichost ($hash);
  &gst_xml_print_structure (\@arr, "interface");
  &gst_xml_print_end ("network-conf");
}

# --- 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_network_conf" => [ \&get_network_conf, [], "Gets the hosts info plus the interfaces networks." ],
  "scan_network" =>     [ \&scan,   [], "Looks for smb or nfs shares in the network." ]
    };

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