diff options
Diffstat (limited to 'sftp-client.c')
-rw-r--r-- | sftp-client.c | 219 |
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 | ||
81 | static char * | 83 | static char * |
82 | get_handle(int fd, u_int expected_id, u_int *len, const char *errfmt, ...) | 84 | get_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 */ | ||
88 | static int | ||
89 | sftpio(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 | ||
85 | static void | 97 | static void |
86 | send_msg(int fd, Buffer *m) | 98 | send_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 | ||
107 | static void | 121 | static void |
108 | get_msg(int fd, Buffer *m) | 122 | get_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 | ||
133 | static void | 150 | static void |
134 | send_string_request(int fd, u_int id, u_int code, char *s, | 151 | send_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 | ||
148 | static void | 165 | static void |
149 | send_string_attrs_request(int fd, u_int id, u_int code, char *s, | 166 | send_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 | ||
164 | static u_int | 181 | static u_int |
165 | get_status(int fd, u_int expected_id) | 182 | get_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 | ||
189 | static char * | 206 | static char * |
190 | get_handle(int fd, u_int expected_id, u_int *len, const char *errfmt, ...) | 207 | get_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 | ||
227 | static Attrib * | 245 | static Attrib * |
228 | get_decode_stat(int fd, u_int expected_id, int quiet) | 246 | get_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 | ||
262 | static int | 280 | static int |
263 | get_decode_statvfs(int fd, struct sftp_statvfs *st, u_int expected_id, | 281 | get_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 | ||
313 | struct sftp_conn * | 331 | struct sftp_conn * |
314 | do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests) | 332 | do_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 | ||
388 | u_int | 413 | u_int |
389 | sftp_proto_version(struct sftp_conn *conn) | 414 | sftp_proto_version(struct sftp_conn *conn) |
390 | { | 415 | { |
391 | return(conn->version); | 416 | return conn->version; |
392 | } | 417 | } |
393 | 418 | ||
394 | int | 419 | int |
@@ -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 | ||
543 | int | 568 | int |
@@ -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 | ||
623 | Attrib * | 647 | Attrib * |
@@ -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 | ||
908 | static void | 931 | static void |
909 | send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len, | 932 | send_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 | ||