mirror of
https://git.libssh.org/projects/libssh.git
synced 2025-07-29 13:01:13 +03:00
scp: Support huge files by changing size to 64-bit type.
Signed-off-by: Mark Riordan <mriordan@ipswitch.com> Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
committed by
Andreas Schneider
parent
3a77f2aebe
commit
96d5f13813
@ -430,10 +430,11 @@ LIBSSH_API ssh_scp ssh_scp_new(ssh_session session, int mode, const char *locati
|
|||||||
LIBSSH_API int ssh_scp_pull_request(ssh_scp scp);
|
LIBSSH_API int ssh_scp_pull_request(ssh_scp scp);
|
||||||
LIBSSH_API int ssh_scp_push_directory(ssh_scp scp, const char *dirname, int mode);
|
LIBSSH_API int ssh_scp_push_directory(ssh_scp scp, const char *dirname, int mode);
|
||||||
LIBSSH_API int ssh_scp_push_file(ssh_scp scp, const char *filename, size_t size, int perms);
|
LIBSSH_API int ssh_scp_push_file(ssh_scp scp, const char *filename, size_t size, int perms);
|
||||||
|
LIBSSH_API int ssh_scp_push_file64(ssh_scp scp, const char *filename, uint64_t size, int perms);
|
||||||
LIBSSH_API int ssh_scp_read(ssh_scp scp, void *buffer, size_t size);
|
LIBSSH_API int ssh_scp_read(ssh_scp scp, void *buffer, size_t size);
|
||||||
LIBSSH_API const char *ssh_scp_request_get_filename(ssh_scp scp);
|
LIBSSH_API const char *ssh_scp_request_get_filename(ssh_scp scp);
|
||||||
LIBSSH_API int ssh_scp_request_get_permissions(ssh_scp scp);
|
LIBSSH_API int ssh_scp_request_get_permissions(ssh_scp scp);
|
||||||
LIBSSH_API size_t ssh_scp_request_get_size(ssh_scp scp);
|
LIBSSH_API uint64_t ssh_scp_request_get_size(ssh_scp scp);
|
||||||
LIBSSH_API const char *ssh_scp_request_get_warning(ssh_scp scp);
|
LIBSSH_API const char *ssh_scp_request_get_warning(ssh_scp scp);
|
||||||
LIBSSH_API int ssh_scp_write(ssh_scp scp, const void *buffer, size_t len);
|
LIBSSH_API int ssh_scp_write(ssh_scp scp, const void *buffer, size_t len);
|
||||||
LIBSSH_API int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd,
|
LIBSSH_API int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd,
|
||||||
|
@ -40,8 +40,8 @@ struct ssh_scp_struct {
|
|||||||
ssh_channel channel;
|
ssh_channel channel;
|
||||||
char *location;
|
char *location;
|
||||||
enum ssh_scp_states state;
|
enum ssh_scp_states state;
|
||||||
size_t filelen;
|
uint64_t filelen;
|
||||||
size_t processed;
|
uint64_t processed;
|
||||||
enum ssh_scp_request_types request_type;
|
enum ssh_scp_request_types request_type;
|
||||||
char *request_name;
|
char *request_name;
|
||||||
char *warning;
|
char *warning;
|
||||||
|
35
src/scp.c
35
src/scp.c
@ -263,7 +263,7 @@ int ssh_scp_push_directory(ssh_scp scp, const char *dirname, int mode){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize the sending of a file to a scp in sink mode.
|
* @brief Initialize the sending of a file to a scp in sink mode, using a 64-bit size.
|
||||||
*
|
*
|
||||||
* @param[in] scp The scp handle.
|
* @param[in] scp The scp handle.
|
||||||
*
|
*
|
||||||
@ -276,8 +276,10 @@ int ssh_scp_push_directory(ssh_scp scp, const char *dirname, int mode){
|
|||||||
*
|
*
|
||||||
* @returns SSH_OK if the file is ready to be sent, SSH_ERROR if an
|
* @returns SSH_OK if the file is ready to be sent, SSH_ERROR if an
|
||||||
* error occured.
|
* error occured.
|
||||||
|
*
|
||||||
|
* @see ssh_scp_push_file()
|
||||||
*/
|
*/
|
||||||
int ssh_scp_push_file(ssh_scp scp, const char *filename, size_t size, int mode){
|
int ssh_scp_push_file64(ssh_scp scp, const char *filename, uint64_t size, int mode){
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
int r;
|
int r;
|
||||||
uint8_t code;
|
uint8_t code;
|
||||||
@ -317,6 +319,25 @@ int ssh_scp_push_file(ssh_scp scp, const char *filename, size_t size, int mode){
|
|||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the sending of a file to a scp in sink mode.
|
||||||
|
*
|
||||||
|
* @param[in] scp The scp handle.
|
||||||
|
*
|
||||||
|
* @param[in] filename The name of the file being sent. It should not contain
|
||||||
|
* any path indicator
|
||||||
|
*
|
||||||
|
* @param[in] size Exact size in bytes of the file being sent.
|
||||||
|
*
|
||||||
|
* @param[in] mode The UNIX permissions for the new file, e.g. 0644.
|
||||||
|
*
|
||||||
|
* @returns SSH_OK if the file is ready to be sent, SSH_ERROR if an
|
||||||
|
* error occured.
|
||||||
|
*/
|
||||||
|
int ssh_scp_push_file(ssh_scp scp, const char *filename, size_t size, int mode){
|
||||||
|
return ssh_scp_push_file64(scp, filename, (uint64_t) size, mode);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*
|
*
|
||||||
@ -389,7 +410,7 @@ int ssh_scp_write(ssh_scp scp, const void *buffer, size_t len){
|
|||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
if(scp->processed + len > scp->filelen)
|
if(scp->processed + len > scp->filelen)
|
||||||
len = scp->filelen - scp->processed;
|
len = (size_t) (scp->filelen - scp->processed);
|
||||||
/* hack to avoid waiting for window change */
|
/* hack to avoid waiting for window change */
|
||||||
ssh_channel_poll(scp->channel,0);
|
ssh_channel_poll(scp->channel,0);
|
||||||
w=ssh_channel_write(scp->channel,buffer,len);
|
w=ssh_channel_write(scp->channel,buffer,len);
|
||||||
@ -476,7 +497,7 @@ int ssh_scp_pull_request(ssh_scp scp){
|
|||||||
char buffer[4096];
|
char buffer[4096];
|
||||||
char *mode=NULL;
|
char *mode=NULL;
|
||||||
char *p,*tmp;
|
char *p,*tmp;
|
||||||
size_t size;
|
uint64_t size;
|
||||||
char *name=NULL;
|
char *name=NULL;
|
||||||
int err;
|
int err;
|
||||||
if(scp==NULL)
|
if(scp==NULL)
|
||||||
@ -514,7 +535,7 @@ int ssh_scp_pull_request(ssh_scp scp){
|
|||||||
if(p==NULL)
|
if(p==NULL)
|
||||||
goto error;
|
goto error;
|
||||||
*p=0;
|
*p=0;
|
||||||
size = (size_t) strtoull(tmp,NULL,10);
|
size = strtoull(tmp,NULL,10);
|
||||||
p++;
|
p++;
|
||||||
name=strdup(p);
|
name=strdup(p);
|
||||||
SAFE_FREE(scp->request_name);
|
SAFE_FREE(scp->request_name);
|
||||||
@ -643,7 +664,7 @@ int ssh_scp_read(ssh_scp scp, void *buffer, size_t size){
|
|||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
if(scp->processed + size > scp->filelen)
|
if(scp->processed + size > scp->filelen)
|
||||||
size = scp->filelen - scp->processed;
|
size = (size_t) (scp->filelen - scp->processed);
|
||||||
if(size > 65536)
|
if(size > 65536)
|
||||||
size=65536; /* avoid too large reads */
|
size=65536; /* avoid too large reads */
|
||||||
r=ssh_channel_read(scp->channel,buffer,size,0);
|
r=ssh_channel_read(scp->channel,buffer,size,0);
|
||||||
@ -701,7 +722,7 @@ int ssh_scp_request_get_permissions(ssh_scp scp){
|
|||||||
*
|
*
|
||||||
* @returns The numeric size of the file being read.
|
* @returns The numeric size of the file being read.
|
||||||
*/
|
*/
|
||||||
size_t ssh_scp_request_get_size(ssh_scp scp){
|
uint64_t ssh_scp_request_get_size(ssh_scp scp){
|
||||||
if(scp==NULL)
|
if(scp==NULL)
|
||||||
return 0;
|
return 0;
|
||||||
return scp->filelen;
|
return scp->filelen;
|
||||||
|
Reference in New Issue
Block a user