mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-27 15:54:22 +02:00
SCP Fixes (from Yanbing), realpath_win cleanup and spawn_child fix (that broke progfiles installation)
This commit is contained in:
parent
c957488af2
commit
9333a08637
@ -155,11 +155,11 @@
|
|||||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\win32_dirent.c" />
|
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\win32_dirent.c" />
|
||||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\no-ops.c" />
|
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\no-ops.c" />
|
||||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\win32_zlib.c" />
|
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\win32_zlib.c" />
|
||||||
<ClCompile Include="..\win32compat\ansiprsr.c" />
|
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\ansiprsr.c" />
|
||||||
<ClCompile Include="..\win32compat\conio.c" />
|
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\conio.c" />
|
||||||
<ClCompile Include="..\win32compat\console.c" />
|
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\console.c" />
|
||||||
<ClCompile Include="..\win32compat\tncon.c" />
|
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\tncon.c" />
|
||||||
<ClCompile Include="..\win32compat\tnnet.c" />
|
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\tnnet.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\w32fd.h" />
|
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\w32fd.h" />
|
||||||
@ -198,6 +198,7 @@
|
|||||||
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\termios.h" />
|
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\termios.h" />
|
||||||
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\dirent.h" />
|
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\dirent.h" />
|
||||||
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\pwd.h" />
|
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\pwd.h" />
|
||||||
|
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\misc_internal.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
@ -117,6 +117,7 @@
|
|||||||
<Filter>inc</Filter>
|
<Filter>inc</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\pwd.h" />
|
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\pwd.h" />
|
||||||
|
<ClInclude Include="..\win32compat\misc_internal.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="inc">
|
<Filter Include="inc">
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "inc\sys\time.h"
|
#include "inc\sys\time.h"
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <Shlwapi.h>
|
#include <Shlwapi.h>
|
||||||
|
#include "misc_internal.h"
|
||||||
|
|
||||||
int usleep(unsigned int useconds)
|
int usleep(unsigned int useconds)
|
||||||
{
|
{
|
||||||
@ -302,11 +303,25 @@ spawn_child(char* cmd, int in, int out, int err, DWORD flags) {
|
|||||||
PROCESS_INFORMATION pi;
|
PROCESS_INFORMATION pi;
|
||||||
STARTUPINFOW si;
|
STARTUPINFOW si;
|
||||||
BOOL b;
|
BOOL b;
|
||||||
char* abs_cmd;
|
char *abs_cmd, *t;
|
||||||
wchar_t * cmd_utf16;
|
wchar_t * cmd_utf16;
|
||||||
|
int add_module_path = 0;
|
||||||
|
|
||||||
/* relative ? if so, add current module path to start */
|
/* should module path be added */
|
||||||
if (!(cmd && cmd[0] != '\0' && (cmd[1] == ':' || cmd[0] == '\\' || cmd[0] == '.'))) {
|
do{
|
||||||
|
if(!cmd)
|
||||||
|
break;
|
||||||
|
t = cmd;
|
||||||
|
if (*t = '\"')
|
||||||
|
t++;
|
||||||
|
if (t[0] == '\0' || t[0] == '\\' || t[0] == '.' || t[1] == ':')
|
||||||
|
break;
|
||||||
|
add_module_path = 1;
|
||||||
|
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
/* add current module path to start if needed */
|
||||||
|
if (add_module_path) {
|
||||||
char* ctr;
|
char* ctr;
|
||||||
abs_cmd = malloc(strlen(w32_programdir()) + 1 + strlen(cmd) + 1);
|
abs_cmd = malloc(strlen(w32_programdir()) + 1 + strlen(cmd) + 1);
|
||||||
if (abs_cmd == NULL) {
|
if (abs_cmd == NULL) {
|
||||||
@ -478,8 +493,6 @@ w32_chown(const char *pathname, unsigned int owner, unsigned int group) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *realpath_win(const char *path, char resolved[MAX_PATH]);
|
|
||||||
|
|
||||||
int
|
int
|
||||||
w32_utimes(const char *filename, struct timeval *tvp) {
|
w32_utimes(const char *filename, struct timeval *tvp) {
|
||||||
struct utimbuf ub;
|
struct utimbuf ub;
|
||||||
@ -487,10 +500,7 @@ w32_utimes(const char *filename, struct timeval *tvp) {
|
|||||||
ub.modtime = tvp[1].tv_sec;
|
ub.modtime = tvp[1].tv_sec;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
// Skip the first '/' in the pathname
|
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(sanitized_path(filename));
|
||||||
char resolvedPathName[MAX_PATH];
|
|
||||||
realpath_win(filename, resolvedPathName);
|
|
||||||
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(resolvedPathName);
|
|
||||||
if (resolvedPathName_utf16 == NULL) {
|
if (resolvedPathName_utf16 == NULL) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
@ -517,16 +527,9 @@ link(const char *oldpath, const char *newpath) {
|
|||||||
|
|
||||||
int
|
int
|
||||||
w32_rename(const char *old_name, const char *new_name) {
|
w32_rename(const char *old_name, const char *new_name) {
|
||||||
// Skip the first '/' in the pathname
|
wchar_t *resolvedOldPathName_utf16 = utf8_to_utf16(sanitized_path(old_name));
|
||||||
char resolvedOldPathName[MAX_PATH];
|
wchar_t *resolvedNewPathName_utf16 = utf8_to_utf16(sanitized_path(new_name));
|
||||||
realpath_win(old_name, resolvedOldPathName);
|
|
||||||
|
|
||||||
// Skip the first '/' in the pathname
|
|
||||||
char resolvedNewPathName[MAX_PATH];
|
|
||||||
realpath_win(new_name, resolvedNewPathName);
|
|
||||||
|
|
||||||
wchar_t *resolvedOldPathName_utf16 = utf8_to_utf16(resolvedOldPathName);
|
|
||||||
wchar_t *resolvedNewPathName_utf16 = utf8_to_utf16(resolvedNewPathName);
|
|
||||||
if (NULL == resolvedOldPathName_utf16 || NULL == resolvedNewPathName_utf16) {
|
if (NULL == resolvedOldPathName_utf16 || NULL == resolvedNewPathName_utf16) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
@ -541,11 +544,8 @@ w32_rename(const char *old_name, const char *new_name) {
|
|||||||
|
|
||||||
int
|
int
|
||||||
w32_unlink(const char *path) {
|
w32_unlink(const char *path) {
|
||||||
// Skip the first '/' in the pathname
|
|
||||||
char resolvedPathName[MAX_PATH];
|
|
||||||
realpath_win(path, resolvedPathName);
|
|
||||||
|
|
||||||
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(resolvedPathName);
|
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(sanitized_path(path));
|
||||||
if (NULL == resolvedPathName_utf16) {
|
if (NULL == resolvedPathName_utf16) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
@ -559,11 +559,7 @@ w32_unlink(const char *path) {
|
|||||||
|
|
||||||
int
|
int
|
||||||
w32_rmdir(const char *path) {
|
w32_rmdir(const char *path) {
|
||||||
// Skip the first '/' in the pathname
|
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(sanitized_path(path));
|
||||||
char resolvedPathName[MAX_PATH];
|
|
||||||
realpath_win(path, resolvedPathName);
|
|
||||||
|
|
||||||
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(resolvedPathName);
|
|
||||||
if (NULL == resolvedPathName_utf16) {
|
if (NULL == resolvedPathName_utf16) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
@ -606,11 +602,8 @@ w32_getcwd(char *buffer, int maxlen) {
|
|||||||
|
|
||||||
int
|
int
|
||||||
w32_mkdir(const char *path_utf8, unsigned short mode) {
|
w32_mkdir(const char *path_utf8, unsigned short mode) {
|
||||||
// Skip the first '/' in the pathname
|
|
||||||
char resolvedPathName[MAX_PATH];
|
|
||||||
realpath_win(path_utf8, resolvedPathName);
|
|
||||||
|
|
||||||
wchar_t *path_utf16 = utf8_to_utf16(resolvedPathName);
|
wchar_t *path_utf16 = utf8_to_utf16(sanitized_path(path_utf8));
|
||||||
if (path_utf16 == NULL) {
|
if (path_utf16 == NULL) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
@ -632,22 +625,14 @@ getrnd(u_char *s, size_t len) {
|
|||||||
|
|
||||||
int
|
int
|
||||||
w32_stat(const char *path, struct w32_stat *buf) {
|
w32_stat(const char *path, struct w32_stat *buf) {
|
||||||
// Skip the first '/' in the pathname
|
return fileio_stat(sanitized_path(path), (struct _stat64*)buf);
|
||||||
char resolvedPathName[MAX_PATH];
|
|
||||||
realpath_win(path, resolvedPathName);
|
|
||||||
|
|
||||||
return fileio_stat(resolvedPathName, (struct _stat64*)buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if file is symbolic link, copy its link into "link" .
|
// if file is symbolic link, copy its link into "link" .
|
||||||
int
|
int
|
||||||
readlink(const char *path, char *link, int linklen)
|
readlink(const char *path, char *link, int linklen)
|
||||||
{
|
{
|
||||||
// Skip the first '/' in the pathname
|
strcpy_s(link, linklen, sanitized_path(path));
|
||||||
char resolvedPathName[MAX_PATH];
|
|
||||||
realpath_win(path, resolvedPathName);
|
|
||||||
|
|
||||||
strcpy_s(link, linklen, resolvedPathName);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -694,16 +679,6 @@ realpath(const char *path, char resolved[MAX_PATH]) {
|
|||||||
return resolved;
|
return resolved;
|
||||||
}
|
}
|
||||||
|
|
||||||
// like realpathWin32() but takes out the first slash so that windows systems can work on the actual file or directory
|
|
||||||
char *
|
|
||||||
realpath_win(const char *path, char resolved[MAX_PATH]) {
|
|
||||||
char tempPath[MAX_PATH];
|
|
||||||
realpath(path, tempPath);
|
|
||||||
|
|
||||||
strncpy(resolved, &tempPath[1], sizeof(tempPath) - 1);
|
|
||||||
return resolved;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maximum reparse buffer info size. The max user defined reparse
|
// Maximum reparse buffer info size. The max user defined reparse
|
||||||
// data is 16KB, plus there's a header.
|
// data is 16KB, plus there's a header.
|
||||||
#define MAX_REPARSE_SIZE 17000
|
#define MAX_REPARSE_SIZE 17000
|
||||||
|
3
contrib/win32/win32compat/misc_internal.h
Normal file
3
contrib/win32/win32compat/misc_internal.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
/* removes first '/' for Windows paths that are unix styled. Ex: /c:/ab.cd */
|
||||||
|
#define sanitized_path(p) (((p)[0] == '/' && (p)[1] != '\0' && (p)[2] == ':')? (p)+1 : (p))
|
@ -40,6 +40,7 @@
|
|||||||
#include <winioctl.h>
|
#include <winioctl.h>
|
||||||
#include "Shlwapi.h"
|
#include "Shlwapi.h"
|
||||||
#include <sys\utime.h>
|
#include <sys\utime.h>
|
||||||
|
#include "misc_internal.h"
|
||||||
|
|
||||||
/* internal table that stores the fd to w32_io mapping*/
|
/* internal table that stores the fd to w32_io mapping*/
|
||||||
struct w32fd_table {
|
struct w32fd_table {
|
||||||
@ -347,7 +348,7 @@ w32_pipe(int *pfds) {
|
|||||||
pio[0]->handle, pio[0], read_index, pio[1]->handle, pio[1], write_index);
|
pio[0]->handle, pio[0], read_index, pio[1]->handle, pio[1], write_index);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
char *realpath_win(const char *path, char resolved[MAX_PATH]);
|
|
||||||
int
|
int
|
||||||
w32_open(const char *pathname, int flags, ...) {
|
w32_open(const char *pathname, int flags, ...) {
|
||||||
int min_index = fd_table_get_min_index();
|
int min_index = fd_table_get_min_index();
|
||||||
@ -357,18 +358,14 @@ w32_open(const char *pathname, int flags, ...) {
|
|||||||
if (min_index == -1)
|
if (min_index == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
// Skip the first '/' in the pathname
|
pio = fileio_open(sanitized_path(pathname), flags, 0);
|
||||||
char resolvedPathName[MAX_PATH];
|
|
||||||
realpath_win(pathname, resolvedPathName);
|
|
||||||
|
|
||||||
pio = fileio_open(resolvedPathName, flags, 0);
|
|
||||||
if (pio == NULL)
|
if (pio == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
pio->type = NONSOCK_FD;
|
pio->type = NONSOCK_FD;
|
||||||
fd_table_set(pio, min_index);
|
fd_table_set(pio, min_index);
|
||||||
debug("open - handle:%p, io:%p, fd:%d", pio->handle, pio, min_index);
|
debug("open - handle:%p, io:%p, fd:%d", pio->handle, pio, min_index);
|
||||||
debug3("open - path:%s", resolvedPathName);
|
debug3("open - path:%s", pathname);
|
||||||
return min_index;
|
return min_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "inc\dirent.h"
|
#include "inc\dirent.h"
|
||||||
#include "inc\libgen.h"
|
#include "inc\libgen.h"
|
||||||
|
#include "misc_internal.h"
|
||||||
|
|
||||||
|
|
||||||
struct DIR_ {
|
struct DIR_ {
|
||||||
@ -19,8 +20,6 @@ struct DIR_ {
|
|||||||
int first;
|
int first;
|
||||||
};
|
};
|
||||||
|
|
||||||
char * realpath_win(const char *path, char resolved[MAX_PATH]);
|
|
||||||
|
|
||||||
/* Open a directory stream on NAME.
|
/* Open a directory stream on NAME.
|
||||||
Return a DIR stream on the directory, or NULL if it could not be opened. */
|
Return a DIR stream on the directory, or NULL if it could not be opened. */
|
||||||
DIR * opendir(const char *name)
|
DIR * opendir(const char *name)
|
||||||
@ -32,11 +31,7 @@ DIR * opendir(const char *name)
|
|||||||
wchar_t* wname = NULL;
|
wchar_t* wname = NULL;
|
||||||
int needed;
|
int needed;
|
||||||
|
|
||||||
// Skip the first '/' in the pathname
|
if ((wname = utf8_to_utf16(sanitized_path(name))) == NULL) {
|
||||||
char resolvedPathName[MAX_PATH];
|
|
||||||
realpath_win(name, resolvedPathName);
|
|
||||||
|
|
||||||
if ((wname = utf8_to_utf16(resolvedPathName)) == NULL) {
|
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -27,12 +27,11 @@ Describe "Tests for scp command" -Tags "CI" {
|
|||||||
$server.SetupServer($client)
|
$server.SetupServer($client)
|
||||||
|
|
||||||
$testData = @(
|
$testData = @(
|
||||||
<# known issue 340
|
|
||||||
@{
|
@{
|
||||||
Title = 'Simple copy local file to local file'
|
Title = 'Simple copy local file to local file'
|
||||||
Source = $SourceFilePath
|
Source = $SourceFilePath
|
||||||
Destination = $DestinationFilePath
|
Destination = $DestinationFilePath
|
||||||
},#>
|
},
|
||||||
@{
|
@{
|
||||||
Title = 'Simple copy local file to remote file'
|
Title = 'Simple copy local file to remote file'
|
||||||
Source = $SourceFilePath
|
Source = $SourceFilePath
|
||||||
@ -43,12 +42,11 @@ Describe "Tests for scp command" -Tags "CI" {
|
|||||||
Source = "$($server.localAdminUserName)@$($server.MachineName):$SourceFilePath"
|
Source = "$($server.localAdminUserName)@$($server.MachineName):$SourceFilePath"
|
||||||
Destination = $DestinationFilePath
|
Destination = $DestinationFilePath
|
||||||
},
|
},
|
||||||
<# known issue 340
|
|
||||||
@{
|
@{
|
||||||
Title = 'Simple copy local file to local dir'
|
Title = 'Simple copy local file to local dir'
|
||||||
Source = $SourceFilePath
|
Source = $SourceFilePath
|
||||||
Destination = $DestinationDir
|
Destination = $DestinationDir
|
||||||
},#>
|
},
|
||||||
@{
|
@{
|
||||||
Title = 'simple copy local file to remote dir'
|
Title = 'simple copy local file to remote dir'
|
||||||
Source = $SourceFilePath
|
Source = $SourceFilePath
|
||||||
@ -121,7 +119,7 @@ Describe "Tests for scp command" -Tags "CI" {
|
|||||||
$equal | Should Be $true
|
$equal | Should Be $true
|
||||||
}
|
}
|
||||||
|
|
||||||
<#It 'Directory recursive Copy with -i option: <Title> ' -TestCases:$testData1 {
|
It 'Directory recursive Copy with -i option: <Title> ' -TestCases:$testData1 {
|
||||||
param([string]$Title, $Source, $Destination)
|
param([string]$Title, $Source, $Destination)
|
||||||
|
|
||||||
.\scp -r -i $identifyFile $Source $Destination
|
.\scp -r -i $identifyFile $Source $Destination
|
||||||
@ -129,10 +127,10 @@ Describe "Tests for scp command" -Tags "CI" {
|
|||||||
$equal = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
|
$equal = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
|
||||||
$equal | Should Be $true
|
$equal | Should Be $true
|
||||||
|
|
||||||
#known issue 364
|
|
||||||
#$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
|
$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
|
||||||
#$equal | Should Be $true
|
$equal | Should Be $true
|
||||||
}#>
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#this context only run on windows
|
#this context only run on windows
|
||||||
@ -154,32 +152,29 @@ Describe "Tests for scp command" -Tags "CI" {
|
|||||||
It 'File Copy with -S option (positive)' {
|
It 'File Copy with -S option (positive)' {
|
||||||
.\scp -S .\ssh.exe $SourceFilePath "$($server.localAdminUserName)@$($server.MachineName):$DestinationFilePath"
|
.\scp -S .\ssh.exe $SourceFilePath "$($server.localAdminUserName)@$($server.MachineName):$DestinationFilePath"
|
||||||
#validate file content. DestPath is the path to the file.
|
#validate file content. DestPath is the path to the file.
|
||||||
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length).Length -eq 0 #todo: add LastWriteTime in comparison when issue is fixed
|
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length).Length -eq 0
|
||||||
$equal | Should Be $true
|
$equal | Should Be $true
|
||||||
}
|
}
|
||||||
|
|
||||||
<#It 'File Copy with -p -c -v option: <Title> ' -TestCases:$testData {
|
<#It 'File Copy with -p -c -v option: <Title> ' -TestCases:$testData {
|
||||||
param([string]$Title, $Source, $Destination)
|
param([string]$Title, $Source, $Destination)
|
||||||
|
|
||||||
.\scp -p -c aes128-ctr -C $Source $Destination #Todo: add -v after it is supported.
|
.\scp -p -c aes128-ctr -v -C $Source $Destination
|
||||||
#validate file content. DestPath is the path to the file.
|
#validate file content. DestPath is the path to the file.
|
||||||
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length).Length -eq 0 #todo: add LastWriteTime in comparison when issue is fixed
|
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length, LastWriteTime.DateTime).Length -eq 0
|
||||||
$equal | Should Be $true
|
$equal | Should Be $true
|
||||||
}#>
|
}#>
|
||||||
|
|
||||||
<# known issue 369
|
It 'Directory recursive Copy with -r -p -v option: <Title> ' -TestCases:$testData1 {
|
||||||
It 'Directory recursive Copy with -v option: <Title> ' -TestCases:$testData1 {
|
|
||||||
param([string]$Title, $Source, $Destination)
|
param([string]$Title, $Source, $Destination)
|
||||||
|
.\scp -r -p -v $Source $Destination
|
||||||
|
|
||||||
.\scp -r -p $Source $Destination
|
$equal = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
|
||||||
|
|
||||||
$equal = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length, LastWriteTime).Length -eq 0
|
|
||||||
$equal | Should Be $true
|
$equal | Should Be $true
|
||||||
|
|
||||||
#known issue 364
|
$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length, LastWriteTime.DateTime).Length -eq 0
|
||||||
#$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length, LastWriteTime).Length -eq 0
|
$equal | Should Be $true
|
||||||
#$equal | Should Be $true
|
}
|
||||||
}#>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Context "Key based authentication with -i -C -q options. host keys are not secured on server" {
|
Context "Key based authentication with -i -C -q options. host keys are not secured on server" {
|
||||||
@ -192,23 +187,20 @@ Describe "Tests for scp command" -Tags "CI" {
|
|||||||
|
|
||||||
.\scp -i $identifyFile -C -q $Source $Destination
|
.\scp -i $identifyFile -C -q $Source $Destination
|
||||||
#validate file content. DestPath is the path to the file.
|
#validate file content. DestPath is the path to the file.
|
||||||
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length).Length -eq 0 # need to validate LastWriteTime after issue 356 is fixed.
|
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length).Length -eq 0
|
||||||
$equal | Should Be $true
|
$equal | Should Be $true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
<#It 'Directory recursive Copy with -i and -q options: <Title> ' -TestCases:$testData1 {
|
It 'Directory recursive Copy with -i and -q options: <Title> ' -TestCases:$testData1 {
|
||||||
param([string]$Title, $Source, $Destination)
|
param([string]$Title, $Source, $Destination)
|
||||||
|
|
||||||
.\scp -i $identifyFile -r -q $Source $Destination
|
.\scp -i $identifyFile -r -q $Source $Destination
|
||||||
$equal = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
|
$equal = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
|
||||||
$equal | Should Be $true
|
$equal | Should Be $true
|
||||||
|
|
||||||
#known issue 364
|
$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
|
||||||
#$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
|
$equal | Should Be $true
|
||||||
#$equal | Should Be $true
|
}
|
||||||
}#>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
35
scp.c
35
scp.c
@ -598,15 +598,9 @@ main(int argc, char **argv)
|
|||||||
* convert '\\' to '/' in rest of arguments
|
* convert '\\' to '/' in rest of arguments
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
char *s1, *s2;
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++)
|
||||||
s1 = argv[i];
|
convertToForwardslash(argv[i]);
|
||||||
while ((s2 = strchr(s1, '\\')) != NULL) {
|
|
||||||
*s2 = '/';
|
|
||||||
s1 = s2 + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif /* WINDOWS */
|
#endif /* WINDOWS */
|
||||||
|
|
||||||
@ -831,8 +825,12 @@ tolocal(int argc, char **argv)
|
|||||||
/* local to local on windows - need to use local native copy command */
|
/* local to local on windows - need to use local native copy command */
|
||||||
struct stat stb;
|
struct stat stb;
|
||||||
int exists;
|
int exists;
|
||||||
|
char *last;
|
||||||
|
|
||||||
exists = stat(argv[i], &stb) == 0;
|
exists = stat(argv[i], &stb) == 0;
|
||||||
|
/* convert '/' to '\\' */
|
||||||
|
convertToBackslash(argv[i]);
|
||||||
|
convertToBackslash(argv[i - 1]);
|
||||||
if (exists && (S_ISDIR(stb.st_mode))) {
|
if (exists && (S_ISDIR(stb.st_mode))) {
|
||||||
addargs(&alist, "%s", _PATH_XCOPY);
|
addargs(&alist, "%s", _PATH_XCOPY);
|
||||||
if (iamrecursive)
|
if (iamrecursive)
|
||||||
@ -842,23 +840,13 @@ tolocal(int argc, char **argv)
|
|||||||
addargs(&alist, "/Y /F /I");
|
addargs(&alist, "/Y /F /I");
|
||||||
addargs(&alist, "%s", argv[i]);
|
addargs(&alist, "%s", argv[i]);
|
||||||
|
|
||||||
char *lastf = NULL, *lastr = NULL, *name;
|
if ((last = strrchr(argv[i], '\\')) == NULL)
|
||||||
if ((lastf = strrchr(argv[i], '/')) == NULL && (lastr = strrchr(argv[i], '\\')) == NULL)
|
last = argv[i];
|
||||||
name = argv[i];
|
else
|
||||||
else {
|
++last;
|
||||||
if (lastf)
|
|
||||||
name = lastf;
|
|
||||||
if (lastr)
|
|
||||||
name = lastr;
|
|
||||||
++name;
|
|
||||||
}
|
|
||||||
|
|
||||||
char * dest = argv[argc - 1];
|
|
||||||
int len = strlen(dest);
|
|
||||||
char * lastletter = dest + len - 1;
|
|
||||||
|
|
||||||
addargs(&alist, "%s%s%s", argv[argc - 1],
|
addargs(&alist, "%s%s%s", argv[argc - 1],
|
||||||
(lastletter == "\\" || lastletter == "/") ? "" : "\\", name);
|
strcmp(argv[argc - 1], "\\") ? "\\" : "", last);
|
||||||
} else {
|
} else {
|
||||||
addargs(&alist, "%s", _PATH_COPY);
|
addargs(&alist, "%s", _PATH_COPY);
|
||||||
addargs(&alist, "/Y");
|
addargs(&alist, "/Y");
|
||||||
@ -1541,3 +1529,4 @@ lostconn(int signo)
|
|||||||
else
|
else
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user