Update docs for change to UTF-8 by default, and emphasise UTF-8 more generally.
[sgt/putty] / psftp.c
diff --git a/psftp.c b/psftp.c
index 5f91822..ab287df 100644 (file)
--- a/psftp.c
+++ b/psftp.c
@@ -37,6 +37,7 @@ char *pwd, *homedir;
 static Backend *back;
 static void *backhandle;
 static Conf *conf;
+int sent_eof = FALSE;
 
 /* ----------------------------------------------------------------------
  * Higher-level helper functions used in commands.
@@ -829,7 +830,17 @@ char *sftp_wildcard_get_filename(SftpWildcardMatcher *swcm)
                    printf("%s: reading directory: %s\n", swcm->prefix,
                           fxp_error());
                return NULL;
-           }
+           } else if (swcm->names->nnames == 0) {
+                /*
+                 * Another failure mode which we treat as EOF is if
+                 * the server reports success from FXP_READDIR but
+                 * returns no actual names. This is unusual, since
+                 * from most servers you'd expect at least "." and
+                 * "..", but there's nothing forbidding a server from
+                 * omitting those if it wants to.
+                 */
+                return NULL;
+            }
 
            swcm->namepos = 0;
        }
@@ -980,6 +991,7 @@ int sftp_cmd_close(struct sftp_command *cmd)
     if (back != NULL && back->connected(backhandle)) {
        char ch;
        back->special(backhandle, TS_EOF);
+        sent_eof = TRUE;
        sftp_recvdata(&ch, 1);
     }
     do_sftp_cleanup();
@@ -2275,10 +2287,13 @@ struct sftp_command *sftp_getcmd(FILE *fp, int mode, int modeflags)
         *      >this has "quotes" in<
         *      >and"this"<
         */
-       while (*p) {
+       while (1) {
            /* skip whitespace */
            while (*p && (*p == ' ' || *p == '\t'))
                p++;
+            /* terminate loop */
+            if (!*p)
+                break;
            /* mark start of word */
            q = r = p;                 /* q sits at start, r writes word */
            quoting = 0;
@@ -2362,6 +2377,7 @@ void do_sftp_cleanup()
     char ch;
     if (back) {
        back->special(backhandle, TS_EOF);
+        sent_eof = TRUE;
        sftp_recvdata(&ch, 1);
        back->free(backhandle);
        sftp_cleanup_request();
@@ -2570,6 +2586,19 @@ int from_backend_untrusted(void *frontend_handle, const char *data, int len)
     assert(!"Unexpected call to from_backend_untrusted()");
     return 0; /* not reached */
 }
+int from_backend_eof(void *frontend)
+{
+    /*
+     * We expect to be the party deciding when to close the
+     * connection, so if we see EOF before we sent it ourselves, we
+     * should panic.
+     */
+    if (!sent_eof) {
+        connection_fatal(frontend,
+                         "Received unexpected end-of-file from SFTP server");
+    }
+    return FALSE;
+}
 int sftp_recvdata(char *buf, int len)
 {
     outptr = (unsigned char *) buf;
@@ -2894,12 +2923,14 @@ int psftp_main(int argc, char *argv[])
            if (flags & FLAG_VERBOSE)
                verbose = 1;
        } else if (strcmp(argv[i], "-h") == 0 ||
-                  strcmp(argv[i], "-?") == 0) {
+                  strcmp(argv[i], "-?") == 0 ||
+                   strcmp(argv[i], "--help") == 0) {
            usage();
         } else if (strcmp(argv[i], "-pgpfp") == 0) {
             pgp_fingerprints();
             return 1;
-       } else if (strcmp(argv[i], "-V") == 0) {
+       } else if (strcmp(argv[i], "-V") == 0 ||
+                   strcmp(argv[i], "--version") == 0) {
            version();
        } else if (strcmp(argv[i], "-batch") == 0) {
            console_batch_mode = 1;
@@ -2952,6 +2983,7 @@ int psftp_main(int argc, char *argv[])
     if (back != NULL && back->connected(backhandle)) {
        char ch;
        back->special(backhandle, TS_EOF);
+        sent_eof = TRUE;
        sftp_recvdata(&ch, 1);
     }
     do_sftp_cleanup();