//template<typename Action>
//Action ...
int read_action_ari (int default_action) {
- if (gSettings.verbosity >= 0 || !gSettings.non_interactive)
- // TranslatorExplanation don't translate letters in parentheses!!
- cout << _("(A)bort, (R)etry, (I)gnore?") << " ";
+ // TranslatorExplanation don't translate letters in parentheses!!
+ cout << _("(A)bort, (R)etry, (I)gnore?") << " ";
// choose abort if no default has been specified
if (default_action == -1) {
default: c = '?';
}
// print the answer for conveniecne
- cout_n << c << endl;
-
+ cout << c << endl;
+ MIL << "answer: " << c << endl;
return default_action;
}
char c;
cin >> c;
c = tolower (c);
+ MIL << "answer: " << c << endl;
if (c == 'a')
return 0;
else if (c == 'r')
else if (c == 'i')
return 2;
cerr << _("Invalid answer. Choose letter a, r, or i.") << endl;
+ DBG << "invalid answer" << endl;
}
return default_action;
// ----------------------------------------------------------------------------
-// return the default value on input failure
-// TODO make this locale dependent?
-bool read_bool_with_default (bool defval) {
+// Read an answer (ynYN)
+bool read_bool_answer(const string & question, bool default_answer)
+{
+ cout << CLEARLN << question << " [y/n]: " << flush;
+
+ // non-interactive mode: print the answer for convenience and return default
+ if (gSettings.non_interactive)
+ {
+ cout << (default_answer ? 'y' : 'n') << endl;
+ MIL << "answer (default): " << (default_answer ? 'y' : 'n') << endl;
+ return default_answer;
+ }
+
istream & stm = cin;
string c = "";
while (stm.good () && c != "y" && c != "Y" && c != "N" && c != "n")
c = zypp::str::getline (stm, zypp::str::TRIM);
-
+
+ MIL << "answer: " << c << endl;
if (c == "y" || c == "Y")
return true;
else if (c == "n" || c == "N")
return false;
else
- return defval;
-}
-
-// ----------------------------------------------------------------------------
-
-// Read an answer (ynYN)
-// Defaults to 'false'
-bool readBoolAnswer()
-{
- return read_bool_with_default (false);
+ {
+ WAR << "could not read answer, returning default: "
+ << (default_answer ? 'y' : 'n') << endl;
+ return default_answer;
+ }
}
// ----------------------------------------------------------------------------
}
}
-/**
+/**
* Abort, Retry, Ignore stdin prompt.
* \param default_action Answer to be returned in non-interactive mode. If none
- * is specified, 0 (ABORT) is returned. In interactive mode, this parameter
+ * is specified, 0 (ABORT) is returned. In interactive mode, this parameter
* is ignored.
*/
int read_action_ari (int default_action = -1);
/**
* Prompt for Yes/No answer from stdin.
- *
- * \todo work with default
- * \todo non-interactive mode
+ *
+ * \param question Question to be printed on prompt.
+ * \param default_answer Value to be returned in non-interactive mode or on
+ * input failure.
+ *
* \todo make this localized
*/
-bool readBoolAnswer();
+bool read_bool_answer(const string & question, bool default_answer);
std::string to_string (zypp::Resolvable::constPtr resolvable);
#endif
#include <stdlib.h>
#include <iostream>
+#include <boost/format.hpp>
#include <zypp/base/Logger.h>
#include <zypp/ZYppCallbacks.h>
{
virtual bool askUserToAcceptUnsignedFile( const std::string &file )
{
- cout << CLEARLN << file << _(" is unsigned, continue?") << " [y/n]: " << flush;
- return readBoolAnswer();
+ if (gSettings.no_gpg_checks)
+ {
+ MIL << "Accepting unsigned file (" << file << ")" << endl;
+ cout_v << boost::format(_("Warning: Accepting an unsigned file %s.")) % file;
+ return true;
+ }
+
+ // TranslatorExplanation: speaking of a file
+ std::string question = boost::str(boost::format(
+ _("%s is unsigned, continue?")) % file);
+ return read_bool_answer(question, false);
}
-
+
virtual bool askUserToImportKey( const PublicKey &key )
{
if ( geteuid() != 0 )
return false;
-
- cout << CLEARLN << _("Import key ") << key.id() << _(" to trusted keyring?") << " [y/n]: " << flush;
- return readBoolAnswer();
- }
+
+ std::string question = boost::str(boost::format(
+ _("Import key %s to trusted keyring?")) % key.id());
+ return read_bool_answer(question, false);
+ }
virtual bool askUserToAcceptUnknownKey( const std::string &file, const std::string &id )
{
- cout << CLEARLN << file << _(" is signed with an unknown key id: ") << id << ", " << _("continue?") << " [y/n]: " << flush;
- return readBoolAnswer();
+ if (gSettings.no_gpg_checks)
+ {
+ MIL << "Accepting file signed with an unknown key (" << file << "," << id << ")" << endl;
+ cout_n << boost::format(
+ _("Warnging: Accepting file %s signed with an unknown key %s."))
+ % file % id;
+ return true;
+ }
+
+ // TranslatorExplanation: speaking of a file
+ std::string question = boost::str(boost::format(
+ _("%s is signed with an unknown key %s. Continue?")) % file % id);
+ return read_bool_answer(question, false);
}
virtual bool askUserToTrustKey( const PublicKey &key )
{
const std::string& keyid = key.id(), keyname = key.name(),
fingerprint = key.fingerprint();
- cout << CLEARLN << _("Do you want to trust key id ") << keyid << " " << keyname << _(" fingerprint:") << fingerprint << " ? [y/n]: " << flush;
- return readBoolAnswer();
+
+ if (gSettings.no_gpg_checks)
+ {
+ MIL << boost::format("Automatically trusting key id %s, %s, fingerprint %s")
+ % keyid % keyname % fingerprint << endl;
+ cout_n << boost::format(
+ _("Automatically trusting key id %s, %s, fingerprint %s"))
+ % keyid % keyname % fingerprint << endl;
+ return true;
+ }
+
+ std::string question = boost::str(boost::format(
+ _("Do you want to trust key id %s, %s, fingerprint %s"))
+ % keyid % keyname % fingerprint);
+ return read_bool_answer(question, false);
}
virtual bool askUserToAcceptVerificationFailed( const std::string &file,const PublicKey &key )
{
const std::string& keyid = key.id(), keyname = key.name(),
fingerprint = key.fingerprint();
- cout << file << _("Signature verification for ") << file
- << _(" with public key id ") << keyid << " " << keyname << _(" fingerprint:") << fingerprint << _(" failed, THIS IS RISKY!") << ". " << _("continue?") << " [y/n]: " << endl;
- return readBoolAnswer(); // TODO do this with format()
+
+ if (gSettings.no_gpg_checks)
+ {
+ MIL << boost::format(
+ "Ignoring failed signature verification for %s"
+ " with public key id %s, %s, fingerprint %s")
+ % file % keyid % keyname % fingerprint << endl;
+ cerr << boost::format(
+ _("Warning: Ignoring failed signature verification for %s"
+ " with public key id %s, %s, fingerprint %s!"
+ " Double-check this is not caused by some malicious"
+ " changes in the file!"))
+ %file % keyid % keyname % fingerprint << endl;
+ return true;
+ }
+
+ std::string question = boost::str(boost::format(
+ _("Signature verification failed for %s"
+ " with public key id %s, %s, fingerprint %s."
+ " Warning: this might be caused by a malicious change in the file!"
+ " Continuing is risky! Continue anyway?"))
+ % file % keyid % keyname % fingerprint);
+ return read_bool_answer(question, false);
}
};
-
struct DigestReceive : public zypp::callback::ReceiveReport<zypp::DigestReport>
{
virtual bool askUserToAcceptNoDigest( const zypp::Pathname &file )
{
- cout << CLEARLN << _("No digest for ") << file
- << ", " << _("continue?") << " [y/n]" << flush;
- return readBoolAnswer();
+ std::string question = boost::str(boost::format(
+ _("No digest for file %s.")) % file) + " " + _("Continue?");
+ return read_bool_answer(question, gSettings.no_gpg_checks);
}
+
virtual bool askUserToAccepUnknownDigest( const Pathname &file, const std::string &name )
{
- cout << CLEARLN << _("Unknown digest ") << name << _(" for ") << file
- << ", " << _("continue?") << " [y/n]" << flush;
- return readBoolAnswer();
+ std::string question = boost::str(boost::format(
+ _("Unknown digest %s for file %s.")) %name % file) + " " +
+ _("Continue?");
+ return read_bool_answer(question, gSettings.no_gpg_checks);
}
+
virtual bool askUserToAcceptWrongDigest( const Pathname &file, const std::string &requested, const std::string &found )
{
- cout << CLEARLN << _("Digest verification failed for ") << file
- << _(", expected ") << requested << _(" found ") << found
- << ", " << _("continue?") << " [y/n]" << flush;
- return readBoolAnswer();
+ if (gSettings.no_gpg_checks)
+ {
+ WAR << boost::format(
+ "Ignoring failed digest verification for %s (expected %s, found %s).")
+ % file % requested % found << endl;
+ cerr << boost::format(
+ _("Ignoring failed digest verification for %s (expected %s, found %s)."))
+ % file % requested % found << endl;
+ return true;
+ }
+
+ std::string question = boost::str(boost::format(
+ _("Digest verification failed for %s. Expected %s, found %s."))
+ % file % requested % found) + " " + _("Continue?");
+ return read_bool_answer(question, false);
}
};
int retv = show_summary();
if (retv >= 0) { // there are resolvables to install/uninstall
- cerr << _("Continue?") << " [y/n] " << (non_interactive ? "y\n" : "");
- if (non_interactive || readBoolAnswer()) {
+ if (read_bool_answer(_("Continue?"), non_interactive)) {
if (!confirm_licenses(non_interactive)) return ZYPPER_EXIT_OK;
return retv;
}
-// TODO
+// TODO confirm licenses
// - make this more user-friendly e.g. show only license name and
// ask for [y/n/r] with 'r' for read the license text
// (opened throu more or less, etc...)
" " << _("license") << ": " <<
it->resolvable()->licenseToConfirm() << endl;
- cout << _("In order to install this package, you must agree"
- " to terms of the above licencse. Continue?") << " [y/n] " <<
- (non_interactive ? "n\n" : "");
+ string question = _("In order to install this package, you must agree"
+ " to terms of the above licencse. Continue?");
- if (non_interactive || !readBoolAnswer())
+ if (non_interactive || !read_bool_answer(question, false))
{
confirmed = false;
DigestCallbacks digest_callbacks;
static struct option global_options[] = {
- {"help", no_argument, 0, 'h'},
- {"verbose", no_argument, 0, 'v'},
- {"quiet", no_argument, 0, 'q'},
- {"version", no_argument, 0, 'V'},
- {"terse", no_argument, 0, 't'},
- {"table-style", required_argument, 0, 's'},
- {"rug-compatible", no_argument, 0, 'r'},
- {"non-interactive", no_argument, 0, 0},
- {"root", required_argument, 0, 'R'},
- {"opt", optional_argument, 0, 'o'},
+ {"help", no_argument, 0, 'h'},
+ {"verbose", no_argument, 0, 'v'},
+ {"quiet", no_argument, 0, 'q'},
+ {"version", no_argument, 0, 'V'},
+ {"terse", no_argument, 0, 't'},
+ {"table-style", required_argument, 0, 's'},
+ {"rug-compatible", no_argument, 0, 'r'},
+ {"non-interactive", no_argument, 0, 0},
+ {"no-gpg-checks", no_argument, 0, 0},
+ {"root", required_argument, 0, 'R'},
+ {"opt", optional_argument, 0, 'o'},
{0, 0, 0, 0}
};
if (gopts.count("verbose")) {
gSettings.verbosity += gopts["verbose"].size();
cout << _("Verbosity ") << gSettings.verbosity << endl;
- DBG << _("Verbosity ") << gSettings.verbosity << endl;
+ DBG << "Verbosity " << gSettings.verbosity << endl;
}
if (gopts.count("non-interactive")) {
- gSettings.non_interactive = true;
- cout_n << "Entering non-interactive mode.\n"
- "WARNING: global non-interactive mode is still under development, use "
- "with caution. This mode has been implemented and tested for install, "
- "remove, and update commands so far. In case of problems related to "
- "non-interactive mode, please file a bugreport following instructions at "
- "http://en.opensuse.org/Zypper#Troubleshooting" << endl;
+ gSettings.non_interactive = true;
+ MIL << "Entering non-interactive mode" << endl;
+ }
+
+ if (gopts.count("no-gpg-checks")) {
+ gSettings.no_gpg_checks = true;
+ MIL << "Entering no-gpg-checks mode" << endl;
}
if (gopts.count("table-style")) {
disable_system_resolvables(false),
is_rug_compatible(false),
non_interactive(false),
+ no_gpg_checks(false),
root_dir("/")
{}
bool disable_system_resolvables;
bool is_rug_compatible;
bool non_interactive;
+ bool no_gpg_checks;
std::string root_dir;
};