Raise the default scrollback from 200 to 2000 lines. The former was
[u/mdw/putty] / windows / wincons.c
index c38fa01..508be3f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * console.c: various interactive-prompt routines shared between
+ * wincons.c - various interactive-prompt routines shared between
  * the Windows console PuTTY tools
  */
 
@@ -41,7 +41,7 @@ void notify_remote_exit(void *frontend)
 {
 }
 
-void timer_change_notify(long next)
+void timer_change_notify(unsigned long next)
 {
 }
 
@@ -201,7 +201,7 @@ int askalg(void *frontend, const char *algtype, const char *algname,
  * Ask whether to wipe a session log file before writing to it.
  * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
  */
-int askappend(void *frontend, Filename filename,
+int askappend(void *frontend, Filename *filename,
              void (*callback)(void *ctx, int result), void *ctx)
 {
     HANDLE hin;
@@ -223,11 +223,11 @@ int askappend(void *frontend, Filename filename,
     char line[32];
 
     if (console_batch_mode) {
-       fprintf(stderr, msgtemplate_batch, FILENAME_MAX, filename.path);
+       fprintf(stderr, msgtemplate_batch, FILENAME_MAX, filename->path);
        fflush(stderr);
        return 0;
     }
-    fprintf(stderr, msgtemplate, FILENAME_MAX, filename.path);
+    fprintf(stderr, msgtemplate, FILENAME_MAX, filename->path);
     fflush(stderr);
 
     hin = GetStdHandle(STD_INPUT_HANDLE);
@@ -294,52 +294,129 @@ void console_provide_logctx(void *logctx)
 
 void logevent(void *frontend, const char *string)
 {
-    if (console_logctx)
-       log_eventlog(console_logctx, string);
+    log_eventlog(console_logctx, string);
 }
 
-int console_get_line(const char *prompt, char *str,
-                           int maxlen, int is_pw)
+static void console_data_untrusted(HANDLE hout, const char *data, int len)
+{
+    DWORD dummy;
+    /* FIXME: control-character filtering */
+    WriteFile(hout, data, len, &dummy, NULL);
+}
+
+int console_get_userpass_input(prompts_t *p, unsigned char *in, int inlen)
 {
     HANDLE hin, hout;
-    DWORD savemode, newmode, i;
+    size_t curr_prompt;
 
-    if (console_batch_mode) {
-       if (maxlen > 0)
-           str[0] = '\0';
-       return 0;
-    } else {
+    /*
+     * Zero all the results, in case we abort half-way through.
+     */
+    {
+       int i;
+       for (i = 0; i < (int)p->n_prompts; i++)
+            prompt_set_result(p->prompts[i], "");
+    }
+
+    /*
+     * The prompts_t might contain a message to be displayed but no
+     * actual prompt. More usually, though, it will contain
+     * questions that the user needs to answer, in which case we
+     * need to ensure that we're able to get the answers.
+     */
+    if (p->n_prompts) {
+       if (console_batch_mode)
+           return 0;
        hin = GetStdHandle(STD_INPUT_HANDLE);
+       if (hin == INVALID_HANDLE_VALUE) {
+           fprintf(stderr, "Cannot get standard input handle\n");
+           cleanup_exit(1);
+       }
+    }
+
+    /*
+     * And if we have anything to print, we need standard output.
+     */
+    if ((p->name_reqd && p->name) || p->instruction || p->n_prompts) {
        hout = GetStdHandle(STD_OUTPUT_HANDLE);
-       if (hin == INVALID_HANDLE_VALUE || hout == INVALID_HANDLE_VALUE) {
-           fprintf(stderr, "Cannot get standard input/output handles\n");
+       if (hout == INVALID_HANDLE_VALUE) {
+           fprintf(stderr, "Cannot get standard output handle\n");
            cleanup_exit(1);
        }
+    }
+
+    /*
+     * Preamble.
+     */
+    /* We only print the `name' caption if we have to... */
+    if (p->name_reqd && p->name) {
+       size_t l = strlen(p->name);
+       console_data_untrusted(hout, p->name, l);
+       if (p->name[l-1] != '\n')
+           console_data_untrusted(hout, "\n", 1);
+    }
+    /* ...but we always print any `instruction'. */
+    if (p->instruction) {
+       size_t l = strlen(p->instruction);
+       console_data_untrusted(hout, p->instruction, l);
+       if (p->instruction[l-1] != '\n')
+           console_data_untrusted(hout, "\n", 1);
+    }
+
+    for (curr_prompt = 0; curr_prompt < p->n_prompts; curr_prompt++) {
+
+       DWORD savemode, newmode;
+        int len;
+       prompt_t *pr = p->prompts[curr_prompt];
 
        GetConsoleMode(hin, &savemode);
        newmode = savemode | ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT;
-       if (is_pw)
+       if (!pr->echo)
            newmode &= ~ENABLE_ECHO_INPUT;
        else
            newmode |= ENABLE_ECHO_INPUT;
        SetConsoleMode(hin, newmode);
 
-       WriteFile(hout, prompt, strlen(prompt), &i, NULL);
-       ReadFile(hin, str, maxlen - 1, &i, NULL);
+       console_data_untrusted(hout, pr->prompt, strlen(pr->prompt));
+
+        len = 0;
+        while (1) {
+            DWORD ret = 0;
+            BOOL r;
+
+            prompt_ensure_result_size(pr, len * 5 / 4 + 512);
+
+            r = ReadFile(hin, pr->result + len, pr->resultsize - len - 1,
+                         &ret, NULL);
+
+            if (!r || ret == 0) {
+                len = -1;
+                break;
+            }
+            len += ret;
+            if (pr->result[len - 1] == '\n') {
+                len--;
+                if (pr->result[len - 1] == '\r')
+                    len--;
+                break;
+            }
+        }
 
        SetConsoleMode(hin, savemode);
 
-       if ((int) i > maxlen)
-           i = maxlen - 1;
-       else
-           i = i - 2;
-       str[i] = '\0';
+       if (!pr->echo) {
+           DWORD dummy;
+           WriteFile(hout, "\r\n", 2, &dummy, NULL);
+       }
 
-       if (is_pw)
-           WriteFile(hout, "\r\n", 2, &i, NULL);
+        if (len < 0) {
+            return 0;                  /* failure due to read error */
+        }
 
-       return 1;
+       pr->result[len] = '\0';
     }
+
+    return 1; /* success */
 }
 
 void frontend_keypress(void *handle)