How does one append to a remote file using libssh2?
(Nevermind that appending to a file usually isn't a good idea.)
I tried doing a libssh2_sftp_fstat_ex on the remote file to find its size,
then seeking to the end of the file using libssh2_sftp_seek64.
But libssh2_sftp_seek64 isn't a real seek. In this case, it
causes subsequent calls to libssh2_sftp_write to write 0 bytes.
Is there a real remote seek or append capability?
I'm reluctant to open the file with LIBSSH2_FXF_APPEND,
because of this comment in the code:
"Danger will robinson... APPEND doesn't have any effect on OpenSSH servers"
At any rate, I eventually tried the LIBSSH2_FXF_APPEND approach
and got the same problem.
I used a different SSH client to append a file to the same OpenSSH
server and it did work.
Sample code below.
Thanks.
Mark R
remotemode = LIBSSH2_FXF_READ;
if ("put" == settings.action || "append" == settings.action)
remotemode = LIBSSH2_FXF_WRITE | LIBSSH2_FXF_CREAT;
sftp_handle =
libssh2_sftp_open(sftp_session, settings.remotefile.c_str(),
remotemode, 0777);
if (!sftp_handle) {
fprintf(stderr, "Unable to open file with SFTP\n");
goto shutdown;
}
if(settings.debug > 0) fprintf(stderr, "libssh2_sftp_open()
succeeded.\n");
if ("put" == settings.action || "append" == settings.action) {
if("append" == settings.action) {
LIBSSH2_SFTP_ATTRIBUTES attrs;
if(libssh2_sftp_fstat_ex(sftp_handle, &attrs, 0) < 0) {
printf("libssh2_sftp_fstat_ex failed\n");
}
libssh2_sftp_seek64(sftp_handle, attrs.filesize);
printf("Did a seek to position %ld\n", (long) attrs.filesize);
}
hand = open(settings.localfile.c_str(), O_BINARY | O_RDONLY,
_S_IREAD);
if (-1 == hand) {
perror("opening local file");
exit(2);
}
char mem[32500];
long bytes_sent = 0;
do {
/* loop until we fail */
int nbytes = read(hand, mem, sizeof(mem));
if (nbytes > 0) {
filesize += nbytes;
int offset = 0, bytes_to_send = nbytes;
do {
rc = libssh2_sftp_write(sftp_handle, mem + offset,
bytes_to_send);
if (rc < 0) {
printf("libssh2_sftp_write failed with code %d\n", rc);
char *errmsg=NULL;
int errmsg_len=0;
rc = libssh2_session_last_error(session, &errmsg,
&errmsg_len, 0);
printf("libssh2_session_last_error() returned %s\n",
errmsg);
break;
} else if(0==rc) {
printf("libssh2_sftp_write returned 0, probably due to
seek problems.\n");
rc = -1;
break;
}
offset += rc;
bytes_to_send -= rc;
} while (bytes_to_send > 0);
} else {
break;
}
} while (rc >= 0);
}
close(hand);
libssh2_sftp_close(sftp_handle);
_______________________________________________
libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel
Received on 2010-11-24