changeset 9:72619175004e

Fix issues found in testing.
author David Barts <n5jrn@me.com>
date Sat, 01 Oct 2022 09:57:23 -0700
parents 698c4a3d758d
children cbe4c797c9a6
files src/main/kotlin/name/blackcap/passman/CreateSubcommand.kt src/main/kotlin/name/blackcap/passman/DeleteSubcommand.kt src/main/kotlin/name/blackcap/passman/Entry.kt src/main/kotlin/name/blackcap/passman/ListSubcommand.kt src/main/kotlin/name/blackcap/passman/MergeSubcommand.kt src/main/kotlin/name/blackcap/passman/ReadSubcommand.kt src/main/kotlin/name/blackcap/passman/See.kt src/main/kotlin/name/blackcap/passman/UpdateSubcommand.kt
diffstat 8 files changed, 54 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- 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)
+        }
     }
 }
--- 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) {
--- 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)
--- 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 {
--- 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<String>) {
+        /*
+         * 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")
     }
 }
--- 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()
--- 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<Char, Char>('\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()
--- 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")
+        }
+    }
 }