|
Lines 69-74
struct sftp_conn {
Link Here
|
| 69 |
#define SFTP_EXT_STATVFS 0x00000002 |
69 |
#define SFTP_EXT_STATVFS 0x00000002 |
| 70 |
#define SFTP_EXT_FSTATVFS 0x00000004 |
70 |
#define SFTP_EXT_FSTATVFS 0x00000004 |
| 71 |
#define SFTP_EXT_HARDLINK 0x00000008 |
71 |
#define SFTP_EXT_HARDLINK 0x00000008 |
|
|
72 |
#define SFTP_EXT_FSYNC 0x00000010 |
| 72 |
u_int exts; |
73 |
u_int exts; |
| 73 |
u_int64_t limit_kbps; |
74 |
u_int64_t limit_kbps; |
| 74 |
struct bwlimit bwlimit_in, bwlimit_out; |
75 |
struct bwlimit bwlimit_in, bwlimit_out; |
|
Lines 381-386
do_init(int fd_in, int fd_out, u_int tra
Link Here
|
| 381 |
strcmp(value, "1") == 0) { |
382 |
strcmp(value, "1") == 0) { |
| 382 |
ret->exts |= SFTP_EXT_HARDLINK; |
383 |
ret->exts |= SFTP_EXT_HARDLINK; |
| 383 |
known = 1; |
384 |
known = 1; |
|
|
385 |
} else if (strcmp(name, "fsync@openssh.com") == 0 && |
| 386 |
strcmp(value, "1") == 0) { |
| 387 |
ret->exts |= SFTP_EXT_FSYNC; |
| 388 |
known = 1; |
| 384 |
} |
389 |
} |
| 385 |
if (known) { |
390 |
if (known) { |
| 386 |
debug2("Server supports extension \"%s\" revision %s", |
391 |
debug2("Server supports extension \"%s\" revision %s", |
|
Lines 862-867
do_symlink(struct sftp_conn *conn, char
Link Here
|
| 862 |
return(status); |
867 |
return(status); |
| 863 |
} |
868 |
} |
| 864 |
|
869 |
|
|
|
870 |
int |
| 871 |
do_fsync(struct sftp_conn *conn, char *handle, u_int handle_len) |
| 872 |
{ |
| 873 |
Buffer msg; |
| 874 |
u_int status, id; |
| 875 |
|
| 876 |
/* Silently return if the extension is not supported */ |
| 877 |
if ((conn->exts & SFTP_EXT_FSYNC) == 0) |
| 878 |
return -1; |
| 879 |
|
| 880 |
buffer_init(&msg); |
| 881 |
|
| 882 |
/* Send fsync request */ |
| 883 |
id = conn->msg_id++; |
| 884 |
|
| 885 |
buffer_put_char(&msg, SSH2_FXP_EXTENDED); |
| 886 |
buffer_put_int(&msg, id); |
| 887 |
buffer_put_cstring(&msg, "fsync@openssh.com"); |
| 888 |
buffer_put_string(&msg, handle, handle_len); |
| 889 |
send_msg(conn, &msg); |
| 890 |
debug3("Sent message fsync@openssh.com I:%u", id); |
| 891 |
buffer_free(&msg); |
| 892 |
|
| 893 |
status = get_status(conn, id); |
| 894 |
if (status != SSH2_FX_OK) |
| 895 |
error("Couldn't sync file: %s", fx2txt(status)); |
| 896 |
|
| 897 |
return status; |
| 898 |
} |
| 899 |
|
| 865 |
#ifdef notyet |
900 |
#ifdef notyet |
| 866 |
char * |
901 |
char * |
| 867 |
do_readlink(struct sftp_conn *conn, char *path) |
902 |
do_readlink(struct sftp_conn *conn, char *path) |
|
Lines 984-990
send_read_request(struct sftp_conn *conn
Link Here
|
| 984 |
|
1019 |
|
| 985 |
int |
1020 |
int |
| 986 |
do_download(struct sftp_conn *conn, char *remote_path, char *local_path, |
1021 |
do_download(struct sftp_conn *conn, char *remote_path, char *local_path, |
| 987 |
Attrib *a, int preserve_flag, int resume_flag) |
1022 |
Attrib *a, int preserve_flag, int resume_flag, int fsync_flag) |
| 988 |
{ |
1023 |
{ |
| 989 |
Attrib junk; |
1024 |
Attrib junk; |
| 990 |
Buffer msg; |
1025 |
Buffer msg; |
|
Lines 1240-1245
do_download(struct sftp_conn *conn, char
Link Here
|
| 1240 |
error("Can't set times on \"%s\": %s", |
1275 |
error("Can't set times on \"%s\": %s", |
| 1241 |
local_path, strerror(errno)); |
1276 |
local_path, strerror(errno)); |
| 1242 |
} |
1277 |
} |
|
|
1278 |
if (fsync_flag) { |
| 1279 |
debug("syncing \"%s\"", local_path); |
| 1280 |
if (fsync(local_fd) == -1) |
| 1281 |
error("Couldn't sync file \"%s\": %s", |
| 1282 |
local_path, strerror(errno)); |
| 1283 |
} |
| 1243 |
} |
1284 |
} |
| 1244 |
close(local_fd); |
1285 |
close(local_fd); |
| 1245 |
buffer_free(&msg); |
1286 |
buffer_free(&msg); |
|
Lines 1250-1256
do_download(struct sftp_conn *conn, char
Link Here
|
| 1250 |
|
1291 |
|
| 1251 |
static int |
1292 |
static int |
| 1252 |
download_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, |
1293 |
download_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, |
| 1253 |
Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag) |
1294 |
Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag, |
|
|
1295 |
int fsync_flag) |
| 1254 |
{ |
1296 |
{ |
| 1255 |
int i, ret = 0; |
1297 |
int i, ret = 0; |
| 1256 |
SFTP_DIRENT **dir_entries; |
1298 |
SFTP_DIRENT **dir_entries; |
|
Lines 1303-1313
download_dir_internal(struct sftp_conn *
Link Here
|
| 1303 |
continue; |
1345 |
continue; |
| 1304 |
if (download_dir_internal(conn, new_src, new_dst, |
1346 |
if (download_dir_internal(conn, new_src, new_dst, |
| 1305 |
depth + 1, &(dir_entries[i]->a), preserve_flag, |
1347 |
depth + 1, &(dir_entries[i]->a), preserve_flag, |
| 1306 |
print_flag, resume_flag) == -1) |
1348 |
print_flag, resume_flag, fsync_flag) == -1) |
| 1307 |
ret = -1; |
1349 |
ret = -1; |
| 1308 |
} else if (S_ISREG(dir_entries[i]->a.perm) ) { |
1350 |
} else if (S_ISREG(dir_entries[i]->a.perm) ) { |
| 1309 |
if (do_download(conn, new_src, new_dst, |
1351 |
if (do_download(conn, new_src, new_dst, |
| 1310 |
&(dir_entries[i]->a), preserve_flag, resume_flag) == -1) { |
1352 |
&(dir_entries[i]->a), preserve_flag, |
|
|
1353 |
resume_flag, fsync_flag) == -1) { |
| 1311 |
error("Download of file %s to %s failed", |
1354 |
error("Download of file %s to %s failed", |
| 1312 |
new_src, new_dst); |
1355 |
new_src, new_dst); |
| 1313 |
ret = -1; |
1356 |
ret = -1; |
|
Lines 1340-1346
download_dir_internal(struct sftp_conn *
Link Here
|
| 1340 |
|
1383 |
|
| 1341 |
int |
1384 |
int |
| 1342 |
download_dir(struct sftp_conn *conn, char *src, char *dst, |
1385 |
download_dir(struct sftp_conn *conn, char *src, char *dst, |
| 1343 |
Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag) |
1386 |
Attrib *dirattrib, int preserve_flag, int print_flag, |
|
|
1387 |
int resume_flag, int fsync_flag) |
| 1344 |
{ |
1388 |
{ |
| 1345 |
char *src_canon; |
1389 |
char *src_canon; |
| 1346 |
int ret; |
1390 |
int ret; |
|
Lines 1351-1364
download_dir(struct sftp_conn *conn, cha
Link Here
|
| 1351 |
} |
1395 |
} |
| 1352 |
|
1396 |
|
| 1353 |
ret = download_dir_internal(conn, src_canon, dst, 0, |
1397 |
ret = download_dir_internal(conn, src_canon, dst, 0, |
| 1354 |
dirattrib, preserve_flag, print_flag, resume_flag); |
1398 |
dirattrib, preserve_flag, print_flag, resume_flag, fsync_flag); |
| 1355 |
free(src_canon); |
1399 |
free(src_canon); |
| 1356 |
return ret; |
1400 |
return ret; |
| 1357 |
} |
1401 |
} |
| 1358 |
|
1402 |
|
| 1359 |
int |
1403 |
int |
| 1360 |
do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, |
1404 |
do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, |
| 1361 |
int preserve_flag) |
1405 |
int preserve_flag, int fsync_flag) |
| 1362 |
{ |
1406 |
{ |
| 1363 |
int local_fd; |
1407 |
int local_fd; |
| 1364 |
int status = SSH2_FX_OK; |
1408 |
int status = SSH2_FX_OK; |
|
Lines 1533-1538
do_upload(struct sftp_conn *conn, char *
Link Here
|
| 1533 |
if (preserve_flag) |
1577 |
if (preserve_flag) |
| 1534 |
do_fsetstat(conn, handle, handle_len, &a); |
1578 |
do_fsetstat(conn, handle, handle_len, &a); |
| 1535 |
|
1579 |
|
|
|
1580 |
if (fsync_flag) |
| 1581 |
(void)do_fsync(conn, handle, handle_len); |
| 1582 |
|
| 1536 |
if (do_close(conn, handle, handle_len) != SSH2_FX_OK) |
1583 |
if (do_close(conn, handle, handle_len) != SSH2_FX_OK) |
| 1537 |
status = -1; |
1584 |
status = -1; |
| 1538 |
free(handle); |
1585 |
free(handle); |
|
Lines 1542-1548
do_upload(struct sftp_conn *conn, char *
Link Here
|
| 1542 |
|
1589 |
|
| 1543 |
static int |
1590 |
static int |
| 1544 |
upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, |
1591 |
upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, |
| 1545 |
int preserve_flag, int print_flag) |
1592 |
int preserve_flag, int print_flag, int fsync_flag) |
| 1546 |
{ |
1593 |
{ |
| 1547 |
int ret = 0, status; |
1594 |
int ret = 0, status; |
| 1548 |
DIR *dirp; |
1595 |
DIR *dirp; |
|
Lines 1611-1621
upload_dir_internal(struct sftp_conn *co
Link Here
|
| 1611 |
continue; |
1658 |
continue; |
| 1612 |
|
1659 |
|
| 1613 |
if (upload_dir_internal(conn, new_src, new_dst, |
1660 |
if (upload_dir_internal(conn, new_src, new_dst, |
| 1614 |
depth + 1, preserve_flag, print_flag) == -1) |
1661 |
depth + 1, preserve_flag, print_flag, |
|
|
1662 |
fsync_flag) == -1) |
| 1615 |
ret = -1; |
1663 |
ret = -1; |
| 1616 |
} else if (S_ISREG(sb.st_mode)) { |
1664 |
} else if (S_ISREG(sb.st_mode)) { |
| 1617 |
if (do_upload(conn, new_src, new_dst, |
1665 |
if (do_upload(conn, new_src, new_dst, |
| 1618 |
preserve_flag) == -1) { |
1666 |
preserve_flag, fsync_flag) == -1) { |
| 1619 |
error("Uploading of file %s to %s failed!", |
1667 |
error("Uploading of file %s to %s failed!", |
| 1620 |
new_src, new_dst); |
1668 |
new_src, new_dst); |
| 1621 |
ret = -1; |
1669 |
ret = -1; |
|
Lines 1634-1640
upload_dir_internal(struct sftp_conn *co
Link Here
|
| 1634 |
|
1682 |
|
| 1635 |
int |
1683 |
int |
| 1636 |
upload_dir(struct sftp_conn *conn, char *src, char *dst, int preserve_flag, |
1684 |
upload_dir(struct sftp_conn *conn, char *src, char *dst, int preserve_flag, |
| 1637 |
int print_flag) |
1685 |
int print_flag, int fsync_flag) |
| 1638 |
{ |
1686 |
{ |
| 1639 |
char *dst_canon; |
1687 |
char *dst_canon; |
| 1640 |
int ret; |
1688 |
int ret; |
|
Lines 1645-1651
upload_dir(struct sftp_conn *conn, char
Link Here
|
| 1645 |
} |
1693 |
} |
| 1646 |
|
1694 |
|
| 1647 |
ret = upload_dir_internal(conn, src, dst_canon, 0, preserve_flag, |
1695 |
ret = upload_dir_internal(conn, src, dst_canon, 0, preserve_flag, |
| 1648 |
print_flag); |
1696 |
print_flag, fsync_flag); |
|
|
1697 |
|
| 1649 |
free(dst_canon); |
1698 |
free(dst_canon); |
| 1650 |
return ret; |
1699 |
return ret; |
| 1651 |
} |
1700 |
} |