#!/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: Hans Petter Jansson <hpj@ximian.com>
#          Grzegorz Golawski <grzegol@pld-linux.org> (PLD Support)
#          James Ogley <james@usr-local-bin.org> (SuSE 9.0 support)
#
# 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/used:
#
# /usr/share/zoneinfo/zone.tab
# /etc/ntp.conf
# /etc/ntp/step-tickers
# /etc/localtime

# Running programs affected/used:
#
# date

use File::Copy;

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/service.pl$DOTIN";
  require "$SCRIPTSDIR/parse.pl$DOTIN";
  require "$SCRIPTSDIR/replace.pl$DOTIN";
}


# --- Tool information --- #

$name = "time";
$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-7.3", "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",
              "debian-3.0", "debian-3.1", "debian-4.0", "debian-testing",
              "suse-7.0", "suse-9.0", "suse-9.1", "turbolinux-7.0",
              "slackware-8.0.0", "slackware-8.1", "slackware-9.0.0", "slackware-9.1.0", "slackware-10.0.0", "slackware-10.1.0", "slackware-10.2.0",
              "gentoo", "vlos-1.2", "pld-1.0", "pld-1.1", "pld-1.99", "fedora-1", "fedora-2", "fedora-3", "rpath",
              "vine-3.0", "vine-3.1",
	      "archlinux",
              "freebsd-5", "freebsd-6");

$description =<<"end_of_description;";
       Configures your system clock, timezone and time server list.
end_of_description;

$progress_max = 365;


# --- XML parsing --- #


# Scan XML from standard input to an internal tree.

sub xml_parse
{
  my ($tree, %hash);
  
  # 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 "time" tag.

  while (@$tree)
  {
    if ($$tree[0] eq "time") { &xml_parse_time($$tree[1], \%hash); }

    shift @$tree;
    shift @$tree;
  }

  return(\%hash);
}


# <time>...</time>

sub xml_parse_time
{
  my $tree = $_[0];
  my $hash = $_[1];

  shift @$tree;  # Skip attributes.

  while (@$tree)
  {
    if    ($$tree[0] eq "local_time"){ $$hash{"local_time"} = &xml_parse_local_time ($$tree[1]); }
    elsif ($$tree[0] eq "timezone") { $$hash{"timezone"} = &gst_xml_get_word ($$tree[1]); }
    elsif ($$tree[0] eq "sync")     { $$hash{"sync"} = &xml_parse_sync ($$tree[1], $hash); }

    shift @$tree;
    shift @$tree;
  }
}


sub xml_parse_sync
{
  my $tree = $_[0];
  my $hash = $_[1];
  my @sync;

  $$hash{"sync_active"} = &gst_util_read_boolean($$tree[0]->{active});
  shift @$tree;

  while (@$tree)
  {
    if ($$tree[0] eq "server")  { push (@sync, &gst_xml_get_word($$tree[1])); }
    
    shift @$tree;
    shift @$tree;
  }

  return \@sync;
}


sub xml_parse_local_time
{
  my $tree = $_[0];
  my $hash;

  shift @$tree;

  while (@$tree)
  {
    if    ($$tree[0] eq "year")     { $$hash{"year"} = &gst_xml_get_word($$tree[1]); }
    elsif ($$tree[0] eq "month")    { $$hash{"month"} = &gst_xml_get_word($$tree[1]); }
    elsif ($$tree[0] eq "monthday") { $$hash{"monthday"} = &gst_xml_get_word($$tree[1]); }
    elsif ($$tree[0] eq "hour")     { $$hash{"hour"} = &gst_xml_get_word($$tree[1]); }
    elsif ($$tree[0] eq "minute")   { $$hash{"minute"} = &gst_xml_get_word($$tree[1]); }
    elsif ($$tree[0] eq "second")   { $$hash{"second"} = &gst_xml_get_word($$tree[1]); }
    
    shift @$tree;
    shift @$tree;
  }

  return $hash;
}

# --- XML printing --- #


sub xml_print
{
  my $h = $_[0];
  my @sync;
  my @scalar_keys = qw (timezone ntpinstalled);

  $sync = $$h{"sync"};

  &gst_xml_print_begin ();

  &gst_xml_print_vspace ();
  &gst_xml_print_hash ($$h{"local_time"}, "local_time");
  &gst_xml_print_vspace ();
  
  &gst_xml_print_vspace ();
  &gst_xml_print_line ("<sync active='" . &gst_print_boolean_yesno ($$h{'sync_active'}) . "'>\n");
  
  &gst_xml_enter ();
  foreach $server (@$sync)
  {
    &gst_xml_print_line ("<server>$server</server>\n");
  }
  &gst_xml_leave ();
  
  &gst_xml_print_line ("</sync>\n");
  &gst_xml_print_vspace ();

  &gst_xml_print_scalars ($h, @scalar_keys);
  &gst_xml_print_vspace ();

  &gst_xml_print_end ();
}

# Main operations

sub get
{
  my $hash;

  $hash = &conf_get ();

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


sub set
{
  my $hash;

  $hash = &xml_parse ();

  &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, [], "" ]
    };

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

# Portable code.

sub time_get_local_time
{
  my (%h, $trash);

  ($h{"second"}, $h{"minute"}, $h{"hour"}, $h{"monthday"}, $h{"month"}, $h{"year"},
   $trash, $trash, $trash) = localtime (time);

  $h{"month"}++;
  $h{"year"} += 1900;

  return \%h;
}

sub time_get_rh62_zone
{
  my ($local_time_file, $zoneinfo_dir) = @_;
  local *TZLIST;
  my $zone;
  my $size_search;
  my $size_test;

  *TZLIST = &gst_file_open_read_from_names($zoneinfo_dir . "/zone.tab");
  if (not *TZLIST) { return; }

  &gst_report ("time_timezone_scan");

  # Get the filesize for /etc/localtime so that we don't have to execute
  # a diff for every file, only for file with the correct size. This speeds
  # up loading 
  $size_search = (stat ($local_time_file))[7];

  while (<TZLIST>)
  {
    if (/^\#/) { next; }                   # Skip comments.
    ($d, $d, $zone) = split /[\t ]+/, $_;  # Get 3rd column.
    chomp $zone;                           # Remove linefeeds.


    # See if this zone file matches the installed one.
    &gst_report ("time_timezone_cmp", $zone);
    &gst_print_progress();
    $size_test = (stat("$zoneinfo_dir/$zone"))[7];
    if ($size_test eq $size_search)
    {
      if (!&gst_file_run ("diff $zoneinfo_dir/$zone $local_time_file"))
      {
        # Found a match.
        last;
      }
    }
    
    $zone = "";
  }
  
  return $zone;
  close (TZLIST);
}

sub conf_get
{
  my %dist_attrib;
  my $hash;

  %dist_attrib = &conf_get_parse_table ();

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

  return $hash;
}

# This function will force date format when setting time
sub time_change_date
{
  my ($time) = @_;
  my ($plat) = $$tool {"system"};
  my ($command);

  my $plat_table = {
    "Linux"   => "date %02d%02d%02d%02d%04d.%02d",
    "FreeBSD" => "date -f %%m%%d%%H%%M%%Y.%%S  %02d%02d%02d%02d%04d.%02d"
  };

  $command = sprintf ($$plat_table {$plat},
                      $$time{"month"}, $$time{"monthday"},
                      $$time{"hour"},  $$time{"minute"}, 
                      $$time{"year"},  $$time{"second"});

  &gst_report ("time_localtime_set", $command);

  return &gst_file_run ($command);
}

sub time_set_local_time
{
  my ($time) = @_;
  my ($res, $xscreensaver_owners);

  &gst_report_enter ();

  # Kill screensaver, so it doesn't confuse the users.
  $xscreensaver_owners = &gst_service_proc_get_owners ("xscreensaver");
  &gst_service_proc_stop_all  ("xscreensaver");

  $res = &time_change_date ($time);

  # Restart screensaver.
  &gst_service_proc_start_all ("xscreensaver -no-splash", $xscreensaver_owners);

  &gst_report_leave ();
  return -1 if $res;
  return 0;
}

sub time_set_archlinux_zone
{
	my ($localtime, $zonebase, $timezone) =@_;
	&gst_report_enter ();
	&gst_report ("time_timezone_set", $timezone);
	
	$tz = "$zonebase/$timezone";
	if (stat($tz) ne "")
	{
    my $rcconf = '/etc/rc.conf';
    open DATA, "$rcconf";
    my @rcconflines = <DATA>;
    close (DATA);
    open DATAOUT, ">", "$rcconf";

    foreach my $line (@rcconflines)
    {
      if ( $line =~ /\TIMEZONE=/i) 
      {
        $line = "TIMEZONE=$timezone\n";
      }

      print DATAOUT "$line";
    }
		
		close (DATAOUT);	
		unlink $localtime;
		&gst_report_enter ();
		$res = copy ($tz, $localtime);
		&gst_report_leave ();
		return -1 unless $res;
		return 0;
	}
	
	&gst_report_leave ();
	return -1;
}

sub time_set_rh62_zone
{
  my ($localtime, $zonebase, $timezone) = @_;

  &gst_report_enter ();
  &gst_report ("time_timezone_set", $timezone);

  $tz = "$zonebase/$timezone";

  if (stat($tz) ne "")
  {
    unlink $localtime;  # Important, since it might be a symlink.
    
    &gst_report_enter ();
    $res = copy ($tz, $localtime);
    &gst_report_leave ();
    return -1 unless $res;
    return 0;
  }

  &gst_report_leave ();
  return -1;
}

sub time_sync_hw_from_sys
{
  &gst_file_run ("hwclock --systohc");
  return 0;
}

sub time_replace_ntp_servers
{
  my ($file, $key, $re, $value) = @_;
  my ($fd, @line, @res);
  my ($buff, $i);
  my ($pre_space, $post_comment);
  my ($line_key, $val, $rest);
  my ($n, $ret);

  &gst_report_enter ();
  &gst_report ("replace_split", $key, $file);

  $buff = &gst_file_buffer_load ($file);
  
  foreach $i (@$buff)
  {
    $pre_space = $post_comment = "";

    chomp $i;

    $pre_space    = $1 if $i =~ s/^([ \t]+)//;
    $post_comment = $1 if $i =~ s/([ \t]*\#.*)//;
    
    if ($i ne "")
    {
      @line = split ($re, $i, 3);
      $line_key = shift (@line);
      $val      = shift (@line);
      $rest     = shift (@line);

      # found the key?
      if ($line_key eq $key)
      {
        $n = 0;

        while (@$value[$n] && (@$value[$n] ne $val))
        {
          $n++;
        }

        if (@$value[$n] ne $val)
        {
          $i = "";
          next;
        }

        delete @$value[$n];
        chomp $val;
        $i  = &set_value ($key, $val, $re) . " " . $rest;
      }
    }

    $i = $pre_space . $i . $post_comment . "\n";
  }

  foreach $i (@$value)
  {
#      print "$key  $i\n";
    push (@$buff, &set_value ($key, $i, $re) . "\n") if ($i ne "");
  }

  &gst_file_buffer_clean ($buff);
  $ret = &gst_file_buffer_save ($buff, $file);
  &gst_report_leave ();
  return $ret;
}

sub conf_set
{
  my $values_hash = $_[0];
  my %dist_attrib;

  # we need to init those values to start/stop ntp properly,
  # if the system is not sysV it will warn and return safely
  ($rcd_path, $initd_path, $relative_path) = &gst_service_sysv_get_paths ();

  %dist_attrib = &conf_get_replace_table ();

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

  &time_sync_hw_from_sys ();

  return $res;
}

sub conf_get_parse_table
{
  my %dist_map =
  (
   "redhat-6.0"      => "redhat-6.2",
   "redhat-6.1"      => "redhat-6.2",
   "redhat-6.2"      => "redhat-6.2",

   "redhat-7.0"      => "redhat-7.0",
   "redhat-7.1"      => "redhat-7.0",
   "redhat-7.2"      => "redhat-7.0",
   "redhat-7.3"      => "redhat-7.0",
   "redhat-8.0"      => "redhat-7.0",
   "redhat-9"        => "redhat-7.0",
   "openna-1.0"      => "redhat-7.0",

   "mandrake-7.1"    => "redhat-7.0",
   "mandrake-7.2"    => "redhat-7.0",
   "mandrake-9.0"    => "redhat-7.0",
   "mandrake-9.1"    => "redhat-7.0",
   "mandrake-9.2"    => "redhat-7.0",
   "mandrake-10.0"   => "redhat-7.0",
   "mandrake-10.1"   => "redhat-7.0",

   "debian-3.0"      => "debian-3.0",
   "debian-3.1"      => "debian-3.0",
   "debian-4.0"      => "debian-3.0",
   "debian-testing"  => "debian-3.0",

   "suse-7.0"        => "suse-7.0",
   "suse-9.0"        => "suse-9.0",
   "suse-9.1"        => "suse-9.0",

   "turbolinux-7.0"  => "redhat-7.0",
   
   "slackware-8.0.0" => "slackware",
   "slackware-8.1"   => "slackware",
   "slackware-9.0.0" => "slackware",
   "slackware-9.1.0" => "slackware",
   "slackware-10.0.0" => "slackware",
   "slackware-10.1.0" => "slackware",
   "slackware-10.2.0" => "slackware",

   "gentoo"          => "gentoo",
   "vlos-1.2"        => "gentoo",
   "archlinux"       => "archlinux",
   "pld-1.0"         => "pld-1.0",
   "pld-1.1"         => "pld-1.0",
   "pld-1.99"        => "pld-1.0",
   "fedora-1"        => "redhat-7.0",
   "fedora-2"        => "redhat-7.0",
   "fedora-3"        => "redhat-7.0",
   
   "rpath"           => "redhat-7.0",

   "vine-3.0"        => "redhat-7.0",
   "vine-3.1"        => "redhat-7.0",

   "freebsd-5"       => "freebsd-5",
   "freebsd-6"       => "freebsd-5",
   );

  my %dist_tables =
      (
       "redhat-6.2" =>
       {
         fn =>
         {
           NTP_CONF     => "/etc/ntp.conf",
           STEP_TICKERS => "/etc/ntp/step-tickers",
           ZONEINFO     => "/usr/share/zoneinfo",
           LOCAL_TIME    => "/etc/localtime"
         },
         table =>
             [
              [ "local_time",   \&time_get_local_time ],
              [ "timezone",     \&time_get_rh62_zone, [LOCAL_TIME, ZONEINFO] ],
              [ "sync",         \&gst_parse_split_all_array_with_pos, NTP_CONF, "server", 0, "[ \t]+", "[ \t]+" ],
              [ "sync_active",  \&gst_service_sysv_get_status, "xntpd" ],
              [ "ntpinstalled", \&gst_service_sysv_installed, "xntpd" ],
              ]
                },
       
       "redhat-7.0" =>
       {
         fn =>
         {
           NTP_CONF     => "/etc/ntp.conf",
           ZONEINFO     => "/usr/share/zoneinfo",
           LOCAL_TIME    => "/etc/localtime"
         },
         table =>
             [
              [ "local_time",   \&time_get_local_time ],
              [ "timezone",     \&time_get_rh62_zone, [LOCAL_TIME, ZONEINFO] ],
              [ "sync",         \&gst_parse_split_all_array_with_pos, NTP_CONF, "server", 0, "[ \t]+", "[ \t]+" ],
              [ "sync_active",  \&gst_service_sysv_get_status, "ntpd" ],
              [ "ntpinstalled", \&gst_service_sysv_installed, "ntpd" ],
              ]
                },
       
       "slackware" =>
       {
         fn =>
         {
           NTP_CONF     => "/etc/ntp.conf",
           ZONEINFO     => "/usr/share/zoneinfo",
           LOCAL_TIME    => "/etc/localtime"
         },
         table =>
             [
              [ "local_time",   \&time_get_local_time ],
              [ "timezone",     \&time_get_rh62_zone, [LOCAL_TIME, ZONEINFO] ],
              [ "sync",         \&gst_parse_split_first_array_pos, NTP_CONF, "server", 0, "[ \t]+", "[ \t]+" ],
              [ "sync_active",  \&gst_service_sysv_get_status, "ntpd" ],
              [ "ntpinstalled", \&gst_service_sysv_installed, "ntp" ],
              ]
                },

       "debian-3.0" =>
       {
         fn =>
         {
           NTP_CONF     => "/etc/ntp.conf",
           ZONEINFO     => "/usr/share/zoneinfo",
           LOCAL_TIME    => "/etc/localtime"
         },
         table =>
             [
              [ "local_time",   \&time_get_local_time ],
              [ "timezone",     \&time_get_rh62_zone, [LOCAL_TIME, ZONEINFO] ],
              [ "sync",         \&gst_parse_split_all_array_with_pos, NTP_CONF, "server", 0, "[ \t]+", "[ \t]+" ],
              [ "sync_active",  \&gst_service_sysv_get_status, "ntpd" ],
              [ "ntpinstalled", \&gst_service_sysv_installed, "ntp-server" ],
              ]
                },

       "suse-7.0" =>
       {
         fn =>
         {
           NTP_CONF     => "/etc/ntp.conf",
           ZONEINFO     => "/usr/share/zoneinfo",
           LOCAL_TIME    => "/etc/localtime"
         },
         table =>
             [
              [ "local_time",   \&time_get_local_time ],
              [ "timezone",     \&time_get_rh62_zone, [LOCAL_TIME, ZONEINFO] ],
              [ "sync",         \&gst_parse_split_all_array_with_pos, NTP_CONF, "server", 0, "[ \t]+", "[ \t]+" ],
              [ "sync_active",  \&gst_service_sysv_get_status, "xntpd" ],
              [ "ntpinstalled", \&gst_service_sysv_installed, "xntpd" ],
              ]
                },

       "suse-9.0" =>
       {
         fn =>
         {
           NTP_CONF     => "/etc/ntp.conf",
           ZONEINFO     => "/usr/share/zoneinfo",
           LOCAL_TIME    => "/etc/localtime"
         },
         table =>
         [
          [ "local_time",   \&time_get_local_time ],
          [ "timezone",     \&time_get_rh62_zone, [LOCAL_TIME, ZONEINFO] ],
          [ "sync",         \&gst_parse_split_all_array_with_pos, NTP_CONF, "server", 0, "[ \t]+", "[ \t]+" ],
          [ "sync_active",  \&gst_service_get_status, "xntpd" ],
          [ "ntpinstalled", \&gst_service_installed,  "xntpd" ],
         ]
       },

       "pld-1.0" =>
       {
         fn =>
         {
           NTP_CONF     => "/etc/ntp/ntp.conf",
           ZONEINFO     => "/usr/share/zoneinfo",
           LOCAL_TIME   => "/etc/localtime"
         },
         table =>
             [
              [ "local_time",   \&time_get_local_time ],
              [ "timezone",     \&time_get_rh62_zone, [LOCAL_TIME, ZONEINFO] ],
              [ "sync",         \&gst_parse_split_all_array_with_pos, NTP_CONF, "server", 0, "[ \t]+", "[ \t]+" ],
              [ "sync_active",  \&gst_service_sysv_get_status, "ntpd" ],
              [ "ntpinstalled", \&gst_service_sysv_installed, "ntpd" ],
              ]
          },


       "gentoo" =>
       {
         fn =>
         {
           NTP_CONF     => "/etc/ntp.conf",
           ZONEINFO     => "/usr/share/zoneinfo",
           LOCAL_TIME    => "/etc/localtime"
         },
         table =>
         [
          [ "local_time",   \&time_get_local_time ],
          [ "timezone",     \&time_get_rh62_zone, [LOCAL_TIME, ZONEINFO] ],
          [ "sync",         \&gst_parse_split_all_array_with_pos, NTP_CONF, "server", 0, "[ \t]+", "[ \t]+" ],
          [ "sync_active",  \&gst_service_gentoo_get_status, "ntpd" ],
          [ "ntpinstalled", \&gst_service_list_any_installed, [ "ntpd", "openntpd" ]],
          ]
        },
	
       "archlinux" =>
       {
         fn =>
         {
           NTP_CONF     => "/etc/ntp.conf",
           ZONEINFO     => "/usr/share/zoneinfo",
           LOCAL_TIME    => "/etc/localtime"
         },
         table =>
         [
          [ "local_time",   \&time_get_local_time ],
          [ "timezone",     \&time_get_rh62_zone, [LOCAL_TIME, ZONEINFO] ],
          [ "sync",         \&gst_parse_split_all_array_with_pos, NTP_CONF, "server", 0, "[ \t]+", "[ \t]+" ],
	  [ "sync_active",  \&gst_service_archlinux_get_status, "ntpd" ],
          [ "ntpinstalled", \&gst_service_rcng_installed, [ "ntpd", "openntpd" ]],
          ]
        },
	
       "freebsd-5" =>
       {
         fn =>
         {
           NTP_CONF     => "/etc/ntp.conf",
           ZONEINFO     => "/usr/share/zoneinfo",
           LOCAL_TIME    => "/etc/localtime"
         },
         table =>
         [
          [ "local_time",   \&time_get_local_time ],
          [ "timezone",     \&time_get_rh62_zone, [LOCAL_TIME, ZONEINFO] ],
          [ "sync",         \&gst_parse_split_all_array_with_pos, NTP_CONF, "server", 0, "[ \t]+", "[ \t]+" ],
          [ "sync_active",  \&gst_service_rcng_get_status, "ntpd" ],
          [ "ntpinstalled", \&gst_service_installed, "ntpd" ],
          ]
        },
       );

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

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

sub conf_get_replace_table
{
  my %dist_map =
  (
   "redhat-6.0"      => "redhat-6.2",
   "redhat-6.1"      => "redhat-6.2",
   "redhat-6.2"      => "redhat-6.2",
   
   "redhat-7.0"      => "redhat-7.0",
   "redhat-7.1"      => "redhat-7.0",
   "redhat-7.2"      => "redhat-7.0",
   "redhat-7.3"      => "redhat-7.0",
   "redhat-8.0"      => "redhat-7.0",
   "redhat-9"        => "redhat-7.0",
   "openna-1.0"      => "redhat-7.0",

   "mandrake-7.1"    => "redhat-7.0",
   "mandrake-7.2"    => "redhat-7.0",
   "mandrake-9.0"    => "redhat-7.0",
   "mandrake-9.1"    => "redhat-7.0",
   "mandrake-9.2"    => "redhat-7.0",
   "mandrake-10.0"   => "redhat-7.0",
   "mandrake-10.1"   => "redhat-7.0",

   "debian-3.0"      => "debian-3.0",
   "debian-3.1"      => "debian-3.0",
   "debian-4.0"      => "debian-3.0",
   "debian-testing"  => "debian-3.0",

   "suse-7.0"        => "suse-7.0",
   "suse-9.0"        => "suse-9.0",
   "suse-9.1"        => "suse-9.0",

   "turbolinux-7.0"  => "redhat-7.0",
   
   "slackware-8.0.0" => "slackware",
   "slackware-9.0.0" => "slackware",
   "slackware-9.1.0" => "slackware",
   "slackware-10.0.0" => "slackware",
   "slackware-10.1.0" => "slackware",
   "slackware-10.2.0" => "slackware",

   "gentoo"          => "gentoo",
   "vlos-1.2"        => "gentoo",
   "archlinux"       => "archlinux",
   "pld-1.0"         => "pld-1.0",
   "pld-1.1"         => "pld-1.0",
   "pld-1.99"        => "pld-1.0",
   "fedora-1"        => "redhat-7.0",
   "fedora-2"        => "redhat-7.0",
   "fedora-3"        => "redhat-7.0",
   "rpath"           => "redhat-7.0",

   "vine-3.0"        => "redhat-7.0",
   "vine-3.1"        => "redhat-7.0",

   "freebsd-5"       => "freebsd-5",
   "freebsd-6"       => "freebsd-5",
   );

  my %dist_tables =
      (
       "redhat-6.2" =>
       {
         fn =>
         {
           NTP_CONF     => "/etc/ntp.conf",
           STEP_TICKERS => "/etc/ntp/step-tickers",
           ZONEINFO     => "/usr/share/zoneinfo",
           LOCAL_TIME    => "/etc/localtime"
         },
         table =>
             [
              [ "timezone",    \&time_set_rh62_zone, [LOCAL_TIME, ZONEINFO] ],
              [ "local_time",  \&time_set_local_time ],
              [ "sync",        \&time_replace_ntp_servers, NTP_CONF, "server", "[ \t]+" ],
              [ "sync_active", \&gst_service_sysv_set_status, 90, "xntpd", "%sync_active%" ],
              ]
                },

       "redhat-7.0" =>
       {
         fn =>
         {
           NTP_CONF     => "/etc/ntp.conf",
           ZONEINFO     => "/usr/share/zoneinfo",
           LOCAL_TIME    => "/etc/localtime"
         },
         table =>
             [
              [ "timezone",     \&time_set_rh62_zone, [LOCAL_TIME, ZONEINFO] ],
              [ "local_time",   \&time_set_local_time ],
              [ "sync",         \&time_replace_ntp_servers, NTP_CONF, "server", "[ \t]+" ],
              [ "sync_active",  \&gst_service_sysv_set_status, 90, "ntpd", "%sync_active%" ],
              ]
                },

       "slackware" =>
       {
         fn =>
         {
           NTP_CONF     => "/etc/ntp.conf",
           ZONEINFO     => "/usr/share/zoneinfo",
           LOCAL_TIME    => "/etc/localtime"
         },
         table =>
             [
              [ "timezone",    \&time_set_rh62_zone, [LOCAL_TIME, ZONEINFO] ],
              [ "local_time",  \&time_set_local_time ],
              [ "sync",        \&time_replace_ntp_servers, NTP_CONF, "server", "[ \t]+" ],
              [ "sync_active", \&gst_service_sysv_set_status, 23, "ntp", "%sync_active%" ],
              ]
                },
       
       "debian-3.0" =>
       {
         fn =>
         {
           NTP_CONF     => "/etc/ntp.conf",
           ZONEINFO     => "/usr/share/zoneinfo",
           LOCAL_TIME   => "/etc/localtime",
           TIMEZONE     => "/etc/timezone"
         },
         table =>
             [
              [ "timezone",    \&time_set_rh62_zone, [LOCAL_TIME, ZONEINFO] ],
              [ "timezone",    \&gst_replace_line_first, TIMEZONE ],
              [ "local_time",  \&time_set_local_time ],
              [ "sync",        \&time_replace_ntp_servers, NTP_CONF, "server", "[ \t]+" ],
              [ "sync_active", \&gst_service_sysv_set_status, 23, "ntp-server", "%sync_active%" ],
              ]
                },
       
       "suse-7.0" =>
       {
         fn =>
         {
           NTP_CONF     => "/etc/ntp.conf",
           ZONEINFO     => "/usr/share/zoneinfo",
           LOCAL_TIME    => "/etc/localtime"
         },
         table =>
             [
              [ "timezone",     \&time_set_rh62_zone, [LOCAL_TIME, ZONEINFO] ],
              [ "local_time",   \&time_set_local_time ],
              [ "sync",         \&time_replace_ntp_servers, NTP_CONF, "server", "[ \t]+" ],
              [ "sync_active",  \&gst_service_sysv_set_status, 90, "xntpd", "%sync_active%" ],
              ]
                },

       "suse-9.0" =>
       {
         fn =>
         {
           NTP_CONF     => "/etc/ntp.conf",
           ZONEINFO     => "/usr/share/zoneinfo",
           LOCAL_TIME    => "/etc/localtime"
         },
         table =>
         [
          [ "timezone",     \&time_set_rh62_zone, [LOCAL_TIME, ZONEINFO] ],
          [ "local_time",   \&time_set_local_time ],
          [ "sync",         \&time_replace_ntp_servers, NTP_CONF, "server", "[ \t]+" ],
          [ "sync_active",  \&gst_service_suse_set_status, "xntpd" ],
         ]
       },

       "pld-1.0" =>
       {
         fn =>
         {
           NTP_CONF     => "/etc/ntp/ntp.conf",
           ZONEINFO     => "/usr/share/zoneinfo",
           LOCAL_TIME   => "/etc/localtime"
         },
         table =>
             [
              [ "timezone",     \&time_set_rh62_zone, [LOCAL_TIME, ZONEINFO] ],
              [ "local_time",   \&gst_replace_join_all, NTP_CONF, "server", "[ \t]+" ],
              [ "sync_active",  \&gst_service_sysv_set_status, 90, "ntpd", "%sync_active%" ],
              ]
        },

       "gentoo" =>
       {
         fn =>
         {
           NTP_CONF     => "/etc/ntp.conf",
           ZONEINFO     => "/usr/share/zoneinfo",
           LOCAL_TIME    => "/etc/localtime"
         },
         table =>
         [
          [ "timezone",     \&time_set_rh62_zone, [LOCAL_TIME, ZONEINFO] ],
          [ "local_time",   \&time_set_local_time ],
          [ "sync",         \&time_replace_ntp_servers, NTP_CONF, "server", "[ \t]+" ],
          [ "sync_active",  \&gst_service_gentoo_set_status, "ntpd", 1, "%sync_active%" ],
          ]
        },
       
       "archlinux" =>
       {
       	 fn =>
         {
           NTP_CONF => "/etc/ntp.conf",
           ZONEINFO => "/usr/share/zoneinfo",
           LOCAL_TIME => "/etc/localtime"
         },
         table =>
         [
          [ "timezone",     \&time_set_archlinux_zone, [LOCAL_TIME, ZONEINFO] ],
          [ "local_time",   \&time_set_local_time ],
          [ "sync",         \&time_replace_ntp_servers, NTP_CONF, "server", "[ \t]+" ],
          [ "sync_active",  \&gst_service_archlinux_set_status, "ntpd", "%sync_active%" ],
         ]
       },
       
       "freebsd-5" =>
       {
         fn =>
         {
           NTP_CONF     => "/etc/ntp.conf",
           ZONEINFO     => "/usr/share/zoneinfo",
           LOCAL_TIME    => "/etc/localtime"
         },
         table =>
         [
          [ "timezone",     \&time_set_rh62_zone, [LOCAL_TIME, ZONEINFO] ],
          [ "local_time",   \&time_set_local_time ],
          [ "sync",         \&time_replace_ntp_servers, NTP_CONF, "server", "[ \t]+" ],
          [ "sync_active",  \&gst_service_rcng_set_status, "ntpd", "%sync_active%" ],
          ]
        },
       );

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

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

