version 1.11.2.1, 2001/03/12 15:44:14 |
version 1.11.2.2, 2001/03/21 18:53:04 |
|
|
unsigned char buf[4096]; |
unsigned char buf[4096]; |
|
|
len = atomicio(read, fd, buf, 4); |
len = atomicio(read, fd, buf, 4); |
if (len != 4) |
if (len == 0) |
|
fatal("Connection closed"); |
|
else if (len == -1) |
fatal("Couldn't read packet: %s", strerror(errno)); |
fatal("Couldn't read packet: %s", strerror(errno)); |
|
|
msg_len = GET_32BIT(buf); |
msg_len = GET_32BIT(buf); |
|
|
|
|
while (msg_len) { |
while (msg_len) { |
len = atomicio(read, fd, buf, MIN(msg_len, sizeof(buf))); |
len = atomicio(read, fd, buf, MIN(msg_len, sizeof(buf))); |
if (len <= 0) |
if (len == 0) |
|
fatal("Connection closed"); |
|
else if (len == -1) |
fatal("Couldn't read packet: %s", strerror(errno)); |
fatal("Couldn't read packet: %s", strerror(errno)); |
|
|
msg_len -= len; |
msg_len -= len; |
|
|
} |
} |
|
|
Attrib * |
Attrib * |
get_decode_stat(int fd, u_int expected_id) |
get_decode_stat(int fd, u_int expected_id, int quiet) |
{ |
{ |
Buffer msg; |
Buffer msg; |
u_int type, id; |
u_int type, id; |
|
|
if (type == SSH2_FXP_STATUS) { |
if (type == SSH2_FXP_STATUS) { |
int status = buffer_get_int(&msg); |
int status = buffer_get_int(&msg); |
|
|
error("Couldn't stat remote file: %s", fx2txt(status)); |
if (quiet) |
|
debug("Couldn't stat remote file: %s", fx2txt(status)); |
|
else |
|
error("Couldn't stat remote file: %s", fx2txt(status)); |
return(NULL); |
return(NULL); |
} else if (type != SSH2_FXP_ATTRS) { |
} else if (type != SSH2_FXP_ATTRS) { |
fatal("Expected SSH2_FXP_ATTRS(%d) packet, got %d", |
fatal("Expected SSH2_FXP_ATTRS(%d) packet, got %d", |
|
|
} |
} |
|
|
buffer_free(&msg); |
buffer_free(&msg); |
return(0); |
|
|
return(version); |
} |
} |
|
|
int |
int |
|
|
return(status); |
return(status); |
} |
} |
|
|
|
|
int |
int |
do_ls(int fd_in, int fd_out, char *path) |
do_lsreaddir(int fd_in, int fd_out, char *path, int printflag, |
|
SFTP_DIRENT ***dir) |
{ |
{ |
Buffer msg; |
Buffer msg; |
u_int type, id, handle_len, i, expected_id; |
u_int type, id, handle_len, i, expected_id, ents = 0; |
char *handle; |
char *handle; |
|
|
id = msg_id++; |
id = msg_id++; |
|
|
if (handle == NULL) |
if (handle == NULL) |
return(-1); |
return(-1); |
|
|
|
if (dir) { |
|
ents = 0; |
|
*dir = xmalloc(sizeof(**dir)); |
|
(*dir)[0] = NULL; |
|
} |
|
|
|
|
for(;;) { |
for(;;) { |
int count; |
int count; |
|
|
|
|
longname = buffer_get_string(&msg, NULL); |
longname = buffer_get_string(&msg, NULL); |
a = decode_attrib(&msg); |
a = decode_attrib(&msg); |
|
|
printf("%s\n", longname); |
if (printflag) |
|
printf("%s\n", longname); |
|
|
|
if (dir) { |
|
*dir = xrealloc(*dir, sizeof(**dir) * |
|
(ents + 2)); |
|
(*dir)[ents] = xmalloc(sizeof(***dir)); |
|
(*dir)[ents]->filename = xstrdup(filename); |
|
(*dir)[ents]->longname = xstrdup(longname); |
|
memcpy(&(*dir)[ents]->a, a, sizeof(*a)); |
|
(*dir)[++ents] = NULL; |
|
} |
|
|
xfree(filename); |
xfree(filename); |
xfree(longname); |
xfree(longname); |
} |
} |
|
|
} |
} |
|
|
int |
int |
|
do_ls(int fd_in, int fd_out, char *path) |
|
{ |
|
return(do_lsreaddir(fd_in, fd_out, path, 1, NULL)); |
|
} |
|
|
|
int |
|
do_readdir(int fd_in, int fd_out, char *path, SFTP_DIRENT ***dir) |
|
{ |
|
return(do_lsreaddir(fd_in, fd_out, path, 0, dir)); |
|
} |
|
|
|
void free_sftp_dirents(SFTP_DIRENT **s) |
|
{ |
|
int i; |
|
|
|
for(i = 0; s[i]; i++) { |
|
xfree(s[i]->filename); |
|
xfree(s[i]->longname); |
|
xfree(s[i]); |
|
} |
|
xfree(s); |
|
} |
|
|
|
int |
do_rm(int fd_in, int fd_out, char *path) |
do_rm(int fd_in, int fd_out, char *path) |
{ |
{ |
u_int status, id; |
u_int status, id; |
|
|
} |
} |
|
|
Attrib * |
Attrib * |
do_stat(int fd_in, int fd_out, char *path) |
do_stat(int fd_in, int fd_out, char *path, int quiet) |
{ |
{ |
u_int id; |
u_int id; |
|
|
id = msg_id++; |
id = msg_id++; |
send_string_request(fd_out, id, SSH2_FXP_STAT, path, strlen(path)); |
send_string_request(fd_out, id, SSH2_FXP_STAT, path, strlen(path)); |
return(get_decode_stat(fd_in, id)); |
return(get_decode_stat(fd_in, id, quiet)); |
} |
} |
|
|
Attrib * |
Attrib * |
do_lstat(int fd_in, int fd_out, char *path) |
do_lstat(int fd_in, int fd_out, char *path, int quiet) |
{ |
{ |
u_int id; |
u_int id; |
|
|
id = msg_id++; |
id = msg_id++; |
send_string_request(fd_out, id, SSH2_FXP_LSTAT, path, strlen(path)); |
send_string_request(fd_out, id, SSH2_FXP_LSTAT, path, strlen(path)); |
return(get_decode_stat(fd_in, id)); |
return(get_decode_stat(fd_in, id, quiet)); |
} |
} |
|
|
Attrib * |
Attrib * |
do_fstat(int fd_in, int fd_out, char *handle, |
do_fstat(int fd_in, int fd_out, char *handle, u_int handle_len, int quiet) |
u_int handle_len) |
|
{ |
{ |
u_int id; |
u_int id; |
|
|
id = msg_id++; |
id = msg_id++; |
send_string_request(fd_out, id, SSH2_FXP_FSTAT, handle, handle_len); |
send_string_request(fd_out, id, SSH2_FXP_FSTAT, handle, handle_len); |
return(get_decode_stat(fd_in, id)); |
return(get_decode_stat(fd_in, id, quiet)); |
} |
} |
|
|
int |
int |
|
|
Attrib *a; |
Attrib *a; |
|
|
expected_id = id = msg_id++; |
expected_id = id = msg_id++; |
send_string_request(fd_out, id, SSH2_FXP_REALPATH, path, |
send_string_request(fd_out, id, SSH2_FXP_REALPATH, path, strlen(path)); |
strlen(path)); |
|
|
|
buffer_init(&msg); |
buffer_init(&msg); |
|
|
|
|
} |
} |
|
|
int |
int |
|
do_symlink(int fd_in, int fd_out, char *oldpath, char *newpath) |
|
{ |
|
Buffer msg; |
|
u_int status, id; |
|
|
|
buffer_init(&msg); |
|
|
|
/* Send rename request */ |
|
id = msg_id++; |
|
buffer_put_char(&msg, SSH2_FXP_SYMLINK); |
|
buffer_put_int(&msg, id); |
|
buffer_put_cstring(&msg, oldpath); |
|
buffer_put_cstring(&msg, newpath); |
|
send_msg(fd_out, &msg); |
|
debug3("Sent message SSH2_FXP_SYMLINK \"%s\" -> \"%s\"", oldpath, |
|
newpath); |
|
buffer_free(&msg); |
|
|
|
status = get_status(fd_in, id); |
|
if (status != SSH2_FX_OK) |
|
error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath, newpath, |
|
fx2txt(status)); |
|
|
|
return(status); |
|
} |
|
|
|
char * |
|
do_readlink(int fd_in, int fd_out, char *path) |
|
{ |
|
Buffer msg; |
|
u_int type, expected_id, count, id; |
|
char *filename, *longname; |
|
Attrib *a; |
|
|
|
expected_id = id = msg_id++; |
|
send_string_request(fd_out, id, SSH2_FXP_READLINK, path, strlen(path)); |
|
|
|
buffer_init(&msg); |
|
|
|
get_msg(fd_in, &msg); |
|
type = buffer_get_char(&msg); |
|
id = buffer_get_int(&msg); |
|
|
|
if (id != expected_id) |
|
fatal("ID mismatch (%d != %d)", id, expected_id); |
|
|
|
if (type == SSH2_FXP_STATUS) { |
|
u_int status = buffer_get_int(&msg); |
|
|
|
error("Couldn't readlink: %s", fx2txt(status)); |
|
return(NULL); |
|
} else if (type != SSH2_FXP_NAME) |
|
fatal("Expected SSH2_FXP_NAME(%d) packet, got %d", |
|
SSH2_FXP_NAME, type); |
|
|
|
count = buffer_get_int(&msg); |
|
if (count != 1) |
|
fatal("Got multiple names (%d) from SSH_FXP_READLINK", count); |
|
|
|
filename = buffer_get_string(&msg, NULL); |
|
longname = buffer_get_string(&msg, NULL); |
|
a = decode_attrib(&msg); |
|
|
|
debug3("SSH_FXP_READLINK %s -> %s", path, filename); |
|
|
|
xfree(longname); |
|
|
|
buffer_free(&msg); |
|
|
|
return(filename); |
|
} |
|
|
|
int |
do_download(int fd_in, int fd_out, char *remote_path, char *local_path, |
do_download(int fd_in, int fd_out, char *remote_path, char *local_path, |
int pflag) |
int pflag) |
{ |
{ |
|
|
Attrib junk, *a; |
Attrib junk, *a; |
int status; |
int status; |
|
|
a = do_stat(fd_in, fd_out, remote_path); |
a = do_stat(fd_in, fd_out, remote_path, 0); |
if (a == NULL) |
if (a == NULL) |
return(-1); |
return(-1); |
|
|
|
|
else |
else |
mode = 0666; |
mode = 0666; |
|
|
|
if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) && |
|
(a->perm & S_IFDIR)) { |
|
error("Cannot download a directory: %s", remote_path); |
|
return(-1); |
|
} |
|
|
local_fd = open(local_path, O_WRONLY | O_CREAT | O_TRUNC, mode); |
local_fd = open(local_path, O_WRONLY | O_CREAT | O_TRUNC, mode); |
if (local_fd == -1) { |
if (local_fd == -1) { |
error("Couldn't open local file \"%s\" for writing: %s", |
error("Couldn't open local file \"%s\" for writing: %s", |
local_path, strerror(errno)); |
local_path, strerror(errno)); |
return(errno); |
return(-1); |
} |
} |
|
|
buffer_init(&msg); |
buffer_init(&msg); |
|
|
buffer_free(&msg); |
buffer_free(&msg); |
return status; |
return status; |
} |
} |
|
|