I don't know where to fine these files:
use esmith::FormMagick;
use esmith::ConfigDB;
use esmith::Backup;
use esmith::BackupHistoryDB;
use esmith::AccountsDB;
use esmith::cgi;
use esmith::util;
use esmith::lockfile;
I went to the program / file to see this @ : (I check this with another file and they where the same)
#!/usr/bin/perl -wT
#----------------------------------------------------------------------
# heading : Administration
# description : Backup or restore
# navigation : 4000 4200
# Copyright (C) 2002 Mitel Networks Corporation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU 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
#
# Technical support for this program is available from Mitel Networks
# Please visit our web site
www.mitel.com/sme/ for details.
#----------------------------------------------------------------------
use strict;
use esmith::FormMagick;
use esmith::ConfigDB;
use esmith::Backup;
use esmith::BackupHistoryDB;
use esmith::AccountsDB;
use esmith::cgi;
use esmith::util;
use esmith::lockfile;
my $fm = esmith::FormMagick->new();
# These statements _must_ come _after_ the FormMagick constructor. It sets
# POST_MAX and DISABLE_UPLOADS to values that will cause this script to fail
# on restores and verification of files.
$CGI::POST_MAX = -1; # allow any size POST
$CGI::DISABLE_UPLOADS = 0; # need to upload to restore from desktop
$fm->parse_xml();
my $conf = esmith::ConfigDB->open()
|| die $fm->localise('CANNOT_OPEN').'configuration db';
my $restore = esmith::ConfigDB->open('/etc/e-smith/restore')
|| die $fm->localise('CANNOT_OPEN').'/etc/e-smith/restore';
my $es_backup = new esmith::Backup or die "Couldn't create Backup object\n";
my @directories = $es_backup->restore_list;
# Unbuffer standard output so that files and directories are listed as
# they are restored
$| = 1;
# Store away current gid of 'www' group.
my $www_gid = getgrnam("www");
#------------------------------------------------------------
# examine state parameter and display the appropriate form
#------------------------------------------------------------
my $q = $fm->{cgi};
if (! grep (/^state$/, $q->param))
{
showInitial ($q, '');
}
elsif ($q->param ('state') eq "perform")
{
performAndShowResult ($q);
}
elsif ($q->param ('state') eq "desktop-restore")
{
performDesktopRestore($q);
}
elsif ($q->param ('state') eq "desktop-verify")
{
performDesktopVerify($q);
}
elsif ($q->param ('state') eq "tape-configure")
{
updateTapeBackupConfig($q);
}
elsif ($q->param ('state') eq "tape-restore")
{
performTapeRestore ($q);
}
else
{
esmith::cgi::genStateError ($q, undef);
}
exit (0);
#------------------------------------------------------------
# subroutine to display initial form
#------------------------------------------------------------
sub showInitial
{
my ($q, $msg) = @_;
my $rec = $restore->get('restore');
if($msg eq '')
{
if($rec)
{
$msg = $fm->localise($rec->prop('errmsg') || '');
$rec->delete_prop('errmsg');
}
}
if ($msg eq '')
{
esmith::cgi::genHeaderNonCacheable ($q, undef,
$fm->localise('BACKUP_TITLE'));
}
else
{
esmith::cgi::genHeaderNonCacheable
($q, undef, $fm->localise('OPERATION_STATUS_REPORT'));
print $q->div ({-class => "sme-error"}, $msg);
print $q->hr;
}
print $q->div({-class => 'error'},
$q->h5('Warning: a reboot is required before proceeding!
Failure to reboot now may leave your system in an unknown
state!'))
if $conf->get_prop('bootstrap-console', 'Run') eq 'yes';
my ($tarsize, $dumpsize, undef, undef) = &CalculateSizes();
my $module = $conf->get('backup');
if ($module)
{
$module = $module->prop('Program');
}
# The default e-smith backup program is flexbackup.
unless (defined $module)
{
$module = "flexbackup";
}
elsif ($module eq '')
{
$module = "flexbackup";
}
# Hack to evaluate embedded vars
print eval 'return "'.$fm->localise('BACKUP_DESC').'\n";';
if ($tarsize =~ /Tb/ or $tarsize =~ /(\d+)Gb/ and $1 >= 2)
{
print $fm->localise("BACKUP_DESKTOP_TOO_BIG"), "\n";
}
print $q->h2($fm->localise("BACKUP_CONFIG_STATUS")),"\n";
my $backup_status = $conf->get('backup');
if ($backup_status)
{
$backup_status = $backup_status->prop('status');
}
if (defined $backup_status && $backup_status eq "enabled")
{
my $backupTime = $conf->get('backup')->prop('backupTime');
my $reminderTime = $conf->get('backup')->prop('reminderTime');
print $q->p ($fm->localise('TAPE_BACKUPS_ENABLED'),
$fm->localise('BACKUPS_RUN_AT'),$q->b($backupTime),
$fm->localise('REMINDER_MESSAGE_AT'),$q->b($reminderTime)),
"\n";
}
else
{
print $q->p($fm->localise('TAPE_BACKUPS_DISABLED')),"\n";
}
my %labels = (
"desktop-backup" => $fm->localise('DESKTOP_BACKUP'),
"desktop-restore" => $fm->localise('DESKTOP_RESTORE'),
"desktop-verify" => $fm->localise('DESKTOP_VERIFY'),
"tape-configure" => $fm->localise('TAPE_CONFIGURE'),
"tape-restore" => $fm->localise('TAPE_RESTORE'),
);
my @labels = (
'desktop-backup',
'desktop-restore',
'desktop-verify',
'tape-configure',
'tape-restore',
);
my $default_action = 'desktop-backup';
my $restore_state;
if($rec)
{
$restore_state = $rec->prop('state');
}
unless (defined $restore_state)
{
# Undefined, set it to idle
if ($rec)
{
$rec->reset_props(type=>'status', state=>'idle', finish=>0,
start=>0);
}
else
{
$rec = $restore->new_record('restore',
{type=>'status', state=>'idle', finish=>0, start=>0});
}
$restore_state = 'idle';
}
elsif ($restore_state eq 'running')
{
my $start = $rec->prop('start');
$start = scalar localtime($start);
print $q->p ($fm->localise('RESTORE_IN_PROGRESS_BEGAN_AT')
. "<b>$start</b>.\n" );
%labels = (
"refresh" => $fm->localise('REFRESH_THIS_DISPLAY'),
"tape-configure" => $fm->localise('CONFIGURE_TAPE_BACKUP'),
);
@labels = (
'refresh',
'tape-configure',
);
$default_action = 'refresh';
}
elsif ($restore_state eq 'complete')
{
my $start = $rec->prop('start');
$start = scalar localtime($start);
my $finish = $rec->prop('finish');
$finish = scalar localtime($finish);
print $q->p ($fm->localise('RESTORE_COMPLETED'),$q->br(),
$fm->localise('STARTED_AT'),$q->b($start),$q->br(),
$fm->localise('FINISHED_AT'),$q->b($finish)),"\n";
print $q->p (
$q->b ($fm->localise('YOU_MUST_REBOOT')
)
),"\n";
$default_action = 'reboot';
}
else
{
# Unknown state. Reset it to idle
$rec->set_prop('state', 'idle');
$restore_state = 'idle';
}
print $q->startform(
-method => 'POST',
-action => $q->url (-absolute => 1)
),"\n";
print $q->start_table ({-class => "sme-noborders"}),"\n";
if ($default_action eq 'reboot')
{
print $q->start_table ({width => "100%", -class => "sme-noborders"}),"\n";
print esmith::cgi::genButtonRow(
$q,
$q->submit (-name => 'action', -value =>
$fm->localise('REBOOT'))
);
# Put in a hidden widget to store the reboot value.
print $q->hidden(
-name => 'function',
-value => 'reboot'
),"\n";
print $q->end_table,"\n";
}
else
{
print $q->Tr(
$q->td({-class => "sme-noborders-label"},
$fm->localise("SELECT_AN_ACTION")),
$q->td({-class => "sme-noborders-content"},
$q->popup_menu (
-name => 'function',
-values => [ @labels ],
-default => $default_action,
-labels => \%labels
)
)
),"\n";
#print esmith::cgi::genWidgetRow(
# $q,
# $fm->localise("SELECT_AN_ACTION"),
# $q->popup_menu (
# -name => 'function',
# -values => [ @labels ],
# -default => $default_action,
# -labels => \%labels
# )
#);
}
print $q->end_table,"\n";
if ($default_action ne 'reboot')
{
print $q->start_table ({width => "100%", -class => "sme-noborders"}),
"\n";
print esmith::cgi::genButtonRow(
$q,
$q->submit (-name => 'action', -value =>
$fm->localise('PERFORM'))
);
print $q->end_table,"\n";
}
print $q->hidden (
-name => 'state',
-override => 1,
-default => 'perform'
),"\n";
print $q->endform,"\n";
esmith::cgi::genFooter($fm);
return;
}
sub performAndShowResult
{
my ($q) = @_;
my $function = $q->param ('function');
if ($function eq 'refresh')
{
showInitial ($q, '');
}
elsif ($function eq 'reboot')
{
performReboot();
}
elsif ($function eq 'desktop-backup')
{
desktopBackup();
}
elsif ($function eq 'desktop-restore')
{
desktopRestore();
}
elsif ($function eq 'desktop-verify')
{
desktopVerify();
}
elsif ($function eq 'tape-configure')
{
TapeBackupConfig ($q);
}
elsif ($function eq 'tape-restore')
{
tapeRestore();
}
else
{
# Unknown function - refresh the screen anyway
showInitial ($q, 'unknown');
}
return;
esmith::cgi::genHeaderNonCacheable ($q, undef,
$fm->localise("X_BACKUP_OR_RESTORE"));
print $q->p ( $function );
esmith::cgi::genFooter($fm);
}
sub desktopBackupRecordStatus
{
my ($backup, $phase, $status) = @_;
my $now = time();
warn("Backup terminated: $phase failed - status: $status\n");
$backup->set_prop('EndEpochTime', "$now");
$backup->set_prop('Result', "$phase:$status");
}
sub desktopBackup ()
{
# Generate a header that will trigger a download and send data as
# an octet stream.
my $backup = $conf->get('backup');
$backup->set_prop('BackupType', 'desktop');
my $backups = esmith::BackupHistoryDB->open;
my $now = time();
my $backup_rec = $backups->new_record($now, {
type => 'backup_record',
BackupType => 'desktop',
StartEpochTime => $now,
});
# Dump the current mysql tables so that they are part of the image.
# The events handle cases where mysqld is not enabled, and/or is
# not running.
my $status = system("/sbin/e-smith/signal-event", "pre-backup", "desktop");
if ($status)
{
desktopBackupRecordStatus($backup_rec, 'pre-backup', $status);
esmith::cgi::genHeaderNonCacheable(
$fm->{cgi},
undef, $fm->localise('OPERATION_STATUS_REPORT'));
esmith::cgi::genResult(
$fm->{cgi}, $fm->localise('ERR_PRE_BACKUP'));
return;
}
print "Expires: 0\n";
print "Content-type: application/octet-stream\n";
print "Content-disposition: attachment; filename=smeserver.tgz\n";
print "\n";
setpgrp;
my $ourpgrp = getpgrp;
local $SIG{PIPE} = sub
{
local $SIG{HUP} = 'IGNORE';
warn "Got sigpipe - sending HUP to $ourpgrp\n";
kill HUP => -$ourpgrp;
desktopBackupRecordStatus($backup_rec,
'send2browser', 'Incomplete');
exit 1;
};
open(RD,
"/bin/tar --directory / --create @directories --file=-"
. " | /usr/bin/gzip |"
);
while (<RD>)
{
print;
}
close RD;
# Remove the dumped tables.
$status = system("/sbin/e-smith/signal-event", "post-backup", "desktop");
if ($status)
{
desktopBackupRecordStatus($backup_rec, 'post-backup', $status);
die ($fm->localise('ERR_POST_BACKUP'),"\n");
}
$now = time();
$backup_rec->set_prop('EndEpochTime', "$now");
$backup_rec->set_prop('Result', "0");
}
sub desktopRestore ()
{
my (undef, undef, $tmpfree, $halffree) = &CalculateSizes();
esmith::cgi::genHeaderNonCacheable ($q, undef,
$fm->localise('RESTORE_SERVER_CONFIG'));
print $q->p ($fm->localise('DESKTOP_RESTORE_DESC'));
my $freespace = eval 'return "'.$fm->localise('FREE_SPACE').'";';
print $q->p($freespace);
print $q->p (
$q->b ($fm->localise('MUST_REBOOT_AFTER_RESTORE')));
print $q->start_multipart_form(
-method => 'POST',
-action => $q->url (-absolute => 1)
);
print $q->table (
{border => 0, cellspacing => 0, cellpadding => 4},
esmith::cgi::genWidgetRow(
$q,
$fm->localise('FILE_TO_RESTORE'),
$q->filefield(
-name => 'backupFile',
-default => 'smeserver.tgz',
-size => 32
)
),
);
print $q->start_table ({width => "100%", -class => "sme-noborders"});
print esmith::cgi::genButtonRow(
$q,
$q->submit(
-name => 'action',
-value => $fm->localise('RESTORE')
)
);
print $q->end_table,"\n";
print $q->hidden(
-name => 'state',
-override => 1,
-default => 'desktop-restore'
);
print $q->endform;
esmith::cgi::genFooter($fm);
}
sub desktopVerify ()
{
my (undef, undef, $tmpfree, $halffree) = &CalculateSizes();
esmith::cgi::genHeaderNonCacheable ($q, undef,
$fm->localise('VERIFY_DESKTOP_BACKUP_FILE'));
print $q->p ($fm->localise('VERIFY_BACKUP_DESC'));
print $q->start_multipart_form(
-method => 'POST',
-action => $q->url (-absolute => 1)
);
print $q->table (
{border => 0, cellspacing => 0, cellpadding => 4},
esmith::cgi::genWidgetRow(
$q,
$fm->localise('SELECT_BACKUP_FILE'),
$q->filefield(
-name => 'backupFile',
-default => 'smeserver.tgz',
-size => 32
)
));
print $q->table ({width => "100%", -class => "sme-noborders"},
esmith::cgi::genButtonRow(
$q,
$q->submit(
-name => 'action',
-value => $fm->localise('VERIFY')
)
)),"\n";
print $q->hidden(
-name => 'state',
-override => 1,
-default => 'desktop-verify'
);
print $q->endform;
esmith::cgi::genFooter($fm);
}
sub performDesktopRestore
{
my ($q) = @_;
# Need to validate this here: $q->param ('backupFile');
my $lock_file = "/var/lock/subsys/e-smith-restore";
my $file_handle = &esmith::lockfile::LockFileOrReturn($lock_file);
unless ($file_handle)
{
esmith::cgi::genHeaderNonCacheable(
$q,
undef, $fm->localise('RESTORE_CANNOT_PROCEED')
);
print $q->p (
$q->b ($fm->localise('ANOTHER_RESTORE_IN_PROGRESS')
)
);
esmith::cgi::genFooter($fm);
return;
}
my $rec = $restore->get('restore');
$rec->set_prop('state','running');
$rec->set_prop('start', time);
unless (system("/sbin/e-smith/signal-event", "pre-restore") == 0)
{
esmith::cgi::genHeaderNonCacheable(
$fm->{cgi},
undef, $fm->localise('OPERATION_STATUS_REPORT'));
esmith::cgi::genResult(
$fm->{cgi}, $fm->localise('ERR_PRE_RESTORE'));
return;
}
if (open(RD, "-|"))
{
#----------------------------------------
# restore system from uploaded backup file
#----------------------------------------
esmith::cgi::genHeaderNonCacheable ($q, undef,
$fm->localise('RESTORE_IN_PROGRESS'));
print $q->p (
$q->b ($fm->localise('RESTORE_IN_PROGRESS_DESC')
)
);
print $q->p($fm->localise('FILES_HAVE_BEEN_RESTORED'));
print "<UL>";
my $complete = 0;
while (<RD>)
{
$complete++ if /^etc\/smbpasswd$/; # 5.x case
$complete++ if /^etc\/samba\/smbpasswd$/; # 6.0 base
print "<li>$_</li>\n";
}
print "</UL>";
my $message;
if (!close RD)
{
$message = $fm->localise('RESTORE_FAILED_MSG');
}
else
{
#-----------------------------------------------------
# if restore completed, regenerate configuration files
#-----------------------------------------------------
if ($complete)
{
$message = $fm->localise('RESTORE_COMPLETE');
system("/usr/sbin/groupmod", "-g", "$www_gid", "www") == 0
or warn ($fm->localise('ERR_RESTORING_GID')."\n");
system("/usr/sbin/usermod", "-g", "$www_gid", "www") == 0
or warn ($fm->localise('ERR_RESTORING_INITIAL_GRP')."\n");
system("/sbin/e-smith/signal-event", "post-upgrade") == 0
or die ($fm->localise('ERR_UPDATING_SYSCONF')."\n");
}
else
{
$message = $fm->localise('RESTORE_FAILED');
}
}
$rec->set_prop('state', 'complete');
$rec->set_prop('finish', time);
&esmith::lockfile::UnlockFile($file_handle);
print $q->p ($q->b ($message));
print $q->startform(
-method => 'POST',
-action => $q->url (-absolute => 1)
);
print $q->p($q->b ($fm->localise('YOU_MUST_REBOOT'))),"\n";
print $q->start_table ({width => "100%", -class => "sme-noborders"}),"\n";
print esmith::cgi::genButtonRow(
$q,
$q->submit (-name => 'action', -value =>
$fm->localise('REBOOT'))
);
# Put in a hidden widget to store the reboot value.
print $q->hidden(
-name => 'function',
-value => 'reboot'
),"\n";
print $q->hidden (
-name => 'state',
-override => 1,
-default => 'perform'
),"\n";
print $q->end_table,"\n";
print $q->endform;
esmith::cgi::genFooter($fm);
}
else
{
select(STDOUT);
$| = 1;
my $backupFile = $q->param ('backupFile');
my $decodeCommand = ( $backupFile =~ /\.bak$/ ) ?
"|/usr/bin/uudecode -o /dev/stdout" :
"|/usr/bin/gzip -d";
open(WR,
$decodeCommand
. " | /bin/tar --directory / --extract --verbose --file=-"
) || die ($fm->localise('COULD_NOT_EXEC_PIPELINE')."$!\n");
while (<$backupFile>)
{
print WR;
}
close WR || die($fm->localise('COULD_NOT_DECODE')."$!\n");
exit(0);
}
return;
}
sub performDesktopVerify
{
my ($q) = @_;
if (open(RD, "-|"))
{
esmith::cgi::genHeaderNonCacheable ($q,
undef, $fm->localise("VERIFY_DESKTOP_BACKUP_FILE"));
print $q->p($fm->localise('FILES_IN_BACKUP'));
print "<UL>";
my $complete = 0;
while (<RD>)
{
$complete++ if /^etc\/smbpasswd$/; # 5.x case
$complete++ if /^etc\/samba\/smbpasswd$/; # 6.0 base
print "<li>$_</li>\n";
}
print "</UL>";
my $status = close RD ?
($complete ?
$fm->localise('VERIFY_COMPLETE') :
$fm->localise('BACKUP_FILE_INCOMPLETE'))
: $fm->localise('ERROR_READING_FILE');
print $q->p ($q->b ($status));
esmith::cgi::genFooter($fm);
}
else
{
select(STDOUT);
$| = 1;
my $backupFile = $q->param ('backupFile');
my $decodeCommand = ( $backupFile =~ /\.bak$/ ) ?
"|/usr/bin/uudecode -o /dev/stdout" :
"|/usr/bin/gzip -d";
open(WR,
$decodeCommand
. " | /bin/tar --directory / --list --file=-"
) || die ($fm->localise('COULD_NOT_DECODE')."$!\n");
while (<$backupFile>)
{
print WR;
}
close WR;
exit 0;
}
return;
}
sub TapeBackupConfig
{
my ($q) = @_;
my $enabledChk = "";
my $backupAMPM = 'AM';
my $backupMin;
my $backupHour;
my $reminderAMPM = 'AM';
my $reminderMin;
my $reminderHour;
esmith::cgi::genHeaderNonCacheable(
$q, undef, $fm->localise('ENABLE_DISABLE_TAPE'));
print $q->p ($fm->localise('TAPE_CONFIG_DESC'));
# Obtain time for backup from the backup cron template
my $rec = $conf->get('backup');
my $backupTime = "2:00";
if ($rec)
{
$backupTime = $rec->prop('backupTime') || "2:00";
}
($backupHour, $backupMin) = split (":", $backupTime, -1);
if ($backupHour > 11)
{
if ($backupHour > 12)
{
$backupHour -= 12;
}
$backupAMPM = 'PM';
}
# Obtain time for reminder notice from the backup cron template
my $reminderTime = "14:00";
if ($rec)
{
$reminderTime = $rec->prop('reminderTime') || "14:00";
}
($reminderHour, $reminderMin) = split (":", $reminderTime, -1);
if ($reminderHour > 12)
{
$reminderHour -= 12;
$reminderAMPM = 'PM';
}
print $q->startform(
-method => 'POST',
-action => $q->url (-absolute => 1)
);
print $q->start_table ({-class => "sme-noborders"});
my $backup_status;
if ($rec)
{
$backup_status = $rec->prop('status');
}
if (defined $backup_status && $backup_status eq "enabled")
{
$enabledChk = "checked";
}
print $q->Tr(
$q->td(
$fm->localise('ENABLE_TAPE_BACKUP')
. " <input type=\"checkbox\""
. " name=\"tapebackup\""
. " $enabledChk"
. " value=\"on\">"
)
);
print $q->Tr(
esmith::cgi::genCell(
$q,$fm->localise('TAPE_BACKUP_TIME')
),
esmith::cgi::genCell ($q, $q->textfield (-name => 'backupHour',
-override => 1,
-default => $backupHour,
-size => 2)),
esmith::cgi::genCell ($q, $q->textfield (-name => 'backupMin',
-override => 1,
-default => $backupMin,
-size => 2)),
esmith::cgi::genCell ($q, "AM/PM:"),
esmith::cgi::genCell ($q, $q->popup_menu (-name => 'backupAMPM',
-values => ['AM', 'PM'],
-default => $backupAMPM)));
my %timelabels=('AM' => $fm->localise('AM'),'PM' => $fm->localise('PM'));
print $q->Tr(
esmith::cgi::genCell(
$q, $fm->localise('LOAD_TAPE_REMINDER_TIME')
),
esmith::cgi::genCell(
$q,
$q->textfield(
-name => 'reminderHour',
-override => 1,
-default => $reminderHour,
-size => 2
)
),
esmith::cgi::genCell(
$q,
$q->textfield(
-name => 'reminderMin',
-override => 1,
-default => $reminderMin,
-size => 2
)
),
esmith::cgi::genCell($q, $fm->localise("AM/PM").":"),
esmith::cgi::genCell(
$q,
$q->popup_menu(
-name => 'reminderAMPM',
-values => ['AM', 'PM'],
-labels => \%timelabels,
-default => $reminderAMPM
)
)
);
print "</table>\n";
print $q->start_table ({width => "100%", -class => "sme-noborders"});
print $q->Tr($q->th({-class => "sme-layout"},
$q->submit(
-name => 'action',
-value => $fm->localise('UPDATE_CONF')
)
)
);
print $q->hidden(
-name => 'state',
-override => 1,
-default => 'tape-configure'
);
print $q->endform;
print '</table>';
esmith::cgi::genFooter($fm);
return;
}
sub updateTapeBackupConfig
{
my ($q) = @_;
my $status = $q->param ('tapebackup');
my $ampm;
esmith::cgi::genHeaderNonCacheable(
$q,
undef, $fm->localise('UPDATING_TAPE_CONF')
);
if (defined $status && $status eq "on")
{
#--------------------------------------------------
# Untaint parameters and check for validity
#--------------------------------------------------
my $backupHour = $q->param ('backupHour');
if ($backupHour =~ /^(.*)$/) {
$backupHour = $1;
} else {
$backupHour = "12";
}
if (($backupHour < 1) || ($backupHour > 12))
{
esmith::cgi::genResult(
$fm->{cgi}, $fm->localise('ERR_INVALID_HOUR').$backupHour.
$fm->localise('BETWEEN_1_AND_12')
);
return;
}
my $backupMin = $q->param ('backupMin');
if ($backupMin =~ /^(.*)$/) {
$backupMin = $1;
} else {
$backupMin = "0";
}
if (($backupMin < 0) || ($backupMin > 59))
{
esmith::cgi::genResult(
$fm->{cgi}, $fm->localise('ERR_INVALID_MINUTE').$backupMin.
$fm->localise('BETWEEN_0_AND_59')
);
return;
}
$backupMin = sprintf("%02d", $backupMin);
$ampm = $q->param ('backupAMPM');
if ($ampm =~ /^(.*)$/) {
$ampm = $1;
} else {
$ampm = "AM";
}
# convert to 24 hour time
$backupHour = $backupHour % 12;
if ($ampm eq "PM")
{
$backupHour = $backupHour + 12;
}
my $reminderHour = $q->param ('reminderHour');
if ($reminderHour =~ /^(.*)$/) {
$reminderHour = $1;
} else {
$reminderHour = "12";
}
if (($reminderHour < 1) || ($reminderHour > 12))
{
esmith::cgi::genResult(
$fm->{cgi},
$fm->localise('ERR_INVALID_REMINDER_HOUR').$reminderHour
.$fm->localise('BETWEEN_1_AND_12')
);
return;
}
my $reminderMin = $q->param ('reminderMin');
if ($reminderMin =~ /^(.*)$/) {
$reminderMin = $1;
} else {
$reminderMin = "0";
}
if (($reminderMin < 0) || ($reminderMin > 59))
{
esmith::cgi::genResult(
$fm->{cgi}, $fm->localise('ERR_INVALID_REMINDER_MINUTE').
$reminderMin.$fm->localise('BETWEEN_0_AND_59')
);
return;
}
$reminderMin = sprintf("%02d", $reminderMin);
$ampm = $q->param ('reminderAMPM');
if ($ampm =~ /^(.*)$/) {
$ampm = $1;
} else {
$ampm = "AM";
}
# convert to 24 hour time
$reminderHour = $reminderHour % 12;
if ($ampm eq "PM")
{
$reminderHour = $reminderHour + 12;
}
# variables passed validity checks, set configuration database values
my $old = $conf->get('UnsavedChanges')->value;
my $rec = $conf->get('backup');
unless (defined $rec)
{
$rec = $conf->new_record('backup', {type=>'service'});
}
$rec->set_prop('status', 'enabled');
my $module = $rec->prop('Program');
# The default e-smith backup program is flexbackup.
unless (defined $module)
{
$module = "flexbackup";
}
elsif ($module eq '')
{
$module = "flexbackup";
}
$rec->set_prop('Program', $module);
$rec->set_prop('backupTime', "$backupHour:$backupMin");
$rec->set_prop('reminderTime', "$reminderHour:$reminderMin");
$conf->get('UnsavedChanges')->set_value($old);
system("/sbin/e-smith/signal-event", "conf-backup") == 0
or die($fm->localise('ERR_CONF_BACKUP'),"\n");
esmith::cgi::genResult(
$fm->{cgi}, $fm->localise('SUCCESSFULLY_ENABLED_TAPE').$q->br().
$fm->localise('WITH_BACKUP_TIME')."$backupHour:$backupMin".
$q->br().$fm->localise('WITH_REMINDER_TIME').
"$reminderHour:$reminderMin");
}
else
{
# set service to disabled
my $old = $conf->get('UnsavedChanges')->value;
my $rec = $conf->get('backup');
unless ($rec)
{
$rec = $conf->new_record('backup', {type=>'service'});
}
$rec->set_prop('status', 'disabled');
$conf->get('UnsavedChanges')->set_value($old);
system("/sbin/e-smith/signal-event", "conf-backup") == 0
or die($fm->localise('ERR_CONF_BACKUP')."\n");
esmith::cgi::genResult(
$fm->{cgi}, $fm->localise('SUCCESSFULLY_DISABLED')
);
}
return;
}
sub tapeRestore ()
{
esmith::cgi::genHeaderNonCacheable(
$q, undef, $fm->localise('RESTORE_CONF_FROM_TAPE'));
print $fm->localise('RESTORE_CONF_FROM_TAPE_DESC');
print $q->start_multipart_form(
-method => 'POST',
-action => $q->url (-absolute => 1)
);
print $q->start_table ({width => "100%", -class => "sme-noborders"});
print esmith::cgi::genButtonRow(
$q,
$q->submit (-name => 'action',
-value => $fm->localise('RESTORE_FROM_TAPE'))
);
print "</table>\n";
print $q->hidden(
-name => 'state',
-override => 1,
-default => 'tape-restore'
);
print $q->endform;
esmith::cgi::genFooter($fm);
}
sub performTapeRestore
{
my ($q) = @_;
#----------------------------------------
# restore system from backup tape
#----------------------------------------
my $lock_file = "/var/lock/subsys/e-smith-restore";
my $file_handle = &esmith::lockfile::LockFileOrReturn($lock_file);
unless ($file_handle)
{
esmith::cgi::genHeaderNonCacheable(
$q,
undef,
$fm->localise('UNABLE_TO_RESTORE_CONF')
);
print $q->p (
$q->b ($fm->localise('ANOTHER_RESTORE_IN_PROGRESS')
)
);
esmith::cgi::genFooter($fm);
return;
}
my $rec = $restore->get('restore');
$rec->set_prop('state', 'running');
$rec->set_prop('start', time);
my $sec = 10;
print "Refresh: $sec; URL=/server-manager/cgi-bin/backup\n";
esmith::cgi::genHeaderNonCacheable(
$q, undef, $fm->localise()
);
print $q->p($fm->localise('NOW_RESTORING_FROM_TAPE')
);
print $q->p (
$q->b ($fm->localise('MUST_REBOOT_AFTER_RESTORE'))
);
print $q->p($fm->localise('PAGE_REFRESH_IN', {sec=>$sec}));
my $child;
if ($child = fork)
{
# Parent
$SIG{'CHLD'} = 'IGNORE';
&esmith::lockfile::UnlockFile($file_handle);
esmith::cgi::genFooter($fm);
return;
}
elsif (defined $child)
{
# Child
# Re-establish the lock. Wait till it is relinquished by the parent.
$file_handle = &esmith::lockfile::LockFileOrWait($lock_file);
# Close STDOUT so that the web server connection is closed.
close STDOUT;
# Now reopen STDOUT for the child. Redirect it to STDERR.
open(STDOUT, ">&STDERR");
unless(system("/sbin/e-smith/signal-event", "pre-restore") == 0)
{
$rec->set_prop('errmsg', 'ERR_PRE_RESTORE');
$rec->delete_prop('state');
die ($fm->localise('ERR_PRE_RESTORE'),"\n");
}
unless(system("/sbin/e-smith/signal-event", "restore-tape") == 0)
{
$rec->set_prop('errmsg', 'ERR_RESTORING_FROM_TAPE');
$rec->delete_prop('state');
die ($fm->localise('ERR_RESTORING_FROM_TAPE')."\n");
}
#----------------------------------------
# regenerate configuration files
#----------------------------------------
unless(system("/usr/sbin/groupmod", "-g", "$www_gid", "www") == 0)
{
$rec->set_prop('errmsg', $rec->prop('errmsg').'<br>ERR_RESTORING_GID');
warn ($fm->localise('ERR_RESTORING_GID')."\n");
}
unless(system("/usr/sbin/usermod", "-g", "$www_gid", "www") == 0)
{
$rec->set_prop('errmsg', $rec->prop('errmsg').
'<br>ERR_RESTORING_INITIAL_GRP');
warn ($fm->localise('ERR_RESTORING_INITIAL_GRP')."\n");
}
unless(system("/sbin/e-smith/signal-event", "post-upgrade") == 0)
{
$rec->set_prop('errmsg', $rec->prop('errmsg').
'<br>ERR_UPDATING_CONF_AFTER_TAPE_RESTORE');
$rec->delete_prop('state');
die ($fm->localise('ERR_UPDATING_CONF_AFTER_TAPE_RESTORE'));
}
my $finish = time;
$rec->set_prop('state', 'complete');
$rec->set_prop('finish', $finish);
my $start = $rec->prop('start');
$start = scalar localtime($start);
$finish = scalar localtime($finish);
&esmith::lockfile::UnlockFile($file_handle);
exit;
}
else
{
# Error
$rec->delete_prop('state');
$rec->set_prop('errmsg', 'COULD_NOT_FORK');
die ($fm->localise("COULD_NOT_FORK")."$!\n");
}
}
sub performReboot ()
{
esmith::cgi::genHeaderNonCacheable ($q, undef,
$fm->localise('SERVER_REBOOT'));
print $q->p (
$q->b ($fm->localise('SERVER_WILL_REBOOT'))
);
esmith::cgi::genFooter($fm);
esmith::util::backgroundCommand(
5,
"/sbin/e-smith/signal-event",
"reboot"
);
}
sub CalculateSizes ()
{
#------------------------------------------------------------
# figure out the size of the tar file.
#------------------------------------------------------------
my $tarsize = 0;
# It takes way too much time to do a du on /home/e-smith. So we'll
# estimate the current size.
# We do this by checking the quota used by each user on the system.
use Quota;
use esmith::AccountsDB;
my $accounts = esmith::AccountsDB->open;
# Get a $dev value appropriate for use in Quota::query call.
my $dev = Quota::getqcarg("/home/e-smith/files");
foreach my $user ($accounts->users())
{
my $name = $user->key;
my $uid = getpwnam($name);
unless ($uid)
{
warn ($fm->localise('NO_UID_FOR_NAME').$name."\n");
# We shouldn't ever get here. If we do, we can't get
# the quota value for this user, so we just skip to
# the next one.
next;
}
# Get current quota settings.
my ($blocks) = Quota::query($dev, $uid, 0);
$tarsize += $blocks;
}
# We add to this the size of root owned firectories, estimated using du.
# If this takes too long, then the admin only has his or
# herself to blame!
# Remove /home/e-smith from backup list, and make paths absolute
my @list = map { "/$_" } grep { !/home\/e-smith/ } @directories;
open(DU, "-|")
or exec '/usr/bin/du', '-s', @list;
while (<DU>)
{
my ($du) = split(/\s+/);
$tarsize += $du;
}
close DU;
$tarsize = &showSize($tarsize);
#------------------------------------------------------------
# figure out the size of the dump files
#------------------------------------------------------------
my $dumpsize = 0;
open(DF, "-|")
or exec '/bin/df', '-P', '-t', 'ext3';
while (<DF>)
{
next unless (/^\//);
(undef, undef, my $s, undef) = split(/\s+/, $_);
$dumpsize += $s;
}
# increase size by 10% to cope with dump overhead.
$dumpsize *= 1.1;
close DF;
$dumpsize = &showSize($dumpsize);
#------------------------------------------------------------
# how much free space is in /tmp
#------------------------------------------------------------
my $tmpfree = 0;
my $halffree = 0;
open(DF, "-|")
or exec '/bin/df', '-P', '-t', 'ext3', '/tmp';
while (<DF>)
{
next unless (/^\//);
(undef, undef, undef, my $s) = split(/\s+/, $_);
$tmpfree += $s;
}
close DF;
$halffree = $tmpfree / 2;
$tmpfree = &showSize($tmpfree);
$halffree = &showSize($halffree);
return ($tarsize, $dumpsize, $tmpfree, $halffree);
}
sub showSize
{
# convert size to Mb or Gb or Tb

Remember, df reports in kb.
my $size = shift;
my $Mb = 1024;
my $Gb = $Mb * $Mb;
my $Tb = $Mb * $Mb * $Mb;
if ($size >= $Tb)
{
$size /= $Tb;
$size = int($size) . "Tb";
}
elsif ($size >= $Gb)
{
$size /= $Gb;
$size = int($size) . "Gb";
}
elsif ($size >= $Mb)
{
$size /= $Mb;
$size = int($size) . "Mb";
}
else
{
$size .= "kb";
}
return $size;
}
__DATA__
<form>
</form>