X-Git-Url: https://git.distorted.org.uk/~mdw/tripe-android/blobdiff_plain/d5f0ba6279327b05859f6286b7dd5036bb35023a..HEAD:/keys.scala diff --git a/keys.scala b/keys.scala index 9108b38..544462e 100644 --- a/keys.scala +++ b/keys.scala @@ -27,7 +27,7 @@ package uk.org.distorted.tripe; package object keys { /*----- Imports -----------------------------------------------------------*/ -import scala.collection.mutable.HashMap; +import scala.collection.mutable.{ArrayBuffer, HashMap}; import java.io.{Closeable, File, IOException}; import java.lang.{Long => JLong}; @@ -41,7 +41,8 @@ import sys.Errno.EEXIST; import sys.FileImplicits._; import sys.FileInfo.{DIR, REG}; -import progress.{Eyecandy, SimpleModel, DataModel}; +import progress.{Eyecandy, SimpleModel, DataModel, DetailedModel}; +import Implicits.truish; /*----- Useful regular expressions ----------------------------------------*/ @@ -275,6 +276,7 @@ def checkConfigSanity(file: File, ic: Eyecandy) { } 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"); @@ -318,7 +320,7 @@ class PrivateKey private[keys](repo: Repository, dir: File) { * 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 circumolution. + * need this circumlocution. */ (JLong.parseLong(info("keyid"), 16)&0xffffffff).toInt; } @@ -595,16 +597,33 @@ class Repository(val root: File) extends Closeable { /* Confirm that the configuration in the new archive is sane. */ checkConfigSanity(unpkdir/"tripe-keys.conf", ic); - /* Build the public keyring. (Observe the quadratic performance.) */ - ic.operation("collecting public keys") { or => + /* Build the public keyring. */ + ic.job(new SimpleModel("counting public keys", -1)) { jr => + + /* Delete the accumulated keyring. */ val pubkeys = unpkdir/"keyring.pub"; pubkeys.remove_!(); - reposdir foreachFile { file => file.getName match { - case RX_PUBKEY(peer) if file.isreg_! => - or.step(peer); - runCommand("key", "-k", pubkeys.getPath, "merge", file.getPath); + + /* Figure out which files we need to hack. */ + var kv = ArrayBuffer[File](); + reposdir.foreachFile { file => file.getName match { + case RX_PUBKEY(peer) if file.isreg_! => kv += file; case _ => ok; } } + kv = kv.sorted; + val m = new DetailedModel("collecting public keys", kv.length); + var i: Long = 0; + + /* Work through the key files. */ + for (k <- kv) { + m.detail = k.getName; + if (!i) jr.change(m, i); + else jr.step(i); + runCommand("key", "-k", pubkeys.getPath, "merge", k.getPath); + i += 1; + } + + /* Clean up finally. */ (unpkdir/"keyring.pub.old").remove_!(); }