title: File download with libssh SFTP is corrupt
body: <p>I'm using libssh to download a file from a Debian Linux server on my local Windows machine, the program is running without error but the downloaded file is corrupted. When I download via <code>pscp</code> it works, I don't know if I'm doing something wrong with regards to the buffer or something else.</p>
  <p>The sizes of the generated files are identical, when I download it via other tools like FileZilla or WinSCP everything goes well. The file doesn't corrupt anymore. When I run my code then it gets corrupted</p>
  <p>I'm running this code on Windows 10 with Visual Studio 2019. After messing with this code a lot I think the problem is with the <code>write</code> file writing function when I open the generated file in a hex editor I see differences in bytes only the end of the file that stays the same.</p>
  <p>I ended up posting the Dart version of the code previously, but the C version is almost identical to the Dart version.</p>
  <pre class="lang-c prettyprint-override"><code>#define _CRT_SECURE_NO_WARNINGS
  #define _CRT_NONSTDC_NO_DEPRECATE
  #include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;iostream&gt;
  #include &lt;stdexcept&gt;
  #include &lt;string.h&gt;
  #include &lt;exception&gt;
  #include &lt;fstream&gt;
  #include &lt;libssh/callbacks.h&gt;
  #include &lt;libssh/libssh.h&gt;
  #include &lt;libssh/sftp.h&gt;
  #include &quot;custom_exception.cpp&quot;
  #include &lt;sys/stat.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;fcntl.h&gt;
  #include &lt;io.h&gt;
  #include &lt;time.h&gt;
  #include &lt;chrono&gt;
  
  using std::chrono::high_resolution_clock;
  using std::chrono::duration_cast;
  using std::chrono::duration;
  using std::chrono::milliseconds;
  
  //using namespace std;
  using std::string;
  using std::cout;
  using std::endl;
  using std::cin;
  
  
  // Good chunk size
  #define MAX_XFER_BUF_SIZE 16384
  int sftpDownloadFileTo(ssh_session session, const char* fullRemotePath, const char* fullLocalPath)
  {
       
      int access_type;
      sftp_file file;
      char buffer[MAX_XFER_BUF_SIZE * 8];//128KB
      ssize_t nbytes, nwritten, rc;
      int fd;
      access_type = O_RDONLY;
  
       sftp_session sftp = sftp_new(session);
      if (sftp == NULL)
      {
          fprintf(stderr, &quot;Error allocating SFTP session: %s\n&quot;,
              ssh_get_error(session));
          return SSH_ERROR;
      }
      rc = sftp_init(sftp);
      if (rc != SSH_OK)
      {
          fprintf(stderr, &quot;Error initializing SFTP session: %d.\n&quot;,
              sftp_get_error(sftp));
          sftp_free(sftp);
          return rc;
      }
          
  
      file = sftp_open(sftp, fullRemotePath, access_type, 0);
  
      if (file == NULL) {
          fprintf(stderr, &quot;Can't open file for reading: %s\n&quot;, ssh_get_error(session));
          return SSH_ERROR;
      }
  
      fd = open(fullLocalPath, O_CREAT | O_RDWR, 0777);
      if (fd &lt; 0) {
          fprintf(stderr, &quot;Can't open file for writing: %s\n&quot;,
              strerror(errno));
          return SSH_ERROR;
      }
  
      for (;;) {
          nbytes = sftp_read(file, buffer, sizeof(buffer));
          if (nbytes == 0) {
              break; // EOF
          }
          else if (nbytes &lt; 0) {
              fprintf(stderr, &quot;Error while reading file: %s\n&quot;,
                  ssh_get_error(session));
              sftp_close(file);
              return SSH_ERROR;
          }
          nwritten = write(fd, buffer, nbytes);
          if (nwritten != nbytes) {
              fprintf(stderr, &quot;Error writing: %s\n&quot;,
                  strerror(errno));
              sftp_close(file);
              return SSH_ERROR;
          }
      }
      rc = sftp_close(file);
      if (rc != SSH_OK) {
          fprintf(stderr, &quot;Can't close the read file: %s\n&quot;,
              ssh_get_error(session));
          return rc;
      }
  
      sftp_free(sftp);
      return SSH_OK;
  }
  
  int main()
  {
  
      ssh_session my_ssh_session;
      int rc;
      int port = 22;
      string password = &quot;Ins257257&quot;;
      auto host = &quot;192.168.133.13&quot;;
      auto username = &quot;isaque.neves&quot;;
  
      int verbosity = SSH_LOG_PROTOCOL;
      // Abra a sessão e defina as opções
      my_ssh_session = ssh_new();
      if (my_ssh_session == NULL)
          exit(-1);
      ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, host);
      //ssh_options_set(my_ssh_session, SSH_OPTIONS_LOG_VERBOSITY, &amp;verbosity);
      ssh_options_set(my_ssh_session, SSH_OPTIONS_PORT, &amp;port);
      // Conecte-se ao servidor
      rc = ssh_connect(my_ssh_session);
      if (rc != SSH_OK)
      {
          
          fprintf(stderr, &quot;Error connecting to host: %s\n&quot;,
              ssh_get_error(my_ssh_session));
          exit(-1);
          
      }
      // Autenticar-se
  
      rc = ssh_userauth_password(my_ssh_session, username, password.c_str());
      if (rc != SSH_AUTH_SUCCESS)
      {
          fprintf(stderr, &quot;Error authenticating with password: %s\n&quot;,
              ssh_get_error(my_ssh_session));
          ssh_disconnect(my_ssh_session);
          ssh_free(my_ssh_session);
          exit(-1);
      }
  
      clock_t tic = clock();
      auto t1 = high_resolution_clock::now();
      sftpDownloadFileTo(my_ssh_session, &quot;/home/isaque.neves/go1.11.4.linux-amd64.tar.gz&quot;, &quot;D:/MyDartProjects/fsbackup/libssh_binding/go1.11.4.linux-amd64.tar.gz&quot;);
      auto t2 = high_resolution_clock::now();
      clock_t toc = clock();
      
      duration&lt;double, std::milli&gt; ms_double = t2 - t1;   
      std::cout &lt;&lt; ms_double.count() &lt;&lt; &quot; ms\r\n&quot;;
  
      printf(&quot;Elapsed: %f seconds\n&quot;, (double)(toc - tic) / CLOCKS_PER_SEC);
  
      ssh_disconnect(my_ssh_session);
      ssh_free(my_ssh_session);
  
      std::cout &lt;&lt; &quot;End\n&quot;;
  
      return 0;
  }
  </code></pre>
  <p><a href="https://github.com/insinfo/fsbackup/tree/main/libssh_binding" rel="nofollow noreferrer">https://github.com/insinfo/fsbackup/tree/main/libssh_binding</a></p>