Mercurial > cgi-bin > hgweb.cgi > PassMan
annotate src/main/kotlin/name/blackcap/passman/Main.kt @ 26:69526ae8c8de
Allow list --name to be abbreviated -n, since it is so commonly used.
author | David Barts <n5jrn@me.com> |
---|---|
date | Fri, 05 Jul 2024 10:11:31 -0700 |
parents | 2188b2f13326 |
children | 3a3067ba673b |
rev | line source |
---|---|
0
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
1 package name.blackcap.passman |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
2 |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
3 import java.io.BufferedReader |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
4 import java.io.InputStreamReader |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
5 import java.util.* |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
6 import java.util.stream.Collectors |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
7 import kotlin.reflect.jvm.javaMethod |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
8 import kotlin.reflect.jvm.kotlinFunction |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
9 import kotlin.system.exitProcess |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
10 |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
11 fun main(args: Array<String>) { |
24
2188b2f13326
Make some minor tweaks to the help system.
David Barts <n5jrn@me.com>
parents:
23
diff
changeset
|
12 val NOPASSWORD = setOf<String>("help", "quit") |
0
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
13 if (args.isEmpty()) { |
22 | 14 openDatabase() |
15 runInteractive() | |
16 } | |
17 val subcommand = args[0] | |
18 val scArgs = args.sliceArray(1 until args.size) | |
19 if (subcommand !in NOPASSWORD) { | |
20 openDatabase() | |
21 } | |
22 runNonInteractive(subcommand, scArgs) | |
23 } | |
24 | |
25 fun openDatabase() { | |
26 try { | |
27 Database.default = Database.open() | |
28 } catch (e: DatabaseException) { | |
29 handleMessagedException(e) | |
0
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
30 exitProcess(2) |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
31 } |
22 | 32 } |
33 | |
34 fun runNonInteractive(subcommand: String, scArgs: Array<String>): Unit { | |
35 try { | |
36 runSubcommand(subcommand, scArgs) | |
37 } catch (e: SubcommandException) { | |
38 handleSubcommandException(e) | |
39 exitProcess(e.status) | |
40 } catch (e: MessagedException) { | |
41 handleMessagedException(e) | |
42 exitProcess(1) | |
43 } | |
44 exitProcess(0) | |
45 } | |
46 | |
47 fun runInteractive() { | |
48 val DISALLOWED = setOf<String>("password") | |
49 val QUIT = setOf<String>("exit", "quit") | |
50 var lastStatus = 0 | |
24
2188b2f13326
Make some minor tweaks to the help system.
David Barts <n5jrn@me.com>
parents:
23
diff
changeset
|
51 println("This is PassMan interactive mode. Type help for help.") |
22 | 52 while (true) { |
23 | 53 val rawLine = System.console()?.readLine("passman> ") |
54 if (rawLine == null) { | |
55 println() // ensure shell prompt comes out on a line of its own | |
56 break | |
57 } | |
22 | 58 val s = Shplitter() |
59 s.feed(rawLine) | |
60 if (!s.complete) { | |
61 error("unterminated quoting") | |
62 lastStatus = 1 | |
63 continue | |
64 } | |
65 val line = s.split().toList() | |
66 if (line.isEmpty()) { | |
67 continue | |
68 } | |
69 val subcommand = line.first() | |
70 val scArgs = line.drop(1).toTypedArray() | |
71 if (subcommand in QUIT) { | |
72 break | |
73 } | |
74 if (subcommand in DISALLOWED) { | |
75 error("$subcommand subcommand not allowed in interactive mode") | |
76 lastStatus = 2 | |
77 continue | |
78 } | |
79 try { | |
80 runSubcommand(subcommand, scArgs) | |
81 lastStatus = 0 | |
82 } catch(e: SubcommandException) { | |
83 handleSubcommandException(e) | |
84 lastStatus = e.status | |
85 } catch(e: MessagedException) { | |
86 handleMessagedException(e) | |
87 lastStatus = 1 | |
88 } | |
89 } | |
90 exitProcess(lastStatus) | |
0
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
91 } |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
92 |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
93 fun runSubcommand(name: String, args: Array<String>): Unit { |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
94 val instance = getInstanceForClass(getClassForSubcommand(name)) |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
95 if (instance == null) { |
22 | 96 throw SubcommandException(message = "${see(name)} - unknown subcommand", status = 2) |
0
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
97 } else { |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
98 instance.run(args) |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
99 } |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
100 } |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
101 |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
102 fun getClassForSubcommand(name: String): Class<Subcommand>? = try { |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
103 val shortName = name.replace('-', '_') |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
104 .lowercase() |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
105 .replaceFirstChar { it.titlecase(Locale.getDefault()) } |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
106 Class.forName("$MAIN_PACKAGE.${shortName}Subcommand") as? Class<Subcommand> |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
107 } catch (e: ClassNotFoundException) { |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
108 null |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
109 } |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
110 |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
111 fun getInstanceForClass(klass: Class<Subcommand>?) = try { |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
112 klass?.getDeclaredConstructor()?.newInstance() |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
113 } catch (e: ReflectiveOperationException) { |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
114 null |
a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
115 } |
22 | 116 |
117 fun handleMessagedException(e: MessagedException) = error(e.message) | |
118 | |
119 fun handleSubcommandException(e: SubcommandException): Unit { | |
120 if (e.message != null) { | |
121 error(e.message!!) | |
122 } | |
123 } |