<commit_before>#[macro_use]
extern crate serde_derive;
extern crate toml;

#[macro_use]
extern crate clap;

use std::io::prelude::*;
use std::fs::File;
use std::collections::BTreeMap;

use clap::{App,Arg};

macro_rules! die(
    ($($arg:tt)*) => { {
        writeln!(std::io::stderr(), $($arg)*)
            .expect("Failed to print to stderr");
        std::process::exit(1);
    } }
);

#[derive(Deserialize)]
struct Config {
    commands: BTreeMap<String,String>,
}

fn read_config<P: AsRef<std::path::Path>>(path: P) -> Result<Config, Box<std::error::Error>> {
    let mut contents = String::new();

    File::open(path)?
        .read_to_string(&mut contents)?;

    let config: Config = toml::from_str(&contents)?;
    Ok(config)
}

fn run_command(command: &str) -> Result<i32, Box<std::error::Error>> {
    let mut child = std::process::Command::new("/bin/sh")
        .arg("-c")
        .arg(command)
        .spawn()?;

    child
        .wait()?
        .code()
        .ok_or_else(|| std::io::Error::last_os_error().into())
}

fn main() {
    let matches = App::new(crate_name!())
        .version(crate_version!())
        .author("<NAME> <<EMAIL>>")
        .about("Restricted Shell that only allows whitelisted aliases")
        .arg((Arg::with_name("command")
            .short("-c")
            .help("Alias of command to execute")
            .value_name("COMMAND")))
        .get_matches();

    let command_alias = match matches.value_of("command") {
        Some(cmd) => String::from(cmd),
        None => {
            match std::env::var("SSH_ORIGINAL_COMMAND") {
                Ok(cmd) => cmd,
                _ => die!("Usage: {} <command alias>", crate_name!()), }
        }
    };

    let config_file = std::env::var("RESH_CONFIG")
        .unwrap_or_else(|_| {"/etc/resh.toml".to_string()});

    let config: Config = read_config(&config_file).
        unwrap_or_else(|e| { die!("Failed to read {}: {}", config_file, e); });

    let full_command = match config.commands.get(&command_alias) {
        Some(cmd) => cmd,
        None => { die!("Undefined command alias: {}", command_alias) },
    };

    let exitcode = run_command(full_command)
        .unwrap_or(1);

    std::process::exit(exitcode);
}<commit_msg>Cleanup (deprecation) warnings<commit_after>#[macro_use]
extern crate serde_derive;
extern crate toml;

#[macro_use]
extern crate clap;

use std::collections::BTreeMap;
use std::fs::File;
use std::io::prelude::*;

use clap::{App, Arg};

macro_rules! die(
    ($($arg:tt)*) => { {
        writeln!(std::io::stderr(), $($arg)*)
            .expect("Failed to print to stderr");
        std::process::exit(1);
    } }
);

#[derive(Deserialize)]
struct Config {
    commands: BTreeMap<String, String>,
}

fn read_config<P: AsRef<std::path::Path>>(path: P) -> Result<Config, Box<dyn std::error::Error>> {
    let mut contents = String::new();

    File::open(path)?.read_to_string(&mut contents)?;

    let config: Config = toml::from_str(&contents)?;
    Ok(config)
}

fn run_command(command: &str) -> Result<i32, Box<dyn std::error::Error>> {
    let mut child = std::process::Command::new("/bin/sh")
        .arg("-c")
        .arg(command)
        .spawn()?;

    child
        .wait()?
        .code()
        .ok_or_else(|| std::io::Error::last_os_error().into())
}

fn main() {
    let matches = App::new(crate_name!())
        .version(crate_version!())
        .author("<NAME> <<EMAIL>>")
        .about("Restricted Shell that only allows whitelisted aliases")
        .arg(
            Arg::with_name("command")
                .short("-c")
                .help("Alias of command to execute")
                .value_name("COMMAND"),
        )
        .get_matches();

    let command_alias = match matches.value_of("command") {
        Some(cmd) => String::from(cmd),
        None => match std::env::var("SSH_ORIGINAL_COMMAND") {
            Ok(cmd) => cmd,
            _ => die!("Usage: {} <command alias>", crate_name!()),
        },
    };

    let config_file = std::env::var("RESH_CONFIG").unwrap_or_else(|_| "/etc/resh.toml".to_string());

    let config: Config = read_config(&config_file).unwrap_or_else(|e| {
        die!("Failed to read {}: {}", config_file, e);
    });

    let full_command = match config.commands.get(&command_alias) {
        Some(cmd) => cmd,
        None => die!("Undefined command alias: {}", command_alias),
    };

    let exitcode = run_command(full_command).unwrap_or(1);

    std::process::exit(exitcode);
}
{'fraction_non_alphanumeric': 0.18857015788303313, 'fraction_numerical': 0.00177896375361352, 'mean_word_length': 2.9215344376634698, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4062208', 'n_tokens_mistral': 1506, 'n_tokens_neox': 1510, 'n_words': 283}