version 1.153, 2021/08/09 07:16:09 |
version 1.154, 2021/08/09 23:47:44 |
|
|
#define SFTP_EXT_FSYNC 0x00000010 |
#define SFTP_EXT_FSYNC 0x00000010 |
#define SFTP_EXT_LSETSTAT 0x00000020 |
#define SFTP_EXT_LSETSTAT 0x00000020 |
#define SFTP_EXT_LIMITS 0x00000040 |
#define SFTP_EXT_LIMITS 0x00000040 |
|
#define SFTP_EXT_PATH_EXPAND 0x00000080 |
u_int exts; |
u_int exts; |
u_int64_t limit_kbps; |
u_int64_t limit_kbps; |
struct bwlimit bwlimit_in, bwlimit_out; |
struct bwlimit bwlimit_in, bwlimit_out; |
|
|
strcmp((char *)value, "1") == 0) { |
strcmp((char *)value, "1") == 0) { |
ret->exts |= SFTP_EXT_LIMITS; |
ret->exts |= SFTP_EXT_LIMITS; |
known = 1; |
known = 1; |
|
} else if (strcmp(name, "expand-path@openssh.com") == 0 && |
|
strcmp((char *)value, "1") == 0) { |
|
ret->exts |= SFTP_EXT_PATH_EXPAND; |
|
known = 1; |
} |
} |
if (known) { |
if (known) { |
debug2("Server supports extension \"%s\" revision %s", |
debug2("Server supports extension \"%s\" revision %s", |
|
|
return status == SSH2_FX_OK ? 0 : -1; |
return status == SSH2_FX_OK ? 0 : -1; |
} |
} |
|
|
char * |
/* Implements both the realpath and expand-path operations */ |
do_realpath(struct sftp_conn *conn, const char *path) |
static char * |
|
do_realpath_expand(struct sftp_conn *conn, const char *path, int expand) |
{ |
{ |
struct sshbuf *msg; |
struct sshbuf *msg; |
u_int expected_id, count, id; |
u_int expected_id, count, id; |
|
|
Attrib a; |
Attrib a; |
u_char type; |
u_char type; |
int r; |
int r; |
|
const char *what = "SSH2_FXP_REALPATH"; |
|
|
expected_id = id = conn->msg_id++; |
if (expand) |
send_string_request(conn, id, SSH2_FXP_REALPATH, path, |
what = "expand-path@openssh.com"; |
strlen(path)); |
|
|
|
if ((msg = sshbuf_new()) == NULL) |
if ((msg = sshbuf_new()) == NULL) |
fatal_f("sshbuf_new failed"); |
fatal_f("sshbuf_new failed"); |
|
|
|
expected_id = id = conn->msg_id++; |
|
if (expand) { |
|
if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || |
|
(r = sshbuf_put_u32(msg, id)) != 0 || |
|
(r = sshbuf_put_cstring(msg, |
|
"expand-path@openssh.com")) != 0 || |
|
(r = sshbuf_put_cstring(msg, path)) != 0) |
|
fatal_fr(r, "compose %s", what); |
|
send_msg(conn, msg); |
|
} else { |
|
send_string_request(conn, id, SSH2_FXP_REALPATH, |
|
path, strlen(path)); |
|
} |
get_msg(conn, msg); |
get_msg(conn, msg); |
if ((r = sshbuf_get_u8(msg, &type)) != 0 || |
if ((r = sshbuf_get_u8(msg, &type)) != 0 || |
(r = sshbuf_get_u32(msg, &id)) != 0) |
(r = sshbuf_get_u32(msg, &id)) != 0) |
|
|
if ((r = sshbuf_get_u32(msg, &count)) != 0) |
if ((r = sshbuf_get_u32(msg, &count)) != 0) |
fatal_fr(r, "parse count"); |
fatal_fr(r, "parse count"); |
if (count != 1) |
if (count != 1) |
fatal("Got multiple names (%d) from SSH_FXP_REALPATH", count); |
fatal("Got multiple names (%d) from %s", count, what); |
|
|
if ((r = sshbuf_get_cstring(msg, &filename, NULL)) != 0 || |
if ((r = sshbuf_get_cstring(msg, &filename, NULL)) != 0 || |
(r = sshbuf_get_cstring(msg, &longname, NULL)) != 0 || |
(r = sshbuf_get_cstring(msg, &longname, NULL)) != 0 || |
(r = decode_attrib(msg, &a)) != 0) |
(r = decode_attrib(msg, &a)) != 0) |
fatal_fr(r, "parse filename/attrib"); |
fatal_fr(r, "parse filename/attrib"); |
|
|
debug3("SSH_FXP_REALPATH %s -> %s size %lu", path, filename, |
debug3("%s %s -> %s", what, path, filename); |
(unsigned long)a.size); |
|
|
|
free(longname); |
free(longname); |
|
|
sshbuf_free(msg); |
sshbuf_free(msg); |
|
|
return(filename); |
return(filename); |
|
} |
|
|
|
char * |
|
do_realpath(struct sftp_conn *conn, const char *path) |
|
{ |
|
return do_realpath_expand(conn, path, 0); |
|
} |
|
|
|
int |
|
can_expand_path(struct sftp_conn *conn) |
|
{ |
|
return (conn->exts & SFTP_EXT_PATH_EXPAND) != 0; |
|
} |
|
|
|
char * |
|
do_expand_path(struct sftp_conn *conn, const char *path) |
|
{ |
|
if (!can_expand_path(conn)) { |
|
debug3_f("no server support, fallback to realpath"); |
|
return do_realpath_expand(conn, path, 0); |
|
} |
|
return do_realpath_expand(conn, path, 1); |
} |
} |
|
|
int |
int |