diff --git a/include/libssh2.h b/include/libssh2.h index 6bce4e26..0dd1beb8 100644 --- a/include/libssh2.h +++ b/include/libssh2.h @@ -372,6 +372,7 @@ typedef struct _LIBSSH2_SK_SIG_INFO { /* flags */ #define LIBSSH2_FLAG_SIGPIPE 1 #define LIBSSH2_FLAG_COMPRESS 2 +#define LIBSSH2_FLAG_QUOTE_PATHS 3 typedef struct _LIBSSH2_SESSION LIBSSH2_SESSION; typedef struct _LIBSSH2_CHANNEL LIBSSH2_CHANNEL; diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h index 01289727..428dad1c 100644 --- a/src/libssh2_priv.h +++ b/src/libssh2_priv.h @@ -578,8 +578,9 @@ struct _LIBSSH2_PUBLICKEY #define LIBSSH2_SCP_RESPONSE_BUFLEN 256 struct flags { - int sigpipe; /* LIBSSH2_FLAG_SIGPIPE */ - int compress; /* LIBSSH2_FLAG_COMPRESS */ + int sigpipe; /* LIBSSH2_FLAG_SIGPIPE */ + int compress; /* LIBSSH2_FLAG_COMPRESS */ + int quote_paths; /* LIBSSH2_FLAG_QUOTE_PATHS */ }; struct _LIBSSH2_SESSION diff --git a/src/scp.c b/src/scp.c index 4fb81b92..6ade9102 100644 --- a/src/scp.c +++ b/src/scp.c @@ -299,9 +299,21 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb) "scp -%sf ", sb ? "p" : ""); cmd_len = strlen((char *)session->scpRecv_command); - cmd_len += shell_quotearg(path, - &session->scpRecv_command[cmd_len], - session->scpRecv_command_len - cmd_len); + + if(!session->flag.quote_paths) { + size_t path_len; + + path_len = strlen(path); + + /* no NUL-termination neeed, so memcpy will do */ + memcpy(&session->scpRecv_command[cmd_len], path, path_len); + cmd_len += path_len; + } + else { + cmd_len += shell_quotearg(path, + &session->scpRecv_command[cmd_len], + session->scpRecv_command_len - cmd_len); + } /* the command to exec should _not_ be NUL-terminated */ session->scpRecv_command_len = cmd_len; @@ -860,9 +872,22 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode, "scp -%st ", (mtime || atime) ? "p" : ""); cmd_len = strlen((char *)session->scpSend_command); - cmd_len += shell_quotearg(path, - &session->scpSend_command[cmd_len], - session->scpSend_command_len - cmd_len); + + if(!session->flag.quote_paths) { + size_t path_len; + + path_len = strlen(path); + + /* no NUL-termination neeed, so memcpy will do */ + memcpy(&session->scpSend_command[cmd_len], path, path_len); + cmd_len += path_len; + + } + else { + cmd_len += shell_quotearg(path, + &session->scpSend_command[cmd_len], + session->scpSend_command_len - cmd_len); + } /* the command to exec should _not_ be NUL-terminated */ session->scpSend_command_len = cmd_len; diff --git a/src/session.c b/src/session.c index eea239e2..35d2d68a 100644 --- a/src/session.c +++ b/src/session.c @@ -524,6 +524,8 @@ libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)), session->api_timeout = 0; /* timeout-free API by default */ session->api_block_mode = 1; /* blocking API by default */ session->packet_read_timeout = LIBSSH2_DEFAULT_READ_TIMEOUT; + session->flag.quote_paths = 1; /* default behavior is to quote paths + for the scp subsystem */ _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "New session resource allocated")); _libssh2_init_if_needed(); @@ -1409,6 +1411,9 @@ libssh2_session_flag(LIBSSH2_SESSION * session, int flag, int value) case LIBSSH2_FLAG_COMPRESS: session->flag.compress = value; break; + case LIBSSH2_FLAG_QUOTE_PATHS: + session->flag.quote_paths = value; + break; default: /* unknown flag */ return LIBSSH2_ERROR_INVAL;