diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/BackupTime mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/BackupTime --- e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/BackupTime 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/BackupTime 2007-09-05 15:53:17.000000000 -0400 @@ -0,0 +1 @@ +22:00 diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/Compression mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/Compression --- e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/Compression 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/Compression 2007-09-05 15:53:22.000000000 -0400 @@ -0,0 +1 @@ +4 diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/DaysInSet mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/DaysInSet --- e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/DaysInSet 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/DaysInSet 2007-09-05 15:54:31.000000000 -0400 @@ -0,0 +1 @@ +1 diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/IncOnlyTimeout mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/IncOnlyTimeout --- e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/IncOnlyTimeout 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/IncOnlyTimeout 2007-09-05 15:54:38.000000000 -0400 @@ -0,0 +1 @@ +no diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/Login mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/Login --- e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/Login 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/Login 2007-09-05 15:54:43.000000000 -0400 @@ -0,0 +1 @@ +backup diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/Password mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/Password --- e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/Password 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/Password 2007-09-05 15:56:11.000000000 -0400 @@ -0,0 +1 @@ +backup diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/Program mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/Program --- e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/Program 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/Program 2007-09-05 15:56:15.000000000 -0400 @@ -0,0 +1 @@ +dar diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/SetsMax mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/SetsMax --- e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/SetsMax 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/SetsMax 2007-09-05 15:58:44.000000000 -0400 @@ -0,0 +1 @@ +1 diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/SmbHost mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/SmbHost --- e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/SmbHost 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/SmbHost 2007-09-05 15:55:01.000000000 -0400 @@ -0,0 +1 @@ +host diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/SmbShare mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/SmbShare --- e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/SmbShare 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/SmbShare 2007-09-05 15:58:49.000000000 -0400 @@ -0,0 +1 @@ +share diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/status mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/status --- e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/status 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/status 2007-09-05 15:55:09.000000000 -0400 @@ -0,0 +1 @@ +disabled diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/Timeout mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/Timeout --- e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/Timeout 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/Timeout 2007-09-05 15:58:55.000000000 -0400 @@ -0,0 +1 @@ +8 diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/type mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/type --- e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/type 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/type 2007-09-05 15:56:22.000000000 -0400 @@ -0,0 +1 @@ +service diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/VFSType mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/VFSType --- e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/VFSType 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/db/configuration/defaults/backupwk/VFSType 2007-09-05 15:56:26.000000000 -0400 @@ -0,0 +1 @@ +smbfs diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/events/actions/workstation-backup-dar mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/events/actions/workstation-backup-dar --- e-smith-backup-1.15.0/root/etc/e-smith/events/actions/workstation-backup-dar 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/events/actions/workstation-backup-dar 2007-09-05 15:52:45.000000000 -0400 @@ -0,0 +1,267 @@ +#!/usr/bin/perl -w + +#---------------------------------------------------------------------- +# copyright (C) 2006 Jean-Paul Leclere +# +# 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 +# +#---------------------------------------------------------------------- + +use strict; +use Errno; +use esmith::util; +use esmith::templates; +use Time::localtime; +use File::Copy; +use File::Path; +use esmith::ConfigDB; + +sub ldie; + +my $job = shift || 'DailyBackup'; +my $report; + +my $confdb = esmith::ConfigDB->open; +my $backupwk = $confdb->get('backupwk') or die "No backupwk db entry found\n"; + +my $tm = localtime(time); +my $bkname = $tm->year+1900; + if (($tm->mon) < 9) {$bkname .= ("0".($tm->mon+1))} else {$bkname .= ($tm->mon+1)} + if (($tm->mday) < 10) {$bkname .= ("0".$tm->mday)} else {$bkname .= $tm->mday} +my $dow = $tm->wday; +my $id = $backupwk->prop('Id') || $confdb->get('SystemName')->value . "." . $confdb->get('DomainName')->value; +my $err; +my $ref = ""; +my $mntdone = 0; +my $tim = ctime(); + +my $smbhost = $backupwk->prop('SmbHost'); +my $smbshare = $backupwk->prop('SmbShare'); +my $login = $backupwk->prop('Login'); +my $password = $backupwk->prop('Password'); +my $setsmax = $backupwk->prop('SetsMax') || 1; +my $daysinset = $backupwk->prop('DaysInSet') || 1; +my $setnum = $backupwk->prop('SetNum'); $setnum = ($setsmax-1) unless defined $setnum; +my $incnum = $backupwk->prop('IncNum'); $incnum = ($daysinset-1) unless defined $incnum; +my $timeout = (($backupwk->prop('Timeout') * 3600) - 30) || '88500'; +my $inconly = $backupwk->prop('IncOnlyTimeout') || 'no'; +my $VFSType = $backupwk->prop('VFSType') || 'smbfs'; +my $fullday = $backupwk->prop('FullDay') || 7; +my $mail = $backupwk->prop('MailNotify') || 'yes'; +my $mntdir = $backupwk->prop('Mount') || '/mnt/smb'; +my $tmpdir = $mntdir . "/tmp_dir"; + +$report .= "From: Backup-Program\n"; +$report .= "Subject: Daily Backup Report\n\n"; +$report .= "================================== \n"; +$report .= "DAILY BACKUP TO WORKSTATION REPORT \n"; +$report .= "================================== \n"; +$report .= "Backup started at " .$tim . "\n"; +$report .= "Backup of mysql databases has been done.\n"; + +# mounting backup directory + +$report .= "Mounting backup shared directory $smbhost/$smbshare \n"; + +# verify backup directory not already mounted + +if ( $VFSType ne 'usb' ) { + open FD, '/proc/mounts'; + while () { + next unless /$smbhost(.*)\/$smbshare/; + next unless /$mntdir/; + $err++ + } + close FD; + if ($err) { + ldie("Seems backup directory is already mounted. It should not happen \ +and maybe there is a zombie process you must kill, or another backup in progress. \n") + } + if ($VFSType eq 'cifs'){ + $err = qx(/bin/mount -t cifs $smbhost:$smbshare $mntdir -o user=$login,pass=$password); + if ($err) {ldie("Error while mounting $smbhost:$smbshare : \n" . $err)}; + } + elsif ($VFSType eq 'smbfs'){ + $err = qx(/bin/mount -t smbfs //$smbhost/$smbshare $mntdir -o username=$login,password=$password,dmask=777,fmask=777,ip=$smbhost 2>&1); + if ($err) {ldie("Error while mounting //$smbhost/$smbshare : \n" . $err)}; + } + elsif ($VFSType eq 'nfs'){ + $err = qx(/bin/mount -t nfs -o nolock $smbhost:/$smbshare $mntdir 2>&1); + if ($err) {ldie("Error while mounting $smbhost:/$smbshare : \n" . $err)}; + } + else {ldie("Error while mounting $smbhost/$smbshare : $VFSType not supported.\n")} + + $mntdone = 1; + } +else { $mntdir = "/".$smbshare } + +if (-d "$tmpdir/$id") { + eval {rmtree("$tmpdir/$id")}; + if ($@) {ldie("Error while deleting $tmpdir/$id : $@.\n")} + } +eval {mkpath("$tmpdir/$id")}; +if ($@) {ldie("Error while creating $tmpdir/$id : $@. Maybe insufficient rights on backup directory.\n")} + +# we know right backup directory is in line and we can write on it. +$report .= "Backup temp directory $tmpdir/$id is mounted and is writable \n"; + +# rotating backup indicators + +++$incnum; +$incnum %= $daysinset; +if ( $incnum == 0 ) { + ++$setnum; + $setnum %= $setsmax; + } + +$report .= "Using set number $setnum of $setsmax\n"; +if ($incnum == 0) { + $report .= "Attempt to full backup \n"; + } +else { + $report .= "Attempt to incremental backup number $incnum of $daysinset\n"; + } + +# if no set directory, make it + +my $setname = "set" . $setnum; +my $setdirname = $mntdir . "/$id/" . $setname; + +unless ( -d $setdirname ) { + eval {mkpath($setdirname)}; + if ($@) {ldie("Can't create $setdirname : $@.\n")} + $report .= "Backup directory $id/$setname created \n"; + } + +# if $incnum <> 0 backup should be incremental +# we find correct reference backup for incremental + +if ( $incnum != 0 ) { + my $file; + opendir(DIR, $setdirname) or ldie("Can't open dir $setdirname $!"); + while (defined($file = readdir(DIR))) { + next if $file =~ /^\.\.?$/; + if ( $file =~ /dar$/) { + $ref = $file; + } + } + closedir (DIR); + # if no reference do full backup + if ($ref eq "") { + $incnum = 0; + $report .= "No existing reference backup, will make full backup \n"; + $bkname = "full-" . $bkname; + } + else { # removing .dar extension + $ref =~ s/\..*\.dar$//; + $ref = "--ref " . $setdirname . "/" . $ref; + $bkname = "inc-" . sprintf("%03d", $incnum) . "-". $bkname; + } + } +else { + $bkname = "full-" . $bkname; + } + +unless ( ( $incnum != 0 ) || ( $fullday == 7 ) || ( $dow == $fullday ) ) { + my $delay = ($fullday - $dow) % 7; + ldie("Not a permitted day for full backup. Aborting...\nNext full backup in $delay days.\n"); + } + +$report .= "Backup base file name is $bkname \n"; +$report .= "Making backup on temporary dir... \n"; + +# calculate real timeout if we timeout incrementals only. +# timeout of 88500 is a security for aborting backup within 24h + +if ( ($ref eq "") && ($inconly eq "yes")) { + $timeout = 88500; + } +$report .= "using a backup session timeout of : $timeout seconds\n"; + +# expanding backup configuration file template + +processTemplate({ + TEMPLATE_PATH => "/etc/dar/$job.dcf", + }); + +# launching dar backup + +$err = system("/usr/bin/timeout -s TERM $timeout /usr/bin/dar -c $tmpdir/$id/$bkname $ref -B /etc/dar/$job.dcf"); + +if ($err == 0) +{ +$report .= "Backup completed successfully on temporary dir \n"; +} +elsif ($err == 15) +{ +$report .= "Partial backup stored on temp dir.\n" + . " Session closed by timeout after $timeout seconds.\n" + . "Not an error, backup process will continue next night.\n"; +} +else +{ +$err = $err >> 8; +ldie("Dar error during backup : $err \n"); +} + +if ($incnum == 0) { + $report .= "Rotating backups in a new set $setdirname. \n"; + eval {rmtree($setdirname)}; + if ($@) {ldie("Error while deleting $setdirname : $@.\n")} + eval {mkpath("$setdirname")}; + if ($@) {ldie("Error while creating $setdirname : $@.\n")} + } +$report .= "Moving backup files to target directory $setdirname \n"; +foreach (<$tmpdir/$id/$bkname*>) { + unless ( move($_, $setdirname) ) + {ldie("Error while moving backup file $_ from temporary dir $tmpdir/$id to $setdirname : $!")}; + } + +# unmount shared folder + +if ( $VFSType ne 'usb' ) {system("/bin/umount -f $mntdir")} + +# time now to update backup configuration + +$report .= "Updating backup configuration data \n"; +$backupwk->set_prop('SetNum', $setnum); +$backupwk->set_prop('IncNum', $incnum); + +$tim = ctime(); +$report .= "Backup successfully terminated at : $tim \n"; + +if ($mail eq 'yes') { + open (MAIL, "|/var/qmail/bin/qmail-inject -a admin") + || die "Cannot start mail program: $!\n"; + print MAIL $report; + close(MAIL); + } + +exit (0); + +sub ldie +{ +my $errmsg = shift; +$report .= "*** No backup allowed or error during backup ***\n"; +$report .= $errmsg; +if (($mail eq 'yes') || ($mail eq 'error')) { + open (MAIL, "|/var/qmail/bin/qmail-inject -a admin") + || die "Cannot start mail program: $!\n"; + print MAIL $report; + close(MAIL); + } +if (($mntdone) && ($VFSType ne 'usb')) {system("/bin/umount $mntdir")}; +die($errmsg); +} diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/locale/en-us/etc/e-smith/web/functions/backup mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/locale/en-us/etc/e-smith/web/functions/backup --- e-smith-backup-1.15.0/root/etc/e-smith/locale/en-us/etc/e-smith/web/functions/backup 2007-09-05 15:45:52.000000000 -0400 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/locale/en-us/etc/e-smith/web/functions/backup 2007-09-05 15:52:45.000000000 -0400 @@ -11,8 +11,9 @@ BACKUP_DESC The server provides two ways to back up and restore - your server: using your local desktop or a tape drive.

+

The server provides three ways to back up and restore + your server: using your local desktop, a tape drive or a + workstation on your LAN.

The first method creates a copy of your server configuration and user data files, and downloads it to your local desktop via your web browser. @@ -29,9 +30,19 @@ reminder automatically e-mailed to the administrator during the day). Currently your hard disk contains $dumpsize of data.

-

Both restore methods allow you to restore your configuration and user - data files. Ideally, the restore should be performed on a freshly - installed server.

+

The workstation backup method uses a software package called dar + to back up your server configuration and data files to a workstation + on your LAN (or a local USB disk). This requires you provide a writable share + (smbfs, cifs, or nfs) on the backup workstation or an a local USB disk. You can manage + how many rotating sets of backup are kept on the backup share, and also make each + set doing incremental backup upon several days. The backup is performed + automatically at the selected time every night. Currently + configuration and data files total approximately $tarsize uncompressed. + Twice the compressed data size must be available on the backup share.

+ +

All restore methods allow you to restore your configuration and user + data files. Workstation backup provides individual file restore. Ideally, + full restore should be performed on a freshly installed server.

]]>
@@ -330,8 +341,8 @@ Error: invalid backup hour: - BETWEEN_1_AND_12 - Please choose an hour between 1 and 12. + BETWEEN_0_AND_12 + Please choose an hour between 0 and 12. ERR_INVALID_MINUTE @@ -458,5 +469,412 @@ ]]> - + + WORKSTN_BACKUPS_DISABLED + + disabled + ]]> + + + + WORKSTN_BACKUPS_ENABLED + + enabled. + ]]> + + + + WKBACKUPS_RUN_AT + Regular workstation backups will run at: + + + WORKSTN_CONFIGURE + Configure workstation backup + + + WORKSTN_VERIFY + Verify workstation backup + + + WORKSTN_RESTORE + Restore from workstation + + + CONFIGURE_WORKSTN_BACKUP + Configure Workstation Backup + + + ENABLE_DISABLE_WORKSTN + Enable/Disable Daily Workstation Backup + + + ENABLE_WORKSTN_BACKUP + Enable Workstation Backup + + + WORKSTN_BACKUP_TIME + Workstation backup time of day (hour/min) + + + UPDATING_WORKSTN_CONF + Updating workstation backup configuration + + + SUCCESSFULLY_ENABLED_WORKSTN + Successfully enabled workstation backups + + + SUCCESSFULLY_DISABLED_WORKSTN + Successfully disabled workstation backups + + + VERIFY_WORKSTN_BACKUP_FILE + Verify workstation backup file + + + VERIFY_WORKSTN_BACKUP_DESC + + This option will display the names of all files + in a previously created workstation daily backup. You + can use this option to verify the contents of the + backup.You must choose the backup you want to verify

+

You will see all files in the selected backup.

+ Backup files are verified from shared folder : + ]]> +
+
+ + RESTORE_CONF_FROM_WORKSTN + Restore server configuration from workstation backup + + + RESTORE_CONF_FROM_WORKSTN_DESC + + This process will restore the configuration and user data files from a + Server workstation backup. The restore + should be performed on a freshly installed Server.

+

Ensure that choose the right backup to restore below + before proceeding.

+

After the restore completes you must reboot the server.

+ Backup will be restored from : + ]]> +
+
+ + RESTORE_FROM_WORKSTN + Restore From Workstation + + + RESTORING_FROM_WORKSTN + Restoring From Workstation + + + NOW_RESTORING_FROM_WORKSTN + + Your server configuration and user data + files are now being restored from workstation shared folder. + + + + ERR_RESTORING_FROM_WORKSTN + Error occurred restoring files from workstation. + + + ERR_UPDATING_CONF_AFTER_WORKSTN_RESTORE + Error occurred while updating system configuration after workstation + restore. + + + + WORKSTN_NAME + Workstation IP or hostname + + + + WORKSTN_BACKUP_SETTINGS + Workstation Backup Settings + + + SHARED_FOLDER_NAME + Backup share + + + + WORKSTN_LOGIN + Login name + + + + WORKSTN_PASSWORD + Password + + + WORKSTATION_BACKUP_DEST + Backup workstation settings + + + CONFIGURE_WORKSTN_BACKUP_DESC + You can set the number of + successive backup sets to keep on the workstation, with automatic rotation. + Each set may contain saved datas for several consecutive days. + In this case first backup of the set is full backup, others daily backups are + incremental. You can also set a time limit for each backup session or for incremental + backups only. When this limit occurs, backup is cleanly stopped and the next + incremental backup will safely continue with unsaved and modified datas. + + + ERR_INVALID_WORKSTN + Invalid Workstation IP or Hostname + + + + ERR_INVALID_FOLDER + Invalid share name + + + + ERR_INVALID_LOGIN + Invalid Login + + + + ERR_INVALID_PASSWORD + Invalid Password + + + ERR_MOUNTING_SMBSHARE + Unable to mount workstation shared folder + + + WORKSTN_NOT_SET + You must first correctly configure your workstation backup + + + NO_BACKUPS_TO_RESTORE + There is no backup set on configured workstation shared folder. Verify your configuration settings. + + + NUMBER_OF_SETS + Number of rotating backup sets + + + NUMBER_OF_FILES_IN_SET + Daily backups in each set + + + ERR_INVALID_SETS_NUMBER + Sets number must be 1 or greater + + + ERR_INVALID_FILES_IN_SET_NUMBER + This number must be 1 or greater. First backup in set is full others are incrementals + + + WORKSTN_TIMEOUT + Optional backup session timeout (hours) + + + INC_ONLY_TIMEOUT + Don't timeout full backup sessions + + + ERR_INVALID_TIMEOUT + Maximum backup time must be set between 1 and 24 hours + + + ERR_NO_HOST_DIR + No directory for your host in shared folder. Maybe your host name is different from backup ones + + + ERROR_READING_FILE + Error while reading files from + + + WORKSTN_SEL_RESTORE + Selective file restore from workstation + + + WORKSTN_SELECTIVE_RESTORE + Workstation selective file restore + + + ALL_BACKUPS + All backups + + + WORKSTN_SEL_REST_DESC + +
+ The next panel will display available files and directories, + so you can choose the ones to restore. To restrict the number of files and directories + displayed in this panel, you have the option to give now a filtering expression, + applied as a regular expression to the displayed names.

+ You have the responsability not to restore files which could break the functioning + of your server.

Currently, files will be restored from : + ]]> +
+
+ + BACKUP_CHOICE + Selecting files to display + + + SELECT_DATE_BEFORE + Restore most recent before + + + FILTER_EXPRESSION + Names filtered by + + + READ_COMPLETE + + Warning : If you select a directory, + all contained files and directories will be restored.

+ By default the most recent version of selected files is restored, but if you specify a date + in the format [ [ [yyyy/]mm/]dd-]hh:mm[:ss] the process + will restore only the most recent version modified before the given date. + ]]> + + + + ERR_INVALID_SELDATE + Date format is invalid, must be [ [ [yyyy/]mm/]dd-]hh:mm[:ss]. ie: 2005/12/31-08:23:32 or + 10-08:32 or 08:32 + + + SELECT_FILES_TO_RESTORE + Select files to restore + + + ERR_WHILE_UNMOUNTING + Error occurs when unmounting distant share + + + ERR_DAR_CATALOG + Error when using Dar catalog + + + COMPRESSION_LEVEL + Backup compression level [0-9] + + + FULL_ONLY_ON + Full backup is allowed on + + + ERR_INVALID_COMPRESSION + Compression level must be set between 0 (no compression) and 7 (maximum compression) + + + DOW + Sunday Monday Tuesday Wednesday Thursday Friday Saturday Everyday + + + CONFIGURATION_TO_BE_DONE + You must before execute Workstation backup configuration option + + + WORKSTN_BACKUP_DESC + + This panel displays the present workstation backup configuration. You can + change it in this panel and the next one.

+ ]]> + + + + WORKSTN_BACKUP_NOT_CONFIGURED + + Presently, workstation backup is not configured. You can set this configuration + with this panel and the next one.

+ ]]> + + + + WORKSTN_BACKUP_ENABLED + Backup is + + + WORKSTN_BACKUP_USB + Backup is made on local USB disk + + + WORKSTN_BACKUP_HOST + Backup is made on LAN workstation + + + WORKSTN_BACKUP_VFSTYPE + via + + + WORKSTN_BACKUP_SHARE + Destination backup share folder is + + + WORKSTN_BACKUP_TOD + Daily backup occurs at + + + LOGIN + Login is + + + PASSWORD + Password is + + + WORKSTN_BACKUP_SETSNUM + Number of rotating backup sets is + + + WORKSTN_BACKUP_DAYSINSET + Number of daily backups contained in each set is + + + WORKSTN_BACKUP_COMPRESSION + Compression level (0-7) of backup is + + + WORKSTN_BACKUP_TIMEOUT + Each daily backup session is cleanly timed out after + + + WORKSTN_BACKUP_INCONLY_TIMEOUT + except full backups which are cleanly timed out after 24 hours + + + WORKSTN_FULL_BACKUP_EVERYDAY + Full backup sessions (new backup set) are allowed everyday + + + WORKSTN_FULL_BACKUP_DAY + Full backup session (new backup sets) is allowed only on + + + WORKSTATION_BACKUP_SETCONF + Create or modify workstation backup configuration + + + SELECT_VFS_TYPE + Select the type of share for backup destination + + + ERR_NO_USB_DISK + Error : No USB disk available. Please connect an USB disk or select another type of backup share. + + + NEXT + Next + diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/crontab/backupwk mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/crontab/backupwk --- e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/crontab/backupwk 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/crontab/backupwk 2007-09-05 15:52:45.000000000 -0400 @@ -0,0 +1,30 @@ +{ + + $OUT = ''; + + my $status = $backupwk{status}; + + if (defined $status && $status eq 'enabled') + { + # configure backup time and reminder times from the configuration + # database + + my $backupMin; + my $backupHour; + + my $backupTime = $backupwk{BackupTime} || "1:00"; + + ($backupHour, $backupMin) = split (":", $backupTime, -1); + + # remove leading zeros from minutes + + $backupMin =~ s/00/0/; + + $OUT .="$backupMin $backupHour * * * root" + . " /sbin/e-smith/do_backupwk" + } + else + { + $OUT .= "# Workstation Backup task is disabled"; + } +} diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/10compression mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/10compression --- e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/10compression 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/10compression 2007-09-05 15:52:45.000000000 -0400 @@ -0,0 +1,3 @@ +{ +($backupwk{Compression} || '0') eq '0' ? "#Compression off\n" : "--bzip2=$backupwk{Compression}\n" +} \ No newline at end of file diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/20empty-dir mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/20empty-dir --- e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/20empty-dir 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/20empty-dir 2007-09-05 15:52:45.000000000 -0400 @@ -0,0 +1 @@ +--empty-dir diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/30fs-root mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/30fs-root --- e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/30fs-root 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/30fs-root 2007-09-05 15:52:45.000000000 -0400 @@ -0,0 +1 @@ +--fs-root / diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/40go-into mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/40go-into --- e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/40go-into 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/40go-into 2007-09-05 15:52:45.000000000 -0400 @@ -0,0 +1,13 @@ +--go-into etc/e-smith/templates-custom +--go-into etc/e-smith/templates-user-custom +--go-into etc/group +--go-into etc/gshadow +--go-into etc/passwd +--go-into etc/samba/secrets.tdb +--go-into etc/samba/smbpasswd +--go-into etc/shadow +--go-into etc/smbpasswd +--go-into etc/ssh +--go-into etc/sudoers +--go-into home/e-smith +--go-into root diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/50exclude mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/50exclude --- e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/50exclude 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/50exclude 2007-09-05 15:52:45.000000000 -0400 @@ -0,0 +1 @@ +--exclude "*.dar" diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/60exclude-compression mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/60exclude-compression --- e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/60exclude-compression 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/60exclude-compression 2007-09-05 15:52:45.000000000 -0400 @@ -0,0 +1,29 @@ +{ +($backupwk{Compression} || '0') eq '0' ? "#Compression off\n" : +'--exclude-compression "*.mp3" +--exclude-compression "*.avi" +--exclude-compression "*.mpg" +--exclude-compression "*.mpeg" +--exclude-compression "*.divx" +--exclude-compression "*.rm" +--exclude-compression "*.wmv" +--exclude-compression "*.wma" +--exclude-compression "*.asf" +--exclude-compression "*.ra" +--exclude-compression "*.gif" +--exclude-compression "*.jpg" +--exclude-compression "*.jpeg" +--exclude-compression "*.png" +--exclude-compression "*.zip" +--exclude-compression "*.dar" +--exclude-compression "*.tgz" +--exclude-compression "*.gzip" +--exclude-compression "*.bzip" +--exclude-compression "*.bzip2" +--exclude-compression "*.rar" +--exclude-compression "*.gz" +--exclude-compression "*.rpm" +--exclude-compression "*.iso" +--exclude-compression "*.bz2" +' +} \ No newline at end of file diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/70noconf mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/70noconf --- e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/70noconf 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/70noconf 2007-09-05 15:52:45.000000000 -0400 @@ -0,0 +1 @@ +--noconf diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/80no-warn mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/80no-warn --- e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/80no-warn 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/80no-warn 2007-09-05 15:52:45.000000000 -0400 @@ -0,0 +1 @@ +--no-warn diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/90slice mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/90slice --- e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/90slice 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/templates/etc/dar/DailyBackup.dcf/90slice 2007-09-05 15:52:45.000000000 -0400 @@ -0,0 +1,3 @@ +{ +($backupwk{Slice} || '700M') eq '700M' ? "--slice 700M\n" : "--slice $backupwk{Slice}\n" +} diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/etc/e-smith/web/functions/backup mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/web/functions/backup --- e-smith-backup-1.15.0/root/etc/e-smith/web/functions/backup 2007-09-05 15:45:52.000000000 -0400 +++ mezzanine_patched_e-smith-backup-1.15.0/root/etc/e-smith/web/functions/backup 2007-09-05 15:52:45.000000000 -0400 @@ -31,6 +31,9 @@ use esmith::cgi; use esmith::util; use esmith::lockfile; +use File::Find; + +$File::Find::dont_use_nlink = 1; # fix for Windows shares my $fm = esmith::FormMagick->new(); @@ -90,6 +93,30 @@ { performTapeRestore ($q); } +elsif ($q->param ('state') eq "workstn-configure") +{ + WorkstnBackupConfig1($q); +} +elsif ($q->param ('state') eq "workstn-configure1") +{ + updateWorkstnBackupConfig($q); +} +elsif ($q->param ('state') eq "workstn-verify") +{ + performWorkstnVerify($q); +} +elsif ($q->param ('state') eq "workstn-restore") +{ + performWorkstnRestore ($q); +} +elsif ($q->param ('state') eq "workstn-sel-restore") +{ + performWorkstnSelRestore ($q); +} +elsif ($q->param ('state') eq "workstn-sel-restore2") +{ + performWorkstnSelRestore2 ($q); +} else { esmith::cgi::genStateError ($q, undef); @@ -184,12 +211,34 @@ print $q->p($fm->localise('TAPE_BACKUPS_DISABLED')),"\n"; } + my $backupwk_status = $conf->get('backupwk'); + if ($backupwk_status) + { + $backupwk_status = $backupwk_status->prop('status'); + } + + if (defined $backupwk_status && $backupwk_status eq "enabled") + { + my $backupwkTime = $conf->get('backupwk')->prop('BackupTime'); + + print $q->p ($fm->localise('WORKSTN_BACKUPS_ENABLED'), + $fm->localise('WKBACKUPS_RUN_AT'),$q->b($backupwkTime)); + } + else + { + print $q->p($fm->localise('WORKSTN_BACKUPS_DISABLED')); + } + 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'), + "workstn-configure" => $fm->localise('WORKSTN_CONFIGURE'), + "workstn-verify" => $fm->localise('WORKSTN_VERIFY'), + "workstn-restore" => $fm->localise('WORKSTN_RESTORE'), + "workstn-sel-restore" => $fm->localise('WORKSTN_SEL_RESTORE'), ); my @labels = ( @@ -198,6 +247,10 @@ 'desktop-verify', 'tape-configure', 'tape-restore', + 'workstn-configure', + 'workstn-verify', + 'workstn-restore', + 'workstn-sel-restore', ); my $default_action = 'desktop-backup'; @@ -234,11 +287,13 @@ %labels = ( "refresh" => $fm->localise('REFRESH_THIS_DISPLAY'), "tape-configure" => $fm->localise('CONFIGURE_TAPE_BACKUP'), + "workstn-configure" => $fm->localise('CONFIGURE_WORKSTN_BACKUP'), ); @labels = ( 'refresh', 'tape-configure', + 'workstn-configure', ); $default_action = 'refresh'; @@ -381,6 +436,22 @@ { tapeRestore(); } + elsif ($function eq 'workstn-configure') + { + WorkstnBackupConfig ($q); + } + elsif ($function eq 'workstn-verify') + { + workstnVerify(); + } + elsif ($function eq 'workstn-restore') + { + workstnRestore(); + } + elsif ($function eq 'workstn-sel-restore') + { + workstnSelRestore(); + } else { # Unknown function - refresh the screen anyway @@ -1291,166 +1362,1980 @@ } } -sub performReboot () +sub WorkstnBackupConfig { - esmith::cgi::genHeaderNonCacheable ($q, undef, - $fm->localise('SERVER_REBOOT')); + my ($q) = @_; + my $backupwk_status; + my $enabledIncOnlyTimeout = ""; + my $backupwkLogin = 'backup'; + my $backupwkPassword = 'backup'; + my $backupwkStation = 'host'; + my $backupwkFolder = 'share'; + my $setsNumber; + my $filesinset; + my $backupwkTime; + my $backupwkTimeout; + my $backupwkIncOnlyTimeout; + my $compression; + my $VFSType; + my $dof; + my @dlabels = split(' ', $fm->localise('DOW')); + my @VFST = ('smbfs', 'cifs', 'nfs', 'usb'); + my %VFST = ('smbfs', 'smbfs', 'cifs', 'cifs', 'nfs', 'nfs', 'usb', 'local usb disk'); + + # Obtain backup informations from configuration + my $rec = $conf->get('backupwk'); + if ($rec) + { + $backupwkTime = $rec->prop('BackupTime') || '2:00'; + $backupwkLogin = $rec->prop('Login') || 'backup'; + $backupwkPassword = $rec->prop('Password') || 'backup'; + $backupwkStation = $rec->prop('SmbHost') || 'host'; + $backupwkFolder = $rec->prop('SmbShare') || 'share'; + $setsNumber = $rec->prop('SetsMax') || '1'; + $filesinset = $rec->prop('DaysInSet') || '1'; + $backupwkTimeout = $rec->prop('Timeout') || '12'; + $backupwkIncOnlyTimeout = $rec->prop('IncOnlyTimeout') || 'yes'; + $compression = $rec->prop('Compression') || '0'; + $dof = (defined $rec->prop('FullDay')) ? $rec->prop('FullDay') : '7'; + $VFSType = $rec->prop('VFSType') || 'smbfs'; + $backupwk_status = $rec->prop('status'); + } - print $q->p ( - $q->b ($fm->localise('SERVER_WILL_REBOOT')) - ); + esmith::cgi::genHeaderNonCacheable( + $q, undef, $fm->localise('CONFIGURE_WORKSTN_BACKUP')); - esmith::cgi::genFooter($fm); + if ($rec) { + print $fm->localise('WORKSTN_BACKUP_DESC'); + print $fm->localise('WORKSTN_BACKUP_ENABLED'), $q->b(' '.$backupwk_status), '.
'; + if ($VFSType eq 'usb') { + print $fm->localise('WORKSTN_BACKUP_USB'), '
'; + } + else { + print $fm->localise('WORKSTN_BACKUP_HOST'), ' ', $backupwkStation; + print ' ', $fm->localise('WORKSTN_BACKUP_VFSTYPE'), ' ', $VFSType, '
'; + } + print $fm->localise('WORKSTN_BACKUP_SHARE'), ' ', $backupwkFolder, '
'; + if (($VFSType eq 'smbfs') || ($VFSType eq 'cifs')) { + print $fm->localise('LOGIN'), ' ', $backupwkLogin, '
'; + print $fm->localise('PASSWORD'), ' ', $backupwkPassword, '
'; + } + print $fm->localise('WORKSTN_BACKUP_SETSNUM'), ' ', $setsNumber, '
'; + print $fm->localise('WORKSTN_BACKUP_DAYSINSET'), ' ', $filesinset, '
'; + print $fm->localise('WORKSTN_BACKUP_COMPRESSION'), ' ', $compression, '
'; + print $fm->localise('WORKSTN_BACKUP_TOD'), ' ', $backupwkTime, '
'; + print $fm->localise('WORKSTN_BACKUP_TIMEOUT'), ' ', $backupwkTimeout, 'h '; + if ( $backupwkIncOnlyTimeout eq 'yes' ) {print $fm->localise('WORKSTN_BACKUP_INCONLY_TIMEOUT')} + print '
'; + if ( $dof eq '7' ) { + print $fm->localise('WORKSTN_FULL_BACKUP_EVERYDAY', '
'); + } + else { + print $fm->localise('WORKSTN_FULL_BACKUP_DAY'), ' ', $dlabels[$dof], '
'; + } + } + else { print $fm->localise('WORKSTN_BACKUP_NOT_CONFIGURED'), '
' } - esmith::util::backgroundCommand( - 5, - "/sbin/e-smith/signal-event", - "reboot" + print $q->startform( + -method => 'POST', + -action => $q->url (-absolute => 1) ); -} -sub CalculateSizes () -{ - #------------------------------------------------------------ - # figure out the size of the tar file. - #------------------------------------------------------------ + print $q->start_table ({-class => "sme-noborders"}); - my $tarsize = 0; + print $q->Tr($q->td($q->h3 ($fm->localise('WORKSTATION_BACKUP_SETCONF')))); - # 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; + print $q->Tr( + esmith::cgi::genCell( + $q, + $fm->localise('SELECT_VFS_TYPE') + ), - # Get a $dev value appropriate for use in Quota::query call. - my $dev = Quota::getqcarg("/home/e-smith/files"); + esmith::cgi::genCell ($q, $q->popup_menu (-name => 'VFSType', + -values => [ @VFST ], + -labels => \%VFST, + -default => $VFSType))); - foreach my $user ($accounts->users()) + print "\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('NEXT') + ) + ) + ); + + print $q->hidden( + -name => 'state', + -override => 1, + -default => 'workstn-configure' + ); + print ''; + + print $q->endform; + + esmith::cgi::genFooter ($q); + return; +} + +sub WorkstnBackupConfig1 +{ + my ($q) = @_; + my $enabledChk = ""; + my $enabledIncOnlyTimeout = ""; + my $backupwkAMPM = 'AM'; + my $backupwkMin; + my $backupwkHour; + my $backupwkLogin = 'backup'; + my $backupwkPassword = 'backup'; + my $backupwkStation = 'host'; + my $backupwkFolder = 'share'; + my $setsNumber; + my $filesinset; + my $backupwkTimeout; + my $backupwkIncOnlyTimeout; + my $compression; + my $VFSType = $q->param ('VFSType'); + my $dof; + my @usbdisks; + my %dlabels = (); + my @dlabels = split(' ', $fm->localise('DOW')); + my $i = 0; + foreach (@dlabels) { + $dlabels{$i} = $_; + $i++; + } + + # Obtain backup informations from configuration + my $rec = $conf->get('backupwk'); + my $backupwkTime = '2:00'; + if ($rec) { - 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; - } + $backupwkTime = $rec->prop('BackupTime') || '2:00'; + $backupwkLogin = $rec->prop('Login') || 'backup'; + $backupwkPassword = $rec->prop('Password') || 'backup'; + $backupwkStation = $rec->prop('SmbHost') || 'host'; + $backupwkFolder = $rec->prop('SmbShare') || 'share'; + $setsNumber = $rec->prop('SetsMax') || '1'; + $filesinset = $rec->prop('DaysInSet') || '1'; + $backupwkTimeout = $rec->prop('Timeout') || '12'; + $backupwkIncOnlyTimeout = $rec->prop('IncOnlyTimeout') || 'yes'; + $compression = $rec->prop('Compression') || '0'; + $dof = $rec->prop('FullDay') || '7'; + } - # Get current quota settings. - my ($blocks) = Quota::query($dev, $uid, 0); - $tarsize += $blocks; + ($backupwkHour, $backupwkMin) = split (':', $backupwkTime, -1); + + if ($backupwkHour > 12) + { + $backupwkHour -= 12; + $backupwkAMPM = 'PM'; } - # 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! + my $backupwk_status; + if ($rec) + { + $backupwk_status = $rec->prop('status'); + } - # 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; + if (defined $backupwk_status && $backupwk_status eq 'enabled') + { + $enabledChk = 'checked'; + } - while () + if (defined $backupwkIncOnlyTimeout && $backupwkIncOnlyTimeout eq 'yes') { - my ($du) = split(/\s+/); - $tarsize += $du; + $enabledIncOnlyTimeout = 'checked'; } - close DU; - $tarsize = &showSize($tarsize); + esmith::cgi::genHeaderNonCacheable( + $q, undef, $fm->localise('CONFIGURE_WORKSTN_BACKUP')); - #------------------------------------------------------------ - # figure out the size of the dump files - #------------------------------------------------------------ + if ( $VFSType eq 'usb' ) { + my @usbdisklist; + @usbdisklist = qx'ls /media'; + for (@usbdisklist) { + next if /floppy/; + next if /cdrom/; + push @usbdisks, $_; + } + unless (scalar @usbdisks) { + esmith::cgi::genResult( + $fm->{cgi}, $fm->localise('ERR_NO_USB_DISK')); + return + } + } - my $dumpsize = 0; + print $q->startform( + -method => 'POST', + -action => $q->url (-absolute => 1) + ); - open(DF, "-|") - or exec '/bin/df', '-P', '-t', 'ext3'; + print $fm->localise('CONFIGURE_WORKSTN_BACKUP_DESC'); - while () - { - next unless (/^\//); + print $q->start_table ({-class => "sme-noborders"}); - (undef, undef, my $s, undef) = split(/\s+/, $_); + print $q->Tr( + $q->td( + $fm->localise('ENABLE_WORKSTN_BACKUP') + . " " + ) + ); - $dumpsize += $s; - } + print $q->Tr($q->td($q->h3 ($fm->localise('WORKSTATION_BACKUP_DEST')))); - # increase size by 10% to cope with dump overhead. + if ( $VFSType eq 'usb' ) { + print $q->Tr( + esmith::cgi::genCell( + $q, + $fm->localise('WORKSTN_NAME') + ), - $dumpsize *= 1.1; + esmith::cgi::genCell ($q, 'localhost'), + ); + } + else { + print $q->Tr( + esmith::cgi::genCell( + $q, + $fm->localise('WORKSTN_NAME') + ), - close DF; + esmith::cgi::genCell ($q, $q->textfield (-name => 'backupwkStation', + -override => 1, + -default => $backupwkStation, + -size => 20)), + ); + } - $dumpsize = &showSize($dumpsize); + if ( $VFSType eq 'usb' ) { + print $q->Tr( + esmith::cgi::genCell( + $q, + $fm->localise('SHARED_FOLDER_NAME') + ), + + esmith::cgi::genCell ($q, $q->popup_menu (-name => 'backupwkFolder', + -values => [ @usbdisks ], + -default => $backupwkFolder,)), + ); + } + else { + print $q->Tr( + esmith::cgi::genCell( + $q, + $fm->localise('SHARED_FOLDER_NAME') + ), - #------------------------------------------------------------ - # how much free space is in /tmp - #------------------------------------------------------------ + esmith::cgi::genCell ($q, $q->textfield (-name => 'backupwkFolder', + -override => 1, + -default => $backupwkFolder, + -size => 20)), + ); + } - my $tmpfree = 0; - my $halffree = 0; + if ( ( $VFSType eq 'smbfs' ) || ( $VFSType eq 'cifs' ) ) { + print $q->Tr( + esmith::cgi::genCell( + $q, + $fm->localise('WORKSTN_LOGIN') + ), - open(DF, "-|") - or exec '/bin/df', '-P', '-t', 'ext3', '/tmp'; + esmith::cgi::genCell ($q, $q->textfield (-name => 'backupwkLogin', + -override => 1, + -default => $backupwkLogin, + -size => 12)), + ); - while () - { - next unless (/^\//); + print $q->Tr( + esmith::cgi::genCell( + $q, + $fm->localise('WORKSTN_PASSWORD') + ), - (undef, undef, undef, my $s) = split(/\s+/, $_); + esmith::cgi::genCell ($q, $q->textfield (-name => 'backupwkPassword', + -override => 1, + -default => $backupwkPassword, + -size => 20)), + ); + } - $tmpfree += $s; - } + print ''; - close DF; + print $q->table ({border => 0, cellspacing => 1, cellpadding => 4}); - $halffree = $tmpfree / 2; + print $q->Tr($q->td({-colspan=>4},$q->h3 ($fm->localise('WORKSTN_BACKUP_SETTINGS')))); - $tmpfree = &showSize($tmpfree); - $halffree = &showSize($halffree); + print $q->Tr( + esmith::cgi::genCell( + $q, + $fm->localise('NUMBER_OF_SETS') + ), - return ($tarsize, $dumpsize, $tmpfree, $halffree); -} + esmith::cgi::genCell ($q, $q->textfield (-name => 'setsNumber', + -override => 1, + -default => $setsNumber, + -size => 3)), -sub showSize -{ - # convert size to Mb or Gb or Tb :) Remember, df reports in kb. + esmith::cgi::genCell ($q, $fm->localise('NUMBER_OF_FILES_IN_SET')), + esmith::cgi::genCell ($q, $q->textfield (-name => 'filesinset', + -override => 1, + -default => $filesinset, + -size => 3)) + ); - my $size = shift; + print $q->Tr( + esmith::cgi::genCell( + $q, + $fm->localise('WORKSTN_BACKUP_TIME') + ), - my $Mb = 1024; - my $Gb = $Mb * $Mb; - my $Tb = $Mb * $Mb * $Mb; + esmith::cgi::genCell ($q, $q->textfield (-name => 'backupwkHour', + -override => 1, + -default => $backupwkHour, + -size => 2)), - 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"; - } + esmith::cgi::genCell ($q, $q->textfield (-name => 'backupwkMin', + -override => 1, + -default => $backupwkMin, + -size => 2)), - return $size; -} + esmith::cgi::genCell ($q, $q->popup_menu (-name => 'backupwkAMPM', + -values => ['AM', 'PM'], + -default => $backupwkAMPM))); + + print $q->Tr( + esmith::cgi::genCell( + $q, + $fm->localise('WORKSTN_TIMEOUT') + ), + + esmith::cgi::genCell ($q, $q->textfield (-name => 'backupwkTimeout', + -override => 1, + -default => $backupwkTimeout, + -size => 2)), + + esmith::cgi::genCell( + $q, + $fm->localise('INC_ONLY_TIMEOUT') + ), + + esmith::cgi::genCell ( + $q, + " " + ), + ); + + print $q->Tr( + esmith::cgi::genCell( + $q, + $fm->localise('COMPRESSION_LEVEL') + ), + + esmith::cgi::genCell ($q, $q->textfield (-name => 'compression', + -override => 1, + -default => $compression, + -size => 1)), + + esmith::cgi::genCell( + $q, + $fm->localise('FULL_ONLY_ON') + ), + + esmith::cgi::genCell ( + $q, + $q->popup_menu ( + -name => 'dof', + -values => [ '7', '0', '1', '2', '3', '4', '5', '6' ], + -labels => \%dlabels, + -default => $dof)) + ); + + print "\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 => 'workstn-configure1' + ); + print $q->hidden( + -name => 'VFSType', + -override => 1, + -default => $VFSType + ); + print ''; + + print $q->endform; + + esmith::cgi::genFooter ($q); + return; +} + +sub updateWorkstnBackupConfig +{ + my ($q) = @_; + + my $status = $q->param ('workstnbackup'); + my $inconly = $q->param ('incOnlyTimeout'); + my $dof = $q->param('dof'); + my $ampm; + my $incOnlyTimeout; + + esmith::cgi::genHeaderNonCacheable( + $q, + undef, $fm->localise('UPDATING_WORKSTN_CONF') + ); + + #-------------------------------------------------- + # Untaint parameters and check for validity + #-------------------------------------------------- + + my $VFSType = $q->param ('VFSType'); + + my $backupwkStation = $q->param ('backupwkStation'); + if ( $VFSType eq 'usb') { $backupwkStation = 'localhost' } + if ($backupwkStation =~ /^(.*)$/) { + $backupwkStation = $1; + } else { + $backupwkStation = ""; + } + if ( $backupwkStation eq "" ) + { + esmith::cgi::genResult( + $q, $fm->localise('ERR_INVALID_WORKSTN') + ); + return; + } + + my $backupwkFolder = $q->param ('backupwkFolder'); + if ( $VFSType eq 'usb' ) { + $backupwkFolder = 'media/' . $backupwkFolder; + } + if ($backupwkFolder =~ /^(.*)$/) { + $backupwkFolder = $1; + $backupwkFolder =~ s/^\//; # remove leading / + } else { + $backupwkFolder = ""; + } + if ( $backupwkFolder eq "" ) + { + esmith::cgi::genResult( + $q, $fm->localise('ERR_INVALID_FOLDER') + ); + return; + } + + my $backupwkLogin = $q->param ('backupwkLogin'); + if ($backupwkLogin =~ /^(.*)$/) { + $backupwkLogin = $1; + } else { + $backupwkLogin = ""; + } + if ( ( $backupwkLogin eq "" ) && (( $VFSType eq 'smbfs' ) || ( $VFSType eq 'cifs' )) ) + { + esmith::cgi::genResult( + $q, $fm->localise('ERR_INVALID_LOGIN') + ); + return; + } + + my $backupwkPassword = $q->param ('backupwkPassword'); + if ($backupwkPassword =~ /^(.*)$/) { + $backupwkPassword = $1; + } else { + $backupwkPassword = ""; + } + if ( ( $backupwkPassword eq "" ) && (( $VFSType eq 'smbfs' ) || ( $VFSType eq 'cifs' )) ) + { + esmith::cgi::genResult( + $q, $fm->localise('ERR_INVALID_PASSWORD') + ); + return; + } + + my $setsNumber = $q->param ('setsNumber'); + unless ( $setsNumber > 0 ) + { + esmith::cgi::genResult( + $q, $fm->localise('ERR_INVALID_SETS_NUMBER') + ); + return; + } + + my $filesinset = $q->param ('filesinset'); + unless ( $filesinset > 0 ) + { + esmith::cgi::genResult( + $q, $fm->localise('ERR_INVALID_FILES_IN_SET_NUMBER') + ); + return; + } + + my $timeout = $q->param ('backupwkTimeout'); + if (( $timeout eq '') || ( $timeout == 0 )) {$timeout = 24 } + if (( $timeout < 1 ) || ( $timeout > 24 )) + { + esmith::cgi::genResult( + $q, $fm->localise('ERR_INVALID_TIMEOUT') + ); + return; + } + + if (defined $inconly && $inconly eq 'on') + { + $incOnlyTimeout = 'yes'; + } + else + { + $incOnlyTimeout = 'no'; + } + + my $compression = $q->param ('compression'); + if (( $compression < 0 ) || ( $compression > 7 )) + { + esmith::cgi::genResult( + $q, $fm->localise('ERR_INVALID_COMPRESSION') + ); + return; + } + + my $rec = $conf->get('backupwk'); + unless (defined $rec) + { + $rec = $conf->new_record('backupwk', {type=>'service'}); + } + + $rec->set_prop('SmbHost', $backupwkStation); + $rec->set_prop('SmbShare', $backupwkFolder); + $rec->set_prop('Login', $backupwkLogin); + $rec->set_prop('Password', $backupwkPassword); + $rec->set_prop('SetsMax', $setsNumber); + $rec->set_prop('DaysInSet', $filesinset); + $rec->set_prop('Timeout', $timeout); + $rec->set_prop('IncOnlyTimeout', $incOnlyTimeout); + $rec->set_prop('Compression', $compression); + $rec->set_prop('FullDay', $dof); + $rec->set_prop('VFSType', $VFSType); + + my $module = $rec->prop('Program'); + + # The default workstation backup program is dar. + + unless (defined $module) + { + $module = 'dar'; + } + elsif ($module eq '') + { + $module = 'dar'; + } + + $rec->set_prop('Program', $module); + + if (defined $status && $status eq 'on') + { + + my $backupwkHour = $q->param ('backupwkHour'); + if ($backupwkHour =~ /^(.*)$/) { + $backupwkHour = $1; + } else { + $backupwkHour = '12'; + } + if (($backupwkHour < 0) || ($backupwkHour > 12)) + { + esmith::cgi::genResult( + $q, $fm->localise('ERR_INVALID_HOUR').$backupwkHour. + $fm->localise('BETWEEN_0_AND_12') + ); + + return; + } + + my $backupwkMin = $q->param ('backupwkMin'); + if ($backupwkMin =~ /^(.*)$/) { + $backupwkMin = $1; + } else { + $backupwkMin = '0'; + } + if (($backupwkMin < 0) || ($backupwkMin > 59)) + { + esmith::cgi::genResult( + $q, $fm->localise('ERR_INVALID_MINUTE').$backupwkMin. + $fm->localise('BETWEEN_0_AND_59') + ); + + return; + } + + $backupwkMin = sprintf("%02d", $backupwkMin); + + $ampm = $q->param ('backupwkAMPM'); + if ($ampm =~ /^(.*)$/) { + $ampm = $1; + } else { + $ampm = 'AM'; + } + + # convert to 24 hour time + + $backupwkHour = $backupwkHour % 12; + if ($ampm eq 'PM') + { + $backupwkHour = $backupwkHour + 12; + } + + + # variables passed validity checks, set configuration database values + my $old = $conf->get('UnsavedChanges')->value; + + $rec->set_prop('status', 'enabled'); + + $rec->set_prop('BackupTime', "$backupwkHour:$backupwkMin"); + + $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( + $q, $fm->localise('SUCCESSFULLY_ENABLED_WORKSTN').$q->br(). + $fm->localise('WITH_BACKUP_TIME')."$backupwkHour:$backupwkMin"); + } + else + { + # set service to disabled + my $old = $conf->get('UnsavedChanges')->value; + + $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( + $q, $fm->localise('SUCCESSFULLY_DISABLED_WORKSTN') + ); + } + + return; +} + +sub workstnVerify () +{ + + my $rec = $conf->get('backupwk'); + + esmith::cgi::genHeaderNonCacheable ($q, undef, + $fm->localise('VERIFY_WORKSTN_BACKUP_FILE')); + + unless ($rec) + { + esmith::cgi::genResult( + $q, $fm->localise('CONFIGURATION_TO_BE_DONE')); + return; + } + + my %backupfiles = (); + my $mntdir = $rec->prop('MountDir') || '/mnt/smb'; + my $mntbkdir; + my $mounted; + my $key; + my $id = $rec->prop('Id') || $conf->get('SystemName')->value . "." . $conf->get('DomainName')->value; + my $smbhost = $rec->prop('SmbHost'); + my $smbshare = $rec->prop('SmbShare'); + my $VFSType = $rec->prop('VFSType') || 'smbfs'; + my $err; + + my $setbackuplist = sub { + if ( $_ =~ /\.dar/ ) { + my $dir = $File::Find::dir; + my $backupref; + $dir =~ s/$mntbkdir\///; + $_ =~ s/\..*\.dar//; + $backupref = $_; + $_ =~ s/.*-//; + @{$backupfiles{$_}}[0] = $dir; + @{$backupfiles{$_}}[1] = $backupref; + } + }; + + # Mounting backup shared folder + + unless (-d $mntdir) + { + mkdir -p $mntdir; + } + + my $login = $rec->prop('Login') || 'backup'; + my $password = $rec->prop('Password') || 'backup'; + + if ( $err = dmount($smbhost,$smbshare,$mntdir,$login,$password,$VFSType) ) + { + esmith::cgi::genResult( + $q, $fm->localise('ERR_MOUNTING_SMBSHARE') . "\n" . $err + ); + return; + } + elsif ( $VFSType ne 'usb' ) {$mounted = 1} + + # Test if backup subdirectory for our server + + $mntbkdir = $mntdir . '/' . $id; + unless ( -d $mntbkdir) + { + if ($mounted) { + system("/bin/umount $mntdir") == 0 + or die($fm->localise('ERR_WHILE_UNMOUNTING'),"\n"); + } + esmith::cgi::genResult( + $q, $fm->localise('ERR_NO_HOST_DIR'.$id) + ); + return; + } + + # Finding existing backups + + find { wanted => \&$setbackuplist, untaint => 1 }, $mntbkdir ; + + my %blabels = (); + my @blabels; + my $backups = 0; + + foreach $key (sort keys %backupfiles) { + my $labkey = $mntbkdir . '/' . $backupfiles{$key}[0] . '/' . $backupfiles{$key}[1]; + $blabels{$labkey} = $backupfiles{$key}[1] . " (" . $backupfiles{$key}[0] . ")"; + $backups = push @blabels, $labkey; + } + + if ($mounted) { + system("/bin/umount $mntdir") == 0 + or die($fm->localise('ERR_WHILE_UNMOUNTING'),"\n"); + } + + # Stops here if no backups + + if ( $backups == 0 ) { + esmith::cgi::genResult( + $q, $fm->localise('NO_BACKUPS_TO_RESTORE')); + return; + } + + print $q->p ($fm->localise('VERIFY_WORKSTN_BACKUP_DESC') . ' ' . "$smbhost/$smbshare/$id"); + print $q->p; + + 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->popup_menu ( + -name => 'backupset', + -values => [ @blabels ], + -labels => \%blabels + ) + ) + ); + + 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 => 'workstn-verify' + ); + + print $q->endform; + + esmith::cgi::genFooter ($q); +} + +sub performWorkstnVerify +{ + my ($q) = @_; + + my $backupwkrec = $conf->get('backupwk'); + my $smbhost = $backupwkrec->prop('SmbHost'); + my $smbshare = $backupwkrec->prop('SmbShare'); + my $login = $backupwkrec->prop('Login'); + my $password = $backupwkrec->prop('Password'); + my $mntdir = $backupwkrec->prop('MountDir') || '/mnt/smb'; + my $mounted; + my $key; + my $id = $backupwkrec->prop('Id') || $conf->get('SystemName')->value . "." . $conf->get('DomainName')->value; + my $err; + my $VFSType = $backupwkrec->prop('VFSType') || 'smbfs'; + + # Mounting backup shared folder + + if ( $err = dmount($smbhost,$smbshare,$mntdir,$login,$password,$VFSType) ) + { + esmith::cgi::genResult( + $q, $fm->localise('ERR_MOUNTING_SMBSHARE') . "\n" . $err + ); + return; + } + elsif ( $VFSType ne 'usb' ) {$mounted = 1} + + # Test if backup subdirectory for our server + + my $mntbkdir = $mntdir . "/$id"; + unless ( -d $mntbkdir) + { + if ($mounted) { + system("/bin/umount $mntdir") == 0 + or die($fm->localise('ERR_WHILE_UNMOUNTING'),"\n"); + } + esmith::cgi::genResult( + $q, $fm->localise('ERR_NO_HOST_DIR'.$id) + ); + return; + } + + my $backupkey = $q->param ('backupset'); + if ($backupkey =~ /^(.*)$/) { + $backupkey = $1; + } + else { + if ($mounted) { + system("/bin/umount $mntdir") == 0 + or die($fm->localise('ERR_WHILE_UNMOUNTING'),"\n"); + } + die('Unsecure data : ' . $backupkey); + } + + if (open(RD, "-|")) + { + esmith::cgi::genHeaderNonCacheable ($q, + undef, $fm->localise('VERIFY_WORKSTN_BACKUP_FILE')); + + print $q->p($fm->localise('FILES_IN_BACKUP')); + + print '

    '; + + my $complete = 0; + while () + { + $complete++ if /etc\/smbpasswd$/; + $complete++ if /etc\/samba\/smbpasswd$/; # >6.0 base + print "
  • $_
  • \n"; + } + + print '
'; + my $status = close RD ? + ($complete ? + $fm->localise('VERIFY_COMPLETE') : + $fm->localise('BACKUP_FILE_INCOMPLETE')) + : ($fm->localise('ERROR_READING_FILE').' : '.$backupkey); + print $q->p ($q->b ($status)); + + esmith::cgi::genFooter ($q); + + } + else + { + select(STDOUT); + $| = 1; + + system ("/usr/bin/dar --list $backupkey --noconf") == 0 + or die ($fm->localise('ERR_EXTRACT')." : ".$!); + + if ($mounted) { + system("/bin/umount $mntdir") == 0 + or die($fm->localise('ERR_WHILE_UNMOUNTING'),"\n"); + } + exit(0); + } + + return; +} + +sub workstnRestore () +{ + + my $rec = $conf->get('backupwk'); + + esmith::cgi::genHeaderNonCacheable( + $q, undef, $fm->localise('RESTORE_CONF_FROM_WORKSTN')); + + unless ($rec) + { + esmith::cgi::genResult( + $q, $fm->localise('CONFIGURATION_TO_BE_DONE')); + return; + } + + my $mntdir = $rec->prop('MountDir') || '/mnt/smb'; + my $mntbkdir; + my $mounted; + my %backupfiles = (); + my $key; + my $id = $rec->prop('Id') || $conf->get('SystemName')->value . "." . $conf->get('DomainName')->value; + my $VFSType = $rec->prop('VFSType') || 'smbfs'; + my $smbhost = $rec->prop('SmbHost'); + my $smbshare = $rec->prop('SmbShare'); + my $err; + + my $setbackupflist = sub { + if ( $_ =~ /\.dar/ ) { + my $dir = $File::Find::dir; + my $backupref; + $dir =~ s/$mntbkdir\///; + $_ =~ s/\..*\.dar//; + $backupref = $_; + $_ =~ s/.*-//; + @{$backupfiles{$_}}[0] = $dir; + @{$backupfiles{$_}}[1] = $backupref; + } + }; + + # Mounting backup shared folder + + unless (-d $mntdir) + { + mkdir -p $mntdir; + } + + my $login = $rec->prop('Login') || 'backup'; + my $password = $rec->prop('Password') || 'backup'; + + if ( $err = dmount($smbhost,$smbshare,$mntdir,$login,$password,$VFSType) ) + { + esmith::cgi::genResult( + $q, $fm->localise('ERR_MOUNTING_SMBSHARE') . "\n" . $err + ); + return; + } + elsif ( $VFSType ne 'usb' ) {$mounted = 1} + + # Test if backup subdirectory for our server + + $mntbkdir = $mntdir . "/$id"; + unless ( -d $mntbkdir) + { + if ($mounted) { + system("/bin/umount $mntdir") == 0 + or die($fm->localise('ERR_WHILE_UNMOUNTING'),"\n"); + } + esmith::cgi::genResult( + $q, $fm->localise('ERR_NO_HOST_DIR'.$id) + ); + return; + } + + # Finding existing backups + + find { wanted => \&$setbackupflist, untaint => 1 }, $mntbkdir ; + + my %blabels = (); + my @blabels; + my $backups = 0; + + foreach $key (sort keys %backupfiles) { + my $labkey = $mntbkdir . '/' . $backupfiles{$key}[0] . '/' . $backupfiles{$key}[1]; + $blabels{$labkey} = $backupfiles{$key}[1] . ' (' . $backupfiles{$key}[0] . ')'; + $backups = push @blabels, $labkey; + } + + if ($mounted) { + system("/bin/umount $mntdir") == 0 + or die($fm->localise('ERR_WHILE_UNMOUNTING'),"\n"); + } + + if ( $backups == 0 ) { + esmith::cgi::genResult( + $q, $fm->localise('NO_BACKUPS_TO_RESTORE')); + return; + } + + print $q->p ($fm->localise('RESTORE_CONF_FROM_WORKSTN_DESC') . ' ' . "$smbhost/$smbshare/$id"); + print $q->p; + + 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->popup_menu ( + -name => 'backuptorestore', + -values => [ @blabels ], + -labels => \%blabels + ) + ) + ); + + print $q->table ( {width => "100%", -class => "sme-noborders"}, + esmith::cgi::genButtonRow( + $q, + $q->submit( + -name => 'action', + -value => $fm->localise('RESTORE_FROM_WORKSTN') + ) + ) + ); + + print $q->hidden( + -name => 'state', + -override => 1, + -default => 'workstn-restore' + ); + + print $q->endform; + + esmith::cgi::genFooter ($q); +} + +sub performWorkstnRestore +{ + my ($q) = @_; + my $restoreref = $q->param ('backuptorestore'); + my $set = $restoreref; + $set =~ s/\/[^\/]*$//; + my %backupsetfiles = (); + my @restorefiles; + + my $backupsetlist = sub { + if ( $_ =~ /\.dar/ ) { + my $backupref = $File::Find::name; + $backupref =~ s/\.[0-9]+\.dar//; + $_ =~ s/\..*\.dar//; + $_ =~ s/.*-//; + $backupsetfiles{$_} = $backupref; + } + }; + + + 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 ($q); + return; + } + + # mounting backup shared folder + + my $backupwkrec = $conf->get('backupwk'); + my $login = $backupwkrec->prop('Login'); + my $password = $backupwkrec->prop('Password'); + my $id = $backupwkrec->prop('Id') || $conf->get('SystemName')->value . "." . $conf->get('DomainName')->value; + my $mntdir = $backupwkrec->prop('MountDir') || '/mnt/smb'; + my $mounted; + my $VFSType = $backupwkrec->prop('VFSType') || 'smbfs'; + my $smbhost = $backupwkrec->prop('SmbHost'); + my $smbshare = $backupwkrec->prop('SmbShare'); + my $err; + + if ( $err = dmount($smbhost,$smbshare,$mntdir,$login,$password,$VFSType) ) + { + esmith::cgi::genHeaderNonCacheable( + $q, + undef, $fm->localise('RESTORE_CANNOT_PROCEED') + ); + esmith::cgi::genResult( + $q, $fm->localise('ERR_MOUNTING_SMBSHARE') . "\n" . $err + ); + return; + } + elsif ( $VFSType ne 'usb' ) {$mounted = 1} + + # Test if backup subdirectory for our server + + my $mntbkdir = $mntdir . "/$id"; + unless ( -d $mntbkdir) + { + if ($mounted) { + system("/bin/umount $mntdir") == 0 + or die($fm->localise('ERR_WHILE_UNMOUNTING'),"\n"); + } + esmith::cgi::genResult( + $q, $fm->localise('ERR_NO_HOST_DIR'.$id) + ); + return; + } + + # finding list of available backups + + find { wanted => \&$backupsetlist, untaint => 1 }, $set ; + + my $key; + foreach $key (sort keys %backupsetfiles) { + push @restorefiles, $backupsetfiles{$key}; + last if ( $backupsetfiles{$key} eq $restoreref ); + } + + # backup is online, restoring now + + my $rec = $restore->get('restore'); + $rec->set_prop('state','running'); + $rec->set_prop('start', time); + $conf->get('bootstrap-console')->set_prop('Run', 'yes'); + + 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; + } + + $| = 1; + + if (open(RD, "-|")) + { + + #----------------------------------------------------- + # restore system from uploaded workstation 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 '
    '; + my $complete = 0; + while () + { + $complete++ if /etc\/smbpasswd$/; + $complete++ if /etc\/samba\/smbpassword$/; + print "
  • $_
  • \n"; + } + + print '
'; + 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 ($q); + } + else + { + select(STDOUT); + $| = 1; + + my $file; + foreach $file (@restorefiles) { + if ($file =~ /^(.*)$/) { + $file = $1; + } + else { + if ($mounted) { + system("/bin/umount $mntdir") == 0 + or die($fm->localise('ERR_WHILE_UNMOUNTING'),"\n"); + } + die('Unsecure data : ' . $file); + } + system ("/usr/bin/dar -x $file --verbose --noconf --no-warn=all"); + } + + if ($mounted) { + system("/bin/umount $mntdir") == 0 + or die($fm->localise('ERR_WHILE_UNMOUNTING'),"\n"); + } + + exit(0); + } + return; +} + +sub workstnSelRestore() +{ + my $rec = $conf->get('backupwk'); + + esmith::cgi::genHeaderNonCacheable ($q, undef, + $fm->localise('WORKSTN_SELECTIVE_RESTORE')); + + unless ($rec) + { + esmith::cgi::genResult( + $q, $fm->localise('CONFIGURATION_TO_BE_DONE')); + return; + } + + my %backupfiles = (); + my $mntdir = $rec->prop('MountDir') || '/mnt/smb'; + my $mntbkdir; + my $mounted; + my $key; + my $id = $rec->prop('Id') || $conf->get('SystemName')->value . '.' . $conf->get('DomainName')->value; + my %blabels = (); + my @blabels; + my $backups = 0; + my $filterexp; + my $VFSType = $rec->prop('VFSType') || 'smbfs'; + my $smbhost = $rec->prop('SmbHost'); + my $smbshare = $rec->prop('SmbShare'); + my $err; + + my $setbackuplist = sub { + if ( $_ =~ /\.dar/ ) { + my $dir = $File::Find::dir; + my $backupref; + $dir =~ s/$mntbkdir\///; + $_ =~ s/\..*\.dar//; + $backupref = $_; + $_ =~ s/.*-//; + @{$backupfiles{$_}}[0] = $dir; + @{$backupfiles{$_}}[1] = $backupref; + } + }; + + # Mounting backups smb shared folder + + unless (-d $mntdir) + { + mkdir -p $mntdir; + } + + my $login = $rec->prop('Login') || 'backup'; + my $password = $rec->prop('Password') || 'backup'; + + if ( $err = dmount($smbhost,$smbshare,$mntdir,$login,$password,$VFSType) ) + { + esmith::cgi::genResult( + $q, $fm->localise('ERR_MOUNTING_SMBSHARE') . "\n" . $err + ); + return; + } + elsif ( $VFSType ne 'usb' ) {$mounted = 1} + + # Test if backup subdirectory for our server + + $mntbkdir = $mntdir . '/' . $id; + unless ( -d $mntbkdir) + { + if ($mounted) { + system("/bin/umount $mntdir") == 0 + or die($fm->localise('ERR_WHILE_UNMOUNTING'),"\n"); + } + esmith::cgi::genResult( + $q, $fm->localise('ERR_NO_HOST_DIR'.$id) + ); + return; + } + + my $catalog = "$mntbkdir/dar-catalog"; + unless ( -e $catalog) + { + system("/usr/bin/dar_manager -C $catalog") == 0 + or die($fm->localise('ERR_DAR_CATALOG'),"\n"); + } + + # find available backups for the server + + find { wanted => \&$setbackuplist, untaint => 1 }, $mntbkdir ; + + # find backups in current catalog + + my $i = 0; + my @bknum; + my @setd; + my @bkname; + open(DAR_LIST, "/usr/bin/dar_manager -B $catalog -l |"); + while () { + next unless ($_ =~ /set/); + chomp; + ($bknum[$i], $setd[$i], $bkname[$i]) = split(' ', $_, 3); + $i++; + } + close (DAR_LIST); + + # delete from catalog old removed backups + + my $j = $i; + while ($j) { + unless (-e "$setd[$j-1]/$bkname[$j-1]\.1\.dar") { + my $del = $bknum[$j-1]; + if ($del =~ /^(.*)$/) { + $del = $1; + } + system("/usr/bin/dar_manager -B $catalog -D $del 1>&2") == 0 + or die($fm->localise('ERR_DAR_CATALOG'),"\n"); + } + $j--; + } + + # add to catalog new backups + + foreach $key (sort keys %backupfiles) { + my $exists = 0; + my $rf; + foreach $rf (@bkname) { + $exists = 1 if ($rf eq $backupfiles{$key}[1]); + last if $exists; + } + do { + my $add = "$mntbkdir/$backupfiles{$key}[0]/$backupfiles{$key}[1]"; + if ($add =~ /^(.*)$/) { + $add = $1; + } + system("/usr/bin/dar_manager -B $catalog -A $add") == 0 + or die($fm->localise('ERR_DAR_CATALOG'),"\n"); + } unless $exists; + } + + # update backups list from current catalog + + open(DAR_LIST, "/usr/bin/dar_manager -B $catalog -l |") ; + + $i = 0; + while () { + next unless m/set/; + chomp; + ($bknum[$i], $setd[$i], $bkname[$i]) = split(' ', $_, 3); + $i++; + } + close (DAR_LIST); + + # set drop down list of backups + + push @blabels, "0"; + $blabels{"0"} = $fm->localise('ALL_BACKUPS'); + $j = 0; + while ($j < $i) { + push @blabels, $bknum[$j]; + $blabels{$bknum[$j]} = $bkname[$j]; + $j++ + } + + print $q->p ($fm->localise('WORKSTN_SEL_REST_DESC') . " $smbhost/$smbshare/$id"); + + print $q->h2 ($fm->localise('BACKUP_CHOICE')); + + 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, + $q->b($fm->localise('SELECT_BACKUP_FILE')), + $q->popup_menu ( + -name => 'backupset', + -values => [ @blabels ], + -labels => \%blabels) + ), + + esmith::cgi::genNameValueRow( + $q, + $fm->localise('FILTER_EXPRESSION'), + 'filterexp', + $filterexp + ) + ); + + + print $q->table ({width => "100%", -class => "sme-noborders"}, + esmith::cgi::genButtonRow( + $q, + $q->submit( + -name => 'action', + -value => $fm->localise('PERFORM') + ) + ) + ),"\n"; + + print $q->hidden( + -name => 'state', + -override => 1, + -default => 'workstn-sel-restore' + ); + + print $q->endform; + + + esmith::cgi::genFooter ($q); + + if ($mounted) { + system("/bin/umount $mntdir") == 0 + or die($fm->localise('ERR_WHILE_UNMOUNTING'),"\n"); + } +} + +sub performWorkstnSelRestore +{ + my ($q) = @_; + + my $rgfilter; + my $filterexp = $q->param ('filterexp'); + if ($filterexp =~ /^(.*)$/) { + $filterexp = $1; + $rgfilter = qr/$filterexp/; + } else { + $filterexp = ""; + } + my $seldatebf; + + esmith::cgi::genHeaderNonCacheable ($q, + undef, $fm->localise('WORKSTN_SELECTIVE_RESTORE')); + + my $backupwkrec = $conf->get('backupwk'); + my $smbhost = $backupwkrec->prop('SmbHost'); + my $smbshare = $backupwkrec->prop('SmbShare'); + my $login = $backupwkrec->prop('Login'); + my $password = $backupwkrec->prop('Password'); + my $mntdir = $backupwkrec->prop('MountDir') || '/mnt/smb'; + my $mntbkdir; + my $mounted; + my $key; + my $id = $backupwkrec->prop('Id') || $conf->get('SystemName')->value . "." . $conf->get('DomainName')->value; + my @flabels; + my %flabels = (); + my $VFSType = $backupwkrec->prop('VFSType') || 'smbfs'; + my $err; + + my $backupkey = $q->param ('backupset'); + if ($backupkey =~ /^(.*)$/) { + $backupkey = $1; + } + else { + die('Unsecure data : ' . $backupkey); + } + + # Mounting backup shared folder + + if ( $err = dmount($smbhost,$smbshare,$mntdir,$login,$password,$VFSType) ) + { + esmith::cgi::genResult( + $q, $fm->localise('ERR_MOUNTING_SMBSHARE') . "\n" . $err + ); + return; + } + elsif ( $VFSType ne 'usb' ) {$mounted = 1} + + # Test if backup subdirectory for our server + + $mntbkdir = $mntdir . "/$id"; + unless ( -d $mntbkdir) + { + if ($mounted) { + system("/bin/umount $mntdir") == 0 + or die($fm->localise('ERR_WHILE_UNMOUNTING'),"\n"); + } + esmith::cgi::genResult( + $q, $fm->localise('ERR_NO_HOST_DIR'.$id) + ); + return; + } + + # Read wanted file list from selected backup + + if (open(RD, "-|")) + { + my $regex = qr/\[.*\] */; + while () + { + $_ =~ s/$regex//; + if ($filterexp) {next unless m/$rgfilter/}; + push @flabels, $_; + } + + my $status = close RD ? + $fm->localise('READ_COMPLETE') + : ($fm->localise('ERROR_READING_FILE').' : '.$backupkey); + print $q->p ($status); + + } + else + { + select(STDOUT); + $| = 1; + + system ("/usr/bin/dar_manager -B $mntbkdir/dar-catalog -u $backupkey") == 0 + or die ($fm->localise('ERR_EXTRACT')." : ".$!); + + if ($mounted) { + system("/bin/umount $mntdir") == 0 + or die($fm->localise('ERR_WHILE_UNMOUNTING'),"\n"); + } + exit(0); + } + + 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, + $q->b($fm->localise('SELECT_FILES_TO_RESTORE')), + $q->scrolling_list ( + -name => 'restorefiles', + -values => [ @flabels ], + -size => 15, + -multiple => 'true') + ), + + esmith::cgi::genNameValueRow( + $q, + $fm->localise('SELECT_DATE_BEFORE'), + 'seldatebefore', + $seldatebf + ) + ); + + print $q->table ({width => "100%", -class => "sme-noborders"}, + esmith::cgi::genButtonRow( + $q, + $q->submit( + -name => 'action', + -value => $fm->localise('PERFORM') + ) + ) + ),"\n"; + + print $q->hidden( + -name => 'state', + -override => 1, + -default => 'workstn-sel-restore2' + ); + + print $q->hidden( + -name => 'when', + -override => 1, + -value => $seldatebf + ); + + print $q->endform; + + esmith::cgi::genFooter ($q); + +} + +sub performWorkstnSelRestore2 +{ + my ($q) = @_; + + esmith::cgi::genHeaderNonCacheable ($q, undef, + $fm->localise('RESTORE_IN_PROGRESS')); + + my @restorelist; + my $when = $q->param ('seldatebefore'); + if ($when =~ /^(.*)$/) { + $when = $1; + } + else { + die('Unsecure data : ' . $when); + } + my $tymd = qr/((19|20)\d\d\/(?=\d\d\/\d\d-))?((0?[1-9]|1[0-2])\/(?=\d\d-))?((31|[123]0|[012]?[1-9])-)?/; + my $thms = qr/([01]?[0-9]|2[0-3]):([0-5][0-9])(:[0-5][0-9])?/; + + unless (($when =~ m/^$tymd$thms$/) || ($when eq "")) { + esmith::cgi::genResult( + $q, "$when : " . $fm->localise('ERR_INVALID_SELDATE') + ); + return; + } + + my $f; + foreach $f ($q->param ('restorefiles')) { + if ($f =~ /^(.*)$/) { + push @restorelist, "\"".$1."\""; + } + } + + # mounting backup shared folder + + my $backupwkrec = $conf->get('backupwk'); + my $login = $backupwkrec->prop('Login'); + my $password = $backupwkrec->prop('Password'); + my $id = $backupwkrec->prop('Id') || $conf->get('SystemName')->value . "." . $conf->get('DomainName')->value; + my $mntdir = $backupwkrec->prop('MountDir') || '/mnt/smb'; + my $mounted; + my $VFSType = $backupwkrec->prop('VFSType') || 'smbfs'; + my $smbhost = $backupwkrec->prop('SmbHost'); + my $smbshare = $backupwkrec->prop('SmbShare'); + my $err; + + if ( $err = dmount($smbhost,$smbshare,$mntdir,$login,$password,$VFSType) ) + { + esmith::cgi::genResult( + $q, $fm->localise('ERR_MOUNTING_SMBSHARE') . "\n" . $err + ); + return; + } + elsif ( $VFSType ne 'usb' ) {$mounted = 1} + + # Test if backup subdirectory for our server + + my $mntbkdir = $mntdir . "/$id"; + unless ( -d $mntbkdir) + { + if ($mounted) { + system("/bin/umount $mntdir") == 0 + or die($fm->localise('ERR_WHILE_UNMOUNTING'),"\n"); + } + esmith::cgi::genResult( + $q, $fm->localise('ERR_NO_HOST_DIR'.$id) + ); + return; + } + + # backup is online, restoring now + + $| = 1; + my $restorerr; + + if (open(RD, "-|")) + { + + #----------------------------------------------------- + # restore system from uploaded workstation backup file + #----------------------------------------------------- + + print $q->p($fm->localise('FILES_HAVE_BEEN_RESTORED')); + + print '
    '; + while () + { + print "
  • $_
  • \n"; + } + + print '
'; + my $message; + if (!close RD) + { + $message = $fm->localise('RESTORE_FAILED_MSG'); + } + else + { + if ($restorerr) + { + $message = $fm->localise('RESTORE_FAILED'); + } + else + { + $message = $fm->localise('RESTORE_COMPLETE'); + } + } + + print $q->p ($q->b ($message)); + + esmith::cgi::genFooter ($q); + } + else + { + select(STDOUT); + $| = 1; + + if ($when) + { + $restorerr = system ("/usr/bin/dar_manager -B $mntbkdir/dar-catalog -w $when -e '-N -R / -w' -r @restorelist"); + } + else + { + $restorerr = system ("/usr/bin/dar_manager -B $mntbkdir/dar-catalog -e '-N -R / -w' -r @restorelist"); + } + + if ($mounted) { + system("/bin/umount $mntdir") == 0 + or die($fm->localise('ERR_WHILE_UNMOUNTING'),"\n"); + } + + exit(0); + } + + return; + +} + +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 () + { + 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 () + { + 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 () + { + 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; +} + +sub dmount() +{ + # mount dar unit according to dar-workstation configuration + # return nothing if mount successfull + + my ($host,$share,$mountdir,$login,$password,$VFSType) = @_; + + if ($VFSType eq 'cifs'){ + return ( qx(/bin/mount -t cifs $host:$share $mountdir -o user=$login,pass=$password) ); + } + elsif ($VFSType eq 'smbfs'){ + return ( qx(/bin/mount -t smbfs //$host/$share $mountdir -o username=$login,password=$password,dmask=777,fmask=777,ip=$host 2>&1) ); + } + elsif ($VFSType eq 'nfs'){ + return ( qx(/bin/mount -t nfs -o nolock $host:/$share $mountdir 2>&1) ); + } + elsif ($VFSType eq 'usb'){ + $_[2] = "/" . $share; + return + } + else {return ("Error while mounting $host/$share : $VFSType not supported.\n")} + +} __DATA__
diff -Nur -x '*.orig' -x '*.rej' e-smith-backup-1.15.0/root/sbin/e-smith/do_backupwk mezzanine_patched_e-smith-backup-1.15.0/root/sbin/e-smith/do_backupwk --- e-smith-backup-1.15.0/root/sbin/e-smith/do_backupwk 1969-12-31 19:00:00.000000000 -0500 +++ mezzanine_patched_e-smith-backup-1.15.0/root/sbin/e-smith/do_backupwk 2007-09-05 15:52:45.000000000 -0400 @@ -0,0 +1,74 @@ +#! /usr/bin/perl -w +#---------------------------------------------------------------------- +# copyright (C) 2006 SME Server +# +# 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 +# +#---------------------------------------------------------------------- + +use strict; +use esmith::ConfigDB; +use esmith::BackupHistoryDB; + +$ENV{PATH} = "/sbin/e-smith:/sbin:/bin:/usr/bin"; + +my $conf = esmith::ConfigDB->open || die("Could not open config db\n"); +my $backup = $conf->get('backupwk'); +my $status = $backup->prop('status') || 'disabled'; +my $program = $backup->prop('Program') || 'dar'; + +unless ($status eq 'enabled') +{ + print "Backup is disabled\n"; + exit 0; +} + +my $backups = esmith::BackupHistoryDB->open + || die("Could not open backup history db\n"); +my $now = time(); +my $backup_rec = $backups->new_record($now, { type => 'backup_record' }); +$backup_rec->set_prop('StartEpochTime', "$now"); +$backup_rec->set_prop('BackupType', "workstation"); + +if ($status = system(qw(signal-event pre-backup))) +{ + exit bad_exit($backup_rec, "pre-backup", $status); +} + +if ($status = system("/etc/e-smith/events/actions/workstation-backup-$program DailyBackup")) +{ + exit bad_exit($backup_rec, "backup", $status); +} + +if ($status = system(qw(signal-event post-backup))) +{ + exit bad_exit($backup_rec, "post-backup", $status); +} + +$now = time(); +$backup_rec->set_prop('EndEpochTime', "$now"); +$backup_rec->set_prop('Result', "$status"); +exit 0; + +sub bad_exit +{ + my ($backup_rec, $phase, $status) = @_; + my $now = time(); + + warn("Backup terminated: $phase failed - status: $status\n"); + $backup_rec->set_prop('EndEpochTime', "$now"); + $backup_rec->set_prop('Result', "$phase:$status"); + return $status / 256; +}