+private val keydatefmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
+
+class PrivateKey private[keys](repo: Repository, dir: File) {
+ private[this] lazy val keyring = dir/"keyring";
+ private[this] lazy val meta = parseConfig(dir/"meta");
+ lazy val tag = meta("tag");
+ lazy val time = datefmt synchronized { datefmt.parse(meta("time")); };
+ lazy val fingerprint = keyFingerprint(keyring, tag,
+ repo.config("fingerprint-hash"));
+
+ def remove() { dir.rmTree(); }
+
+ private[this] lazy val (info, _attr) = {
+ val m = Map.newBuilder[String, String];
+ val a = Map.newBuilder[String, String];
+ val (out, _) = runCommand("key", "-k", keyring.getPath,
+ "list", "-vv", tag);
+ val lines = out.lines;
+ while (lines.hasNext) lines.next match {
+ case "attributes:" =>
+ while (lines.hasNext) lines.next match {
+ case RX_KEYATTR(k, v) => a += k -> v;
+ case line => throw new IOException(
+ s"unexpected output from `key list': $line");
+ }
+ case RX_KEYINFO(k, v) =>
+ m += k -> v;
+ case line => throw new IOException(
+ s"unexpected output from `key list': $line");
+ }
+ (m.result, a.result)
+ }
+
+ lazy val expires = info("expiry") match {
+ case "forever" => None
+ case d => Some(keydatefmt synchronized { keydatefmt.parse(d) })
+ }
+ lazy val ty = info("type");
+ lazy val comment = info("comment");
+ lazy val keyid = {
+
+ /* Ugh. Using `Int' throws an exception on words whose top bit is set
+ * because Java doesn't have proper unsigned integers. There's
+ * `parseUnsignedInt' in Java 1.8, but that limits our Android targets.
+ * And Scala has put its own `Long' object in the way of Java's so we
+ * need this circumlocution.
+ */
+ (JLong.parseLong(info("keyid"), 16)&0xffffffff).toInt;
+ }
+ lazy val attr = _attr;
+}
+