=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/sftp-client.c,v retrieving revision 1.35.2.2 retrieving revision 1.36 diff -u -r1.35.2.2 -r1.36 --- src/usr.bin/ssh/sftp-client.c 2003/09/16 21:20:27 1.35.2.2 +++ src/usr.bin/ssh/sftp-client.c 2002/11/05 20:10:37 1.36 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2003 Damien Miller. All rights reserved. + * Copyright (c) 2001,2002 Damien Miller. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,7 +28,7 @@ /* XXX: copy between two remote sites */ #include "includes.h" -RCSID("$OpenBSD: sftp-client.c,v 1.35.2.2 2003/09/16 21:20:27 brad Exp $"); +RCSID("$OpenBSD: sftp-client.c,v 1.36 2002/11/05 20:10:37 markus Exp $"); #include @@ -38,20 +38,14 @@ #include "xmalloc.h" #include "log.h" #include "atomicio.h" -#include "progressmeter.h" #include "sftp.h" #include "sftp-common.h" #include "sftp-client.h" -extern int showprogress; - /* Minimum amount of data to read at at time */ #define MIN_READ_SIZE 512 -/* Maximum packet size */ -#define MAX_MSG_LENGTH (256 * 1024) - struct sftp_conn { int fd_in; int fd_out; @@ -64,45 +58,48 @@ static void send_msg(int fd, Buffer *m) { - u_char mlen[4]; + int mlen = buffer_len(m); + int len; + Buffer oqueue; - if (buffer_len(m) > MAX_MSG_LENGTH) - fatal("Outbound message too long %u", buffer_len(m)); + buffer_init(&oqueue); + buffer_put_int(&oqueue, mlen); + buffer_append(&oqueue, buffer_ptr(m), mlen); + buffer_consume(m, mlen); - /* Send length first */ - PUT_32BIT(mlen, buffer_len(m)); - if (atomicio(vwrite, fd, mlen, sizeof(mlen)) <= 0) + len = atomicio(write, fd, buffer_ptr(&oqueue), buffer_len(&oqueue)); + if (len <= 0) fatal("Couldn't send packet: %s", strerror(errno)); - if (atomicio(vwrite, fd, buffer_ptr(m), buffer_len(m)) <= 0) - fatal("Couldn't send packet: %s", strerror(errno)); - - buffer_clear(m); + buffer_free(&oqueue); } static void get_msg(int fd, Buffer *m) { - ssize_t len; - u_int msg_len; + u_int len, msg_len; + unsigned char buf[4096]; - buffer_append_space(m, 4); - len = atomicio(read, fd, buffer_ptr(m), 4); + len = atomicio(read, fd, buf, 4); if (len == 0) fatal("Connection closed"); else if (len == -1) fatal("Couldn't read packet: %s", strerror(errno)); - msg_len = buffer_get_int(m); - if (msg_len > MAX_MSG_LENGTH) + msg_len = GET_32BIT(buf); + if (msg_len > 256 * 1024) fatal("Received message too long %u", msg_len); - buffer_append_space(m, msg_len); - len = atomicio(read, fd, buffer_ptr(m), msg_len); - if (len == 0) - fatal("Connection closed"); - else if (len == -1) - fatal("Read packet: %s", strerror(errno)); + while (msg_len) { + len = atomicio(read, fd, buf, MIN(msg_len, sizeof(buf))); + if (len == 0) + fatal("Connection closed"); + else if (len == -1) + fatal("Couldn't read packet: %s", strerror(errno)); + + msg_len -= len; + buffer_append(m, buf, len); + } } static void @@ -374,7 +371,6 @@ error("Couldn't read directory: %s", fx2txt(status)); do_close(conn, handle, handle_len); - xfree(handle); return(status); } } else if (type != SSH2_FXP_NAME) @@ -507,7 +503,7 @@ if (quiet) debug("Server version does not support lstat operation"); else - logit("Server version does not support lstat operation"); + log("Server version does not support lstat operation"); return(do_stat(conn, path, quiet)); } @@ -745,7 +741,6 @@ int read_error, write_errno; u_int64_t offset, size; u_int handle_len, mode, type, id, buflen; - off_t progress_counter; struct request { u_int id; u_int len; @@ -763,13 +758,13 @@ /* XXX: should we preserve set[ug]id? */ if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) - mode = a->perm & 0777; + mode = S_IWRITE | (a->perm & 0777); else mode = 0666; if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) && - (!S_ISREG(a->perm))) { - error("Cannot download non-regular file: %s", remote_path); + (a->perm & S_IFDIR)) { + error("Cannot download a directory: %s", remote_path); return(-1); } @@ -798,8 +793,7 @@ return(-1); } - local_fd = open(local_path, O_WRONLY | O_CREAT | O_TRUNC, - mode | S_IWRITE); + 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)); @@ -811,16 +805,6 @@ /* Read from remote and write to local */ write_error = read_error = write_errno = num_req = offset = 0; max_req = 1; - progress_counter = 0; - - if (showprogress) { - if (size) - start_progress_meter(remote_path, size, - &progress_counter); - else - printf("Fetching %s to %s\n", remote_path, local_path); - } - while (num_req > 0 || max_req > 0) { char *data; u_int len; @@ -873,15 +857,14 @@ (unsigned long long)req->offset + len - 1); if (len > req->len) fatal("Received more data than asked for " - "%u > %u", len, req->len); + "%u > %u", len, req->len); if ((lseek(local_fd, req->offset, SEEK_SET) == -1 || - atomicio(vwrite, local_fd, data, len) != len) && + atomicio(write, local_fd, data, len) != len) && !write_error) { write_errno = errno; write_error = 1; max_req = 0; } - progress_counter += len; xfree(data); if (len == req->len) { @@ -924,9 +907,6 @@ } } - if (showprogress && size) - stop_progress_meter(); - /* Sanity check */ if (TAILQ_FIRST(&requests) != NULL) fatal("Transfer complete, but requests still in queue"); @@ -946,7 +926,7 @@ /* Override umask and utimes if asked */ if (pflag && fchmod(local_fd, mode) == -1) error("Couldn't set mode on \"%s\": %s", local_path, - strerror(errno)); + strerror(errno)); if (pflag && (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME)) { struct timeval tv[2]; tv[0].tv_sec = a->atime; @@ -954,7 +934,7 @@ tv[0].tv_usec = tv[1].tv_usec = 0; if (utimes(local_path, tv) == -1) error("Can't set times on \"%s\": %s", - local_path, strerror(errno)); + local_path, strerror(errno)); } } close(local_fd); @@ -999,11 +979,6 @@ close(local_fd); return(-1); } - if (!S_ISREG(sb.st_mode)) { - error("%s is not a regular file", local_path); - close(local_fd); - return(-1); - } stat_to_attrib(&sb, &a); a.flags &= ~SSH2_FILEXFER_ATTR_SIZE; @@ -1038,11 +1013,6 @@ /* Read from local and write to remote */ offset = 0; - if (showprogress) - start_progress_meter(local_path, sb.st_size, &offset); - else - printf("Uploading %s to %s\n", local_path, remote_path); - for (;;) { int len; @@ -1073,7 +1043,7 @@ buffer_put_string(&msg, data, len); send_msg(conn->fd_out, &msg); debug3("Sent message SSH2_FXP_WRITE I:%u O:%llu S:%u", - id, (unsigned long long)offset, len); + id, (unsigned long long)offset, len); } else if (TAILQ_FIRST(&acks) == NULL) break; @@ -1107,11 +1077,9 @@ if (status != SSH2_FX_OK) { error("Couldn't write to remote file \"%s\": %s", - remote_path, fx2txt(status)); + remote_path, fx2txt(status)); do_close(conn, handle, handle_len); close(local_fd); - xfree(data); - xfree(ack); goto done; } debug3("In write loop, ack for %u %u bytes at %llu", @@ -1121,8 +1089,6 @@ } offset += len; } - if (showprogress) - stop_progress_meter(); xfree(data); if (close(local_fd) == -1) {