1
1

Add better error detection + EOF request

Этот коммит содержится в:
Aris Adamantiadis 2009-09-06 14:26:33 +03:00
родитель 480dfd9050
Коммит 7ff80a2666
3 изменённых файлов: 70 добавлений и 7 удалений

Просмотреть файл

@ -474,7 +474,9 @@ enum ssh_scp_request_types {
/** A new directory is going to be pulled */
SSH_SCP_REQUEST_NEWDIR=1,
/** A new file is going to be pulled */
SSH_SCP_REQUEST_NEWFILE
SSH_SCP_REQUEST_NEWFILE,
/** End of requests */
SSH_SCP_REQUEST_EOF
};
LIBSSH_API ssh_scp ssh_scp_new(ssh_session session, int mode, const char *location);

Просмотреть файл

@ -358,7 +358,8 @@ enum ssh_scp_states {
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_ERROR //Something bad happened
SSH_SCP_ERROR, //Something bad happened
SSH_SCP_TERMINATED //Transfer finished
};
struct ssh_scp_struct {
@ -866,6 +867,7 @@ int ssh_execute_message_callbacks(SSH_SESSION *session);
int ssh_scp_read_string(ssh_scp scp, char *buffer, size_t len);
int ssh_scp_integer_mode(const char *mode);
char *ssh_scp_string_mode(int mode);
int ssh_scp_response(ssh_scp scp, char **response);
/* log.c */

Просмотреть файл

@ -234,6 +234,48 @@ int ssh_scp_push_file(ssh_scp scp, const char *filename, size_t size, int mode){
return SSH_OK;
}
/** @brief waits for a response of the scp server
* @internal
* @param response pointer where the response message must be
* copied if any. This pointer must then be free'd.
* @returns the return code.
* @returns SSH_ERROR a error occured
*/
int ssh_scp_response(ssh_scp scp, char **response){
unsigned char code;
int r;
char msg[128];
r=channel_read(scp->channel,&code,1,0);
if(r == SSH_ERROR)
return SSH_ERROR;
if(code == 0)
return 0;
if(code > 2){
ssh_set_error(scp->session,SSH_FATAL, "SCP: invalid status code %ud received", code);
scp->state=SSH_SCP_ERROR;
return SSH_ERROR;
}
r=ssh_scp_read_string(scp,msg,sizeof(msg));
if(r==SSH_ERROR)
return r;
/* Warning */
if(code == 1){
ssh_set_error(scp->session,SSH_REQUEST_DENIED, "SCP: Warning: status code 1 received: %s", msg);
ssh_log(scp->session,SSH_LOG_RARE,"SCP: Warning: status code 1 received: %s", msg);
if(response)
*response=strdup(msg);
return 1;
}
if(code == 2){
ssh_set_error(scp->session,SSH_FATAL, "SCP: Error: status code 2 received: %s", msg);
if(response)
*response=strdup(msg);
return 2;
}
/* Not reached */
return SSH_ERROR;
}
/** @brief Write into a remote scp file
* @param buffer the buffer to write
* @param len the number of bytes to write
@ -330,8 +372,13 @@ int ssh_scp_pull_request(ssh_scp scp){
return SSH_ERROR;
}
err=ssh_scp_read_string(scp,buffer,sizeof(buffer));
if(err==SSH_ERROR)
if(err==SSH_ERROR){
if(channel_is_eof(scp->channel)){
scp->state=SSH_SCP_TERMINATED;
return SSH_SCP_REQUEST_EOF;
}
return err;
}
p=strchr(buffer,'\n');
if(p!=NULL)
*p='\0';
@ -373,13 +420,13 @@ int ssh_scp_pull_request(ssh_scp scp){
/* Timestamp */
break;
case 0x1:
ssh_set_error(scp->session,SSH_REQUEST_DENIED,"SCP: %s",&buffer[1]);
ssh_set_error(scp->session,SSH_REQUEST_DENIED,"SCP: Warning: %s",&buffer[1]);
return SSH_ERROR;
case 0x2:
ssh_set_error(scp->session,SSH_FATAL,"SCP: %s",&buffer[1]);
ssh_set_error(scp->session,SSH_FATAL,"SCP: Error: %s",&buffer[1]);
return SSH_ERROR;
default:
ssh_set_error(scp->session,SSH_FATAL,"Unhandled message: %s",buffer);
ssh_set_error(scp->session,SSH_FATAL,"Unhandled message: (%d)%s",buffer[0],buffer);
return SSH_ERROR;
}
@ -449,6 +496,7 @@ int ssh_scp_accept_request(ssh_scp scp){
*/
int ssh_scp_read(ssh_scp scp, void *buffer, size_t size){
int r;
int code;
if(scp->state == SSH_SCP_READ_REQUESTED && scp->request_type == SSH_SCP_REQUEST_NEWFILE){
r=ssh_scp_accept_request(scp);
if(r==SSH_ERROR)
@ -472,7 +520,18 @@ int ssh_scp_read(ssh_scp scp, void *buffer, size_t size){
/* Check if we arrived at end of file */
if(scp->processed == scp->filelen) {
scp->processed=scp->filelen=0;
scp->state=SSH_SCP_READ_INITED;
channel_write(scp->channel,"",1);
code=ssh_scp_response(scp,NULL);
if(code == 0){
scp->state=SSH_SCP_READ_INITED;
return r;
}
if(code==1){
scp->state=SSH_SCP_READ_INITED;
return SSH_ERROR;
}
scp->state=SSH_SCP_ERROR;
return SSH_ERROR;
}
return r;
}