diff options
Diffstat (limited to 'imp.ha')
| -rw-r--r-- | imp.ha | 64 |
1 files changed, 63 insertions, 1 deletions
@@ -5,7 +5,10 @@ use os::exec; use io; use strings; use memio; +use bufio; use format::ini; +use encoding::utf8; +use unix::tty; let verbose: bool = false; @@ -32,6 +35,8 @@ export fn main() void = { ('v', "Verbose mode"), ('l', "List the accounts"), ('p', "Display the account passwords"), + ('c', "Print ini config from parsed accounts"), + ('a', "Add an account"), ('f', "file", "The accounts file to use (IMP_FILE by default)"), ('g', "groups...", "Filters by a comma-separated list of groups"), ('m', "matches...", "Filters by a comma-separated list of matches"), @@ -53,11 +58,18 @@ export fn main() void = { let accfilter = filter {...}; + let add = false; + let printconf = false; + for (let i = 0z; i < len(cmd.opts); i += 1) { let opt = cmd.opts[i]; switch (opt.0) { case 'v' => verbose = true; + case 'a' => + add = true; + case 'c' => + printconf = true; case 'p' => displaypass = true; case 'l' => @@ -108,9 +120,25 @@ export fn main() void = { fmt::fatal(format::ini::strerror(e)); }; + if (add) { + const acc = account { + ... + }; + const n = getinput("name: ")!; + const u = getinput("user: ")!; + const p = getinput("pass: ")!; + acc.name = n; + acc.user = u; + acc.pass = p; + append(accounts, acc)!; + }; + accounts = accs_filter(accounts, accfilter); defer accounts_free(accounts); - if (list) { + + if (printconf) { + printaccs(os::stdout, accounts); + } else if (list) { for (let i = 0z; i < len(accounts); i += 1) { let acc = accounts[i]; fmt::println(acc.name)!; @@ -267,6 +295,24 @@ fn parse(data: []u8) ([]account | format::ini::error) = { return accounts; }; +// Returns the accounts as an ini string. The return value must be freed. +fn printaccs(h: io::handle, accs: []account) void = { + for (let i = 0z; i < len(accs); i += 1) { + const acc = accs[i]; + fmt::fprintf(h, "[{}]\nuser={}\npass={}\n", acc.name, acc.user, + acc.pass)!; + if (acc.notes != "") { + fmt::fprintf(h, "notes={}\n", acc.notes)!; + }; + if (acc.url != "") { + fmt::fprintf(h, "match={}\n", acc.url)!; + }; + if (i < len(accs) - 1) { + fmt::fprint(h, "\n")!; + }; + }; +}; + fn setfieldaccount(acc: *account, key: str, val: str) void = { key = strings::trim(key, ' '); defer free(key); @@ -325,3 +371,19 @@ fn decrypt(file: str) ([]u8 | os::exec::error | io::error) = { return out; }; + +// Gets user input from the tty (supports pipes) +fn getinput(text: str = "") (str | tty::error | io::error | utf8::invalid) = { + let termf = tty::open()?; + defer io::close(termf)!; + fmt::fprintf(termf, "{}", text)!; + const scanner = bufio::newscanner(termf); + defer bufio::finish(&scanner); + const line = match (bufio::scan_line(&scanner)?) { + case io::EOF => + yield ""; + case let line: const str => + yield line; + }; + return strings::dup(line); +}; |
