# HG changeset patch # User David Barts # Date 1664643443 25200 # Node ID 72619175004e1edea5a96691d27dcb2ddbd80f4b # Parent 698c4a3d758dd9211c83d9c8f3b94bc3de10e314 Fix issues found in testing. diff -r 698c4a3d758d -r 72619175004e src/main/kotlin/name/blackcap/passman/CreateSubcommand.kt --- a/src/main/kotlin/name/blackcap/passman/CreateSubcommand.kt Fri Sep 23 20:59:52 2022 -0700 +++ b/src/main/kotlin/name/blackcap/passman/CreateSubcommand.kt Sat Oct 01 09:57:23 2022 -0700 @@ -27,7 +27,7 @@ die(e.message ?: "syntax error", 2) } if (commandLine.hasOption(HELP)) { - HelpFormatter().printHelp("$SHORTNAME create", options) + HelpFormatter().printHelp("$SHORTNAME create [options]", options) exitProcess(0) } checkArguments() @@ -97,11 +97,11 @@ } } } - if (commandLine.args.isNotEmpty()) { - error("unexpected trailing arguments") - } if (bad) { exitProcess(2); } + if (commandLine.args.isNotEmpty()) { + die("unexpected trailing arguments", 2) + } } } diff -r 698c4a3d758d -r 72619175004e src/main/kotlin/name/blackcap/passman/DeleteSubcommand.kt --- a/src/main/kotlin/name/blackcap/passman/DeleteSubcommand.kt Fri Sep 23 20:59:52 2022 -0700 +++ b/src/main/kotlin/name/blackcap/passman/DeleteSubcommand.kt Sat Oct 01 09:57:23 2022 -0700 @@ -7,6 +7,10 @@ if (args.isEmpty()) { die("expecting a site name", 2) } + if (args[0] == "-h" || args[0].startsWith("--h")) { + println("usage: passman delete name [...]") + exitProcess(0) + } val db = Database.open() var errors = 0 for (nameIn in args) { diff -r 698c4a3d758d -r 72619175004e src/main/kotlin/name/blackcap/passman/Entry.kt --- a/src/main/kotlin/name/blackcap/passman/Entry.kt Fri Sep 23 20:59:52 2022 -0700 +++ b/src/main/kotlin/name/blackcap/passman/Entry.kt Sat Oct 01 09:57:23 2022 -0700 @@ -58,7 +58,7 @@ } fun printLong(redactPassword: String? = null) { - print(redactPassword) + this.print(redactPassword) println("Notes: ${notes ?: "(none)"}") printDate("Created", created) printDate("Modified", modified) diff -r 698c4a3d758d -r 72619175004e src/main/kotlin/name/blackcap/passman/ListSubcommand.kt --- a/src/main/kotlin/name/blackcap/passman/ListSubcommand.kt Fri Sep 23 20:59:52 2022 -0700 +++ b/src/main/kotlin/name/blackcap/passman/ListSubcommand.kt Sat Oct 01 09:57:23 2022 -0700 @@ -60,11 +60,11 @@ die(e.message ?: "syntax error", 2) } if (commandLine.hasOption(HELP)) { - HelpFormatter().printHelp("$SHORTNAME list", options) + HelpFormatter().printHelp("$SHORTNAME list [options]", options) exitProcess(0) } if (commandLine.args.isNotEmpty()) { - error("unexpected trailing arguments") + die("unexpected trailing arguments", 2) } STRING_OPTIONS.forEach { diff -r 698c4a3d758d -r 72619175004e src/main/kotlin/name/blackcap/passman/MergeSubcommand.kt --- a/src/main/kotlin/name/blackcap/passman/MergeSubcommand.kt Fri Sep 23 20:59:52 2022 -0700 +++ b/src/main/kotlin/name/blackcap/passman/MergeSubcommand.kt Sat Oct 01 09:57:23 2022 -0700 @@ -2,6 +2,21 @@ class MergeSubcommand(): Subcommand() { override fun run(args: Array) { + /* + * To merge, plow through both the old and the new databases in the same + * order. By id is sorta idiosyncratic by human standards, but why not? + * If the entries do not match, write the lowest-numbered one to the + * output database and read the next record from where the lowest-numbered + * one came. If they do match, rely on modified time (fall back to created + * time if null) to sort out the winner. Continue till we hit the end + * of one database, then "drain" the other. Preserve time stamps. + * + * Maybe do something special (warning? confirmation prompt?) on mismatched + * creation times, as this means a new record was created w/o knowledge + * of an existing one. Choices should be to clobber w/ newest, pick one + * manually, or rename one so the other can persist under original name. + * + */ error("not yet implemented") } } diff -r 698c4a3d758d -r 72619175004e src/main/kotlin/name/blackcap/passman/ReadSubcommand.kt --- a/src/main/kotlin/name/blackcap/passman/ReadSubcommand.kt Fri Sep 23 20:59:52 2022 -0700 +++ b/src/main/kotlin/name/blackcap/passman/ReadSubcommand.kt Sat Oct 01 09:57:23 2022 -0700 @@ -30,10 +30,10 @@ exitProcess(0) } if (commandLine.args.isEmpty()) { - error("expecting site name") + die("expecting site name", 2) } if (commandLine.args.size > 1) { - error("unexpected trailing arguments") + die("unexpected trailing arguments", 2) } val nameIn = commandLine.args[0]; val db = Database.open() diff -r 698c4a3d758d -r 72619175004e src/main/kotlin/name/blackcap/passman/See.kt --- a/src/main/kotlin/name/blackcap/passman/See.kt Fri Sep 23 20:59:52 2022 -0700 +++ b/src/main/kotlin/name/blackcap/passman/See.kt Sat Oct 01 09:57:23 2022 -0700 @@ -9,7 +9,7 @@ Character.SURROGATE, Character.PRIVATE_USE, Character.UNASSIGNED, Character.SPACE_SEPARATOR) private val STD_ESC_MAP = mapOf('\t' to 't', '\b' to 'b', '\n' to 'n', - '\r' to 'r', '\u000c' to 'f', '"' to '"', '\\' to '\\') + '\r' to 'r', '"' to '"', '\\' to '\\') fun see(input: String): String { val accum = Formatter() diff -r 698c4a3d758d -r 72619175004e src/main/kotlin/name/blackcap/passman/UpdateSubcommand.kt --- a/src/main/kotlin/name/blackcap/passman/UpdateSubcommand.kt Fri Sep 23 20:59:52 2022 -0700 +++ b/src/main/kotlin/name/blackcap/passman/UpdateSubcommand.kt Sat Oct 01 09:57:23 2022 -0700 @@ -50,7 +50,7 @@ die(e.message ?: "syntax error", 2) } if (commandLine.hasOption(HELP)) { - HelpFormatter().printHelp("$SHORTNAME update", options) + HelpFormatter().printHelp("$SHORTNAME update [options] name", options) exitProcess(0) } checkArguments() @@ -77,14 +77,14 @@ } } } + if (bad) { + exitProcess(2); + } if (commandLine.args.isEmpty()) { - error("expecting site name") + die("expecting site name", 2) } if (commandLine.args.size > 1) { - error("unexpected trailing arguments") - } - if (bad) { - exitProcess(2); + die("unexpected trailing arguments", 2) } } @@ -131,13 +131,17 @@ } private fun cleanUp(): Unit { - fieldValues.forEach { if (it is CharArray) { it.clear() } } + fieldValues.forEach { + if (it is CharArray) { + it.clear() + } + } } private fun updateOne(name: String): Unit { val prompt = name.replaceFirstChar { it.titlecase(Locale.getDefault()) } + ": " val value: Any? = if (name in SENSITIVE_FIELDS) { - getPassword(prompt, verify = true) + updatePassword() } else { val rawValue = readLine(prompt) if (name in NULLABLE_FIELDS && rawValue == NULL_SPECIFIED) { @@ -176,4 +180,17 @@ addOne("password", newPassword) } + private fun updatePassword(): CharArray { + while (true) { + val pw1 = getPassword("Password: ") + if (pw1.isEmpty()) { + return pw1 + } + val pw2 = getPassword("Verification: ") + if (pw1 contentEquals pw2) { + return pw1 + } + error("mismatch, try again") + } + } }