]> andersk Git - openssh.git/blobdiff - sftp-client.c
- markus@cvs.openbsd.org 2002/12/13 15:20:52
[openssh.git] / sftp-client.c
index f3d752cdb4d5c6032e3fddecb61549f13dd3403f..df9838648f99466cd1e9d98a1398a12d8cac33b8 100644 (file)
 /* XXX: copy between two remote sites */
 
 #include "includes.h"
-RCSID("$OpenBSD: sftp-client.c,v 1.25 2002/03/08 06:10:16 itojun Exp $");
+RCSID("$OpenBSD: sftp-client.c,v 1.37 2002/11/21 23:03:51 deraadt Exp $");
 
-#if defined(HAVE_SYS_QUEUE_H) && !defined(HAVE_BOGUS_SYS_QUEUE_H)
-#include <sys/queue.h>
-#else
-#include "openbsd-compat/fake-queue.h"
-#endif
+#include "openbsd-compat/sys-queue.h"
 
 #include "buffer.h"
 #include "bufaux.h"
@@ -92,7 +88,7 @@ get_msg(int fd, Buffer *m)
 
        msg_len = GET_32BIT(buf);
        if (msg_len > 256 * 1024)
-               fatal("Received message too long %d", msg_len);
+               fatal("Received message too long %u", msg_len);
 
        while (msg_len) {
                len = atomicio(read, fd, buf, MIN(msg_len, sizeof(buf)));
@@ -117,7 +113,7 @@ send_string_request(int fd, u_int id, u_int code, char *s,
        buffer_put_int(&msg, id);
        buffer_put_string(&msg, s, len);
        send_msg(fd, &msg);
-       debug3("Sent message fd %d T:%d I:%d", fd, code, id);
+       debug3("Sent message fd %d T:%u I:%u", fd, code, id);
        buffer_free(&msg);
 }
 
@@ -133,12 +129,12 @@ send_string_attrs_request(int fd, u_int id, u_int code, char *s,
        buffer_put_string(&msg, s, len);
        encode_attrib(&msg, a);
        send_msg(fd, &msg);
-       debug3("Sent message fd %d T:%d I:%d", fd, code, id);
+       debug3("Sent message fd %d T:%u I:%u", fd, code, id);
        buffer_free(&msg);
 }
 
 static u_int
-get_status(int fd, int expected_id)
+get_status(int fd, u_int expected_id)
 {
        Buffer msg;
        u_int type, id, status;
@@ -149,15 +145,15 @@ get_status(int fd, int expected_id)
        id = buffer_get_int(&msg);
 
        if (id != expected_id)
-               fatal("ID mismatch (%d != %d)", id, expected_id);
+               fatal("ID mismatch (%u != %u)", id, expected_id);
        if (type != SSH2_FXP_STATUS)
-               fatal("Expected SSH2_FXP_STATUS(%d) packet, got %d",
+               fatal("Expected SSH2_FXP_STATUS(%u) packet, got %u",
                    SSH2_FXP_STATUS, type);
 
        status = buffer_get_int(&msg);
        buffer_free(&msg);
 
-       debug3("SSH2_FXP_STATUS %d", status);
+       debug3("SSH2_FXP_STATUS %u", status);
 
        return(status);
 }
@@ -175,14 +171,14 @@ get_handle(int fd, u_int expected_id, u_int *len)
        id = buffer_get_int(&msg);
 
        if (id != expected_id)
-               fatal("ID mismatch (%d != %d)", id, expected_id);
+               fatal("ID mismatch (%u != %u)", id, expected_id);
        if (type == SSH2_FXP_STATUS) {
                int status = buffer_get_int(&msg);
 
                error("Couldn't get handle: %s", fx2txt(status));
                return(NULL);
        } else if (type != SSH2_FXP_HANDLE)
-               fatal("Expected SSH2_FXP_HANDLE(%d) packet, got %d",
+               fatal("Expected SSH2_FXP_HANDLE(%u) packet, got %u",
                    SSH2_FXP_HANDLE, type);
 
        handle = buffer_get_string(&msg, len);
@@ -204,9 +200,9 @@ get_decode_stat(int fd, u_int expected_id, int quiet)
        type = buffer_get_char(&msg);
        id = buffer_get_int(&msg);
 
-       debug3("Received stat reply T:%d I:%d", type, id);
+       debug3("Received stat reply T:%u I:%u", type, id);
        if (id != expected_id)
-               fatal("ID mismatch (%d != %d)", id, expected_id);
+               fatal("ID mismatch (%u != %u)", id, expected_id);
        if (type == SSH2_FXP_STATUS) {
                int status = buffer_get_int(&msg);
 
@@ -216,7 +212,7 @@ get_decode_stat(int fd, u_int expected_id, int quiet)
                        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",
+               fatal("Expected SSH2_FXP_ATTRS(%u) packet, got %u",
                    SSH2_FXP_ATTRS, type);
        }
        a = decode_attrib(&msg);
@@ -228,7 +224,8 @@ get_decode_stat(int fd, u_int expected_id, int quiet)
 struct sftp_conn *
 do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests)
 {
-       int type, version;
+       u_int type;
+       int version;
        Buffer msg;
        struct sftp_conn *ret;
 
@@ -243,7 +240,7 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests)
 
        /* Expecting a VERSION reply */
        if ((type = buffer_get_char(&msg)) != SSH2_FXP_VERSION) {
-               error("Invalid packet back from SSH2_FXP_INIT (type %d)",
+               error("Invalid packet back from SSH2_FXP_INIT (type %u)",
                    type);
                buffer_free(&msg);
                return(NULL);
@@ -274,7 +271,7 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests)
 
        /* Some filexfer v.0 servers don't support large packets */
        if (version == 0)
-               ret->transfer_buflen = MAX(ret->transfer_buflen, 20480);
+               ret->transfer_buflen = MIN(ret->transfer_buflen, 20480);
 
        return(ret);
 }
@@ -298,7 +295,7 @@ do_close(struct sftp_conn *conn, char *handle, u_int handle_len)
        buffer_put_int(&msg, id);
        buffer_put_string(&msg, handle, handle_len);
        send_msg(conn->fd_out, &msg);
-       debug3("Sent message SSH2_FXP_CLOSE I:%d", id);
+       debug3("Sent message SSH2_FXP_CLOSE I:%u", id);
 
        status = get_status(conn->fd_in, id);
        if (status != SSH2_FX_OK)
@@ -343,7 +340,7 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
 
                id = expected_id = conn->msg_id++;
 
-               debug3("Sending SSH2_FXP_READDIR I:%d", id);
+               debug3("Sending SSH2_FXP_READDIR I:%u", id);
 
                buffer_clear(&msg);
                buffer_put_char(&msg, SSH2_FXP_READDIR);
@@ -358,10 +355,10 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
                type = buffer_get_char(&msg);
                id = buffer_get_int(&msg);
 
-               debug3("Received reply T:%d I:%d", type, id);
+               debug3("Received reply T:%u I:%u", type, id);
 
                if (id != expected_id)
-                       fatal("ID mismatch (%d != %d)", id, expected_id);
+                       fatal("ID mismatch (%u != %u)", id, expected_id);
 
                if (type == SSH2_FXP_STATUS) {
                        int status = buffer_get_int(&msg);
@@ -377,7 +374,7 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
                                return(status);
                        }
                } else if (type != SSH2_FXP_NAME)
-                       fatal("Expected SSH2_FXP_NAME(%d) packet, got %d",
+                       fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
                            SSH2_FXP_NAME, type);
 
                count = buffer_get_int(&msg);
@@ -417,12 +414,6 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
        return(0);
 }
 
-int
-do_ls(struct sftp_conn *conn, char *path)
-{
-       return(do_lsreaddir(conn, path, 1, NULL));
-}
-
 int
 do_readdir(struct sftp_conn *conn, char *path, SFTP_DIRENT ***dir)
 {
@@ -449,7 +440,7 @@ do_rm(struct sftp_conn *conn, char *path)
        debug2("Sending SSH2_FXP_REMOVE \"%s\"", path);
 
        id = conn->msg_id++;
-       send_string_request(conn->fd_out, id, SSH2_FXP_REMOVE, path, 
+       send_string_request(conn->fd_out, id, SSH2_FXP_REMOVE, path,
            strlen(path));
        status = get_status(conn->fd_in, id);
        if (status != SSH2_FX_OK)
@@ -496,8 +487,8 @@ do_stat(struct sftp_conn *conn, char *path, int quiet)
 
        id = conn->msg_id++;
 
-       send_string_request(conn->fd_out, id, 
-           conn->version == 0 ? SSH2_FXP_STAT_VERSION_0 : SSH2_FXP_STAT, 
+       send_string_request(conn->fd_out, id,
+           conn->version == 0 ? SSH2_FXP_STAT_VERSION_0 : SSH2_FXP_STAT,
            path, strlen(path));
 
        return(get_decode_stat(conn->fd_in, id, quiet));
@@ -512,8 +503,8 @@ do_lstat(struct sftp_conn *conn, char *path, int quiet)
                if (quiet)
                        debug("Server version does not support lstat operation");
                else
-                       error("Server version does not support lstat operation");
-               return(NULL);
+                       log("Server version does not support lstat operation");
+               return(do_stat(conn, path, quiet));
        }
 
        id = conn->msg_id++;
@@ -588,7 +579,7 @@ do_realpath(struct sftp_conn *conn, char *path)
        id = buffer_get_int(&msg);
 
        if (id != expected_id)
-               fatal("ID mismatch (%d != %d)", id, expected_id);
+               fatal("ID mismatch (%u != %u)", id, expected_id);
 
        if (type == SSH2_FXP_STATUS) {
                u_int status = buffer_get_int(&msg);
@@ -596,7 +587,7 @@ do_realpath(struct sftp_conn *conn, char *path)
                error("Couldn't canonicalise: %s", fx2txt(status));
                return(NULL);
        } else if (type != SSH2_FXP_NAME)
-               fatal("Expected SSH2_FXP_NAME(%d) packet, got %d",
+               fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
                    SSH2_FXP_NAME, type);
 
        count = buffer_get_int(&msg);
@@ -669,7 +660,7 @@ do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath)
 
        status = get_status(conn->fd_in, id);
        if (status != SSH2_FX_OK)
-               error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath,
+               error("Couldn't symlink file \"%s\" to \"%s\": %s", oldpath,
                    newpath, fx2txt(status));
 
        return(status);
@@ -694,7 +685,7 @@ do_readlink(struct sftp_conn *conn, char *path)
        id = buffer_get_int(&msg);
 
        if (id != expected_id)
-               fatal("ID mismatch (%d != %d)", id, expected_id);
+               fatal("ID mismatch (%u != %u)", id, expected_id);
 
        if (type == SSH2_FXP_STATUS) {
                u_int status = buffer_get_int(&msg);
@@ -702,7 +693,7 @@ do_readlink(struct sftp_conn *conn, char *path)
                error("Couldn't readlink: %s", fx2txt(status));
                return(NULL);
        } else if (type != SSH2_FXP_NAME)
-               fatal("Expected SSH2_FXP_NAME(%d) packet, got %d",
+               fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
                    SSH2_FXP_NAME, type);
 
        count = buffer_get_int(&msg);
@@ -727,7 +718,7 @@ send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len,
     char *handle, u_int handle_len)
 {
        Buffer msg;
-       
+
        buffer_init(&msg);
        buffer_clear(&msg);
        buffer_put_char(&msg, SSH2_FXP_READ);
@@ -737,7 +728,7 @@ send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len,
        buffer_put_int(&msg, len);
        send_msg(fd_out, &msg);
        buffer_free(&msg);
-}      
+}
 
 int
 do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
@@ -754,7 +745,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
                u_int id;
                u_int len;
                u_int64_t offset;
-               TAILQ_ENTRY(request) tq; 
+               TAILQ_ENTRY(request) tq;
        };
        TAILQ_HEAD(reqhead, request) requests;
        struct request *req;
@@ -794,7 +785,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
        attrib_clear(&junk); /* Send empty attributes */
        encode_attrib(&msg, &junk);
        send_msg(conn->fd_out, &msg);
-       debug3("Sent message SSH2_FXP_OPEN I:%d P:%s", id, remote_path);
+       debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path);
 
        handle = get_handle(conn->fd_in, id, &handle_len);
        if (handle == NULL) {
@@ -820,7 +811,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
 
                /* Send some more requests */
                while (num_req < max_req) {
-                       debug3("Request range %llu -> %llu (%d/%d)", 
+                       debug3("Request range %llu -> %llu (%d/%d)",
                            (unsigned long long)offset,
                            (unsigned long long)offset + buflen - 1,
                            num_req, max_req);
@@ -831,7 +822,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
                        offset += buflen;
                        num_req++;
                        TAILQ_INSERT_TAIL(&requests, req, tq);
-                       send_read_request(conn->fd_out, req->id, req->offset, 
+                       send_read_request(conn->fd_out, req->id, req->offset,
                            req->len, handle, handle_len);
                }
 
@@ -839,7 +830,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
                get_msg(conn->fd_in, &msg);
                type = buffer_get_char(&msg);
                id = buffer_get_int(&msg);
-               debug3("Received reply T:%d I:%d R:%d", type, id, max_req);
+               debug3("Received reply T:%u I:%u R:%d", type, id, max_req);
 
                /* Find the request in our queue */
                for(req = TAILQ_FIRST(&requests);
@@ -861,13 +852,14 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
                        break;
                case SSH2_FXP_DATA:
                        data = buffer_get_string(&msg, &len);
-                       debug3("Received data %llu -> %llu", req->offset, 
-                           req->offset + len - 1);
+                       debug3("Received data %llu -> %llu",
+                           (unsigned long long)req->offset,
+                           (unsigned long long)req->offset + len - 1);
                        if (len > req->len)
                                fatal("Received more data than asked for "
-                                     "%d > %d", len, req->len);
+                                   "%u > %u", len, req->len);
                        if ((lseek(local_fd, req->offset, SEEK_SET) == -1 ||
-                            atomicio(write, local_fd, data, len) != len) &&
+                           atomicio(write, local_fd, data, len) != len) &&
                            !write_error) {
                                write_errno = errno;
                                write_error = 1;
@@ -882,12 +874,14 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
                        } else {
                                /* Resend the request for the missing data */
                                debug3("Short data block, re-requesting "
-                                   "%llu -> %llu (%2d)", req->offset + len, 
-                                       req->offset + req->len - 1, num_req);
+                                   "%llu -> %llu (%2d)",
+                                   (unsigned long long)req->offset + len,
+                                   (unsigned long long)req->offset +
+                                   req->len - 1, num_req);
                                req->id = conn->msg_id++;
                                req->len -= len;
                                req->offset += len;
-                               send_read_request(conn->fd_out, req->id, 
+                               send_read_request(conn->fd_out, req->id,
                                    req->offset, req->len, handle, handle_len);
                                /* Reduce the request size */
                                if (len < buflen)
@@ -898,7 +892,8 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
                                        /* Only one request at a time
                                         * after the expected EOF */
                                        debug3("Finish at %llu (%2d)",
-                                           offset, num_req);
+                                           (unsigned long long)offset,
+                                           num_req);
                                        max_req = 1;
                                }
                                else if (max_req < conn->num_requests + 1) {
@@ -907,7 +902,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
                        }
                        break;
                default:
-                       fatal("Expected SSH2_FXP_DATA(%d) packet, got %d",
+                       fatal("Expected SSH2_FXP_DATA(%u) packet, got %u",
                            SSH2_FXP_DATA, type);
                }
        }
@@ -917,7 +912,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
                fatal("Transfer complete, but requests still in queue");
 
        if (read_error) {
-               error("Couldn't read from remote file \"%s\" : %s", 
+               error("Couldn't read from remote file \"%s\" : %s",
                    remote_path, fx2txt(status));
                do_close(conn, handle, handle_len);
        } else if (write_error) {
@@ -935,7 +930,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
                if (pflag && chmod(local_path, mode) == -1)
 #endif /* HAVE_FCHMOD */
                        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;
@@ -943,7 +938,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
                        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);
@@ -970,7 +965,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
                u_int id;
                u_int len;
                u_int64_t offset;
-               TAILQ_ENTRY(outstanding_ack) tq; 
+               TAILQ_ENTRY(outstanding_ack) tq;
        };
        TAILQ_HEAD(ackhead, outstanding_ack) acks;
        struct outstanding_ack *ack;
@@ -1006,7 +1001,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
        buffer_put_int(&msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT|SSH2_FXF_TRUNC);
        encode_attrib(&msg, &a);
        send_msg(conn->fd_out, &msg);
-       debug3("Sent message SSH2_FXP_OPEN I:%d P:%s", id, remote_path);
+       debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path);
 
        buffer_clear(&msg);
 
@@ -1051,20 +1046,22 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
                        buffer_put_int64(&msg, offset);
                        buffer_put_string(&msg, data, len);
                        send_msg(conn->fd_out, &msg);
-                       debug3("Sent message SSH2_FXP_WRITE I:%d O:%llu S:%u",
-                              id, (u_int64_t)offset, len);
+                       debug3("Sent message SSH2_FXP_WRITE I:%u O:%llu S:%u",
+                           id, (unsigned long long)offset, len);
                } else if (TAILQ_FIRST(&acks) == NULL)
                        break;
 
                if (ack == NULL)
                        fatal("Unexpected ACK %u", id);
 
-               if (id == startid || len == 0 || 
+               if (id == startid || len == 0 ||
                    id - ackid >= conn->num_requests) {
+                       u_int r_id;
+
                        buffer_clear(&msg);
                        get_msg(conn->fd_in, &msg);
                        type = buffer_get_char(&msg);
-                       id = buffer_get_int(&msg);
+                       r_id = buffer_get_int(&msg);
 
                        if (type != SSH2_FXP_STATUS)
                                fatal("Expected SSH2_FXP_STATUS(%d) packet, "
@@ -1075,24 +1072,24 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
 
                        /* Find the request in our queue */
                        for(ack = TAILQ_FIRST(&acks);
-                           ack != NULL && ack->id != id;
+                           ack != NULL && ack->id != r_id;
                            ack = TAILQ_NEXT(ack, tq))
                                ;
                        if (ack == NULL)
-                               fatal("Can't find request for ID %d", id);
+                               fatal("Can't find request for ID %u", r_id);
                        TAILQ_REMOVE(&acks, ack, tq);
 
                        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);
                                goto done;
                        }
-                       debug3("In write loop, ack for %u %d bytes at %llu", 
-                          ack->id, ack->len, ack->offset);
+                       debug3("In write loop, ack for %u %u bytes at %llu",
+                          ack->id, ack->len, (unsigned long long)ack->offset);
                        ++ackid;
-                       free(ack);
+                       xfree(ack);
                }
                offset += len;
        }
This page took 0.062418 seconds and 4 git commands to generate.