From d1a64b5dffb0d851224ba08773e65a2cb438d014 Mon Sep 17 00:00:00 2001 From: Jamie Cameron Date: Tue, 15 Jan 2008 20:57:43 +0000 Subject: [PATCH] Allow custom port for FTP and SSH backups and restores --- backup-config/CHANGELOG | 1 + backup-config/backup-config-lib.pl | 60 ++++++++++++++++++++---------- backup-config/backup.cgi | 2 +- backup-config/index.cgi | 6 +-- backup-config/lang/en | 5 +++ backup-config/restore.cgi | 2 +- backup-config/save.cgi | 4 +- 7 files changed, 54 insertions(+), 26 deletions(-) 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 .= "\n"; +$rv .= "\n"; +$rv .= "\n"; # SCP file fields $rv .= "\n"; @@ -129,6 +134,10 @@ $rv .= "\n"; +$rv .= "\n"; +$rv .= "\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"); }
$text{'backup_login'} ". $rv .= "$text{'backup_pass'} ". &ui_password("$_[0]_pass", $mode == 1 ? $pass : undef, 15). "
$text{'backup_port'} ". + &ui_opt_textbox("$_[0]_port", $mode == 1 ? $port : undef, 5, + $text{'default'})."
".&ui_oneradio("$_[0]_mode", 2, undef, $mode == 2)."$text{'backup_login'} ". $rv .= "$text{'backup_pass'} ". &ui_password("$_[0]_spass", $mode == 2 ? $pass : undef, 15). "
$text{'backup_port'} ". + &ui_opt_textbox("$_[0]_sport", $mode == 2 ? $port : undef, 5, + $text{'default'})."