# # patch "ChangeLog" # from [683818fdb59ab01eb7b399f0fbd1a0e0931899b9] # to [f7bda6981ec9dd19194efa5e2be23ebe06f93a1f] # # patch "automate.cc" # from [004901821667adc38fe25860366b855c46af630d] # to [537672e70cf440a84c25999dcc6ee90cb2b50c00] # # patch "commands.cc" # from [711e8e878e0b90261086a5a2118f9bc221c692a1] # to [6f05e3d223ca762c2c01bb07e7a4404902be6b2a] # # patch "monotone.texi" # from [ded6d505b8240d0a1c08c36abb07da288543ddbc] # to [5aab75283d872c661e05c638b0b2a8c085759747] # --- ChangeLog +++ ChangeLog @@ -1,3 +1,11 @@ +2005-05-17 Grahame Bowland + + * commands.cc: add "automate certs ID" to the help string + for the automate command + * automate.cc: implement "automate certs". Add to the list + of commands available through "automate stdio". + * monotone.texi: document "automate certs" + 2005-05-15 graydon hoare * rcs_import.cc (note_state_at_branch_beginning): collect --- automate.cc +++ automate.cc @@ -787,6 +787,100 @@ } +// Name: certs +// Arguments: +// 1: a revision id +// Added in: 1.0 +// Purpose: Prints all certificates associated with the given revision ID. +// Each certificate is contained in a basic IO stanza. For each certificate, +// the following values are provided: +// +// "key" : a string indicating the key used to sign this certificate. +// "status": a string indicating the status of the signature. Possible +// values of this string are: +// "ok" : the signature is correct +// "bad" : the signature is invalid +// "unknown" : signature was made with an unknown key +// "name" : the name of this certificate +// "value" : the value of this certificate +// +// Output format: All stanzas are formatted by basic_io. Stanzas are seperated +// by a blank line. Values will be escaped, '\' -> '\\' and '"' -> '\"'. +// +// Error conditions: If a certificate is signed with an unknown public key, a +// warning message is printed to stderr. If the revision specified is unknown +// or invalid prints an error message to stderr and exits with status 1. +static void +automate_certs(std::vector args, + std::string const & help_name, + app_state & app, + std::ostream & output) +{ + if (args.size() != 1) + throw usage(help_name); + + std::vector certs; + + transaction_guard guard(app.db); + + revision_id rid(idx(args, 0)()); + N(app.db.revision_exists(rid), F("No such revision %s") % rid); + + std::vector< revision > ts; + app.db.get_revision_certs(rid, ts); + for (size_t i = 0; i < ts.size(); ++i) + certs.push_back(idx(ts, i).inner()); + + { + std::set checked; + for (size_t i = 0; i < certs.size(); ++i) + { + if (checked.find(idx(certs, i).key) == checked.end() && + !app.db.public_key_exists(idx(certs, i).key)) + P(F("warning: no public key '%s' found in database\n") + % idx(certs, i).key); + checked.insert(idx(certs, i).key); + } + } + + // Make the output deterministic; this is useful for the test suite, in + // particular. + sort(certs.begin(), certs.end()); + + basic_io::printer pr(output); + + for (size_t i = 0; i < certs.size(); ++i) + { + basic_io::stanza st; + cert_status status = check_cert(app, idx(certs, i)); + cert_value tv; + decode_base64(idx(certs, i).value, tv); + + st.push_str_pair("key", idx(certs, i).key()); + + std::string stat; + switch (status) + { + case cert_ok: + stat = "ok"; + break; + case cert_bad: + stat = "bad"; + break; + case cert_unknown: + stat = "unknown"; + break; + } + st.push_str_pair("status", stat); + st.push_str_pair("name", idx(certs, i).name()); + st.push_str_pair("value", tv()); + + pr.print_stanza(st); + } + + guard.commit(); +} + void automate_command(utf8 cmd, std::vector args, std::string const & root_cmd_name, @@ -927,6 +1021,8 @@ automate_attributes(args, root_cmd_name, app, output); else if (cmd() == "stdio") automate_stdio(args, root_cmd_name, app, output); + else if (cmd() == "certs") + automate_certs(args, root_cmd_name, app, output); else throw usage(root_cmd_name); } --- commands.cc +++ commands.cc @@ -3622,7 +3622,8 @@ "ancestry_difference NEW_REV [OLD_REV1 [OLD_REV2 [...]]]\n" "leaves\n" "inventory\n" - "stdio\n", + "stdio\n" + "certs REV\n", "automation interface", OPT_NONE) { --- monotone.texi +++ monotone.texi @@ -4897,6 +4897,63 @@ @end table address@hidden monotone automate certs @var{id} + address@hidden @strong address@hidden Arguments: + +A revision ID @var{id}, for which any certificates will be printed. + address@hidden Added in: + +1.0 + address@hidden Purpose: + +Prints all certificates associated with the given revision ID. +Each certificate is contained in a basic IO stanza. For each certificate, +the following values are provided: + address@hidden Sample output: + address@hidden + key "address@hidden" +status "ok" + name "author" + value "address@hidden" + + key "address@hidden" +status "ok" + name "branch" + value "net.venge.monotone" + + key "address@hidden" +status "ok" + name "changelog" + value "merge of c48bf9be32757e804a7eca4cf717b2fa5f62b397 + and be6e404d588dcf10b544e1d64f8d2ec4bc0982c8 +" + + key "address@hidden" +status "ok" + name "date" + value "2005-05-16T14:48:16" address@hidden verbatim + address@hidden Output format: + +All stanzas are formatted by basic_io. Stanzas are seperated +by a blank line. Values will be escaped, '\' to '\\' and +'"' to '\"'. + address@hidden Error conditions: + +If a certificate is signed with an unknown public key, a +warning message is printed to stderr. If the revision specified is unknown +or invalid prints an error message to stderr and exits with status 1. + address@hidden table + @item monotone automate stdio @table @strong