From 3f09e8b55fbe20f33fb98964f2125d5a39bfbb36 Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Wed, 13 Oct 2021 00:50:48 -0500 Subject: [PATCH] updates: - reformat with 80char - add SQLx to daemon - add backtrace to anyhow --- Cargo.lock | 819 +++++++++++++++--- daemon/Cargo.toml | 6 +- .../20211013053733_initial.down.sql | 3 + .../migrations/20211013053733_initial.up.sql | 14 + daemon/src/config/watcher.rs | 9 +- daemon/src/lib.rs | 15 + daemon/src/mail/mod.rs | 53 +- daemon/src/mail/store.rs | 21 +- daemon/src/main.rs | 20 +- imap/Cargo.toml | 2 +- imap/src/client/auth.rs | 10 +- imap/src/client/client.rs | 57 +- imap/src/client/codec.rs | 35 +- imap/src/client/configurable_cert_verifier.rs | 13 +- imap/src/client/inner.rs | 22 +- imap/src/client/mod.rs | 4 +- imap/src/client/response_stream.rs | 9 +- imap/src/client/tls.rs | 8 +- imap/src/proto/command.rs | 4 +- imap/src/proto/response.rs | 8 +- imap/src/proto/rfc3501/mod.rs | 20 +- imap/src/proto/rfc3501/tests.rs | 8 +- mbsync/Cargo.toml | 2 +- mbsync/src/config.rs | 47 +- mbsync/src/store.rs | 11 +- proto-common/Cargo.toml | 2 +- proto-common/src/bytes.rs | 22 +- proto-common/src/convert_error.rs | 28 +- proto-common/src/formatter.rs | 6 +- proto-common/src/lib.rs | 4 +- proto-common/src/parsers.rs | 4 +- rustfmt.toml | 4 +- 32 files changed, 1056 insertions(+), 234 deletions(-) create mode 100644 daemon/migrations/20211013053733_initial.down.sql create mode 100644 daemon/migrations/20211013053733_initial.up.sql create mode 100644 daemon/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index f1cfc74..4830ca9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,32 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a2e47a1fbe209ee101dd6d61285226744c6c8d3c21c8dc878ba6cb9f467f3a" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "991984e3fd003e7ba02eb724f87a0f997b78677c46c0e91f8424ad7394c9886a" +dependencies = [ + "getrandom 0.2.3", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "0.7.15" @@ -13,19 +39,28 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28ae2b3dec75a406790005a200b1bd89785afc02517a00ca99ecfe093ee9e6cf" +checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1" +dependencies = [ + "backtrace", +] [[package]] name = "arbitrary" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "237430fd6ed3740afe94eefcc278ae21e050285be882804e0d6e8695f0c94691" +checksum = "577b08a4acd7b99869f863c50011b01eb73424ccc798ecd996f2e24817adfca7" dependencies = [ "derive_arbitrary", ] +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + [[package]] name = "arrayvec" version = "0.5.2" @@ -43,6 +78,15 @@ dependencies = [ "syn", ] +[[package]] +name = "atoi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616896e05fc0e2649463a93a15183c6a16bf03413a7af88ef1285ddedfa9cda5" +dependencies = [ + "num-traits", +] + [[package]] name = "atty" version = "0.2.14" @@ -60,6 +104,21 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +[[package]] +name = "backtrace" +version = "0.3.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4717cfcbfaa661a0fd48f8453951837ae7e8f81e481fbb136e3202d72805a744" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base64" version = "0.13.0" @@ -84,6 +143,26 @@ dependencies = [ "wyz", ] +[[package]] +name = "blake2b_simd" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + [[package]] name = "bstr" version = "0.2.15" @@ -97,21 +176,27 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.7.0" +version = "3.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" +checksum = "d9df67f7bf9ef8498769f994239c45613ef0c5899415fb58e9add412d2c1a538" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" [[package]] name = "cc" -version = "1.0.69" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" +checksum = "79c2681d6594606957bbb8631c4b90a7fcaaa72cdb714743a437b156d6a7eedd" [[package]] name = "cfg-if" @@ -163,6 +248,66 @@ dependencies = [ "syn", ] +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "cpufeatures" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10c2722795460108a7872e1cd933a85d6ec38abc4baecad51028f702da28889f" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccaeedb56da03b09f598226e25e80088cb4cd25f316e6e4df7d695f0feeb1403" + +[[package]] +name = "crossbeam-channel" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b10ddc024425c88c2ad148c1b0fd53f4c6d38db9697c9f1588381212fa657c9" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +dependencies = [ + "cfg-if", + "lazy_static", +] + [[package]] name = "darling" version = "0.12.4" @@ -211,9 +356,9 @@ dependencies = [ [[package]] name = "derive_arbitrary" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f1281ee141df08871db9fe261ab5312179eac32d1e314134ceaa8dd7c042f5a" +checksum = "b24629208e87a2d8b396ff43b15c4afb0a69cea3fbbaa9ed9b92b7c02f0aed73" dependencies = [ "proc-macro2", "quote", @@ -251,6 +396,38 @@ dependencies = [ "syn", ] +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "dirs" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + [[package]] name = "env_logger" version = "0.9.0" @@ -270,6 +447,16 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "form_urlencoded" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +dependencies = [ + "matches", + "percent-encoding", +] + [[package]] name = "format-bytes" version = "0.2.2" @@ -300,9 +487,9 @@ checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" [[package]] name = "futures" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adc00f486adfc9ce99f77d717836f0c5aa84965eb0b4f051f4e83f7cab53f8b" +checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca" dependencies = [ "futures-channel", "futures-core", @@ -315,9 +502,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74ed2411805f6e4e3d9bc904c95d5d423b89b3b25dc0250aa74729de20629ff9" +checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" dependencies = [ "futures-core", "futures-sink", @@ -325,15 +512,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99" +checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" [[package]] name = "futures-executor" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d0d535a57b87e1ae31437b892713aee90cd2d7b0ee48727cd11fc72ef54761c" +checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c" dependencies = [ "futures-core", "futures-task", @@ -341,16 +528,27 @@ dependencies = [ ] [[package]] -name = "futures-io" -version = "0.3.16" +name = "futures-intrusive" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b0e06c393068f3a6ef246c75cdca793d6a46347e75286933e5e75fd2fd11582" +checksum = "62007592ac46aa7c2b6416f7deb9a8a8f63a01e0f1d6e1787d5630170db2b63e" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + +[[package]] +name = "futures-io" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" [[package]] name = "futures-macro" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54913bae956fb8df7f4dc6fc90362aa72e69148e3f39041fbe8742d21e0ac57" +checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb" dependencies = [ "autocfg", "proc-macro-hack", @@ -361,21 +559,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f30aaa67363d119812743aa5f33c201a7a66329f97d1a887022971feea4b53" +checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" [[package]] name = "futures-task" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe54a98670017f3be909561f6ad13e810d9a51f3f061b902062ca3da80799f2" +checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" [[package]] name = "futures-util" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78" +checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" dependencies = [ "autocfg", "futures-channel", @@ -393,10 +591,48 @@ dependencies = [ ] [[package]] -name = "h2" -version = "0.3.4" +name = "generic-array" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7f3675cfef6a30c8031cf9e6493ebdc3bb3272a3fea3923c4210d1830e6a472" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", +] + +[[package]] +name = "gimli" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4075386626662786ddb0ec9081e7c7eeb1ba31951f447ca780ef9f5d568189" + +[[package]] +name = "h2" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c06815895acec637cd6ed6e9662c935b866d20a106f8361892893a7d9234964" dependencies = [ "bytes", "fnv", @@ -416,6 +652,18 @@ name = "hashbrown" version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashlink" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf" +dependencies = [ + "hashbrown", +] [[package]] name = "heck" @@ -436,10 +684,16 @@ dependencies = [ ] [[package]] -name = "http" -version = "0.2.4" +name = "hex" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "http" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" dependencies = [ "bytes", "fnv", @@ -477,9 +731,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.11" +version = "0.14.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b61cf2d1aebcf6e6352c97b81dc2244ca29194be1b276f5d8ad5c6330fffb11" +checksum = "15d1cfb9e4f68655fa04c01f59edb405b6074a0f7118ea881e5026e4a1cd8593" dependencies = [ "bytes", "futures-channel", @@ -504,6 +758,17 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "indexmap" version = "1.7.0" @@ -516,9 +781,9 @@ dependencies = [ [[package]] name = "inotify" -version = "0.9.3" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b031475cb1b103ee221afb806a23d35e0570bf7271d7588762ceba8127ed43b3" +checksum = "9e5fc8f41dbaa9c8492a96c8afffda4f76896ee041d6a57606e70581b80c901f" dependencies = [ "bitflags", "futures-core", @@ -538,13 +803,22 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" +checksum = "716d3d89f35ac6a34fd0eed635395f4c3b76fa889338a4632e5231a8684216bd" dependencies = [ "cfg-if", ] +[[package]] +name = "itertools" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "0.4.8" @@ -553,9 +827,9 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "js-sys" -version = "0.3.53" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4bf49d50e2961077d9c99f4b7997d770a1114f087c3c2e0069b36c13fc2979d" +checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" dependencies = [ "wasm-bindgen", ] @@ -581,15 +855,26 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.100" +version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1fa8cddc8fbbee11227ef194b5317ed014b8acbf15139bd716a18ad3fe99ec5" +checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" + +[[package]] +name = "libsqlite3-sys" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290b64917f8b0cb885d9de0f9959fe1f775d7fa12f1da2db9001c1c8ab60f89d" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] [[package]] name = "lock_api" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" +checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" dependencies = [ "scopeguard", ] @@ -603,12 +888,34 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "matches" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" + [[package]] name = "memchr" version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" +[[package]] +name = "minimal-lexical" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c64630dcdd71f1a64c435f54885086a0de5d6a12d104d69b165fb7d5286d677" + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + [[package]] name = "mio" version = "0.7.13" @@ -644,6 +951,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "nom" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffd9d26838a953b4af82cbeb9f1592c6798916983959be223a7124e992742c1" +dependencies = [ + "memchr", + "minimal-lexical", + "version_check", +] + [[package]] name = "ntapi" version = "0.3.6" @@ -682,12 +1000,24 @@ dependencies = [ "libc", ] +[[package]] +name = "object" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5b3dd1c072ee7963717671d1ca129f1048fda25edea6b752bfc71ac8854170" + [[package]] name = "once_cell" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + [[package]] name = "os_str_bytes" version = "3.1.0" @@ -709,6 +1039,7 @@ dependencies = [ "panorama-imap", "panorama-smtp", "serde", + "sqlx", "stderrlog", "tokio", "tokio-rustls", @@ -731,7 +1062,7 @@ dependencies = [ "format-bytes", "futures", "log", - "nom", + "nom 6.2.1", "panorama-proto-common", "stderrlog", "tokio", @@ -768,7 +1099,7 @@ dependencies = [ "bytes", "format-bytes", "log", - "nom", + "nom 6.2.1", "num-traits", ] @@ -776,15 +1107,15 @@ dependencies = [ name = "panorama-smtp" version = "0.0.1" dependencies = [ - "nom", + "nom 6.2.1", "panorama-proto-common", ] [[package]] name = "parking_lot" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", "lock_api", @@ -793,18 +1124,24 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" dependencies = [ "cfg-if", "instant", "libc", - "redox_syscall", + "redox_syscall 0.2.10", "smallvec", "winapi", ] +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + [[package]] name = "pin-project-lite" version = "0.2.7" @@ -817,6 +1154,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c9b1041b4387893b91ee6746cddfc28516aff326a3519fb2adf820932c5e6cb" + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -855,18 +1198,18 @@ checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" [[package]] name = "proc-macro2" -version = "1.0.28" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +checksum = "edc3358ebc67bc8b7fa0c007f945b0b18226f78437d61bec735a9eb96b61ee70" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" dependencies = [ "proc-macro2", ] @@ -877,6 +1220,12 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8" +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + [[package]] name = "redox_syscall" version = "0.2.10" @@ -886,6 +1235,17 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_users" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" +dependencies = [ + "getrandom 0.1.16", + "redox_syscall 0.1.57", + "rust-argon2", +] + [[package]] name = "regex" version = "1.4.6" @@ -924,6 +1284,24 @@ dependencies = [ "winapi", ] +[[package]] +name = "rust-argon2" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb" +dependencies = [ + "base64", + "blake2b_simd", + "constant_time_eq", + "crossbeam-utils", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" + [[package]] name = "rustls" version = "0.19.1" @@ -961,24 +1339,49 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.128" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1056a0db1978e9dbf0f6e4fca677f6f9143dc1c19de346f22cac23e422196834" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.128" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13af2fbb8b60a8950d6c72a56d2095c28870367cc8e10c55e9745bac4995a2c4" +checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "serde_json" +version = "1.0.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" +dependencies = [ + "block-buffer", + "cfg-if", + "cpufeatures", + "digest", + "opaque-debug", +] + [[package]] name = "signal-hook-registry" version = "1.4.0" @@ -996,9 +1399,9 @@ checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" [[package]] name = "smallvec" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" +checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" [[package]] name = "spin" @@ -1006,6 +1409,106 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "sqlformat" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4b7922be017ee70900be125523f38bdd644f4f06a1b16e8fa5a8ee8c34bffd4" +dependencies = [ + "itertools", + "nom 7.0.0", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7911b0031a0247af40095838002999c7a52fba29d9739e93326e71a5a1bc9d43" +dependencies = [ + "sqlx-core", + "sqlx-macros", +] + +[[package]] +name = "sqlx-core" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aec89bfaca8f7737439bad16d52b07f1ccd0730520d3bf6ae9d069fe4b641fb1" +dependencies = [ + "ahash", + "atoi", + "bitflags", + "byteorder", + "bytes", + "chrono", + "crc", + "crossbeam-channel", + "crossbeam-queue", + "crossbeam-utils", + "either", + "futures-channel", + "futures-core", + "futures-intrusive", + "futures-util", + "hashlink", + "hex", + "indexmap", + "itoa", + "libc", + "libsqlite3-sys", + "log", + "memchr", + "once_cell", + "parking_lot", + "percent-encoding", + "rustls", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlformat", + "sqlx-rt", + "stringprep", + "thiserror", + "tokio-stream", + "url", + "webpki", + "webpki-roots", + "whoami", +] + +[[package]] +name = "sqlx-macros" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "584866c833511b1a152e87a7ee20dee2739746f60c858b3c5209150bc4b466f5" +dependencies = [ + "dotenv", + "either", + "heck", + "once_cell", + "proc-macro2", + "quote", + "serde_json", + "sha2", + "sqlx-core", + "sqlx-rt", + "syn", + "url", +] + +[[package]] +name = "sqlx-rt" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d1bd069de53442e7a320f525a6d4deb8bb0621ac7a55f7eccbc2b58b57f43d0" +dependencies = [ + "once_cell", + "tokio", + "tokio-rustls", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -1025,6 +1528,16 @@ dependencies = [ "thread_local", ] +[[package]] +name = "stringprep" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "strsim" version = "0.10.0" @@ -1033,9 +1546,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.75" +version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7" +checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194" dependencies = [ "proc-macro2", "quote", @@ -1066,6 +1579,26 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thiserror" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "thread_local" version = "1.0.1" @@ -1082,15 +1615,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" dependencies = [ "libc", - "wasi", + "wasi 0.10.0+wasi-snapshot-preview1", "winapi", ] [[package]] -name = "tokio" -version = "1.10.0" +name = "tinyvec" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cf844b23c6131f624accf65ce0e4e9956a8bb329400ea5bcc26ae3a5c20b0b" +checksum = "f83b2a3d4d9091d0abd7eba4dc2710b1718583bd4d8992e2190720ea38f391f7" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "tokio" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2c2416fdedca8443ae44b4527de1ea633af61d8f7169ffa6e72c5b53d24efcc" dependencies = [ "autocfg", "bytes", @@ -1108,9 +1656,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110" +checksum = "154794c8f499c2619acd19e839294703e9e32e7630ef5f46ea80d4ef0fbee5eb" dependencies = [ "proc-macro2", "quote", @@ -1129,10 +1677,21 @@ dependencies = [ ] [[package]] -name = "tokio-util" -version = "0.6.7" +name = "tokio-stream" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592" +checksum = "7b2f3f698253f03119ac0102beaa64f67a67e08074d03a22d18784104543727f" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d3725d3efa29485e87311c5b699de63cde14b00ed4d256b8318aa30ca452cd" dependencies = [ "bytes", "futures-core", @@ -1159,9 +1718,9 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" [[package]] name = "tracing" -version = "0.1.26" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" +checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" dependencies = [ "cfg-if", "pin-project-lite", @@ -1170,9 +1729,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.19" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ca517f43f0fb96e0c3072ed5c275fe5eece87e8cb52f4a77b69226d3b1c9df8" +checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" dependencies = [ "lazy_static", ] @@ -1183,6 +1742,27 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +[[package]] +name = "typenum" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" + +[[package]] +name = "unicode-bidi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" + +[[package]] +name = "unicode-normalization" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-segmentation" version = "1.8.0" @@ -1191,9 +1771,9 @@ checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" [[package]] name = "unicode-width" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" [[package]] name = "unicode-xid" @@ -1201,12 +1781,36 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + [[package]] name = "untrusted" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "url" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +dependencies = [ + "form_urlencoded", + "idna", + "matches", + "percent-encoding", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "vec_map" version = "0.8.2" @@ -1229,6 +1833,12 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + [[package]] name = "wasi" version = "0.10.0+wasi-snapshot-preview1" @@ -1237,9 +1847,9 @@ checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" [[package]] name = "wasm-bindgen" -version = "0.2.76" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce9b1b516211d33767048e5d47fa2a381ed8b76fc48d2ce4aa39877f9f183e0" +checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1247,9 +1857,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.76" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfe8dc78e2326ba5f845f4b5bf548401604fa20b1dd1d365fb73b6c1d6364041" +checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" dependencies = [ "bumpalo", "lazy_static", @@ -1262,9 +1872,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.76" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44468aa53335841d9d6b6c023eaab07c0cd4bddbcfdee3e2bb1e8d2cb8069fef" +checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1272,9 +1882,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.76" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0195807922713af1e67dc66132c7328206ed9766af3858164fb583eedc25fbad" +checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" dependencies = [ "proc-macro2", "quote", @@ -1285,15 +1895,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.76" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acdb075a845574a1fa5f09fd77e43f7747599301ea3417a9fbffdeedfc1f4a29" +checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" [[package]] name = "web-sys" -version = "0.3.53" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224b2f6b67919060055ef1a67807367c2066ed520c3862cc013d26cf893a783c" +checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" dependencies = [ "js-sys", "wasm-bindgen", @@ -1318,6 +1928,16 @@ dependencies = [ "webpki", ] +[[package]] +name = "whoami" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "483a59fee1a93fec90eb08bc2eb4315ef10f4ebc478b3a5fadc969819cb66117" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + [[package]] name = "winapi" version = "0.3.9" @@ -1357,6 +1977,9 @@ checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" [[package]] name = "xdg" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" +checksum = "de4cfc7dc9727713f386aadce9496f1ed64ea368d9f1f813a54d0f98f8741286" +dependencies = [ + "dirs", +] diff --git a/daemon/Cargo.toml b/daemon/Cargo.toml index 826d0fc..e269020 100644 --- a/daemon/Cargo.toml +++ b/daemon/Cargo.toml @@ -4,7 +4,7 @@ version = "0.0.1" edition = "2018" [dependencies] -anyhow = "1.0.42" +anyhow = { version = "1.0.42", features = ["backtrace"] } async-trait = "0.1.50" clap = "3.0.0-beta.2" derivative = "2.2.0" @@ -20,3 +20,7 @@ tokio = { version = "1.9.0", features = ["full"] } tokio-rustls = "0.22.0" toml = "0.5.8" xdg = "2.2.0" + +[dependencies.sqlx] +version = "0.5.9" +features = ["runtime-tokio-rustls", "sqlite", "json", "chrono"] diff --git a/daemon/migrations/20211013053733_initial.down.sql b/daemon/migrations/20211013053733_initial.down.sql new file mode 100644 index 0000000..e55995a --- /dev/null +++ b/daemon/migrations/20211013053733_initial.down.sql @@ -0,0 +1,3 @@ +DROP TABLE "messages"; +DROP TABLE "mailboxes"; +DROP TABLE "accounts"; diff --git a/daemon/migrations/20211013053733_initial.up.sql b/daemon/migrations/20211013053733_initial.up.sql new file mode 100644 index 0000000..e3bbd39 --- /dev/null +++ b/daemon/migrations/20211013053733_initial.up.sql @@ -0,0 +1,14 @@ +CREATE TABLE "accounts" ( + "id" PRIMARY KEY AUTOINCREMENT +); + +CREATE TABLE "mailboxes" ( + "account" INTEGER, + "name" TEXT, + + PRIMARY KEY ("account", "name") +); + +CREATE TABLE "messages" ( + "id" TEXT PRIMARY KEY +); diff --git a/daemon/src/config/watcher.rs b/daemon/src/config/watcher.rs index a4c6734..51f1bf8 100644 --- a/daemon/src/config/watcher.rs +++ b/daemon/src/config/watcher.rs @@ -14,7 +14,8 @@ pub type ConfigWatcher = watch::Receiver; /// Start the entire config watcher system, and return a /// [ConfigWatcher][self::ConfigWatcher], which is a cloneable receiver of /// config update events. -pub fn spawn_config_watcher_system() -> Result<(JoinHandle<()>, ConfigWatcher)> { +pub fn spawn_config_watcher_system() -> Result<(JoinHandle<()>, ConfigWatcher)> +{ let mut inotify = Inotify::init()?; let xdg = BaseDirectories::new()?; let config_home = xdg.get_config_home().join("panorama"); @@ -29,7 +30,8 @@ pub fn spawn_config_watcher_system() -> Result<(JoinHandle<()>, ConfigWatcher)> debug!("watching {:?}", config_home); let (config_tx, config_update) = watch::channel(Config::default()); let handle = tokio::spawn( - start_inotify_stream(inotify, config_home, config_tx).unwrap_or_else(|_err| todo!()), + start_inotify_stream(inotify, config_home, config_tx) + .unwrap_or_else(|_err| todo!()), ); Ok((handle, config_update)) } @@ -66,7 +68,8 @@ async fn start_inotify_stream( continue; } // TODO: any better way to do this? - let config_path_c = config_path.canonicalize().context("cfg_path")?; + let config_path_c = + config_path.canonicalize().context("cfg_path")?; if config_path_c != path_c { debug!("did not match {:?} {:?}", config_path_c, path_c); continue; diff --git a/daemon/src/lib.rs b/daemon/src/lib.rs new file mode 100644 index 0000000..12f7149 --- /dev/null +++ b/daemon/src/lib.rs @@ -0,0 +1,15 @@ +#[macro_use] +extern crate serde; +#[macro_use] +extern crate anyhow; +#[macro_use] +extern crate log; +#[macro_use] +extern crate derivative; + +pub mod config; +pub mod mail; + +use sqlx::migrate::Migrator; + +static MIGRATOR: Migrator = sqlx::migrate!(); diff --git a/daemon/src/mail/mod.rs b/daemon/src/mail/mod.rs index 8dc13a4..b1217f6 100644 --- a/daemon/src/mail/mod.rs +++ b/daemon/src/mail/mod.rs @@ -68,18 +68,23 @@ pub async fn sync_main( debug!("folder: {:?}", folder); let select = authed.select("INBOX").await?; debug!("select response: {:?}", select); - if let (Some(_exists), Some(_uidvalidity)) = (select.exists, select.uid_validity) { + if let (Some(_exists), Some(_uidvalidity)) = + (select.exists, select.uid_validity) + { // figure out which uids don't exist locally yet let new_uids = vec![]; - // let new_uids = stream::iter(1..exists).map(Ok).try_filter_map(|uid| { + // let new_uids = + // stream::iter(1..exists).map(Ok).try_filter_map(|uid| { // todo!() - // // mail_store.try_identify_email(&acct_name, &folder, uid, - // uidvalidity, None) // // invert the option to - // only select uids that haven't been downloaded // + // // mail_store.try_identify_email(&acct_name, &folder, + // uid, uidvalidity, None) // // + // invert the option to only select uids that + // haven't been downloaded // // .map_ok(move |o| o.map_or_else(move || Some(uid), |v| None)) - // // .map_err(|err| err.context("error checking if the email is - // already downloaded [try_identify_email]")) - // }).try_collect::>().await?; + // // .map_err(|err| err.context("error checking if + // the email is already downloaded + // [try_identify_email]")) }).try_collect:: + // >().await?; if !new_uids.is_empty() { debug!("fetching uids {:?}", new_uids); let _fetched = authed @@ -99,14 +104,15 @@ pub async fn sync_main( tokio::time::sleep(std::time::Duration::from_secs(50)).await; // TODO: remove this later // continue; - // let's just select INBOX for now, maybe have a config for default mailbox - // later? + // let's just select INBOX for now, maybe have a config for default + // mailbox later? debug!("selecting the INBOX mailbox"); let select = authed.select("INBOX").await?; debug!("select result: {:?}", select); loop { let message_uids = authed.uid_search().await?; - let message_uids = message_uids.into_iter().take(30).collect::>(); + let message_uids = + message_uids.into_iter().take(30).collect::>(); // let _ = mail2ui_tx.send(MailEvent::MessageUids( // acct_name.clone(), // message_uids.clone(), @@ -133,7 +139,10 @@ pub async fn sync_main( debug!("got an event: {:?}", evt); match evt { Response::MailboxData(MailboxData::Exists(uid)) => { - debug!("NEW MESSAGE WITH UID {:?}, droping everything", uid); + debug!( + "NEW MESSAGE WITH UID {:?}, droping everything", + uid + ); // send DONE to stop the idle std::mem::drop(idle_stream); // let handle = Notification::new() @@ -143,18 +152,23 @@ pub async fn sync_main( // .timeout(Timeout::Milliseconds(6000)) // .show()?; let message_uids = authed.uid_search().await?; - let message_uids = - message_uids.into_iter().take(20).collect::>(); + let message_uids = message_uids + .into_iter() + .take(20) + .collect::>(); // let _ = mail2ui_tx.send(MailEvent::MessageUids( // acct_name.clone(), // message_uids.clone(), // )); - // TODO: make this happen concurrently with the main loop? + // TODO: make this happen concurrently with the main + // loop? let mut message_list = authed .uid_fetch(&message_uids, &[], FetchItems::All) .await .unwrap(); - while let Some((_uid, _attrs)) = message_list.next().await { + while let Some((_uid, _attrs)) = + message_list.next().await + { // let evt = MailEvent::UpdateUid(acct_name. // clone(), uid, attrs); // debug!("sent {:?}", evt); @@ -168,7 +182,8 @@ pub async fn sync_main( } } else { loop { - tokio::time::sleep(std::time::Duration::from_secs(20)).await; + tokio::time::sleep(std::time::Duration::from_secs(20)) + .await; debug!("heartbeat"); } } @@ -177,8 +192,8 @@ pub async fn sync_main( } } - // wait a bit so we're not hitting the server really fast if the fail happens - // early on + // wait a bit so we're not hitting the server really fast if the fail + // happens early on // // TODO: some kind of smart exponential backoff that considers some time // threshold to be a failing case? diff --git a/daemon/src/mail/store.rs b/daemon/src/mail/store.rs index e425c97..fd5ebcb 100644 --- a/daemon/src/mail/store.rs +++ b/daemon/src/mail/store.rs @@ -1 +1,20 @@ -pub struct MailStore; +use anyhow::Result; +use sqlx::sqlite::{SqlitePool, SqlitePoolOptions}; + +use crate::MIGRATOR; + +pub struct MailStore { + pool: SqlitePool, +} + +impl MailStore { + /// Creates a new connection to a SQLite database. + pub async fn open(uri: impl AsRef) -> Result { + let pool = SqlitePoolOptions::new().connect(uri.as_ref()).await?; + + // run migrations, if available + MIGRATOR.run(&pool).await?; + + Ok(MailStore { pool }) + } +} diff --git a/daemon/src/main.rs b/daemon/src/main.rs index accb49a..6dfa19d 100644 --- a/daemon/src/main.rs +++ b/daemon/src/main.rs @@ -1,16 +1,7 @@ #[macro_use] -extern crate serde; -#[macro_use] -extern crate anyhow; -#[macro_use] extern crate log; #[macro_use] extern crate futures; -#[macro_use] -extern crate derivative; - -mod config; -mod mail; use anyhow::Result; use clap::Clap; @@ -19,11 +10,10 @@ use futures::future::{ Either::{Left, Right}, FutureExt, }; +use panorama_daemon::config::{self, Config, MailAccountConfig, TlsMethod}; use panorama_imap::client::ConfigBuilder; use tokio::sync::oneshot; -use crate::config::{Config, MailAccountConfig, TlsMethod}; - type ExitListener = oneshot::Receiver<()>; /// The panorama daemon runs in the background and communicates with other @@ -55,7 +45,8 @@ async fn main() -> Result<()> { let new_config = config_watcher.borrow().clone(); tokio::spawn(run_with_config(new_config, exit_rx)); - // wait till the config has changed, then tell the current thread to stop + // wait till the config has changed, then tell the current thread to + // stop config_watcher.changed().await?; let _ = exit_tx.send(()); } @@ -79,6 +70,10 @@ async fn run_with_config(config: Config, exit: ExitListener) -> Result<()> { Ok(()) } +/// The main loop for a single mail account. +/// +/// This loop is restarted each time the config watcher gets a new config, at +/// which point `exit` is sent a single value telling us to break the loop. async fn run_single_mail_account( account_name: String, account: MailAccountConfig, @@ -108,6 +103,7 @@ async fn run_single_mail_account( loop { select! { + // we're being told to exit the loop _ = exit => break, } } diff --git a/imap/Cargo.toml b/imap/Cargo.toml index d9057f6..c4a27c0 100644 --- a/imap/Cargo.toml +++ b/imap/Cargo.toml @@ -22,7 +22,7 @@ rfc6154 = [] # list fuzzing = ["arbitrary", "panorama-proto-common/fuzzing"] [dependencies] -anyhow = "1.0.42" +anyhow = { version = "1.0.42", features = ["backtrace"] } async-trait = "0.1.51" bitflags = "1.2.1" bytes = "1.0.1" diff --git a/imap/src/client/auth.rs b/imap/src/client/auth.rs index f820ce3..6c70964 100644 --- a/imap/src/client/auth.rs +++ b/imap/src/client/auth.rs @@ -6,8 +6,14 @@ use panorama_proto_common::Bytes; use crate::client::inner::Inner; use crate::proto::command::{Command, CommandLogin}; -pub trait Client: AsyncRead + AsyncWrite + Unpin + Sync + Send + 'static {} -impl Client for C where C: Send + Sync + Unpin + AsyncWrite + AsyncRead + 'static {} +pub trait Client: + AsyncRead + AsyncWrite + Unpin + Sync + Send + 'static +{ +} +impl Client for C where + C: Send + Sync + Unpin + AsyncWrite + AsyncRead + 'static +{ +} #[async_trait] pub trait AuthMethod { diff --git a/imap/src/client/client.rs b/imap/src/client/client.rs index 0f18bff..b259a99 100644 --- a/imap/src/client/client.rs +++ b/imap/src/client/client.rs @@ -13,12 +13,12 @@ use tokio_rustls::client::TlsStream; use crate::proto::{ command::{ - Command, CommandFetch, CommandList, CommandSearch, CommandSelect, FetchItems, - SearchCriteria, Sequence, + Command, CommandFetch, CommandList, CommandSearch, CommandSelect, + FetchItems, SearchCriteria, Sequence, }, response::{ - Condition, Flag, Mailbox, MailboxData, MailboxList, MessageAttribute, Response, - ResponseCode, Status, + Condition, Flag, Mailbox, MailboxData, MailboxList, MessageAttribute, + Response, ResponseCode, Status, }, }; @@ -98,7 +98,10 @@ impl ClientUnauthenticated { } } - pub async fn auth(self, auth: impl AuthMethod) -> Result { + pub async fn auth( + self, + auth: impl AuthMethod, + ) -> Result { match self { // this is a no-op, we don't need to upgrade ClientUnauthenticated::Encrypted(mut inner) => { @@ -148,7 +151,11 @@ impl ClientAuthenticated { let mut folders = Vec::new(); for resp in data { - if let Response::MailboxData(MailboxData::List(MailboxList { mailbox, .. })) = resp { + if let Response::MailboxData(MailboxData::List(MailboxList { + mailbox, + .. + })) = resp + { folders.push(mailbox); } } @@ -157,7 +164,10 @@ impl ClientAuthenticated { } /// Runs the SELECT command - pub async fn select(&mut self, mailbox: impl AsRef) -> Result { + pub async fn select( + &mut self, + mailbox: impl AsRef, + ) -> Result { let cmd = Command::Select(CommandSelect { mailbox: Bytes::from(mailbox.as_ref().to_owned()), }); @@ -168,9 +178,15 @@ impl ClientAuthenticated { let mut select = SelectResponse::default(); for resp in data { match resp { - Response::MailboxData(MailboxData::Flags(flags)) => select.flags = flags, - Response::MailboxData(MailboxData::Exists(exists)) => select.exists = Some(exists), - Response::MailboxData(MailboxData::Recent(recent)) => select.recent = Some(recent), + Response::MailboxData(MailboxData::Flags(flags)) => { + select.flags = flags + } + Response::MailboxData(MailboxData::Exists(exists)) => { + select.exists = Some(exists) + } + Response::MailboxData(MailboxData::Recent(recent)) => { + select.recent = Some(recent) + } Response::Tagged( _, Condition { @@ -185,8 +201,12 @@ impl ClientAuthenticated { .. }) => match code { ResponseCode::Unseen(value) => select.unseen = Some(value), - ResponseCode::UidNext(value) => select.uid_next = Some(value), - ResponseCode::UidValidity(value) => select.uid_validity = Some(value), + ResponseCode::UidNext(value) => { + select.uid_next = Some(value) + } + ResponseCode::UidValidity(value) => { + select.uid_validity = Some(value) + } _ => {} }, _ => warn!("unknown response {:?}", resp), @@ -230,7 +250,9 @@ impl ClientAuthenticated { let stream = self.execute(cmd).await?; // let (done, data) = stream.wait().await?; Ok(stream.filter_map(|resp| match resp { - Response::Fetch(n, attrs) => future::ready(Some((n, attrs))).boxed(), + Response::Fetch(n, attrs) => { + future::ready(Some((n, attrs))).boxed() + } Response::Done(_) => future::ready(None).boxed(), _ => future::pending().boxed(), })) @@ -255,7 +277,9 @@ impl ClientAuthenticated { let stream = self.execute(cmd).await?; // let (done, data) = stream.wait().await?; Ok(stream.filter_map(|resp| match resp { - Response::Fetch(n, attrs) => future::ready(Some((n, attrs))).boxed(), + Response::Fetch(n, attrs) => { + future::ready(Some((n, attrs))).boxed() + } Response::Done(_) => future::ready(None).boxed(), _ => future::pending().boxed(), })) @@ -305,7 +329,10 @@ impl Drop for IdleToken { #[cfg_attr(docsrs, doc(cfg(feature = "rfc2177")))] impl Stream for IdleToken { type Item = Response; - fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll> { + fn poll_next( + mut self: Pin<&mut Self>, + cx: &mut Context, + ) -> Poll> { let stream = Pin::new(&mut self.stream); Stream::poll_next(stream, cx) } diff --git a/imap/src/client/codec.rs b/imap/src/client/codec.rs index 193258a..a03160c 100644 --- a/imap/src/client/codec.rs +++ b/imap/src/client/codec.rs @@ -21,7 +21,10 @@ impl<'a> Decoder for ImapCodec { type Item = Response; type Error = io::Error; - fn decode(&mut self, buf: &mut BytesMut) -> Result, io::Error> { + fn decode( + &mut self, + buf: &mut BytesMut, + ) -> Result, io::Error> { use nom::Err; if self.decode_need_message_bytes > buf.len() { @@ -31,22 +34,23 @@ impl<'a> Decoder for ImapCodec { // this is a pretty hot mess so here's my best attempt at explaining // buf, or buf1, is the original message - // "split" mutably removes all the bytes from the self, and returns a new - // BytesMut with the contents. so buf2 now has all the original contents - // and buf1 is now empty + // "split" mutably removes all the bytes from the self, and returns a + // new BytesMut with the contents. so buf2 now has all the + // original contents and buf1 is now empty let buf2 = buf.split(); - // now we're going to clone buf2 here, calling "freeze" turns the BytesMut - // back into Bytes so we can manipulate it. remember, none of this should be - // actually copying anything + // now we're going to clone buf2 here, calling "freeze" turns the + // BytesMut back into Bytes so we can manipulate it. remember, + // none of this should be actually copying anything let buf3 = buf2.clone().freeze(); debug!("going to parse a response since buffer len: {}", buf3.len()); // trace!("buf: {:?}", buf3); - // we don't know how long the message is going to be yet, so parse it out of the - // Bytes right now, and since the buffer is being consumed, subtracting the - // remainder of the string from the original total (buf4_len) will tell us how - // long the payload was. this also avoids unnecessary cloning + // we don't know how long the message is going to be yet, so parse it + // out of the Bytes right now, and since the buffer is being + // consumed, subtracting the remainder of the string from the + // original total (buf4_len) will tell us how long the payload + // was. this also avoids unnecessary cloning let buf4: Bytes = buf3.clone().into(); let buf4_len = buf4.len(); let (response, len) = match parse_response(buf4) { @@ -74,7 +78,8 @@ impl<'a> Decoder for ImapCodec { }; info!("success, parsed as {:?}", response); - // "unsplit" is the opposite of split, we're getting back the original data here + // "unsplit" is the opposite of split, we're getting back the original + // data here buf.unsplit(buf2); // and then move to after the message we just parsed @@ -94,7 +99,11 @@ pub struct TaggedCommand(pub Tag, pub Command); impl<'a> Encoder<&'a TaggedCommand> for ImapCodec { type Error = io::Error; - fn encode(&mut self, tagged_cmd: &TaggedCommand, dst: &mut BytesMut) -> Result<(), io::Error> { + fn encode( + &mut self, + tagged_cmd: &TaggedCommand, + dst: &mut BytesMut, + ) -> Result<(), io::Error> { let tag = &*tagged_cmd.0 .0; let command = &tagged_cmd.1; diff --git a/imap/src/client/configurable_cert_verifier.rs b/imap/src/client/configurable_cert_verifier.rs index ae2b59a..67a8f1f 100644 --- a/imap/src/client/configurable_cert_verifier.rs +++ b/imap/src/client/configurable_cert_verifier.rs @@ -5,11 +5,12 @@ use tokio_rustls::{ rustls::{ - Certificate, OwnedTrustAnchor, RootCertStore, ServerCertVerified, ServerCertVerifier, - TLSError, + Certificate, OwnedTrustAnchor, RootCertStore, ServerCertVerified, + ServerCertVerifier, TLSError, }, webpki::{ - self, DNSNameRef, EndEntityCert, SignatureAlgorithm, TLSServerTrustAnchors, TrustAnchor, + self, DNSNameRef, EndEntityCert, SignatureAlgorithm, + TLSServerTrustAnchors, TrustAnchor, }, }; @@ -75,7 +76,8 @@ impl ServerCertVerifier for ConfigurableCertVerifier { } } -type CertChainAndRoots<'a, 'b> = (EndEntityCert<'a>, Vec<&'a [u8]>, Vec>); +type CertChainAndRoots<'a, 'b> = + (EndEntityCert<'a>, Vec<&'a [u8]>, Vec>); fn prepare<'a, 'b>( roots: &'b RootCertStore, @@ -86,7 +88,8 @@ fn prepare<'a, 'b>( } // EE cert must appear first. - let cert = EndEntityCert::from(&presented_certs[0].0).map_err(TLSError::WebPKIError)?; + let cert = EndEntityCert::from(&presented_certs[0].0) + .map_err(TLSError::WebPKIError)?; let chain: Vec<&'a [u8]> = presented_certs .iter() diff --git a/imap/src/client/inner.rs b/imap/src/client/inner.rs index 20f3071..9160bfe 100644 --- a/imap/src/client/inner.rs +++ b/imap/src/client/inner.rs @@ -11,7 +11,10 @@ use futures::{ }; use panorama_proto_common::Bytes; use tokio::{ - io::{split, AsyncRead, AsyncWrite, AsyncWriteExt, BufWriter, ReadHalf, WriteHalf}, + io::{ + split, AsyncRead, AsyncWrite, AsyncWriteExt, BufWriter, ReadHalf, + WriteHalf, + }, sync::{mpsc, oneshot, RwLock}, task::JoinHandle, }; @@ -90,7 +93,8 @@ where // spawn the client->server loop let (write_exit, exit_rx) = oneshot::channel(); - let write_handle = tokio::spawn(write_loop(write_half, exit_rx, write_rx)); + let write_handle = + tokio::spawn(write_loop(write_half, exit_rx, write_rx)); let tag_number = AtomicU32::new(0); let capabilities = Arc::new(RwLock::new(None)); @@ -108,7 +112,10 @@ where }) } - pub async fn execute(&mut self, command: Command) -> Result { + pub async fn execute( + &mut self, + command: Command, + ) -> Result { let id = self.tag_number.fetch_add(1, Ordering::SeqCst); let tag = Tag(Bytes::from(format!("{}{}", TAG_PREFIX, id))); @@ -123,7 +130,10 @@ where Ok(stream) } - pub async fn has_capability(&mut self, cap: impl AsRef) -> Result { + pub async fn has_capability( + &mut self, + cap: impl AsRef, + ) -> Result { let cap_bytes = cap.as_ref().as_bytes().to_vec(); let (_, cap) = parse_capability(Bytes::from(cap_bytes))?; @@ -215,8 +225,8 @@ where // only listen for a new command if there isn't one already let mut cmd_fut = if let Some(ref cmd) = curr_cmd { debug!("current command: {:?}", cmd); - // if there is one, just make a future that never resolves so it'll always pick - // the other options in the select. + // if there is one, just make a future that never resolves so it'll + // always pick the other options in the select. future::pending().boxed().fuse() } else { command_rx.recv().boxed().fuse() diff --git a/imap/src/client/mod.rs b/imap/src/client/mod.rs index 5609199..30aab66 100644 --- a/imap/src/client/mod.rs +++ b/imap/src/client/mod.rs @@ -24,7 +24,9 @@ mod codec; mod inner; mod tls; -pub use self::client::{ClientAuthenticated, ClientUnauthenticated, Config, ConfigBuilder}; +pub use self::client::{ + ClientAuthenticated, ClientUnauthenticated, Config, ConfigBuilder, +}; pub use self::codec::{ImapCodec, TaggedCommand}; #[cfg(feature = "low-level")] diff --git a/imap/src/client/response_stream.rs b/imap/src/client/response_stream.rs index 7288739..4ca0d50 100644 --- a/imap/src/client/response_stream.rs +++ b/imap/src/client/response_stream.rs @@ -25,7 +25,9 @@ impl ResponseStream { /// Waits for the entire stream to finish, returning the DONE status and the /// stream - pub async fn wait(mut self) -> Result<(Option, Vec)> { + pub async fn wait( + mut self, + ) -> Result<(Option, Vec)> { let mut done = None; let mut vec = Vec::new(); while let Some(resp) = self.inner.recv().await { @@ -42,7 +44,10 @@ impl ResponseStream { impl Stream for ResponseStream { type Item = Response; - fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll> { + fn poll_next( + mut self: Pin<&mut Self>, + cx: &mut Context, + ) -> Poll> { self.inner.poll_recv(cx) } } diff --git a/imap/src/client/tls.rs b/imap/src/client/tls.rs index b2fed17..93e67c0 100644 --- a/imap/src/client/tls.rs +++ b/imap/src/client/tls.rs @@ -3,11 +3,15 @@ use std::sync::Arc; use anyhow::Result; use tokio::io::{AsyncRead, AsyncWrite}; use tokio_rustls::{ - client::TlsStream, rustls::ClientConfig as RustlsConfig, webpki::DNSNameRef, TlsConnector, + client::TlsStream, rustls::ClientConfig as RustlsConfig, + webpki::DNSNameRef, TlsConnector, }; /// Wraps the given async stream in TLS with the given hostname (required) -pub async fn wrap_tls(c: C, hostname: impl AsRef) -> Result> +pub async fn wrap_tls( + c: C, + hostname: impl AsRef, +) -> Result> where C: AsyncRead + AsyncWrite + Unpin, { diff --git a/imap/src/proto/command.rs b/imap/src/proto/command.rs index 09d9e9e..f6f98be 100644 --- a/imap/src/proto/command.rs +++ b/imap/src/proto/command.rs @@ -79,7 +79,9 @@ impl DisplayBytes for Command { quote(&list.mailbox) ) } - Command::Select(select) => write_bytes!(w, b"SELECT {}", quote(&select.mailbox)), + Command::Select(select) => { + write_bytes!(w, b"SELECT {}", quote(&select.mailbox)) + } // selected Command::UidFetch(fetch) => write_bytes!(w, b"UID FETCH {}", fetch), diff --git a/imap/src/proto/response.rs b/imap/src/proto/response.rs index da04d1d..3272629 100644 --- a/imap/src/proto/response.rs +++ b/imap/src/proto/response.rs @@ -17,7 +17,9 @@ pub type Atom = Bytes; pub struct Tag(pub Bytes); impl DisplayBytes for Tag { - fn display_bytes(&self, w: &mut dyn Write) -> io::Result<()> { write_bytes!(w, b"{}", self.0) } + fn display_bytes(&self, w: &mut dyn Write) -> io::Result<()> { + write_bytes!(w, b"{}", self.0) + } } #[derive(Clone, Debug, PartialEq, Eq, Hash)] @@ -84,7 +86,9 @@ impl DisplayBytes for Response { } Response::Expunge(n) => write_bytes!(w, b"{} EXPUNGE\r\n", n), Response::Fatal(cond) => write_bytes!(w, b"* {}\r\n", cond), - Response::Tagged(tag, cond) => write_bytes!(w, b"{} {}\r\n", tag, cond), + Response::Tagged(tag, cond) => { + write_bytes!(w, b"{} {}\r\n", tag, cond) + } _ => todo!(), } } diff --git a/imap/src/proto/rfc3501/mod.rs b/imap/src/proto/rfc3501/mod.rs index fcdf80d..c3b76ba 100644 --- a/imap/src/proto/rfc3501/mod.rs +++ b/imap/src/proto/rfc3501/mod.rs @@ -18,12 +18,13 @@ use panorama_proto_common::{ }; use super::response::{ - Address, Atom, Capability, Condition, Envelope, Flag, Mailbox, MailboxData, MailboxList, - MailboxListFlag, MessageAttribute, Response, ResponseCode, ResponseText, Status, Tag, - Timestamp, + Address, Atom, Capability, Condition, Envelope, Flag, Mailbox, MailboxData, + MailboxList, MailboxListFlag, MessageAttribute, Response, ResponseCode, + ResponseText, Status, Tag, Timestamp, }; use super::rfc2234::{ - is_char, is_cr, is_ctl, is_digit, is_dquote, is_lf, is_sp, CRLF, DIGIT, DQUOTE, SP, + is_char, is_cr, is_ctl, is_digit, is_dquote, is_lf, is_sp, CRLF, DIGIT, + DQUOTE, SP, }; /// Grammar rule `T / nil` produces `Option` @@ -50,7 +51,9 @@ rule!(pub addr_name : Option => nstring); rule!(pub astring : Bytes => alt((take_while1(is_astring_char), string))); -pub(crate) fn is_astring_char(c: u8) -> bool { is_atom_char(c) || is_resp_specials(c) } +pub(crate) fn is_astring_char(c: u8) -> bool { + is_atom_char(c) || is_resp_specials(c) +} rule!(pub ASTRING_CHAR : u8 => alt((ATOM_CHAR, resp_specials))); // really odd behavior about take_while1 is that if there isn't a character @@ -212,7 +215,8 @@ rule!(pub list_wildcards : u8 => satisfy(is_list_wildcards)); // determined to exceed a certain threshold so we don't have insane amounts of // data in memory pub fn literal(i: Bytes) -> VResult { - let mut length_of = terminated(delimited(byte(b'{'), number, byte(b'}')), CRLF); + let mut length_of = + terminated(delimited(byte(b'{'), number, byte(b'}')), CRLF); let (i, length) = length_of(i)?; debug!("length is: {:?}", length); map(take(length), Bytes::from)(i) @@ -373,7 +377,9 @@ rule!(pub tag : Tag => map(take_while1(is_tag_char), Tag)); rule!(pub text : Bytes => map(take_while1(is_text_char), Bytes::from)); -pub(crate) fn is_text_char(c: u8) -> bool { is_char(c) && !is_cr(c) && !is_lf(c) } +pub(crate) fn is_text_char(c: u8) -> bool { + is_char(c) && !is_cr(c) && !is_lf(c) +} rule!(pub TEXT_CHAR : u8 => satisfy(is_text_char)); rule!(pub time : NaiveTime => map_res( diff --git a/imap/src/proto/rfc3501/tests.rs b/imap/src/proto/rfc3501/tests.rs index 2a9d682..82273f3 100644 --- a/imap/src/proto/rfc3501/tests.rs +++ b/imap/src/proto/rfc3501/tests.rs @@ -66,9 +66,11 @@ fn test_capabilities() { ); assert_eq!( - capability_data(Bytes::from(b"CAPABILITY UNSELECT IMAP4rev1 NAMESPACE\r\n")) - .unwrap() - .1, + capability_data(Bytes::from( + b"CAPABILITY UNSELECT IMAP4rev1 NAMESPACE\r\n" + )) + .unwrap() + .1, vec![ Capability::Atom(Bytes::from(b"UNSELECT")), Capability::Atom(Bytes::from(b"NAMESPACE")) diff --git a/mbsync/Cargo.toml b/mbsync/Cargo.toml index 0604bcb..5bf3bf0 100644 --- a/mbsync/Cargo.toml +++ b/mbsync/Cargo.toml @@ -12,7 +12,7 @@ readme = "README.md" workspace = ".." [dependencies] -anyhow = "1.0.42" +anyhow = { version = "1.0.42", features = ["backtrace"] } bitflags = "1.2.1" clap = "3.0.0-beta.2" derivative = "2.2.0" diff --git a/mbsync/src/config.rs b/mbsync/src/config.rs index d1d84c2..e020d40 100644 --- a/mbsync/src/config.rs +++ b/mbsync/src/config.rs @@ -152,12 +152,16 @@ pub fn read_from_reader(r: R) -> Result { }, "subfolders" => match current_section.as_mut() { Some(Section::MaildirStore(ref mut builder)) => { - builder.subfolders(match parts[1].to_lowercase().as_str() { - "verbatim" => MaildirSubfolderStyle::Verbatim, - "maildir++" => MaildirSubfolderStyle::Maildirpp, - "legacy" => MaildirSubfolderStyle::Legacy, - unknown => panic!("unknown subfolder style '{}'", unknown), - }); + builder.subfolders( + match parts[1].to_lowercase().as_str() { + "verbatim" => MaildirSubfolderStyle::Verbatim, + "maildir++" => MaildirSubfolderStyle::Maildirpp, + "legacy" => MaildirSubfolderStyle::Legacy, + unknown => { + panic!("unknown subfolder style '{}'", unknown) + } + }, + ); } _ => panic!("unexpected subfolders keyword"), }, @@ -187,19 +191,24 @@ pub fn read_from_reader(r: R) -> Result { }, "sync" => match current_section.as_mut() { Some(Section::Channel(ref mut builder)) => { - builder.sync(parts[1..].iter().fold(ChannelSyncOps::empty(), |a, b| { - a | match b.to_lowercase().as_str() { - "none" => ChannelSyncOps::empty(), - "pull" => ChannelSyncOps::PULL, - "push" => ChannelSyncOps::PUSH, - "new" => ChannelSyncOps::NEW, - "renew" => ChannelSyncOps::RENEW, - "delete" => ChannelSyncOps::DELETE, - "flags" => ChannelSyncOps::FLAGS, - "all" => ChannelSyncOps::all(), - unknown => panic!("unknown sync op '{}'", unknown), - } - })); + builder.sync(parts[1..].iter().fold( + ChannelSyncOps::empty(), + |a, b| { + a | match b.to_lowercase().as_str() { + "none" => ChannelSyncOps::empty(), + "pull" => ChannelSyncOps::PULL, + "push" => ChannelSyncOps::PUSH, + "new" => ChannelSyncOps::NEW, + "renew" => ChannelSyncOps::RENEW, + "delete" => ChannelSyncOps::DELETE, + "flags" => ChannelSyncOps::FLAGS, + "all" => ChannelSyncOps::all(), + unknown => { + panic!("unknown sync op '{}'", unknown) + } + } + }, + )); } _ => panic!("unexpected near keyword"), }, diff --git a/mbsync/src/store.rs b/mbsync/src/store.rs index 88f9b0e..a49f0f9 100644 --- a/mbsync/src/store.rs +++ b/mbsync/src/store.rs @@ -43,7 +43,9 @@ pub trait IStore { async fn delete_mailbox(&mut self) -> Result<()> { todo!() } - async fn prepare_load_mailbox(&mut self, opts: u32) -> Result<()> { todo!() } + async fn prepare_load_mailbox(&mut self, opts: u32) -> Result<()> { + todo!() + } async fn close_mailbox(&mut self) -> Result<()> { todo!() } @@ -112,7 +114,8 @@ impl IStore for ImapStore { use futures::stream::StreamExt; use panorama_imap::proto::command::FetchItems; - let mut result = client.uid_fetch(&[8225], &[], FetchItems::All).await?; + let mut result = + client.uid_fetch(&[8225], &[], FetchItems::All).await?; while let Some(item) = result.next().await { println!("epic: {:?}", item); } @@ -128,7 +131,9 @@ pub struct MaildirStore { } impl MaildirStore { - pub fn new(config: MaildirStoreConfig) -> Box { Box::new(MaildirStore { config }) } + pub fn new(config: MaildirStoreConfig) -> Box { + Box::new(MaildirStore { config }) + } } #[async_trait] diff --git a/proto-common/Cargo.toml b/proto-common/Cargo.toml index 0f6a4c0..ecd7311 100644 --- a/proto-common/Cargo.toml +++ b/proto-common/Cargo.toml @@ -13,7 +13,7 @@ default = [] fuzzing = ["arbitrary"] [dependencies] -anyhow = "1.0.42" +anyhow = { version = "1.0.42", features = ["backtrace"] } bstr = "0.2.15" bytes = "1.0.1" format-bytes = "0.2.2" diff --git a/proto-common/src/bytes.rs b/proto-common/src/bytes.rs index 30ed4a9..120e6a6 100644 --- a/proto-common/src/bytes.rs +++ b/proto-common/src/bytes.rs @@ -39,12 +39,16 @@ impl Bytes { } impl DisplayBytes for Bytes { - fn display_bytes(&self, w: &mut dyn Write) -> io::Result<()> { w.write(&*self.0).map(|_| ()) } + fn display_bytes(&self, w: &mut dyn Write) -> io::Result<()> { + w.write(&*self.0).map(|_| ()) + } } static CHARS: &[u8] = b"0123456789abcdef"; impl HexDisplay for Bytes { - fn to_hex(&self, chunk_size: usize) -> String { self.to_hex_from(chunk_size, 0) } + fn to_hex(&self, chunk_size: usize) -> String { + self.to_hex_from(chunk_size, 0) + } fn to_hex_from(&self, chunk_size: usize, from: usize) -> String { let mut v = Vec::with_capacity(self.len() * 3); @@ -119,7 +123,10 @@ pub trait ShitNeededForParsing: Sized { fn take_split(&self, count: usize) -> (Self, Self); // InputTakeAtPosition - fn split_at_position>(&self, predicate: P) -> IResult + fn split_at_position>( + &self, + predicate: P, + ) -> IResult where P: Fn(Self::Item) -> bool; fn split_at_position1>( @@ -148,7 +155,9 @@ impl ShitNeededForParsing for Bytes { type Item = u8; type Sliced = Bytes; - fn slice>(&self, range: R) -> Self::Sliced { Self(self.0.slice(range)) } + fn slice>(&self, range: R) -> Self::Sliced { + Self(self.0.slice(range)) + } fn first(&self) -> Option { self.0.first().copied() } fn slice_index(&self, count: usize) -> Result { @@ -168,7 +177,10 @@ impl ShitNeededForParsing for Bytes { } // InputTakeAtPosition - fn split_at_position>(&self, predicate: P) -> IResult + fn split_at_position>( + &self, + predicate: P, + ) -> IResult where P: Fn(Self::Item) -> bool, { diff --git a/proto-common/src/convert_error.rs b/proto-common/src/convert_error.rs index d4976b1..e77db7b 100644 --- a/proto-common/src/convert_error.rs +++ b/proto-common/src/convert_error.rs @@ -11,7 +11,10 @@ use nom::{ use crate::VResult; /// Same as nom's dbg_dmp, except operates on Bytes -pub fn dbg_dmp<'a, T, F, O>(mut f: F, context: &'static str) -> impl FnMut(T) -> VResult +pub fn dbg_dmp<'a, T, F, O>( + mut f: F, + context: &'static str, +) -> impl FnMut(T) -> VResult where F: FnMut(T) -> VResult, T: AsRef<[u8]> + HexDisplay + Clone + Debug + Deref, @@ -31,7 +34,10 @@ where } /// Same as nom's convert_error, except operates on u8 -pub fn convert_error + Debug>(input: I, e: &VerboseError) -> String { +pub fn convert_error + Debug>( + input: I, + e: &VerboseError, +) -> String { let mut result = String::new(); debug!("e: {:?}", e); @@ -41,20 +47,29 @@ pub fn convert_error + Debug>(input: I, e: &VerboseError if input.is_empty() { match kind { VerboseErrorKind::Char(c) => { - write!(&mut result, "{}: expected '{}', got empty input\n\n", i, c) + write!( + &mut result, + "{}: expected '{}', got empty input\n\n", + i, c + ) } VerboseErrorKind::Context(s) => { write!(&mut result, "{}: in {}, got empty input\n\n", i, s) } VerboseErrorKind::Nom(e) => { - write!(&mut result, "{}: in {:?}, got empty input\n\n", i, e) + write!( + &mut result, + "{}: in {:?}, got empty input\n\n", + i, e + ) } } } else { let prefix = &input.as_bytes()[..offset]; // Count the number of newlines in the first `offset` bytes of input - let line_number = prefix.iter().filter(|&&b| b == b'\n').count() + 1; + let line_number = + prefix.iter().filter(|&&b| b == b'\n').count() + 1; // Find the line that includes the subslice: // Find the *last* newline before the substring starts @@ -72,7 +87,8 @@ pub fn convert_error + Debug>(input: I, e: &VerboseError .unwrap_or(&input[line_begin..]) .trim_end(); - // The (1-indexed) column number is the offset of our substring into that line + // The (1-indexed) column number is the offset of our substring into + // that line let column_number = line.offset(substring) + 1; match kind { diff --git a/proto-common/src/formatter.rs b/proto-common/src/formatter.rs index 0631d76..1c78ad5 100644 --- a/proto-common/src/formatter.rs +++ b/proto-common/src/formatter.rs @@ -7,7 +7,11 @@ /// let quote = quote_string(b'\x22', b'\\', |c| c == b'\x22' || c == b'\x27'); /// assert_eq!(quote(b"hello \"' world"), b"\"hello \\\"\\' world\""); /// ``` -pub fn quote_string(quote: u8, escape: u8, should_escape: F) -> impl Fn(B) -> Vec +pub fn quote_string( + quote: u8, + escape: u8, + should_escape: F, +) -> impl Fn(B) -> Vec where B: AsRef<[u8]>, F: Fn(u8) -> bool, diff --git a/proto-common/src/lib.rs b/proto-common/src/lib.rs index 1337ba6..2f7d1d7 100644 --- a/proto-common/src/lib.rs +++ b/proto-common/src/lib.rs @@ -12,4 +12,6 @@ mod rule; pub use crate::bytes::{Bytes, ShitCompare, ShitNeededForParsing}; pub use crate::convert_error::{convert_error, dbg_dmp}; pub use crate::formatter::quote_string; -pub use crate::parsers::{byte, never, parse_num, satisfy, skip, tagi, take, take_while1, VResult}; +pub use crate::parsers::{ + byte, never, parse_num, satisfy, skip, tagi, take, take_while1, VResult, +}; diff --git a/proto-common/src/parsers.rs b/proto-common/src/parsers.rs index efb6eb8..f68bbed 100644 --- a/proto-common/src/parsers.rs +++ b/proto-common/src/parsers.rs @@ -177,7 +177,9 @@ where let snd = i.slice(tag_len..); Ok((snd, fst)) } - CompareResult::Incomplete => Err(Err::Incomplete(Needed::new(tag_len - i.input_len()))), + CompareResult::Incomplete => { + Err(Err::Incomplete(Needed::new(tag_len - i.input_len()))) + } CompareResult::Error => { let e: ErrorKind = ErrorKind::Tag; Err(Err::Error(E::from_error_kind(i, e))) diff --git a/rustfmt.toml b/rustfmt.toml index 397187f..5106ca8 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,3 +1,3 @@ fn_single_line = true -max_width = 100 -wrap_comments = true \ No newline at end of file +max_width = 80 +wrap_comments = true