Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions src/wolfscp.c
Original file line number Diff line number Diff line change
Expand Up @@ -883,6 +883,37 @@ int DoScpSource(WOLFSSH* ssh)
return ret;
}

/* Contract is in wolfssh/wolfscp.h. */
int wolfSSH_SCP_accept(WOLFSSH* ssh)
{
int ret;

Comment thread
ejohnstown marked this conversation as resolved.
if (ssh == NULL)
return WS_BAD_ARGUMENT;

/* Clear a want left by the previous call so the retry starts clean,
* the way the other re-entrant entry points do. */
if (ssh->error == WS_WANT_READ || ssh->error == WS_WANT_WRITE)
ssh->error = WS_SUCCESS;

ret = DoScpRequest(ssh);

if (ret >= WS_SUCCESS) {
/* The tail of DoScpRequest() passes a read count through, so treat
* anything non-negative as done the way wolfSSH_accept() does. */
ret = WS_SCP_COMPLETE;
}
else if (ret == WS_FATAL_ERROR && wolfSSH_get_error(ssh) == WS_WANT_READ) {
/* GetInputData() hides a read want behind WS_FATAL_ERROR. Write
* wants come back by value, and a stale WS_WANT_WRITE from an
* accepted short send can outlive a terminal result. */
ret = WS_WANT_READ;
}

return ret;
}


int DoScpRequest(WOLFSSH* ssh)
{
int ret = WS_SUCCESS;
Expand Down
11 changes: 11 additions & 0 deletions wolfssh/wolfscp.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,17 @@ WOLFSSH_API int wolfSSH_SCP_to(WOLFSSH* ssh, const char* src,
const char* dst);
WOLFSSH_API int wolfSSH_SCP_from(WOLFSSH* ssh, const char* src,
const char* dst);
/* Server side. Drives an SCP transfer on a channel whose "exec scp ..."
* command is already bound. This is the same work wolfSSH_accept() does
* through its WS_SCP_INIT re-entry, exposed so an application can start the
* transfer itself; use one or the other, not both. Call it once
* wolfSSH_accept() has returned and the exec channel-request callback has
* reported an SCP command, not from inside that callback.
*
* Returns WS_SCP_COMPLETE when the transfer is done. On a non-blocking
* socket it returns WS_WANT_READ or WS_WANT_WRITE with the transfer part
* done; call it again on the same session until it completes. */
WOLFSSH_API int wolfSSH_SCP_accept(WOLFSSH* ssh);


#ifdef __cplusplus
Expand Down
Loading