1. Add the default path parameter to the wolfsftp client.

2. Split the error check on the Windows file write into two checks.
3. Check the success of closing the local file in Windows.
4. Rearrange the Get state machine to attempt to close the remote file
first then the local file. The local file close is always attempted.
pull/134/head
John Safranek 2019-01-23 18:22:56 -08:00
parent 4bdfb5bfa3
commit ae6144f596
4 changed files with 52 additions and 17 deletions

View File

@ -269,6 +269,7 @@ static void ShowUsage(void)
printf(" -p <num> port to connect on, default %d\n", wolfSshPort);
printf(" -u <username> username to authenticate as (REQUIRED)\n");
printf(" -P <password> password for username, prompted if omitted\n");
printf(" -d <path> set the default local path\n");
printf(" -N use non blocking sockets\n");
ShowCommands();
@ -885,14 +886,19 @@ THREAD_RETURN WOLFSSH_THREAD sftpclient_test(void* args)
char* host = (char*)wolfSshIp;
const char* username = NULL;
const char* password = NULL;
const char* defaultSftpPath = NULL;
byte nonBlock = 0;
int argc = ((func_args*)args)->argc;
char** argv = ((func_args*)args)->argv;
((func_args*)args)->return_code = 0;
while ((ch = mygetopt(argc, argv, "?h:p:u:P:N")) != -1) {
while ((ch = mygetopt(argc, argv, "?d:h:p:u:P:N")) != -1) {
switch (ch) {
case 'd':
defaultSftpPath = myoptarg;
break;
case 'h':
host = myoptarg;
break;
@ -949,6 +955,14 @@ THREAD_RETURN WOLFSSH_THREAD sftpclient_test(void* args)
if (ssh == NULL)
err_sys("Couldn't create wolfSSH session.");
if (defaultSftpPath != NULL) {
if (wolfSSH_SFTP_SetDefaultPath(ssh, defaultSftpPath)
!= WS_SUCCESS) {
fprintf(stderr, "Couldn't store default sftp path.\n");
exit(EXIT_FAILURE);
}
}
if (password != NULL)
wolfSSH_SetUserAuthCtx(ssh, (void*)password);

View File

@ -263,6 +263,9 @@ const char* GetErrorString(int err)
case WS_SIZE_ONLY:
return "Only getting the size of buffer needed";
case WS_CLOSE_FILE_E:
return "Unable to close local file";
default:
return "Unknown error code";
}

View File

@ -6785,7 +6785,7 @@ int wolfSSH_SFTP_Get(WOLFSSH* ssh, char* from,
if (state->gOfst > 0)
desiredAccess |= FILE_APPEND_DATA;
state->fileHandle = CreateFileA(to, desiredAccess,
0, NULL, CREATE_NEW,
0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
}
if (resume) {
@ -6836,8 +6836,18 @@ int wolfSSH_SFTP_Get(WOLFSSH* ssh, char* from,
{
DWORD bytesWritten = 0;
if (WriteFile(state->fileHandle, state->r, sz,
&bytesWritten, &state->offset) == 0 ||
(DWORD)sz != bytesWritten) {
&bytesWritten, &state->offset) == 0) {
WLOG(WS_LOG_SFTP, "Error writing to file");
ssh->error = WS_BAD_FILE_E;
ret = WS_FATAL_ERROR;
state->state = STATE_GET_CLEANUP;
break; /* either at end of file or error */
}
if ((DWORD)sz != bytesWritten) {
WLOG(WS_LOG_SFTP, "Error writing to file");
ssh->error = WS_MATCH_KEX_ALGO_E;
ret = WS_FATAL_ERROR;
state->state = STATE_GET_CLEANUP;
break; /* either at end of file or error */
}
}
@ -6859,16 +6869,6 @@ int wolfSSH_SFTP_Get(WOLFSSH* ssh, char* from,
wolfSSH_SFTP_SaveOfst(ssh, from, to, state->gOfst);
}
ssh->sftpInt = 0;
state->state = STATE_GET_CLOSE_LOCAL;
FALL_THROUGH;
case STATE_GET_CLOSE_LOCAL:
WLOG(WS_LOG_SFTP, "SFTP GET STATE: CLOSE LOCAL");
#ifndef USE_WINDOWS_API
WFCLOSE(state->fl);
#else /* USE_WINDOWS_API */
CloseHandle(state->fileHandle);
#endif /* USE_WINDOWS_API */
state->state = STATE_GET_CLOSE_REMOTE;
FALL_THROUGH;
@ -6877,9 +6877,26 @@ int wolfSSH_SFTP_Get(WOLFSSH* ssh, char* from,
ret = wolfSSH_SFTP_Close(ssh,
state->handle, state->handleSz);
if (ret != WS_SUCCESS) {
WLOG(WS_LOG_SFTP, "Error closing handle");
return WS_FATAL_ERROR;
if (ssh->error == WS_WANT_READ ||
ssh->error == WS_WANT_WRITE) {
return WS_FATAL_ERROR;
}
WLOG(WS_LOG_SFTP, "Error closing remote handle");
}
state->state = STATE_GET_CLOSE_LOCAL;
FALL_THROUGH;
case STATE_GET_CLOSE_LOCAL:
WLOG(WS_LOG_SFTP, "SFTP GET STATE: CLOSE LOCAL");
#ifndef USE_WINDOWS_API
WFCLOSE(state->fl);
#else /* USE_WINDOWS_API */
if (CloseHandle(state->fileHandle) == 0) {
WLOG(WS_LOG_SFTP, "Error closing file.");
ret = WS_FATAL_ERROR;
ssh->error = WS_CLOSE_FILE_E;
}
#endif /* USE_WINDOWS_API */
state->state = STATE_GET_CLEANUP;
FALL_THROUGH;

View File

@ -102,8 +102,9 @@ enum WS_ErrorCodes {
WS_SFTP_STATUS_NOT_OK = -62, /* SFTP Status not OK */
WS_SFTP_FILE_DNE = -63, /* SFTP File Does Not Exist */
WS_SIZE_ONLY = -64, /* Only getting the size of buffer needed */
WS_CLOSE_FILE_E = -65, /* Unable to close local file */
WS_LAST_E = -64 /* Update this to indicate last error */
WS_LAST_E = -65 /* Update this to indicate last error */
};