diff options
Diffstat (limited to 'sftp-client.c')
-rw-r--r-- | sftp-client.c | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/sftp-client.c b/sftp-client.c index 2f5907c85..990b58d14 100644 --- a/sftp-client.c +++ b/sftp-client.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sftp-client.c,v 1.114 2014/01/31 16:39:19 tedu Exp $ */ | 1 | /* $OpenBSD: sftp-client.c,v 1.115 2014/04/21 14:36:16 logan 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 | * |
@@ -1420,7 +1420,7 @@ download_dir(struct sftp_conn *conn, char *src, char *dst, | |||
1420 | 1420 | ||
1421 | int | 1421 | int |
1422 | do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, | 1422 | do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, |
1423 | int preserve_flag, int fsync_flag) | 1423 | int preserve_flag, int resume, int fsync_flag) |
1424 | { | 1424 | { |
1425 | int local_fd; | 1425 | int local_fd; |
1426 | int status = SSH2_FX_OK; | 1426 | int status = SSH2_FX_OK; |
@@ -1429,7 +1429,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, | |||
1429 | char *handle, *data; | 1429 | char *handle, *data; |
1430 | Buffer msg; | 1430 | Buffer msg; |
1431 | struct stat sb; | 1431 | struct stat sb; |
1432 | Attrib a; | 1432 | Attrib a, *c = NULL; |
1433 | u_int32_t startid; | 1433 | u_int32_t startid; |
1434 | u_int32_t ackid; | 1434 | u_int32_t ackid; |
1435 | struct outstanding_ack { | 1435 | struct outstanding_ack { |
@@ -1467,6 +1467,26 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, | |||
1467 | if (!preserve_flag) | 1467 | if (!preserve_flag) |
1468 | a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME; | 1468 | a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME; |
1469 | 1469 | ||
1470 | if (resume) { | ||
1471 | /* Get remote file size if it exists */ | ||
1472 | if ((c = do_stat(conn, remote_path, 0)) == NULL) { | ||
1473 | close(local_fd); | ||
1474 | return -1; | ||
1475 | } | ||
1476 | |||
1477 | if ((off_t)c->size >= sb.st_size) { | ||
1478 | error("destination file bigger or same size as " | ||
1479 | "source file"); | ||
1480 | close(local_fd); | ||
1481 | return -1; | ||
1482 | } | ||
1483 | |||
1484 | if (lseek(local_fd, (off_t)c->size, SEEK_SET) == -1) { | ||
1485 | close(local_fd); | ||
1486 | return -1; | ||
1487 | } | ||
1488 | } | ||
1489 | |||
1470 | buffer_init(&msg); | 1490 | buffer_init(&msg); |
1471 | 1491 | ||
1472 | /* Send open request */ | 1492 | /* Send open request */ |
@@ -1474,7 +1494,8 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, | |||
1474 | buffer_put_char(&msg, SSH2_FXP_OPEN); | 1494 | buffer_put_char(&msg, SSH2_FXP_OPEN); |
1475 | buffer_put_int(&msg, id); | 1495 | buffer_put_int(&msg, id); |
1476 | buffer_put_cstring(&msg, remote_path); | 1496 | buffer_put_cstring(&msg, remote_path); |
1477 | buffer_put_int(&msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT|SSH2_FXF_TRUNC); | 1497 | buffer_put_int(&msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT| |
1498 | (resume ? SSH2_FXF_APPEND : SSH2_FXF_TRUNC)); | ||
1478 | encode_attrib(&msg, &a); | 1499 | encode_attrib(&msg, &a); |
1479 | send_msg(conn, &msg); | 1500 | send_msg(conn, &msg); |
1480 | debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path); | 1501 | debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path); |
@@ -1493,7 +1514,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, | |||
1493 | data = xmalloc(conn->transfer_buflen); | 1514 | data = xmalloc(conn->transfer_buflen); |
1494 | 1515 | ||
1495 | /* Read from local and write to remote */ | 1516 | /* Read from local and write to remote */ |
1496 | offset = progress_counter = 0; | 1517 | offset = progress_counter = (resume ? c->size : 0); |
1497 | if (showprogress) | 1518 | if (showprogress) |
1498 | start_progress_meter(local_path, sb.st_size, | 1519 | start_progress_meter(local_path, sb.st_size, |
1499 | &progress_counter); | 1520 | &progress_counter); |
@@ -1608,7 +1629,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, | |||
1608 | 1629 | ||
1609 | static int | 1630 | static int |
1610 | upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, | 1631 | upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, |
1611 | int preserve_flag, int print_flag, int fsync_flag) | 1632 | int preserve_flag, int print_flag, int resume, int fsync_flag) |
1612 | { | 1633 | { |
1613 | int ret = 0, status; | 1634 | int ret = 0, status; |
1614 | DIR *dirp; | 1635 | DIR *dirp; |
@@ -1677,12 +1698,12 @@ upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, | |||
1677 | continue; | 1698 | continue; |
1678 | 1699 | ||
1679 | if (upload_dir_internal(conn, new_src, new_dst, | 1700 | if (upload_dir_internal(conn, new_src, new_dst, |
1680 | depth + 1, preserve_flag, print_flag, | 1701 | depth + 1, preserve_flag, print_flag, resume, |
1681 | fsync_flag) == -1) | 1702 | fsync_flag) == -1) |
1682 | ret = -1; | 1703 | ret = -1; |
1683 | } else if (S_ISREG(sb.st_mode)) { | 1704 | } else if (S_ISREG(sb.st_mode)) { |
1684 | if (do_upload(conn, new_src, new_dst, | 1705 | if (do_upload(conn, new_src, new_dst, |
1685 | preserve_flag, fsync_flag) == -1) { | 1706 | preserve_flag, resume, fsync_flag) == -1) { |
1686 | error("Uploading of file %s to %s failed!", | 1707 | error("Uploading of file %s to %s failed!", |
1687 | new_src, new_dst); | 1708 | new_src, new_dst); |
1688 | ret = -1; | 1709 | ret = -1; |
@@ -1701,7 +1722,7 @@ upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, | |||
1701 | 1722 | ||
1702 | int | 1723 | int |
1703 | upload_dir(struct sftp_conn *conn, char *src, char *dst, int preserve_flag, | 1724 | upload_dir(struct sftp_conn *conn, char *src, char *dst, int preserve_flag, |
1704 | int print_flag, int fsync_flag) | 1725 | int print_flag, int resume, int fsync_flag) |
1705 | { | 1726 | { |
1706 | char *dst_canon; | 1727 | char *dst_canon; |
1707 | int ret; | 1728 | int ret; |
@@ -1712,7 +1733,7 @@ upload_dir(struct sftp_conn *conn, char *src, char *dst, int preserve_flag, | |||
1712 | } | 1733 | } |
1713 | 1734 | ||
1714 | ret = upload_dir_internal(conn, src, dst_canon, 0, preserve_flag, | 1735 | ret = upload_dir_internal(conn, src, dst_canon, 0, preserve_flag, |
1715 | print_flag, fsync_flag); | 1736 | print_flag, resume, fsync_flag); |
1716 | 1737 | ||
1717 | free(dst_canon); | 1738 | free(dst_canon); |
1718 | return ret; | 1739 | return ret; |