Commit 4261898b11d0a614fcc887ae2d5e9b54c4ee5add

antirez 2020-03-02T17:06:38

A few improvements to mask mode.

diff --git a/README.markdown b/README.markdown
index 9f583c7..1afea2a 100644
--- a/README.markdown
+++ b/README.markdown
@@ -126,6 +126,24 @@ Linenoise has direct support for persisting the history into an history
 file. The functions `linenoiseHistorySave` and `linenoiseHistoryLoad` do
 just that. Both functions return -1 on error and 0 on success.
 
+## Mask mode
+
+Sometimes it is useful to allow the user to type passwords or other
+secrets that should not be displayed. For such situations linenoise supports
+a "mask mode" that will just replace the characters the user is typing 
+with `*` characters, like in the following example:
+
+    $ ./linenoise_example
+    hello> get mykey
+    echo: 'get mykey'
+    hello> /mask
+    hello> *********
+
+You can enable and disable mask mode using the following two functions:
+
+    void linenoiseMaskModeEnable(void);
+    void linenoiseMaskModeDisable(void);
+
 ## Completion
 
 Linenoise supports completion, which is the ability to complete the user
diff --git a/linenoise.c b/linenoise.c
index 8a89835..6d63856 100644
--- a/linenoise.c
+++ b/linenoise.c
@@ -125,7 +125,7 @@ static linenoiseHintsCallback *hintsCallback = NULL;
 static linenoiseFreeHintsCallback *freeHintsCallback = NULL;
 
 static struct termios orig_termios; /* In order to restore at exit.*/
-static int maskmode = 0; /* for mask input mode */
+static int maskmode = 0; /* Show "***" instead of input. For passwords. */
 static int rawmode = 0; /* For atexit() function to check if restore is needed*/
 static int mlmode = 0;  /* Multi line mode. Default is single line. */
 static int atexit_registered = 0; /* Register atexit just 1 time. */
@@ -198,11 +198,16 @@ FILE *lndebug_fp = NULL;
 
 /* ======================= Low level terminal handling ====================== */
 
-void linenoiseMaskModeEnable() {
+/* Enable "mask mode". When it is enabled, instead of the input that
+ * the user is typing, the terminal will just display a corresponding
+ * number of asterisks, like "****". This is useful for passwords and other
+ * secrets that should not be displayed. */
+void linenoiseMaskModeEnable(void) {
     maskmode = 1;
 }
 
-void linenoiseMaskModeDisable() {
+/* Disable mask mode. */
+void linenoiseMaskModeDisable(void) {
     maskmode = 0;
 }
 
@@ -535,11 +540,10 @@ static void refreshSingleLine(struct linenoiseState *l) {
     /* Write the prompt and the current buffer content */
     abAppend(&ab,l->prompt,strlen(l->prompt));
     if (maskmode == 1) {
-        while (len--) {
-            abAppend(&ab,"*",1);
-        }
-    } else
+        while (len--) abAppend(&ab,"*",1);
+    } else {
         abAppend(&ab,buf,len);
+    }
     /* Show hits if any. */
     refreshShowHints(&ab,l,plen);
     /* Erase to right */
@@ -594,11 +598,10 @@ static void refreshMultiLine(struct linenoiseState *l) {
     /* Write the prompt and the current buffer content */
     abAppend(&ab,l->prompt,strlen(l->prompt));
     if (maskmode == 1) {
-        for (uint i = 0; i < l->len; i++) {
-            abAppend(&ab,"*",1);
-        }
-    } else
+        for (uint i = 0; i < l->len; i++) abAppend(&ab,"*",1);
+    } else {
         abAppend(&ab,l->buf,l->len);
+    }
 
     /* Show hits if any. */
     refreshShowHints(&ab,l,plen);
diff --git a/linenoise.h b/linenoise.h
index d031ed0..6dfee73 100644
--- a/linenoise.h
+++ b/linenoise.h
@@ -65,9 +65,8 @@ int linenoiseHistoryLoad(const char *filename);
 void linenoiseClearScreen(void);
 void linenoiseSetMultiLine(int ml);
 void linenoisePrintKeyCodes(void);
-
-void linenoiseMaskModeEnable();
-void linenoiseMaskModeDisable();
+void linenoiseMaskModeEnable(void);
+void linenoiseMaskModeDisable(void);
 
 #ifdef __cplusplus
 }