<commit_before>use std::fs::File;
use std::io::prelude::*;
use std::collections::HashMap;

extern crate clap;
use clap::{Arg, App, SubCommand};
extern crate toml;

// extern crate hyper;
// extern crate hyper_rustls;
// use hyper::Client;
// use hyper::net::HttpsConnector;
// use hyper_rustls::TlsClient;
// use hyper::header::Authorization;
// use hyper::header::{Accept, qitem};
// use hyper::mime::{Mime, TopLevel, SubLevel};

extern crate reqwest;
use reqwest::header::Authorization;

extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;

extern crate glob;
use glob::glob;

#[derive(Deserialize, Debug)]
struct Config {
    token: String,
    org: String,
    team: String,
    #[serde(default="default_endpoint")]
    endpoint: String,
    #[serde(default="default_home")]
    home: String,
    #[serde(default="default_gid")]
    gid: u64,
    #[serde(default="default_sh")]
    sh: String,
    group: Option<String>,
    #[serde(default="default_cert_path")]
    cert_path: String
}

fn default_endpoint() -> String { String::from("https://api.github.com") }
fn default_home() -> String { String::from("/home/{}") }
fn default_gid() -> u64 { 2000 }
fn default_sh() -> String { String::from("/bin/bash") }
fn default_cert_path() -> String { String::from("/etc/ssl/certs/ca-certificates.crt") }

#[derive(Serialize, Deserialize, Debug)]
struct Team {
    id: u64,
    name: String,
}

#[derive(Serialize, Deserialize, Debug)]
struct Member {
    id: u64,
    login: String,
}

#[derive(Serialize, Deserialize, Debug)]
struct PublicKey {
    id: u64,
    key: String,
}

#[derive(Debug)]
enum CliError {
    Serde(serde_json::Error),
    Reqwest(reqwest::Error),
    Io(std::io::Error)
}

impl From<serde_json::Error> for CliError {fn from(err: serde_json::Error) -> CliError { CliError::Serde(err) }}
impl From<reqwest::Error> for CliError {fn from(err: reqwest::Error) -> CliError { CliError::Reqwest(err) }}
impl From<std::io::Error> for CliError {fn from(err: std::io::Error) -> CliError { CliError::Io(err) }}

fn main() {

    let matches = App::new("ghteam-auth")
                      .version("0.1")
                      .author("Yasuyuki YAMADA <yasuyuki.ymd@gmail.com>")
                      .about("")
                      .arg(Arg::with_name("config")
                               .short("c")
                               .long("config")
                               .value_name("FILE")
                               .help("Sets a custom config file (toml)")
                               .takes_value(true))
                      .arg(Arg::with_name("v")
                               .short("v")
                               .multiple(true)
                               .help("Sets the level of verbosity"))
                      .subcommand(SubCommand::with_name("key")
                                             .about("get user public key")
                                             .arg(Arg::with_name("USER")
                                                      .required(true)
                                                      .index(1)
                                                      .help("user name")))
                      .subcommand(SubCommand::with_name("pam")
                                             .about("get user public key")
                                             .arg(Arg::with_name("USER")
                                                      .required(false)
                                                      .index(1)
                                                      .help("user name")))
                      .subcommand(SubCommand::with_name("passwd")
                                             .about("get passwd"))
                      .subcommand(SubCommand::with_name("shadow")
                                             .about("get shadow"))
                      .subcommand(SubCommand::with_name("group")
                                             .about("get group"))
                      .subcommand(SubCommand::with_name("refresh")
                                             .about("refresh cache"))
                      .get_matches();

    let config = matches.value_of("config").unwrap_or("/etc/ghteam-auth.conf");
    let mut file = File::open(config).unwrap();
    let mut contents = String::new();
    file.read_to_string(&mut contents).unwrap();
    let config = toml::from_str::<Config>(contents.as_str()).unwrap();

    match std::env::var("SSL_CERT_FILE") {
        Ok(_) => (),
        Err(_) => std::env::set_var("SSL_CERT_FILE", config.cert_path.clone()),
    }

    // let client = Client::with_connector(HttpsConnector::new(TlsClient::new()));
    let client = reqwest::Client::new().unwrap();
    let client = GithubClient::new(client, config);

    if let Some(matches) = matches.subcommand_matches("key") {
        client.print_user_public_key(matches.value_of("USER").unwrap()).unwrap();
    } else if let Some(_) = matches.subcommand_matches("passwd") {
        client.get_passwd().unwrap();
    } else if let Some(_) = matches.subcommand_matches("shadow") {
        client.get_shadow().unwrap();
    } else if let Some(_) = matches.subcommand_matches("group") {
        client.get_group().unwrap();
    } else if let Some(_) = matches.subcommand_matches("refresh") {
        client.clear_all_caches().unwrap();
    } else if let Some(_) = matches.subcommand_matches("pam") {
        match std::env::var("PAM_USER") {
            Ok(user) => {
                if client.check_pam(&user).unwrap() { std::process::exit(0); }
                else { std::process::exit(1) }
            }
            Err(e) => println!("couldn't interpret PAM_USER: {}", e),
        }
    }

}

struct GithubClient {
    // client: hyper::Client,
    client: reqwest::Client,
    conf: Config
}

impl GithubClient {
    fn new(client:reqwest::Client, conf:Config) -> GithubClient {
        GithubClient {client:client, conf:conf}
    }

    fn load_content_from_cache(&self, url:&String) -> Result<String,CliError> {
        let mut path = std::env::temp_dir();
        path.push("ghteam-auth-cache");
        path.push(url.as_str());
        let mut f = File::open(path.to_str().unwrap())?;
        let mut content = String::new();
        f.read_to_string(&mut content)?;
        Ok(content)
    }

    fn store_content_to_cache(&self, url:&String, content:&String) -> Result<(),CliError> {
        let mut path = std::env::temp_dir();
        path.push("ghteam-auth-cache");
        path.push(url.as_str());
        let mut dirpath = path.clone(); dirpath.pop();
        std::fs::create_dir_all(dirpath)?;
        let mut f = File::create(path.to_str().unwrap())?;
        f.write(content.as_bytes())?;
        Ok(())
    }

    fn get_content_from_url(&self, url:&String) -> Result<String,CliError> {
        let token = String::from("token ") + self.conf.token.clone().as_str();
        let res = self.client.get(url.as_str()).header(Authorization(token)).send();
        let mut content = String::new();
        res?.read_to_string(&mut content)?;
        Ok(content)
    }

    fn get_content(&self, url:&String) -> Result<String,CliError> {
        match self.load_content_from_cache(url) {
            Ok(content) => {
                Ok(content)
            },
            Err(_) => {
                let content = self.get_content_from_url(url)?;
                self.store_content_to_cache(url,&content)?;
                Ok(content)
            }
        }
    }

    fn print_user_public_key(&self, user:&str) -> Result<(), CliError> {
        let keys = self.get_user_public_key(user)?;
        println!("{}", keys);
        Ok(())
    }

    fn get_user_public_key(&self, user:&str) -> Result<String, CliError> {
        let url = format!("{}/users/{}/keys", self.conf.endpoint.clone(),user);
        let content = self.get_content(&url);
        let keys = serde_json::from_str::<Vec<PublicKey>>(content?.as_str())?;
        Ok(keys.iter().map(|k|{k.key.clone()}).collect::<Vec<String>>().join("\n"))
    }

    fn check_pam(&self, user:&String) -> Result<bool, CliError> {
        let teams:HashMap<String,Team> = self.get_teams()?;
        if let Some(team) = teams.get(&self.conf.team.clone()) {
            for member in self.get_members(team.id)? {
                if member.login==*user { return Ok(true) }
            }
        }
        Ok(false)
    }

    fn get_passwd(&self) -> Result<(), CliError> {
        let teams:HashMap<String,Team> = self.get_teams()?;
        if let Some(team) = teams.get(&self.conf.team.clone()) {
            for member in self.get_members(team.id)? {
                println!("{}", self.create_passwd_line(&member));
            }
            Ok(())
        } else {
            Ok(())
        }
    }

    fn get_shadow(&self) -> Result<(), CliError> {
        let teams:HashMap<String,Team> = self.get_teams()?;
        if let Some(team) = teams.get(&self.conf.team.clone()) {
            for member in self.get_members(team.id)? {
                println!("{}", self.create_shadow_line(&member));
            }
            Ok(())
        } else {
            Ok(())
        }
    }

    fn get_group(&self) -> Result<(), CliError> {
        let teams:HashMap<String,Team> = self.get_teams()?;
        if let Some(team) = teams.get(&self.conf.team.clone()) {
            let members = self.get_members(team.id)?;
            println!("{}", self.create_group_line(&team.name, self.conf.gid, &members));
            Ok(())
        } else {
            Ok(())
        }
    }

    fn create_passwd_line(&self, member:&Member) -> String {
        format!("{login}:x:{uid}:{gid}:user@{org}:{home}:{sh}",
                login=member.login,
                uid=member.id,
                gid=self.conf.gid,
                org=self.conf.org,
                home=self.conf.home.replace("{}",member.login.as_str()),
                sh=self.conf.sh,
                )
    }

    fn create_shadow_line(&self, member:&Member) -> String {
        format!("{login}:!!:::::::", login=member.login )
    }

    fn create_group_line(&self, name:&String, id:u64, members:&Vec<Member>) -> String {
        format!("{name}:x:{id}:{members}", name=name, id=id,
                members=members.iter().map(|m|{m.login.clone()}).collect::<Vec<String>>().join(","))
    }

    fn get_teams(&self) -> Result<HashMap<String,Team>, CliError> {
        let url = format!("{}/orgs/{}/teams",self.conf.endpoint.clone(), self.conf.org.clone());
        let content = self.get_content(&url)?;
        let teams = serde_json::from_str::<Vec<Team>>(content.as_str())?;
        let mut team_map = HashMap::new();
        for team in teams { team_map.insert(team.name.clone(), team); }
        Ok(team_map)
    }

    fn get_members(&self, mid:u64) -> Result<Vec<Member>, CliError> {
        let url = format!("{}/teams/{}/members",self.conf.endpoint.clone(), mid);
        let content = self.get_content(&url)?;
        let members = serde_json::from_str::<Vec<Member>>(content.as_str())?;
        Ok(members)
    }

    fn clear_all_caches(&self) -> Result<(), CliError> {
        let mut path = std::env::temp_dir();
        path.push("ghteam-auth-cache");
        path.push("**");
        path.push("*");
        for entry in glob(&path.to_str().unwrap()).unwrap() {
            match entry {
                Ok(path) => {if path.is_file() {std::fs::remove_file(path)?}},
                Err(e) => println!("{:?}", e),
            }
        }
        Ok(())
    }

}
<commit_msg>Add cash duration check<commit_after>use std::fs::File;
use std::io::prelude::*;
use std::collections::HashMap;

extern crate clap;
use clap::{Arg, App, SubCommand};
extern crate toml;

// extern crate hyper;
// extern crate hyper_rustls;
// use hyper::Client;
// use hyper::net::HttpsConnector;
// use hyper_rustls::TlsClient;
// use hyper::header::Authorization;
// use hyper::header::{Accept, qitem};
// use hyper::mime::{Mime, TopLevel, SubLevel};

extern crate reqwest;
use reqwest::header::Authorization;

extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;

extern crate glob;
use glob::glob;

#[derive(Deserialize, Debug)]
struct Config {
    token: String,
    org: String,
    team: String,
    #[serde(default="default_endpoint")]
    endpoint: String,
    #[serde(default="default_home")]
    home: String,
    #[serde(default="default_gid")]
    gid: u64,
    #[serde(default="default_sh")]
    sh: String,
    group: Option<String>,
    #[serde(default="default_cache_duration")]
    cache_duration: u64,
    #[serde(default="default_cert_path")]
    cert_path: String
}

fn default_endpoint() -> String { String::from("https://api.github.com") }
fn default_home() -> String { String::from("/home/{}") }
fn default_gid() -> u64 { 2000 }
fn default_sh() -> String { String::from("/bin/bash") }
fn default_cache_duration() -> u64 { 3600 }
fn default_cert_path() -> String { String::from("/etc/ssl/certs/ca-certificates.crt") }

#[derive(Serialize, Deserialize, Debug)]
struct Team {
    id: u64,
    name: String,
}

#[derive(Serialize, Deserialize, Debug)]
struct Member {
    id: u64,
    login: String,
}

#[derive(Serialize, Deserialize, Debug)]
struct PublicKey {
    id: u64,
    key: String,
}

#[derive(Debug)]
enum CliError {
    Serde(serde_json::Error),
    Reqwest(reqwest::Error),
    Io(std::io::Error),
    SystemTime(std::time::SystemTimeError),
}

impl From<serde_json::Error> for CliError {fn from(err: serde_json::Error) -> CliError { CliError::Serde(err) }}
impl From<reqwest::Error> for CliError {fn from(err: reqwest::Error) -> CliError { CliError::Reqwest(err) }}
impl From<std::io::Error> for CliError {fn from(err: std::io::Error) -> CliError { CliError::Io(err) }}
impl From<std::time::SystemTimeError> for CliError {fn from(err: std::time::SystemTimeError) -> CliError { CliError::SystemTime(err) }}

fn main() {

    let matches = App::new("ghteam-auth")
                      .version("0.1")
                      .author("Yasuyuki YAMADA <yasuyuki.ymd@gmail.com>")
                      .about("")
                      .arg(Arg::with_name("config")
                               .short("c")
                               .long("config")
                               .value_name("FILE")
                               .help("Sets a custom config file (toml)")
                               .takes_value(true))
                      .arg(Arg::with_name("v")
                               .short("v")
                               .multiple(true)
                               .help("Sets the level of verbosity"))
                      .subcommand(SubCommand::with_name("key")
                                             .about("get user public key")
                                             .arg(Arg::with_name("USER")
                                                      .required(true)
                                                      .index(1)
                                                      .help("user name")))
                      .subcommand(SubCommand::with_name("pam")
                                             .about("get user public key")
                                             .arg(Arg::with_name("USER")
                                                      .required(false)
                                                      .index(1)
                                                      .help("user name")))
                      .subcommand(SubCommand::with_name("passwd")
                                             .about("get passwd"))
                      .subcommand(SubCommand::with_name("shadow")
                                             .about("get shadow"))
                      .subcommand(SubCommand::with_name("group")
                                             .about("get group"))
                      .subcommand(SubCommand::with_name("refresh")
                                             .about("refresh cache"))
                      .get_matches();

    let config = matches.value_of("config").unwrap_or("/etc/ghteam-auth.conf");
    let mut file = File::open(config).unwrap();
    let mut contents = String::new();
    file.read_to_string(&mut contents).unwrap();
    let config = toml::from_str::<Config>(contents.as_str()).unwrap();

    match std::env::var("SSL_CERT_FILE") {
        Ok(_) => (),
        Err(_) => std::env::set_var("SSL_CERT_FILE", config.cert_path.clone()),
    }

    // let client = Client::with_connector(HttpsConnector::new(TlsClient::new()));
    let client = reqwest::Client::new().unwrap();
    let client = GithubClient::new(client, config);

    if let Some(matches) = matches.subcommand_matches("key") {
        client.print_user_public_key(matches.value_of("USER").unwrap()).unwrap();
    } else if let Some(_) = matches.subcommand_matches("passwd") {
        client.get_passwd().unwrap();
    } else if let Some(_) = matches.subcommand_matches("shadow") {
        client.get_shadow().unwrap();
    } else if let Some(_) = matches.subcommand_matches("group") {
        client.get_group().unwrap();
    } else if let Some(_) = matches.subcommand_matches("refresh") {
        client.clear_all_caches().unwrap();
    } else if let Some(_) = matches.subcommand_matches("pam") {
        match std::env::var("PAM_USER") {
            Ok(user) => {
                if client.check_pam(&user).unwrap() { std::process::exit(0); }
                else { std::process::exit(1) }
            }
            Err(e) => println!("couldn't interpret PAM_USER: {}", e),
        }
    }

}

struct GithubClient {
    // client: hyper::Client,
    client: reqwest::Client,
    conf: Config
}

impl GithubClient {
    fn new(client:reqwest::Client, conf:Config) -> GithubClient {
        GithubClient {client:client, conf:conf}
    }

    fn load_content_from_cache(&self, url:&String) -> Result<(std::fs::Metadata,String),CliError> {
        let mut path = std::env::temp_dir();
        path.push("ghteam-auth-cache");
        path.push(url.as_str());
        let metadata = std::fs::metadata(path.to_str().unwrap())?;
        let mut f = File::open(path.to_str().unwrap())?;
        let mut content = String::new();
        f.read_to_string(&mut content)?;
        Ok((metadata,content))
    }

    fn store_content_to_cache(&self, url:&String, content:&String) -> Result<(),CliError> {
        let mut path = std::env::temp_dir();
        path.push("ghteam-auth-cache");
        path.push(url.as_str());
        let mut dirpath = path.clone(); dirpath.pop();
        std::fs::create_dir_all(dirpath)?;
        let mut f = File::create(path.to_str().unwrap())?;
        f.write(content.as_bytes())?;
        Ok(())
    }

    fn get_content_from_url(&self, url:&String) -> Result<String,CliError> {
        let token = String::from("token ") + self.conf.token.clone().as_str();
        let res = self.client.get(url.as_str()).header(Authorization(token)).send();
        let mut content = String::new();
        res?.read_to_string(&mut content)?;
        self.store_content_to_cache(url,&content)?;
        Ok(content)
    }

    fn get_content(&self, url:&String) -> Result<String,CliError> {
        match self.load_content_from_cache(url) {
            Ok((metadata,cache_content)) => {
                match std::time::SystemTime::now().duration_since(metadata.modified()?) {
                    Ok(caching_duration) => {
                        if caching_duration.as_secs() > self.conf.cache_duration {
                            match self.get_content_from_url(url) {
                                Ok(content_from_url) => Ok(content_from_url),
                                Err(_) => Ok(cache_content)
                            }
                        } else {
                            Ok(cache_content)
                        }
                    },
                    Err(_) => {
                        Ok(cache_content)
                    }
                }
            },
            Err(_) => self.get_content_from_url(url)
        }
    }

    fn print_user_public_key(&self, user:&str) -> Result<(), CliError> {
        let keys = self.get_user_public_key(user)?;
        println!("{}", keys);
        Ok(())
    }

    fn get_user_public_key(&self, user:&str) -> Result<String, CliError> {
        let url = format!("{}/users/{}/keys", self.conf.endpoint.clone(),user);
        let content = self.get_content(&url);
        let keys = serde_json::from_str::<Vec<PublicKey>>(content?.as_str())?;
        Ok(keys.iter().map(|k|{k.key.clone()}).collect::<Vec<String>>().join("\n"))
    }

    fn check_pam(&self, user:&String) -> Result<bool, CliError> {
        let teams:HashMap<String,Team> = self.get_teams()?;
        if let Some(team) = teams.get(&self.conf.team.clone()) {
            for member in self.get_members(team.id)? {
                if member.login==*user { return Ok(true) }
            }
        }
        Ok(false)
    }

    fn get_passwd(&self) -> Result<(), CliError> {
        let teams:HashMap<String,Team> = self.get_teams()?;
        if let Some(team) = teams.get(&self.conf.team.clone()) {
            for member in self.get_members(team.id)? {
                println!("{}", self.create_passwd_line(&member));
            }
            Ok(())
        } else {
            Ok(())
        }
    }

    fn get_shadow(&self) -> Result<(), CliError> {
        let teams:HashMap<String,Team> = self.get_teams()?;
        if let Some(team) = teams.get(&self.conf.team.clone()) {
            for member in self.get_members(team.id)? {
                println!("{}", self.create_shadow_line(&member));
            }
            Ok(())
        } else {
            Ok(())
        }
    }

    fn get_group(&self) -> Result<(), CliError> {
        let teams:HashMap<String,Team> = self.get_teams()?;
        if let Some(team) = teams.get(&self.conf.team.clone()) {
            let members = self.get_members(team.id)?;
            println!("{}", self.create_group_line(&team.name, self.conf.gid, &members));
            Ok(())
        } else {
            Ok(())
        }
    }

    fn create_passwd_line(&self, member:&Member) -> String {
        format!("{login}:x:{uid}:{gid}:user@{org}:{home}:{sh}",
                login=member.login,
                uid=member.id,
                gid=self.conf.gid,
                org=self.conf.org,
                home=self.conf.home.replace("{}",member.login.as_str()),
                sh=self.conf.sh,
                )
    }

    fn create_shadow_line(&self, member:&Member) -> String {
        format!("{login}:!!:::::::", login=member.login )
    }

    fn create_group_line(&self, name:&String, id:u64, members:&Vec<Member>) -> String {
        format!("{name}:x:{id}:{members}", name=name, id=id,
                members=members.iter().map(|m|{m.login.clone()}).collect::<Vec<String>>().join(","))
    }

    fn get_teams(&self) -> Result<HashMap<String,Team>, CliError> {
        let url = format!("{}/orgs/{}/teams",self.conf.endpoint.clone(), self.conf.org.clone());
        let content = self.get_content(&url)?;
        let teams = serde_json::from_str::<Vec<Team>>(content.as_str())?;
        let mut team_map = HashMap::new();
        for team in teams { team_map.insert(team.name.clone(), team); }
        Ok(team_map)
    }

    fn get_members(&self, mid:u64) -> Result<Vec<Member>, CliError> {
        let url = format!("{}/teams/{}/members",self.conf.endpoint.clone(), mid);
        let content = self.get_content(&url)?;
        let members = serde_json::from_str::<Vec<Member>>(content.as_str())?;
        Ok(members)
    }

    fn clear_all_caches(&self) -> Result<(), CliError> {
        let mut path = std::env::temp_dir();
        path.push("ghteam-auth-cache");
        path.push("**");
        path.push("*");
        for entry in glob(&path.to_str().unwrap()).unwrap() {
            match entry {
                Ok(path) => {if path.is_file() {std::fs::remove_file(path)?}},
                Err(e) => println!("{:?}", e),
            }
        }
        Ok(())
    }

}
<|endoftext|>


<commit_before>extern crate clap;
extern crate walkdir;
extern crate twox_hash;

use std::collections::HashMap;
use std::fs::File;
use std::io::Read;
use std::path::Path;

use clap::{App, Arg};
use walkdir::WalkDir;
use twox_hash::XxHash;
use std::hash::Hasher;

fn main() {
    let matches = App::new("dupr")
        .version("0.1.0")
        .author("Mike Sampson")
        .about("Duplicate file finder")
        .arg(
            Arg::with_name("DIR")
                .help("Directory to process")
                .required(true),
        )
        .get_matches();

    let mut files = HashMap::new();

    for entry in WalkDir::new(matches.value_of("DIR").unwrap()) {
        let entry = entry.unwrap();

        if !entry.file_type().is_file() {
            continue;
        }

        let metadata = entry.metadata().unwrap();

        let path = entry.path().to_path_buf();

        files.entry(metadata.len()).or_insert(Vec::new()).push(path);
    }

    for (f_len, f_paths) in files {
        println!("=== {} - {} ===", f_len, f_paths.len());
        for f_path in f_paths {
            println!("    {} - {:x}", f_path.display(), hash_file(&f_path));
        }
    }
}

fn hash_file<P: AsRef<Path>>(path: P) -> u64 {
    let mut file = File::open(path).unwrap();

    let mut hash = XxHash::with_seed(0);

    let mut buffer = [0; 32 * 1024];

    while let Ok(n) = file.read(&mut buffer) {
        if n == 0 {
            break;
        }
        hash.write(&buffer[0..n]);
    }

    hash.finish()
}
<commit_msg>Print out duplicate files with hash.<commit_after>extern crate clap;
extern crate walkdir;
extern crate twox_hash;

use std::collections::HashMap;
use std::fs::File;
use std::io::Read;
use std::path::Path;

use clap::{App, Arg};
use walkdir::WalkDir;
use twox_hash::XxHash;
use std::hash::Hasher;

fn main() {
    let matches = App::new("dupr")
        .version("0.1.0")
        .author("Mike Sampson")
        .about("Duplicate file finder")
        .arg(
            Arg::with_name("DIR")
                .help("Directory to process")
                .required(true),
        )
        .get_matches();

    let mut files = HashMap::new();

    for entry in WalkDir::new(matches.value_of("DIR").unwrap()) {
        let entry = entry.unwrap();

        if !entry.file_type().is_file() {
            continue;
        }

        let metadata = entry.metadata().unwrap();

        let path = entry.path().to_path_buf();

        files.entry(metadata.len()).or_insert(Vec::new()).push(path);
    }

    for f_paths in files.values() {
        if f_paths.len() == 1 {
            continue;
        }

        let mut hashes = HashMap::new();
        for f_path in f_paths {
            hashes
                .entry(hash_file(&f_path))
                .or_insert(Vec::new())
                .push(f_path);
        }

        for (hash, paths) in hashes {
            if paths.len() < 2 {
                continue;
            }
            for p in paths {
                println!("{:016x} - {}", hash, p.display());
            }
        }
    }
}

fn hash_file<P: AsRef<Path>>(path: P) -> u64 {
    let mut file = File::open(path).unwrap();

    let mut hash = XxHash::with_seed(0);

    let mut buffer = [0; 32 * 1024];

    while let Ok(n) = file.read(&mut buffer) {
        if n == 0 {
            break;
        }
        hash.write(&buffer[0..n]);
    }

    hash.finish()
}
<|endoftext|>


<commit_before>use png;
use color::{Color, Black, White, Red, Green, Blue};
use point::Point;
use scene::{Scene, Spot};
use shapes::{Object, Sphere, Plane};

static WIDTH: int = 1000;
static HEIGHT: int = 1000;

#[main]
fn main() {
  let mut pixels = ~[Black, ..((WIDTH * HEIGHT) as uint)];

  let scene = Scene {
    eye: Point::new(-12000., 0., 0.),
    spots: ~[
      Spot {
        pos: Point::new(0., -200., 0.),
        color: White
      },
    ],
    objects: ~[
      Object {
        pos: Point::new(0., 400., 400.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., 400., 0.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., 400., -400.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., -400., 400.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., -400., 0.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., -400., -400.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., 0., 400.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., 0., 0.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., 0., -400.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
    ]
  };

  for x in range(0, WIDTH) {
    for y in range(0, HEIGHT) {
      let vector = Point {
        x: 10000.,
        y: (WIDTH / 2 - x) as f64,
        z: (HEIGHT / 2 - y) as f64
      };

      pixels[y * WIDTH + x] = match scene.get_closest(&vector) {
        (Some(obj), k) if k > 0. => scene.get_color(obj, &vector, k),
        _ => Black
      }
    }
  }

  let img = png::Image {
    width: WIDTH as u32,
    height: HEIGHT as u32,
    color_type: png::RGB8,
    pixels: pixels.flat_map(|&Color { r, g, b }| { ~[r, g, b] })
  };

  png::store_png(&img, &Path::new("out.png"));
}<commit_msg>Normalize vector<commit_after>use png;
use color::{Color, Black, White, Red, Green, Blue};
use point::Point;
use scene::{Scene, Spot};
use shapes::{Object, Sphere, Plane};

static WIDTH: int = 1000;
static HEIGHT: int = 1000;

#[main]
fn main() {
  let mut pixels = ~[Black, ..((WIDTH * HEIGHT) as uint)];

  let scene = Scene {
    eye: Point::new(-12000., 0., 0.),
    spots: ~[
      Spot {
        pos: Point::new(0., -200., 0.),
        color: White
      },
    ],
    objects: ~[
      Object {
        pos: Point::new(0., 400., 400.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., 400., 0.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., 400., -400.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., -400., 400.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., -400., 0.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., -400., -400.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., 0., 400.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., 0., 0.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., 0., -400.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
    ]
  };

  for x in range(0, WIDTH) {
    for y in range(0, HEIGHT) {
      let vector = Point {
        x: 10000.,
        y: (WIDTH / 2 - x) as f64,
        z: (HEIGHT / 2 - y) as f64
      }.normalize();

      pixels[y * WIDTH + x] = match scene.get_closest(&vector) {
        (Some(obj), k) if k > 0. => scene.get_color(obj, &vector, k),
        _ => Black
      }
    }
  }

  let img = png::Image {
    width: WIDTH as u32,
    height: HEIGHT as u32,
    color_type: png::RGB8,
    pixels: pixels.flat_map(|&Color { r, g, b }| { ~[r, g, b] })
  };

  png::store_png(&img, &Path::new("out.png"));
}<|endoftext|>


<commit_before>#[macro_use]
extern crate clap;
#[macro_use]
extern crate lazy_static;

extern crate libc;
extern crate scmp;
extern crate tempdir;

use std::fs;
use std::env;
use std::ffi::OsStr;
use std::ffi::CString;
use std::io::Error;
use std::os::unix::process::CommandExt;
use std::os::unix::ffi::OsStrExt;
use std::path::Path;
use std::path::PathBuf;
use std::process::Command;
use scmp::*;

fn setup_seccomp() -> Result<(), Error> {
    unsafe {
        let ctx0 = seccomp_init(SCMP_ACT_TRAP);
        assert!(!ctx0.is_null());
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_execve as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_brk as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_access as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_mmap as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_open as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_read as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_write as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_stat as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_fstat as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_close as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_mprotect as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_arch_prctl as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_munmap as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_set_tid_address as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_set_robust_list as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_rt_sigaction as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_rt_sigprocmask as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_getrlimit as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_statfs as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_fcntl as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_geteuid as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_umask as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_pipe as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_clone as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_wait4 as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_exit_group as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_dup as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_ioctl as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_getpid as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_gettid as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_tgkill as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_rt_sigreturn as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_socket as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_connect as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_lseek as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_openat as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_unlinkat as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_utimensat as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_lstat as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_fchmod as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_unlink as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_utime as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_load(ctx0) == 0);
    }
    return Ok(());
}

const RENAME_NOREPLACE : u64 = 1;

fn rename_noreplace(path0 : &Path, path1 : &Path) -> Result<(), Error> {
    unsafe {
        if libc::syscall(__NR_renameat2 as i64, libc::AT_FDCWD, CString::new(path0.as_os_str().as_bytes()).unwrap().as_ptr(), libc::AT_FDCWD, CString::new(path1.as_os_str().as_bytes()).unwrap().as_ptr(), RENAME_NOREPLACE, 0) == 0 {
            return Ok(());
        } else {
            return Err(Error::last_os_error());
        }
    }
}

fn rename_or_suffix(path0 : &Path, path1 : &Path) -> Result<PathBuf, Error> {
    let rv = rename_noreplace(path0, path1);
    if let Err(err) = rv {
        if err.raw_os_error().expect("Error fails to wrap errno") != libc::EEXIST {
            return Err(err);
        }
        for suffix in 1.. {
            let mut builder = path1.as_os_str().to_os_string();
            builder.push(format!(".{}", suffix));
            let rv = rename_noreplace(path0, Path::new(&builder));
            if let Err(err) = rv {
                if err.raw_os_error().expect("Error fails to wrap errno") != libc::EEXIST {
                    return Err(err);
                }
                continue;
            }
            return Ok(Path::new(&builder).to_path_buf());
        }
        return Ok(PathBuf::new()); // XXX Unreachable
    } else {
        return Ok(path1.to_path_buf());
    }
}

struct ArchiveType {
    extensions: Vec<&'static str>,
    extract_cmd: Vec<&'static str>,
}

lazy_static! {
    static ref ARCHIVE_TYPES : Vec<ArchiveType> = vec![
        ArchiveType {
            extensions: vec![
                ".tgz",
                ".tar.gz",
                ".tar.Z",
                ".tbz2",
                ".tar.bz2",
                ".tlz",
                ".tar.lz",
                ".tar.lzma",
                ".tar.lzo",
                ".tar.xz",
            ],
            extract_cmd: vec!["tar", "-xf"],
        },
        ArchiveType {
            extensions: vec![
                ".zip",
            ],
            extract_cmd: vec!["unzip", "--"],
        },
    ];
}

fn main() {
    let matches = clap_app!(myapp =>
        (@arg ARCHIVE: +required ... "Archives to extract")
    ).get_matches();

    let mut found = false;

    for arch in matches.values_of_os("ARCHIVE").unwrap() {
        let arch = Path::new(arch);
        println!("Extract {:?}", arch);
        for at in ARCHIVE_TYPES.iter() {
            for &ext in &at.extensions {
                if !arch.as_os_str().as_bytes().ends_with(ext.as_bytes()) {
                    continue;
                }
                found = true;

                let noext : &OsStr = OsStrExt::from_bytes(&arch.as_os_str().as_bytes()[0..arch.as_os_str().as_bytes().len()-ext.as_bytes().len()]);
                let stripped =
                    if let Some(noext) = Path::new(noext).file_name() {
                        noext
                    } else {
                        OsStr::new("extracted")
                    };
                let cmd = at.extract_cmd[0];
                let tmpdir = tempdir::TempDir::new_in(
                    env::current_dir().expect("Unable to get the current directory"),
                    stripped.to_string_lossy().to_mut().as_str()).expect("Unable to create temporary directory");
                let status = Command::new(cmd)
                    .args(&at.extract_cmd[1..])
                    .arg(&arch)
                    .current_dir(&tmpdir)
                    .before_exec(setup_seccomp)
                    .status()
                    .expect(format!("Failed to launch {}", cmd).as_str());
                assert!(status.success(), format!("{} wasn't successful", cmd));
                let extracted_path = tmpdir.into_path();
                let mut dir_list = fs::read_dir(&extracted_path).expect("Unable to read the extraction directory");
                if let Some(path) = dir_list.next() {
                    let path = path.expect("Unable to iterate the extraction directory");
                    if let Some(path1) = dir_list.next() {
                        path1.expect("Unable to iterate the extraction directory");
                        rename_or_suffix(&extracted_path, Path::new(stripped)).expect("Failed to rename");
                    } else {
                        rename_or_suffix(&path.path(), Path::new(stripped)).expect("Failed to rename");
                        fs::remove_dir(&extracted_path).expect("Failed to remove empty extraction directory");
                    }
                } else {
                    println!("No files were extracted");
                }
                break;
            }
        }
        if !found {
            println!("Can't handle {:?}", arch);
        }
    }
}

<commit_msg>Add unrar support<commit_after>#[macro_use]
extern crate clap;
#[macro_use]
extern crate lazy_static;

extern crate libc;
extern crate scmp;
extern crate tempdir;

use std::fs;
use std::env;
use std::ffi::OsStr;
use std::ffi::CString;
use std::io::Error;
use std::os::unix::process::CommandExt;
use std::os::unix::ffi::OsStrExt;
use std::path::Path;
use std::path::PathBuf;
use std::process::Command;
use scmp::*;

fn setup_seccomp() -> Result<(), Error> {
    unsafe {
        let ctx0 = seccomp_init(SCMP_ACT_TRAP);
        assert!(!ctx0.is_null());
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_execve as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_brk as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_access as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_mmap as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_open as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_read as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_write as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_stat as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_fstat as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_close as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_mprotect as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_arch_prctl as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_munmap as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_set_tid_address as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_set_robust_list as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_rt_sigaction as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_rt_sigprocmask as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_getrlimit as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_statfs as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_fcntl as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_geteuid as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_umask as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_pipe as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_clone as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_wait4 as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_exit_group as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_dup as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_ioctl as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_getpid as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_gettid as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_tgkill as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_rt_sigreturn as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_socket as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_connect as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_lseek as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_openat as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_unlinkat as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_utimensat as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_lstat as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_fchmod as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_unlink as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_utime as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_futex as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_chmod as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_load(ctx0) == 0);
    }
    return Ok(());
}

const RENAME_NOREPLACE : u64 = 1;

fn rename_noreplace(path0 : &Path, path1 : &Path) -> Result<(), Error> {
    unsafe {
        if libc::syscall(__NR_renameat2 as i64, libc::AT_FDCWD, CString::new(path0.as_os_str().as_bytes()).unwrap().as_ptr(), libc::AT_FDCWD, CString::new(path1.as_os_str().as_bytes()).unwrap().as_ptr(), RENAME_NOREPLACE, 0) == 0 {
            return Ok(());
        } else {
            return Err(Error::last_os_error());
        }
    }
}

fn rename_or_suffix(path0 : &Path, path1 : &Path) -> Result<PathBuf, Error> {
    let rv = rename_noreplace(path0, path1);
    if let Err(err) = rv {
        if err.raw_os_error().expect("Error fails to wrap errno") != libc::EEXIST {
            return Err(err);
        }
        for suffix in 1.. {
            let mut builder = path1.as_os_str().to_os_string();
            builder.push(format!(".{}", suffix));
            let rv = rename_noreplace(path0, Path::new(&builder));
            if let Err(err) = rv {
                if err.raw_os_error().expect("Error fails to wrap errno") != libc::EEXIST {
                    return Err(err);
                }
                continue;
            }
            return Ok(Path::new(&builder).to_path_buf());
        }
        return Ok(PathBuf::new()); // XXX Unreachable
    } else {
        return Ok(path1.to_path_buf());
    }
}

struct ArchiveType {
    extensions: Vec<&'static str>,
    extract_cmd: Vec<&'static str>,
}

lazy_static! {
    static ref ARCHIVE_TYPES : Vec<ArchiveType> = vec![
        ArchiveType {
            extensions: vec![
                ".tgz",
                ".tar.gz",
                ".tar.Z",
                ".tbz2",
                ".tar.bz2",
                ".tlz",
                ".tar.lz",
                ".tar.lzma",
                ".tar.lzo",
                ".tar.xz",
            ],
            extract_cmd: vec!["tar", "-xf"],
        },
        ArchiveType {
            extensions: vec![
                ".zip",
            ],
            extract_cmd: vec!["unzip", "--"],
        },
        ArchiveType {
            extensions: vec![
                ".rar",
            ],
            extract_cmd: vec!["unrar", "x", "--"],
        },
    ];
}

fn main() {
    let matches = clap_app!(myapp =>
        (@arg ARCHIVE: +required ... "Archives to extract")
    ).get_matches();

    let mut found = false;

    for arch in matches.values_of_os("ARCHIVE").unwrap() {
        let arch = Path::new(arch);
        println!("Extract {:?}", arch);
        for at in ARCHIVE_TYPES.iter() {
            for &ext in &at.extensions {
                if !arch.as_os_str().as_bytes().ends_with(ext.as_bytes()) {
                    continue;
                }
                found = true;

                let noext : &OsStr = OsStrExt::from_bytes(&arch.as_os_str().as_bytes()[0..arch.as_os_str().as_bytes().len()-ext.as_bytes().len()]);
                let stripped =
                    if let Some(noext) = Path::new(noext).file_name() {
                        noext
                    } else {
                        OsStr::new("extracted")
                    };
                let cmd = at.extract_cmd[0];
                let tmpdir = tempdir::TempDir::new_in(
                    env::current_dir().expect("Unable to get the current directory"),
                    stripped.to_string_lossy().to_mut().as_str()).expect("Unable to create temporary directory");
                let status = Command::new(cmd)
                    .args(&at.extract_cmd[1..])
                    .arg(&arch)
                    .current_dir(&tmpdir)
                    .before_exec(setup_seccomp)
                    .status()
                    .expect(format!("Failed to launch {}", cmd).as_str());
                assert!(status.success(), format!("{} wasn't successful", cmd));
                let extracted_path = tmpdir.into_path();
                let mut dir_list = fs::read_dir(&extracted_path).expect("Unable to read the extraction directory");
                if let Some(path) = dir_list.next() {
                    let path = path.expect("Unable to iterate the extraction directory");
                    if let Some(path1) = dir_list.next() {
                        path1.expect("Unable to iterate the extraction directory");
                        rename_or_suffix(&extracted_path, Path::new(stripped)).expect("Failed to rename");
                    } else {
                        rename_or_suffix(&path.path(), Path::new(stripped)).expect("Failed to rename");
                        fs::remove_dir(&extracted_path).expect("Failed to remove empty extraction directory");
                    }
                } else {
                    println!("No files were extracted");
                }
                break;
            }
        }
        if !found {
            println!("Can't handle {:?}", arch);
        }
    }
}

<|endoftext|>


<commit_before>use std::{env, process};
use std::io::prelude::*;
use std::io::BufReader;
use std::collections::HashMap;
use std::path::PathBuf;
use std::fs::File;

static OVERRIDES_PATH : &'static str = ".multirust/overrides";

fn clean_toolchain_name(toolchain: &str) -> &str {
    static SHORTNAMES : &'static [&'static str] = &["stable", "nightly", "beta"];

    for short in SHORTNAMES {
        if toolchain.starts_with(short) {
            return short;
        }
    }

    toolchain
}

fn main() {
    let home = env::home_dir().expect("Impossible to get your home dir!");
    let mut overrides_path = home.clone();
    overrides_path.push(OVERRIDES_PATH);

    let overrides = match File::open(&overrides_path) {
        Ok(f) => f,
        Err(_) => {
            println!("default");
            process::exit(0);
        }
    };
    let overrides = BufReader::new(overrides);

    let mut overrides_map = HashMap::<PathBuf, String>::new();

    for line in overrides.lines() {
        let line = line.expect("No valid line found");
        let mut s = line.split(';');
        let path = s.next().expect("No path in line");
        let toolchain = s.next().expect("No toolchain in line");

        let path = PathBuf::from(path);

        overrides_map.insert(path, toolchain.into());
    }

    let cwd = env::current_dir().expect("No valid working directory");

    match overrides_map.get(&cwd) {
        Some(toolchain) => println!("{}", clean_toolchain_name(toolchain)),
        None => println!("default"),
    }
}
<commit_msg>feat: Include date in toolchain name if any<commit_after>use std::{env, process};
use std::io::prelude::*;
use std::io::BufReader;
use std::collections::HashMap;
use std::path::PathBuf;
use std::fs::File;

static OVERRIDES_PATH : &'static str = ".multirust/overrides";

fn with_date<'a>(short: &'a str, toolchain: &'a str) -> Option<&'a str> {
    let date_start = short.len() + 1;
    let date_end   = short.len() + 3 + 4 + 2 + 2;
    let char_range = toolchain.chars()
        .skip(date_start)
        .take(4)
        .all(char::is_numeric);

    if char_range {
        Some(&toolchain[0..date_end])
    } else {
        None
    }
}

fn clean_toolchain_name(toolchain: &str) -> &str {
    static SHORTNAMES : &'static [&'static str] = &["stable", "nightly", "beta"];

    for short in SHORTNAMES {
        if toolchain.starts_with(short) {
            return match with_date(short, toolchain) {
                Some(s) => s,
                None => short
            }
        }
    }

    toolchain
}

fn main() {
    let home = env::home_dir().expect("Impossible to get your home dir!");
    let mut overrides_path = home.clone();
    overrides_path.push(OVERRIDES_PATH);

    let overrides = match File::open(&overrides_path) {
        Ok(f) => f,
        Err(_) => {
            println!("default");
            process::exit(0);
        }
    };
    let overrides = BufReader::new(overrides);

    let mut overrides_map = HashMap::<PathBuf, String>::new();

    for line in overrides.lines() {
        let line = line.expect("No valid line found");
        let mut s = line.split(';');
        let path = s.next().expect("No path in line");
        let toolchain = s.next().expect("No toolchain in line");

        let path = PathBuf::from(path);

        overrides_map.insert(path, toolchain.into());
    }

    let cwd = env::current_dir().expect("No valid working directory");

    match overrides_map.get(&cwd) {
        Some(toolchain) => println!("{}", clean_toolchain_name(toolchain)),
        None => println!("default"),
    }
}
<|endoftext|>


<commit_before>// error-pattern:yummy
#![feature(box_syntax)]
#![feature(rustc_private)]
#![allow(unknown_lints, missing_docs_in_private_items)]

extern crate clippy_lints;
extern crate getopts;
extern crate rustc;
extern crate rustc_driver;
extern crate rustc_errors;
extern crate rustc_plugin;
extern crate syntax;

use rustc_driver::{driver, Compilation, CompilerCalls, RustcDefaultCalls};
use rustc::session::{config, CompileIncomplete, Session};
use rustc::session::config::{ErrorOutputType, Input};
use std::collections::HashMap;
use std::path::PathBuf;
use std::process::{self, Command};
use syntax::ast;
use std::io::{self, Write};

extern crate cargo_metadata;

struct ClippyCompilerCalls {
    default: RustcDefaultCalls,
    run_lints: bool,
}

impl ClippyCompilerCalls {
    fn new(run_lints: bool) -> Self {
        ClippyCompilerCalls {
            default: RustcDefaultCalls,
            run_lints: run_lints,
        }
    }
}

impl<'a> CompilerCalls<'a> for ClippyCompilerCalls {
    fn early_callback(
        &mut self,
        matches: &getopts::Matches,
        sopts: &config::Options,
        cfg: &ast::CrateConfig,
        descriptions: &rustc_errors::registry::Registry,
        output: ErrorOutputType,
    ) -> Compilation {
        self.default.early_callback(
            matches,
            sopts,
            cfg,
            descriptions,
            output,
        )
    }
    fn no_input(
        &mut self,
        matches: &getopts::Matches,
        sopts: &config::Options,
        cfg: &ast::CrateConfig,
        odir: &Option<PathBuf>,
        ofile: &Option<PathBuf>,
        descriptions: &rustc_errors::registry::Registry,
    ) -> Option<(Input, Option<PathBuf>)> {
        self.default.no_input(
            matches,
            sopts,
            cfg,
            odir,
            ofile,
            descriptions,
        )
    }
    fn late_callback(
        &mut self,
        matches: &getopts::Matches,
        sess: &Session,
        input: &Input,
        odir: &Option<PathBuf>,
        ofile: &Option<PathBuf>,
    ) -> Compilation {
        self.default.late_callback(
            matches,
            sess,
            input,
            odir,
            ofile,
        )
    }
    fn build_controller(&mut self, sess: &Session, matches: &getopts::Matches) -> driver::CompileController<'a> {
        let mut control = self.default.build_controller(sess, matches);

        if self.run_lints {
            let old = std::mem::replace(&mut control.after_parse.callback, box |_| {});
            control.after_parse.callback = Box::new(move |state| {
                {
                    let mut registry = rustc_plugin::registry::Registry::new(
                        state.session,
                        state
                            .krate
                            .as_ref()
                            .expect(
                                "at this compilation stage \
                                                                                the krate must be parsed",
                            )
                            .span,
                    );
                    registry.args_hidden = Some(Vec::new());
                    clippy_lints::register_plugins(&mut registry);

                    let rustc_plugin::registry::Registry {
                        early_lint_passes,
                        late_lint_passes,
                        lint_groups,
                        llvm_passes,
                        attributes,
                        ..
                    } = registry;
                    let sess = &state.session;
                    let mut ls = sess.lint_store.borrow_mut();
                    for pass in early_lint_passes {
                        ls.register_early_pass(Some(sess), true, pass);
                    }
                    for pass in late_lint_passes {
                        ls.register_late_pass(Some(sess), true, pass);
                    }

                    for (name, to) in lint_groups {
                        ls.register_group(Some(sess), true, name, to);
                    }

                    sess.plugin_llvm_passes.borrow_mut().extend(llvm_passes);
                    sess.plugin_attributes.borrow_mut().extend(attributes);
                }
                old(state);
            });
        }

        control
    }
}

use std::path::Path;

const CARGO_CLIPPY_HELP: &str = r#"Checks a package to catch common mistakes and improve your Rust code.

Usage:
    cargo clippy [options] [--] [<opts>...]

Common options:
    -h, --help               Print this message
    --features               Features to compile for the package
    -V, --version            Print version info and exit
    --all                    @@@ something sensible here (copy from cargo-edit?)

Other options are the same as `cargo rustc`.

To allow or deny a lint from the command line you can use `cargo clippy --`
with:

    -W --warn OPT       Set lint warnings
    -A --allow OPT      Set lint allowed
    -D --deny OPT       Set lint denied
    -F --forbid OPT     Set lint forbidden

The feature `cargo-clippy` is automatically defined for convenience. You can use
it to allow or deny lints from the code, eg.:

    #[cfg_attr(feature = "cargo-clippy", allow(needless_lifetimes))]
"#;

#[allow(print_stdout)]
fn show_help() {
    println!("{}", CARGO_CLIPPY_HELP);
}

#[allow(print_stdout)]
fn show_version() {
    println!("{}", env!("CARGO_PKG_VERSION"));
}

pub fn main() {
    use std::env;

    if env::var("CLIPPY_DOGFOOD").map(|_| true).unwrap_or(false) {
        panic!("yummy");
    }

    // Check for version and help flags even when invoked as 'cargo-clippy'
    if std::env::args().any(|a| a == "--help" || a == "-h") {
        show_help();
        return;
    }
    if std::env::args().any(|a| a == "--version" || a == "-V") {
        show_version();
        return;
    }

    if let Some("clippy") = std::env::args().nth(1).as_ref().map(AsRef::as_ref) {
        // this arm is executed on the initial call to `cargo clippy`

        let manifest_path_arg = std::env::args()
            .skip(2)
            .find(|val| val.starts_with("--manifest-path="));

        let mut metadata =
            if let Ok(metadata) = cargo_metadata::metadata(manifest_path_arg.as_ref().map(AsRef::as_ref)) {
                metadata
            } else {
                let _ = io::stderr().write_fmt(format_args!("error: Could not obtain cargo metadata.\n"));
                process::exit(101);
            };

        let manifest_path = manifest_path_arg.map(|arg| {
            Path::new(&arg["--manifest-path=".len()..])
                .canonicalize()
                .expect("manifest path could not be canonicalized")
        });

        let packages = if std::env::args().any(|a| a == "--all") {
            metadata.packages
        } else {
            let package_index = {
                if let Some(manifest_path) = manifest_path {
                    metadata.packages.iter().position(|package| {
                        let package_manifest_path = Path::new(&package.manifest_path)
                            .canonicalize()
                            .expect("package manifest path could not be canonicalized");
                        package_manifest_path == manifest_path
                    })
                } else {
                    let package_manifest_paths: HashMap<_, _> = metadata
                        .packages
                        .iter()
                        .enumerate()
                        .map(|(i, package)| {
                            let package_manifest_path = Path::new(&package.manifest_path)
                                .parent()
                                .expect("could not find parent directory of package manifest")
                                .canonicalize()
                                .expect("package directory cannot be canonicalized");
                            (package_manifest_path, i)
                        })
                        .collect();

                    let current_dir = std::env::current_dir()
                        .expect("could not read current directory")
                        .canonicalize()
                        .expect("current directory cannot be canonicalized");

                    let mut current_path: &Path = &current_dir;

                    // This gets the most-recent parent (the one that takes the fewest `cd ..`s to
                    // reach).
                    loop {
                        if let Some(&package_index) = package_manifest_paths.get(current_path) {
                            break Some(package_index);
                        } else {
                            // We'll never reach the filesystem root, because to get to this point in the
                            // code
                            // the call to `cargo_metadata::metadata` must have succeeded. So it's okay to
                            // unwrap the current path's parent.
                            current_path = current_path
                                .parent()
                                .unwrap_or_else(|| panic!("could not find parent of path {}", current_path.display()));
                        }
                    }
                }
            }.expect("could not find matching package");

            vec![metadata.packages.remove(package_index)]
        };

        for package in packages {
            let manifest_path = package.manifest_path;

            for target in package.targets {
                let args = std::env::args()
                    .skip(2)
                    .filter(|a| a != "--all" && !a.starts_with("--manifest-path="));

                let args = std::iter::once(format!("--manifest-path={}", manifest_path)).chain(args);
                if let Some(first) = target.kind.get(0) {
                    if target.kind.len() > 1 || first.ends_with("lib") {
                        if let Err(code) = process(std::iter::once("--lib".to_owned()).chain(args)) {
                            std::process::exit(code);
                        }
                    } else if ["bin", "example", "test", "bench"].contains(&&**first) {
                        if let Err(code) = process(
                            vec![format!("--{}", first), target.name]
                                .into_iter()
                                .chain(args),
                        ) {
                            std::process::exit(code);
                        }
                    }
                } else {
                    panic!("badly formatted cargo metadata: target::kind is an empty array");
                }
            }
        }
    } else {
        // this arm is executed when cargo-clippy runs `cargo rustc` with the `RUSTC`
        // env var set to itself

        let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
        let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
        let sys_root = if let (Some(home), Some(toolchain)) = (home, toolchain) {
            format!("{}/toolchains/{}", home, toolchain)
        } else {
            option_env!("SYSROOT")
                .map(|s| s.to_owned())
                .or_else(|| {
                    Command::new("rustc")
                        .arg("--print")
                        .arg("sysroot")
                        .output()
                        .ok()
                        .and_then(|out| String::from_utf8(out.stdout).ok())
                        .map(|s| s.trim().to_owned())
                })
                .expect(
                    "need to specify SYSROOT env var during clippy compilation, or use rustup or multirust",
                )
        };

        rustc_driver::in_rustc_thread(|| {
            // this conditional check for the --sysroot flag is there so users can call
            // `cargo-clippy` directly
            // without having to pass --sysroot or anything
            let mut args: Vec<String> = if env::args().any(|s| s == "--sysroot") {
                env::args().collect()
            } else {
                env::args()
                    .chain(Some("--sysroot".to_owned()))
                    .chain(Some(sys_root))
                    .collect()
            };

            // this check ensures that dependencies are built but not linted and the final
            // crate is
            // linted but not built
            let clippy_enabled = env::args().any(|s| s == "--emit=metadata");

            if clippy_enabled {
                args.extend_from_slice(&["--cfg".to_owned(), r#"feature="cargo-clippy""#.to_owned()]);
            }

            let mut ccc = ClippyCompilerCalls::new(clippy_enabled);
            let (result, _) = rustc_driver::run_compiler(&args, &mut ccc, None, None);
            if let Err(CompileIncomplete::Errored(_)) = result {
                std::process::exit(1);
            }
        }).expect("rustc_thread failed");
    }
}

fn process<I>(old_args: I) -> Result<(), i32>
where
    I: Iterator<Item = String>,
{

    let mut args = vec!["rustc".to_owned()];

    let mut found_dashes = false;
    for arg in old_args {
        found_dashes |= arg == "--";
        args.push(arg);
    }
    if !found_dashes {
        args.push("--".to_owned());
    }
    args.push("--emit=metadata".to_owned());
    args.push("--cfg".to_owned());
    args.push(r#"feature="cargo-clippy""#.to_owned());

    let path = std::env::current_exe().expect("current executable path invalid");
    let exit_status = std::process::Command::new("cargo")
        .args(&args)
        .env("RUSTC", path)
        .spawn()
        .expect("could not run cargo")
        .wait()
        .expect("failed to wait for cargo?");

    if exit_status.success() {
        Ok(())
    } else {
        Err(exit_status.code().unwrap_or(-1))
    }
}
<commit_msg>Add help text for `--all`<commit_after>// error-pattern:yummy
#![feature(box_syntax)]
#![feature(rustc_private)]
#![allow(unknown_lints, missing_docs_in_private_items)]

extern crate clippy_lints;
extern crate getopts;
extern crate rustc;
extern crate rustc_driver;
extern crate rustc_errors;
extern crate rustc_plugin;
extern crate syntax;

use rustc_driver::{driver, Compilation, CompilerCalls, RustcDefaultCalls};
use rustc::session::{config, CompileIncomplete, Session};
use rustc::session::config::{ErrorOutputType, Input};
use std::collections::HashMap;
use std::path::PathBuf;
use std::process::{self, Command};
use syntax::ast;
use std::io::{self, Write};

extern crate cargo_metadata;

struct ClippyCompilerCalls {
    default: RustcDefaultCalls,
    run_lints: bool,
}

impl ClippyCompilerCalls {
    fn new(run_lints: bool) -> Self {
        ClippyCompilerCalls {
            default: RustcDefaultCalls,
            run_lints: run_lints,
        }
    }
}

impl<'a> CompilerCalls<'a> for ClippyCompilerCalls {
    fn early_callback(
        &mut self,
        matches: &getopts::Matches,
        sopts: &config::Options,
        cfg: &ast::CrateConfig,
        descriptions: &rustc_errors::registry::Registry,
        output: ErrorOutputType,
    ) -> Compilation {
        self.default.early_callback(
            matches,
            sopts,
            cfg,
            descriptions,
            output,
        )
    }
    fn no_input(
        &mut self,
        matches: &getopts::Matches,
        sopts: &config::Options,
        cfg: &ast::CrateConfig,
        odir: &Option<PathBuf>,
        ofile: &Option<PathBuf>,
        descriptions: &rustc_errors::registry::Registry,
    ) -> Option<(Input, Option<PathBuf>)> {
        self.default.no_input(
            matches,
            sopts,
            cfg,
            odir,
            ofile,
            descriptions,
        )
    }
    fn late_callback(
        &mut self,
        matches: &getopts::Matches,
        sess: &Session,
        input: &Input,
        odir: &Option<PathBuf>,
        ofile: &Option<PathBuf>,
    ) -> Compilation {
        self.default.late_callback(
            matches,
            sess,
            input,
            odir,
            ofile,
        )
    }
    fn build_controller(&mut self, sess: &Session, matches: &getopts::Matches) -> driver::CompileController<'a> {
        let mut control = self.default.build_controller(sess, matches);

        if self.run_lints {
            let old = std::mem::replace(&mut control.after_parse.callback, box |_| {});
            control.after_parse.callback = Box::new(move |state| {
                {
                    let mut registry = rustc_plugin::registry::Registry::new(
                        state.session,
                        state
                            .krate
                            .as_ref()
                            .expect(
                                "at this compilation stage \
                                                                                the krate must be parsed",
                            )
                            .span,
                    );
                    registry.args_hidden = Some(Vec::new());
                    clippy_lints::register_plugins(&mut registry);

                    let rustc_plugin::registry::Registry {
                        early_lint_passes,
                        late_lint_passes,
                        lint_groups,
                        llvm_passes,
                        attributes,
                        ..
                    } = registry;
                    let sess = &state.session;
                    let mut ls = sess.lint_store.borrow_mut();
                    for pass in early_lint_passes {
                        ls.register_early_pass(Some(sess), true, pass);
                    }
                    for pass in late_lint_passes {
                        ls.register_late_pass(Some(sess), true, pass);
                    }

                    for (name, to) in lint_groups {
                        ls.register_group(Some(sess), true, name, to);
                    }

                    sess.plugin_llvm_passes.borrow_mut().extend(llvm_passes);
                    sess.plugin_attributes.borrow_mut().extend(attributes);
                }
                old(state);
            });
        }

        control
    }
}

use std::path::Path;

const CARGO_CLIPPY_HELP: &str = r#"Checks a package to catch common mistakes and improve your Rust code.

Usage:
    cargo clippy [options] [--] [<opts>...]

Common options:
    -h, --help               Print this message
    --features               Features to compile for the package
    -V, --version            Print version info and exit
    --all                    Run over all packages in the current workspace

Other options are the same as `cargo rustc`.

To allow or deny a lint from the command line you can use `cargo clippy --`
with:

    -W --warn OPT       Set lint warnings
    -A --allow OPT      Set lint allowed
    -D --deny OPT       Set lint denied
    -F --forbid OPT     Set lint forbidden

The feature `cargo-clippy` is automatically defined for convenience. You can use
it to allow or deny lints from the code, eg.:

    #[cfg_attr(feature = "cargo-clippy", allow(needless_lifetimes))]
"#;

#[allow(print_stdout)]
fn show_help() {
    println!("{}", CARGO_CLIPPY_HELP);
}

#[allow(print_stdout)]
fn show_version() {
    println!("{}", env!("CARGO_PKG_VERSION"));
}

pub fn main() {
    use std::env;

    if env::var("CLIPPY_DOGFOOD").map(|_| true).unwrap_or(false) {
        panic!("yummy");
    }

    // Check for version and help flags even when invoked as 'cargo-clippy'
    if std::env::args().any(|a| a == "--help" || a == "-h") {
        show_help();
        return;
    }
    if std::env::args().any(|a| a == "--version" || a == "-V") {
        show_version();
        return;
    }

    if let Some("clippy") = std::env::args().nth(1).as_ref().map(AsRef::as_ref) {
        // this arm is executed on the initial call to `cargo clippy`

        let manifest_path_arg = std::env::args()
            .skip(2)
            .find(|val| val.starts_with("--manifest-path="));

        let mut metadata =
            if let Ok(metadata) = cargo_metadata::metadata(manifest_path_arg.as_ref().map(AsRef::as_ref)) {
                metadata
            } else {
                let _ = io::stderr().write_fmt(format_args!("error: Could not obtain cargo metadata.\n"));
                process::exit(101);
            };

        let manifest_path = manifest_path_arg.map(|arg| {
            Path::new(&arg["--manifest-path=".len()..])
                .canonicalize()
                .expect("manifest path could not be canonicalized")
        });

        let packages = if std::env::args().any(|a| a == "--all") {
            metadata.packages
        } else {
            let package_index = {
                if let Some(manifest_path) = manifest_path {
                    metadata.packages.iter().position(|package| {
                        let package_manifest_path = Path::new(&package.manifest_path)
                            .canonicalize()
                            .expect("package manifest path could not be canonicalized");
                        package_manifest_path == manifest_path
                    })
                } else {
                    let package_manifest_paths: HashMap<_, _> = metadata
                        .packages
                        .iter()
                        .enumerate()
                        .map(|(i, package)| {
                            let package_manifest_path = Path::new(&package.manifest_path)
                                .parent()
                                .expect("could not find parent directory of package manifest")
                                .canonicalize()
                                .expect("package directory cannot be canonicalized");
                            (package_manifest_path, i)
                        })
                        .collect();

                    let current_dir = std::env::current_dir()
                        .expect("could not read current directory")
                        .canonicalize()
                        .expect("current directory cannot be canonicalized");

                    let mut current_path: &Path = &current_dir;

                    // This gets the most-recent parent (the one that takes the fewest `cd ..`s to
                    // reach).
                    loop {
                        if let Some(&package_index) = package_manifest_paths.get(current_path) {
                            break Some(package_index);
                        } else {
                            // We'll never reach the filesystem root, because to get to this point in the
                            // code
                            // the call to `cargo_metadata::metadata` must have succeeded. So it's okay to
                            // unwrap the current path's parent.
                            current_path = current_path
                                .parent()
                                .unwrap_or_else(|| panic!("could not find parent of path {}", current_path.display()));
                        }
                    }
                }
            }.expect("could not find matching package");

            vec![metadata.packages.remove(package_index)]
        };

        for package in packages {
            let manifest_path = package.manifest_path;

            for target in package.targets {
                let args = std::env::args()
                    .skip(2)
                    .filter(|a| a != "--all" && !a.starts_with("--manifest-path="));

                let args = std::iter::once(format!("--manifest-path={}", manifest_path)).chain(args);
                if let Some(first) = target.kind.get(0) {
                    if target.kind.len() > 1 || first.ends_with("lib") {
                        if let Err(code) = process(std::iter::once("--lib".to_owned()).chain(args)) {
                            std::process::exit(code);
                        }
                    } else if ["bin", "example", "test", "bench"].contains(&&**first) {
                        if let Err(code) = process(
                            vec![format!("--{}", first), target.name]
                                .into_iter()
                                .chain(args),
                        ) {
                            std::process::exit(code);
                        }
                    }
                } else {
                    panic!("badly formatted cargo metadata: target::kind is an empty array");
                }
            }
        }
    } else {
        // this arm is executed when cargo-clippy runs `cargo rustc` with the `RUSTC`
        // env var set to itself

        let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
        let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
        let sys_root = if let (Some(home), Some(toolchain)) = (home, toolchain) {
            format!("{}/toolchains/{}", home, toolchain)
        } else {
            option_env!("SYSROOT")
                .map(|s| s.to_owned())
                .or_else(|| {
                    Command::new("rustc")
                        .arg("--print")
                        .arg("sysroot")
                        .output()
                        .ok()
                        .and_then(|out| String::from_utf8(out.stdout).ok())
                        .map(|s| s.trim().to_owned())
                })
                .expect(
                    "need to specify SYSROOT env var during clippy compilation, or use rustup or multirust",
                )
        };

        rustc_driver::in_rustc_thread(|| {
            // this conditional check for the --sysroot flag is there so users can call
            // `cargo-clippy` directly
            // without having to pass --sysroot or anything
            let mut args: Vec<String> = if env::args().any(|s| s == "--sysroot") {
                env::args().collect()
            } else {
                env::args()
                    .chain(Some("--sysroot".to_owned()))
                    .chain(Some(sys_root))
                    .collect()
            };

            // this check ensures that dependencies are built but not linted and the final
            // crate is
            // linted but not built
            let clippy_enabled = env::args().any(|s| s == "--emit=metadata");

            if clippy_enabled {
                args.extend_from_slice(&["--cfg".to_owned(), r#"feature="cargo-clippy""#.to_owned()]);
            }

            let mut ccc = ClippyCompilerCalls::new(clippy_enabled);
            let (result, _) = rustc_driver::run_compiler(&args, &mut ccc, None, None);
            if let Err(CompileIncomplete::Errored(_)) = result {
                std::process::exit(1);
            }
        }).expect("rustc_thread failed");
    }
}

fn process<I>(old_args: I) -> Result<(), i32>
where
    I: Iterator<Item = String>,
{

    let mut args = vec!["rustc".to_owned()];

    let mut found_dashes = false;
    for arg in old_args {
        found_dashes |= arg == "--";
        args.push(arg);
    }
    if !found_dashes {
        args.push("--".to_owned());
    }
    args.push("--emit=metadata".to_owned());
    args.push("--cfg".to_owned());
    args.push(r#"feature="cargo-clippy""#.to_owned());

    let path = std::env::current_exe().expect("current executable path invalid");
    let exit_status = std::process::Command::new("cargo")
        .args(&args)
        .env("RUSTC", path)
        .spawn()
        .expect("could not run cargo")
        .wait()
        .expect("failed to wait for cargo?");

    if exit_status.success() {
        Ok(())
    } else {
        Err(exit_status.code().unwrap_or(-1))
    }
}
<|endoftext|>


<commit_before>use std::fmt;
use std::io;
use std::io::prelude::*;

use std::str::Chars;

#[derive(Debug)]
enum Op {
    Add,
}

#[derive(Debug)]
enum Value {
    Integer(u32),
}

impl Value {
    fn to_string(&self) -> String {
        match *self {
            Value::Integer(n) => {
                n.to_string()
            }
        }
    }
}

#[derive(Debug)]
enum Expr {
    Value(Value),
    BinOp(Op, Box<Expr>, Box<Expr>)
}

impl Expr {
    fn to_value_string(&self) -> String {
        match *self {
            Expr::Value(ref v) => v.to_string(),
            _ => panic!(),
        }
    }
}

fn parse_add(line: String) -> Expr {
    let mut chars = line.chars().clone();

    let operand1 = chars.next();
    let operator = chars.next();
    let operand2 = chars.next();

    match (operand1, operand2) {
        (Some(op1), Some(op2)) => {
            Expr::BinOp(
                Op::Add,
                Box::new(Expr::Value(Value::Integer(op1.to_digit(10).unwrap()))),
                Box::new(Expr::Value(Value::Integer(op2.to_digit(10).unwrap()))),
            )
        }
        _ => Expr::Value(Value::Integer(-1))
    }
}

fn eval(e: Expr) -> Expr {
    match e {
        Expr::BinOp(Op::Add, v1, v2) => {
            match (*v1, *v2) {
                (Expr::Value(Value::Integer(n1)), Expr::Value(Value::Integer(n2))) => {
                    Expr::Value(Value::Integer(n1 + n2))
                }
                _ => panic!()
            }
        }
        _ => panic!()
    }
}

fn eval_expr(line: String) -> String {
    let expr = parse_add(line);
    let v: Expr = eval(expr);

    return v.to_value_string();
}

fn main() {
    loop {
        print!("calc> ");
        io::stdout().flush();

        let mut input = String::new();
        match io::stdin().read_line(&mut input) {
            Ok(bytes_read) => {
                println!("{}", eval_expr(input))
            },
            Err(e) => print!("error: {}", e)
        }
        io::stdout().flush();
    }
}
<commit_msg>add negative and multi-digit numbers<commit_after>use std::fmt;
use std::io;
use std::io::prelude::*;

use std::str::Chars;

#[derive(Debug)]
enum Op {
    Add,
}

#[derive(Debug)]
enum Value {
    Integer(isize),
}

impl Value {
    fn to_string(&self) -> String {
        match *self {
            Value::Integer(n) => {
                n.to_string()
            }
        }
    }
}

#[derive(Debug)]
enum Expr {
    Value(Value),
    BinOp(Op, Box<Expr>, Box<Expr>)
}

fn parse_add(line: String) -> Expr {
    let mut chars = line.chars().clone();

    let words: Vec<&str> = line.split('+').collect();

    for i in (0..words.len() / 2) {
        let index = 2*i;

        let n1 = words[index].trim();
        let n2 = words[index + 1].trim();

        let i1: isize = n1
            .parse()
            .ok()
            .expect("Wanted an integer");

        let i2: isize = n2
            .parse()
            .ok()
            .expect("Wanted an integer");

        let e = Expr::BinOp(
            Op::Add,
            Box::new(Expr::Value(Value::Integer(i1))),
            Box::new(Expr::Value(Value::Integer(i2))),
        );

        return e;
    }

    panic!()
}

fn eval(e: Expr) -> Expr {
    match e {
        Expr::BinOp(Op::Add, v1, v2) => {
            match (*v1, *v2) {
                (Expr::Value(Value::Integer(n1)), Expr::Value(Value::Integer(n2))) => {
                    Expr::Value(Value::Integer(n1 + n2))
                }
                _ => panic!()
            }
        }
        _ => panic!()
    }
}

fn eval_expr(line: String) -> String {
    let expr: Expr = parse_add(line);
    let v: Expr = eval(expr);

    match v {
        Expr::Value(v) => v.to_string(),
        _ => panic!(),
    }
}

fn main() {
    loop {
        print!("calc> ");
        io::stdout().flush();

        let mut input = String::new();
        match io::stdin().read_line(&mut input) {
            Ok(bytes_read) => {
                println!("{}", eval_expr(input))
            },
            Err(e) => print!("error: {}", e)
        }
        io::stdout().flush();
    }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;

#[deriving(PartialEq, Show)]
pub struct Post {
    header: HashMap<String, String>,
    content: String
}

impl Post {
    pub fn new(header: HashMap<String, String>, content: &str) -> Post {
        Post { header: header, content: content.to_string() }
    }
}
<commit_msg>Add method to retrieve content from Post<commit_after>use std::collections::HashMap;

#[deriving(PartialEq, Show)]
pub struct Post {
    header: HashMap<String, String>,
    content: String
}

impl Post {
    pub fn new(header: HashMap<String, String>, content: &str) -> Post {
        Post { header: header, content: content.to_string() }
    }

    pub fn content(&self) -> &str {
        self.content.as_slice()
    }
}
<|endoftext|>


<commit_before>use num::{Signed, Unsigned};

#[inline(always)]
pub fn inverse<'a, 'b, T: Signed>(out: &'a mut [T; 4], a: &'b [T; 4]) -> &'a mut [T; 4] {
    out[0] = -a[0];
    out[1] = -a[1];
    out[2] = -a[2];
    out[3] = -a[3];
    out
}
#[test]
fn test_inverse() {
    let mut v = [0, 0, 0, 0];
    inverse(&mut v, &[1, 1, 1, 1]);
    assert!(v[0] == -1);
    assert!(v[1] == -1);
    assert!(v[2] == -1);
    assert!(v[3] == -1);
}

#[inline(always)]
pub fn lerp<'a, 'b, T: Unsigned, N: Unsigned>(out: &'a mut [T; 4], a: &'b [T; 4], b: &'b [T; 4], t: N) -> &'a mut [T; 4] {
    let t_f64 = t.to_f64();
    out[0] = T::from_f64((a[0] + (b[0] - a[0])).to_f64() * t_f64);
    out[1] = T::from_f64((a[1] + (b[1] - a[1])).to_f64() * t_f64);
    out[2] = T::from_f64((a[2] + (b[2] - a[2])).to_f64() * t_f64);
    out[3] = T::from_f64((a[3] + (b[3] - a[3])).to_f64() * t_f64);
    out
}
#[test]
fn test_lerp() {
    let mut v = [0.0, 0.0, 0.0, 0.0];
    lerp(&mut v, &[0.0, 0.0, 0.0, 0.0], &[1.0, 1.0, 1.0, 1.0], 0.5);
    assert!(v[0] == 0.5);
    assert!(v[1] == 0.5);
    assert!(v[2] == 0.5);
    assert!(v[3] == 0.5);
}

#[inline(always)]
pub fn min<'a, 'b, T: Unsigned>(out: &'a mut [T; 4], a: &'b [T; 4], b: &'b [T; 4]) -> &'a mut [T; 4] {
    out[0] = if b[0] < a[0] {b[0]} else {a[0]};
    out[1] = if b[1] < a[1] {b[1]} else {a[1]};
    out[2] = if b[2] < a[2] {b[2]} else {a[2]};
    out[3] = if b[3] < a[3] {b[3]} else {a[3]};
    out
}
#[test]
fn test_min() {
    let mut v = [0, 0, 0, 0];
    min(&mut v, &[1, 0, 1, 0], &[0, 1, 0, 1]);
    assert!(v == [0, 0, 0, 0]);
}

#[inline(always)]
pub fn max<'a, 'b, T: Unsigned>(out: &'a mut [T; 4], a: &'b [T; 4], b: &'b [T; 4]) -> &'a mut [T; 4] {
    out[0] = if b[0] > a[0] {b[0]} else {a[0]};
    out[1] = if b[1] > a[1] {b[1]} else {a[1]};
    out[2] = if b[2] > a[2] {b[2]} else {a[2]};
    out[3] = if b[3] > a[3] {b[3]} else {a[3]};
    out
}
#[test]
fn test_max() {
    let mut v = [0, 0, 0, 0];
    max(&mut v, &[1, 0, 1, 0], &[0, 1, 0, 1]);
    assert!(v == [1, 1, 1, 1]);
}

#[inline(always)]
pub fn clamp<'a, 'b, T: Unsigned>(out: &'a mut [T; 4], a: &'b [T; 4], min: &'b [T; 4], max: &'b [T; 4]) -> &'a mut [T; 4] {
    out[0] = if a[0] < min[0] {min[0]} else if a[0] > max[0] {max[0]} else {a[0]};
    out[1] = if a[1] < min[1] {min[1]} else if a[1] > max[1] {max[1]} else {a[1]};
    out[2] = if a[2] < min[2] {min[2]} else if a[2] > max[2] {max[2]} else {a[2]};
    out[3] = if a[3] < min[3] {min[3]} else if a[3] > max[3] {max[3]} else {a[3]};
    out
}
#[test]
fn test_clamp() {
    let mut v = [0, 0, 0, 0];
    clamp(&mut v, &[2, 2, 2, 2], &[0, 0, 0, 0], &[1, 1, 1, 1]);
    assert!(v == [1, 1, 1, 1]);
}

#[inline(always)]
pub fn eq<'a, T: Unsigned>(a: &'a [T; 4], b: &'a [T; 4]) -> bool {
    !nq(a, b)
}

#[inline(always)]
pub fn nq<'a, T: Unsigned>(a: &'a [T; 4], b: &'a [T; 4]) -> bool {
    !a[0].approx_eq(b[0]) ||
    !a[1].approx_eq(b[1]) ||
    !a[2].approx_eq(b[2]) ||
    !a[3].approx_eq(b[3])
}
#[test]
fn test_nq() {
    assert_eq!(nq(&[1f32, 1f32, 1f32, 1f32], &[1f32, 1f32, 1f32, 1f32]), false);
    assert_eq!(nq(&[0f32, 0f32, 0f32, 0f32], &[1f32, 1f32, 1f32, 1f32]), true);
}
<commit_msg>updates<commit_after>use num::{Signed, Unsigned};

#[inline(always)]
pub fn inverse<'a, 'b, T: Signed>(out: &'a mut [T; 4], a: &'b [T; 4]) -> &'a mut [T; 4] {
    out[0] = -a[0];
    out[1] = -a[1];
    out[2] = -a[2];
    out[3] = -a[3];
    out
}
#[test]
fn test_inverse() {
    let mut v = [0, 0, 0, 0];
    inverse(&mut v, &[1, 1, 1, 1]);
    assert!(v[0] == -1);
    assert!(v[1] == -1);
    assert!(v[2] == -1);
    assert!(v[3] == -1);
}

#[inline(always)]
pub fn lerp<'a, 'b, T: Unsigned, N: Unsigned>(out: &'a mut [T; 4], a: &'b [T; 4], b: &'b [T; 4], t: N) -> &'a mut [T; 4] {
    let t_f64 = t.to_f64();
    out[0] = T::from_f64((a[0] + (b[0] - a[0])).to_f64() * t_f64);
    out[1] = T::from_f64((a[1] + (b[1] - a[1])).to_f64() * t_f64);
    out[2] = T::from_f64((a[2] + (b[2] - a[2])).to_f64() * t_f64);
    out[3] = T::from_f64((a[3] + (b[3] - a[3])).to_f64() * t_f64);
    out
}
#[test]
fn test_lerp() {
    let mut v = [0.0, 0.0, 0.0, 0.0];
    lerp(&mut v, &[0.0, 0.0, 0.0, 0.0], &[1.0, 1.0, 1.0, 1.0], 0.5);
    assert!(v[0] == 0.5);
    assert!(v[1] == 0.5);
    assert!(v[2] == 0.5);
    assert!(v[3] == 0.5);
}

#[inline(always)]
pub fn min<'a, 'b, T: Unsigned>(out: &'a mut [T; 4], a: &'b [T; 4], b: &'b [T; 4]) -> &'a mut [T; 4] {
    out[0] = if b[0] < a[0] {b[0]} else {a[0]};
    out[1] = if b[1] < a[1] {b[1]} else {a[1]};
    out[2] = if b[2] < a[2] {b[2]} else {a[2]};
    out[3] = if b[3] < a[3] {b[3]} else {a[3]};
    out
}
#[test]
fn test_min() {
    let mut v = [0, 0, 0, 0];
    min(&mut v, &[1, 0, 1, 0], &[0, 1, 0, 1]);
    assert!(v == [0, 0, 0, 0]);
}

#[inline(always)]
pub fn max<'a, 'b, T: Unsigned>(out: &'a mut [T; 4], a: &'b [T; 4], b: &'b [T; 4]) -> &'a mut [T; 4] {
    out[0] = if b[0] > a[0] {b[0]} else {a[0]};
    out[1] = if b[1] > a[1] {b[1]} else {a[1]};
    out[2] = if b[2] > a[2] {b[2]} else {a[2]};
    out[3] = if b[3] > a[3] {b[3]} else {a[3]};
    out
}
#[test]
fn test_max() {
    let mut v = [0, 0, 0, 0];
    max(&mut v, &[1, 0, 1, 0], &[0, 1, 0, 1]);
    assert!(v == [1, 1, 1, 1]);
}

#[inline(always)]
pub fn clamp<'a, 'b, T: Unsigned>(out: &'a mut [T; 4], a: &'b [T; 4], min: &'b [T; 4], max: &'b [T; 4]) -> &'a mut [T; 4] {
    out[0] = if a[0] < min[0] {min[0]} else if a[0] > max[0] {max[0]} else {a[0]};
    out[1] = if a[1] < min[1] {min[1]} else if a[1] > max[1] {max[1]} else {a[1]};
    out[2] = if a[2] < min[2] {min[2]} else if a[2] > max[2] {max[2]} else {a[2]};
    out[3] = if a[3] < min[3] {min[3]} else if a[3] > max[3] {max[3]} else {a[3]};
    out
}
#[test]
fn test_clamp() {
    let mut v = [0, 0, 0, 0];
    clamp(&mut v, &[2, 2, 2, 2], &[0, 0, 0, 0], &[1, 1, 1, 1]);
    assert!(v == [1, 1, 1, 1]);
}

#[inline(always)]
pub fn eq<'a, T: Unsigned>(a: &'a [T; 4], b: &'a [T; 4]) -> bool {
    !ne(a, b)
}

#[inline(always)]
pub fn ne<'a, T: Unsigned>(a: &'a [T; 4], b: &'a [T; 4]) -> bool {
    !a[0].approx_eq(b[0]) ||
    !a[1].approx_eq(b[1]) ||
    !a[2].approx_eq(b[2]) ||
    !a[3].approx_eq(b[3])
}
#[test]
fn test_ne() {
    assert_eq!(ne(&[1f32, 1f32, 1f32, 1f32], &[1f32, 1f32, 1f32, 1f32]), false);
    assert_eq!(ne(&[0f32, 0f32, 0f32, 0f32], &[1f32, 1f32, 1f32, 1f32]), true);
}
<|endoftext|>


<commit_before>use std::sync::Arc;
use stemmer;

pub struct StemmerTokenStream<TailTokenStream>
    where TailTokenStream: TokenStream {
    tail: TailTokenStream,
    stemmer: Arc<stemmer::Stemmer>,
}

impl<TailTokenStream> TokenStream for StemmerTokenStream<TailTokenStream>
    where TailTokenStream: TokenStream {

    fn token(&self) -> &Token {
        self.tail.token()
    }

    fn token_mut(&mut self) -> &mut Token {
        self.tail.token_mut()
    }

    fn advance(&mut self) -> bool {
        if self.tail.advance() {
            // self.tail.token_mut().term.make_ascii_lowercase();
            let new_str = self.stemmer.stem_str(&self.token().term);
            true
        }
        else {
            false
        }
    }

}

impl<TailTokenStream> StemmerTokenStream<TailTokenStream>
    where TailTokenStream: TokenStream {

    fn wrap(stemmer: Arc<stemmer::Stemmer>, tail: TailTokenStream) -> StemmerTokenStream<TailTokenStream> {
        StemmerTokenStream {
            tail,
            stemmer,
        }
    }
}<commit_msg>WTF is this file doing here (#622)<commit_after><|endoftext|>