|
Lines 76-81
Link Here
|
| 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 |
#define SFTP_EXT_HARDLINK 0x00000008 |
78 |
#define SFTP_EXT_HARDLINK 0x00000008 |
|
|
79 |
#define SFTP_EXT_FSYNC 0x00000010 |
| 79 |
u_int exts; |
80 |
u_int exts; |
| 80 |
u_int64_t limit_kbps; |
81 |
u_int64_t limit_kbps; |
| 81 |
struct bwlimit bwlimit_in, bwlimit_out; |
82 |
struct bwlimit bwlimit_in, bwlimit_out; |
|
Lines 387-392
Link Here
|
| 387 |
strcmp(value, "1") == 0) { |
388 |
strcmp(value, "1") == 0) { |
| 388 |
ret->exts |= SFTP_EXT_HARDLINK; |
389 |
ret->exts |= SFTP_EXT_HARDLINK; |
| 389 |
known = 1; |
390 |
known = 1; |
|
|
391 |
} else if (strcmp(name, "fsync@openssh.com") == 0 && |
| 392 |
strcmp(value, "1") == 0) { |
| 393 |
ret->exts |= SFTP_EXT_FSYNC; |
| 394 |
known = 1; |
| 390 |
} |
395 |
} |
| 391 |
if (known) { |
396 |
if (known) { |
| 392 |
debug2("Server supports extension \"%s\" revision %s", |
397 |
debug2("Server supports extension \"%s\" revision %s", |
|
Lines 864-869
Link Here
|
| 864 |
return(status); |
869 |
return(status); |
| 865 |
} |
870 |
} |
| 866 |
|
871 |
|
|
|
872 |
int |
| 873 |
do_fsync(struct sftp_conn *conn, char *handle, u_int handle_len) |
| 874 |
{ |
| 875 |
Buffer msg; |
| 876 |
u_int status, id; |
| 877 |
|
| 878 |
/* Silently return if the extension is not supported */ |
| 879 |
if ((conn->exts & SFTP_EXT_FSYNC) == 0) |
| 880 |
return -1; |
| 881 |
|
| 882 |
buffer_init(&msg); |
| 883 |
|
| 884 |
/* Send fsync request */ |
| 885 |
id = conn->msg_id++; |
| 886 |
|
| 887 |
buffer_put_char(&msg, SSH2_FXP_EXTENDED); |
| 888 |
buffer_put_int(&msg, id); |
| 889 |
buffer_put_cstring(&msg, "fsync@openssh.com"); |
| 890 |
buffer_put_string(&msg, handle, handle_len); |
| 891 |
send_msg(conn, &msg); |
| 892 |
debug3("Sent message fsync@openssh.com I:%u", id); |
| 893 |
buffer_free(&msg); |
| 894 |
|
| 895 |
status = get_status(conn, id); |
| 896 |
if (status != SSH2_FX_OK) |
| 897 |
error("Couldn't sync file: %s", fx2txt(status)); |
| 898 |
|
| 899 |
return(status); |
| 900 |
} |
| 901 |
|
| 867 |
#ifdef notyet |
902 |
#ifdef notyet |
| 868 |
char * |
903 |
char * |
| 869 |
do_readlink(struct sftp_conn *conn, char *path) |
904 |
do_readlink(struct sftp_conn *conn, char *path) |
|
Lines 985-991
Link Here
|
| 985 |
|
1020 |
|
| 986 |
int |
1021 |
int |
| 987 |
do_download(struct sftp_conn *conn, char *remote_path, char *local_path, |
1022 |
do_download(struct sftp_conn *conn, char *remote_path, char *local_path, |
| 988 |
Attrib *a, int pflag) |
1023 |
Attrib *a, int pflag, int fflag) |
| 989 |
{ |
1024 |
{ |
| 990 |
Attrib junk; |
1025 |
Attrib junk; |
| 991 |
Buffer msg; |
1026 |
Buffer msg; |
|
Lines 1214-1219
Link Here
|
| 1214 |
error("Can't set times on \"%s\": %s", |
1249 |
error("Can't set times on \"%s\": %s", |
| 1215 |
local_path, strerror(errno)); |
1250 |
local_path, strerror(errno)); |
| 1216 |
} |
1251 |
} |
|
|
1252 |
/* Flush file to disk if requested */ |
| 1253 |
if (fflag) { |
| 1254 |
debug("syncing \"%s\"", local_path); |
| 1255 |
if (fsync(local_fd) == -1) |
| 1256 |
error("Couldn't sync file \"%s\": %s", |
| 1257 |
local_path, strerror(errno)); |
| 1258 |
} |
| 1217 |
} |
1259 |
} |
| 1218 |
close(local_fd); |
1260 |
close(local_fd); |
| 1219 |
buffer_free(&msg); |
1261 |
buffer_free(&msg); |
|
Lines 1224-1230
Link Here
|
| 1224 |
|
1266 |
|
| 1225 |
static int |
1267 |
static int |
| 1226 |
download_dir_internal(struct sftp_conn *conn, char *src, char *dst, |
1268 |
download_dir_internal(struct sftp_conn *conn, char *src, char *dst, |
| 1227 |
Attrib *dirattrib, int pflag, int printflag, int depth) |
1269 |
Attrib *dirattrib, int pflag, int fflag, int printflag, int depth) |
| 1228 |
{ |
1270 |
{ |
| 1229 |
int i, ret = 0; |
1271 |
int i, ret = 0; |
| 1230 |
SFTP_DIRENT **dir_entries; |
1272 |
SFTP_DIRENT **dir_entries; |
|
Lines 1276-1287
Link Here
|
| 1276 |
strcmp(filename, "..") == 0) |
1318 |
strcmp(filename, "..") == 0) |
| 1277 |
continue; |
1319 |
continue; |
| 1278 |
if (download_dir_internal(conn, new_src, new_dst, |
1320 |
if (download_dir_internal(conn, new_src, new_dst, |
| 1279 |
&(dir_entries[i]->a), pflag, printflag, |
1321 |
&(dir_entries[i]->a), pflag, fflag, printflag, |
| 1280 |
depth + 1) == -1) |
1322 |
depth + 1) == -1) |
| 1281 |
ret = -1; |
1323 |
ret = -1; |
| 1282 |
} else if (S_ISREG(dir_entries[i]->a.perm) ) { |
1324 |
} else if (S_ISREG(dir_entries[i]->a.perm) ) { |
| 1283 |
if (do_download(conn, new_src, new_dst, |
1325 |
if (do_download(conn, new_src, new_dst, |
| 1284 |
&(dir_entries[i]->a), pflag) == -1) { |
1326 |
&(dir_entries[i]->a), pflag, fflag) == -1) { |
| 1285 |
error("Download of file %s to %s failed", |
1327 |
error("Download of file %s to %s failed", |
| 1286 |
new_src, new_dst); |
1328 |
new_src, new_dst); |
| 1287 |
ret = -1; |
1329 |
ret = -1; |
|
Lines 1314-1320
Link Here
|
| 1314 |
|
1356 |
|
| 1315 |
int |
1357 |
int |
| 1316 |
download_dir(struct sftp_conn *conn, char *src, char *dst, |
1358 |
download_dir(struct sftp_conn *conn, char *src, char *dst, |
| 1317 |
Attrib *dirattrib, int pflag, int printflag) |
1359 |
Attrib *dirattrib, int pflag, int fflag, int printflag) |
| 1318 |
{ |
1360 |
{ |
| 1319 |
char *src_canon; |
1361 |
char *src_canon; |
| 1320 |
int ret; |
1362 |
int ret; |
|
Lines 1325-1338
Link Here
|
| 1325 |
} |
1367 |
} |
| 1326 |
|
1368 |
|
| 1327 |
ret = download_dir_internal(conn, src_canon, dst, |
1369 |
ret = download_dir_internal(conn, src_canon, dst, |
| 1328 |
dirattrib, pflag, printflag, 0); |
1370 |
dirattrib, pflag, fflag, printflag, 0); |
| 1329 |
xfree(src_canon); |
1371 |
xfree(src_canon); |
| 1330 |
return ret; |
1372 |
return ret; |
| 1331 |
} |
1373 |
} |
| 1332 |
|
1374 |
|
| 1333 |
int |
1375 |
int |
| 1334 |
do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, |
1376 |
do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, |
| 1335 |
int pflag) |
1377 |
int pflag, int fflag) |
| 1336 |
{ |
1378 |
{ |
| 1337 |
int local_fd; |
1379 |
int local_fd; |
| 1338 |
int status = SSH2_FX_OK; |
1380 |
int status = SSH2_FX_OK; |
|
Lines 1506-1511
Link Here
|
| 1506 |
if (pflag) |
1548 |
if (pflag) |
| 1507 |
do_fsetstat(conn, handle, handle_len, &a); |
1549 |
do_fsetstat(conn, handle, handle_len, &a); |
| 1508 |
|
1550 |
|
|
|
1551 |
if (fflag) |
| 1552 |
(void)do_fsync(conn, handle, handle_len); |
| 1553 |
|
| 1509 |
if (do_close(conn, handle, handle_len) != SSH2_FX_OK) |
1554 |
if (do_close(conn, handle, handle_len) != SSH2_FX_OK) |
| 1510 |
status = -1; |
1555 |
status = -1; |
| 1511 |
xfree(handle); |
1556 |
xfree(handle); |
|
Lines 1515-1521
Link Here
|
| 1515 |
|
1560 |
|
| 1516 |
static int |
1561 |
static int |
| 1517 |
upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, |
1562 |
upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, |
| 1518 |
int pflag, int printflag, int depth) |
1563 |
int pflag, int fflag, int printflag, int depth) |
| 1519 |
{ |
1564 |
{ |
| 1520 |
int ret = 0, status; |
1565 |
int ret = 0, status; |
| 1521 |
DIR *dirp; |
1566 |
DIR *dirp; |
|
Lines 1584-1593
Link Here
|
| 1584 |
continue; |
1629 |
continue; |
| 1585 |
|
1630 |
|
| 1586 |
if (upload_dir_internal(conn, new_src, new_dst, |
1631 |
if (upload_dir_internal(conn, new_src, new_dst, |
| 1587 |
pflag, printflag, depth + 1) == -1) |
1632 |
pflag, fflag, printflag, depth + 1) == -1) |
| 1588 |
ret = -1; |
1633 |
ret = -1; |
| 1589 |
} else if (S_ISREG(sb.st_mode)) { |
1634 |
} else if (S_ISREG(sb.st_mode)) { |
| 1590 |
if (do_upload(conn, new_src, new_dst, pflag) == -1) { |
1635 |
if (do_upload(conn, new_src, new_dst, pflag, |
|
|
1636 |
fflag) == -1) { |
| 1591 |
error("Uploading of file %s to %s failed!", |
1637 |
error("Uploading of file %s to %s failed!", |
| 1592 |
new_src, new_dst); |
1638 |
new_src, new_dst); |
| 1593 |
ret = -1; |
1639 |
ret = -1; |
|
Lines 1606-1612
Link Here
|
| 1606 |
|
1652 |
|
| 1607 |
int |
1653 |
int |
| 1608 |
upload_dir(struct sftp_conn *conn, char *src, char *dst, int printflag, |
1654 |
upload_dir(struct sftp_conn *conn, char *src, char *dst, int printflag, |
| 1609 |
int pflag) |
1655 |
int pflag, int fflag) |
| 1610 |
{ |
1656 |
{ |
| 1611 |
char *dst_canon; |
1657 |
char *dst_canon; |
| 1612 |
int ret; |
1658 |
int ret; |
|
Lines 1616-1622
Link Here
|
| 1616 |
return -1; |
1662 |
return -1; |
| 1617 |
} |
1663 |
} |
| 1618 |
|
1664 |
|
| 1619 |
ret = upload_dir_internal(conn, src, dst_canon, pflag, printflag, 0); |
1665 |
ret = upload_dir_internal(conn, src, dst_canon, pflag, fflag, printflag, 0); |
| 1620 |
xfree(dst_canon); |
1666 |
xfree(dst_canon); |
| 1621 |
return ret; |
1667 |
return ret; |
| 1622 |
} |
1668 |
} |