Bugzilla – Attachment 3345 Details for
Bug 2948
implement "copy-data" sftp extension
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
sftp client copy-data extension
sftp-client-copy-data.patch (text/plain), 7.48 KB, created by
Darren Tucker
on 2019-12-23 11:04:16 AEDT
(
hide
)
Description:
sftp client copy-data extension
Filename:
MIME Type:
Creator:
Darren Tucker
Created:
2019-12-23 11:04:16 AEDT
Size:
7.48 KB
patch
obsolete
> sftp-client.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++ > sftp-client.h | 3 ++ > sftp.1 | 7 ++- > sftp.c | 12 +++++ > 4 files changed, 139 insertions(+), 1 deletion(-) > >diff --git a/sftp-client.c b/sftp-client.c >index 4986d6d8d291..cd2844a8585e 100644 >--- a/sftp-client.c >+++ b/sftp-client.c >@@ -86,6 +86,7 @@ struct sftp_conn { > #define SFTP_EXT_FSTATVFS 0x00000004 > #define SFTP_EXT_HARDLINK 0x00000008 > #define SFTP_EXT_FSYNC 0x00000010 >+#define SFTP_EXT_COPY_DATA 0x00000020 > u_int exts; > u_int64_t limit_kbps; > struct bwlimit bwlimit_in, bwlimit_out; >@@ -463,6 +464,10 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests, > strcmp((char *)value, "1") == 0) { > ret->exts |= SFTP_EXT_FSYNC; > known = 1; >+ } else if (strcmp(name, "copy-data") == 0 && >+ strcmp((char *)value, "1") == 0) { >+ ret->exts |= SFTP_EXT_COPY_DATA; >+ known = 1; > } > if (known) { > debug2("Server supports extension \"%s\" revision %s", >@@ -879,6 +884,119 @@ do_realpath(struct sftp_conn *conn, const char *path) > return(filename); > } > >+int >+do_copy(struct sftp_conn *conn, const char *oldpath, const char *newpath) >+{ >+ Attrib junk, *a; >+ struct sshbuf *msg; >+ u_char *old_handle, *new_handle; >+ u_int mode, status, id; >+ size_t old_handle_len, new_handle_len; >+ int r; >+ >+ /* Silently return if the extension is not supported */ >+ if ((conn->exts & SFTP_EXT_COPY_DATA) == 0) { >+ error("Server does not support copy-data extension"); >+ return -1; >+ } >+ >+ /* Make sure the file exists, and we can copy its perms */ >+ if ((a = do_stat(conn, oldpath, 0)) == NULL) >+ return -1; >+ >+ /* Do not preserve set[ug]id here, as we do not preserve ownership */ >+ if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { >+ mode = a->perm & 0777; >+ >+ if (!S_ISREG(a->perm)) { >+ error("Cannot copy non-regular file: %s", oldpath); >+ return -1; >+ } >+ } else { >+ mode = 0666; >+ } >+ >+ /* Set up the new perms for the new file */ >+ attrib_clear(a); >+ a->perm = mode; >+ a->flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; >+ >+ if ((msg = sshbuf_new()) == NULL) >+ fatal("%s: sshbuf_new failed", __func__); >+ >+ attrib_clear(&junk); /* Send empty attributes */ >+ >+ /* Open the old file for reading */ >+ id = conn->msg_id++; >+ if ((r = sshbuf_put_u8(msg, SSH2_FXP_OPEN)) != 0 || >+ (r = sshbuf_put_u32(msg, id)) != 0 || >+ (r = sshbuf_put_cstring(msg, oldpath)) != 0 || >+ (r = sshbuf_put_u32(msg, SSH2_FXF_READ)) != 0 || >+ (r = encode_attrib(msg, &junk)) != 0) >+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); >+ send_msg(conn, msg); >+ debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, oldpath); >+ >+ sshbuf_reset(msg); >+ >+ old_handle = get_handle(conn, id, &old_handle_len, >+ "remote open(\"%s\")", oldpath); >+ if (old_handle == NULL) { >+ sshbuf_free(msg); >+ return -1; >+ } >+ >+ /* Open the new file for writing */ >+ id = conn->msg_id++; >+ if ((r = sshbuf_put_u8(msg, SSH2_FXP_OPEN)) != 0 || >+ (r = sshbuf_put_u32(msg, id)) != 0 || >+ (r = sshbuf_put_cstring(msg, newpath)) != 0 || >+ (r = sshbuf_put_u32(msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT| >+ SSH2_FXF_TRUNC)) != 0 || >+ (r = encode_attrib(msg, a)) != 0) >+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); >+ send_msg(conn, msg); >+ debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, newpath); >+ >+ sshbuf_reset(msg); >+ >+ new_handle = get_handle(conn, id, &new_handle_len, >+ "remote open(\"%s\")", newpath); >+ if (new_handle == NULL) { >+ sshbuf_free(msg); >+ return -1; >+ } >+ >+ /* Copy the file data */ >+ id = conn->msg_id++; >+ if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || >+ (r = sshbuf_put_u32(msg, id)) != 0 || >+ (r = sshbuf_put_cstring(msg, "copy-data")) != 0 || >+ (r = sshbuf_put_string(msg, old_handle, old_handle_len)) != 0 || >+ (r = sshbuf_put_u64(msg, 0)) != 0 || >+ (r = sshbuf_put_u64(msg, 0)) != 0 || >+ (r = sshbuf_put_string(msg, new_handle, new_handle_len)) != 0 || >+ (r = sshbuf_put_u64(msg, 0)) != 0) >+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); >+ send_msg(conn, msg); >+ debug3("Sent message copy-data \"%s\" 0 0 -> \"%s\" 0", >+ oldpath, newpath); >+ >+ status = get_status(conn, id); >+ if (status != SSH2_FX_OK) >+ error("Couldn't copy file \"%s\" to \"%s\": %s", oldpath, >+ newpath, fx2txt(status)); >+ >+ /* Clean up everything */ >+ sshbuf_free(msg); >+ do_close(conn, old_handle, old_handle_len); >+ do_close(conn, new_handle, new_handle_len); >+ free(old_handle); >+ free(new_handle); >+ >+ return status == SSH2_FX_OK ? 0 : -1; >+} >+ > int > do_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath, > int force_legacy) >diff --git a/sftp-client.h b/sftp-client.h >index 14a3b8182c49..13b638ef006f 100644 >--- a/sftp-client.h >+++ b/sftp-client.h >@@ -100,6 +100,9 @@ int do_statvfs(struct sftp_conn *, const char *, struct sftp_statvfs *, int); > /* Rename 'oldpath' to 'newpath' */ > int do_rename(struct sftp_conn *, const char *, const char *, int force_legacy); > >+/* Copy 'oldpath' to 'newpath' */ >+int do_copy(struct sftp_conn *, const char *, const char *); >+ > /* Link 'oldpath' to 'newpath' */ > int do_hardlink(struct sftp_conn *, const char *, const char *); > >diff --git a/sftp.1 b/sftp.1 >index 0fd54cae090e..f2eae7f32790 100644 >--- a/sftp.1 >+++ b/sftp.1 >@@ -137,7 +137,7 @@ will abort if any of the following > commands fail: > .Ic get , put , reget , reput, rename , ln , > .Ic rm , mkdir , chdir , ls , >-.Ic lchdir , chmod , chown , >+.Ic lchdir , copy , chmod , chown , > .Ic chgrp , lpwd , df , symlink , > and > .Ic lmkdir . >@@ -340,6 +340,11 @@ may contain > characters and may match multiple files. > .Ar own > must be a numeric UID. >+.It Ic copy Ar oldpath Ar newpath >+Copy remote file from >+.Ar oldpath >+to >+.Ar newpath . > .It Xo Ic df > .Op Fl hi > .Op Ar path >diff --git a/sftp.c b/sftp.c >index 7db86c2d3cf0..3288279172a9 100644 >--- a/sftp.c >+++ b/sftp.c >@@ -142,6 +142,7 @@ enum sftp_command { > I_CHGRP, > I_CHMOD, > I_CHOWN, >+ I_COPY, > I_DF, > I_GET, > I_HELP, >@@ -185,6 +186,7 @@ static const struct CMD cmds[] = { > { "chgrp", I_CHGRP, REMOTE }, > { "chmod", I_CHMOD, REMOTE }, > { "chown", I_CHOWN, REMOTE }, >+ { "cp", I_COPY, REMOTE }, > { "df", I_DF, REMOTE }, > { "dir", I_LS, REMOTE }, > { "exit", I_QUIT, NOARGS }, >@@ -281,6 +283,7 @@ help(void) > "chgrp grp path Change group of file 'path' to 'grp'\n" > "chmod mode path Change permissions of file 'path' to 'mode'\n" > "chown own path Change owner of file 'path' to 'own'\n" >+ "cp oldpath newpath Copy remote file\n" > "df [-hi] [path] Display statistics for current directory or\n" > " filesystem containing 'path'\n" > "exit Quit sftp\n" >@@ -1373,6 +1376,10 @@ parse_args(const char **cpp, int *ignore_errors, int *aflag, > if ((optidx = parse_link_flags(cmd, argv, argc, sflag)) == -1) > return -1; > goto parse_two_paths; >+ case I_COPY: >+ if ((optidx = parse_no_flags(cmd, argv, argc)) == -1) >+ return -1; >+ goto parse_two_paths; > case I_RENAME: > if ((optidx = parse_rename_flags(cmd, argv, argc, lflag)) == -1) > return -1; >@@ -1535,6 +1542,11 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, > err = process_put(conn, path1, path2, *pwd, pflag, > rflag, aflag, fflag); > break; >+ case I_COPY: >+ path1 = make_absolute(path1, *pwd); >+ path2 = make_absolute(path2, *pwd); >+ err = do_copy(conn, path1, path2); >+ break; > case I_RENAME: > path1 = make_absolute(path1, *pwd); > path2 = make_absolute(path2, *pwd);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 2948
:
3344
|
3345
|
3494
|
3495