Newsgroup: it.comp.os.linux.sys
Titolo: Script di Backup con IpCOP

Vorrei fare uno script bash (schedulato) che faccia il backup completto 
delle configurazioni e lo trasferisca via ftp presso il nostro server ftp.
In particolare vorrei lanciare il comando che viene lanciato dal pannello 
web tramite backup.cgi e poi dovrei installare un client ftp.
Come potrei fare?
Grazie 

 e poi dovrei installare un client ftp.
Vedi su
Enrico

 Quale pannello?
Sorry ho letto solo ora "ipcop".
Mai approfondito quella distro, ergo per questo punto non ti so
aiutare :-(
Enrico

 Sorry ho letto solo ora "ipcop".
Quello che hai scritto già lo sapevo.
Si esatto putroppo IPCOP da pannello web ha uno script di backup.cgi che 
parte e che interpreta i comandi e poi da come risultato il backup delle 
configurazioni e la pagina web, siccome non conosco bene il perl volevo 
sapere se qualcuno può aiutarmi a capire come fare in uno scirpt il backup 
delle configurazioni.
Pubblico qui sotto il backup.cgi, magari così potete aiutarmi meglio.
Il pezzo che mi interessa dovrebbe essere questo ma non riesco a capire cosa 
mettere nello script bash:
# Export backup in tar.gz format
if ($settings{'ACTION'} eq "$Lang::tr{'export'} tar.gz") {
        #check form input
        if ($settings{'KEY'} !~ 
m!^$setdir/$hostfilter\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}\.dat$! ){
                $errormessage = $Lang::tr{'bad characters in'}.'KEY';
        } else {
                system('/usr/local/bin/decr_key', 'decr_backup', 
"$settings{'BACKUP_NAME'}");
                my $size = 0;
                my $tmpfilename = "/tmp/$settings{'BACKUP_NAME'}.tar.gz";
                open FH,"< $tmpfilename" or die "Unable to open tmp backup 
file !";
                my @lines=<FH>;
                close FH;
                use bytes;
                foreach (@lines) {$size += length($_)};
                print "Content-Type: application/force-download\n";
                $settings{'BACKUP_NAME'} =~ s/\.dat$//;
                print "Content-Disposition: attachment; 
filename=".$settings{'BACKUP_NAME'}.".tar.gz \n";
                print "Content-length: $size\n\n";# twice \n as an empty 
line is necessary before the data
                print @lines;
                unlink $tmpfilename;
        }
}
##########################################################################
#!/usr/bin/perl
#
# IPCop CGI's - backup.cgi: manage import/export of configuration files
#
# This code is distributed under the terms of the GPL
#
# (c) The IPCop Team
# 2005  Franck Bourdonnec, major rewrite
#
# $Id: backup.cgi,v 1.2.2.36 2006/07/26 19:42:11 eoberlander Exp $
#
#
use strict;
# enable only the following on debugging purpose
#use warnings;
#use CGI::Carp 'fatalsToBrowser';
# to fully troubleshot your code, uncomment diagnostics, Carp and cluck 
lines
# use diagnostics; # need to add the file 
/usr/lib/perl5/5.8.x/pods/perldiag.pod before to work
# next look at /var/log/httpd/error_log , 
http://www.perl.com/pub/a/2002/05/07/mod_perl.html
 may help
#use Carp ();
#local $SIG{__WARN__} = \&Carp::cluck;
use File::Copy;
use Sys::Hostname;
use File::Temp qw/ tempfile /;
require '/var/nethsecurity/
general-functions.pl
';
require "${General::swroot}/
lang.pl
";
require "${General::swroot}/
header.pl
";
my $errormessage = '';
my $warnmessage = '';
my $setdir = '/home/httpd/html/backup'; # location where sets are stored and 
imported
my $datafile = hostname() . '.dat';     # file containing data backup after 
upload
my $disabled= '';                       # without key to disable many 
buttons
my %settings = ();
$settings{'ACTION'} = '';               # define to suppress all warnings 
when form is empty
my $umountdisabled= '';                 # usb mass-storage only need umount
my $hostfilter='([\w-]+\.)+[\w-]+';     # regex for hostname
#workaround to suppress a warning when a variable is used only once
my @dummy = ( ${Header::table1colour}, ${Header::table2colour} );
undef (@dummy);
# Get GUI values
&Header::getcgihash(\%settings, {'wantfile' => 1, 'filevar' => 'FH'});
# Return device name of what is mounted under 'backup'
sub findmounted()
{
        my $mounted = `/bin/mount | /bin/grep " $setdir "`;
        if ($mounted) {
                # extract device name
                $mounted =~ m!^/dev/(.*) on!;           # device on 
mountmoint options
                return $1;
        } else {
                # it's the normal subdir
        return $Lang::tr{'local hard disk'};
        }
}
# return a date/time and comment string from a time file
sub read_timefile($)
{
        my $fname = shift;   # name of data file
        my $dt;
        if (defined(open(FH, "<$fname.time"))) {
                $dt = <FH>;
                chomp $dt;
                close(FH);
                # change format for display
                $dt =~ s/(\d{4}-\d{2}-\d{2})_(\d{2})-(\d{2})-(\d{2})(.*)/$1 
$2:$3:$4 | $5/;
        } else {
                # This should really never happen as helper now import a 
backup
                $dt='Do not suppress a .dat.time file manually, export and 
import again to fix';
        }
        return &Header::cleanhtml($dt);
}
# get backup error text
sub get_bk_error()
{
        my $exit_code = shift || return '';
        if ($exit_code == 0) { return '';
        } elsif ($exit_code == 2) { return $Lang::tr{'err bk 2 key'};
        } elsif ($exit_code == 3) { return $Lang::tr{'err bk 3 tar'};
        } elsif ($exit_code == 4) { return $Lang::tr{'err bk 4 gz'};
        } elsif ($exit_code == 5) { return $Lang::tr{'err bk 5 encrypt'};
        } elsif ($exit_code == 10) { return $Lang::tr{'incorrect password'};
        } else { return $Lang::tr{'err bk 1'};
        }
}
# show any restore errors
sub get_rs_error($)
{
        my $exit_code = shift || return '';
        if ($exit_code == 0) { return '';
        } elsif ($exit_code == 6) { return $Lang::tr{'err rs 6 decrypt'};
        } elsif ($exit_code == 7) { return $Lang::tr{'err rs 7 untartst'};
        } elsif ($exit_code == 8) { return $Lang::tr{'err rs 8 untar'};
        } elsif ($exit_code == 9) { return $Lang::tr{'missing dat'};
        } else { return $Lang::tr{'err rs 1'}."($exit_code)";
        }
}
sub kmgt($)
{
        my ($value,$length,$opt_U) =@_;
        $opt_U='' if not defined($opt_U);
        if ( $value > 10**( $length + 8 ) or $opt_U eq 'T' ) {
                return sprintf( "%d%s", int( ( $value / 1024**4 ) + .5 ), 
'T' );
        } elsif ( $value > 10**( $length + 5 ) or $opt_U eq 'G' ) {
                return sprintf( "%d%s", int( ( $value / 1024**3 ) + .5 ), 
'G' );
        } elsif ( $value > 10**( $length + 2 ) or $opt_U eq 'M' ) {
                return sprintf( "%d%s", int( ( $value / 1024**2 ) + .5 ), 
'M' );
        } elsif ( $value > 10**($length) or $opt_U eq 'K' ) {
                return sprintf( "%d%s", int( ( $value / 1024 ) + .5 ), 
'K' );
        } else {
                return $value;
        }
}
# Export the key.
# backup password is required to disallow user 'noboby' to export the key
# and create a fake backup.
if ($settings{'ACTION'} eq $Lang::tr{'backup export key'}) {
        if (!defined($settings{'PASSWORD'})) {
                $errormessage = $Lang::tr{'password not set'};
        } elsif ($settings{'PASSWORD'} =~ m/[\s\"']/) {
                $errormessage = $Lang::tr{'password contains illegal 
characters'};
        } elsif (length($settings{'PASSWORD'}) < 6) {
                $errormessage = $Lang::tr{'passwords must be at least 6 
characters in length'};
        } else {
                my $size = 0;
                my $filename = 'backup.'.&hostname().'.key';
                (my $fh, my $tmpfilename) = tempfile('/tmp/logfile.XXXXXX');
                $errormessage = 
&get_bk_error(system('/usr/local/bin/ipcopbkcfg', '--keycat',
                                        "$settings{'PASSWORD'}", 
"$tmpfilename")>>8);
                if (!$errormessage) {
                        open FH,"< $tmpfilename" or die "Unable to open tmp 
key file !";
                        my @lines=<FH>;
                        close FH;
                        if (scalar @lines !=2) {
                                $errormessage = "Bad tmp key file : wrong 
lines number!";
                        } else {
                                $lines[0]=&Header::cleanhtml($lines[0]);
                                $lines[1]=&Header::cleanhtml($lines[1]);
                                use bytes;
                                foreach (@lines) {$size += length($_)};
                                print "Content-Type: 
application/force-download\n";
                                print "Content-Disposition: attachment; 
filename=".$filename."\n";
                                print "Content-length: $size\n\n";# twice \n 
as an empty line is necessary before the data
                                print @lines;
                        }
                }
                unlink $tmpfilename;
        }
}
###########################################################################
# Import a backup key
if ($settings{'ACTION'} eq $Lang::tr{'backup import key'}) {
        if (!defined($settings{'PASSWORD2'})) {
                $errormessage = $Lang::tr{'password not set'};
        } elsif ($settings{'PASSWORD2'} =~ m/[\s\"']/) {
                $errormessage = $Lang::tr{'password contains illegal 
characters'};
        } elsif (length($settings{'PASSWORD2'}) < 6) {
                $errormessage = $Lang::tr{'passwords must be at least 6 
characters in length'};
        } elsif (ref ($settings{'FH'}) ne 'Fh') {
                $errormessage = $Lang::tr{'no cfg upload'};
        } elsif (!copy ($settings{'FH'}, "/tmp/enc_back_key")) {
                $errormessage = $Lang::tr{'save error'};
        } else {
                system('/usr/local/bin/decr_key', 'decr_key', 
"$settings{'PASSWORD2'}");
        }
}
#####################################################################
# Export backup in tar.gz format
if ($settings{'ACTION'} eq "$Lang::tr{'export'} tar.gz") {
        #check form input
        if ($settings{'KEY'} !~ 
m!^$setdir/$hostfilter\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}\.dat$! ){
                $errormessage = $Lang::tr{'bad characters in'}.'KEY';
        } else {
                system('/usr/local/bin/decr_key', 'decr_backup', 
"$settings{'BACKUP_NAME'}");
                my $size = 0;
                my $tmpfilename = "/tmp/$settings{'BACKUP_NAME'}.tar.gz";
                open FH,"< $tmpfilename" or die "Unable to open tmp backup 
file !";
                my @lines=<FH>;
                close FH;
                use bytes;
                foreach (@lines) {$size += length($_)};
                print "Content-Type: application/force-download\n";
                $settings{'BACKUP_NAME'} =~ s/\.dat$//;
                print "Content-Disposition: attachment; 
filename=".$settings{'BACKUP_NAME'}.".tar.gz \n";
                print "Content-length: $size\n\n";# twice \n as an empty 
line is necessary before the data
                print @lines;
                unlink $tmpfilename;
        }
}
##########################################################################
my $cryptkeymissing = system ('/usr/local/bin/ipcopbkcfg', '--keyexist')>>8;
# disable 'create key' or other buttons
if ($cryptkeymissing) {
        $disabled = "disabled='disabled'";
} else {
        $disabled = '';
}
# Create new archive set
if ($settings{'ACTION'} eq $Lang::tr{'create new backup'}) {
        $settings{'DESCRIPTION'} =~ s/[^ \w'_-]//g; # remove everything 
potentially bad
        # just because of the page layout
        if (length($settings{'DESCRIPTION'})>80) {
                $errormessage = "$Lang::tr{'description'}".$Lang::tr{'too 
long 80 char max'};
        } else {
                $errormessage = &get_bk_error(
                        system('/usr/local/bin/ipcopbkcfg', '--write', 
"$settings{'DESCRIPTION'}")>>8);
        }
}
# Delete an archive set
if (defined($settings{$Lang::tr{'remove'}.'.y'})) {
        #check form input before erase files
        if ($settings{'KEY'} !~ 
m!^$setdir/$hostfilter\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}\.dat$! ){
                $errormessage = $Lang::tr{'bad characters in'}.'KEY';
        } else {
                unlink $settings{'KEY'};
                unlink $settings{'KEY'}.'.time';
        }
}
# Import an archive set
if ($settings{'ACTION'} eq $Lang::tr{'import'}) {
        if (ref ($settings{'FH'}) ne 'Fh') {
                $errormessage = $Lang::tr{'no cfg upload'};
        } elsif (!copy ($settings{'FH'}, "$setdir/$datafile")) {
                $errormessage = $Lang::tr{'save error'};
        } else {
                $errormessage = &get_rs_error(
                        system('/usr/local/bin/ipcoprscfg',
                                '--import')>>8);
        }
}
# Restore an archive :special confirmation page
if (defined($settings{$Lang::tr{'restore'}.'.y'}) ||
                $settings{'ACTION'} eq $Lang::tr{'restore'}) {
        if ($settings{'ACTION'} eq $Lang::tr{'restore'}) {
                # if keyfile does not exist
                if ($cryptkeymissing) {
                        $errormessage = $Lang::tr{'backup missing key'};
                } elsif (!-e "$settings{'KEY'}") {
                        # encrypted dat is required
                        $errormessage = $Lang::tr{'missing dat'};
                } elsif ($settings{'RESTOREHW'} eq 'on') {
                        # can't use ? --hardware : '' because argc is wrong 
for the helper.
                        $errormessage = get_rs_error(
                                system('/usr/local/bin/ipcoprscfg',
                                        '--restore', "$settings{'KEY'}",
                                system('/usr/local/bin/ipcoprscfg',
                                        '--restore', "$settings{'KEY'}",
                                        '--hardware')>>8);
                } else {
                        $errormessage = get_rs_error(
                                system('/usr/local/bin/ipcoprscfg',
                                        '--restore', 
"$settings{'KEY'}")>>8);
                }
                if (!$errormessage) {
                        # restored ok, recommend restarting system
                        $warnmessage = $Lang::tr{'cfg restart'};
                }
        } else {
                &Header::showhttpheaders();
                &Header::openpage($Lang::tr{'backup'}, 1, '');
                &Header::openbigbox('100%', 'left');
                &Header::openbox('100%', 'left', $Lang::tr{'are you sure'});
                my $settime = read_timefile($settings{'KEY'});
                print <<EOF
<form method='post' action='$ENV{'SCRIPT_NAME'}'>
<input type='hidden' name='KEY' value="$settings{'KEY'}" />
<table align='center' border='0'>
<tr>
        <td>$Lang::tr{'restore'}:</td>
        <td>$settime</td>
</tr>
<tr>
        <td>$Lang::tr{'restore hardware settings'}: <input type='checkbox' 
name='RESTOREHW' /></td>
</tr>
<tr>
        <td align='center'><input type='submit' name='ACTION' 
value='$Lang::tr{'restore'}' /></td>
        <td><input type='submit' name='ACTION' value='$Lang::tr{'cancel'}' 
/></td>
</tr>
</table>
</form>
EOF
;
        &Header::closebox();
        &Header::closebigbox();
        &Header::closepage();
        exit (0);
        }
}
# Build the list of removable device
# Read partitions sizes registered
my %partitions;
my %devcount; # Count partitions to not make whole device mountable when 
partitioned
foreach my $li (`/bin/cat /proc/partitions | /bin/grep 'sd'`) {
        # partitions{'sda1'} = 128M        if         /major minor  blocks 
name/
        if ($li =~ /(\d+) +(\d+) +(\d+) +(.*)/) {
                $partitions{$4} = &kmgt($3*1024,4);
                if (length($4)==3) {
                        $devcount{$4}=0;
                } else {
                        # count the partition on corresponding dev
                        ++$devcount{substr($4,0,3)};
                }
        }
}
# Search usb-storage scsi device
my %medias;
foreach (`/bin/ls -F1 /proc/scsi/usb-storage*/* 2>/dev/null`) {
        my $m;
        foreach ( `/bin/cat $_` ) {
                # list each line of information for the device:
                # Host scsi0: usb-storage
                # Vendor: SWISSBIT
                # Product: Black Silver
                # Serial Number: D0ED423A4F84A31E
                # Protocol: Transparent SCSI
                # Transport: Bulk
                # GUID: 13706828d0ed423a4f84a31e
                # Attached: Yes
                chomp;
                my ($key,$val) = split(': ',$_,2);
                $key =~ s/^ *//;        # remove front space
                # Convert controller and device number to partition letter
                # Convert controller and device number to partition letter
                # and use it as a %medias keyhash
                # there is always one controller with each usb mass-storage 
device
                # but with real scsi disk, on the same host, number vary
                if ($key =~ /Host scsi(.)/) {
                        my $letter =97; # scsi0 => sda
                        my $hostnumber=$1;
                        foreach (`/bin/cat /proc/scsi/scsi | /bin/grep 
'Host: scsi'`) {
                                if ( /scsi$hostnumber/ ) {
                                        #we have the right host, stop to 
increment
                                        last;
                                } else {
                                        ++$letter;
                                }
                        }
                        $val = $m = 'sd' . chr($letter);
                        $key = 'Host';
                }
                # save data
                $medias{$m}{$key} = $val;
        }
}
# Mount a media
if ($settings{'ACTION'} eq $Lang::tr{'mount'}) {
        if ($settings{'MEDIA'} !~ /^sd[a-z]\d{1,2}$/ && 
$settings{'DESCRIPTION'} ne '') {
                $errormessage = $Lang::tr{'bad characters in'}.'MEDIA';
        } else {
                #umount previous, even if same device already mounted.
                system('/usr/local/bin/ipcopbkcfg', '--umount');
                if (grep (/$settings{'MEDIA'}/,%partitions)) {
                        $errormessage = `/usr/local/bin/ipcopbkcfg --mount 
$settings{'MEDIA'}`;
                }
        }
}
# Umount a removable media
if ($settings{'ACTION'} eq $Lang::tr{'umount'}) {
        system('/usr/local/bin/ipcopbkcfg', '--umount');
}
my $mounted = &findmounted();
# For current media, compute a full description of device
my $media_des = $mounted;       # Description
if ($mounted eq $Lang::tr{'local hard disk'}) {
        $umountdisabled = "disabled='disabled'";
} else {
        $umountdisabled = '';
        $_ = $mounted;
        # sda1 => sda
        tr/0-9//d;
        # display Vendor and Product as where the usefull info vary
        $media_des = "$medias{$_}{'Vendor'} $medias{$_}{'Product'} 
($mounted, $partitions{$mounted})";
}
sub readfreespace()
{
        my $space=0;
        if ($mounted eq $Lang::tr{'local hard disk'}) {
                # not able to run awk from the GUI
                $space=`/bin/df -B M / | /bin/grep dev | /usr/bin/cut -d 
M -f3`;
        } else {
                $space=`/bin/df -B M /dev/$mounted | /bin/grep dev | 
/usr/bin/cut -d M -f3`;
        }
        return $space;
}
my $freespace =&readfreespace();
&Header::showhttpheaders();
&Header::openpage($Lang::tr{'backup'}, 1, '');
&Header::openbigbox('100%', 'left', '', $errormessage);
if ($errormessage) {
        &Header::openbox('100%', 'left', $Lang::tr{'error messages'});
        print "<font class='base'>$errormessage&nbsp;</font>";
        &Header::closebox();
}
# after a restore
if ($warnmessage) {
        &Header::openbox('100%', 'left', '');
        $warnmessage = "<font 
color='${Header::colourred}'><b>$Lang::tr{'capswarning'}</b></font>: 
$warnmessage";
        print "<b>$Lang::tr{'alt information'}</b><br />$warnmessage";
        &Header::closebox();
}
&Header::openbox('100%', 'left', $Lang::tr{'backup'});
print <<EOF
<form method='post' action='$ENV{'SCRIPT_NAME'}' 
enctype='multipart/form-data'>
<table width='100%' border='0'>
<tr>
        <td><input type='submit' name='ACTION' value='$Lang::tr{'backup to 
floppy'}' /></td>
        <td> &nbsp; </td>
        <td><p>$Lang::tr{'insert floppy'}</p></td>
</tr>
<tr>
        <td colspan='3'><hr /></td>
</tr>
<tr>
        <td colspan='3'><table width='100%' border='0'>
                <tr>
                        <td valign='top' colspan='2'><table width='100%' 
border='0'>
                                <tr>
                                        <th colspan='2' 
align='left'>$Lang::tr{'select media'}</th>
                                </tr>
EOF
;
my $checked='';
foreach my $media (keys %medias) {
        # Care only of device attached to USB bus
        if ( $medias{$media}{'Attached'} eq 'Yes') {
                $checked = $medias{$media}{'Host'} eq $mounted ? 
"checked='checked'" : '';
                my $devname="<b>$medias{$media}{'Vendor'} 
$medias{$media}{'Product'}</b>";
                $devname =$devname."&nbsp;$medias{$media}{'Host'} 
($partitions{$medias{$media}{'Host'}})";
                if ($devcount{$medias{$media}{'Host'}}>0) {
                        print "<tr><td>&nbsp;</td><td><input type='radio' 
name='MEDIA' ";
                if ($devcount{$medias{$media}{'Host'}}>0) {
                        print "<tr><td>&nbsp;</td><td><input type='radio' 
name='MEDIA' ";
                        print "value='$medias{$media}{'Host'}' 
disabled='disabled' />$devname</td></tr>\n";
                } else {
                        if ($checked ne '') {
                                print "<tr><td><img src='/blob.gif' alt='*' 
/></td>";
                        } else {
                                print "<tr><td>&nbsp;</td>";
                        }
                        print "<td><input type='radio' name='MEDIA' ";
                        print "value='$medias{$media}{'Host'}' $checked 
/>$devname</td></tr>\n";
                }
                # list attached partitions to this media
                foreach my $part (sort (keys (%partitions))) {
                        if ($part =~ /$medias{$media}{'Host'}./) {
                                $checked = $part eq $mounted ? 
"checked='checked'" : '';
                                if ($checked ne '') {
                                        print "<tr><td><img src='/blob.gif' 
alt='*' /></td>";
                                } else {
                                        print "<tr><td>&nbsp;</td>";
                                }
                                print "<td><input type='radio' name='MEDIA' 
";
                                print "value='$part' $checked 
/>&nbsp;&nbsp;$part ($partitions{$part})</td></tr>\n";
                        }
                }
        }
}
#Add an entry for the local disk, next is key interface management
$checked = $Lang::tr{'local hard disk'} eq $mounted ? "checked='checked'" : 
'';
print<<EOF
                                <tr>
                                        <td>&nbsp;</td>
                                        <th align='left'><input type='radio' 
name='MEDIA' value='$Lang::tr{'local hard disk'$
                                                $Lang::tr{'local hard disk'}
                                        </th>
                                </tr>
EOF
;
# after a umount
if ($settings{'ACTION'} eq $Lang::tr{'umount'}) {
# after a umount
if ($settings{'ACTION'} eq $Lang::tr{'umount'}) {
        print "<tr><td colspan='2'>$Lang::tr{'safe removal of umounted 
device'}</td></tr>";
} elsif ($checked ne '') {
        print "<tr><td colspan='2'>$Lang::tr{'removable device 
advice'}</td></tr>";
} else {
print<<EOF
                                <tr>
                                        <td><img src='/blob.gif' alt='*' 
/></td>
                                        <td 
nowrap='nowrap'>$Lang::tr{'umount removable media before to unplug'}</td>
                                </tr>
EOF
;
}
print<<EOF
                                <tr>
                                        <td colspan='2' align='center'>
                                                <input type='submit' 
name='ACTION' value='$Lang::tr{'refresh'}' />&nbsp;
                                                <input type='submit' 
name='ACTION' value='$Lang::tr{'mount'}' />&nbsp;
                                                <input type='submit' 
name='ACTION' value='$Lang::tr{'umount'}' $umountdisabl$
                                        </td>
                                </tr>
                                </table>
                        </td>
                        <td valign='top'>
                        </td>
                </tr>
                <tr>
                        <td colspan='3'><hr /></td>
                </tr>
<!--#################################  -->
                <tr>
                        <td colspan='3'>&nbsp;</td>
                </tr>
               <tr>
               <tr>
                        <td colspan='3'><b>$Lang::tr{'backup import key'} 
(.key):</b></td>
                </tr>
                <tr>
                        <td ><input type='file' name='FH' size='40' /></td>
                        <td nowrap='nowrap'>$Lang::tr{'backup 
password'}:&nbsp;
                        <input type='password' name='PASSWORD2' size='15' />
                        </td>
                        <td width='50%'>
                                <input type='submit' name='ACTION' 
value='$Lang::tr{'backup import key'}' />
                        </td>
                </tr>
                <tr>
                        <td colspan='3'>&nbsp;</td>
                </tr>
<!-- ##################################  -->
                <tr>
                        <td colspan='3'><hr /></td>
                </tr>
                <tr>
                        <td colspan='3'>&nbsp;</td>
                </tr>
                <tr>
                <td> <b>$Lang::tr{'backup export key'} (.key):</b></td>
                <td nowrap='nowrap'>$Lang::tr{'backup password'}:&nbsp;
                <input type='password' name='PASSWORD' size='15' />
                </td>
                <td width='50%'>
                <input type='submit' name='ACTION' value='$Lang::tr{'backup 
export key'}' />
                </td>
                </tr>
<!-- ##################################  -->
                <tr>
                        <td colspan='3'>&nbsp;</td>
                </tr>
                <tr>
                        <td colspan='3'><hr /></td>
                </tr>
                <tr>
                        <th colspan='3' align='left'>$Lang::tr{'current 
media'}:
                                <font 
color='${Header::colourred}'>$media_des &nbsp;</font>
                                $Lang::tr{'free'}:$freespace M
                        </th>
                </tr>
                <tr>
                        <td colspan='3'>&nbsp;</td>
                </tr>
                <tr>
                        <td colspan='3'><b>$Lang::tr{'create new 
backup'}</b></td>
                </tr>
                <tr>
                        <td colspan='3'>
$Lang::tr{'description'}:
</td>
                </tr>
                <tr>
                        <td colspan='2' nowrap='nowrap'>
                                <input type='text' name='DESCRIPTION' 
size='40' $disabled /></td>
                        <td width='50%'>
                                <input type='submit' name='ACTION' 
value='$Lang::tr{'create new backup'}' $disabled />
                        </td>
                </tr>
                <tr>
                        <td colspan='3'>&nbsp;</td>
                </tr>
                <tr>
                        <td colspan='3'><b>$Lang::tr{'backup import dat 
file'}:</b></td>
                <tr>
                        <td colspan='3'><b>$Lang::tr{'backup import dat 
file'}:</b></td>
                </tr>
                <tr>
                        <td colspan='2'><input type='file' name='FH' 
size='40' /></td>
                        <td width='50%'>
                                <input type='submit' name='ACTION' 
value='$Lang::tr{'import'}' />
                        </td>
                </tr>
                <tr>
                        <td colspan='3'>&nbsp;</td>
                </tr>
                <tr>
                        <td colspan='3'><b>$Lang::tr{'backup sets'}:</b>
                                <table width='100%' border='0'>
                                <tr>
                                        <th width='90%' class='boldbase' 
align='center'>$Lang::tr{'description'}</th>
                                        <th class='boldbase' align='center' 
colspan='4'>$Lang::tr{'action'}</th>
                                </tr>
EOF
;
# get list of available sets by globbing directories under $setdir
# External device (usk key) are mounted in $setdir. -R permits finding sets 
in hierarchy.
my $i = 0;
my $set ='';
foreach $set (`/bin/ls -t1 $setdir/*.dat 2>/dev/null`) {
        #remove newline from line
        chop ($set);
        # filter files out of name format
        if ($set =~ 
m!^$setdir/$hostfilter\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}\.dat$! ) {
                if ($i++ % 2) {
                        print " <tr bgcolor='$Header::table2colour'>\n";
                } else {
                        print " <tr bgcolor='$Header::table1colour'>\n";
                }
                # read time with comment and reformat time
                my $settime = read_timefile($set);
                my $name = substr ($set,length($setdir)+1);
                print<<EOF
                                <td>$settime</td>
               print<<EOF
                                <td>$settime</td>
                                <td align='center'><form method='post' 
action='$ENV{'SCRIPT_NAME'}'>
                                        <input type='image' 
name='$Lang::tr{'restore'}' src='/images/reload.gif' alt='$Lang:$
                                        <input type='hidden' name='KEY' 
value='$set' /></form></td>
                                <td align='center'><a 
href='/backup/$name'><img src='/images/lock.gif' alt="$Lang::tr{'expor$
                                <td align='center'><form method='post' 
action='$ENV{'SCRIPT_NAME'}'>
                                        <input type='hidden' 
name='BACKUP_NAME' value='$name' />
                                        <input type='hidden' name='KEY' 
value='$set' />
                                        <input type='hidden' name='ACTION' 
value="$Lang::tr{'export'} tar.gz" />
                                        <input type='image' 
name="$Lang::tr{'export'} tar.gz" src='/images/floppy.gif' alt="$
                                <td align='center'><form method='post' 
action='$ENV{'SCRIPT_NAME'}'>
                                        <input type='image' 
name='$Lang::tr{'remove'}' src='/images/delete.gif' alt='$Lang::$
                                        <input type='hidden' name='KEY' 
value='$set' /></form></td>
                        </tr>
EOF
;
        }
}
print "</table>\n</td></tr><tr><td colspan='3'>" . ($i ? "<br />" : 
"$Lang::tr{'empty'}!<br /><br />");
# after a floppy backup
if ($settings{'ACTION'} eq $Lang::tr{'backup to floppy'} ) {
        print "<hr /><b>$Lang::tr{'alt information'}</b><pre>" .
                        `/usr/local/bin/ipcopbackup` .
                        '&nbsp;</pre>';
}
print "</td></tr></table></td></tr></table></form>";
&Header::closebox();
&Header::closebigbox();
&Header::closepage();
1;