Allow custom port for FTP and SSH backups and restores

This commit is contained in:
Jamie Cameron
2008-01-15 20:57:43 +00:00
parent de974b045c
commit d1a64b5dff
7 changed files with 54 additions and 26 deletions

View File

@ -12,3 +12,4 @@ Added a warning if % is used in filenames but strftime substition is not enabled
Added tabs to reduce the size of the main page.
---- Changes since 1.390 ----
When a directory is entered as an additional path to backup, it will be expanded to the list of all files under it when the backup is done.
When backing up or restoring from an FTP or SSH server, an optional port number can be entered if the remote server is using a non-standard port.

View File

@ -64,14 +64,15 @@ sub delete_backup
}
# parse_backup_url(string)
# Converts a URL like ftp:// or a filename into its components
# Converts a URL like ftp:// or a filename into its components. These are
# user, pass, host, page, port (optional)
sub parse_backup_url
{
if ($_[0] =~ /^ftp:\/\/([^:]*):([^\@]*)\@([^\/]+)(\/.*)$/) {
return (1, $1, $2, $3, $4);
if ($_[0] =~ /^ftp:\/\/([^:]*):([^\@]*)\@([^\/:]+)(:(\d+))?(\/.*)$/) {
return (1, $1, $2, $3, $6, $5);
}
elsif ($_[0] =~ /^ssh:\/\/([^:]*):([^\@]*)\@([^\/]+)(\/.*)$/) {
return (2, $1, $2, $3, $4);
elsif ($_[0] =~ /^ssh:\/\/([^:]*):([^\@]*)\@([^\/:]+)(:(\d+))?(\/.*)$/) {
return (2, $1, $2, $3, $6, $5);
}
elsif ($_[0] =~ /^upload:(.*)$/) {
return (3, undef, undef, undef, $1);
@ -88,7 +89,7 @@ else {
# Returns HTML for a field for selecting a local or FTP file
sub show_backup_destination
{
local ($mode, $user, $pass, $server, $path) = &parse_backup_url($_[1]);
local ($mode, $user, $pass, $server, $path, $port) = &parse_backup_url($_[1]);
local $rv;
$rv .= "<table cellpadding=1 cellspacing=0>";
@ -113,6 +114,10 @@ $rv .= "<td>$text{'backup_login'} ".
$rv .= "<td>$text{'backup_pass'} ".
&ui_password("$_[0]_pass", $mode == 1 ? $pass : undef, 15).
"</td> </tr>\n";
$rv .= "<tr> <td></td>\n";
$rv .= "<td>$text{'backup_port'} ".
&ui_opt_textbox("$_[0]_port", $mode == 1 ? $port : undef, 5,
$text{'default'})."</td> </tr>\n";
# SCP file fields
$rv .= "<tr><td>".&ui_oneradio("$_[0]_mode", 2, undef, $mode == 2)."</td>\n";
@ -129,6 +134,10 @@ $rv .= "<td>$text{'backup_login'} ".
$rv .= "<td>$text{'backup_pass'} ".
&ui_password("$_[0]_spass", $mode == 2 ? $pass : undef, 15).
"</td> </tr>\n";
$rv .= "<tr> <td></td>\n";
$rv .= "<td>$text{'backup_port'} ".
&ui_opt_textbox("$_[0]_sport", $mode == 2 ? $port : undef, 5,
$text{'default'})."</td> </tr>\n";
if ($_[2] == 1) {
# Uploaded file field
@ -166,8 +175,12 @@ elsif ($mode == 1) {
$in{"$_[0]_path"} =~ /^\/\S/ || &error($text{'backup_epath'});
$in{"$_[0]_user"} =~ /^[^:]*$/ || &error($text{'backup_euser'});
$in{"$_[0]_pass"} =~ /^[^\@]*$/ || &error($text{'backup_epass'});
$in{"$_[0]_port_def"} || $in{"$_[0]_port"} =~ /^\d+$/ ||
&error($text{'backup_eport'});
return "ftp://".$in{"$_[0]_user"}.":".$in{"$_[0]_pass"}."\@".
$in{"$_[0]_server"}.$in{"$_[0]_path"};
$in{"$_[0]_server"}.
($in{"$_[0]_port_def"} ? "" : ":".$in{"$_[0]_port"}).
$in{"$_[0]_path"};
}
elsif ($mode == 2) {
# SSH server
@ -175,8 +188,12 @@ elsif ($mode == 2) {
$in{"$_[0]_spath"} =~ /^\/\S/ || &error($text{'backup_epath2'});
$in{"$_[0]_suser"} =~ /^[^:]*$/ || &error($text{'backup_euser'});
$in{"$_[0]_spass"} =~ /^[^\@]*$/ || &error($text{'backup_epass'});
$in{"$_[0]_sport_def"} || $in{"$_[0]_sport"} =~ /^\d+$/ ||
&error($text{'backup_esport'});
return "ssh://".$in{"$_[0]_suser"}.":".$in{"$_[0]_spass"}."\@".
$in{"$_[0]_sserver"}.$in{"$_[0]_spath"};
$in{"$_[0]_sserver"}.
($in{"$_[0]_sport_def"} ? "" : ":".$in{"$_[0]_sport"}).
$in{"$_[0]_spath"};
}
elsif ($mode == 3) {
# Uploaded file .. save as temp file?
@ -198,7 +215,7 @@ sub execute_backup
local @mods = grep { $_ ne '' } @{$_[0]};
# Work out where to write to
local ($mode, $user, $pass, $host, $path) = &parse_backup_url($_[1]);
local ($mode, $user, $pass, $host, $path, $port) = &parse_backup_url($_[1]);
local $file;
if ($mode == 0) {
$file = &date_subs($path);
@ -313,14 +330,15 @@ if (!$_[5]) {
if ($mode == 1) {
# FTP upload to destination
local $err;
&ftp_upload($host, &date_subs($path), $file, \$err, undef, $user,$pass);
&ftp_upload($host, &date_subs($path), $file, \$err, undef,
$user, $pass, $port);
&unlink_file($file);
return $err if ($err);
}
elsif ($mode == 2) {
# SCP to destination
local $err;
&scp_copy($file, "$user\@$host:".&date_subs($path), $pass, \$err);
&scp_copy($file, "$user\@$host:".&date_subs($path), $pass, \$err,$port);
&unlink_file($file);
return $err if ($err);
}
@ -334,7 +352,7 @@ return undef;
sub execute_restore
{
# Fetch file if needed
local ($mode, $user, $pass, $host, $path) = &parse_backup_url($_[1]);
local ($mode, $user, $pass, $host, $path, $port) = &parse_backup_url($_[1]);
local $file;
if ($mode == 0) {
$file = $path;
@ -344,7 +362,7 @@ else {
if ($mode == 2) {
# Download with SCP
local $err;
&scp_copy("$user\@$host:$path", $file, $pass, \$err);
&scp_copy("$user\@$host:$path", $file, $pass, \$err, $port);
if ($err) {
&unlink_file($file);
return $err;
@ -353,7 +371,8 @@ else {
elsif ($mode == 1) {
# Download with FTP
local $err;
&ftp_download($host, $path, $file, \$err, undef, $user, $pass);
&ftp_download($host, $path, $file, \$err, undef,
$user, $pass, $port);
if ($err) {
&unlink_file($file);
return $err;
@ -484,13 +503,14 @@ if ($_[3]) {
return undef;
}
# scp_copy(source, dest, password, &error)
# scp_copy(source, dest, password, &error, [port])
# Copies a file from some source to a destination. One or the other can be
# a server, like user@foo:/path/to/bar/
sub scp_copy
{
&foreign_require("proc", "proc-lib.pl");
local $cmd = "scp -r ".quotemeta($_[0])." ".quotemeta($_[1]);
local $cmd = "scp -r ".($_[4] ? "-P $_[4] " : "").
quotemeta($_[0])." ".quotemeta($_[1]);
local ($fh, $fpid) = &proc::pty_process_exec($cmd);
local $out;
while(1) {
@ -526,7 +546,7 @@ return $job;
# Returns a backup filename in a human-readable format, with dates substituted
sub nice_dest
{
local ($mode, $user, $pass, $server, $path) = &parse_backup_url($_[0]);
local ($mode, $user, $pass, $server, $path, $port) = &parse_backup_url($_[0]);
if ($_[1]) {
$path = &date_subs($path);
}
@ -534,10 +554,12 @@ if ($mode == 0) {
return "<tt>$path</tt>";
}
elsif ($mode == 1) {
return &text('nice_ftp', "<tt>$server</tt>", "<tt>$path</tt>");
return &text($port ? 'nice_ftpp' : 'nice_ftp',
"<tt>$server</tt>", "<tt>$path</tt>", "<tt>$port</tt>");
}
elsif ($mode == 2) {
return &text('nice_ssh', "<tt>$server</tt>", "<tt>$path</tt>");
return &text($port ? 'nice_sshp' : 'nice_ssh',
"<tt>$server</tt>", "<tt>$path</tt>", "<tt>$port</tt>");
}
elsif ($mode == 3) {
return $text{'nice_upload'};

View File

@ -12,7 +12,7 @@ $dest = &parse_backup_destination("dest", \%in);
@mods || ($nofiles && !$configfile) || &error($text{'backup_emods'});
# Go for it
($mode, $user, $pass, $server, $path) = &parse_backup_url($dest);
($mode, $user, $pass, $server, $path, $port) = &parse_backup_url($dest);
if ($mode != 4) {
# Save somewhere, and tell the user
&ui_print_header(undef, $text{'backup_title'}, "");

View File

@ -11,9 +11,9 @@ if (!@mods) {
%mods = map { $_->{'dir'}, $_ } @mods;
# Show tabs
@tabs = ( [ "backup", $text{'index_tabbackup'}, "index.cgi?mode=clone" ],
[ "sched", $text{'index_tabsched'}, "index.cgi?mode=install" ],
[ "restore", $text{'index_tabrestore'}, "index.cgi?mode=delete" ],
@tabs = ( [ "backup", $text{'index_tabbackup'}, "index.cgi?mode=backup" ],
[ "sched", $text{'index_tabsched'}, "index.cgi?mode=sched" ],
[ "restore", $text{'index_tabrestore'}, "index.cgi?mode=restore" ],
);
print &ui_tabs_start(\@tabs, "tab", $in{'mode'} || "backup", 1);

View File

@ -52,6 +52,7 @@ backup_mode4=Download in browser
backup_path=file on server
backup_login=Login as user
backup_pass=with password
backup_port=Server port
backup_epre=Module $1 rejected backup : $2
backup_enone=No modules provided any existing files to backup!
backup_etar=TAR failed : $1
@ -68,6 +69,8 @@ backup_epath=Missing or invalid absolute path on FTP server
backup_epath2=Missing or invalid absolute path on SSH server
backup_euser=Invalid characters in FTP server login
backup_epass=Invalid characters in FTP server password
backup_eport=Missing or invalid FTP server port
backup_esport=Missing or invalid SSH server port
backup_emods=No modules selected
backup_title=Backup Configuration
backup_doing=Starting backup of module configuration files to $1 ..
@ -81,7 +84,9 @@ restore_failed=.. failed! $1
restore_done=.. complete. $1 files were restored.
nice_ftp=$2 on $1 via FTP
nice_ftpp=$2 on $1 port $3 via FTP
nice_ssh=$2 on $1 via SSH
nice_sshp=$2 on $1 port $3 via SSH
nice_upload=uploaded file
nice_download=browser

View File

@ -11,7 +11,7 @@ $src = &parse_backup_destination("src", \%in);
@mods || &error($text{'restore_emods'});
# Do it ..
($mode, $user, $pass, $server, $path) = &parse_backup_url($src);
($mode, $user, $pass, $server, $path, $port) = &parse_backup_url($src);
if ($mode == 3) {
# Create temp file for uploaded file
$temp = &transname();

View File

@ -80,11 +80,11 @@ if ($in{'run'}) {
}
&webmin_log("run", "backup", $backup->{'dest'}, $backup);
&ui_print_footer("edit.cgi?id=$in{'id'}", $text{'edit_return'},
"", $text{'index_return'});
"index.cgi?mode=sched", $text{'index_return'});
exit;
}
else {
&redirect("");
&redirect("index.cgi?mode=sched");
}