mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-09 18:04:25 +09:00
Implementation of ssh_scp_pull_request
Still needed: code in ssh_scp_init, implementation of ssh_scp_read ssh_scp_request_get_filename, ssh_scp_request_get_size, ssh_scp_request_get_mode, ssh_scp_deny_request ssh_scp_accept_request !!
This commit is contained in:
@@ -120,7 +120,6 @@ typedef struct ssh_agent_struct* ssh_agent;
|
|||||||
typedef struct ssh_session_struct* ssh_session;
|
typedef struct ssh_session_struct* ssh_session;
|
||||||
typedef struct ssh_kbdint_struct* ssh_kbdint;
|
typedef struct ssh_kbdint_struct* ssh_kbdint;
|
||||||
typedef struct ssh_scp_struct* ssh_scp;
|
typedef struct ssh_scp_struct* ssh_scp;
|
||||||
typedef struct ssh_scp_request_struct* ssh_scp_request;
|
|
||||||
|
|
||||||
/* Socket type */
|
/* Socket type */
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@@ -471,10 +470,11 @@ enum {
|
|||||||
|
|
||||||
enum ssh_scp_request_types {
|
enum ssh_scp_request_types {
|
||||||
/** A new directory is going to be pulled */
|
/** A new directory is going to be pulled */
|
||||||
SSH_SCP_REQUEST_NEWDIR,
|
SSH_SCP_REQUEST_NEWDIR=1,
|
||||||
/** A new file is going to be pulled */
|
/** A new file is going to be pulled */
|
||||||
SSH_SCP_REQUEST_NEWFILE
|
SSH_SCP_REQUEST_NEWFILE
|
||||||
};
|
};
|
||||||
|
|
||||||
LIBSSH_API ssh_scp ssh_scp_new(ssh_session session, int mode, const char *location);
|
LIBSSH_API ssh_scp ssh_scp_new(ssh_session session, int mode, const char *location);
|
||||||
LIBSSH_API int ssh_scp_init(ssh_scp scp);
|
LIBSSH_API int ssh_scp_init(ssh_scp scp);
|
||||||
LIBSSH_API int ssh_scp_close(ssh_scp scp);
|
LIBSSH_API int ssh_scp_close(ssh_scp scp);
|
||||||
@@ -483,8 +483,9 @@ LIBSSH_API int ssh_scp_push_directory(ssh_scp scp, const char *dirname, const ch
|
|||||||
LIBSSH_API int ssh_scp_leave_directory(ssh_scp scp);
|
LIBSSH_API int ssh_scp_leave_directory(ssh_scp scp);
|
||||||
LIBSSH_API int ssh_scp_push_file(ssh_scp scp, const char *filename, size_t size, const char *perms);
|
LIBSSH_API int ssh_scp_push_file(ssh_scp scp, const char *filename, size_t size, const char *perms);
|
||||||
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 ssh_scp_request ssh_scp_pull_request(ssh_scp scp);
|
LIBSSH_API int ssh_scp_pull_request(ssh_scp scp);
|
||||||
LIBSSH_API int ssh_scp_deny_request(ssh_scp scp, ssh_scp_request request, const char *reason);
|
LIBSSH_API int ssh_scp_deny_request(ssh_scp scp, const char *reason);
|
||||||
|
LIBSSH_API int ssh_scp_accept_request(ssh_scp scp);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -356,6 +356,7 @@ enum ssh_scp_states {
|
|||||||
SSH_SCP_WRITE_INITED, //Gave our intention to write
|
SSH_SCP_WRITE_INITED, //Gave our intention to write
|
||||||
SSH_SCP_WRITE_WRITING,//File was opened and currently writing
|
SSH_SCP_WRITE_WRITING,//File was opened and currently writing
|
||||||
SSH_SCP_READ_INITED, //Gave our intention to read
|
SSH_SCP_READ_INITED, //Gave our intention to read
|
||||||
|
SSH_SCP_READ_REQUESTED, //We got a read request
|
||||||
SSH_SCP_READ_READING, //File is opened and reading
|
SSH_SCP_READ_READING, //File is opened and reading
|
||||||
SSH_SCP_ERROR //Something bad happened
|
SSH_SCP_ERROR //Something bad happened
|
||||||
};
|
};
|
||||||
@@ -368,16 +369,9 @@ struct ssh_scp_struct {
|
|||||||
enum ssh_scp_states state;
|
enum ssh_scp_states state;
|
||||||
size_t filelen;
|
size_t filelen;
|
||||||
size_t processed;
|
size_t processed;
|
||||||
};
|
enum ssh_scp_request_types request_type;
|
||||||
|
char *request_name;
|
||||||
|
char *request_mode;
|
||||||
struct ssh_scp_request_struct {
|
|
||||||
ssh_scp scp;
|
|
||||||
enum ssh_scp_request_types type;
|
|
||||||
char *name;
|
|
||||||
char *mode;
|
|
||||||
size_t size;
|
|
||||||
int acked;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ssh_message_struct;
|
struct ssh_message_struct;
|
||||||
@@ -869,8 +863,7 @@ void message_handle(SSH_SESSION *session, uint32_t type);
|
|||||||
int ssh_execute_message_callbacks(SSH_SESSION *session);
|
int ssh_execute_message_callbacks(SSH_SESSION *session);
|
||||||
|
|
||||||
/* scp.c */
|
/* scp.c */
|
||||||
|
int ssh_scp_read_string(ssh_scp scp, char *buffer, size_t len);
|
||||||
ssh_scp_request ssh_scp_request_new(void);
|
|
||||||
|
|
||||||
/* log.c */
|
/* log.c */
|
||||||
|
|
||||||
|
|||||||
109
libssh/scp.c
109
libssh/scp.c
@@ -120,6 +120,8 @@ void ssh_scp_free(ssh_scp scp){
|
|||||||
if(scp->channel)
|
if(scp->channel)
|
||||||
channel_free(scp->channel);
|
channel_free(scp->channel);
|
||||||
SAFE_FREE(scp->location);
|
SAFE_FREE(scp->location);
|
||||||
|
SAFE_FREE(scp->request_mode);
|
||||||
|
SAFE_FREE(scp->request_name);
|
||||||
SAFE_FREE(scp);
|
SAFE_FREE(scp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,11 +269,106 @@ int ssh_scp_write(ssh_scp scp, const void *buffer, size_t len){
|
|||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssh_scp_request ssh_scp_request_new(void){
|
/**
|
||||||
ssh_scp_request r=malloc(sizeof(struct ssh_scp_request_struct));
|
* @brief reads a string on a channel, terminated by '\n'
|
||||||
if(r==NULL)
|
* @param buffer pointer to a buffer to place the string
|
||||||
return NULL;
|
* @param len size of the buffer in bytes. If the string is bigger
|
||||||
ZERO_STRUCTP(r);
|
* than len-1, only len-1 bytes are read and the string
|
||||||
return r;
|
* is null-terminated.
|
||||||
|
* @returns SSH_OK The string was read
|
||||||
|
* @returns SSH_ERROR Error happened while reading
|
||||||
|
*/
|
||||||
|
int ssh_scp_read_string(ssh_scp scp, char *buffer, size_t len){
|
||||||
|
size_t r=0;
|
||||||
|
int err=SSH_OK;
|
||||||
|
while(r<len-1){
|
||||||
|
err=channel_read(scp->channel,&buffer[r],1,0);
|
||||||
|
if(err==SSH_ERROR){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(err==0){
|
||||||
|
ssh_set_error(scp->session,SSH_FATAL,"End of file while reading string");
|
||||||
|
err=SSH_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
r++;
|
||||||
|
if(buffer[r-1] == '\n')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
buffer[r]=0;
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief waits for a scp request (file, directory)
|
||||||
|
* @returns SSH_ERROR Some error happened
|
||||||
|
* @returns SSH_SCP_REQUEST_FILE The other side is sending a file
|
||||||
|
* @returns SSH_SCP_REQUEST_DIRECTORY The other side is sending a directory
|
||||||
|
* @returns SSH_SCP_REQUEST_END_DIRECTORY The other side has finished with the current directory
|
||||||
|
* @see ssh_scp_read
|
||||||
|
* @see ssh_scp_deny_request
|
||||||
|
* @see ssh_scp_accept_request
|
||||||
|
*/
|
||||||
|
int ssh_scp_pull_request(ssh_scp scp){
|
||||||
|
char buffer[4096];
|
||||||
|
char *mode=NULL;
|
||||||
|
char *p,*tmp;
|
||||||
|
size_t size;
|
||||||
|
char *name=NULL;
|
||||||
|
int err;
|
||||||
|
if(scp->state != SSH_SCP_READ_INITED){
|
||||||
|
ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_pull_request called under invalid state");
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
err=ssh_scp_read_string(scp,buffer,sizeof(buffer));
|
||||||
|
if(err==SSH_ERROR)
|
||||||
|
return err;
|
||||||
|
switch(buffer[0]){
|
||||||
|
case 'C':
|
||||||
|
/* File */
|
||||||
|
case 'D':
|
||||||
|
/* Directory */
|
||||||
|
p=strchr(buffer,' ');
|
||||||
|
if(p==NULL)
|
||||||
|
goto error;
|
||||||
|
*p='\0';
|
||||||
|
p++;
|
||||||
|
mode=strdup(&buffer[1]);
|
||||||
|
tmp=p;
|
||||||
|
p=strchr(p,' ');
|
||||||
|
if(p==NULL)
|
||||||
|
goto error;
|
||||||
|
*p=0;
|
||||||
|
size=strtoull(tmp,NULL,10);
|
||||||
|
p++;
|
||||||
|
tmp=p;
|
||||||
|
p=strchr(p,'\n');
|
||||||
|
if(p==NULL)
|
||||||
|
goto error;
|
||||||
|
*p=0;
|
||||||
|
name=strdup(tmp);
|
||||||
|
scp->request_mode=mode;
|
||||||
|
scp->request_name=name;
|
||||||
|
if(buffer[0]=='C'){
|
||||||
|
scp->filelen=size;
|
||||||
|
scp->request_type=SSH_SCP_REQUEST_NEWFILE;
|
||||||
|
} else {
|
||||||
|
scp->filelen='0';
|
||||||
|
scp->request_type=SSH_SCP_REQUEST_NEWDIR;
|
||||||
|
}
|
||||||
|
scp->state=SSH_SCP_READ_REQUESTED;
|
||||||
|
return scp->request_type;
|
||||||
|
break;
|
||||||
|
case 'T':
|
||||||
|
/* Timestamp */
|
||||||
|
default:
|
||||||
|
ssh_set_error(scp->session,SSH_FATAL,"Unhandled message: %s",buffer);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* a parsing error occured */
|
||||||
|
error:
|
||||||
|
SAFE_FREE(name);
|
||||||
|
SAFE_FREE(mode);
|
||||||
|
ssh_set_error(scp->session,SSH_FATAL,"Parsing error while parsing message: %s",buffer);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user