execute executable gophermaps

pull/1/head
dvkt 4 years ago
parent 599e9bf554
commit 44d554523d

@ -5,7 +5,9 @@ use std::{
io::prelude::*,
io::{BufReader, Read, Write},
net::{TcpListener, TcpStream},
os::unix::fs::PermissionsExt,
path::Path,
process::Command,
};
use threadpool::ThreadPool;
@ -183,10 +185,15 @@ where
&'a W: Write,
{
let path = req.file_path();
let file = File::open(&path)?;
let reader = BufReader::new(file);
let reader = if is_executable(&path) {
sh(&path, &[&req.selector, &req.host, &req.port.to_string()])?
} else {
fs::read_to_string(path)?
};
for line in reader.lines() {
let mut line = line?.trim_end_matches("\r\n").to_string();
let mut line = line.trim_end_matches("\r").to_string();
match line.chars().filter(|&c| c == '\t').count() {
0 => {
if line.chars().nth(0) != Some('i') {
@ -229,3 +236,22 @@ fn file_type(dir: &fs::DirEntry) -> ItemType {
ItemType::Error
}
}
/// Is the file at the given path executable?
fn is_executable(path: &str) -> bool {
if let Ok(meta) = fs::metadata(path) {
meta.permissions().mode() & 0o111 != 0
} else {
false
}
}
/// Run a script and return its output.
fn sh(path: &str, args: &[&str]) -> Result<String> {
let output = Command::new(path).args(args).output()?;
if output.status.success() {
Ok(std::str::from_utf8(&output.stdout)?.to_string())
} else {
Ok(std::str::from_utf8(&output.stderr)?.to_string())
}
}

Loading…
Cancel
Save