From 1e29992068a1f4622cecaa9b0d3d1e3238ef7c58 Mon Sep 17 00:00:00 2001 From: pyro57000 Date: Thu, 16 Oct 2025 17:34:16 -0500 Subject: [PATCH] re-wrote the tool, it actually works now! --- Cargo.lock | 311 ++++++++++++------------- Cargo.toml | 2 +- README.md | 5 + src/main-bkup.rs | 425 +++++++++++++++++++++++++++++++++ src/main.rs | 593 +++++++++++++++++++++++++---------------------- 5 files changed, 899 insertions(+), 437 deletions(-) create mode 100644 src/main-bkup.rs diff --git a/Cargo.lock b/Cargo.lock index 36ebfc4..8496feb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,26 +2,11 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - [[package]] name = "anstream" -version = "0.6.19" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", "anstyle-parse", @@ -34,9 +19,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" @@ -49,50 +34,29 @@ dependencies = [ [[package]] name = "anstyle-query" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" +checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "anstyle-wincon" -version = "3.0.9" +version = "3.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" +checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.59.0", -] - -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - -[[package]] -name = "backtrace" -version = "0.3.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets", + "windows-sys 0.60.2", ] [[package]] name = "bitflags" -version = "2.9.1" +version = "2.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" [[package]] name = "bytes" @@ -102,15 +66,15 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cfg-if" -version = "1.0.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "clap" -version = "4.5.41" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9" +checksum = "f4512b90fa68d3a9932cea5184017c5d200f5921df706d45e853537dea51508f" dependencies = [ "clap_builder", "clap_derive", @@ -118,9 +82,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.41" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d" +checksum = "0025e98baa12e766c67ba13ff4695a887a1eba19569aad00a472546795bd6730" dependencies = [ "anstream", "anstyle", @@ -130,9 +94,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.41" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" +checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" dependencies = [ "heck", "proc-macro2", @@ -142,9 +106,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "colorchoice" @@ -161,29 +125,12 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - [[package]] name = "heck" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "io-uring" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013" -dependencies = [ - "bitflags", - "cfg-if", - "libc", -] - [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -192,35 +139,19 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "libc" -version = "0.2.174" +version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" [[package]] name = "lock_api" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] -[[package]] -name = "memchr" -version = "2.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" - -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", -] - [[package]] name = "mio" version = "1.0.4" @@ -232,15 +163,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "object" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell_polyfill" version = "1.70.1" @@ -249,9 +171,9 @@ checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" [[package]] name = "parking_lot" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -259,15 +181,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.11" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets", + "windows-link", ] [[package]] @@ -278,37 +200,31 @@ checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "proc-macro2" -version = "1.0.95" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.40" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" dependencies = [ "proc-macro2", ] [[package]] name = "redox_syscall" -version = "0.5.13" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ "bitflags", ] -[[package]] -name = "rustc-demangle" -version = "0.1.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" - [[package]] name = "same-file" version = "1.0.6" @@ -326,19 +242,13 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "signal-hook-registry" -version = "1.4.5" +version = "1.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" +checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" dependencies = [ "libc", ] -[[package]] -name = "slab" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" - [[package]] name = "smallvec" version = "1.15.1" @@ -357,12 +267,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.10" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.60.2", ] [[package]] @@ -373,9 +283,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.104" +version = "2.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" dependencies = [ "proc-macro2", "quote", @@ -384,29 +294,26 @@ dependencies = [ [[package]] name = "tokio" -version = "1.46.1" +version = "1.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" dependencies = [ - "backtrace", "bytes", - "io-uring", "libc", "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", - "slab", "socket2", "tokio-macros", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", @@ -415,9 +322,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" [[package]] name = "utf8parse" @@ -443,21 +350,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "winapi-util" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] -name = "windows-sys" -version = "0.52.0" +name = "windows-link" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-sys" @@ -465,7 +369,25 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", ] [[package]] @@ -474,14 +396,31 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] @@ -490,44 +429,92 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" diff --git a/Cargo.toml b/Cargo.toml index 5d5dede..77fd654 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,5 +6,5 @@ edition = "2024" [dependencies] clap = { version = "4.5.41", features = ["derive"] } colored = "3.0.0" -tokio = { version = "1.46.1", features = ["full"] } +tokio = { version = "1.48.0", features = ["full"] } walkdir = "2.5.0" diff --git a/README.md b/README.md index c291cdd..36352f4 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,7 @@ # snaferrous snafflerish but rusty! + +Currently it just looks for some hardcoded keywords to determine if a file has sensitive infomation, but it works! + +# USAGE: + diff --git a/src/main-bkup.rs b/src/main-bkup.rs new file mode 100644 index 0000000..0898a44 --- /dev/null +++ b/src/main-bkup.rs @@ -0,0 +1,425 @@ +/* +Author: Kevin (Kaged Pyro) Gunter +Purpose: I got tired of snaffler getting caught, so I rewrote it in rust, which edrs have trouble detecting. + +*/ +use clap::Parser; +use std::fmt::Debug; +use std::fs; +use std::fs::read_to_string; +use std::fs::OpenOptions; +use std::io::Write; +use std::ops::Index; +use std::path::PathBuf; +use std::process::exit; +use std::process::Command; +use std::thread; +use std::time::Duration; +use tokio; +use tokio::sync::mpsc::{channel, Sender, Receiver}; +use colored::Colorize; + +#[derive(Parser, Debug)] +#[command(version, about, long_about = Some("finds shares, but its written in rust which sometimes gets past EDR!"))] +struct Args{ + #[arg(short, long, help = "path to save output file Defaults to not saving output.")] + outfile: Option, + + #[arg(short, long, help = "number of threads to use, default to 10. \nNote thre thread count will be doubled, one set for share finder tasks, and one set for file and infor finding tasks.")] + threads: Option, + + #[arg(short, long, help = "specific targets. should be comma separated.")] + targets: Option, +} + +struct ShareFinder{ + id: usize, + tx: Sender, +} + +#[derive(Clone)] +struct Message{ + source: MessageType, + destination: MessageType, + content: String, +} + +#[derive(Clone, PartialEq)] +enum MessageType{ + ShareMessage, + InfoMessage, + ControlMessage, +} + + +async fn find_shares(task: ShareFinder, mut rx: Receiver){ + println!("{} share task started!", task.id); + let ping_recv = rx.recv().await; + if ping_recv.is_some(){ + let message = Message{source: MessageType::ShareMessage, destination: MessageType::ControlMessage, content: String::from("pong!")}; + task.tx.send(message).await.unwrap(); + } + loop{ + if rx.capacity() == 0{ + println!("rx is full for share finder {}", task.id); + } + let rx_res = rx.recv().await; + if rx_res.is_some(){ + let computer = rx_res.unwrap().content; + if computer == String::from("||DONE||"){ + let message = Message{source: MessageType::ShareMessage, destination: MessageType::ControlMessage, content: format!("{}:||DONE||", task.id)}; + task.tx.send(message).await.unwrap(); + break; + } + println!("scanning {}", computer); + let share_list_res = Command::new("net").arg("view").arg(computer.clone()).arg("/all").output(); + let mut error_string = String::new(); + let mut success_string = String::new(); + if share_list_res.is_ok(){ + let output = share_list_res.unwrap(); + if output.stdout.len() > 0{ + success_string = String::from_utf8_lossy(&output.stdout).to_string(); + } + + if output.stderr.len() > 0{ + error_string = String::from_utf8_lossy(&output.stderr).to_string(); + } + } + else{ + error_string = share_list_res.err().unwrap().to_string(); + } + if error_string.len() > 0{ + eprintln!("{}", "Error listing shares!".red()); + eprint!("{}", error_string.red()); + } + else if success_string.len() > 0{ + for line in success_string.lines(){ + if line.contains("Disk"){ + let share_name = line.split_whitespace().collect::>()[0]; + let share_path = format!("\\\\{}\\{}", computer, share_name); + let message = Message{source: MessageType::ShareMessage, destination: MessageType::InfoMessage, content: format!("{}:{}", task.id, share_path)}; + task.tx.send(message).await.unwrap(); + } + } + } + } + } +} + +async fn find_info(task: ShareFinder, mut rx: Receiver){ + println!("{} file task started!", task.id); + let ping_recv = rx.recv().await; + if ping_recv.is_some(){ + let message = Message{source: MessageType::ShareMessage, destination: MessageType::ControlMessage, content: String::from("pong!")}; + task.tx.send(message).await.unwrap(); + } + let files_to_read = vec![ + ".txt", + ".ini", + ".xml", + ".json", + ".config", + ".conf", + ".bat", + ".cmd", + ".sql", + ".ps1", + ".py", + ".vbscript" + ]; + + let interesting_info = vec![ + "password", + "pass", + "user", + "api", + "key", + "credit card", + "cc", + "ssn", + "social Security", + "tax", + "i9", + "it", + "identified", + "username", + ]; + loop{ + let rx_res = rx.recv().await; + if rx_res.is_some(){ + let message = rx_res.unwrap(); + let message_vec: Vec<&str> = message.content.split(":").collect(); + let path = message_vec[1]; + if path.contains("||DONE||"){ + let done_message = Message{source: MessageType::InfoMessage, destination: MessageType::ControlMessage, content: format!("{}:||DONE||", task.id)}; + task.tx.send(done_message).await.unwrap(); + } + for entry_res in walkdir::WalkDir::new(path){ + if entry_res.is_ok(){ + let entry = entry_res.unwrap(); + let file_path = entry.into_path(); + let mut file_name = String::new(); + let mut file_content = String::new(); + if file_path.file_name().is_some(){ + file_name = file_path.file_name().unwrap().to_string_lossy().to_string(); + } + for extension in &files_to_read{ + if file_name.contains(extension){ + let file_content_res = read_to_string(&file_path); + if file_content_res.is_ok(){ + file_content = file_content_res.unwrap(); + } + } + } + for thing in &interesting_info{ + if file_name.contains(thing) || file_content.contains(thing){ + let message = Message{source: MessageType::InfoMessage, destination: MessageType::ControlMessage, content: format!("{}:Keyword match at {}", task.id, file_path.display())}; + task.tx.send(message).await.unwrap(); + } + else{ + let message = Message{source: MessageType::InfoMessage, destination: MessageType::ControlMessage, content: format!("{}:file found at {}", task.id, file_path.display())}; + task.tx.send(message).await.unwrap(); + } + } + } + } + } + } +} + + + +#[tokio::main] +async fn main(){ + let args = Args::parse(); + let mut outfile = PathBuf::new(); + let mut file_threads = 1; + let mut share_threads = 1; + let mut save = false; + let mut computers = Vec::new(); + if args.outfile.is_some(){ + outfile = args.outfile.unwrap(); + save = true; + } + if args.threads.is_some(){ + let threads = args.threads.unwrap() / 2; + file_threads = threads; + share_threads = threads; + } + if args.targets.is_some(){ + println!("gathering the targets you gave me."); + let targets = args.targets.unwrap(); + if targets.contains(","){ + let split_targets: Vec<&str> = targets.split(",").collect(); + for target in split_targets{ + computers.push(target.to_string()); + } + } + else{ + computers.push(targets); + } + } + else{ + println!("no targets given, proceeding with domain computer enumeration..."); + println!("finding computers..."); + let command_string = String::from("net group \"domain computers\" /domain"); + let mut temp_file = fs::File::create("./temp.bat").unwrap(); + write!(temp_file, "{}", command_string).unwrap(); + let computer_res = Command::new(".\\temp.bat").output(); + let mut error_string = String::new(); + let mut success_string = String::new(); + fs::remove_file("./temp.bat").unwrap(); + if computer_res.is_ok(){ + let output = computer_res.unwrap(); + if output.stdout.len() > 0{ + success_string = String::from_utf8_lossy(&output.stdout).to_string(); + } + else if output.stderr.len() > 0{ + error_string = String::from_utf8_lossy(&output.stderr).to_string(); + } + } + else{ + error_string = computer_res.err().unwrap().to_string(); + } + if error_string.len() > 0{ + eprintln!("{}", "error getting computers!".red()); + eprintln!("{}", error_string.red()); + exit(1); + } + if success_string.len() > 0{ + for line in success_string.lines(){ + if line.contains("$"){ + let words:Vec<&str> = line.split_whitespace().collect(); + for word in words{ + let mut computer_name = word.to_string(); + computer_name.pop(); + println!("{} {}", "found".green(), computer_name.green()); + computers.push(computer_name); + } + } + } + } + } + if share_threads > computers.len(){ + share_threads = computers.len(); + //file_threads = computers.len(); + } + let mut share_handles = Vec::new(); + let mut file_handles = Vec::new(); + println!("computer enumeration finished, starting task finder threads..."); + let (maintx, mut mainrx) = channel(1024); + let mut share_tasks = Vec::new(); + let mut share_txes = Vec::new(); + let mut file_tasks = Vec::new(); + let mut file_txes = Vec::new(); + for id in 0..share_threads{ + println!("starting share task {}...", id); + let (share_tx,share_rx) = channel(1); + let new_share_task = ShareFinder{id, tx: maintx.clone()}; + share_handles.push(tokio::spawn(find_shares(new_share_task, share_rx))); + share_tasks.push(id); + share_txes.push(share_tx.clone()); + let ping_message = Message{source: MessageType::ControlMessage, destination: MessageType::ShareMessage, content: String::from("ping!")}; + share_tx.send(ping_message).await.unwrap(); + loop{ + let rx_recv = mainrx.recv().await; + if rx_recv.is_some(){ + let message = rx_recv.unwrap(); + if message.content == String::from("pong!"){ + println!("{} ready!", id); + break; + } + } + println!("didn't recieve file pong from {}", id); + } + } + for id in 0..file_threads{ + println!("starting file task {}...", id); + let (file_tx, file_rx) = channel(1); + let new_file_task = ShareFinder{id, tx: maintx.clone()}; + file_handles.push(tokio::spawn(find_info(new_file_task, file_rx))); + file_tasks.push(id); + file_txes.push(file_tx.clone()); + let ping_message = Message{source: MessageType::ControlMessage, destination: MessageType::ShareMessage, content: String::from("ping!")}; + file_tx.send(ping_message).await.unwrap(); + loop{ + let rx_recv = mainrx.recv().await; + if rx_recv.is_some(){ + let message = rx_recv.unwrap(); + if message.content == String::from("pong!"){ + println!("{} ready!", id); + break; + } + } + println!("didn't recieve file pong from {}", id); + } + } + let mut current_computer = 0; + let mut shares_finished = false; + let mut files_finished = false; + let mut file_buffer = Vec::new(); + let mut finished_counter = 0; + let mut empty_counter = 0; + let mut handled_lines = Vec::new(); + loop { + if files_finished && shares_finished{ + exit(0); + } + if !mainrx.is_empty(){ + finished_counter = 0; + empty_counter = 0; + let rx_res = mainrx.recv().await; + if rx_res.is_some(){ + let message = rx_res.unwrap(); + match message.destination{ + MessageType::ControlMessage => { + let message_vec: Vec<&str> = message.content.split(":").collect(); + let _id = message_vec[0]; + let message_content = message_vec[1].to_string(); + match message_content{ + _ => { + if !handled_lines.contains(&message_content){ + if save{ + let open_res = OpenOptions::new().append(true).create(true).open(&outfile); + if open_res.is_ok(){ + let mut file = open_res.unwrap(); + let write_res = write!(file, "{}\n", message_content); + if write_res.is_err(){ + eprintln!("{}", "error writing to outfile!".red()); + eprintln!("{}", write_res.err().unwrap().to_string().red()); + } + } + } + println!("{}", message_content.green()); + handled_lines.push(message_content); + } + + } + } + } + MessageType::InfoMessage => { + file_buffer.push(message.content); + } + MessageType::ShareMessage => {} + } + } + } + let mut sent = false; + if !shares_finished{ + for tx in &share_txes{ + if tx.capacity() > 0{ + let message = Message{source: MessageType::ShareMessage, destination: MessageType::ShareMessage, content: computers[current_computer].clone()}; + tx.send(message).await.unwrap(); + sent = true; + break; + } + } + if sent{ + current_computer +=1; + if current_computer == computers.len() { + shares_finished = true; + } + } + } + if shares_finished{ + if file_buffer.len() == 0{ + empty_counter += 1; + println!("empty counter: {}", empty_counter); + } + if empty_counter >= 100{ + finished_counter +=1; + println!("finished counter: {}", finished_counter); + thread::sleep(Duration::from_millis(50)); + } + } + if file_buffer.len() > 0{ + let mut sent_index = Vec::new(); + empty_counter = 0; + finished_counter = 0; + let mut current_tx = 0; + for index in 0 .. file_buffer.len() - 1{ + let mut sent = false; + let message = Message{source: MessageType::ControlMessage, destination: MessageType::InfoMessage, content: file_buffer[index].clone()}; + if file_txes[current_tx].capacity()> 0{ + file_txes[current_tx].send(message).await.unwrap(); + sent = true; + } + else{ + current_tx += 1; + if current_tx == file_txes.len(){ + current_tx = 0; + } + } + if sent{ + sent_index.push(index); + } + } + for index in sent_index{ + file_buffer.remove(index); + } + } + if finished_counter == 10{ + files_finished = true; + } + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index b03151b..bff3946 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,23 +1,34 @@ -/* -Author: Kevin (Kaged Pyro) Gunter -Purpose: I got tired of snaffler getting caught, so I rewrote it in rust, which edrs have trouble detecting. - -*/ use clap::Parser; use std::fmt::Debug; use std::fs; use std::fs::read_to_string; use std::fs::OpenOptions; use std::io::Write; -use std::ops::Index; use std::path::PathBuf; use std::process::exit; use std::process::Command; -use std::thread; -use std::time::Duration; -use tokio; -use tokio::sync::mpsc::{channel, Sender, Receiver}; use colored::Colorize; +use tokio; +use tokio::sync::mpsc::{channel, Sender}; + +/* +Author: Kevin (Kaged Pyro) Gunter +Purpose: I got tired of snaffler getting caught, so I rewrote it in rust, which edrs have trouble detecting. + +*/ + +/*#[derive(Parser, Debug)] +#[command(version, about, long_about = Some("finds shares, but its written in rust which sometimes gets past EDR!"))] +struct Args{ + #[arg(short, long, help = "path to save output file Defaults to not saving output.")] + outfile: Option, + + #[arg(short, long, help = "number of threads to use, default to 10. \nNote thre thread count will be doubled, one set for share finder tasks, and one set for file and infor finding tasks.")] + threads: Option, + + #[arg(short, long, help = "specific targets. should be comma separated.")] + targets: Option, +}*/ #[derive(Parser, Debug)] #[command(version, about, long_about = Some("finds shares, but its written in rust which sometimes gets past EDR!"))] @@ -30,49 +41,44 @@ struct Args{ #[arg(short, long, help = "specific targets. should be comma separated.")] targets: Option, -} -struct ShareFinder{ - id: usize, - tx: Sender, + #[arg(short, long, help = "echo all found files to the console, regardless of keyword matching. (all files will still be saved to the log file)")] + verbose: bool, } #[derive(Clone)] +struct FinderTask{ + id: usize, + target: String, + tasktype: TaskType, +} + +#[derive(Clone)] +struct Finding{ + path: String, + keyword: Option +} + struct Message{ - source: MessageType, - destination: MessageType, - content: String, + source: usize, + tasktype: TaskType, + finding: Option, + task_finished: bool, } -#[derive(Clone, PartialEq)] -enum MessageType{ - ShareMessage, - InfoMessage, - ControlMessage, +#[derive(Clone)] +enum TaskType{ + Share, + File, + Info, } -async fn find_shares(task: ShareFinder, mut rx: Receiver){ - println!("{} share task started!", task.id); - let ping_recv = rx.recv().await; - if ping_recv.is_some(){ - let message = Message{source: MessageType::ShareMessage, destination: MessageType::ControlMessage, content: String::from("pong!")}; - task.tx.send(message).await.unwrap(); - } - loop{ - if rx.capacity() == 0{ - println!("rx is full for share finder {}", task.id); - } - let rx_res = rx.recv().await; - if rx_res.is_some(){ - let computer = rx_res.unwrap().content; - if computer == String::from("||DONE||"){ - let message = Message{source: MessageType::ShareMessage, destination: MessageType::ControlMessage, content: format!("{}:||DONE||", task.id)}; - task.tx.send(message).await.unwrap(); - break; - } - println!("scanning {}", computer); - let share_list_res = Command::new("net").arg("view").arg(computer.clone()).arg("/all").output(); +async fn task_handler(id: usize, current_task: FinderTask, tx: Sender){ + match current_task.tasktype{ + TaskType::Share => { + println!("scanning {}", current_task.target); + let share_list_res = Command::new("net").arg("view").arg(current_task.target.clone()).arg("/all").output(); let mut error_string = String::new(); let mut success_string = String::new(); if share_list_res.is_ok(){ @@ -93,108 +99,119 @@ async fn find_shares(task: ShareFinder, mut rx: Receiver){ eprint!("{}", error_string.red()); } else if success_string.len() > 0{ + let mut sent_lines = Vec::new(); for line in success_string.lines(){ if line.contains("Disk"){ let share_name = line.split_whitespace().collect::>()[0]; - let share_path = format!("\\\\{}\\{}", computer, share_name); - let message = Message{source: MessageType::ShareMessage, destination: MessageType::InfoMessage, content: format!("{}:{}", task.id, share_path)}; - task.tx.send(message).await.unwrap(); + let share_path = format!("\\\\{}\\{}", current_task.target, share_name); + if !sent_lines.contains(&share_path){ + sent_lines.push(share_path.clone()); + let finding = Finding{path: share_path, keyword: None}; + let message = Message{source: id, tasktype: TaskType::Share, finding: Some(finding), task_finished: false}; + tx.send(message).await.unwrap(); + } } } } } - } -} - -async fn find_info(task: ShareFinder, mut rx: Receiver){ - println!("{} file task started!", task.id); - let ping_recv = rx.recv().await; - if ping_recv.is_some(){ - let message = Message{source: MessageType::ShareMessage, destination: MessageType::ControlMessage, content: String::from("pong!")}; - task.tx.send(message).await.unwrap(); - } - let files_to_read = vec![ - ".txt", - ".ini", - ".xml", - ".json", - ".config", - ".conf", - ".bat", - ".cmd", - ".sql", - ".ps1", - ".py", - ".vbscript" - ]; - - let interesting_info = vec![ - "password", - "pass", - "user", - "api", - "key", - "credit card", - "cc", - "ssn", - "social Security", - "tax", - "i9", - "it", - "identified", - "username", - ]; - loop{ - let rx_res = rx.recv().await; - if rx_res.is_some(){ - let message = rx_res.unwrap(); - let message_vec: Vec<&str> = message.content.split(":").collect(); - let path = message_vec[1]; - if path.contains("||DONE||"){ - let done_message = Message{source: MessageType::InfoMessage, destination: MessageType::ControlMessage, content: format!("{}:||DONE||", task.id)}; - task.tx.send(done_message).await.unwrap(); - } - for entry_res in walkdir::WalkDir::new(path){ + TaskType::File => { + let mut sent_lines = Vec::new(); + for entry_res in walkdir::WalkDir::new(current_task.target.clone()){ if entry_res.is_ok(){ let entry = entry_res.unwrap(); let file_path = entry.into_path(); - let mut file_name = String::new(); - let mut file_content = String::new(); if file_path.file_name().is_some(){ - file_name = file_path.file_name().unwrap().to_string_lossy().to_string(); - } - for extension in &files_to_read{ - if file_name.contains(extension){ - let file_content_res = read_to_string(&file_path); - if file_content_res.is_ok(){ - file_content = file_content_res.unwrap(); - } - } - } - for thing in &interesting_info{ - if file_name.contains(thing) || file_content.contains(thing){ - let message = Message{source: MessageType::InfoMessage, destination: MessageType::ControlMessage, content: format!("{}:Keyword match at {}", task.id, file_path.display())}; - task.tx.send(message).await.unwrap(); - } - else{ - let message = Message{source: MessageType::InfoMessage, destination: MessageType::ControlMessage, content: format!("{}:file found at {}", task.id, file_path.display())}; - task.tx.send(message).await.unwrap(); + let file_path_string = file_path.display().to_string(); + if !sent_lines.contains(&file_path_string){ + sent_lines.push(file_path_string.clone()); + let finding = Finding{path: file_path_string, keyword: None}; + let message = Message{source: id, tasktype: TaskType::File, finding: Some(finding), task_finished: false}; + tx.send(message).await.unwrap(); } } } } } + TaskType::Info => { + let files_to_read = vec![ + ".txt", + ".ini", + ".xml", + ".json", + ".config", + ".conf", + ".bat", + ".cmd", + ".sql", + ".ps1", + ".py", + ".vbscript" + ]; + + let interesting_info = vec![ + "password", + "pass", + "user", + "api", + "key", + "credit card", + "cc", + "ssn", + "social Security", + "tax", + "i9", + "it", + "identified", + "username", + ]; + let mut file_content = String::new(); + for extension in &files_to_read{ + if current_task.target.contains(extension){ + let file_content_res = read_to_string(¤t_task.target); + if file_content_res.is_ok(){ + file_content = file_content_res.unwrap(); + } + } + } + let mut sent_lines = Vec::new(); + for thing in &interesting_info{ + let file_name = current_task.target.clone(); + if file_name.contains(thing) || file_content.contains(thing){ + let sent_line = format!("keyword {}", file_name); + if !sent_lines.contains(&sent_line){ + sent_lines.push(sent_line); + let finding = Finding{path: file_name, keyword: Some(true)}; + let message = Message{source: id, tasktype: TaskType::Info, finding: Some(finding), task_finished: false}; + tx.send(message).await.unwrap(); + } + } + else{ + let sent_line = format!("file {}", file_name); + if !sent_lines.contains(&sent_line){ + sent_lines.push(sent_line); + let finding = Finding{path: file_name, keyword: Some(false)}; + let message = Message{source:id, tasktype: TaskType::Info, finding: Some(finding),task_finished: false}; + tx.send(message).await.unwrap(); + } + } + } + } + } + let message = Message{source: id, tasktype: TaskType::Share, finding: None, task_finished: true}; + let send_res = tx.send(message).await; + if send_res.is_ok(){ + send_res.unwrap(); + } + else{ + println!("{}", send_res.err().unwrap()); } } - - #[tokio::main] async fn main(){ let args = Args::parse(); let mut outfile = PathBuf::new(); - let mut file_threads = 5; - let mut share_threads = 5; + let mut threads = 10; let mut save = false; let mut computers = Vec::new(); if args.outfile.is_some(){ @@ -202,9 +219,7 @@ async fn main(){ save = true; } if args.threads.is_some(){ - let threads = args.threads.unwrap() / 2; - file_threads = threads; - share_threads = threads; + threads = args.threads.unwrap(); } if args.targets.is_some(){ println!("gathering the targets you gave me."); @@ -253,177 +268,207 @@ async fn main(){ for word in words{ let mut computer_name = word.to_string(); computer_name.pop(); - println!("{} {}", "found".green(), computer_name.green()); computers.push(computer_name); } } } } } - if share_threads > computers.len(){ - share_threads = computers.len(); - //file_threads = computers.len(); + let mut tasks = Vec::new(); + let mut id_counter = 0; + for computer in &computers{ + println!("found {}", computer); + let new_task = FinderTask{id: id_counter, target: computer.clone(), tasktype: TaskType::Share}; + tasks.push(new_task); + id_counter += 1; } - let mut share_handles = Vec::new(); - let mut file_handles = Vec::new(); println!("computer enumeration finished, starting task finder threads..."); - let (maintx, mut mainrx) = channel(1024); - let mut share_tasks = Vec::new(); - let mut share_txes = Vec::new(); - let mut file_tasks = Vec::new(); - let mut file_txes = Vec::new(); - for id in 0..share_threads{ - println!("starting share task {}...", id); - let (share_tx,share_rx) = channel(1); - let new_share_task = ShareFinder{id, tx: maintx.clone()}; - share_handles.push(tokio::spawn(find_shares(new_share_task, share_rx))); - share_tasks.push(id); - share_txes.push(share_tx.clone()); - let ping_message = Message{source: MessageType::ControlMessage, destination: MessageType::ShareMessage, content: String::from("ping!")}; - share_tx.send(ping_message).await.unwrap(); - loop{ - let rx_recv = mainrx.recv().await; - if rx_recv.is_some(){ - let message = rx_recv.unwrap(); - if message.content == String::from("pong!"){ - println!("{} ready!", id); + let (tx, mut rx) = channel(1024); + let mut running = Vec::new(); + let mut continue_wihtout_save = false; + loop{ + if running.len() < threads{ + for _i in 0 .. threads{ + if tasks.len() > 0{ + let task = tasks[0].clone(); + tasks.remove(0); + running.push(task.id.clone()); + tokio::spawn(task_handler(task.id, task, tx.clone())); + if running.len() >= threads{ + break; + } + } + else{ break; } } - println!("didn't recieve file pong from {}", id); } - } - for id in 0..file_threads{ - println!("starting file task {}...", id); - let (file_tx, file_rx) = channel(1); - let new_file_task = ShareFinder{id, tx: maintx.clone()}; - file_handles.push(tokio::spawn(find_info(new_file_task, file_rx))); - file_tasks.push(id); - file_txes.push(file_tx.clone()); - let ping_message = Message{source: MessageType::ControlMessage, destination: MessageType::ShareMessage, content: String::from("ping!")}; - file_tx.send(ping_message).await.unwrap(); - loop{ - let rx_recv = mainrx.recv().await; - if rx_recv.is_some(){ - let message = rx_recv.unwrap(); - if message.content == String::from("pong!"){ - println!("{} ready!", id); - break; + if running.len() > 0{ + let rxres = rx.try_recv(); + if rxres.is_ok(){ + let mesage = rxres.unwrap(); + if mesage.task_finished{ + for index in 0 .. running.len(){ + if index == running.len(){ + break; + } + else{ + if running[index] == mesage.source{ + running.remove(index); + } + } + } } - } - println!("didn't recieve file pong from {}", id); - } - } - let mut current_computer = 0; - let mut shares_finished = false; - let mut files_finished = false; - let mut file_buffer = Vec::new(); - let mut finished_counter = 0; - let mut empty_counter = 0; - let mut started = true; - let mut handled_lines = Vec::new(); - loop { - if files_finished && shares_finished{ - break; - } - if !mainrx.is_empty(){ - finished_counter = 0; - empty_counter = 0; - started = true; - let rx_res = mainrx.recv().await; - if rx_res.is_some(){ - let message = rx_res.unwrap(); - match message.destination{ - MessageType::ControlMessage => { - let message_vec: Vec<&str> = message.content.split(":").collect(); - let _id = message_vec[0]; - let message_content = message_vec[1].to_string(); - match message_content{ - _ => { - if !handled_lines.contains(&message_content){ - if save{ - let open_res = OpenOptions::new().append(true).create(true).open(&outfile); - if open_res.is_ok(){ - let mut file = open_res.unwrap(); - let write_res = write!(file, "{}\n", message_content); - if write_res.is_err(){ - eprintln!("{}", "error writing to outfile!".red()); - eprintln!("{}", write_res.err().unwrap().to_string().red()); + else { + let finding = mesage.finding.unwrap(); + match mesage.tasktype{ + TaskType::Share => { + println!("{} {}", "share found!".green(), finding.path); + if save{ + let open_res = OpenOptions::new().create(true).append(true).open(&outfile); + if open_res.is_err(){ + if !continue_wihtout_save{ + eprintln!("{}", "error opening save file!".red()); + eprintln!("{}", open_res.err().unwrap().to_string().red()); + let mut proceed = String::new(); + println!("continue anyway?"); + std::io::stdin().read_line(&mut proceed).unwrap(); + if proceed.to_lowercase().contains("y"){ + continue_wihtout_save = true; + } + else{ + exit(1); + } + } + } + else{ + let mut save_file = open_res.unwrap(); + let write_res = write!(save_file,"share found! {}\n", finding.path); + if write_res.is_err(){ + if !continue_wihtout_save{ + eprintln!("{}", "error writing to save file!".red()); + eprintln!("{}", write_res.err().unwrap().to_string().red()); + let mut proceed = String::new(); + println!("proceed without saving?"); + std::io::stdin().read_line(&mut proceed).unwrap(); + if proceed.to_lowercase().contains("y"){ + continue_wihtout_save = true; + } + else{ + exit(1); } } } - println!("{}", message_content.green()); - handled_lines.push(message_content); + else{ + write_res.unwrap(); + } } - } - } - } - MessageType::InfoMessage => { - file_buffer.push(message.content); - } - MessageType::ShareMessage => {} - } - } - } - let mut sent = false; - if !shares_finished{ - for tx in &share_txes{ - if tx.capacity() > 0{ - let message = Message{source: MessageType::ShareMessage, destination: MessageType::ShareMessage, content: computers[current_computer].clone()}; - tx.send(message).await.unwrap(); - sent = true; - break; - } - } - if sent{ - current_computer +=1; - if current_computer == computers.len() { - shares_finished = true; - } - } - } - if shares_finished{ - if file_buffer.len() == 0{ - empty_counter += 1; - } - if empty_counter >= 100{ - finished_counter +=1; - thread::sleep(Duration::from_millis(50)); - } - } - if file_buffer.len() > 0{ - let mut sent_index = Vec::new(); - empty_counter = 0; - finished_counter = 0; - let mut current_tx = 0; - for index in 0 .. file_buffer.len() - 1{ - let mut sent = false; - let message = Message{source: MessageType::ControlMessage, destination: MessageType::InfoMessage, content: file_buffer[index].clone()}; - if file_txes[current_tx].capacity()> 0{ - file_txes[current_tx].send(message).await.unwrap(); - sent = true; - } - else{ - current_tx += 1; - if current_tx == file_txes.len(){ - current_tx = 0; + let new_task = FinderTask{id: id_counter, tasktype: TaskType::File, target: finding.path}; + tasks.push(new_task); + id_counter += 1; + } + TaskType::File => { + let new_task = FinderTask{id: id_counter, tasktype: TaskType::Info, target: finding.path}; + tasks.push(new_task); + id_counter += 1; + } + TaskType::Info => { + if finding.keyword.unwrap(){ + println!("{} {}", "keyword match at".green(), finding.path.green()); + if save{ + let open_res = OpenOptions::new().create(true).append(true).open(&outfile); + if open_res.is_err(){ + if !continue_wihtout_save{ + eprintln!("{}", "error opening save file!".red()); + eprintln!("{}", open_res.err().unwrap().to_string().red()); + let mut proceed = String::new(); + println!("continue anyway?"); + std::io::stdin().read_line(&mut proceed).unwrap(); + if proceed.to_lowercase().contains("y"){ + continue_wihtout_save = true; + } + else{ + exit(1); + } + } + } + else{ + let mut save_file = open_res.unwrap(); + let write_res = write!(save_file,"keyword match at {}\n", finding.path); + if write_res.is_err(){ + if !continue_wihtout_save{ + eprintln!("{}", "error writing to save file!".red()); + eprintln!("{}", write_res.err().unwrap().to_string().red()); + let mut proceed = String::new(); + println!("proceed without saving?"); + std::io::stdin().read_line(&mut proceed).unwrap(); + if proceed.to_lowercase().contains("y"){ + continue_wihtout_save = true; + } + else{ + exit(1); + } + } + } + else{ + write_res.unwrap(); + } + } + } + } + else{ + if args.verbose{ + println!("{} {}", "file found at".green(), finding.path.green()); + } + if save{ + let open_res = OpenOptions::new().create(true).append(true).open(&outfile); + if open_res.is_err(){ + if !continue_wihtout_save{ + eprintln!("{}", "error opening save file!".red()); + eprintln!("{}", open_res.err().unwrap().to_string().red()); + let mut proceed = String::new(); + println!("continue anyway?"); + std::io::stdin().read_line(&mut proceed).unwrap(); + if proceed.to_lowercase().contains("y"){ + continue_wihtout_save = true; + } + else{ + exit(1); + } + } + } + else{ + let mut save_file = open_res.unwrap(); + let write_res = write!(save_file,"file found! {}\n", finding.path); + if write_res.is_err(){ + if !continue_wihtout_save{ + eprintln!("{}", "error writing to save file!".red()); + eprintln!("{}", write_res.err().unwrap().to_string().red()); + let mut proceed = String::new(); + println!("proceed without saving?"); + std::io::stdin().read_line(&mut proceed).unwrap(); + if proceed.to_lowercase().contains("y"){ + continue_wihtout_save = true; + } + else{ + exit(1); + } + } + } + else{ + write_res.unwrap(); + } + } + } + } + } } } - if sent{ - sent_index.push(index); - } - } - for index in sent_index{ - file_buffer.remove(index); } } - if finished_counter == 10{ - for tx in &file_txes{ - let done_message = Message{source: MessageType::ControlMessage, destination: MessageType::InfoMessage, content: String::from("0:||DONE||")}; - tx.send(done_message).await.unwrap(); - } - files_finished = true; + if running.len() == 0 && tasks.len() == 0 && rx.is_empty(){ + break; } } } \ No newline at end of file