initial commit of file from CVS for e-smith-ntp on Wed 12 Jul 09:00:21 BST 2023

This commit is contained in:
Brian Read
2023-07-12 09:00:21 +01:00
parent 59f5643b62
commit 4d143a42fe
37 changed files with 3230 additions and 2 deletions

0
root/usr/lib/perl5/.gitignore vendored Normal file
View File

View File

View File

@@ -0,0 +1,774 @@
#!/usr/bin/perl -wT
#
# Copyright (C) 2002 Mitel Networks Corporation
#
# Technical support for this program is available from e-smith, inc.
# Please call us at (613) 236-0743 or visit our web site www.e-smith.net
# for details.
#
# $Id: datetime.pm,v 1.13 2003/04/04 19:24:58 lijied Exp $
#
#----------------------------------------------------------------------
package esmith::FormMagick::Panel::datetime;
use strict;
use Exporter;
use esmith::ConfigDB;
use esmith::FormMagick;
use esmith::cgi;
use esmith::TestUtils;
our @ISA = qw(esmith::FormMagick Exporter);
our @EXPORT = qw(
showInitial performAndShowResult verifyResult flushOn
);
our $VERSION = sprintf '%d.%03d', q$Revision: 1.13 $ =~ /: (\d+).(\d+)/;
=pod
=head1 NAME
esmith::FormMagick::Panel::datetime - useful panel functions
=head1 SYNOPSIS
use esmith::FormMagick::Panel::datetime;
my $panel = esmith::FormMagick::Panel::datetime->new();
$panel->display();
=head1 DESCRIPTION
=head2 new
Exactly as for esmith::FormMagick
=begin testing
use_ok('esmith::FormMagick::Panel::datetime');
$FM = esmith::FormMagick::Panel::datetime->new();
isa_ok($FM, 'esmith::FormMagick::Panel::datetime');
$FM->{cgi} = CGI->new;
=end testing
=cut
sub new
{
shift;
my $self = esmith::FormMagick->new();
$self->{calling_package} = (caller)[0];
bless $self;
return $self;
}
=pod
=head2 showInitial
Display the contents of the initial page
=begin testing
is($FM->showInitial(), '', 'showInitial');
like($_STDOUT_, qr/NEW_M\/D\/Y/, ' .. new m/d/y field');
like($_STDOUT_, qr/NEW_H\/M\/S/, ' .. new h/m/s field');
like($_STDOUT_, qr/SAVE_DATE_TIME/, ' .. save date/time button');
like($_STDOUT_, qr/ENABLE_NTP/, ' .. enable NTP box');
like($_STDOUT_, qr/SAVE_NTP/, ' .. save NTP button');
=end testing
=cut
sub showInitial
{
my $self = shift;
my $q = $self->{cgi};
#--------------------------------------------------
# Get a sorted list of time zones
#--------------------------------------------------
$ENV{BASH_ENV} = '';
if (! open (ZONES, "cd /usr/share/zoneinfo; /usr/bin/find . -type f -or -type l | /bin/grep '^./[A-Z]' |"))
{
print $q->h3 ($self->localise('COULD_NOT_OPEN_TZ_FILE').$!.'.');
return;
}
my $zone;
my @zones = ();
while (defined ($zone = <ZONES>))
{
chop ($zone);
$zone =~ s/^.\///;
push @zones, $zone;
}
close ZONES;
@zones = sort @zones;
#--------------------------------------------------
# Read the time
#--------------------------------------------------
my ($weekdaydefault,
$monthnamedefault,
$monthdefault,
$daydefault,
$yeardefault,
$hourdefault,
$minutedefault,
$seconddefault,
$ampmdefault) = split /\|/,
`/bin/date '+%A|%B|%-m|%-d|%Y|%-I|%M|%S|%p'`;
# get rid of trailing carriage return on last field
chop ($ampmdefault);
#--------------------------------------------------
# Figure out time zone by looking first looking at
# the configuration database value of TimeZone.
# If that is not defined, try and get it from /etc/localtime.
# If that doesn't work, default to US/Eastern.
#--------------------------------------------------
my $localtime;
my $timezonedefault = "US/Eastern";
my $conf = esmith::ConfigDB->open();
if (defined $conf->get('TimeZone'))
{
$timezonedefault = $conf->get('TimeZone')->value;
}
else
{
if (defined ($localtime = readlink '/etc/localtime'))
{
my $pos = index $localtime, 'zoneinfo/';
if ($pos > -1)
{
$timezonedefault = substr $localtime, ($pos + 9);
}
}
}
my $now_string = $self->gen_locale_date_string();
my $oldNTPServer = '';
$conf = esmith::ConfigDB->open();
my $rec = $conf->get('ntpd');
if ($rec)
{
$oldNTPServer = $rec->prop('NTPServer') || '';
}
my $ntpEnabled = 0;
if ($rec and $rec->prop('status') eq "enabled")
{
$ntpEnabled = 1 unless ($rec->prop('SyncToHWClockSupported') || 'yes') eq 'yes' and $oldNTPServer =~ m#^\s*$#;
}
#--------------------------------------------------
# Display the time setting form
#--------------------------------------------------
my %monthlabels = ('1' => $self->localise('JANUARY'),
'2' => $self->localise('FEBRUARY'),
'3' => $self->localise('MARCH'),
'4' => $self->localise('APRIL'),
'5' => $self->localise('MAY'),
'6' => $self->localise('JUNE'),
'7' => $self->localise('JULY'),
'8' => $self->localise('AUGUST'),
'9' => $self->localise('SEPTEMBER'),
'10' => $self->localise('OCTOBER'),
'11' => $self->localise('NOVEMBER'),
'12' => $self->localise('DECEMBER'));
# create radio buttons in the same group
my ($rbDisableNTP, $rbEnableNTP) =
$q->radio_group(-name => 'ntpStatus',
-values => ['disabled', 'enabled'],
-default => $ntpEnabled ? 'enabled' : 'disabled',
-linebreak => 'true',
-labels => {enabled => '', disabled => ''});
print "<tr><td colspan=2><table>\n";
if (! $ntpEnabled)
{
print $q->Tr(
$q->td({-class => "sme-radiobutton"}, $rbDisableNTP),
$q->td($q->h3($self->localise('SET_DATE_TITLE')))),
$q->Tr(
$q->td({-class => "sme-radiobutton"}, "&nbsp;"),
$q->td(
$q->p ($self->localise('CURRENT_SETTING').": ",
$q->b ($now_string)))),
$q->Tr(
$q->td({-class => "sme-radiobutton"}, "&nbsp;"),
$q->td(
$q->table({-class => "sme-noborders"},
$q->Tr (esmith::cgi::genCell ($q,
$self->localise('NEW_M/D/Y'), "sme-noborders-label"),
esmith::cgi::genCell ($q,
$q->popup_menu (-name => 'month', -values => [ 1..12 ],
-default => $monthdefault, -labels => \%monthlabels),
"sme-noborders-content"),
esmith::cgi::genCell ($q,
$q->textfield (-name => 'day', -override => 1,
-default => $daydefault, -size => 12),
"sme-noborders-content"),
esmith::cgi::genCell ($q,
$q->textfield (-name => 'year', -override => 1,
-default => $yeardefault, -size => 12),
"sme-noborders-content")),
$q->Tr (esmith::cgi::genCell ($q,
$self->localise('NEW_H/M/S'), "sme-noborders-label"),
esmith::cgi::genCell ($q,
$q->textfield (-name => 'hour', -override => 1,
-default => $hourdefault, -size => 12),
"sme-noborders-content"),
esmith::cgi::genCell ($q,
$q->textfield (-name => 'minute', -override => 1,
-default => $minutedefault, -size => 12),
"sme-noborders-content"),
esmith::cgi::genCell ($q,
$q->textfield (-name => 'second', -override => 1,
-default => $seconddefault, -size => 12),
"sme-noborders-content")),
$q->Tr (esmith::cgi::genCell ($q,
$self->localise('AM/PM_AND_TZ'), "sme-noborders-label"),
esmith::cgi::genCell ($q,
$q->popup_menu (-name => 'ampm', -values => ['AM', 'PM'],
-default => $ampmdefault),
"sme-noborders-content"),
esmith::cgi::genDoubleCell ($q,
$q->popup_menu (-name => 'timezone', -values => \@zones,
-default => $timezonedefault))),
)
)
),"\n";
}
#--------------------------------------------------
# Display the NTP form
#--------------------------------------------------
my $ntpEnabledTitle;
my $ntpEnabledDesc;
my $showTime;
if ($ntpEnabled)
{
$ntpEnabledTitle = $self->localise('NTP_CONFIGURE_TITLE');
$ntpEnabledDesc = $self->localise('NTP_CONFIGURE_DESC');
$showTime = $q->p ($self->localise('CURRENT_SETTING').": ",
$q->b ($now_string));
}
else
{
$ntpEnabledTitle = $self->localise('NTP_ENABLE_TITLE');
$ntpEnabledDesc = $self->localise('NTP_ENABLE_DESC');
}
print $q->Tr(
$q->td({-class => "sme-radiobutton"}, $rbEnableNTP),
$q->td($q->h3($ntpEnabledTitle))),
$q->Tr(
$q->td({-class => "sme-radiobutton"}, "&nbsp;"),
$q->td($ntpEnabledDesc)),
$q->Tr(
$q->td({-class => "sme-radiobutton"}, "&nbsp;"),
$q->td($showTime)),
$q->Tr(
$q->td({-class => "sme-radiobutton"}, "&nbsp;"),
$q->td(
$q->table ({-class => "sme-noborders"},
$q->Tr (esmith::cgi::genCell ($q,
$self->localise('NTP_SERVER'), "sme-noborders-label"),
esmith::cgi::genCell ($q,
$q->textfield(-name => 'ntpServer', -size => '32',
-default => "$oldNTPServer"),
"sme-noborders-content")),
)
)
),"\n";
if ($ntpEnabled)
{
print $q->Tr(
$q->td({-class => "sme-radiobutton"}, $rbDisableNTP),
$q->td($q->h3 ($self->localise("NTP_DISABLE_TITLE")))),
$q->Tr(
$q->td({-class => "sme-radiobutton"}, "&nbsp;"),
$q->td($self->localise('NTP_DISABLE_DESC'))),"\n";
}
print $q->Tr(
$q->td({-colspan => 2},
$q->table ({-class => "sme-noborders", -width=>'100%'},
$q->Tr(
$q->th({-class => "sme-layout"},
$q->submit (-name => 'action',
-value => $self->localise('SAVE'))))
)
)
),"\n";
print "</table></td></tr>\n";
return '';
}
=pod
=head2 performAndShowResult
Subroutine to perform actions and display result
=for testing
is($FM->performAndShowResult(), '', 'performAndShowResult');
=cut
sub performAndShowResult
{
my $self = shift;
my $q = $self->{cgi};
my $conf = esmith::ConfigDB->open();
my $ntpd = $conf->get('ntpd');
$conf->close();
my $hwSync = $ntpd->prop('SyncToHWClockSupported') || 'yes';
my $oldNtpServer = $ntpd->prop('NTPServer') || '';
my $oldNtpStatus = ($hwSync eq 'yes' and $oldNtpServer =~ m#^\s*$#) ? 'disabled' : ($ntpd->prop('status') || 'disabled');
my $newNtpServer = $q->param('ntpServer') || '';
my $newNtpStatus = $q->param('ntpStatus') || '';
# If ntp status was and still is disabled, then set the time.
if (($oldNtpStatus eq 'disabled') &&
($newNtpStatus eq 'disabled'))
{
$self->_performSetDateTime();
}
# If the ntp status changed, then force a reconfigure.
# If it is enabled and the server changed then force a reconfigure.
if (($oldNtpStatus ne $newNtpStatus) ||
(($newNtpStatus eq 'enabled') &&
($oldNtpServer ne $newNtpServer)))
{
# let ntp enable/disable itself as required
$self->_performSetTimeserver();
}
$q->Delete('ntpServer');
$q->Delete('ntpStatus');
return '';
}
=pod
=head2 verifyResult
Subroutine to verify result
=begin testing
is($FM->verifyResult(), '', 'verifyResult');
like($_STDOUT_, qr/NEW_DATE_AND_TIME/, ' .. new date and time');
=end testing
=cut
sub verifyResult
{
my $self = shift;
my $q = $self->{cgi};
$ENV{BASH_ENV} = '';
#--------------------------------------------------
# Read the time
#--------------------------------------------------
my ($weekdaydefault,
$monthnamedefault,
$monthdefault,
$daydefault,
$yeardefault,
$hourdefault,
$minutedefault,
$seconddefault,
$ampmdefault) = split /\|/, `/bin/date '+%A|%B|%-m|%-d|%Y|%-I|%M|%S|%p'`;
# get rid of trailing carriage return on last field
chop ($ampmdefault);
#--------------------------------------------------
# Figure out time zone by looking at /etc/localtime.
# If that doesn't work, default to US/Eastern.
#--------------------------------------------------
my $localtime;
my $timezonedefault = "US/Eastern";
if (defined ($localtime = readlink '/etc/localtime'))
{
my $pos = index $localtime, 'zoneinfo/';
if ($pos > -1)
{
$timezonedefault = substr $localtime, ($pos + 9);
}
}
#--------------------------------------------------
# Display the time
#--------------------------------------------------
print $q->Tr($q->td($q->p ($self->localise('NEW_DATE_AND_TIME'),
$q->b ($weekdaydefault,
$monthnamedefault,
$daydefault,
$yeardefault . ',',
$hourdefault . ':' . $minutedefault . ':' .
$seconddefault,
$ampmdefault,
$timezonedefault))));
return '';
}
=pod
=head2 _performSetDateTime
Subroutine to set the date and time of the e-smith server
=begin testing
$FM->{cgi}->param(-name=>'day', -value=>'55');
$FM->{cgi}->param(-name=>'year', -value=>'5');
is($FM->_performSetDateTime(), '', 'performSetDateTime');
like($_STDOUT_, qr/INVALID_DAY/, ' .. invalid day check');
$FM->{cgi}->param(-name=>'day', -value=>'10');
$FM->_performSetDateTime();
like($_STDOUT_, qr/INVALID_YEAR/, ' .. invalid year check');
$FM->{cgi}->param(-name=>'year', -value=>'1984');
$FM->{cgi}->param(-name=>'hour', -value=>'60');
$FM->{cgi}->param(-name=>'minute', -value=>'90');
$FM->_performSetDateTime();
like($_STDOUT_, qr/INVALID_HOUR/, ' .. invalid hour check');
$FM->{cgi}->param(-name=>'hour', -value=>'12');
$FM->_performSetDateTime();
like($_STDOUT_, qr/INVALID_MINUTE/, ' .. invalid minute check');
$FM->{cgi}->param(-name=>'minute', -value=>'00');
$FM->{cgi}->param(-name=>'second', -value=>'00');
SKIP: {
skip "unsafe!", 2 unless esmith::TestUtils::destruction_ok();
is($FM->_performSetDateTime(), '', ' .. exited happily');
like($_STDOUT_, qr/UPDATING_CLOCK/, ' .. updating clock in background');
}
=end testing
=cut
sub _performSetDateTime
{
my $self = shift;
my $q = $self->{cgi};
# Turn on autoflush, since setting the time forward makes Apache
# stop waiting for CGI output:
$| = 1;
#--------------------------------------------------
# Untaint parameters and check for validity
#--------------------------------------------------
my $timezone = $q->param ('timezone');
if ($timezone =~ /^([\w\-]+\/?[\w\-+]*)$/) {
$timezone = $1;
} else {
$timezone = "US/Eastern";
}
my $month = $q->param ('month');
if ($month =~ /^(\d{1,2})$/) {
$month = $1;
} else {
$month = "1";
}
if (($month < 1) || ($month > 12))
{
$q->param(-name => "status_message",
-value => $q->p($self->localise('INVALID_MONTH')." $month. ".
$self->localise('MONTH_BETWEEN_1_AND_12')));
return $self->error($self->localise('INVALID_MONTH')." $month. ".
$self->localise('MONTH_BETWEEN_1_AND_12'));
}
my $day = $q->param ('day');
if ($day =~ /^(\d{1,2})$/) {
$day = $1;
} else {
$day = "1";
}
if (($day < 1) || ($day > 31))
{
$q->param(-name => "status_message",
-value => $q->p($self->localise('INVALID_DAY')." $day. ".
$self->localise('BETWEEN_1_AND_31')));
return $self->error($self->localise('INVALID_DAY')." $day. ".
$self->localise('BETWEEN_1_AND_31'));
}
my $year = $q->param ('year');
if ($year =~ /^(\d{4})$/) {
$year = $1;
} else {
$year = "2000";
}
if (($year < 1900) || ($year > 2200))
{
$q->param(-name => "status_message",
-value => $q->p($self->localise('INVALID_YEAR')." $year. ".
$self->localise('FOUR_DIGIT_YEAR')));
return $self->error($self->localise('INVALID_YEAR')." $year. ".
$self->localise('FOUR_DIGIT_YEAR'));
}
my $hour = $q->param ('hour');
if ($hour =~ /^(\d{1,2})$/) {
$hour = $1;
} else {
$hour = "12";
}
if (($hour < 1) || ($hour > 12))
{
$q->param(-name => "status_message",
-value => $q->p($self->localise('INVALID_HOUR')." $hour. ".
$self->localise('BETWEEN_1_AND_12')));
return $self->error($self->localise('INVALID_HOUR')." $hour. ".
$self->localise('BETWEEN_1_AND_12'));
}
my $minute = $q->param ('minute');
if ($minute =~ /^(\d{1,2})$/) {
$minute = $1;
} else {
$minute = "0";
}
if (($minute < 0) || ($minute > 59))
{
$q->param(-name => "status_message",
-value => $q->p($self->localise('INVALID_MINUTE')." $minute. ".
$self->localise('BETWEEN_0_AND_59')));
return $self->error(self->localise('INVALID_MINUTE')." $minute. ".
$self->localise('BETWEEN_0_AND_59'));
}
my $second = $q->param ('second');
if ($second =~ /^(\d{1,2})$/) {
$second = $1;
} else {
$second = "0";
}
if (($second < 0) || ($second > 59))
{
$q->param(-name => "status_message",
-value => $q->p($self->localise('INVALID_SECOND')." $second. ".
$self->localise('BETWEEN_0_AND_59')));
return $self->error($self->localise('INVALID_SECOND')." $second. ".
$self->localise('BETWEEN_0_AND_59'));
}
my $ampm = $q->param ('ampm');
if ($ampm =~ /^(AM|PM)$/) {
$ampm = $1;
} else {
$ampm = "AM";
}
# convert to 24 hour time
$hour = $hour % 12;
if ($ampm eq "PM")
{
$hour = $hour + 12;
}
#--------------------------------------------------
# Store time zone in configuration database
#--------------------------------------------------
my $conf = esmith::ConfigDB->open();
my $old = $conf->get('UnsavedChanges')->value;
my $rec = $conf->get('TimeZone');
unless ($rec)
{
$rec = $conf->new_record('TimeZone',undef);
}
$rec->set_value($timezone);
$conf->get('UnsavedChanges')->set_value($old);
#--------------------------------------------------
# Signal event to change time zone, system time
# and hardware clock
#--------------------------------------------------
my $newdate = sprintf "%02d%02d%02d%02d%04d.%02d",
$month, $day, $hour, $minute, $year, $second;
esmith::util::backgroundCommand(2,
"/sbin/e-smith/signal-event","timezone-update",$newdate);
return $self->success('UPDATING_CLOCK');
}
=pod
=head2 _performSetTimeserver
Subroutine to set the NTP server
=begin testing
SKIP: {
skip "unsafe!", 3 unless esmith::TestUtils::destruction_ok();
is($FM->_performSetTimeserver(), '', 'performSetTimeserver');
$FM->{cgi}->param(-name=>'ntpEnabled', -value=>'on');
$FM->{cgi}->param(-name=>'ntpServer', -value=>'time.nrc.ca');
$FM->_performSetTimeserver();
like($_STDOUT_, qr/SETTINGS_CHANGED/, ' .. changed settings');
$FM->{cgi}->param(-name=>'ntpEnabled', -value=>'off');
$FM->_performSetTimeserver();
like($_STDOUT_, qr/SETTINGS_CHANGED/, ' .. and disabled');
}
=end testing
=cut
sub _performSetTimeserver
{
my $self = shift;
my $q = $self->{cgi};
my $msg;
#------------------------------------------------------------
# Verify the arguments and untaint the variables (see Camel
# book, "Detecting and laundering tainted data", pg. 358)
#------------------------------------------------------------
my $newStatus = '';
my $ntpServer = '';
if ($q->param ('ntpStatus') eq 'enabled')
{
$newStatus = "on";
}
else
{
$newStatus = "off";
}
if (defined ($q->param ('ntpServer')))
{
$ntpServer = $q->param ('ntpServer');
}
else
{
$ntpServer = "";
}
if ($newStatus ne "on") # asking to have NTP disabled
{
# make sure that the parameters are set for disabled
my $conf = esmith::ConfigDB->open();
my $old = $conf->get('UnsavedChanges')->value;
my $rec = $conf->get('ntpd');
if ($rec)
{
$rec->set_prop('status', ($rec->prop('SyncToHWClockSupported') || 'yes') eq 'yes' ? 'enabled' : 'disabled');
$rec->set_prop('NTPServer','');
}
else
{
$rec = $conf->new_record('ntpd',
{type=>'service', status=>'enabled', SyncToHWClockSupported => 'yes', NTPServer=>''});
}
$conf->get('UnsavedChanges')->set_value($old);
$msg = 'SERVER_DISABLED_DESC';
}
else # enable service and synch with ntpServer
{
if ($ntpServer eq "pool.ntp.org")
{
return $self->error('INVALID_NTP_ADDR');
}
elsif ($ntpServer =~ /^([a-zA-Z0-9\.\-]+)$/)
{
$ntpServer = $1;
}
elsif ($ntpServer =~ /^\s*$/)
{
$ntpServer = "";
}
else
{
return $self->error('INVALID_NTP_ADDR');
}
#------------------------------------------------------------
# Looks good; go ahead and change the parameters.
#------------------------------------------------------------
my $conf = esmith::ConfigDB->open();
my $old = $conf->get('UnsavedChanges')->value;
my $rec = $conf->get('ntpd');
if ($rec)
{
$rec->set_prop('status','enabled');
$rec->set_prop('NTPServer',$ntpServer);
}
else
{
$rec = $conf->new_record('ntpd',
{type=>'service',status=>'enabled',SyncToHWClockSupported => 'yes',NTPServer=>$ntpServer});
}
$conf->get('UnsavedChanges')->set_value($old);
$msg = 'SETTINGS_CHANGED';
if ($ntpServer =~ /^\s*$/)
{
$rec->set_prop('status', ($rec->prop('SyncToHWClockSupported') || 'yes') eq 'yes' ? 'enabled' : 'disabled');
$rec->set_prop('NTPServer', '');
$msg = 'INVALID_NTP_SERVER' if ($rec->prop('SyncToHWClockSupported') || 'yes') ne 'yes';
}
}
esmith::util::backgroundCommand(2,
"/sbin/e-smith/signal-event", "timeserver-update");
return $self->success($msg);
}
1;