# # # patch "cmd.cc" # from [7e2e64e4e7b59b0f4075a863c25e8e1838caa920] # to [1cfec6b4c6f2737366730df48bbe1b4f65beb5b6] # # patch "cmd_merging.cc" # from [bd6bb3cad56c7fee89fdf2d1c81ce36bc1546306] # to [883fada25173b9e2800de82dc275c6d70cd33619] # # patch "cmd_netsync.cc" # from [ecd5695708dce9eb261fe9fc9a7ec85ba922d4af] # to [fdb66061c29fdb835bc36237373c56ee851d66ef] # # patch "cmd_ws_commit.cc" # from [08e292636ad9de411dc2c8c65cf5a819f49b505d] # to [b9d4815bb8a9a6659377894d3d5a53539627dbd7] # # patch "database.cc" # from [7edf90a2cf52fa99c7b17cc65a0fc5be6bc51526] # to [dd8fc4956a4c268e83fb6e0c27acabaea3f00cae] # # patch "key_store.cc" # from [e11141e0fa1143dece96d218a45417c92da2b84e] # to [894ba4461706e3df33cb48f9ca1b8262908cd5ea] # # patch "keys.cc" # from [dc4b299f4dd152486ecc4c27b8a62b6994be621d] # to [1528a27ad3ac8a35b53954213b61ed8fbef90a28] # # patch "keys.hh" # from [a3b8a5108dc2d418f906403189a4b62a2299097b] # to [665e7f1f1dd80336bb3d961522da79aac4c2fe89] # # patch "monotone.cc" # from [afde49109945b4b1f47ac59d839cd5578968189b] # to [d1186612064cb061d088c85c7e50913d0c71e358] # # patch "netsync.cc" # from [bd455bf5537bd9b1d6dc33a255ad3fd9aec03a74] # to [10ad35a13e22f634408841417f955416b2ec4ec3] # # patch "project.cc" # from [ceed59b027d62e68f882420c3323ac8e48a5f7da] # to [c33b13a28918d13f35351966e7e34b627ca990ef] # # patch "revision.cc" # from [22fdf74939ce38e4d1f512b9fffebbdb66aa329d] # to [6528ec814b79a8409430e132a8dbbb0276ce831d] # # patch "sanity.cc" # from [b1af0d0fe1c4aa81666e23b0e6e9427c22165143] # to [1176978de39b1db2ae77993c2085fcd7230c7d28] # # patch "sanity.hh" # from [400b88cfe22b73c5fecdf10fef41a7fe26c5b69c] # to [e9013683f4ec9a97c3e522296bf87e0f5eb72cba] # # patch "schema_migration.cc" # from [d1573a5d69b208dbbf1face97592b70b7e8bf79e] # to [6454e7300e77b074e1cadcb928091f351e11ae19] # # patch "ui.cc" # from [cbee345d5859b445b47730c1cb779cc02da6d9a1] # to [617c42e7a6cc179979544fc0db59383a8f8ffafc] # # patch "ui.hh" # from [2ca5d4fa5a7b2c36a89fa5f84c36603b9818d861] # to [698164ee671be4906fe4c8ee03a3b8fd001de5d6] # # patch "work.cc" # from [adae88cb01a3e6b39f1f3e593f45ed9c121e66a5] # to [e2ed785cc9a7ec181639bf9c5ce989855997ab9b] # # patch "work_migration.cc" # from [fdd7b30d20ed4ab79dfea448b7c40e4137140d7a] # to [b0e7ef6fdc52db96cf7567c5cfb4ae007ba40ef0] # ============================================================ --- cmd.cc 7e2e64e4e7b59b0f4075a863c25e8e1838caa920 +++ cmd.cc 1cfec6b4c6f2737366730df48bbe1b4f65beb5b6 @@ -212,11 +212,11 @@ namespace commands { { if (!cmd->children().empty()) out << format_text(F("Subcommands of '%s %s':") % - ui.prog_name % visibleid) + prog_name % visibleid) << "\n\n"; else if (!lines.empty()) out << format_text(F("Syntax specific to '%s %s':") % - ui.prog_name % visibleid) + prog_name % visibleid) << "\n\n"; } @@ -244,7 +244,7 @@ namespace commands { << "\n\n"; else out << format_text(F("Description for '%s %s':") % - ui.prog_name % visibleid) + prog_name % visibleid) << "\n\n"; out << format_text(cmd->desc(), 2) << "\n\n"; ============================================================ --- cmd_merging.cc bd6bb3cad56c7fee89fdf2d1c81ce36bc1546306 +++ cmd_merging.cc 883fada25173b9e2800de82dc275c6d70cd33619 @@ -24,7 +24,6 @@ #include "update.hh" #include "work.hh" #include "safe_map.hh" -#include "ui.hh" #include "app_state.hh" #include "project.hh" #include "simplestring_xform.hh" @@ -192,7 +191,7 @@ CMD(update, "update", "", CMD_REF(worksp i != candidates.end(); ++i) P(i18n_format(" %s") % describe_revision(project, *i)); - P(F("choose one with '%s update -r'") % ui.prog_name); + P(F("choose one with '%s update -r'") % prog_name); E(false, origin::user, F("multiple update candidates remain after selection")); } @@ -1174,7 +1173,7 @@ CMD(pluck, "pluck", "", CMD_REF(workspac "to apply the changes relative to one of its parents, use:\n" " %s pluck -r PARENT -r %s") % to_rid - % ui.prog_name + % prog_name % to_rid); from_rid = *parents.begin(); } ============================================================ --- cmd_netsync.cc ecd5695708dce9eb261fe9fc9a7ec85ba922d4af +++ cmd_netsync.cc fdb66061c29fdb835bc36237373c56ee851d66ef @@ -8,7 +8,6 @@ #include "key_store.hh" #include "cert.hh" #include "revision.hh" -#include "ui.hh" #include "uri.hh" #include "vocab_cast.hh" #include "platform-wrapped.hh" @@ -413,7 +412,7 @@ CMD(clone, "clone", "", CMD_REF(network) for (set::const_iterator i = heads.begin(); i != heads.end(); ++i) P(i18n_format(" %s") % describe_revision(project, *i)); - P(F("choose one with '%s clone -r SERVER BRANCH'") % ui.prog_name); + P(F("choose one with '%s clone -r SERVER BRANCH'") % prog_name); E(false, origin::user, F("branch %s has multiple heads") % branchname); } ident = *(heads.begin()); ============================================================ --- cmd_ws_commit.cc 08e292636ad9de411dc2c8c65cf5a819f49b505d +++ cmd_ws_commit.cc b9d4815bb8a9a6659377894d3d5a53539627dbd7 @@ -19,7 +19,6 @@ #include "transforms.hh" #include "work.hh" #include "charset.hh" -#include "ui.hh" #include "app_state.hh" #include "project.hh" #include "basic_io.hh" @@ -636,7 +635,7 @@ CMD(checkout, "checkout", "co", CMD_REF( for (set::const_iterator i = heads.begin(); i != heads.end(); ++i) P(i18n_format(" %s") % describe_revision(project, *i)); - P(F("choose one with '%s checkout -r'") % ui.prog_name); + P(F("choose one with '%s checkout -r'") % prog_name); E(false, origin::user, F("branch %s has multiple heads") % app.opts.branchname); } @@ -1320,7 +1319,7 @@ CMD(commit, "commit", "ci", CMD_REF(work if (heads.size() > old_head_size && old_head_size > 0) { P(F("note: this revision creates divergence\n" "note: you may (or may not) wish to run '%s merge'") - % ui.prog_name); + % prog_name); } work.update_any_attrs(db); @@ -1418,7 +1417,7 @@ CMD_NO_WORKSPACE(import, "import", "", C for (set::const_iterator i = heads.begin(); i != heads.end(); ++i) P(i18n_format(" %s") % describe_revision(project, *i)); - P(F("choose one with '%s import -r'") % ui.prog_name); + P(F("choose one with '%s import -r'") % prog_name); E(false, origin::user, F("branch %s has multiple heads") % app.opts.branchname); } ============================================================ --- database.cc 7edf90a2cf52fa99c7b17cc65a0fc5be6bc51526 +++ database.cc dd8fc4956a4c268e83fb6e0c27acabaea3f00cae @@ -39,7 +39,6 @@ #include "sanity.hh" #include "schema_migration.hh" #include "transforms.hh" -#include "ui.hh" #include "vocab.hh" #include "vocab_cast.hh" #include "xdelta.hh" @@ -493,7 +492,7 @@ database_impl::check_format() origin::no_fault, F("database %s lacks some cached data\n" "run '%s db regenerate_caches' to restore use of this database") - % filename % ui.prog_name); + % filename % prog_name); } else { ============================================================ --- key_store.cc e11141e0fa1143dece96d218a45417c92da2b84e +++ key_store.cc 894ba4461706e3df33cb48f9ca1b8262908cd5ea @@ -12,6 +12,8 @@ #include "constants.hh" #include "ssh_agent.hh" #include "safe_map.hh" +#include "charset.hh" +#include "ui.hh" #include "botan/botan.h" #include "botan/rsa.h" @@ -374,6 +376,65 @@ key_store::delete_key(rsa_keypair_id con // Crypto operations // +// "raw" passphrase prompter; unaware of passphrase caching or the laziness +// hook. KEYID is used only in prompts. CONFIRM_PHRASE causes the user to +// be prompted to type the same thing twice, and will loop if they don't +// match. Prompts are worded slightly differently if GENERATING_KEY is true. +static void +get_passphrase(utf8 & phrase, + rsa_keypair_id const & keyid, + bool confirm_phrase, + bool generating_key) +{ + string prompt1, prompt2; + char pass1[constants::maxpasswd]; + char pass2[constants::maxpasswd]; + int i = 0; + + if (confirm_phrase && !generating_key) + prompt1 = (F("enter new passphrase for key ID [%s]: ") % keyid).str(); + else + prompt1 = (F("enter passphrase for key ID [%s]: ") % keyid).str(); + + if (confirm_phrase) + prompt2 = (F("confirm passphrase for key ID [%s]: ") % keyid).str(); + + try + { + for (;;) + { + memset(pass1, 0, constants::maxpasswd); + memset(pass2, 0, constants::maxpasswd); + ui.ensure_clean_line(); + + read_password(prompt1, pass1, constants::maxpasswd); + if (!confirm_phrase) + break; + + ui.ensure_clean_line(); + read_password(prompt2, pass2, constants::maxpasswd); + if (strcmp(pass1, pass2) == 0) + break; + + E(i++ < 2, origin::user, F("too many failed passphrases")); + P(F("passphrases do not match, try again")); + } + + external ext_phrase(pass1); + system_to_utf8(ext_phrase, phrase); + } + catch (...) + { + memset(pass1, 0, constants::maxpasswd); + memset(pass2, 0, constants::maxpasswd); + throw; + } + memset(pass1, 0, constants::maxpasswd); + memset(pass2, 0, constants::maxpasswd); +} + + + shared_ptr key_store_state::decrypt_private_key(rsa_keypair_id const & id, bool force_from_user) ============================================================ --- keys.cc dc4b299f4dd152486ecc4c27b8a62b6994be621d +++ keys.cc 1528a27ad3ac8a35b53954213b61ed8fbef90a28 @@ -12,7 +12,6 @@ #include "keys.hh" #include "sanity.hh" -#include "ui.hh" #include "constants.hh" #include "platform.hh" #include "transforms.hh" @@ -30,63 +29,6 @@ using std::memset; // there will probably forever be bugs in this file. it's very // hard to get right, portably and securely. sorry about that. -// "raw" passphrase prompter; unaware of passphrase caching or the laziness -// hook. KEYID is used only in prompts. CONFIRM_PHRASE causes the user to -// be prompted to type the same thing twice, and will loop if they don't -// match. Prompts are worded slightly differently if GENERATING_KEY is true. -void -get_passphrase(utf8 & phrase, - rsa_keypair_id const & keyid, - bool confirm_phrase, - bool generating_key) -{ - string prompt1, prompt2; - char pass1[constants::maxpasswd]; - char pass2[constants::maxpasswd]; - int i = 0; - - if (confirm_phrase && !generating_key) - prompt1 = (F("enter new passphrase for key ID [%s]: ") % keyid).str(); - else - prompt1 = (F("enter passphrase for key ID [%s]: ") % keyid).str(); - - if (confirm_phrase) - prompt2 = (F("confirm passphrase for key ID [%s]: ") % keyid).str(); - - try - { - for (;;) - { - memset(pass1, 0, constants::maxpasswd); - memset(pass2, 0, constants::maxpasswd); - ui.ensure_clean_line(); - - read_password(prompt1, pass1, constants::maxpasswd); - if (!confirm_phrase) - break; - - ui.ensure_clean_line(); - read_password(prompt2, pass2, constants::maxpasswd); - if (strcmp(pass1, pass2) == 0) - break; - - E(i++ < 2, origin::user, F("too many failed passphrases")); - P(F("passphrases do not match, try again")); - } - - external ext_phrase(pass1); - system_to_utf8(ext_phrase, phrase); - } - catch (...) - { - memset(pass1, 0, constants::maxpasswd); - memset(pass2, 0, constants::maxpasswd); - throw; - } - memset(pass1, 0, constants::maxpasswd); - memset(pass2, 0, constants::maxpasswd); -} - // Loads a key pair for a given key id, considering it a user error // if that key pair is not available. ============================================================ --- keys.hh a3b8a5108dc2d418f906403189a4b62a2299097b +++ keys.hh 665e7f1f1dd80336bb3d961522da79aac4c2fe89 @@ -23,12 +23,6 @@ struct keypair; // could in theory be in transforms.cc too, but that file's already kinda // big and this stuff "feels" different, imho. -void -get_passphrase(utf8 & phrase, - rsa_keypair_id const & keyid, - bool confirm_phrase, - bool generating_key); - // N()'s out if there is no unique key for us to use void get_user_key(options const & opts, lua_hooks & lua, database & db, key_store & keys, ============================================================ --- monotone.cc afde49109945b4b1f47ac59d839cd5578968189b +++ monotone.cc d1186612064cb061d088c85c7e50913d0c71e358 @@ -161,6 +161,8 @@ cpp_main(int argc, char ** argv) int cpp_main(int argc, char ** argv) { + string real_prog_name; + // go-go gadget i18n localize_monotone(); @@ -173,7 +175,8 @@ cpp_main(int argc, char ** argv) try { // Set up the global sanity object. No destructor is needed and - // therefore no wrapper object is needed either. + // therefore no wrapper object is needed either. This has the + // side effect of making the 'prog_name' global usable. global_sanity.initialize(argc, argv, setlocale(LC_ALL, 0)); // Set up secure memory allocation etc @@ -200,18 +203,6 @@ cpp_main(int argc, char ** argv) args.push_back(arg_type(ut)); } - // find base name of executable, convert to utf8, and save it in the - // global ui object - { - utf8 argv0_u; - system_to_utf8(external(argv[0]), argv0_u); - string prog_name = system_path(argv0_u).basename()(); - if (prog_name.rfind(".exe") == prog_name.size() - 4) - prog_name = prog_name.substr(0, prog_name.size() - 4); - ui.prog_name = prog_name; - I(!ui.prog_name.empty()); - } - app_state app; try { @@ -301,7 +292,7 @@ cpp_main(int argc, char ** argv) u.which.end()))(); usage_stream << F("Usage: %s [OPTION...] command [ARG...]") % - ui.prog_name << "\n\n"; + prog_name << "\n\n"; if (u.which.empty()) usage_stream << get_usage_str(options::opts::globals(), app.opts); @@ -315,7 +306,7 @@ cpp_main(int argc, char ** argv) usage_stream << F("Options specific to '%s %s' " "(run '%s help' to see global options):") - % ui.prog_name % visibleid % ui.prog_name + % prog_name % visibleid % prog_name << "\n\n"; usage_stream << get_usage_str(cmd_options, app.opts); } ============================================================ --- netsync.cc bd455bf5537bd9b1d6dc33a255ad3fd9aec03a74 +++ netsync.cc 10ad35a13e22f634408841417f955416b2ec4ec3 @@ -1608,7 +1608,7 @@ session::process_hello_cmd(rsa_keypair_i "'%s unset %s %s' overrides this check") % printable_key_hash % expected_key_hash - % ui.prog_name % their_key_key.first % their_key_key.second); + % prog_name % their_key_key.first % their_key_key.second); E(false, origin::network, F("server key changed")); } } @@ -1635,7 +1635,7 @@ session::process_hello_cmd(rsa_keypair_i "on your local database before you run this command again,\n" "assuming that key currently present in your database does NOT have\n" "a private counterpart (or in other words, is one of YOUR keys)") - % their_keyname % ui.prog_name % their_keyname); + % their_keyname % prog_name % their_keyname); } else { ============================================================ --- project.cc ceed59b027d62e68f882420c3323ac8e48a5f7da +++ project.cc c33b13a28918d13f35351966e7e34b627ca990ef @@ -12,7 +12,6 @@ #include "lua_hooks.hh" #include "keys.hh" #include "options.hh" -#include "ui.hh" #include "vocab_cast.hh" #include "simplestring_xform.hh" @@ -416,7 +415,7 @@ notify_if_multiple_heads(project_t & pro _("branch '%s' has multiple heads\n" "perhaps consider '%s merge'"), prefixedline); - P(i18n_format(prefixedline) % branchname % ui.prog_name); + P(i18n_format(prefixedline) % branchname % prog_name); } } ============================================================ --- revision.cc 22fdf74939ce38e4d1f512b9fffebbdb66aa329d +++ revision.cc 6528ec814b79a8409430e132a8dbbb0276ce831d @@ -33,7 +33,6 @@ #include "sanity.hh" #include "transforms.hh" #include "simplestring_xform.hh" -#include "ui.hh" #include "vocab.hh" #include "safe_map.hh" #include "legacy.hh" @@ -44,6 +43,7 @@ #include "graph.hh" #include "key_store.hh" #include "vocab_cast.hh" +#include "ui.hh" using std::back_inserter; using std::copy; @@ -765,7 +765,7 @@ make_restricted_revision(parent_map cons E(old_rosters.size() == 1 || no_excludes, origin::user, F("the command '%s %s' cannot be restricted in a two-parent workspace") - % ui.prog_name % cmd_name); + % prog_name % cmd_name); recalculate_manifest_id_for_restricted_rev(old_rosters, edges, rev); } ============================================================ --- sanity.cc b1af0d0fe1c4aa81666e23b0e6e9427c22165143 +++ sanity.cc 1176978de39b1db2ae77993c2085fcd7230c7d28 @@ -37,6 +37,10 @@ using boost::format; using boost::format; +extern string const & prog_name; +static string real_prog_name; +string const & prog_name = real_prog_name; + string origin::type_to_string(origin::type t) { @@ -118,6 +122,15 @@ sanity::initialize(int argc, char ** arg lc_all = "n/a"; PERM_MM(string(lc_all)); L(FL("set locale: LC_ALL=%s") % lc_all); + + // find base name of executable and save in the prog_name global note that + // this does not bother with conversion to utf8. + real_prog_name = argv[0]; + if (real_prog_name.rfind(".exe") == prog_name.size() - 4) + real_prog_name = real_prog_name.substr(0, prog_name.size() - 4); + string::size_type last_slash = real_prog_name.find_last_of("/\\"); + if (last_slash != string::npos) + real_prog_name.erase(0, last_slash); } void ============================================================ --- sanity.hh 400b88cfe22b73c5fecdf10fef41a7fe26c5b69c +++ sanity.hh e9013683f4ec9a97c3e522296bf87e0f5eb72cba @@ -111,6 +111,7 @@ extern sanity & global_sanity; }; extern sanity & global_sanity; +extern std::string const & prog_name; typedef std::runtime_error oops; ============================================================ --- schema_migration.cc d1573a5d69b208dbbf1face97592b70b7e8bf79e +++ schema_migration.cc 6454e7300e77b074e1cadcb928091f351e11ae19 @@ -17,7 +17,6 @@ #include "schema_migration.hh" #include "key_store.hh" #include "transforms.hh" -#include "ui.hh" #include "constants.hh" using std::string; @@ -972,7 +971,7 @@ diagnose_unrecognized_schema(schema_mism E(cat != SCHEMA_EMPTY, origin::user, F("cannot use the empty sqlite database %s\n" "(monotone databases must be created with '%s db init')") - % filename % ui.prog_name); + % filename % prog_name); E(cat != SCHEMA_NOT_MONOTONE, origin::user, F("%s does not appear to be a monotone database\n") @@ -1001,7 +1000,7 @@ check_sql_schema(sqlite3 * db, system_pa F("database %s is laid out according to an old schema\n" "try '%s db migrate' to upgrade\n" "(this is irreversible; you may want to make a backup copy first)") - % filename % ui.prog_name); + % filename % prog_name); } void @@ -1086,13 +1085,13 @@ migrate_sql_schema(sqlite3 * db, key_sto P(F("NOTE: because this database was last used by a rather old version\n" "of monotone, you're not done yet. If you're a project leader, then\n" "see the file UPGRADE for instructions on running '%s db %s'") - % ui.prog_name % command_str); + % prog_name % command_str); } break; case upgrade_regen_caches: P(F("NOTE: this upgrade cleared monotone's caches\n" "you should now run '%s db regenerate_caches'") - % ui.prog_name); + % prog_name); break; case upgrade_none: break; ============================================================ --- ui.cc cbee345d5859b445b47730c1cb779cc02da6d9a1 +++ ui.cc 617c42e7a6cc179979544fc0db59383a8f8ffafc @@ -432,7 +432,7 @@ void tick_write_dot::clear_line() // global, and we don't want global constructors/destructors doing // any real work. see monotone.cc for how this is handled. -user_interface::user_interface() : prog_name("?"), imp(0) {} +user_interface::user_interface() : imp(0) {} void user_interface::initialize() { ============================================================ --- ui.hh 2ca5d4fa5a7b2c36a89fa5f84c36603b9818d861 +++ ui.hh 698164ee671be4906fe4c8ee03a3b8fd001de5d6 @@ -69,7 +69,6 @@ public: void redirect_log_to(system_path const & filename); std::string output_prefix(); - std::string prog_name; private: void finish_ticking(); ============================================================ --- work.cc adae88cb01a3e6b39f1f3e593f45ed9c121e66a5 +++ work.cc e2ed785cc9a7ec181639bf9c5ce989855997ab9b @@ -28,7 +28,6 @@ #include "revision.hh" #include "inodeprint.hh" #include "diff_patch.hh" -#include "ui.hh" #include "charset.hh" #include "app_state.hh" #include "database.hh" @@ -1387,8 +1386,8 @@ workspace::update_current_roster_from_fi "To handle all at once, simply use\n" " '%s drop --missing' or\n" " '%s revert --missing'") - % missing_items % ui.prog_name % ui.prog_name % ui.prog_name - % ui.prog_name % ui.prog_name); + % missing_items % prog_name % prog_name % prog_name + % prog_name % prog_name); } void @@ -1625,7 +1624,7 @@ workspace::perform_rename(database & db, E(!src.empty(), origin::user, F("cannot rename the workspace root (try '%s pivot_root' instead)") - % ui.prog_name); + % prog_name); E(new_roster.has_node(src), origin::user, F("source file %s is not versioned") % src); @@ -1659,7 +1658,7 @@ workspace::perform_rename(database & db, { E(!i->empty(), origin::user, F("cannot rename the workspace root (try '%s pivot_root' instead)") - % ui.prog_name); + % prog_name); E(new_roster.has_node(*i), origin::user, F("source file %s is not versioned") % *i); ============================================================ --- work_migration.cc fdd7b30d20ed4ab79dfea448b7c40e4137140d7a +++ work_migration.cc b0e7ef6fdc52db96cf7567c5cfb4ae007ba40ef0 @@ -9,7 +9,6 @@ #include "base.hh" #include "sanity.hh" -#include "ui.hh" #include "cset.hh" #include "simplestring_xform.hh" #include "revision.hh" @@ -137,7 +136,7 @@ workspace::check_ws_format() "'%s migrate_workspace'.\n" "once you have done this, you will not be able to use the workspace\n" "with versions of monotone older than %s.") - % format % current_workspace_format % ui.prog_name + % format % current_workspace_format % prog_name % first_version_supporting_current_format); // keep this message in sync with the copy in migrate_ws_format