181 lines
5.6 KiB
Rust
181 lines
5.6 KiB
Rust
pub mod entry;
|
|
|
|
mod settings;
|
|
|
|
pub mod status;
|
|
use std::{thread::sleep, time::Duration};
|
|
|
|
use crate::app::{
|
|
entry::Entry,
|
|
settings::Settings,
|
|
status::{AppStatus, CurrentScreen, EditingField, EntryValError},
|
|
};
|
|
use ratatui::widgets::TableState;
|
|
|
|
pub struct AppState {
|
|
pub fromIP: String,
|
|
pub fromPort: String,
|
|
pub toIP: String,
|
|
pub toPort: String,
|
|
pub currentlyEditing: Option<EditingField>,
|
|
pub screen: CurrentScreen,
|
|
pub entries: Vec<Entry>,
|
|
pub confDir: String,
|
|
pub tableState: TableState,
|
|
pub appStatus: AppStatus,
|
|
pub savedHash: String,
|
|
pub currentHash: String,
|
|
pub settings: Settings,
|
|
}
|
|
|
|
impl AppState {
|
|
pub fn new(confDir: String) -> Self {
|
|
let settings = Settings::new(&confDir);
|
|
AppState {
|
|
fromIP: String::new(),
|
|
fromPort: String::new(),
|
|
toIP: String::new(),
|
|
toPort: String::new(),
|
|
currentlyEditing: None,
|
|
screen: CurrentScreen::Main,
|
|
savedHash: settings.entryHash(),
|
|
currentHash: settings.entryHash(),
|
|
entries: settings.entries.clone(),
|
|
settings,
|
|
confDir,
|
|
tableState: TableState::default().with_selected(0),
|
|
appStatus: AppStatus::Welcome,
|
|
}
|
|
}
|
|
|
|
pub fn genCurrentEntriesHash(&mut self) {
|
|
let mut entries = String::new();
|
|
for e in &self.entries {
|
|
entries.push_str(&format!("{e}"));
|
|
}
|
|
self.currentHash = format!("{:x}", md5::compute(entries));
|
|
}
|
|
|
|
pub fn store(&mut self) -> EntryValError {
|
|
match Entry::new(
|
|
self.fromIP.clone(),
|
|
self.toIP.clone(),
|
|
self.fromPort.clone(),
|
|
self.toPort.clone(),
|
|
) {
|
|
Ok(entry) => {
|
|
self.entries.push(entry);
|
|
self.fromIP = String::new();
|
|
self.toIP = String::new();
|
|
self.fromPort = String::new();
|
|
self.toPort = String::new();
|
|
self.currentlyEditing = None;
|
|
self.tableState.select(Some(self.entries.len() - 1_usize));
|
|
self.genCurrentEntriesHash();
|
|
EntryValError::None
|
|
}
|
|
Err(e) => e,
|
|
}
|
|
}
|
|
|
|
pub fn isHashDifferent(&self) -> bool {
|
|
self.currentHash != self.savedHash
|
|
}
|
|
|
|
pub fn nextField(&mut self) {
|
|
if let Some(currentField) = &self.currentlyEditing {
|
|
self.currentlyEditing = match currentField {
|
|
EditingField::FromIP => Some(EditingField::FromPort),
|
|
EditingField::FromPort => Some(EditingField::ToIP),
|
|
EditingField::ToIP => Some(EditingField::ToPort),
|
|
EditingField::ToPort => Some(EditingField::FromIP),
|
|
};
|
|
}
|
|
}
|
|
|
|
pub fn prevField(&mut self) {
|
|
if let Some(currentField) = &self.currentlyEditing {
|
|
self.currentlyEditing = match currentField {
|
|
EditingField::FromIP => Some(EditingField::ToPort),
|
|
EditingField::FromPort => Some(EditingField::FromIP),
|
|
EditingField::ToIP => Some(EditingField::FromPort),
|
|
EditingField::ToPort => Some(EditingField::ToIP),
|
|
};
|
|
}
|
|
}
|
|
|
|
// pub fn print(&self) {
|
|
// let tempEntry = &self.entries[0];
|
|
// let res = serde_json::to_string(tempEntry).unwrap();
|
|
// println!("{res}");
|
|
// let resString = tempEntry.to_string();
|
|
// println!("{resString}");
|
|
// }
|
|
|
|
pub fn saveConfigToScript(&self) {
|
|
let mut outputString: String = String::new();
|
|
outputString.push_str("#! /bin/bash\n\n# DO NOT EDIT THIS FILE MANUALLY\n# ANY MODIFICATIONS WILL BE OVERWRITTEN BY STECKBRETT\n# USE THAT STECKBRETT (stb) TO CONFIGURE PORT MAPPINGS.\n\n");
|
|
for ent in self.entries.iter() {
|
|
outputString.push_str(&format!(
|
|
"socat TCP-LISTEN:{},fork,reuseaddr,bind={} TCP:{}:{} &\n",
|
|
ent.fromPort, ent.fromIP, ent.toIP, ent.toPort
|
|
))
|
|
}
|
|
outputString.push_str("\nwait");
|
|
// for o in 0..1 {
|
|
// println!("test {o}");
|
|
// sleep(Duration::from_secs(1));
|
|
// }
|
|
println!("Writing config to system");
|
|
sleep(Duration::from_millis(100));
|
|
let _ = std::fs::write("./forward.sh", outputString);
|
|
}
|
|
|
|
pub fn saveConfigToSettingsFile(&mut self) {
|
|
// let mut settings = Settings::new(&self.confDir);
|
|
// settings.entries = self.entries.clone();
|
|
// settings.save(&self.confDir);
|
|
self.settings.entries = self.entries.clone();
|
|
self.settings.save(&self.confDir);
|
|
self.savedHash = self.settings.entryHash();
|
|
}
|
|
|
|
pub fn nextRow(&mut self) {
|
|
let i = match self.tableState.selected() {
|
|
Some(i) => {
|
|
if i >= self.entries.len() - 1 {
|
|
0
|
|
} else {
|
|
i + 1
|
|
}
|
|
}
|
|
None => 0,
|
|
};
|
|
self.tableState.select(Some(i));
|
|
}
|
|
|
|
pub fn prevRow(&mut self) {
|
|
let i = match self.tableState.selected() {
|
|
Some(i) => {
|
|
if i == 0 {
|
|
self.entries.len() - 1
|
|
} else {
|
|
i - 1
|
|
}
|
|
}
|
|
None => 0,
|
|
};
|
|
self.tableState.select(Some(i));
|
|
}
|
|
|
|
pub fn delCur(&mut self) {
|
|
if self.entries.is_empty() {
|
|
self.screen = CurrentScreen::Main;
|
|
return;
|
|
}
|
|
self.entries.remove(self.tableState.selected().unwrap());
|
|
self.genCurrentEntriesHash();
|
|
self.appStatus = AppStatus::Deleted;
|
|
}
|
|
}
|