1 // Copyright (C) 2004 Nico Schottelius <nico-linux-monotone@schottelius.org>
2 //
3 // This program is made available under the GNU GPL version 2.0 or
4 // greater. See the accompanying file COPYING for details.
5 //
6 // This program is distributed WITHOUT ANY WARRANTY; without even the
7 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE.
9 
10 #include "../base.hh"
11 #include <unistd.h>
12 #include <string.h>
13 #include <iostream>
14 #include <windows.h>
15 
16 #include "../sanity.hh"
17 
18 void
read_password(std::string const & prompt,char * buf,size_t bufsz)19 read_password(std::string const & prompt, char * buf, size_t bufsz)
20 {
21   HANDLE mt_stdin;
22   DWORD origmode, pwmode = 0;
23 
24   I(buf != NULL);
25 
26   mt_stdin = GetStdHandle(STD_INPUT_HANDLE);
27   I(mt_stdin != INVALID_HANDLE_VALUE);
28   I(mt_stdin != NULL); // NULL is non-interactive.  Can't get a passphrase if we're non-interactive
29   if (GetConsoleMode(mt_stdin, &origmode) == 0)
30   {
31     /* This looks like we're not a real windows console.
32        Possibly MSYS or Cygwin.  We'll do the best we can
33        to make the password invisible in the absence of tcsetattr,
34        namely emitting vt100 codes to change the foreground and
35        background colour to the same thing.  If someone knows a
36        better way, be my guest. */
37     mt_stdin = NULL;
38   }
39   else
40     pwmode = origmode & (~ENABLE_ECHO_INPUT);
41 
42   memset(buf, 0, bufsz);
43   std::cout << prompt;
44   std::cout.flush();
45 
46   if (mt_stdin != NULL)
47   {
48     I(SetConsoleMode(mt_stdin, pwmode) != 0);
49     std::cin.getline(buf, bufsz, '\n');
50     std::cout << std::endl;
51     I(SetConsoleMode(mt_stdin, origmode) != 0);
52   }
53   else
54   {
55     std::cout << "\x1B\x37\x1B[30;40m";
56     std::cout.flush();
57     fgets(buf, bufsz, stdin); /* Sorry, but cin.getline just doesn't work under MinGW's rxvt */
58     std::cout << "\x1B[0m\x1B\x38\n";
59     std::cout.flush();
60 
61     /* ...and fgets gives us an LF we don't want */
62     size_t bufend = strlen(buf)-1;
63     if (buf[bufend]=='\x0A')
64       buf[bufend] = '\0';
65   }
66 }
67 
68 // Local Variables:
69 // mode: C++
70 // fill-column: 76
71 // c-file-style: "gnu"
72 // indent-tabs-mode: nil
73 // End:
74 // vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:
75