1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-12-02 01:17:52 +03:00

Improve sftp_write().

git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@604 7dcaeef0-15fb-0310-b436-a5af3365683c
This commit is contained in:
Andreas Schneider
2009-04-24 10:08:46 +00:00
parent b0778ca169
commit 29e6f140fa

View File

@@ -1663,59 +1663,84 @@ int sftp_async_read(SFTP_FILE *file, void *data, u32 size, u32 id){
return SSH_ERROR; return SSH_ERROR;
} }
ssize_t sftp_write(SFTP_FILE *file, const void *buf, size_t count){ ssize_t sftp_write(SFTP_FILE *file, const void *buf, size_t count) {
SFTP_MESSAGE *msg=NULL; SFTP_SESSION *sftp = file->sftp;
STATUS_MESSAGE *status; SFTP_MESSAGE *msg = NULL;
STRING *datastring; STATUS_MESSAGE *status;
SFTP_SESSION *sftp=file->sftp; STRING *datastring;
int id; BUFFER *buffer;
BUFFER *buffer; u32 id;
buffer=buffer_new(); int len;
id=sftp_get_new_id(file->sftp);
buffer_add_u32(buffer,id); buffer = buffer_new();
buffer_add_ssh_string(buffer,file->handle); if (buffer == NULL) {
buffer_add_u64(buffer,htonll(file->offset)); return -1;
datastring=string_new(count); }
string_fill(datastring, buf, count);
buffer_add_ssh_string(buffer,datastring); datastring = string_new(count);
free(datastring); if (datastring == NULL) {
if((u32) sftp_packet_write(file->sftp,SSH_FXP_WRITE,buffer)
!= buffer_get_len(buffer)) {
ssh_log(sftp->session, SSH_LOG_PACKET,
"sftp_packet_write did not write as much data as expected");
}
buffer_free(buffer); buffer_free(buffer);
while(!msg){ return -1;
if(sftp_read_and_dispatch(file->sftp)) }
/* something nasty has happened */ string_fill(datastring, buf, count);
return -1;
msg=sftp_dequeue(file->sftp,id); id = sftp_get_new_id(file->sftp);
if (buffer_add_u32(buffer, id) < 0 ||
buffer_add_ssh_string(buffer, file->handle) < 0 ||
buffer_add_u64(buffer, htonll(file->offset)) < 0 ||
buffer_add_ssh_string(buffer, datastring) < 0) {
buffer_free(buffer);
string_free(datastring);
return -1;
}
string_free(datastring);
len = sftp_packet_write(file->sftp, SSH_FXP_WRITE, buffer);
buffer_free(buffer);
if (len < 0) {
return -1;
} else if ((u32) len != buffer_get_len(buffer)) {
ssh_log(sftp->session, SSH_LOG_PACKET,
"Could not write as much data as expected");
}
while (msg == NULL) {
if (sftp_read_and_dispatch(file->sftp) < 0) {
/* something nasty has happened */
return -1;
} }
switch (msg->packet_type){ msg = sftp_dequeue(file->sftp, id);
case SSH_FXP_STATUS: }
status=parse_status_msg(msg);
sftp_message_free(msg); switch (msg->packet_type) {
if(!status) case SSH_FXP_STATUS:
return -1; status = parse_status_msg(msg);
sftp_set_error(sftp, status->status); sftp_message_free(msg);
switch (status->status) { if (status == NULL) {
case SSH_FX_OK: return -1;
file->offset += count; }
status_msg_free(status); sftp_set_error(sftp, status->status);
return count; switch (status->status) {
default: case SSH_FX_OK:
break; file->offset += count;
} status_msg_free(status);
ssh_set_error(sftp->session,SSH_REQUEST_DENIED,"sftp server : %s",status->errormsg); return count;
file->offset += count;
status_msg_free(status);
return -1;
default: default:
ssh_set_error(sftp->session,SSH_FATAL,"Received message %d during write!",msg->packet_type); break;
sftp_message_free(msg); }
return -1; ssh_set_error(sftp->session, SSH_REQUEST_DENIED,
} "SFTP server: %s", status->errormsg);
return -1; /* not reached */ file->offset += count;
status_msg_free(status);
return -1;
default:
ssh_set_error(sftp->session, SSH_FATAL,
"Received message %d during write!", msg->packet_type);
sftp_message_free(msg);
return -1;
}
return -1; /* not reached */
} }
/* Seek to a specific location in a file. */ /* Seek to a specific location in a file. */