re-wrote the tool, it actually works now!

This commit is contained in:
pyro57000
2025-10-16 17:34:16 -05:00
parent 835eecd815
commit 1e29992068
5 changed files with 899 additions and 437 deletions

425
src/main-bkup.rs Normal file
View File

@@ -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<PathBuf>,
#[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<usize>,
#[arg(short, long, help = "specific targets. should be comma separated.")]
targets: Option<String>,
}
struct ShareFinder{
id: usize,
tx: Sender<Message>,
}
#[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<Message>){
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::<Vec<&str>>()[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<Message>){
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;
}
}
}

View File

@@ -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<PathBuf>,
#[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<usize>,
#[arg(short, long, help = "specific targets. should be comma separated.")]
targets: Option<String>,
}*/
#[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<String>,
}
struct ShareFinder{
id: usize,
tx: Sender<Message>,
#[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<bool>
}
struct Message{
source: MessageType,
destination: MessageType,
content: String,
source: usize,
tasktype: TaskType,
finding: Option<Finding>,
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<Message>){
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<Message>){
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<Message>){
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::<Vec<&str>>()[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<Message>){
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(&current_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;
}
}
}