dynamic_cast<zypp::media::CurlAuthData*> (&auth_data);
if (auth_data_ptr)
{
-//! \todo move this to prompt help once it's done
-// cout_vv << "available auth types: "
-// << auth_data_ptr->authTypeAsString() << std::endl;
-
- Zypper::instance()->out().prompt(
- PROMPT_AUTH_USERNAME, description, PromptOptions(_("User Name"), 0));
+
+ // user name
+
std::string username;
- std::cin >> username;
- auth_data_ptr->setUserName(username);
+ // expect the input from machine on stdin
+ if (Zypper::instance()->globalOpts().machine_readable)
+ {
+ Zypper::instance()->out().prompt(
+ PROMPT_AUTH_USERNAME, _("User Name"), PromptOptions(), description);
+ std::cin >> username;
+ }
+ // input from human using readline
+ else
+ {
+ std::cout << description << std::endl;
+ username = get_text(_("User Name") + std::string(": "), auth_data.username());
+ }
+ auth_data_ptr->setUsername(username);
+ // password
+
Zypper::instance()->out().prompt(
- PROMPT_AUTH_PASSWORD, description, PromptOptions(_("Password"), 0));
+ PROMPT_AUTH_PASSWORD, _("Password"), PromptOptions());
+
std::string password;
- std::cin >> password;
+ // expect the input from machine on stdin
+ if (Zypper::instance()->globalOpts().machine_readable)
+ std::cin >> password;
+ else
+ password = get_password();
if (password.empty()) return false;
auth_data_ptr->setPassword(password);
cout << CLEARLN;
else
cout << startdesc << endl;
- cout << prompt << " [" << poptions.optionString() << "]: " << std::flush;
+ cout << prompt;
+ if (!poptions.empty())
+ cout << " [" << poptions.optionString() << "]";
+ cout << ": " << std::flush;
}
void OutNormal::promptHelp(const PromptOptions & poptions)
#include <iostream>
#include <sstream>
#include <poll.h>
+#include <readline/readline.h>
+//#include <unistd.h>
+#include <termios.h>
+
#include <boost/format.hpp>
return reply_int;
}
+
+// ---------------------------------------------------------------------------
+
+static const char * prefill = NULL;
+
+static int init_line(void)
+{
+ if (prefill)
+ {
+ rl_replace_line(prefill, 1);
+ rl_end_of_line(1,0);
+ rl_redisplay();
+ }
+ return 1;
+}
+
+string get_text(const string & prompt, const string & prefilled)
+{
+ // A static variable for holding the line.
+ static char * line_read = NULL;
+
+ prefill = prefilled.c_str();
+
+ /* If the buffer has already been allocated,
+ return the memory to the free pool. */
+ if (line_read)
+ {
+ free (line_read);
+ line_read = NULL;
+ }
+
+ rl_pre_input_hook = init_line;
+
+ /* Get a line from the user. */
+ line_read = ::readline (prompt.c_str());
+
+ if (line_read)
+ return line_read;
+ return string();
+}
+
+static int silent_getch ( void )
+{
+ int ch;
+ struct termios oldt, newt;
+
+ tcgetattr ( STDIN_FILENO, &oldt );
+ newt = oldt;
+ newt.c_lflag &= ~( ICANON | ECHO );
+ tcsetattr ( STDIN_FILENO, TCSANOW, &newt );
+ ch = getchar();
+ tcsetattr ( STDIN_FILENO, TCSANOW, &oldt );
+
+ return ch;
+}
+
+/** FIXME is there really not some nice standard library call for this???
+ * is it possible to get this from readline? */
+/** \todo restore old terminal settings on interrupt */
+string get_password()
+{
+ int ch;
+ char pw[20];
+ unsigned i = 0;
+
+ while ((ch = silent_getch()) != EOF
+ && ch != '\n'
+ && ch != '\r'
+ && i < sizeof(pw) - 1)
+ {
+ if (i && (ch == '\b' || ch == 127 /* DEL */))
+ {
+// printf("\b \b"); // does not work for me :O(
+// fflush(stdout);
+ pw[--i] = '\0';
+ }
+ else if (isalnum(ch))
+ {
+// putchar('*');
+ pw[i++] = (char)ch;
+ }
+ }
+
+ pw[i] = '\0';
+ cout << endl;
+
+ return pw;
+}
void setOptions(const std::string & option_str, unsigned int default_opt);
unsigned int defaultOpt() const { return _default; }
const std::string optionString() const;
+ bool empty() const { return _options.empty(); }
const std::string optionHelp(unsigned int opt) const
{ static std::string empty; return opt < _opt_help.size() ? _opt_help[opt] : empty; }
PromptId pid,
const PromptOptions & poptions);
+/**
+ * Get text from user using readline without history.
+ * \param prompt prompt text or empty string
+ * \param prefilled prefilled text
+ */
+std::string get_text(const std::string & prompt, const std::string & prefilled = "");
+
+/**
+ * Get text from user without showing the typed text on the terminal.
+ * Uses getchar(), not suitable for machines.
+ */
+std::string get_password();
+
/*
enum Error {
NO_ERROR,