Clean up handling of the return value from sftp_find_request. In many
[sgt/putty] / pscp.c
diff --git a/pscp.c b/pscp.c
index 054e437..93111d3 100644 (file)
--- a/pscp.c
+++ b/pscp.c
@@ -320,6 +320,29 @@ static void bump(char *fmt, ...)
 }
 
 /*
+ * Wait for the reply to a single SFTP request. Parallels the same
+ * function in psftp.c (but isn't centralised into sftp.c because the
+ * latter module handles SFTP only and shouldn't assume that SFTP is
+ * the only thing going on by calling connection_fatal).
+ */
+struct sftp_packet *sftp_wait_for_reply(struct sftp_request *req)
+{
+    struct sftp_packet *pktin;
+    struct sftp_request *rreq;
+
+    sftp_register(req);
+    pktin = sftp_recv();
+    if (pktin == NULL)
+        connection_fatal(NULL, "did not receive SFTP response packet "
+                         "from server");
+    rreq = sftp_find_request(pktin);
+    if (rreq != req)
+        connection_fatal(NULL, "unable to understand SFTP response packet "
+                         "from server: %s", fxp_error());
+    return pktin;
+}
+
+/*
  *  Open an SSH connection to user@host and execute cmd.
  */
 static void do_cmd(char *host, char *user, char *cmd)
@@ -685,7 +708,7 @@ void scp_sftp_listdir(char *dirname)
     struct fxp_names *names;
     struct fxp_name *ournames;
     struct sftp_packet *pktin;
-    struct sftp_request *req, *rreq;
+    struct sftp_request *req;
     int nnames, namesize;
     int i;
 
@@ -697,10 +720,9 @@ void scp_sftp_listdir(char *dirname)
 
     printf("Listing directory %s\n", dirname);
 
-    sftp_register(req = fxp_opendir_send(dirname));
-    rreq = sftp_find_request(pktin = sftp_recv());
-    assert(rreq == req);
-    dirh = fxp_opendir_recv(pktin, rreq);
+    req = fxp_opendir_send(dirname);
+    pktin = sftp_wait_for_reply(req);
+    dirh = fxp_opendir_recv(pktin, req);
 
     if (dirh == NULL) {
        printf("Unable to open %s: %s\n", dirname, fxp_error());
@@ -710,10 +732,9 @@ void scp_sftp_listdir(char *dirname)
 
        while (1) {
 
-           sftp_register(req = fxp_readdir_send(dirh));
-           rreq = sftp_find_request(pktin = sftp_recv());
-           assert(rreq == req);
-           names = fxp_readdir_recv(pktin, rreq);
+           req = fxp_readdir_send(dirh);
+            pktin = sftp_wait_for_reply(req);
+           names = fxp_readdir_recv(pktin, req);
 
            if (names == NULL) {
                if (fxp_error_type() == SSH_FX_EOF)
@@ -736,10 +757,9 @@ void scp_sftp_listdir(char *dirname)
            names->nnames = 0;         /* prevent free_names */
            fxp_free_names(names);
        }
-       sftp_register(req = fxp_close_send(dirh));
-       rreq = sftp_find_request(pktin = sftp_recv());
-       assert(rreq == req);
-       fxp_close_recv(pktin, rreq);
+       req = fxp_close_send(dirh);
+        pktin = sftp_wait_for_reply(req);
+       fxp_close_recv(pktin, req);
 
        /*
         * Now we have our filenames. Sort them by actual file
@@ -786,7 +806,7 @@ int scp_source_setup(char *target, int shouldbedir)
         * directory.
         */
        struct sftp_packet *pktin;
-       struct sftp_request *req, *rreq;
+       struct sftp_request *req;
        struct fxp_attrs attrs;
        int ret;
 
@@ -796,10 +816,9 @@ int scp_source_setup(char *target, int shouldbedir)
            return 1;
        }
 
-       sftp_register(req = fxp_stat_send(target));
-       rreq = sftp_find_request(pktin = sftp_recv());
-       assert(rreq == req);
-       ret = fxp_stat_recv(pktin, rreq, &attrs);
+       req = fxp_stat_send(target);
+        pktin = sftp_wait_for_reply(req);
+       ret = fxp_stat_recv(pktin, req, &attrs);
 
        if (!ret || !(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS))
            scp_sftp_targetisdir = 0;
@@ -850,7 +869,7 @@ int scp_send_filename(char *name, uint64 size, int permissions)
     if (using_sftp) {
        char *fullname;
        struct sftp_packet *pktin;
-       struct sftp_request *req, *rreq;
+       struct sftp_request *req;
         struct fxp_attrs attrs;
 
        if (scp_sftp_targetisdir) {
@@ -862,12 +881,11 @@ int scp_send_filename(char *name, uint64 size, int permissions)
         attrs.flags = 0;
         PUT_PERMISSIONS(attrs, permissions);
 
-       sftp_register(req = fxp_open_send(fullname, SSH_FXF_WRITE |
-                                         SSH_FXF_CREAT | SSH_FXF_TRUNC,
-                                          &attrs));
-       rreq = sftp_find_request(pktin = sftp_recv());
-       assert(rreq == req);
-       scp_sftp_filehandle = fxp_open_recv(pktin, rreq);
+       req = fxp_open_send(fullname,
+                            SSH_FXF_WRITE | SSH_FXF_CREAT | SSH_FXF_TRUNC,
+                            &attrs);
+        pktin = sftp_wait_for_reply(req);
+       scp_sftp_filehandle = fxp_open_recv(pktin, req);
 
        if (!scp_sftp_filehandle) {
            tell_user(stderr, "pscp: unable to open %s: %s",
@@ -907,7 +925,7 @@ int scp_send_filedata(char *data, int len)
        while (!xfer_upload_ready(scp_sftp_xfer)) {
            pktin = sftp_recv();
            ret = xfer_upload_gotpkt(scp_sftp_xfer, pktin);
-           if (!ret) {
+           if (ret <= 0) {
                tell_user(stderr, "error while writing: %s\n", fxp_error());
                errs++;
                return 1;
@@ -942,12 +960,17 @@ int scp_send_finish(void)
     if (using_sftp) {
        struct fxp_attrs attrs;
        struct sftp_packet *pktin;
-       struct sftp_request *req, *rreq;
+       struct sftp_request *req;
        int ret;
 
        while (!xfer_done(scp_sftp_xfer)) {
            pktin = sftp_recv();
-           xfer_upload_gotpkt(scp_sftp_xfer, pktin);
+           ret = xfer_upload_gotpkt(scp_sftp_xfer, pktin);
+           if (ret <= 0) {
+               tell_user(stderr, "error while writing: %s\n", fxp_error());
+               errs++;
+               return 1;
+           }
        }
        xfer_cleanup(scp_sftp_xfer);
 
@@ -958,19 +981,17 @@ int scp_send_finish(void)
            attrs.flags = SSH_FILEXFER_ATTR_ACMODTIME;
            attrs.atime = scp_sftp_atime;
            attrs.mtime = scp_sftp_mtime;
-           sftp_register(req = fxp_fsetstat_send(scp_sftp_filehandle, attrs));
-           rreq = sftp_find_request(pktin = sftp_recv());
-           assert(rreq == req);
-           ret = fxp_fsetstat_recv(pktin, rreq);
+           req = fxp_fsetstat_send(scp_sftp_filehandle, attrs);
+            pktin = sftp_wait_for_reply(req);
+           ret = fxp_fsetstat_recv(pktin, req);
            if (!ret) {
                tell_user(stderr, "unable to set file times: %s\n", fxp_error());
                errs++;
            }
        }
-       sftp_register(req = fxp_close_send(scp_sftp_filehandle));
-       rreq = sftp_find_request(pktin = sftp_recv());
-       assert(rreq == req);
-       fxp_close_recv(pktin, rreq);
+       req = fxp_close_send(scp_sftp_filehandle);
+        pktin = sftp_wait_for_reply(req);
+       fxp_close_recv(pktin, req);
        scp_has_times = 0;
        return 0;
     } else {
@@ -1000,7 +1021,7 @@ int scp_send_dirname(char *name, int modes)
        char const *err;
        struct fxp_attrs attrs;
        struct sftp_packet *pktin;
-       struct sftp_request *req, *rreq;
+       struct sftp_request *req;
        int ret;
 
        if (scp_sftp_targetisdir) {
@@ -1016,20 +1037,18 @@ int scp_send_dirname(char *name, int modes)
         * exists and is a directory we will assume we were either
         * successful or it didn't matter.
         */
-       sftp_register(req = fxp_mkdir_send(fullname));
-       rreq = sftp_find_request(pktin = sftp_recv());
-       assert(rreq == req);
-       ret = fxp_mkdir_recv(pktin, rreq);
+       req = fxp_mkdir_send(fullname);
+        pktin = sftp_wait_for_reply(req);
+       ret = fxp_mkdir_recv(pktin, req);
 
        if (!ret)
            err = fxp_error();
        else
            err = "server reported no error";
 
-       sftp_register(req = fxp_stat_send(fullname));
-       rreq = sftp_find_request(pktin = sftp_recv());
-       assert(rreq == req);
-       ret = fxp_stat_recv(pktin, rreq, &attrs);
+       req = fxp_stat_send(fullname);
+        pktin = sftp_wait_for_reply(req);
+       ret = fxp_stat_recv(pktin, req, &attrs);
 
        if (!ret || !(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS) ||
            !(attrs.permissions & 0040000)) {
@@ -1179,7 +1198,7 @@ int scp_get_sink_action(struct scp_sink_action *act)
        int must_free_fname;
        struct fxp_attrs attrs;
        struct sftp_packet *pktin;
-       struct sftp_request *req, *rreq;
+       struct sftp_request *req;
        int ret;
 
        if (!scp_sftp_dirstack_head) {
@@ -1248,10 +1267,9 @@ int scp_get_sink_action(struct scp_sink_action *act)
         * Now we have a filename. Stat it, and see if it's a file
         * or a directory.
         */
-       sftp_register(req = fxp_stat_send(fname));
-       rreq = sftp_find_request(pktin = sftp_recv());
-       assert(rreq == req);
-       ret = fxp_stat_recv(pktin, rreq, &attrs);
+       req = fxp_stat_send(fname);
+        pktin = sftp_wait_for_reply(req);
+       ret = fxp_stat_recv(pktin, req, &attrs);
 
        if (!ret || !(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS)) {
            tell_user(stderr, "unable to identify %s: %s", fname,
@@ -1304,10 +1322,9 @@ int scp_get_sink_action(struct scp_sink_action *act)
             * list), we must push the other (target,namelist) pair
             * on a stack.
             */
-           sftp_register(req = fxp_opendir_send(fname));
-           rreq = sftp_find_request(pktin = sftp_recv());
-           assert(rreq == req);
-           dirhandle = fxp_opendir_recv(pktin, rreq);
+           req = fxp_opendir_send(fname);
+            pktin = sftp_wait_for_reply(req);
+           dirhandle = fxp_opendir_recv(pktin, req);
 
            if (!dirhandle) {
                tell_user(stderr, "scp: unable to open directory %s: %s",
@@ -1321,10 +1338,9 @@ int scp_get_sink_action(struct scp_sink_action *act)
            while (1) {
                int i;
 
-               sftp_register(req = fxp_readdir_send(dirhandle));
-               rreq = sftp_find_request(pktin = sftp_recv());
-               assert(rreq == req);
-               names = fxp_readdir_recv(pktin, rreq);
+               req = fxp_readdir_send(dirhandle);
+                pktin = sftp_wait_for_reply(req);
+               names = fxp_readdir_recv(pktin, req);
 
                if (names == NULL) {
                    if (fxp_error_type() == SSH_FX_EOF)
@@ -1362,10 +1378,9 @@ int scp_get_sink_action(struct scp_sink_action *act)
                names->nnames = 0;             /* prevent free_names */
                fxp_free_names(names);
            }
-           sftp_register(req = fxp_close_send(dirhandle));
-           rreq = sftp_find_request(pktin = sftp_recv());
-           assert(rreq == req);
-           fxp_close_recv(pktin, rreq);
+           req = fxp_close_send(dirhandle);
+            pktin = sftp_wait_for_reply(req);
+           fxp_close_recv(pktin, req);
 
            newitem = snew(struct scp_sftp_dirstack);
            newitem->next = scp_sftp_dirstack_head;
@@ -1510,13 +1525,11 @@ int scp_accept_filexfer(void)
 {
     if (using_sftp) {
        struct sftp_packet *pktin;
-       struct sftp_request *req, *rreq;
+       struct sftp_request *req;
 
-       sftp_register(req = fxp_open_send(scp_sftp_currentname, SSH_FXF_READ,
-                                          NULL));
-       rreq = sftp_find_request(pktin = sftp_recv());
-       assert(rreq == req);
-       scp_sftp_filehandle = fxp_open_recv(pktin, rreq);
+       req = fxp_open_send(scp_sftp_currentname, SSH_FXF_READ, NULL);
+        pktin = sftp_wait_for_reply(req);
+       scp_sftp_filehandle = fxp_open_recv(pktin, req);
 
        if (!scp_sftp_filehandle) {
            tell_user(stderr, "pscp: unable to open %s: %s",
@@ -1545,8 +1558,7 @@ int scp_recv_filedata(char *data, int len)
        xfer_download_queue(scp_sftp_xfer);
        pktin = sftp_recv();
        ret = xfer_download_gotpkt(scp_sftp_xfer, pktin);
-
-       if (ret < 0) {
+       if (ret <= 0) {
            tell_user(stderr, "pscp: error while reading: %s", fxp_error());
            errs++;
            return -1;
@@ -1577,7 +1589,7 @@ int scp_finish_filerecv(void)
 {
     if (using_sftp) {
        struct sftp_packet *pktin;
-       struct sftp_request *req, *rreq;
+       struct sftp_request *req;
 
        /*
         * Ensure that xfer_done() will work correctly, so we can
@@ -1587,19 +1599,23 @@ int scp_finish_filerecv(void)
        xfer_set_error(scp_sftp_xfer);
        while (!xfer_done(scp_sftp_xfer)) {
            void *vbuf;
-           int len;
+           int ret, len;
 
            pktin = sftp_recv();
-           xfer_download_gotpkt(scp_sftp_xfer, pktin);
+           ret = xfer_download_gotpkt(scp_sftp_xfer, pktin);
+            if (ret <= 0) {
+                tell_user(stderr, "pscp: error while reading: %s", fxp_error());
+                errs++;
+                return -1;
+            }
            if (xfer_download_data(scp_sftp_xfer, &vbuf, &len))
                sfree(vbuf);
        }
        xfer_cleanup(scp_sftp_xfer);
 
-       sftp_register(req = fxp_close_send(scp_sftp_filehandle));
-       rreq = sftp_find_request(pktin = sftp_recv());
-       assert(rreq == req);
-       fxp_close_recv(pktin, rreq);
+       req = fxp_close_send(scp_sftp_filehandle);
+        pktin = sftp_wait_for_reply(req);
+       fxp_close_recv(pktin, req);
        return 0;
     } else {
        back->send(backhandle, "", 1);