diff --git a/include/libssh/sftp.h b/include/libssh/sftp.h index 5a21a959..d370f0ec 100644 --- a/include/libssh/sftp.h +++ b/include/libssh/sftp.h @@ -133,6 +133,7 @@ struct sftp_client_message_struct { ssh_buffer attrbuf; /* used by sftp_reply_attrs */ ssh_string data; /* can be newpath of rename() */ ssh_buffer complete_message; /* complete message in case of retransmission*/ + char *str_data; /* cstring version of data */ }; struct sftp_request_queue_struct { @@ -203,6 +204,19 @@ struct sftp_statvfs_struct { */ LIBSSH_API sftp_session sftp_new(ssh_session session); +/** + * @brief Start a new sftp session with an existing channel. + * + * @param session The ssh session to use. + * @param channel An open session channel with subsystem already allocated + * + * @return A new sftp session or NULL on error. + * + * @see sftp_free() + */ +LIBSSH_API sftp_session sftp_new_channel(ssh_session session, ssh_channel channel); + + /** * @brief Close and deallocate a sftp session. * @@ -830,7 +844,7 @@ LIBSSH_API void sftp_client_message_free(sftp_client_message msg); LIBSSH_API uint8_t sftp_client_message_get_type(sftp_client_message msg); LIBSSH_API const char *sftp_client_message_get_filename(sftp_client_message msg); LIBSSH_API void sftp_client_message_set_filename(sftp_client_message msg, const char *newname); -LIBSSH_API char *sftp_client_message_get_data(sftp_client_message msg); +LIBSSH_API const char *sftp_client_message_get_data(sftp_client_message msg); LIBSSH_API uint32_t sftp_client_message_get_flags(sftp_client_message msg); LIBSSH_API int sftp_send_client_message(sftp_session sftp, sftp_client_message msg); int sftp_reply_name(sftp_client_message msg, const char *name, diff --git a/src/sftp.c b/src/sftp.c index ee86107b..73b1f301 100644 --- a/src/sftp.c +++ b/src/sftp.c @@ -149,6 +149,37 @@ sftp_session sftp_new(ssh_session session){ return sftp; } +sftp_session sftp_new_channel(ssh_session session, ssh_channel channel){ + sftp_session sftp; + + if (session == NULL) { + return NULL; + } + enter_function(); + + sftp = malloc(sizeof(struct sftp_session_struct)); + if (sftp == NULL) { + ssh_set_error_oom(session); + leave_function(); + return NULL; + } + ZERO_STRUCTP(sftp); + + sftp->ext = sftp_ext_new(); + if (sftp->ext == NULL) { + ssh_set_error_oom(session); + SAFE_FREE(sftp); + leave_function(); + return NULL; + } + + sftp->session = session; + sftp->channel = channel; + + leave_function(); + return sftp; +} + #ifdef WITH_SERVER sftp_session sftp_server_new(ssh_session session, ssh_channel chan){ sftp_session sftp = NULL; diff --git a/src/sftpserver.c b/src/sftpserver.c index 431d1d82..0986b6ce 100644 --- a/src/sftpserver.c +++ b/src/sftpserver.c @@ -263,9 +263,10 @@ void sftp_client_message_set_filename(sftp_client_message msg, const char *newna msg->filename = strdup(newname); } -char *sftp_client_message_get_data(sftp_client_message msg){ - char *str = ssh_string_to_char(msg->data); - return str; +const char *sftp_client_message_get_data(sftp_client_message msg){ + if (msg->str_data == NULL) + msg->str_data = ssh_string_to_char(msg->data); + return msg->str_data; } uint32_t sftp_client_message_get_flags(sftp_client_message msg){ @@ -282,6 +283,7 @@ void sftp_client_message_free(sftp_client_message msg) { ssh_string_free(msg->handle); sftp_attributes_free(msg->attr); ssh_buffer_free(msg->complete_message); + SAFE_FREE(msg->str_data); ZERO_STRUCTP(msg); SAFE_FREE(msg); }