summaryrefslogtreecommitdiff
path: root/sftp-client.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2010-09-24 22:15:11 +1000
committerDamien Miller <djm@mindrot.org>2010-09-24 22:15:11 +1000
commit65e42f87fe945a2bf30d7e02358554dbaefa8a4c (patch)
tree102c10a0b5328a40c79dca19d208f0ca0c1671b5 /sftp-client.c
parent7fe2b1fec3b364faf952828f3875b8e7eed8feb4 (diff)
- djm@cvs.openbsd.org 2010/09/22 22:58:51
[atomicio.c atomicio.h misc.c misc.h scp.c sftp-client.c] [sftp-client.h sftp.1 sftp.c] add an option per-read/write callback to atomicio factor out bandwidth limiting code from scp(1) into a generic bandwidth limiter that can be attached using the atomicio callback mechanism add a bandwidth limit option to sftp(1) using the above "very nice" markus@
Diffstat (limited to 'sftp-client.c')
-rw-r--r--sftp-client.c219
1 files changed, 121 insertions, 98 deletions
diff --git a/sftp-client.c b/sftp-client.c
index 9dab47780..4e009ef25 100644
--- a/sftp-client.c
+++ b/sftp-client.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sftp-client.c,v 1.92 2010/07/19 03:16:33 djm Exp $ */ 1/* $OpenBSD: sftp-client.c,v 1.93 2010/09/22 22:58:51 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> 3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
4 * 4 *
@@ -76,14 +76,26 @@ struct sftp_conn {
76#define SFTP_EXT_STATVFS 0x00000002 76#define SFTP_EXT_STATVFS 0x00000002
77#define SFTP_EXT_FSTATVFS 0x00000004 77#define SFTP_EXT_FSTATVFS 0x00000004
78 u_int exts; 78 u_int exts;
79 u_int64_t limit_kbps;
80 struct bwlimit bwlimit_in, bwlimit_out;
79}; 81};
80 82
81static char * 83static char *
82get_handle(int fd, u_int expected_id, u_int *len, const char *errfmt, ...) 84get_handle(struct sftp_conn *conn, u_int expected_id, u_int *len,
83 __attribute__((format(printf, 4, 5))); 85 const char *errfmt, ...) __attribute__((format(printf, 4, 5)));
86
87/* ARGSUSED */
88static int
89sftpio(void *_bwlimit, size_t amount)
90{
91 struct bwlimit *bwlimit = (struct bwlimit *)_bwlimit;
92
93 bandwidth_limit(bwlimit, amount);
94 return 0;
95}
84 96
85static void 97static void
86send_msg(int fd, Buffer *m) 98send_msg(struct sftp_conn *conn, Buffer *m)
87{ 99{
88 u_char mlen[4]; 100 u_char mlen[4];
89 struct iovec iov[2]; 101 struct iovec iov[2];
@@ -98,19 +110,22 @@ send_msg(int fd, Buffer *m)
98 iov[1].iov_base = buffer_ptr(m); 110 iov[1].iov_base = buffer_ptr(m);
99 iov[1].iov_len = buffer_len(m); 111 iov[1].iov_len = buffer_len(m);
100 112
101 if (atomiciov(writev, fd, iov, 2) != buffer_len(m) + sizeof(mlen)) 113 if (atomiciov6(writev, conn->fd_out, iov, 2,
114 conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_out) !=
115 buffer_len(m) + sizeof(mlen))
102 fatal("Couldn't send packet: %s", strerror(errno)); 116 fatal("Couldn't send packet: %s", strerror(errno));
103 117
104 buffer_clear(m); 118 buffer_clear(m);
105} 119}
106 120
107static void 121static void
108get_msg(int fd, Buffer *m) 122get_msg(struct sftp_conn *conn, Buffer *m)
109{ 123{
110 u_int msg_len; 124 u_int msg_len;
111 125
112 buffer_append_space(m, 4); 126 buffer_append_space(m, 4);
113 if (atomicio(read, fd, buffer_ptr(m), 4) != 4) { 127 if (atomicio6(read, conn->fd_in, buffer_ptr(m), 4,
128 conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_in) != 4) {
114 if (errno == EPIPE) 129 if (errno == EPIPE)
115 fatal("Connection closed"); 130 fatal("Connection closed");
116 else 131 else
@@ -122,7 +137,9 @@ get_msg(int fd, Buffer *m)
122 fatal("Received message too long %u", msg_len); 137 fatal("Received message too long %u", msg_len);
123 138
124 buffer_append_space(m, msg_len); 139 buffer_append_space(m, msg_len);
125 if (atomicio(read, fd, buffer_ptr(m), msg_len) != msg_len) { 140 if (atomicio6(read, conn->fd_in, buffer_ptr(m), msg_len,
141 conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_in)
142 != msg_len) {
126 if (errno == EPIPE) 143 if (errno == EPIPE)
127 fatal("Connection closed"); 144 fatal("Connection closed");
128 else 145 else
@@ -131,7 +148,7 @@ get_msg(int fd, Buffer *m)
131} 148}
132 149
133static void 150static void
134send_string_request(int fd, u_int id, u_int code, char *s, 151send_string_request(struct sftp_conn *conn, u_int id, u_int code, char *s,
135 u_int len) 152 u_int len)
136{ 153{
137 Buffer msg; 154 Buffer msg;
@@ -140,14 +157,14 @@ send_string_request(int fd, u_int id, u_int code, char *s,
140 buffer_put_char(&msg, code); 157 buffer_put_char(&msg, code);
141 buffer_put_int(&msg, id); 158 buffer_put_int(&msg, id);
142 buffer_put_string(&msg, s, len); 159 buffer_put_string(&msg, s, len);
143 send_msg(fd, &msg); 160 send_msg(conn, &msg);
144 debug3("Sent message fd %d T:%u I:%u", fd, code, id); 161 debug3("Sent message fd %d T:%u I:%u", conn->fd_out, code, id);
145 buffer_free(&msg); 162 buffer_free(&msg);
146} 163}
147 164
148static void 165static void
149send_string_attrs_request(int fd, u_int id, u_int code, char *s, 166send_string_attrs_request(struct sftp_conn *conn, u_int id, u_int code,
150 u_int len, Attrib *a) 167 char *s, u_int len, Attrib *a)
151{ 168{
152 Buffer msg; 169 Buffer msg;
153 170
@@ -156,19 +173,19 @@ send_string_attrs_request(int fd, u_int id, u_int code, char *s,
156 buffer_put_int(&msg, id); 173 buffer_put_int(&msg, id);
157 buffer_put_string(&msg, s, len); 174 buffer_put_string(&msg, s, len);
158 encode_attrib(&msg, a); 175 encode_attrib(&msg, a);
159 send_msg(fd, &msg); 176 send_msg(conn, &msg);
160 debug3("Sent message fd %d T:%u I:%u", fd, code, id); 177 debug3("Sent message fd %d T:%u I:%u", conn->fd_out, code, id);
161 buffer_free(&msg); 178 buffer_free(&msg);
162} 179}
163 180
164static u_int 181static u_int
165get_status(int fd, u_int expected_id) 182get_status(struct sftp_conn *conn, u_int expected_id)
166{ 183{
167 Buffer msg; 184 Buffer msg;
168 u_int type, id, status; 185 u_int type, id, status;
169 186
170 buffer_init(&msg); 187 buffer_init(&msg);
171 get_msg(fd, &msg); 188 get_msg(conn, &msg);
172 type = buffer_get_char(&msg); 189 type = buffer_get_char(&msg);
173 id = buffer_get_int(&msg); 190 id = buffer_get_int(&msg);
174 191
@@ -183,11 +200,12 @@ get_status(int fd, u_int expected_id)
183 200
184 debug3("SSH2_FXP_STATUS %u", status); 201 debug3("SSH2_FXP_STATUS %u", status);
185 202
186 return(status); 203 return status;
187} 204}
188 205
189static char * 206static char *
190get_handle(int fd, u_int expected_id, u_int *len, const char *errfmt, ...) 207get_handle(struct sftp_conn *conn, u_int expected_id, u_int *len,
208 const char *errfmt, ...)
191{ 209{
192 Buffer msg; 210 Buffer msg;
193 u_int type, id; 211 u_int type, id;
@@ -201,7 +219,7 @@ get_handle(int fd, u_int expected_id, u_int *len, const char *errfmt, ...)
201 va_end(args); 219 va_end(args);
202 220
203 buffer_init(&msg); 221 buffer_init(&msg);
204 get_msg(fd, &msg); 222 get_msg(conn, &msg);
205 type = buffer_get_char(&msg); 223 type = buffer_get_char(&msg);
206 id = buffer_get_int(&msg); 224 id = buffer_get_int(&msg);
207 225
@@ -225,14 +243,14 @@ get_handle(int fd, u_int expected_id, u_int *len, const char *errfmt, ...)
225} 243}
226 244
227static Attrib * 245static Attrib *
228get_decode_stat(int fd, u_int expected_id, int quiet) 246get_decode_stat(struct sftp_conn *conn, u_int expected_id, int quiet)
229{ 247{
230 Buffer msg; 248 Buffer msg;
231 u_int type, id; 249 u_int type, id;
232 Attrib *a; 250 Attrib *a;
233 251
234 buffer_init(&msg); 252 buffer_init(&msg);
235 get_msg(fd, &msg); 253 get_msg(conn, &msg);
236 254
237 type = buffer_get_char(&msg); 255 type = buffer_get_char(&msg);
238 id = buffer_get_int(&msg); 256 id = buffer_get_int(&msg);
@@ -260,14 +278,14 @@ get_decode_stat(int fd, u_int expected_id, int quiet)
260} 278}
261 279
262static int 280static int
263get_decode_statvfs(int fd, struct sftp_statvfs *st, u_int expected_id, 281get_decode_statvfs(struct sftp_conn *conn, struct sftp_statvfs *st,
264 int quiet) 282 u_int expected_id, int quiet)
265{ 283{
266 Buffer msg; 284 Buffer msg;
267 u_int type, id, flag; 285 u_int type, id, flag;
268 286
269 buffer_init(&msg); 287 buffer_init(&msg);
270 get_msg(fd, &msg); 288 get_msg(conn, &msg);
271 289
272 type = buffer_get_char(&msg); 290 type = buffer_get_char(&msg);
273 id = buffer_get_int(&msg); 291 id = buffer_get_int(&msg);
@@ -311,21 +329,29 @@ get_decode_statvfs(int fd, struct sftp_statvfs *st, u_int expected_id,
311} 329}
312 330
313struct sftp_conn * 331struct sftp_conn *
314do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests) 332do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests,
333 u_int64_t limit_kbps)
315{ 334{
316 u_int type, exts = 0; 335 u_int type;
317 int version;
318 Buffer msg; 336 Buffer msg;
319 struct sftp_conn *ret; 337 struct sftp_conn *ret;
320 338
339 ret = xmalloc(sizeof(*ret));
340 ret->fd_in = fd_in;
341 ret->fd_out = fd_out;
342 ret->transfer_buflen = transfer_buflen;
343 ret->num_requests = num_requests;
344 ret->exts = 0;
345 ret->limit_kbps = 0;
346
321 buffer_init(&msg); 347 buffer_init(&msg);
322 buffer_put_char(&msg, SSH2_FXP_INIT); 348 buffer_put_char(&msg, SSH2_FXP_INIT);
323 buffer_put_int(&msg, SSH2_FILEXFER_VERSION); 349 buffer_put_int(&msg, SSH2_FILEXFER_VERSION);
324 send_msg(fd_out, &msg); 350 send_msg(ret, &msg);
325 351
326 buffer_clear(&msg); 352 buffer_clear(&msg);
327 353
328 get_msg(fd_in, &msg); 354 get_msg(ret, &msg);
329 355
330 /* Expecting a VERSION reply */ 356 /* Expecting a VERSION reply */
331 if ((type = buffer_get_char(&msg)) != SSH2_FXP_VERSION) { 357 if ((type = buffer_get_char(&msg)) != SSH2_FXP_VERSION) {
@@ -334,9 +360,9 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests)
334 buffer_free(&msg); 360 buffer_free(&msg);
335 return(NULL); 361 return(NULL);
336 } 362 }
337 version = buffer_get_int(&msg); 363 ret->version = buffer_get_int(&msg);
338 364
339 debug2("Remote version: %d", version); 365 debug2("Remote version: %u", ret->version);
340 366
341 /* Check for extensions */ 367 /* Check for extensions */
342 while (buffer_len(&msg) > 0) { 368 while (buffer_len(&msg) > 0) {
@@ -346,15 +372,15 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests)
346 372
347 if (strcmp(name, "posix-rename@openssh.com") == 0 && 373 if (strcmp(name, "posix-rename@openssh.com") == 0 &&
348 strcmp(value, "1") == 0) { 374 strcmp(value, "1") == 0) {
349 exts |= SFTP_EXT_POSIX_RENAME; 375 ret->exts |= SFTP_EXT_POSIX_RENAME;
350 known = 1; 376 known = 1;
351 } else if (strcmp(name, "statvfs@openssh.com") == 0 && 377 } else if (strcmp(name, "statvfs@openssh.com") == 0 &&
352 strcmp(value, "2") == 0) { 378 strcmp(value, "2") == 0) {
353 exts |= SFTP_EXT_STATVFS; 379 ret->exts |= SFTP_EXT_STATVFS;
354 known = 1; 380 known = 1;
355 } if (strcmp(name, "fstatvfs@openssh.com") == 0 && 381 } if (strcmp(name, "fstatvfs@openssh.com") == 0 &&
356 strcmp(value, "2") == 0) { 382 strcmp(value, "2") == 0) {
357 exts |= SFTP_EXT_FSTATVFS; 383 ret->exts |= SFTP_EXT_FSTATVFS;
358 known = 1; 384 known = 1;
359 } 385 }
360 if (known) { 386 if (known) {
@@ -369,26 +395,25 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests)
369 395
370 buffer_free(&msg); 396 buffer_free(&msg);
371 397
372 ret = xmalloc(sizeof(*ret));
373 ret->fd_in = fd_in;
374 ret->fd_out = fd_out;
375 ret->transfer_buflen = transfer_buflen;
376 ret->num_requests = num_requests;
377 ret->version = version;
378 ret->msg_id = 1;
379 ret->exts = exts;
380
381 /* Some filexfer v.0 servers don't support large packets */ 398 /* Some filexfer v.0 servers don't support large packets */
382 if (version == 0) 399 if (ret->version == 0)
383 ret->transfer_buflen = MIN(ret->transfer_buflen, 20480); 400 ret->transfer_buflen = MIN(ret->transfer_buflen, 20480);
384 401
385 return(ret); 402 ret->limit_kbps = limit_kbps;
403 if (ret->limit_kbps > 0) {
404 bandwidth_limit_init(&ret->bwlimit_in, ret->limit_kbps,
405 ret->transfer_buflen);
406 bandwidth_limit_init(&ret->bwlimit_out, ret->limit_kbps,
407 ret->transfer_buflen);
408 }
409
410 return ret;
386} 411}
387 412
388u_int 413u_int
389sftp_proto_version(struct sftp_conn *conn) 414sftp_proto_version(struct sftp_conn *conn)
390{ 415{
391 return(conn->version); 416 return conn->version;
392} 417}
393 418
394int 419int
@@ -403,16 +428,16 @@ do_close(struct sftp_conn *conn, char *handle, u_int handle_len)
403 buffer_put_char(&msg, SSH2_FXP_CLOSE); 428 buffer_put_char(&msg, SSH2_FXP_CLOSE);
404 buffer_put_int(&msg, id); 429 buffer_put_int(&msg, id);
405 buffer_put_string(&msg, handle, handle_len); 430 buffer_put_string(&msg, handle, handle_len);
406 send_msg(conn->fd_out, &msg); 431 send_msg(conn, &msg);
407 debug3("Sent message SSH2_FXP_CLOSE I:%u", id); 432 debug3("Sent message SSH2_FXP_CLOSE I:%u", id);
408 433
409 status = get_status(conn->fd_in, id); 434 status = get_status(conn, id);
410 if (status != SSH2_FX_OK) 435 if (status != SSH2_FX_OK)
411 error("Couldn't close file: %s", fx2txt(status)); 436 error("Couldn't close file: %s", fx2txt(status));
412 437
413 buffer_free(&msg); 438 buffer_free(&msg);
414 439
415 return(status); 440 return status;
416} 441}
417 442
418 443
@@ -430,14 +455,14 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
430 buffer_put_char(&msg, SSH2_FXP_OPENDIR); 455 buffer_put_char(&msg, SSH2_FXP_OPENDIR);
431 buffer_put_int(&msg, id); 456 buffer_put_int(&msg, id);
432 buffer_put_cstring(&msg, path); 457 buffer_put_cstring(&msg, path);
433 send_msg(conn->fd_out, &msg); 458 send_msg(conn, &msg);
434 459
435 buffer_clear(&msg); 460 buffer_clear(&msg);
436 461
437 handle = get_handle(conn->fd_in, id, &handle_len, 462 handle = get_handle(conn, id, &handle_len,
438 "remote readdir(\"%s\")", path); 463 "remote readdir(\"%s\")", path);
439 if (handle == NULL) 464 if (handle == NULL)
440 return(-1); 465 return -1;
441 466
442 if (dir) { 467 if (dir) {
443 ents = 0; 468 ents = 0;
@@ -454,11 +479,11 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
454 buffer_put_char(&msg, SSH2_FXP_READDIR); 479 buffer_put_char(&msg, SSH2_FXP_READDIR);
455 buffer_put_int(&msg, id); 480 buffer_put_int(&msg, id);
456 buffer_put_string(&msg, handle, handle_len); 481 buffer_put_string(&msg, handle, handle_len);
457 send_msg(conn->fd_out, &msg); 482 send_msg(conn, &msg);
458 483
459 buffer_clear(&msg); 484 buffer_clear(&msg);
460 485
461 get_msg(conn->fd_in, &msg); 486 get_msg(conn, &msg);
462 487
463 type = buffer_get_char(&msg); 488 type = buffer_get_char(&msg);
464 id = buffer_get_int(&msg); 489 id = buffer_get_int(&msg);
@@ -537,7 +562,7 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
537 **dir = NULL; 562 **dir = NULL;
538 } 563 }
539 564
540 return(0); 565 return 0;
541} 566}
542 567
543int 568int
@@ -566,9 +591,8 @@ do_rm(struct sftp_conn *conn, char *path)
566 debug2("Sending SSH2_FXP_REMOVE \"%s\"", path); 591 debug2("Sending SSH2_FXP_REMOVE \"%s\"", path);
567 592
568 id = conn->msg_id++; 593 id = conn->msg_id++;
569 send_string_request(conn->fd_out, id, SSH2_FXP_REMOVE, path, 594 send_string_request(conn, id, SSH2_FXP_REMOVE, path, strlen(path));
570 strlen(path)); 595 status = get_status(conn, id);
571 status = get_status(conn->fd_in, id);
572 if (status != SSH2_FX_OK) 596 if (status != SSH2_FX_OK)
573 error("Couldn't delete file: %s", fx2txt(status)); 597 error("Couldn't delete file: %s", fx2txt(status));
574 return(status); 598 return(status);
@@ -580,10 +604,10 @@ do_mkdir(struct sftp_conn *conn, char *path, Attrib *a, int printflag)
580 u_int status, id; 604 u_int status, id;
581 605
582 id = conn->msg_id++; 606 id = conn->msg_id++;
583 send_string_attrs_request(conn->fd_out, id, SSH2_FXP_MKDIR, path, 607 send_string_attrs_request(conn, id, SSH2_FXP_MKDIR, path,
584 strlen(path), a); 608 strlen(path), a);
585 609
586 status = get_status(conn->fd_in, id); 610 status = get_status(conn, id);
587 if (status != SSH2_FX_OK && printflag) 611 if (status != SSH2_FX_OK && printflag)
588 error("Couldn't create directory: %s", fx2txt(status)); 612 error("Couldn't create directory: %s", fx2txt(status));
589 613
@@ -596,10 +620,10 @@ do_rmdir(struct sftp_conn *conn, char *path)
596 u_int status, id; 620 u_int status, id;
597 621
598 id = conn->msg_id++; 622 id = conn->msg_id++;
599 send_string_request(conn->fd_out, id, SSH2_FXP_RMDIR, path, 623 send_string_request(conn, id, SSH2_FXP_RMDIR, path,
600 strlen(path)); 624 strlen(path));
601 625
602 status = get_status(conn->fd_in, id); 626 status = get_status(conn, id);
603 if (status != SSH2_FX_OK) 627 if (status != SSH2_FX_OK)
604 error("Couldn't remove directory: %s", fx2txt(status)); 628 error("Couldn't remove directory: %s", fx2txt(status));
605 629
@@ -613,11 +637,11 @@ do_stat(struct sftp_conn *conn, char *path, int quiet)
613 637
614 id = conn->msg_id++; 638 id = conn->msg_id++;
615 639
616 send_string_request(conn->fd_out, id, 640 send_string_request(conn, id,
617 conn->version == 0 ? SSH2_FXP_STAT_VERSION_0 : SSH2_FXP_STAT, 641 conn->version == 0 ? SSH2_FXP_STAT_VERSION_0 : SSH2_FXP_STAT,
618 path, strlen(path)); 642 path, strlen(path));
619 643
620 return(get_decode_stat(conn->fd_in, id, quiet)); 644 return(get_decode_stat(conn, id, quiet));
621} 645}
622 646
623Attrib * 647Attrib *
@@ -634,10 +658,10 @@ do_lstat(struct sftp_conn *conn, char *path, int quiet)
634 } 658 }
635 659
636 id = conn->msg_id++; 660 id = conn->msg_id++;
637 send_string_request(conn->fd_out, id, SSH2_FXP_LSTAT, path, 661 send_string_request(conn, id, SSH2_FXP_LSTAT, path,
638 strlen(path)); 662 strlen(path));
639 663
640 return(get_decode_stat(conn->fd_in, id, quiet)); 664 return(get_decode_stat(conn, id, quiet));
641} 665}
642 666
643#ifdef notyet 667#ifdef notyet
@@ -647,10 +671,10 @@ do_fstat(struct sftp_conn *conn, char *handle, u_int handle_len, int quiet)
647 u_int id; 671 u_int id;
648 672
649 id = conn->msg_id++; 673 id = conn->msg_id++;
650 send_string_request(conn->fd_out, id, SSH2_FXP_FSTAT, handle, 674 send_string_request(conn, id, SSH2_FXP_FSTAT, handle,
651 handle_len); 675 handle_len);
652 676
653 return(get_decode_stat(conn->fd_in, id, quiet)); 677 return(get_decode_stat(conn, id, quiet));
654} 678}
655#endif 679#endif
656 680
@@ -660,10 +684,10 @@ do_setstat(struct sftp_conn *conn, char *path, Attrib *a)
660 u_int status, id; 684 u_int status, id;
661 685
662 id = conn->msg_id++; 686 id = conn->msg_id++;
663 send_string_attrs_request(conn->fd_out, id, SSH2_FXP_SETSTAT, path, 687 send_string_attrs_request(conn, id, SSH2_FXP_SETSTAT, path,
664 strlen(path), a); 688 strlen(path), a);
665 689
666 status = get_status(conn->fd_in, id); 690 status = get_status(conn, id);
667 if (status != SSH2_FX_OK) 691 if (status != SSH2_FX_OK)
668 error("Couldn't setstat on \"%s\": %s", path, 692 error("Couldn't setstat on \"%s\": %s", path,
669 fx2txt(status)); 693 fx2txt(status));
@@ -678,10 +702,10 @@ do_fsetstat(struct sftp_conn *conn, char *handle, u_int handle_len,
678 u_int status, id; 702 u_int status, id;
679 703
680 id = conn->msg_id++; 704 id = conn->msg_id++;
681 send_string_attrs_request(conn->fd_out, id, SSH2_FXP_FSETSTAT, handle, 705 send_string_attrs_request(conn, id, SSH2_FXP_FSETSTAT, handle,
682 handle_len, a); 706 handle_len, a);
683 707
684 status = get_status(conn->fd_in, id); 708 status = get_status(conn, id);
685 if (status != SSH2_FX_OK) 709 if (status != SSH2_FX_OK)
686 error("Couldn't fsetstat: %s", fx2txt(status)); 710 error("Couldn't fsetstat: %s", fx2txt(status));
687 711
@@ -697,12 +721,12 @@ do_realpath(struct sftp_conn *conn, char *path)
697 Attrib *a; 721 Attrib *a;
698 722
699 expected_id = id = conn->msg_id++; 723 expected_id = id = conn->msg_id++;
700 send_string_request(conn->fd_out, id, SSH2_FXP_REALPATH, path, 724 send_string_request(conn, id, SSH2_FXP_REALPATH, path,
701 strlen(path)); 725 strlen(path));
702 726
703 buffer_init(&msg); 727 buffer_init(&msg);
704 728
705 get_msg(conn->fd_in, &msg); 729 get_msg(conn, &msg);
706 type = buffer_get_char(&msg); 730 type = buffer_get_char(&msg);
707 id = buffer_get_int(&msg); 731 id = buffer_get_int(&msg);
708 732
@@ -756,13 +780,13 @@ do_rename(struct sftp_conn *conn, char *oldpath, char *newpath)
756 } 780 }
757 buffer_put_cstring(&msg, oldpath); 781 buffer_put_cstring(&msg, oldpath);
758 buffer_put_cstring(&msg, newpath); 782 buffer_put_cstring(&msg, newpath);
759 send_msg(conn->fd_out, &msg); 783 send_msg(conn, &msg);
760 debug3("Sent message %s \"%s\" -> \"%s\"", 784 debug3("Sent message %s \"%s\" -> \"%s\"",
761 (conn->exts & SFTP_EXT_POSIX_RENAME) ? "posix-rename@openssh.com" : 785 (conn->exts & SFTP_EXT_POSIX_RENAME) ? "posix-rename@openssh.com" :
762 "SSH2_FXP_RENAME", oldpath, newpath); 786 "SSH2_FXP_RENAME", oldpath, newpath);
763 buffer_free(&msg); 787 buffer_free(&msg);
764 788
765 status = get_status(conn->fd_in, id); 789 status = get_status(conn, id);
766 if (status != SSH2_FX_OK) 790 if (status != SSH2_FX_OK)
767 error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath, 791 error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath,
768 newpath, fx2txt(status)); 792 newpath, fx2txt(status));
@@ -789,12 +813,12 @@ do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath)
789 buffer_put_int(&msg, id); 813 buffer_put_int(&msg, id);
790 buffer_put_cstring(&msg, oldpath); 814 buffer_put_cstring(&msg, oldpath);
791 buffer_put_cstring(&msg, newpath); 815 buffer_put_cstring(&msg, newpath);
792 send_msg(conn->fd_out, &msg); 816 send_msg(conn, &msg);
793 debug3("Sent message SSH2_FXP_SYMLINK \"%s\" -> \"%s\"", oldpath, 817 debug3("Sent message SSH2_FXP_SYMLINK \"%s\" -> \"%s\"", oldpath,
794 newpath); 818 newpath);
795 buffer_free(&msg); 819 buffer_free(&msg);
796 820
797 status = get_status(conn->fd_in, id); 821 status = get_status(conn, id);
798 if (status != SSH2_FX_OK) 822 if (status != SSH2_FX_OK)
799 error("Couldn't symlink file \"%s\" to \"%s\": %s", oldpath, 823 error("Couldn't symlink file \"%s\" to \"%s\": %s", oldpath,
800 newpath, fx2txt(status)); 824 newpath, fx2txt(status));
@@ -812,12 +836,11 @@ do_readlink(struct sftp_conn *conn, char *path)
812 Attrib *a; 836 Attrib *a;
813 837
814 expected_id = id = conn->msg_id++; 838 expected_id = id = conn->msg_id++;
815 send_string_request(conn->fd_out, id, SSH2_FXP_READLINK, path, 839 send_string_request(conn, id, SSH2_FXP_READLINK, path, strlen(path));
816 strlen(path));
817 840
818 buffer_init(&msg); 841 buffer_init(&msg);
819 842
820 get_msg(conn->fd_in, &msg); 843 get_msg(conn, &msg);
821 type = buffer_get_char(&msg); 844 type = buffer_get_char(&msg);
822 id = buffer_get_int(&msg); 845 id = buffer_get_int(&msg);
823 846
@@ -871,10 +894,10 @@ do_statvfs(struct sftp_conn *conn, const char *path, struct sftp_statvfs *st,
871 buffer_put_int(&msg, id); 894 buffer_put_int(&msg, id);
872 buffer_put_cstring(&msg, "statvfs@openssh.com"); 895 buffer_put_cstring(&msg, "statvfs@openssh.com");
873 buffer_put_cstring(&msg, path); 896 buffer_put_cstring(&msg, path);
874 send_msg(conn->fd_out, &msg); 897 send_msg(conn, &msg);
875 buffer_free(&msg); 898 buffer_free(&msg);
876 899
877 return get_decode_statvfs(conn->fd_in, st, id, quiet); 900 return get_decode_statvfs(conn, st, id, quiet);
878} 901}
879 902
880#ifdef notyet 903#ifdef notyet
@@ -898,16 +921,16 @@ do_fstatvfs(struct sftp_conn *conn, const char *handle, u_int handle_len,
898 buffer_put_int(&msg, id); 921 buffer_put_int(&msg, id);
899 buffer_put_cstring(&msg, "fstatvfs@openssh.com"); 922 buffer_put_cstring(&msg, "fstatvfs@openssh.com");
900 buffer_put_string(&msg, handle, handle_len); 923 buffer_put_string(&msg, handle, handle_len);
901 send_msg(conn->fd_out, &msg); 924 send_msg(conn, &msg);
902 buffer_free(&msg); 925 buffer_free(&msg);
903 926
904 return get_decode_statvfs(conn->fd_in, st, id, quiet); 927 return get_decode_statvfs(conn, st, id, quiet);
905} 928}
906#endif 929#endif
907 930
908static void 931static void
909send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len, 932send_read_request(struct sftp_conn *conn, u_int id, u_int64_t offset,
910 char *handle, u_int handle_len) 933 u_int len, char *handle, u_int handle_len)
911{ 934{
912 Buffer msg; 935 Buffer msg;
913 936
@@ -918,7 +941,7 @@ send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len,
918 buffer_put_string(&msg, handle, handle_len); 941 buffer_put_string(&msg, handle, handle_len);
919 buffer_put_int64(&msg, offset); 942 buffer_put_int64(&msg, offset);
920 buffer_put_int(&msg, len); 943 buffer_put_int(&msg, len);
921 send_msg(fd_out, &msg); 944 send_msg(conn, &msg);
922 buffer_free(&msg); 945 buffer_free(&msg);
923} 946}
924 947
@@ -976,10 +999,10 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
976 buffer_put_int(&msg, SSH2_FXF_READ); 999 buffer_put_int(&msg, SSH2_FXF_READ);
977 attrib_clear(&junk); /* Send empty attributes */ 1000 attrib_clear(&junk); /* Send empty attributes */
978 encode_attrib(&msg, &junk); 1001 encode_attrib(&msg, &junk);
979 send_msg(conn->fd_out, &msg); 1002 send_msg(conn, &msg);
980 debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path); 1003 debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path);
981 1004
982 handle = get_handle(conn->fd_in, id, &handle_len, 1005 handle = get_handle(conn, id, &handle_len,
983 "remote open(\"%s\")", remote_path); 1006 "remote open(\"%s\")", remote_path);
984 if (handle == NULL) { 1007 if (handle == NULL) {
985 buffer_free(&msg); 1008 buffer_free(&msg);
@@ -1032,12 +1055,12 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
1032 offset += buflen; 1055 offset += buflen;
1033 num_req++; 1056 num_req++;
1034 TAILQ_INSERT_TAIL(&requests, req, tq); 1057 TAILQ_INSERT_TAIL(&requests, req, tq);
1035 send_read_request(conn->fd_out, req->id, req->offset, 1058 send_read_request(conn, req->id, req->offset,
1036 req->len, handle, handle_len); 1059 req->len, handle, handle_len);
1037 } 1060 }
1038 1061
1039 buffer_clear(&msg); 1062 buffer_clear(&msg);
1040 get_msg(conn->fd_in, &msg); 1063 get_msg(conn, &msg);
1041 type = buffer_get_char(&msg); 1064 type = buffer_get_char(&msg);
1042 id = buffer_get_int(&msg); 1065 id = buffer_get_int(&msg);
1043 debug3("Received reply T:%u I:%u R:%d", type, id, max_req); 1066 debug3("Received reply T:%u I:%u R:%d", type, id, max_req);
@@ -1092,7 +1115,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
1092 req->id = conn->msg_id++; 1115 req->id = conn->msg_id++;
1093 req->len -= len; 1116 req->len -= len;
1094 req->offset += len; 1117 req->offset += len;
1095 send_read_request(conn->fd_out, req->id, 1118 send_read_request(conn, req->id,
1096 req->offset, req->len, handle, handle_len); 1119 req->offset, req->len, handle, handle_len);
1097 /* Reduce the request size */ 1120 /* Reduce the request size */
1098 if (len < buflen) 1121 if (len < buflen)
@@ -1327,12 +1350,12 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
1327 buffer_put_cstring(&msg, remote_path); 1350 buffer_put_cstring(&msg, remote_path);
1328 buffer_put_int(&msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT|SSH2_FXF_TRUNC); 1351 buffer_put_int(&msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT|SSH2_FXF_TRUNC);
1329 encode_attrib(&msg, &a); 1352 encode_attrib(&msg, &a);
1330 send_msg(conn->fd_out, &msg); 1353 send_msg(conn, &msg);
1331 debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path); 1354 debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path);
1332 1355
1333 buffer_clear(&msg); 1356 buffer_clear(&msg);
1334 1357
1335 handle = get_handle(conn->fd_in, id, &handle_len, 1358 handle = get_handle(conn, id, &handle_len,
1336 "remote open(\"%s\")", remote_path); 1359 "remote open(\"%s\")", remote_path);
1337 if (handle == NULL) { 1360 if (handle == NULL) {
1338 close(local_fd); 1361 close(local_fd);
@@ -1381,7 +1404,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
1381 buffer_put_string(&msg, handle, handle_len); 1404 buffer_put_string(&msg, handle, handle_len);
1382 buffer_put_int64(&msg, offset); 1405 buffer_put_int64(&msg, offset);
1383 buffer_put_string(&msg, data, len); 1406 buffer_put_string(&msg, data, len);
1384 send_msg(conn->fd_out, &msg); 1407 send_msg(conn, &msg);
1385 debug3("Sent message SSH2_FXP_WRITE I:%u O:%llu S:%u", 1408 debug3("Sent message SSH2_FXP_WRITE I:%u O:%llu S:%u",
1386 id, (unsigned long long)offset, len); 1409 id, (unsigned long long)offset, len);
1387 } else if (TAILQ_FIRST(&acks) == NULL) 1410 } else if (TAILQ_FIRST(&acks) == NULL)
@@ -1395,7 +1418,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
1395 u_int r_id; 1418 u_int r_id;
1396 1419
1397 buffer_clear(&msg); 1420 buffer_clear(&msg);
1398 get_msg(conn->fd_in, &msg); 1421 get_msg(conn, &msg);
1399 type = buffer_get_char(&msg); 1422 type = buffer_get_char(&msg);
1400 r_id = buffer_get_int(&msg); 1423 r_id = buffer_get_int(&msg);
1401 1424