/* XXX: copy between two remote sites */
#include "includes.h"
-RCSID("$OpenBSD: sftp-client.c,v 1.12 2001/03/13 22:42:54 djm Exp $");
+RCSID("$OpenBSD: sftp-client.c,v 1.18 2001/07/14 15:10:16 stevesk Exp $");
-#include "ssh.h"
#include "buffer.h"
#include "bufaux.h"
#include "getput.h"
#include "xmalloc.h"
#include "log.h"
#include "atomicio.h"
-#include "pathnames.h"
#include "sftp.h"
#include "sftp-common.h"
/* Message ID */
static u_int msg_id = 1;
-void
+static void
send_msg(int fd, Buffer *m)
{
int mlen = buffer_len(m);
buffer_free(&oqueue);
}
-void
+static void
get_msg(int fd, Buffer *m)
{
u_int len, msg_len;
unsigned char buf[4096];
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));
msg_len = GET_32BIT(buf);
while (msg_len) {
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));
msg_len -= len;
}
}
-void
+static void
send_string_request(int fd, u_int id, u_int code, char *s,
u_int len)
{
buffer_free(&msg);
}
-void
+static void
send_string_attrs_request(int fd, u_int id, u_int code, char *s,
u_int len, Attrib *a)
{
buffer_free(&msg);
}
-u_int
+static u_int
get_status(int fd, int expected_id)
{
Buffer msg;
return(status);
}
-char *
+static char *
get_handle(int fd, u_int expected_id, u_int *len)
{
Buffer msg;
return(handle);
}
-Attrib *
-get_decode_stat(int fd, u_int expected_id)
+static Attrib *
+get_decode_stat(int fd, u_int expected_id, int quiet)
{
Buffer msg;
u_int type, id;
if (type == SSH2_FXP_STATUS) {
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);
} else if (type != SSH2_FXP_ATTRS) {
fatal("Expected SSH2_FXP_ATTRS(%d) packet, got %d",
}
-int
-do_lsreaddir(int fd_in, int fd_out, char *path, int printflag,
+static int
+do_lsreaddir(int fd_in, int fd_out, char *path, int printflag,
SFTP_DIRENT ***dir)
{
Buffer msg;
- u_int type, id, handle_len, i, expected_id, ents;
+ u_int type, id, handle_len, i, expected_id, ents = 0;
char *handle;
id = msg_id++;
printf("%s\n", longname);
if (dir) {
- *dir = xrealloc(*dir, sizeof(**dir) *
+ *dir = xrealloc(*dir, sizeof(**dir) *
(ents + 2));
(*dir)[ents] = xmalloc(sizeof(***dir));
(*dir)[ents]->filename = xstrdup(filename);
}
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;
id = msg_id++;
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 *
-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;
id = msg_id++;
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 *
-do_fstat(int fd_in, int fd_out, char *handle,
- u_int handle_len)
+do_fstat(int fd_in, int fd_out, char *handle, u_int handle_len, int quiet)
{
u_int id;
id = msg_id++;
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
Attrib junk, *a;
int status;
- a = do_stat(fd_in, fd_out, remote_path);
+ a = do_stat(fd_in, fd_out, remote_path, 0);
if (a == NULL)
return(-1);
else
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);
if (local_fd == -1) {
error("Couldn't open local file \"%s\" for writing: %s",
local_path, strerror(errno));
- return(errno);
+ return(-1);
}
buffer_init(&msg);