[BACK]Return to sftp-client.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/sftp-client.c between version 1.140 and 1.141

version 1.140, 2021/03/10 04:58:45 version 1.141, 2021/03/31 22:16:34
Line 54 
Line 54 
 extern volatile sig_atomic_t interrupted;  extern volatile sig_atomic_t interrupted;
 extern int showprogress;  extern int showprogress;
   
   /* Default size of buffer for up/download */
   #define DEFAULT_COPY_BUFLEN     32768
   
   /* Default number of concurrent outstanding requests */
   #define DEFAULT_NUM_REQUESTS    64
   
 /* Minimum amount of data to read at a time */  /* Minimum amount of data to read at a time */
 #define MIN_READ_SIZE   512  #define MIN_READ_SIZE   512
   
Line 63 
Line 69 
 struct sftp_conn {  struct sftp_conn {
         int fd_in;          int fd_in;
         int fd_out;          int fd_out;
         u_int transfer_buflen;          u_int download_buflen;
           u_int upload_buflen;
         u_int num_requests;          u_int num_requests;
         u_int version;          u_int version;
         u_int msg_id;          u_int msg_id;
Line 73 
Line 80 
 #define SFTP_EXT_HARDLINK       0x00000008  #define SFTP_EXT_HARDLINK       0x00000008
 #define SFTP_EXT_FSYNC          0x00000010  #define SFTP_EXT_FSYNC          0x00000010
 #define SFTP_EXT_LSETSTAT       0x00000020  #define SFTP_EXT_LSETSTAT       0x00000020
   #define SFTP_EXT_LIMITS         0x00000040
         u_int exts;          u_int exts;
         u_int64_t limit_kbps;          u_int64_t limit_kbps;
         struct bwlimit bwlimit_in, bwlimit_out;          struct bwlimit bwlimit_in, bwlimit_out;
Line 391 
Line 399 
         ret->msg_id = 1;          ret->msg_id = 1;
         ret->fd_in = fd_in;          ret->fd_in = fd_in;
         ret->fd_out = fd_out;          ret->fd_out = fd_out;
         ret->transfer_buflen = transfer_buflen;          ret->download_buflen = ret->upload_buflen =
         ret->num_requests = num_requests;              transfer_buflen ? transfer_buflen : DEFAULT_COPY_BUFLEN;
           ret->num_requests =
               num_requests ? num_requests : DEFAULT_NUM_REQUESTS;
         ret->exts = 0;          ret->exts = 0;
         ret->limit_kbps = 0;          ret->limit_kbps = 0;
   
Line 455 
Line 465 
                     strcmp((char *)value, "1") == 0) {                      strcmp((char *)value, "1") == 0) {
                         ret->exts |= SFTP_EXT_LSETSTAT;                          ret->exts |= SFTP_EXT_LSETSTAT;
                         known = 1;                          known = 1;
                   } else if (strcmp(name, "limits@openssh.com") == 0 &&
                       strcmp((char *)value, "1") == 0) {
                           ret->exts |= SFTP_EXT_LIMITS;
                           known = 1;
                 }                  }
                 if (known) {                  if (known) {
                         debug2("Server supports extension \"%s\" revision %s",                          debug2("Server supports extension \"%s\" revision %s",
Line 468 
Line 482 
   
         sshbuf_free(msg);          sshbuf_free(msg);
   
           /* Query the server for its limits */
           if (ret->exts & SFTP_EXT_LIMITS) {
                   struct sftp_limits limits;
                   if (do_limits(ret, &limits) != 0)
                           fatal_f("limits failed");
   
                   /* If the caller did not specify, find a good value */
                   if (transfer_buflen == 0) {
                           ret->download_buflen = limits.read_length;
                           ret->upload_buflen = limits.write_length;
                           debug("Using server download size %u", ret->download_buflen);
                           debug("Using server upload size %u", ret->upload_buflen);
                   }
   
                   /* Use the server limit to scale down our value only */
                   if (num_requests == 0 && limits.open_handles) {
                           ret->num_requests =
                               MINIMUM(DEFAULT_NUM_REQUESTS, limits.open_handles);
                           debug("Server handle limit %llu; using %u",
                                 (unsigned long long)limits.open_handles, ret->num_requests);
                   }
           }
   
         /* Some filexfer v.0 servers don't support large packets */          /* Some filexfer v.0 servers don't support large packets */
         if (ret->version == 0)          if (ret->version == 0) {
                 ret->transfer_buflen = MINIMUM(ret->transfer_buflen, 20480);                  ret->download_buflen = MINIMUM(ret->download_buflen, 20480);
                   ret->upload_buflen = MINIMUM(ret->upload_buflen, 20480);
           }
   
         ret->limit_kbps = limit_kbps;          ret->limit_kbps = limit_kbps;
         if (ret->limit_kbps > 0) {          if (ret->limit_kbps > 0) {
                 bandwidth_limit_init(&ret->bwlimit_in, ret->limit_kbps,                  bandwidth_limit_init(&ret->bwlimit_in, ret->limit_kbps,
                     ret->transfer_buflen);                      ret->download_buflen);
                 bandwidth_limit_init(&ret->bwlimit_out, ret->limit_kbps,                  bandwidth_limit_init(&ret->bwlimit_out, ret->limit_kbps,
                     ret->transfer_buflen);                      ret->upload_buflen);
         }          }
   
         return ret;          return ret;
Line 490 
Line 529 
 }  }
   
 int  int
   do_limits(struct sftp_conn *conn, struct sftp_limits *limits)
   {
           u_int id, msg_id;
           u_char type;
           struct sshbuf *msg;
           int r;
   
           if ((conn->exts & SFTP_EXT_LIMITS) == 0) {
                   error("Server does not support limits@openssh.com extension");
                   return -1;
           }
   
           if ((msg = sshbuf_new()) == NULL)
                   fatal_f("sshbuf_new failed");
   
           id = conn->msg_id++;
           if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
               (r = sshbuf_put_u32(msg, id)) != 0 ||
               (r = sshbuf_put_cstring(msg, "limits@openssh.com")) != 0)
                   fatal_fr(r, "compose");
           send_msg(conn, msg);
           debug3("Sent message limits@openssh.com I:%u", id);
   
           get_msg(conn, msg);
   
           if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
               (r = sshbuf_get_u32(msg, &msg_id)) != 0)
                   fatal_fr(r, "parse");
   
           debug3("Received limits reply T:%u I:%u", type, msg_id);
           if (id != msg_id)
                   fatal("ID mismatch (%u != %u)", msg_id, id);
           if (type != SSH2_FXP_EXTENDED_REPLY) {
                   fatal("Expected SSH2_FXP_EXTENDED_REPLY(%u) packet, got %u",
                         SSH2_FXP_EXTENDED_REPLY, type);
           }
   
           memset(limits, 0, sizeof(*limits));
           if ((r = sshbuf_get_u64(msg, &limits->packet_length)) != 0 ||
               (r = sshbuf_get_u64(msg, &limits->read_length)) != 0 ||
               (r = sshbuf_get_u64(msg, &limits->write_length)) != 0 ||
               (r = sshbuf_get_u64(msg, &limits->open_handles)) != 0)
                   fatal_fr(r, "parse limits");
   
           sshbuf_free(msg);
   
           return 0;
   }
   
   int
 do_close(struct sftp_conn *conn, const u_char *handle, u_int handle_len)  do_close(struct sftp_conn *conn, const u_char *handle, u_int handle_len)
 {  {
         u_int id, status;          u_int id, status;
Line 1222 
Line 1311 
         else          else
                 size = 0;                  size = 0;
   
         buflen = conn->transfer_buflen;          buflen = conn->download_buflen;
         if ((msg = sshbuf_new()) == NULL)          if ((msg = sshbuf_new()) == NULL)
                 fatal_f("sshbuf_new failed");                  fatal_f("sshbuf_new failed");
   
Line 1683 
Line 1772 
         }          }
   
         startid = ackid = id + 1;          startid = ackid = id + 1;
         data = xmalloc(conn->transfer_buflen);          data = xmalloc(conn->upload_buflen);
   
         /* Read from local and write to remote */          /* Read from local and write to remote */
         offset = progress_counter = (resume ? c->size : 0);          offset = progress_counter = (resume ? c->size : 0);
Line 1703 
Line 1792 
                 if (interrupted || status != SSH2_FX_OK)                  if (interrupted || status != SSH2_FX_OK)
                         len = 0;                          len = 0;
                 else do                  else do
                         len = read(local_fd, data, conn->transfer_buflen);                          len = read(local_fd, data, conn->upload_buflen);
                 while ((len == -1) && (errno == EINTR || errno == EAGAIN));                  while ((len == -1) && (errno == EINTR || errno == EAGAIN));
   
                 if (len == -1)                  if (len == -1)

Legend:
Removed from v.1.140  
changed lines
  Added in v.1.141