Adds a parameter to define echoing behaviour in read.  Then one can use
--echo=no or --echo=wildcard to make it suitable for reading passwords.

-- 
Robert Millan

<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)
2008-02-10  Robert Millan  <[EMAIL PROTECTED]>

	* commands/read.c (options): New struct.
	(grub_getline): Receive a hook as argument, that will be invoked
	for each character read instead of directly printing it.  This lets
	the caller choose which action is appropiate.
	Echo the final newline.
	(grub_cmd_read): Parse --echo parameter to determine echoing behaviour.
	Pass a hook to grub_getline() that implements behaviour determined by
	--echo.
	(grub_read_init): Pass `options' parameter to grub_register_command().

diff -x configure -x config.h.in -x CVS -x '*~' -x '*.mk' -urp ../grub2/commands/read.c ./commands/read.c
--- ../grub2/commands/read.c	2008-02-02 21:35:08.000000000 +0100
+++ ./commands/read.c	2008-02-09 22:46:56.000000000 +0100
@@ -24,8 +24,14 @@
 #include <grub/term.h>
 #include <grub/types.h>
 
+static const struct grub_arg_option options[] =
+  {
+    {"echo", 'e', 0, "whether to echo user input", "[yes|no|wildcard]", ARG_TYPE_STRING},
+    {0, 0, 0, 0, 0, 0}
+  };
+
 static char *
-grub_getline (void)
+grub_getline (void (*hook) (char c))
 {
   int i;
   char *line;
@@ -39,8 +45,7 @@ grub_getline (void)
   while ((line[i - 1] != '\n') && (line[i - 1] != '\r'))
     {
       line[i] = grub_getkey ();
-      if (grub_isprint (line[i]))
-	grub_putchar (line[i]);
+      hook (line[i]);
       i++;
       tmp = grub_realloc (line, 1 + i + sizeof('\0'));
       if (! tmp)
@@ -51,14 +56,53 @@ grub_getline (void)
       line = tmp;
     }
   line[i] = '\0';
+  grub_putchar ('\n');
 
   return line;
 }
 
+enum
+{
+  ECHO_YES,
+  ECHO_NO,
+  ECHO_WILDCARD,
+};
+
 static grub_err_t
-grub_cmd_read (struct grub_arg_list *state UNUSED, int argc, char **args)
+grub_cmd_read (struct grub_arg_list *state, int argc, char **args)
 {
-  char *line = grub_getline ();
+  char *line;
+  int echo = ECHO_YES;
+
+  if (state[0].set)
+    {
+      grub_printf ("%s\n", state[0].arg);
+      if (! grub_strcmp (state[0].arg, "no"))
+	echo = ECHO_NO;
+      else if (! grub_strcmp (state[0].arg, "wildcard"))
+	echo = ECHO_WILDCARD;
+      else if (grub_strcmp (state[0].arg, "yes"))
+	return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
+    }
+
+  auto void hook (char);
+  void hook (char c)
+  {
+    if (! grub_isprint (c))
+      return;
+
+    switch (echo)
+      {
+      case ECHO_YES:
+	grub_putchar (c);
+	break;
+      case ECHO_WILDCARD:
+	grub_putchar ('*');
+	break;
+      }
+  }
+
+  line = grub_getline (hook);
   if (! line)
     return grub_errno;
   if (argc > 0)
@@ -72,7 +116,7 @@ grub_cmd_read (struct grub_arg_list *sta
 GRUB_MOD_INIT(read)
 {
   grub_register_command ("read", grub_cmd_read, GRUB_COMMAND_FLAG_CMDLINE,
-			 "read [ENVVAR]", "Set variable with user input", 0);
+			 "read [ENVVAR]", "Set variable with user input", options);
 }
 
 GRUB_MOD_FINI(read)
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to