50 bool is_cin_tty() noexcept
52 return 0 != _isatty(_fileno(stdin));
57 HANDLE h_cin = ::GetStdHandle(STD_INPUT_HANDLE);
60 ::GetConsoleMode(h_cin, &mode_old);
61 DWORD mode_new = mode_old & ~((hide_input ? ENABLE_ECHO_INPUT : 0) | ENABLE_LINE_INPUT);
62 ::SetConsoleMode(h_cin, mode_new);
66 std::vector<int> chlen;
72 r = (TRUE == ::ReadConsoleW(h_cin, &ucs2_ch, 1, &read, NULL));
79 else if (ucs2_ch == L
'\r')
81 std::cout << std::endl;
84 else if (ucs2_ch == L
'\b')
88 int len = chlen.back();
96 char utf8_ch[8] = {0};
98 if((len = WideCharToMultiByte(CP_UTF8, 0, &ucs2_ch, 1, utf8_ch,
sizeof(utf8_ch), NULL, NULL)) <= 0)
104 chlen.push_back(len);
108 ::SetConsoleMode(h_cin, mode_old);
115 bool is_cin_tty() noexcept
117 return 0 != isatty(fileno(stdin));
120 int getch(
bool hide_input) noexcept
122 struct termios tty_old;
123 tcgetattr(STDIN_FILENO, &tty_old);
125 struct termios tty_new;
127 tty_new.c_lflag &= ~(ICANON | (hide_input ? ECHO : 0));
128 tcsetattr(STDIN_FILENO, TCSANOW, &tty_new);
132 tcsetattr(STDIN_FILENO, TCSANOW, &tty_old);
139 static constexpr
const char BACKSPACE = 127;
144 int ch = getch(hide_input);
145 if (EOF == ch || ch ==
EOT)
149 else if (ch ==
'\n' || ch ==
'\r')
151 std::cout << std::endl;
154 else if (ch == BACKSPACE)
160 std::cout <<
"\b\b\b \b\b\b" << std::flush;
165 std::cout <<
"\b\b \b\b" << std::flush;
184 std::cout <<
message <<
": " << std::flush;
185 if (!read_from_tty(pass1, hide_input))
189 std::cout <<
"Confirm password: ";
190 if (!read_from_tty(pass2, hide_input))
194 std::cout <<
"Passwords do not match! Please try again." << std::endl;
214 char ch =
static_cast<char>(std::cin.get());
215 if (std::cin.eof() || ch ==
'\n' || ch ==
'\r')
219 else if (std::cin.fail())
242 : m_password(password)
258 if (is_cin_tty() ? read_from_tty(verify,
message, hide_input, pass1.m_password, pass2.m_password) : read_from_file(pass1.m_password))
268 boost::optional<login>
login::parse(
std::string&& userpass,
bool verify,
const std::function<boost::optional<password_container>(
bool)> &prompt)
272 const auto loc = userpass.find(
':');
273 if (loc == std::string::npos)
275 auto result = prompt(verify);
286 out.username = userpass.substr(0, loc);
size_t size() const noexcept
bool empty() const noexcept
std::string message("Message requiring signing")
const T & move(const T &t)