I want to copy a file from a client to a remote server, but I don't understand how to do it with the libssh library SFTP API.
The situation is that: The SSH session is open and the SFTP session is open too, I can create a file and write in it from the client to the server with the integrated function of libssh.
I did not find an easy way to copy a file from the client to the server with a simple function like sftp_transfer(sourceFile(like c:\my document\hello world.txt),RemoteFile(/home/user/hello world.txt),right(read and write)) ?
With what I have understood from the tutorial it is first creating a file in the remote location (server) then it is opening this file with this line of code:
file = sftp_open(sftp, "/home/helloworld.txt",access_type,1);
After that the file is created on the server, and then it is writing into this created file with a buffer:
const char *helloworld = "Hello, World!\n";
int length = strlen(helloworld);
nwritten = sftp_write(file, helloworld, length);
My question is now if I have a file for example a .doc file and I want to transfer/upload that file from c:\mydocument\document.doc
to remote the remote server /home/user/document.doc
, how can I do it with this method ?
How can I put this file into the sftp_write()
function to send it like the helloworld in the sample function?
I may be not good enough in programming to understand, but I really tried to understand it and I'm stuck with it.
Thanks in advance for your help
See below a sample of the code I used to test:
// Set variable for the communication
char buffer[256];
unsigned int nbytes;
//create a file to send by SFTP
int access_type = O_WRONLY | O_CREAT | O_TRUNC;
const char *helloworld = "Hello, World!\n";
int length = strlen(helloworld);
//Open a SFTP session
sftp = sftp_new(my_ssh_session);
if (sftp == NULL)
{
fprintf(stderr, "Error allocating SFTP session: %s\n",
ssh_get_error(my_ssh_session));
return SSH_ERROR;
}
// Initialize the SFTP session
rc = sftp_init(sftp);
if (rc != SSH_OK)
{
fprintf(stderr, "Error initializing SFTP session: %s.\n",
sftp_get_error(sftp));
sftp_free(sftp);
return rc;
}
//Open the file into the remote side
file = sftp_open(sftp, "/home/helloworld.txt",access_type,1);
if (file == NULL)
{
fprintf(stderr, "Can't open file for writing: %s\n",ssh_get_error(my_ssh_session));
return SSH_ERROR;
}
//Write the file created with what's into the buffer
nwritten = sftp_write(file, helloworld, length);
if (nwritten != length)
{
fprintf(stderr, "Can't write data to file: %s\n",
ssh_get_error(my_ssh_session));
sftp_close(file);
return SSH_ERROR;
}
Open the file in the usual way (using C++'s fstream or C's stdio.h), read its contents to a buffer, and pass the buffer to sftp_write
.
Something like this:
ifstream fin("file.doc", ios::binary);
if (fin) {
fin.seekg(0, ios::end);
ios::pos_type bufsize = fin.tellg(); // get file size in bytes
fin.seekg(0); // rewind to beginning of file
std::vector<char> buf(bufsize); // allocate buffer
fin.read(buf.data(), bufsize); // read file contents into buffer
sftp_write(file, buf.data(), bufsize); // write buffer to remote file
}
Note that this is a very simple implementation. You should probably open the remote file in append mode, then write the data in chunks instead of sending single huge blob of data.
The following example uses ifstream
in a loop to avoid loading a whole file into a memory (as the accepted answer does):
ifstream fin("C:\\myfile.zip", ios::binary);
while (fin)
{
constexpr size_t max_xfer_buf_size = 10240
char buffer[max_xfer_buf_size];
fin.read(buffer, sizeof(buffer));
if (fin.gcount() > 0)
{
ssize_t nwritten = sftp_write(NULL, buffer, fin.gcount());
if (nwritten != fin.gcount())
{
fprintf(stderr, "Error writing to file: %s\n", ssh_get_error(ssh_session));
sftp_close(file);
return 1;
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With