Update main.rs
fixed the copying of an existing folder structure over for importing a project
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
use std::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@@ -42,7 +43,7 @@ fn install(config_path: &PathBuf){
|
|||||||
std::io::stdin().read_line(&mut files_response).unwrap();
|
std::io::stdin().read_line(&mut files_response).unwrap();
|
||||||
println!("path to folder with your custom tools?");
|
println!("path to folder with your custom tools?");
|
||||||
std::io::stdin().read_line(&mut tools_response).unwrap();
|
std::io::stdin().read_line(&mut tools_response).unwrap();
|
||||||
let config_string = format!("Project_files:{}\nProject_notes:{}\ntools:{}", files_response.trim_end(), notes_response.trim_end(), tools_response.trim_end());
|
let config_string = format!("Project_files:{}\nProject_notes:{}\ntools_folder:{}", files_response.trim_end(), notes_response.trim_end(), tools_response.trim_end());
|
||||||
config_file.write_all(config_string.as_bytes()).expect("error writing to config file");
|
config_file.write_all(config_string.as_bytes()).expect("error writing to config file");
|
||||||
println!("config file generated and saved to {}\n", config_path.display());
|
println!("config file generated and saved to {}\n", config_path.display());
|
||||||
println!("please make sure to install distrobox:\nhttps://github.com/89luca89/distrobox\n\nthis will require either docker or podman as well.\n\n");
|
println!("please make sure to install distrobox:\nhttps://github.com/89luca89/distrobox\n\nthis will require either docker or podman as well.\n\n");
|
||||||
@@ -71,15 +72,15 @@ fn get_projects(base_notes: &PathBuf, base_files: &PathBuf, config_path: &mut Pa
|
|||||||
notes_folder.push(&folder_name);
|
notes_folder.push(&folder_name);
|
||||||
project_folder.push(&folder_name);
|
project_folder.push(&folder_name);
|
||||||
let hours_count:u64 = settings[3].trim_end().parse().expect("error converting to u64");
|
let hours_count:u64 = settings[3].trim_end().parse().expect("error converting to u64");
|
||||||
let _mins_count = hours_count * 60;
|
|
||||||
let secs_count = hours_count * 60;
|
let secs_count = hours_count * 60;
|
||||||
let hours = Duration::from_secs(secs_count);
|
let hours = Duration::from_secs(secs_count);
|
||||||
let mut active = false;
|
let mut active = false;
|
||||||
|
let boxname = settings[4].to_owned();
|
||||||
if settings[2] == "yes"{
|
if settings[2] == "yes"{
|
||||||
|
env::set_var("CURRENT_PROJECT_BOX", boxname.clone());
|
||||||
active = true;
|
active = true;
|
||||||
}
|
}
|
||||||
let time = SystemTime::now();
|
let time = SystemTime::now();
|
||||||
let boxname = settings[4].to_owned();
|
|
||||||
let new_project = Project{customer: customer, project_name: project, files_folder: project_folder, notes_folder: notes_folder, activativation_time: time, hour_count: hours, active: active, id: first, boxname: boxname};
|
let new_project = Project{customer: customer, project_name: project, files_folder: project_folder, notes_folder: notes_folder, activativation_time: time, hour_count: hours, active: active, id: first, boxname: boxname};
|
||||||
println!("{} {} LOADED!", &new_project.customer, &new_project.project_name);
|
println!("{} {} LOADED!", &new_project.customer, &new_project.project_name);
|
||||||
projects.push(new_project);
|
projects.push(new_project);
|
||||||
@@ -90,7 +91,7 @@ fn get_projects(base_notes: &PathBuf, base_files: &PathBuf, config_path: &mut Pa
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn switch_project(projects: &mut Vec<Project>, config_path: &PathBuf){
|
fn switch_project(projects: &mut Vec<Project>){
|
||||||
for project in projects.clone(){
|
for project in projects.clone(){
|
||||||
if project.active == false{
|
if project.active == false{
|
||||||
println!("{} {}|{}", project.id, project.customer, project.project_name);
|
println!("{} {}|{}", project.id, project.customer, project.project_name);
|
||||||
@@ -105,13 +106,7 @@ fn switch_project(projects: &mut Vec<Project>, config_path: &PathBuf){
|
|||||||
if project.id == new_id{
|
if project.id == new_id{
|
||||||
project.active = true;
|
project.active = true;
|
||||||
println!("project found switching to {} {}", project.customer, project.project_name);
|
println!("project found switching to {} {}", project.customer, project.project_name);
|
||||||
let mut box_selection_path = config_path.clone();
|
env::set_var("CURRENT_PROJECT_BOX", project.boxname.clone());
|
||||||
box_selection_path.pop();
|
|
||||||
box_selection_path.pop();
|
|
||||||
box_selection_path.push("current_box");
|
|
||||||
let mut box_selection = fs::File::create(box_selection_path).expect("error opening up box selection file");
|
|
||||||
let box_output = project.boxname.as_bytes();
|
|
||||||
box_selection.write_all(box_output).expect("error writing new box");
|
|
||||||
}
|
}
|
||||||
else if project.id != new_id{
|
else if project.id != new_id{
|
||||||
project.active = false;
|
project.active = false;
|
||||||
@@ -201,10 +196,6 @@ fn new_project(projects: &mut Vec<Project>, project_dir: &PathBuf, notes_dir: &P
|
|||||||
std::io::stdin().read_line(&mut existing_folders).unwrap();
|
std::io::stdin().read_line(&mut existing_folders).unwrap();
|
||||||
let customer_name = customer_name.trim_end().to_owned();
|
let customer_name = customer_name.trim_end().to_owned();
|
||||||
let project_name = project_name.trim_end().to_owned();
|
let project_name = project_name.trim_end().to_owned();
|
||||||
new_project_dir.push(&customer_name);
|
|
||||||
new_note_dir.push(&customer_name);
|
|
||||||
new_project_dir.push(&project_name);
|
|
||||||
new_note_dir.push(&project_name);
|
|
||||||
if existing_folders.contains("y") || existing_folders.contains("Y"){
|
if existing_folders.contains("y") || existing_folders.contains("Y"){
|
||||||
let mut files_to_copy = String::new();
|
let mut files_to_copy = String::new();
|
||||||
let mut notes_to_copy = String::new();
|
let mut notes_to_copy = String::new();
|
||||||
@@ -243,18 +234,23 @@ fn new_project(projects: &mut Vec<Project>, project_dir: &PathBuf, notes_dir: &P
|
|||||||
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
//working_path.push("working");
|
new_project_dir.push(&customer_name);
|
||||||
|
new_note_dir.push(&customer_name);
|
||||||
|
new_project_dir.push(&project_name);
|
||||||
|
new_note_dir.push(&project_name);
|
||||||
fs::create_dir_all(&new_project_dir).expect("error creating new files folder");
|
fs::create_dir_all(&new_project_dir).expect("error creating new files folder");
|
||||||
fs::create_dir_all(&new_note_dir).expect("error creating new notes folder");
|
fs::create_dir_all(&new_note_dir).expect("error creating new notes folder");
|
||||||
|
|
||||||
}
|
}
|
||||||
let box_name = format!("atarchbox_{}", customer_name);
|
let box_name = format!("atarchbox_{}", customer_name);
|
||||||
let pentest_volume = format!("{}:/pentest:rw", new_project_dir.display());
|
let pentest_volume = format!("{}:/pentest:rw", new_project_dir.display());
|
||||||
let toold_volume = format!("{}:/tools:rw", tools_dir.display());
|
let toold_volume = format!("{}:/tools:rw", tools_dir.display());
|
||||||
|
println!("distrobox create --root --clone {} --volume {} --volume {} --name {}", boxtemplate, toold_volume, pentest_volume, box_name);
|
||||||
let distrobox_result = process::Command::new("distrobox")
|
let distrobox_result = process::Command::new("distrobox")
|
||||||
.arg("create")
|
.arg("create")
|
||||||
|
.arg("--root")
|
||||||
.arg("--clone")
|
.arg("--clone")
|
||||||
.arg(boxtemplate)
|
.arg(boxtemplate)
|
||||||
.arg("--init")
|
|
||||||
.arg("--volume")
|
.arg("--volume")
|
||||||
.arg(toold_volume)
|
.arg(toold_volume)
|
||||||
.arg("--volume")
|
.arg("--volume")
|
||||||
@@ -267,6 +263,7 @@ fn new_project(projects: &mut Vec<Project>, project_dir: &PathBuf, notes_dir: &P
|
|||||||
println!("we made a distrobox oh boy!");
|
println!("we made a distrobox oh boy!");
|
||||||
let distrobox_start_result = process::Command::new("distrobox")
|
let distrobox_start_result = process::Command::new("distrobox")
|
||||||
.arg("enter")
|
.arg("enter")
|
||||||
|
.arg("--root")
|
||||||
.arg(&box_name)
|
.arg(&box_name)
|
||||||
.status()
|
.status()
|
||||||
.expect("error getting response from distrobox start");
|
.expect("error getting response from distrobox start");
|
||||||
@@ -312,6 +309,7 @@ fn remove_project(projects: &mut Vec<Project>){
|
|||||||
project_set = true;
|
project_set = true;
|
||||||
let distrobox_rm_status = process::Command::new("distrobox")
|
let distrobox_rm_status = process::Command::new("distrobox")
|
||||||
.arg("rm")
|
.arg("rm")
|
||||||
|
.arg("--root")
|
||||||
.arg("-f")
|
.arg("-f")
|
||||||
.arg(project.boxname)
|
.arg(project.boxname)
|
||||||
.status().expect("error calling distrobox");
|
.status().expect("error calling distrobox");
|
||||||
@@ -358,6 +356,7 @@ fn stop_all_boxes(projects: &Vec<Project>){
|
|||||||
for project in projects{
|
for project in projects{
|
||||||
let stopped = process::Command::new("distrobox")
|
let stopped = process::Command::new("distrobox")
|
||||||
.arg("stop")
|
.arg("stop")
|
||||||
|
.arg("--root")
|
||||||
.arg(&project.boxname)
|
.arg(&project.boxname)
|
||||||
.status().expect("error spawing distrobox");
|
.status().expect("error spawing distrobox");
|
||||||
if stopped.success(){
|
if stopped.success(){
|
||||||
@@ -382,13 +381,52 @@ fn stop_all_boxes(projects: &Vec<Project>){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn project_standalone_terminal(){
|
fn print_report_information(project: Project){
|
||||||
process::Command::new("konsole").arg("-e").arg("'~/.config/start_box.sh'").spawn().expect("error opeing konsole");
|
let mut general_notes_path = project.notes_folder.clone();
|
||||||
|
let mut finding_notes_path = project.notes_folder.clone();
|
||||||
|
general_notes_path.push("general.md ");
|
||||||
|
finding_notes_path.push("findings.md ");
|
||||||
|
println!("general: {}\nfindings: {}", general_notes_path.display(), finding_notes_path.display());
|
||||||
|
let general_string = fs::read_to_string(general_notes_path).expect("error opening general notes");
|
||||||
|
let findings_string = fs::read_to_string(finding_notes_path).expect("error opening findings notes");
|
||||||
|
let general_lines: Vec<&str> = general_string.split("\n").collect();
|
||||||
|
let finding_lines: Vec<&str> = findings_string.split("\n").collect();
|
||||||
|
println!("Scope:");
|
||||||
|
for line in general_lines{
|
||||||
|
if line.contains("|"){
|
||||||
|
let split: Vec<&str> = line.split("|").collect();
|
||||||
|
println!("{}\t{}", split[0], split[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!("Findings");
|
||||||
|
for line in finding_lines{
|
||||||
|
if line.contains("# "){
|
||||||
|
println!("{}", line);
|
||||||
|
}
|
||||||
|
else if line.contains("- "){
|
||||||
|
println!("{}", line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reset_hour_counters(projects: &mut Vec<Project>){
|
||||||
|
println!("Clearing Counters, please esure these times are in sales force...");
|
||||||
|
for project in projects{
|
||||||
|
println!("{} {}: {}", project.customer, project.project_name, project.hour_count.as_secs()/60/60);
|
||||||
|
project.hour_count = Duration::ZERO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fn project_standalone_terminal(project: Project){
|
||||||
|
process::Command::new("konsole").arg("--profile").arg("attack").arg(project.boxname).spawn().expect("error opeing konsole");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn project_inline_terminal(project: Project){
|
fn project_inline_terminal(project: Project){
|
||||||
process::Command::new("distrobox").arg("enter").arg(project.boxname).status().expect("error opeing konsole");
|
process::Command::new("distrobox").arg("enter").arg("--root").arg(project.boxname).arg("--").arg("script").arg("-a").arg("-B").arg("/pentest/working/terminal.log").status().expect("error opeing konsole");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -399,6 +437,42 @@ fn main_menu(mut projects: Vec<Project>, config_path: &PathBuf, base_files: &Pat
|
|||||||
let mut response = String::new();
|
let mut response = String::new();
|
||||||
clear().expect("error clearing screen");
|
clear().expect("error clearing screen");
|
||||||
print!("
|
print!("
|
||||||
|
,,,;;::ccccc::;;;::c::;,;::cccccllc::::::;:::;;;;,,;,'',,;,,;;;;;;;:;;;;;,,,,,,,,,,,'''''',,,,,,''''
|
||||||
|
,;;;::ccccc::::::ccc:;;;:ccccccclc::ccccccc::;;;;;;;;;;,,;;;;;;;;;;;;;;;,,,,,,,,,,,'''''''''',,,,,''
|
||||||
|
,;;:::ccc:cc:::ccc:::::::ccccclcccllccccllc::::::;;;;;;;;;;;;;;;;;;;;;;,,,,,,,,,,,''''''''...'',,,,'
|
||||||
|
,;;:::c::ccc::cc::::::::cclollllllolllllccccc::cc:::::;;;;;;;;;;;;;;;;;;,,,,,,,,,,'''''''''''..'',,,
|
||||||
|
,;::::::ccc::cc::::::ccloodollooooollllcccccc:llc::::::;;;;;;:;;;;;;;;;;;,,,,,,,,,,''''''''''''''',,
|
||||||
|
,;:::::c:::c::::ccccloddxxddxxddddodollllccclclcccccc:::::::::::::::;;;;;;;;,,,,,,,,,'''''''''''''',
|
||||||
|
;;:::::::c::c::clllodxxO0OKX0kkOkkxxxxxdooooolcccccccc:::::::cllc::::::::;;;;;,,,,,,,,,,'''''''''',,
|
||||||
|
;:::::c:cc::cclolclokO0KXNNX00KKK0O0KOxdxxdooccccclllccccccccdkdlcccccllcc::;;;;;;;;,,,,,,,,,,,',,,,
|
||||||
|
::::::cc::::coxdlllok00KNWNXXX0KXKOKNOkO0kddocccllllllccccclx0Kkodddoodddoollc::;;;;;;;;;,,,,,,,,,,,
|
||||||
|
:::::::c:::clkkodooxxkO0KX0xookKKkkKNKO0KkdoodolcllllollolldKNNXKKXKKKKKK0Okxdocc:cc:::;;;;;,,,,,,,,
|
||||||
|
::cc::cc::cldxllolodxxdoddc'.,okkxOXXOdxkxolkOdlllllllldkdokXNNNNNNNNX0kxollcc:::::cclc::;;;;;;,,,,,
|
||||||
|
:::::::cccldko:,.';cc:;:;....;clllOXOxxOkocoK0xooddollx0Odd0XNNNNNX0Oxdolcccc::;;;;;;:cllc:;;:;,,,,,
|
||||||
|
;;::c:::ccldkl;'...,''''....',;,';dxdkkdc;cONKxxOOOxddOXOdx0XXNNWNOdddxkOOOOkdllc:;,,,;cool:;;;;;,,;
|
||||||
|
,;;::;;::llco:,'..''..,.......''.';:ldl;,,:xXNOOXXX0xdkOOddkXNNWWWX00KXNNX0kxddddol:,''';lol:;;:;;,;
|
||||||
|
,,,;;;;;:coc;;'..;;. .,,;'.......':dxdc;ldc,l00xkXNKxodkkkkk0XNWWMWWWNXKOxdooolooool:;'..,lol::::;;;
|
||||||
|
',,,;;;;:cllc;,..',. ','. .....;odoo:;co:.'ldldOOx::x0KXX0kk0XNWWWXOxdoooollllllllcc:'..':lc:::;;;
|
||||||
|
',,,;;;;;:cccc:,. . ..;cccccc:,,''.',,:l:;;:oOXXKOOOkxOXNNNXOxddooooollllllllc,....:c:::;;;
|
||||||
|
''',,,;;;;;;;cll,.. .. .':lc:c:;,,......,,;:;;:cokkxxO00O0KXNNN0kxkkkxddoollllllll:'...':::::::
|
||||||
|
.''',,,,,,,,,;:c:,.. ..'. ..','',;;'........',,;:;:::cdxxxddkKXXXKKKKXXXXXX0kdoloolllol;....,;:::::
|
||||||
|
..'''',,'',,,;;:::;..... ............... .'.....,;,',:ldc;:ldOKKK00KNWWWNNXK0xoooodooooo:'...';;;:;;
|
||||||
|
....'''''',,;;::cll:,''...... . ..........'...,;;l:,,;oddkOOKNWWWWNX0kdodxxxxdddooc,...',;;;;,
|
||||||
|
......''''',;::cloodddol;. ...........',.;;,,',:cxdd0KXXKKKXKOkxxkkkxdddooc,...';;,,,,
|
||||||
|
........''',;:clloddxxdo:'. .. ...........''.'',;c:;cccodddk0KX0OOkxddddddo:...';;;;,,'
|
||||||
|
..........',;:cclodxxkxdl:,.. ... ......'....'..':c,..'.,c,,,.,cxkO00Okxdddddc'..';:;;;,,'
|
||||||
|
..........',;;:cloodxkkkdol:'. . ... ...... ......';c'.'...:;',;,'..,lxO00Oxxxo:'...,::;;,,,,
|
||||||
|
...........',;;:clodxkOOkxdol;. .. .. ... ....',::'.''.',.........'oxdxxxdl;...';::;;;,,''
|
||||||
|
............',;:clodxkkOOOxddo;. ...... ........',,',................';:clc;,...';::;;,,,'''
|
||||||
|
............',;:cldxkkOkkkxdddo;. ..... .........,'...........'''','.',,'''....,cc:;;,,'''..
|
||||||
|
.............';:cldxxkkkkxddddxl,. .... .;c;'...................',;;cc;'...';clolc:;,,'''...
|
||||||
|
............'';clodxkkkkkxddddddl' ... .:lc;'................. ....',,''';lxkxdlc:;,'''....
|
||||||
|
........',,;:;coddxkOOOOOkxxddddd:. ... ..,''.................. . ..;cdkkkkxoc:;,'''.....
|
||||||
|
......',;::cllodxkkOOOOOOkxxxddddc. ... ..,;,'................... .. .':odO0Okdl:;,'''......
|
||||||
|
.....',;:cloddxxkOOOOOOOkkxxdoooo;. .. ......................... .';cokOOxlc:;,''.......
|
||||||
|
....,;:clodxxkkOOOkO0OOOOxdlcc;;,...... .';,................. ...',:ldxxxdlc;,''.......
|
||||||
|
...,:clodooxkkkO0OxO00OOxo:;;,. ........ .''.......... .. .. ..,,,;:codxxdlc:;,'.......
|
||||||
|
'',;clodolokOkxkOkkO00Oko:;;;. ..... .. .,,........'. .. .. .. ..........;:codocclc:,,'......
|
||||||
___ __ __ ___ __ ___ __
|
___ __ __ ___ __ ___ __
|
||||||
| | |__ | / ` / \\ |\\/| |__ |__| /\\ / ` |__/ |__ |__)
|
| | |__ | / ` / \\ |\\/| |__ |__| /\\ / ` |__/ |__ |__)
|
||||||
|/\\| |___ |___ \\__, \\__/ | | |___ | | /~~\\ \\__, | \\ |___ | \\
|
|/\\| |___ |___ \\__, \\__/ | | |___ | | /~~\\ \\__, | \\ |___ | \\
|
||||||
@@ -429,8 +503,10 @@ Current Minutes: {} minutes
|
|||||||
11.) Open A Terminal In this windows for the current active project
|
11.) Open A Terminal In this windows for the current active project
|
||||||
12.) Open Project Files Folder In Dolphin
|
12.) Open Project Files Folder In Dolphin
|
||||||
13.) Open Project Notes Folder In Dolphin
|
13.) Open Project Notes Folder In Dolphin
|
||||||
14.) Stop All Distroboxes
|
14.) Print Project Info For Report
|
||||||
15.) Quit Application
|
15.) Stop All Distroboxes
|
||||||
|
16.) Reset Hour Counters
|
||||||
|
17.) Quit Application
|
||||||
\n", active_project.customer, active_project.project_name, SystemTime::now().duration_since(active_project.activativation_time).unwrap().as_secs() / 60);
|
\n", active_project.customer, active_project.project_name, SystemTime::now().duration_since(active_project.activativation_time).unwrap().as_secs() / 60);
|
||||||
std::io::stdin().read_line(&mut response).expect("error getting menu input");
|
std::io::stdin().read_line(&mut response).expect("error getting menu input");
|
||||||
clear().expect("error clearing screen");
|
clear().expect("error clearing screen");
|
||||||
@@ -440,7 +516,7 @@ Current Minutes: {} minutes
|
|||||||
for project in &projects{
|
for project in &projects{
|
||||||
println!("++{}|{}++",project.customer ,project.project_name)}
|
println!("++{}|{}++",project.customer ,project.project_name)}
|
||||||
println!("++++++++++++++++++++")},
|
println!("++++++++++++++++++++")},
|
||||||
"3" => switch_project(&mut projects, config_path),
|
"3" => switch_project(&mut projects),
|
||||||
"4" => println!("current Hour Count: {}", active_project.hour_count.as_secs()/3600 + time::SystemTime::now().duration_since(active_project.activativation_time).expect("error caclucating hours").as_secs()/3600),
|
"4" => println!("current Hour Count: {}", active_project.hour_count.as_secs()/3600 + time::SystemTime::now().duration_since(active_project.activativation_time).expect("error caclucating hours").as_secs()/3600),
|
||||||
"5" => {println!("++++++++++++++++++++");
|
"5" => {println!("++++++++++++++++++++");
|
||||||
for project in &projects{
|
for project in &projects{
|
||||||
@@ -457,12 +533,14 @@ Current Minutes: {} minutes
|
|||||||
"7" => save_projects(&projects, &config_path),
|
"7" => save_projects(&projects, &config_path),
|
||||||
"8" => new_project(&mut projects, &base_files, &base_notes, &tools_dir, &boxtemplate),
|
"8" => new_project(&mut projects, &base_files, &base_notes, &tools_dir, &boxtemplate),
|
||||||
"9" => remove_project(&mut projects),
|
"9" => remove_project(&mut projects),
|
||||||
"10" => project_standalone_terminal(),
|
"10" => project_standalone_terminal(active_project.clone()),
|
||||||
"11" => project_inline_terminal(active_project.clone()),
|
"11" => project_inline_terminal(active_project.clone()),
|
||||||
"12" => open_in_dolphin("files", active_project.clone()),
|
"12" => open_in_dolphin("files", active_project.clone()),
|
||||||
"13" => open_in_dolphin("notes", active_project.clone()),
|
"13" => open_in_dolphin("notes", active_project.clone()),
|
||||||
"14" => stop_all_boxes(&projects),
|
"14" => print_report_information(active_project.clone()),
|
||||||
"15" => {save_projects(&projects, &config_path);
|
"15" => stop_all_boxes(&projects),
|
||||||
|
"16" => reset_hour_counters(&mut projects),
|
||||||
|
"17" => {save_projects(&projects, &config_path);
|
||||||
let mut stop = String::new();
|
let mut stop = String::new();
|
||||||
println!("stop all boxes?\ny/n");
|
println!("stop all boxes?\ny/n");
|
||||||
std::io::stdin().read_line(&mut stop).unwrap();
|
std::io::stdin().read_line(&mut stop).unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user