diff --git a/backup-config/CHANGELOG b/backup-config/CHANGELOG
index dc23c857d..f051f9663 100644
--- a/backup-config/CHANGELOG
+++ b/backup-config/CHANGELOG
@@ -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.
diff --git a/backup-config/backup-config-lib.pl b/backup-config/backup-config-lib.pl
index 7527fb529..108b68ea3 100644
--- a/backup-config/backup-config-lib.pl
+++ b/backup-config/backup-config-lib.pl
@@ -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 .= "
";
@@ -113,6 +114,10 @@ $rv .= "| $text{'backup_login'} ".
$rv .= " | $text{'backup_pass'} ".
&ui_password("$_[0]_pass", $mode == 1 ? $pass : undef, 15).
" | \n";
+$rv .= " | \n";
+$rv .= "$text{'backup_port'} ".
+ &ui_opt_textbox("$_[0]_port", $mode == 1 ? $port : undef, 5,
+ $text{'default'})." |
\n";
# SCP file fields
$rv .= "| ".&ui_oneradio("$_[0]_mode", 2, undef, $mode == 2)." | \n";
@@ -129,6 +134,10 @@ $rv .= "$text{'backup_login'} ".
$rv .= " | $text{'backup_pass'} ".
&ui_password("$_[0]_spass", $mode == 2 ? $pass : undef, 15).
" |
\n";
+$rv .= " | \n";
+$rv .= "$text{'backup_port'} ".
+ &ui_opt_textbox("$_[0]_sport", $mode == 2 ? $port : undef, 5,
+ $text{'default'})." |
\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 "$path";
}
elsif ($mode == 1) {
- return &text('nice_ftp', "$server", "$path");
+ return &text($port ? 'nice_ftpp' : 'nice_ftp',
+ "$server", "$path", "$port");
}
elsif ($mode == 2) {
- return &text('nice_ssh', "$server", "$path");
+ return &text($port ? 'nice_sshp' : 'nice_ssh',
+ "$server", "$path", "$port");
}
elsif ($mode == 3) {
return $text{'nice_upload'};
diff --git a/backup-config/backup.cgi b/backup-config/backup.cgi
index 274877399..6bc56d63f 100755
--- a/backup-config/backup.cgi
+++ b/backup-config/backup.cgi
@@ -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'}, "");
diff --git a/backup-config/index.cgi b/backup-config/index.cgi
index 169ec47fe..087fb9ec3 100755
--- a/backup-config/index.cgi
+++ b/backup-config/index.cgi
@@ -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);
diff --git a/backup-config/lang/en b/backup-config/lang/en
index c7bc40c40..ddbbc20b1 100644
--- a/backup-config/lang/en
+++ b/backup-config/lang/en
@@ -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
diff --git a/backup-config/restore.cgi b/backup-config/restore.cgi
index d3696dcd7..826c9dfa6 100755
--- a/backup-config/restore.cgi
+++ b/backup-config/restore.cgi
@@ -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();
diff --git a/backup-config/save.cgi b/backup-config/save.cgi
index d2b436ef9..02c601081 100755
--- a/backup-config/save.cgi
+++ b/backup-config/save.cgi
@@ -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");
}