aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2023-07-16 16:20:17 -0400
committerGitHub <noreply@github.com>2023-07-16 16:20:17 -0400
commit3e9bcc72938feee1491124ff8c5e8bec2f15bedc (patch)
tree278750c6c431c6fce9092f7890c0a8bad466f513
parent389655d8f76b49a8a391deda28cf75bd99d17a96 (diff)
parentb06eab0609451ec449a88ed5141a658e16197eb0 (diff)
downloadrbw-3e9bcc72938feee1491124ff8c5e8bec2f15bedc.tar.gz
rbw-3e9bcc72938feee1491124ff8c5e8bec2f15bedc.zip
Merge pull request #120 from eatradish/result-to-clipboard
rbw get add flag --clipboard to copy result to clipboard
-rw-r--r--Cargo.lock424
-rw-r--r--Cargo.toml1
-rw-r--r--src/bin/rbw/commands.rs219
-rw-r--r--src/bin/rbw/main.rs4
4 files changed, 565 insertions, 83 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 8acee10..0ca3587 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -113,6 +113,12 @@ dependencies = [
]
[[package]]
+name = "block"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
+
+[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -226,12 +232,36 @@ dependencies = [
]
[[package]]
+name = "clipboard-win"
+version = "3.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fdf5e01086b6be750428ba4a40619f847eb2e95756eee84b18e06e5f0b50342"
+dependencies = [
+ "lazy-bytes-cast",
+ "winapi",
+]
+
+[[package]]
name = "const-oid"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913"
[[package]]
+name = "copypasta"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "133fc8675ee3a4ec9aa513584deda9aa0faeda3586b87f7f0f2ba082c66fb172"
+dependencies = [
+ "clipboard-win",
+ "objc",
+ "objc-foundation",
+ "objc_id",
+ "smithay-clipboard",
+ "x11-clipboard",
+]
+
+[[package]]
name = "core-foundation"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -319,6 +349,21 @@ dependencies = [
]
[[package]]
+name = "dlib"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
+dependencies = [
+ "libloading",
+]
+
+[[package]]
+name = "downcast-rs"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
+
+[[package]]
name = "encoding_rs"
version = "0.8.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -485,6 +530,16 @@ dependencies = [
]
[[package]]
+name = "gethostname"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
name = "getrandom"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -723,6 +778,12 @@ dependencies = [
]
[[package]]
+name = "lazy-bytes-cast"
+version = "5.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10257499f089cd156ad82d0a9cd57d9501fa2c989068992a97eb3c27836f206b"
+
+[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -738,6 +799,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
[[package]]
+name = "libloading"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d580318f95776505201b28cf98eb1fa5e4be3b689633ba6a3e6cd880ff22d8cb"
+dependencies = [
+ "cfg-if",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
name = "libm"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -778,12 +849,39 @@ dependencies = [
]
[[package]]
+name = "malloc_buf"
+version = "0.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
+dependencies = [
+ "libc",
+]
+
+[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
+name = "memmap2"
+version = "0.5.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "memoffset"
+version = "0.6.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
name = "memoffset"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -799,6 +897,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]]
+name = "minimal-lexical"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+
+[[package]]
name = "mio"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -812,6 +916,18 @@ dependencies = [
[[package]]
name = "nix"
+version = "0.24.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069"
+dependencies = [
+ "bitflags",
+ "cfg-if",
+ "libc",
+ "memoffset 0.6.5",
+]
+
+[[package]]
+name = "nix"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
@@ -819,12 +935,22 @@ dependencies = [
"bitflags",
"cfg-if",
"libc",
- "memoffset",
+ "memoffset 0.7.1",
"pin-utils",
"static_assertions",
]
[[package]]
+name = "nom"
+version = "7.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
+dependencies = [
+ "memchr",
+ "minimal-lexical",
+]
+
+[[package]]
name = "num-bigint-dig"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -883,6 +1009,35 @@ dependencies = [
]
[[package]]
+name = "objc"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
+dependencies = [
+ "malloc_buf",
+]
+
+[[package]]
+name = "objc-foundation"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9"
+dependencies = [
+ "block",
+ "objc",
+ "objc_id",
+]
+
+[[package]]
+name = "objc_id"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b"
+dependencies = [
+ "objc",
+]
+
+[[package]]
name = "once_cell"
version = "1.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1000,6 +1155,12 @@ dependencies = [
]
[[package]]
+name = "pkg-config"
+version = "0.3.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
+
+[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1068,6 +1229,7 @@ dependencies = [
"cbc",
"clap",
"clap_complete",
+ "copypasta",
"daemonize",
"directories",
"env_logger",
@@ -1079,7 +1241,7 @@ dependencies = [
"humantime",
"libc",
"log",
- "nix",
+ "nix 0.26.2",
"pbkdf2",
"percent-encoding",
"pkcs8",
@@ -1314,6 +1476,12 @@ dependencies = [
]
[[package]]
+name = "scoped-tls"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
+
+[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1489,6 +1657,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f67ad224767faa3c7d8b6d91985b78e70a1324408abcb1cfcc2be4c06bc06043"
[[package]]
+name = "smithay-client-toolkit"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f307c47d32d2715eb2e0ece5589057820e0e5e70d07c247d1063e844e107f454"
+dependencies = [
+ "bitflags",
+ "dlib",
+ "lazy_static",
+ "log",
+ "memmap2",
+ "nix 0.24.3",
+ "pkg-config",
+ "wayland-client",
+ "wayland-cursor",
+ "wayland-protocols",
+]
+
+[[package]]
+name = "smithay-clipboard"
+version = "0.6.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0a345c870a1fae0b1b779085e81b51e614767c239e93503588e54c5b17f4b0e8"
+dependencies = [
+ "smithay-client-toolkit",
+ "wayland-client",
+]
+
+[[package]]
name = "socket2"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1944,6 +2140,79 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d"
[[package]]
+name = "wayland-client"
+version = "0.29.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715"
+dependencies = [
+ "bitflags",
+ "downcast-rs",
+ "libc",
+ "nix 0.24.3",
+ "scoped-tls",
+ "wayland-commons",
+ "wayland-scanner",
+ "wayland-sys",
+]
+
+[[package]]
+name = "wayland-commons"
+version = "0.29.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902"
+dependencies = [
+ "nix 0.24.3",
+ "once_cell",
+ "smallvec",
+ "wayland-sys",
+]
+
+[[package]]
+name = "wayland-cursor"
+version = "0.29.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661"
+dependencies = [
+ "nix 0.24.3",
+ "wayland-client",
+ "xcursor",
+]
+
+[[package]]
+name = "wayland-protocols"
+version = "0.29.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6"
+dependencies = [
+ "bitflags",
+ "wayland-client",
+ "wayland-commons",
+ "wayland-scanner",
+]
+
+[[package]]
+name = "wayland-scanner"
+version = "0.29.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "xml-rs",
+]
+
+[[package]]
+name = "wayland-sys"
+version = "0.29.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4"
+dependencies = [
+ "dlib",
+ "lazy_static",
+ "pkg-config",
+]
+
+[[package]]
name = "web-sys"
version = "0.3.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1989,6 +2258,15 @@ dependencies = [
]
[[package]]
+name = "winapi-wsapoll"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44c17110f57155602a80dca10be03852116403c9ff3cd25b079d666f2aa3df6e"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2000,13 +2278,13 @@ version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
dependencies = [
- "windows_aarch64_gnullvm",
- "windows_aarch64_msvc",
- "windows_i686_gnu",
- "windows_i686_msvc",
- "windows_x86_64_gnu",
- "windows_x86_64_gnullvm",
- "windows_x86_64_msvc",
+ "windows_aarch64_gnullvm 0.42.2",
+ "windows_aarch64_msvc 0.42.2",
+ "windows_i686_gnu 0.42.2",
+ "windows_i686_msvc 0.42.2",
+ "windows_x86_64_gnu 0.42.2",
+ "windows_x86_64_gnullvm 0.42.2",
+ "windows_x86_64_msvc 0.42.2",
]
[[package]]
@@ -2015,7 +2293,16 @@ version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
dependencies = [
- "windows-targets",
+ "windows-targets 0.42.2",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+dependencies = [
+ "windows-targets 0.48.0",
]
[[package]]
@@ -2024,13 +2311,28 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
dependencies = [
- "windows_aarch64_gnullvm",
- "windows_aarch64_msvc",
- "windows_i686_gnu",
- "windows_i686_msvc",
- "windows_x86_64_gnu",
- "windows_x86_64_gnullvm",
- "windows_x86_64_msvc",
+ "windows_aarch64_gnullvm 0.42.2",
+ "windows_aarch64_msvc 0.42.2",
+ "windows_i686_gnu 0.42.2",
+ "windows_i686_msvc 0.42.2",
+ "windows_x86_64_gnu 0.42.2",
+ "windows_x86_64_gnullvm 0.42.2",
+ "windows_x86_64_msvc 0.42.2",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
+dependencies = [
+ "windows_aarch64_gnullvm 0.48.0",
+ "windows_aarch64_msvc 0.48.0",
+ "windows_i686_gnu 0.48.0",
+ "windows_i686_msvc 0.48.0",
+ "windows_x86_64_gnu 0.48.0",
+ "windows_x86_64_gnullvm 0.48.0",
+ "windows_x86_64_msvc 0.48.0",
]
[[package]]
@@ -2040,42 +2342,84 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
+
+[[package]]
name = "windows_aarch64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
[[package]]
+name = "windows_aarch64_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
+
+[[package]]
name = "windows_i686_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]]
+name = "windows_i686_gnu"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
+
+[[package]]
name = "windows_i686_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
[[package]]
+name = "windows_i686_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
+
+[[package]]
name = "windows_x86_64_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
[[package]]
+name = "windows_x86_64_gnu"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
+
+[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
+
+[[package]]
name = "windows_x86_64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
[[package]]
+name = "windows_x86_64_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
+
+[[package]]
name = "winreg"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2085,6 +2429,52 @@ dependencies = [
]
[[package]]
+name = "x11-clipboard"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "980b9aa9226c3b7de8e2adb11bf20124327c054e0e5812d2aac0b5b5a87e7464"
+dependencies = [
+ "x11rb",
+]
+
+[[package]]
+name = "x11rb"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "592b4883219f345e712b3209c62654ebda0bb50887f330cbd018d0f654bfd507"
+dependencies = [
+ "gethostname",
+ "nix 0.24.3",
+ "winapi",
+ "winapi-wsapoll",
+ "x11rb-protocol",
+]
+
+[[package]]
+name = "x11rb-protocol"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56b245751c0ac9db0e006dc812031482784e434630205a93c73cfefcaabeac67"
+dependencies = [
+ "nix 0.24.3",
+]
+
+[[package]]
+name = "xcursor"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7"
+dependencies = [
+ "nom",
+]
+
+[[package]]
+name = "xml-rs"
+version = "0.8.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "52839dc911083a8ef63efa4d039d1f58b5e409f923e44c80828f206f66e5541c"
+
+[[package]]
name = "zeroize"
version = "1.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index ef700e2..fa19acd 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -59,6 +59,7 @@ totp-lite = "2.0.0"
url = "2.3.1"
uuid = { version = "1.3.0", features = ["v4"] }
zeroize = "1.5.7"
+copypasta = "0.8.2"
rmpv = "1.0.0"
tokio-tungstenite = { version = "0.18.0", features = ["rustls-tls-native-roots"] }
diff --git a/src/bin/rbw/commands.rs b/src/bin/rbw/commands.rs
index 5d51f70..252c5ec 100644
--- a/src/bin/rbw/commands.rs
+++ b/src/bin/rbw/commands.rs
@@ -1,4 +1,5 @@
use anyhow::Context as _;
+use copypasta::{ClipboardContext, ClipboardProvider};
use serde::Serialize;
use std::io;
use std::io::prelude::Write;
@@ -26,7 +27,7 @@ struct DecryptedCipher {
}
impl DecryptedCipher {
- fn display_short(&self, desc: &str) -> bool {
+ fn display_short(&self, desc: &str, clipboard: bool) -> bool {
match &self.data {
DecryptedData::Login { password, .. } => {
password.as_ref().map_or_else(
@@ -35,8 +36,8 @@ impl DecryptedCipher {
false
},
|password| {
- println!("{password}");
- true
+ let res = val_display_or_store(clipboard, password);
+ res
},
)
}
@@ -47,8 +48,8 @@ impl DecryptedCipher {
false
},
|number| {
- println!("{number}");
- true
+ let res = val_display_or_store(clipboard, number);
+ res
},
)
}
@@ -70,8 +71,11 @@ impl DecryptedCipher {
eprintln!("entry for '{desc}' had no name");
false
} else {
- println!("{}", names.join(" "));
- true
+ let res = val_display_or_store(
+ clipboard,
+ &format!("{}", names.join(" ")),
+ );
+ res
}
}
DecryptedData::SecureNote {} => self.notes.as_ref().map_or_else(
@@ -80,14 +84,14 @@ impl DecryptedCipher {
false
},
|notes| {
- println!("{notes}");
- true
+ let res = val_display_or_store(clipboard, notes);
+ res
},
),
}
}
- fn display_field(&self, desc: &str, field: &str) {
+ fn display_field(&self, desc: &str, field: &str, clipboard: bool) {
// Convert the field name to lowercase
let field = field.to_lowercase();
let field = field.as_str();
@@ -100,11 +104,11 @@ impl DecryptedCipher {
} => match field {
"notes" => {
if let Some(notes) = &self.notes {
- println!("{notes}");
+ val_display_or_store(clipboard, notes);
}
}
"username" | "user" => {
- display_field("Username", username.as_deref());
+ display_field("Username", username.as_deref(), clipboard);
}
"totp" | "code" => {
if let Some(totp) = totp {
@@ -116,12 +120,16 @@ impl DecryptedCipher {
"uris" | "urls" | "sites" => {
if let Some(uris) = uris {
for uri in uris {
- display_field("URI", Some(uri.uri.as_str()));
+ display_field(
+ "URI",
+ Some(uri.uri.as_str()),
+ clipboard,
+ );
}
}
}
"password" => {
- self.display_short(desc);
+ self.display_short(desc, clipboard);
}
_ => {
for f in &self.fields {
@@ -135,6 +143,7 @@ impl DecryptedCipher {
display_field(
f.name.as_deref().unwrap_or("(null)"),
Some(f.value.as_deref().unwrap_or("")),
+ clipboard,
);
}
}
@@ -149,34 +158,39 @@ impl DecryptedCipher {
..
} => match field {
"number" | "card" => {
- self.display_short(desc);
+ self.display_short(desc, clipboard);
}
"exp" => {
if let (Some(month), Some(year)) = (exp_month, exp_year) {
display_field(
"Exp",
Some(format!("{month}/{year}").as_str()),
+ clipboard,
);
}
}
"exp_month" | "month" => {
- display_field("Month", exp_month.as_deref());
+ display_field("Month", exp_month.as_deref(), clipboard);
}
"exp_year" | "year" => {
- display_field("Year", exp_year.as_deref());
+ display_field("Year", exp_year.as_deref(), clipboard);
}
"cvv" => {
- display_field("CVV", code.as_deref());
+ display_field("CVV", code.as_deref(), clipboard);
}
"name" | "cardholder" => {
- display_field("Name", cardholder_name.as_deref());
+ display_field(
+ "Name",
+ cardholder_name.as_deref(),
+ clipboard,
+ );
}
"brand" | "type" => {
- display_field("Brand", brand.as_deref());
+ display_field("Brand", brand.as_deref(), clipboard);
}
"notes" => {
if let Some(notes) = &self.notes {
- println!("{notes}");
+ val_display_or_store(clipboard, notes);
}
}
_ => {
@@ -191,6 +205,7 @@ impl DecryptedCipher {
display_field(
f.name.as_deref().unwrap_or("(null)"),
Some(f.value.as_deref().unwrap_or("")),
+ clipboard,
);
}
}
@@ -213,42 +228,50 @@ impl DecryptedCipher {
..
} => match field {
"name" => {
- self.display_short(desc);
+ self.display_short(desc, clipboard);
}
"email" => {
- display_field("Email", email.as_deref());
+ display_field("Email", email.as_deref(), clipboard);
}
"address" => {
- display_field("Address", address1.as_deref());
- display_field("Address", address2.as_deref());
- display_field("Address", address3.as_deref());
+ display_field("Address", address1.as_deref(), clipboard);
+ display_field("Address", address2.as_deref(), clipboard);
+ display_field("Address", address3.as_deref(), clipboard);
}
"city" => {
- display_field("City", city.as_deref());
+ display_field("City", city.as_deref(), clipboard);
}
"state" => {
- display_field("State", state.as_deref());
+ display_field("State", state.as_deref(), clipboard);
}
"postcode" | "zipcode" | "zip" => {
- display_field("Zip", postal_code.as_deref());
+ display_field("Zip", postal_code.as_deref(), clipboard);
}
"country" => {
- display_field("Country", country.as_deref());
+ display_field("Country", country.as_deref(), clipboard);
}
"phone" => {
- display_field("Phone", phone.as_deref());
+ display_field("Phone", phone.as_deref(), clipboard);
}
"ssn" => {
- display_field("SSN", ssn.as_deref());
+ display_field("SSN", ssn.as_deref(), clipboard);
}
"license" => {
- display_field("License", license_number.as_deref());
+ display_field(
+ "License",
+ license_number.as_deref(),
+ clipboard,
+ );
}
"passport" => {
- display_field("Passport", passport_number.as_deref());
+ display_field(
+ "Passport",
+ passport_number.as_deref(),
+ clipboard,
+ );
}
"username" => {
- display_field("Username", username.as_deref());
+ display_field("Username", username.as_deref(), clipboard);
}
"notes" => {
if let Some(notes) = &self.notes {
@@ -267,6 +290,7 @@ impl DecryptedCipher {
display_field(
f.name.as_deref().unwrap_or("(null)"),
Some(f.value.as_deref().unwrap_or("")),
+ clipboard,
);
}
}
@@ -274,7 +298,7 @@ impl DecryptedCipher {
},
DecryptedData::SecureNote {} => match field {
"note" | "notes" => {
- self.display_short(desc);
+ self.display_short(desc, clipboard);
}
_ => {
for f in &self.fields {
@@ -288,6 +312,7 @@ impl DecryptedCipher {
display_field(
f.name.as_deref().unwrap_or("(null)"),
Some(f.value.as_deref().unwrap_or("")),
+ clipboard,
);
}
}
@@ -296,7 +321,7 @@ impl DecryptedCipher {
}
}
- fn display_long(&self, desc: &str) {
+ fn display_long(&self, desc: &str, clipboard: bool) {
match &self.data {
DecryptedData::Login {
username,
@@ -304,18 +329,22 @@ impl DecryptedCipher {
uris,
..
} => {
- let mut displayed = self.display_short(desc);
- displayed |= display_field("Username", username.as_deref());
- displayed |= display_field("TOTP Secret", totp.as_deref());
+ let mut displayed = self.display_short(desc, clipboard);
+ displayed |=
+ display_field("Username", username.as_deref(), clipboard);
+ displayed |=
+ display_field("TOTP Secret", totp.as_deref(), clipboard);
if let Some(uris) = uris {
for uri in uris {
- displayed |= display_field("URI", Some(&uri.uri));
+ displayed |=
+ display_field("URI", Some(&uri.uri), clipboard);
let match_type =
uri.match_type.map(|ty| format!("{ty}"));
displayed |= display_field(
"Match type",
match_type.as_deref(),
+ clipboard,
);
}
}
@@ -324,6 +353,7 @@ impl DecryptedCipher {
displayed |= display_field(
field.name.as_deref().unwrap_or("(null)"),
Some(field.value.as_deref().unwrap_or("")),
+ clipboard,
);
}
@@ -342,7 +372,7 @@ impl DecryptedCipher {
code,
..
} => {
- let mut displayed = self.display_short(desc);
+ let mut displayed = self.display_short(desc, clipboard);
if let (Some(exp_month), Some(exp_year)) =
(exp_month, exp_year)
@@ -350,10 +380,14 @@ impl DecryptedCipher {
println!("Expiration: {exp_month}/{exp_year}");
displayed = true;
}
- displayed |= display_field("CVV", code.as_deref());
+ displayed |= display_field("CVV", code.as_deref(), clipboard);
+ displayed |= display_field(
+ "Name",
+ cardholder_name.as_deref(),
+ clipboard,
+ );
displayed |=
- display_field("Name", cardholder_name.as_deref());
- displayed |= display_field("Brand", brand.as_deref());
+ display_field("Brand", brand.as_deref(), clipboard);
if let Some(notes) = &self.notes {
if displayed {
@@ -378,24 +412,42 @@ impl DecryptedCipher {
username,
..
} => {
- let mut displayed = self.display_short(desc);
+ let mut displayed = self.display_short(desc, clipboard);
- displayed |= display_field("Address", address1.as_deref());
- displayed |= display_field("Address", address2.as_deref());
- displayed |= display_field("Address", address3.as_deref());
- displayed |= display_field("City", city.as_deref());
- displayed |= display_field("State", state.as_deref());
displayed |=
- display_field("Postcode", postal_code.as_deref());
- displayed |= display_field("Country", country.as_deref());
- displayed |= display_field("Phone", phone.as_deref());
- displayed |= display_field("Email", email.as_deref());
- displayed |= display_field("SSN", ssn.as_deref());
+ display_field("Address", address1.as_deref(), clipboard);
+ displayed |=
+ display_field("Address", address2.as_deref(), clipboard);
+ displayed |=
+ display_field("Address", address3.as_deref(), clipboard);
+ displayed |=
+ display_field("City", city.as_deref(), clipboard);
+ displayed |=
+ display_field("State", state.as_deref(), clipboard);
+ displayed |= display_field(
+ "Postcode",
+ postal_code.as_deref(),
+ clipboard,
+ );
+ displayed |=
+ display_field("Country", country.as_deref(), clipboard);
displayed |=
- display_field("License", license_number.as_deref());
+ display_field("Phone", phone.as_deref(), clipboard);
displayed |=
- display_field("Passport", passport_number.as_deref());
- displayed |= display_field("Username", username.as_deref());
+ display_field("Email", email.as_deref(), clipboard);
+ displayed |= display_field("SSN", ssn.as_deref(), clipboard);
+ displayed |= display_field(
+ "License",
+ license_number.as_deref(),
+ clipboard,
+ );
+ displayed |= display_field(
+ "Passport",
+ passport_number.as_deref(),
+ clipboard,
+ );
+ displayed |=
+ display_field("Username", username.as_deref(), clipboard);
if let Some(notes) = &self.notes {
if displayed {
@@ -405,7 +457,7 @@ impl DecryptedCipher {
}
}
DecryptedData::SecureNote {} => {
- self.display_short(desc);
+ self.display_short(desc, clipboard);
}
}
}
@@ -521,6 +573,27 @@ impl DecryptedCipher {
}
}
+fn val_display_or_store(
+ clipboard: bool,
+ password: &str,
+) -> bool {
+ if clipboard {
+ match clipboard_store(password) {
+ Ok(_) => {
+ println!("The results are already stored on the clipboard.");
+ true
+ }
+ Err(e) => {
+ println!("{e}");
+ false
+ }
+ }
+ } else {
+ println!("{password}");
+ true
+ }
+}
+
#[derive(Debug, Clone, Serialize)]
#[serde(untagged)]
#[cfg_attr(test, derive(Eq, PartialEq))]
@@ -686,6 +759,19 @@ pub fn config_unset(key: &str) -> anyhow::Result<()> {
Ok(())
}
+fn clipboard_store(val: &str) -> anyhow::Result<()> {
+ let mut ctx = ClipboardContext::new().map_err(|e| {
+ anyhow::anyhow!("Couldn't create clipboard context: {e}")
+ })?;
+
+ ctx.set_contents(val.to_owned())
+ .map_err(|e| anyhow::anyhow!("Couldn't store value to clipboard: {e}"))?;
+
+ let _ = ctx.get_contents();
+
+ Ok(())
+}
+
pub fn register() -> anyhow::Result<()> {
ensure_agent()?;
crate::actions::register()?;
@@ -780,6 +866,7 @@ pub fn get(
field: Option<&str>,
full: bool,
raw: bool,
+ clipboard: bool,
) -> anyhow::Result<()> {
unlock()?;
@@ -796,11 +883,11 @@ pub fn get(
if raw {
decrypted.display_json(&desc)?;
} else if full {
- decrypted.display_long(&desc);
+ decrypted.display_long(&desc, clipboard);
} else if let Some(field) = field {
- decrypted.display_field(&desc, field);
+ decrypted.display_field(&desc, field, clipboard);
} else {
- decrypted.display_short(&desc);
+ decrypted.display_short(&desc, clipboard);
}
Ok(())
@@ -1906,12 +1993,12 @@ mod test {
}
}
-fn display_field(name: &str, field: Option<&str>) -> bool {
+fn display_field(name: &str, field: Option<&str>, clipboard: bool) -> bool {
field.map_or_else(
|| false,
|field| {
- println!("{name}: {field}");
- true
+ let res = val_display_or_store(clipboard, &format!("{name}: {field}"));
+ res
},
)
}
diff --git a/src/bin/rbw/main.rs b/src/bin/rbw/main.rs
index 4c706bd..3bede5b 100644
--- a/src/bin/rbw/main.rs
+++ b/src/bin/rbw/main.rs
@@ -83,6 +83,8 @@ enum Opt {
full: bool,
#[structopt(long, help = "Display output as JSON")]
raw: bool,
+ #[structopt(long, help = "Copy result to clipboard")]
+ clipboard: bool,
},
#[command(about = "Display the authenticator code for a given entry")]
@@ -322,6 +324,7 @@ fn main() {
field,
full,
raw,
+ clipboard
} => commands::get(
name,
user.as_deref(),
@@ -329,6 +332,7 @@ fn main() {
field.as_deref(),
*full,
*raw,
+ *clipboard,
),
Opt::Code { name, user, folder } => {
commands::code(name, user.as_deref(), folder.as_deref())