<commit_before>extern crate ansi_term;
#[macro_use]
extern crate clap;
extern crate hyper;
extern crate libzou;
extern crate num_cpus;

use clap::{App, Arg};
use libzou::cargo_helper::get_cargo_info;
use libzou::download::download_chunks;
use libzou::filesize::format_filesize;
use libzou::util::prompt_user;
use libzou::write::OutputFileWriter;
#[macro_use]
mod logs;
use std::fs::{File, remove_file};
use std::path::Path;
use std::process::exit;

// static DEFAULT_FILENAME: &'static str = "index.html";

fn main() {

    // Parse arguments

    let argparse = App::new("Zou")
        .about("Zou, a simple and fast download accelerator, written in Rust.")
        .version(crate_version!())
        .arg(Arg::with_name("file")
                 .long("file")
                 .short("f")
                 .takes_value(true)
                 .help("The local file to save the remote content file"))
        .arg(Arg::with_name("threads")
                 .long("threads")
                 .short("t")
                 .takes_value(true)
                 .help("Threads which can use to download"))
        .arg(Arg::with_name("debug")
                 .long("debug")
                 .short("d")
                 .help("Active the debug mode"))
        .arg(Arg::with_name("force")
                 .long("force")
                 .help("Assume Yes to all queries and do not prompt"))
        .arg(Arg::with_name("mirrors")
                 .long("mirrors")
                 .short("m")
                 .multiple(true)
                 .takes_value(true)
                 .help("Download using a list of mirrors - the list of mirrors is used WITH the original URL"))
        .arg(Arg::with_name("url")
            .index(1)
            //.multiple(true)
            .required(true))
        .get_matches();

    // Get informations from arguments

    // Get the URL as a Path structure
    let url = Path::new(argparse.value_of("url").unwrap());

    // Set the mirrors vectors
    let mut servers_urls: Vec<&str> = match url.parent() {
        Some(parent) => vec![parent.to_str().unwrap()],
        None => vec![],
    };
    // Set given mirrors
    if argparse.is_present("mirrors") {
        let mirrors_vec: Vec<&str> = argparse.values_of("mirrors").unwrap().collect();
        for mirror in mirrors_vec {
            servers_urls.push(mirror);
        }
    }

    // Get the path filename
    let filename = url.file_name().unwrap().to_str().unwrap();

    // Check if multi-threaded download is possible
    let mut threads: usize = value_t!(argparse, "threads", usize)
        .and_then(|v| if v != 0 {
                      Ok(v)
                  } else {
                      Err(clap::Error::with_description("Cannot download a file using 0 thread",
                                                        clap::ErrorKind::InvalidValue))
                  })
        .unwrap_or(num_cpus::get_physical());

    if argparse.is_present("debug") {
        info!(&format!("version: {}", crate_version!()));
        info!(&format!("file: {}", filename));
        info!(&format!("threads: {}", threads));
    }

    let local_path = Path::new(&filename);

    if local_path.exists() {
        if local_path.is_dir() {
            epanic!("The local path to store the remote content is already exists, \
                        and is a directory!");
        }
        if !argparse.is_present("force") {
            let user_input = prompt_user("The path to store the file already exists! \
                                          Do you want to override it? [y/N]");
            if !(user_input == "y" || user_input == "Y") {
                exit(0);
            }
        } else {
            warning!("The path to store the file already exists! \
                                 It is going to be overriden.");
        }
    }

    let cargo_info = get_cargo_info(filename, servers_urls).expect("fail to parse url");
    info!(&format!("Remote content length: {}",
                   format_filesize(cargo_info.content_length)));

    let local_file = File::create(local_path).expect("[ERROR] Cannot create a file !");

    local_file
        .set_len(cargo_info.content_length)
        .expect("Cannot extend local file !");
    let out_file = OutputFileWriter::new(local_file);

    // If the server does not accept PartialContent status, download the remote file
    // using only one thread
    if !cargo_info.accept_partialcontent {
        warning!("The remote server does not accept PartialContent status! \
                             Downloading the remote file using one thread.");
        threads = 1;
    }

    if download_chunks(cargo_info, out_file, threads as u64, filename) {
        ok!(&format!("Your download is available in {}",
                     local_path.to_str().unwrap()));
    } else {
        // If the file is not ok, delete it from the file system
        error!("Download failed! An error occured - erasing file... ");
        if remove_file(local_path).is_err() {
            error!("Cannot remove downloaded file!");
        }
    }

}
<commit_msg>Format changes<commit_after>extern crate ansi_term;
#[macro_use]
extern crate clap;
extern crate hyper;
extern crate libzou;
extern crate num_cpus;

use clap::{App, Arg};
use libzou::cargo_helper::get_cargo_info;
use libzou::download::download_chunks;
use libzou::filesize::format_filesize;
use libzou::util::prompt_user;
use libzou::write::OutputFileWriter;
#[macro_use]
mod logs;
use std::fs::{File, remove_file};
use std::path::Path;
use std::process::exit;

// static DEFAULT_FILENAME: &'static str = "index.html";

fn main() {

    // Parse arguments

    let argparse = App::new("Zou")
        .about("Zou, a simple and fast download accelerator, written in Rust.")
        .version(crate_version!())
        .arg(Arg::with_name("file")
                 .long("file")
                 .short("f")
                 .takes_value(true)
                 .help("The local file to save the remote content file"))
        .arg(Arg::with_name("threads")
                 .long("threads")
                 .short("t")
                 .takes_value(true)
                 .help("Threads which can use to download"))
        .arg(Arg::with_name("debug")
                 .long("debug")
                 .short("d")
                 .help("Active the debug mode"))
        .arg(Arg::with_name("force")
                 .long("force")
                 .help("Assume Yes to all queries and do not prompt"))
        .arg(Arg::with_name("mirrors")
                 .long("mirrors")
                 .short("m")
                 .multiple(true)
                 .takes_value(true)
                 .help("Download using a list of mirrors - the list of mirrors is used WITH the original URL"))
        .arg(Arg::with_name("url")
            .index(1)
            //.multiple(true)
            .required(true))
        .get_matches();

    // Get informations from arguments

    // Get the URL as a Path structure
    let url = Path::new(argparse.value_of("url").unwrap());

    // Set the mirrors vectors
    let mut servers_urls: Vec<&str> = match url.parent() {
        Some(parent) => vec![parent.to_str().unwrap()],
        None => vec![],
    };
    // Set given mirrors
    if argparse.is_present("mirrors") {
        let mirrors_vec: Vec<&str> = argparse.values_of("mirrors").unwrap().collect();
        for mirror in mirrors_vec {
            servers_urls.push(mirror);
        }
    }

    // Get the path filename
    let filename = url.file_name().unwrap().to_str().unwrap();

    // Check if multi-threaded download is possible
    let mut threads: usize = value_t!(argparse, "threads", usize)
        .and_then(|v| if v != 0 {
            Ok(v)
        } else {
            Err(clap::Error::with_description(
                "Cannot download a file using 0 thread",
                clap::ErrorKind::InvalidValue,
            ))
        })
        .unwrap_or(num_cpus::get_physical());

    if argparse.is_present("debug") {
        info!(&format!("version: {}", crate_version!()));
        info!(&format!("file: {}", filename));
        info!(&format!("threads: {}", threads));
    }

    let local_path = Path::new(&filename);

    if local_path.exists() {
        if local_path.is_dir() {
            epanic!(
                "The local path to store the remote content is already exists, \
                        and is a directory!"
            );
        }
        if !argparse.is_present("force") {
            let user_input = prompt_user(
                "The path to store the file already exists! \
                                          Do you want to override it? [y/N]",
            );
            if !(user_input == "y" || user_input == "Y") {
                exit(0);
            }
        } else {
            warning!(
                "The path to store the file already exists! \
                                 It is going to be overriden."
            );
        }
    }

    let cargo_info = get_cargo_info(filename, servers_urls).expect("fail to parse url");
    info!(&format!(
        "Remote content length: {}",
        format_filesize(cargo_info.content_length)
    ));

    let local_file = File::create(local_path).expect("[ERROR] Cannot create a file !");

    local_file.set_len(cargo_info.content_length).expect(
        "Cannot extend local file !",
    );
    let out_file = OutputFileWriter::new(local_file);

    // If the server does not accept PartialContent status, download the remote file
    // using only one thread
    if !cargo_info.accept_partialcontent {
        warning!(
            "The remote server does not accept PartialContent status! \
                             Downloading the remote file using one thread."
        );
        threads = 1;
    }

    if download_chunks(cargo_info, out_file, threads as u64, filename) {
        ok!(&format!(
            "Your download is available in {}",
            local_path.to_str().unwrap()
        ));
    } else {
        // If the file is not ok, delete it from the file system
        error!("Download failed! An error occured - erasing file... ");
        if remove_file(local_path).is_err() {
            error!("Cannot remove downloaded file!");
        }
    }

}
<|endoftext|>


<commit_before>#[macro_use] extern crate lazy_static;
extern crate deploy;
extern crate dotenv;
extern crate pencil;

use deploy::*;
use dotenv::dotenv;
use pencil::{Pencil, Response, Request, PencilResult};
use std::env;
use std::path::Path;
use std::process::{Stdio, Command};
use std::thread;

lazy_static! {
  pub static ref SECRET: String = env::var("TENJAVA_DEPLOY_SECRET").expect("missing TENJAVA_DEPLOY_SECRET");
  pub static ref PROD_REPO: String = env::var("TENJAVA_WEBSITE_PROD_REPO").expect("missing TENJAVA_WEBSITE_PROD_REPO");
  pub static ref DEV_REPO: String = env::var("TENJAVA_WEBSITE_DEV_REPO").expect("missing TENJAVA_WEBSITE_DEV_REPO");
}

fn deploy_webhook(r: &mut Request) -> PencilResult {
  println!("receiving a deploy request");
  let (signature, event) = {
    let headers = r.headers();
    let signature: &XHubSignature = match headers.get() {
      Some(x) => x,
      None => {
        println!("  it was missing a signature header");
        println!("  done");
        let mut res = Response::new("missing a signature header");
        res.status_code = 401;
        return Ok(res);
      }
    };
    let event: &XGitHubEvent = match headers.get() {
      Some(x) => x,
      None => {
        println!("  it was missing an event header");
        println!("  done");
        let mut res = Response::new("missing an event header");
        res.status_code = 401;
        return Ok(res);
      }
    };
    (signature.clone(), event.clone())
  };
  if *event != "push" {
    println!("  it was not a push event");
    println!("  done");
    return Ok("not a push event, but thanks anyway".into());
  }
  let signature_check = match deploy::check_signature(r, &signature, &SECRET) {
    Ok(x) => x,
    Err(e) => {
      println!("  an error occurred while checking the signature: {}", e);
      println!("  done");
      let mut res = Response::new(format!("an error occurred while checking signature: {}", e));
      res.status_code = 500;
      return Ok(res);
    }
  };
  if !signature_check {
    println!("  it had an invalid signature");
    println!("  done");
    let mut res = Response::new("invalid signature");
    res.status_code = 401;
    return Ok(res);
  }
  println!("  everything checks out");
  println!("  checking branch");
  let branch = match deploy::get_branch(r) {
    Ok(b) => b,
    Err(e) => {
      println!("  an error occurred while checking branch: {}", e);
      println!("  done");
      let mut res = Response::new(format!("couldn't get branch: {}", e));
      res.status_code = 401;
      return Ok(res);
    }
  };
  println!("  spawning update thread");
  update_repo(&branch);
  println!("  thread spawned");
  println!("  done");
  println!("");
  Ok("deploy initiated".into())
}

fn update_repo(branch: &Branch) {
  let repo_path = match *branch {
    Branch::Master => &*PROD_REPO,
    Branch::Dev => &*DEV_REPO
  };
  thread::spawn(move || {
    let status = Command::new("git")
      .arg("pull")
      .stdout(Stdio::null())
      .current_dir(Path::new(repo_path))
      .status()
      .expect("could not start git");
    if !status.success() {
      match status.code() {
        Some(code) => {
          println!("git exited with code {}", code);
        },
        None => {
          println!("git exited with an unknown status code");
        }
      }
    } else {
      println!("git exited successfully")
    }
  });
}

fn inner() -> i32 {
  // load up env
  dotenv().ok();

  // check env
  if (&*SECRET).is_empty() {
    println!("oops, no TENJAVA_DEPLOY_SECRET was specified");
    return 1;
  }
  if (&*PROD_REPO).is_empty() {
    println!("oops, no TENJAVA_WEBSITE_PROD_REPO was specified");
    return 1;
  }
  if (&*DEV_REPO).is_empty() {
    println!("oops, no TENJAVA_WEBSITE_DEV_REPO was specified");
    return 1;
  }
  let mut app = Pencil::new("/static");
  app.post("/deploy", "deploy", deploy_webhook);
  app.run("0.0.0.0:32260");
  0
}

fn main() {
  let exit_code = inner();
  std::process::exit(exit_code);
}
<commit_msg>fix: use 500 error code<commit_after>#[macro_use] extern crate lazy_static;
extern crate deploy;
extern crate dotenv;
extern crate pencil;

use deploy::*;
use dotenv::dotenv;
use pencil::{Pencil, Response, Request, PencilResult};
use std::env;
use std::path::Path;
use std::process::{Stdio, Command};
use std::thread;

lazy_static! {
  pub static ref SECRET: String = env::var("TENJAVA_DEPLOY_SECRET").expect("missing TENJAVA_DEPLOY_SECRET");
  pub static ref PROD_REPO: String = env::var("TENJAVA_WEBSITE_PROD_REPO").expect("missing TENJAVA_WEBSITE_PROD_REPO");
  pub static ref DEV_REPO: String = env::var("TENJAVA_WEBSITE_DEV_REPO").expect("missing TENJAVA_WEBSITE_DEV_REPO");
}

fn deploy_webhook(r: &mut Request) -> PencilResult {
  println!("receiving a deploy request");
  let (signature, event) = {
    let headers = r.headers();
    let signature: &XHubSignature = match headers.get() {
      Some(x) => x,
      None => {
        println!("  it was missing a signature header");
        println!("  done");
        let mut res = Response::new("missing a signature header");
        res.status_code = 401;
        return Ok(res);
      }
    };
    let event: &XGitHubEvent = match headers.get() {
      Some(x) => x,
      None => {
        println!("  it was missing an event header");
        println!("  done");
        let mut res = Response::new("missing an event header");
        res.status_code = 401;
        return Ok(res);
      }
    };
    (signature.clone(), event.clone())
  };
  if *event != "push" {
    println!("  it was not a push event");
    println!("  done");
    return Ok("not a push event, but thanks anyway".into());
  }
  let signature_check = match deploy::check_signature(r, &signature, &SECRET) {
    Ok(x) => x,
    Err(e) => {
      println!("  an error occurred while checking the signature: {}", e);
      println!("  done");
      let mut res = Response::new(format!("an error occurred while checking signature: {}", e));
      res.status_code = 500;
      return Ok(res);
    }
  };
  if !signature_check {
    println!("  it had an invalid signature");
    println!("  done");
    let mut res = Response::new("invalid signature");
    res.status_code = 401;
    return Ok(res);
  }
  println!("  everything checks out");
  println!("  checking branch");
  let branch = match deploy::get_branch(r) {
    Ok(b) => b,
    Err(e) => {
      println!("  an error occurred while checking branch: {}", e);
      println!("  done");
      let mut res = Response::new(format!("couldn't get branch: {}", e));
      res.status_code = 500;
      return Ok(res);
    }
  };
  println!("  spawning update thread");
  update_repo(&branch);
  println!("  thread spawned");
  println!("  done");
  println!("");
  Ok("deploy initiated".into())
}

fn update_repo(branch: &Branch) {
  let repo_path = match *branch {
    Branch::Master => &*PROD_REPO,
    Branch::Dev => &*DEV_REPO
  };
  thread::spawn(move || {
    let status = Command::new("git")
      .arg("pull")
      .stdout(Stdio::null())
      .current_dir(Path::new(repo_path))
      .status()
      .expect("could not start git");
    if !status.success() {
      match status.code() {
        Some(code) => {
          println!("git exited with code {}", code);
        },
        None => {
          println!("git exited with an unknown status code");
        }
      }
    } else {
      println!("git exited successfully")
    }
  });
}

fn inner() -> i32 {
  // load up env
  dotenv().ok();

  // check env
  if (&*SECRET).is_empty() {
    println!("oops, no TENJAVA_DEPLOY_SECRET was specified");
    return 1;
  }
  if (&*PROD_REPO).is_empty() {
    println!("oops, no TENJAVA_WEBSITE_PROD_REPO was specified");
    return 1;
  }
  if (&*DEV_REPO).is_empty() {
    println!("oops, no TENJAVA_WEBSITE_DEV_REPO was specified");
    return 1;
  }
  let mut app = Pencil::new("/static");
  app.post("/deploy", "deploy", deploy_webhook);
  app.run("0.0.0.0:32260");
  0
}

fn main() {
  let exit_code = inner();
  std::process::exit(exit_code);
}
<|endoftext|>


<commit_before>extern crate byteorder;
extern crate crc;

use std::fs::File;
use std::io::{Read, Result, Error, Seek, SeekFrom};
use std::io::ErrorKind::Other;

use byteorder::{LittleEndian, ByteOrder};

use crc::{crc32, Hasher32};

const LABEL_SCAN_SECTORS: usize = 4;
const MYPATH: &'static str = "/dev/mapper/luks-291e9250-200e-4c36-8e5e-66aa257669ed";
const ID_LEN: usize = 32;
const MDA_MAGIC: &'static [u8] = b"\x20\x4c\x56\x4d\x32\x20\x78\x5b\x35\x41\x25\x72\x30\x4e\x2a\x3e";
const INITIAL_CRC: u32 = 0xf597a6cf;
const SECTOR_SIZE: usize = 512;

#[derive(Debug)]
struct Label {
    id: String,
    sector: u64,
    crc: u32,
    offset: u32,
    label: String,
}

#[derive(Debug)]
struct PvArea {
    offset: u64,
    size: u64,
}

#[derive(Debug)]
struct PvHeader {
    uuid: String,
    size: u64, // in bytes
    ext_version: u32,
    ext_flags: u32,
    data_areas: Vec<PvArea>,
    metadata_areas: Vec<PvArea>,
    bootloader_areas: Vec<PvArea>,
}

fn get_label(buf: &[u8]) -> Result<Label> {
    for x in 0..LABEL_SCAN_SECTORS {
        let sec_buf = &buf[x*SECTOR_SIZE..x*SECTOR_SIZE+SECTOR_SIZE];
        if &sec_buf[..8] == b"LABELONE" {
            let crc = LittleEndian::read_u32(&sec_buf[16..20]);
            crc32_ok(crc, &sec_buf[20..SECTOR_SIZE]);

            let sector = LittleEndian::read_u64(&sec_buf[8..16]);
            if sector != x as u64 {
                println!("sector field is {} in sector {}", sector, x);
            }

            return Ok(Label{
                id: String::from_utf8_lossy(&sec_buf[..8]).into_owned(),
                sector: sector,
                crc: crc,
                offset: LittleEndian::read_u32(&sec_buf[20..24]) + (x*SECTOR_SIZE as usize) as u32,
                label: String::from_utf8_lossy(&sec_buf[24..32]).into_owned(),
            })
        }
    }

    Err(Error::new(Other, "bad"))
}

struct PvAreaIter<'a> {
    area: &'a[u8],
}

fn iter_pv_area<'a>(buf: &'a[u8]) -> PvAreaIter<'a> {
    PvAreaIter { area: buf }
}

impl<'a> Iterator for PvAreaIter<'a> {
    type Item = PvArea;

    fn next (&mut self) -> Option<PvArea> {
        let off = LittleEndian::read_u64(&self.area[..8]);
        let size = LittleEndian::read_u64(&self.area[8..16]);

        if off == 0 {
            None
        }
        else {
            self.area = &self.area[16..];
            Some(PvArea {
                offset: off,
                size: size,
            })
        }
    }
}

//
// PV HEADER LAYOUT:
// - static header (uuid and size)
// - 0+ data areas
// - blank entry
// - 0+ metadata areas
// - blank entry
// - 8 bytes of pvextension header
// - if version > 0
//   - list of bootloader areas
//
fn get_pv_header(buf: &[u8]) -> Result<PvHeader> {

    let mut da_buf = &buf[ID_LEN+8..];

    let da_vec: Vec<_> = iter_pv_area(da_buf).collect();

    // move slice past any actual entries plus blank
    // terminating entry
    da_buf = &da_buf[(da_vec.len()+1)*16..];

    let md_vec: Vec<_> = iter_pv_area(da_buf).collect();

    da_buf = &da_buf[(md_vec.len()+1)*16..];

    let ext_version = LittleEndian::read_u32(&da_buf[..4]);
    let mut ext_flags = 0;
    let mut ba_vec = Vec::new();

    if ext_version != 0 {
        ext_flags = LittleEndian::read_u32(&da_buf[4..8]);

        da_buf = &da_buf[8..];

        ba_vec = iter_pv_area(da_buf).collect();
    }

    Ok(PvHeader{
        uuid: String::from_utf8_lossy(&buf[..ID_LEN]).into_owned(),
        size: LittleEndian::read_u64(&buf[ID_LEN..ID_LEN+8]),
        ext_version: ext_version,
        ext_flags: ext_flags,
        data_areas: da_vec,
        metadata_areas: md_vec,
        bootloader_areas: ba_vec,
    })
}

fn crc32_ok(val: u32, buf: &[u8]) -> bool {
    let mut digest = crc32::Digest::new(INITIAL_CRC);
    digest.write(&buf);
    let crc32 = digest.sum32();
    if val != crc32 {
        println!("CRC32: input {:x} != calculated {:x}", val, crc32);
    }
    val == crc32
}

fn parse_mda_header(buf: &[u8]) -> () {

    let crc1 = LittleEndian::read_u32(&buf[..4]);

    // TODO: why is this failing?
    crc32_ok(crc1, &buf[4..512]);

    if &buf[4..20] != MDA_MAGIC {
        println!("'{}' doesn't match '{}'", String::from_utf8_lossy(&buf[4..20]),
                 String::from_utf8_lossy(MDA_MAGIC));
    }
}

fn find_stuff(path: &str) -> Result<Label> {

    let mut f = try!(File::open(path));

    let mut buf = vec![0; LABEL_SCAN_SECTORS * 512];

    try!(f.read(&mut buf));

    let label = try!(get_label(&buf));

    let pvheader = try!(get_pv_header(&buf[label.offset as usize..]));

    for md in &pvheader.metadata_areas {
        try!(f.seek(SeekFrom::Start(md.offset)));

        let mut buf = vec![0; md.size as usize];

        try!(f.read(&mut buf));

        parse_mda_header(&buf);
    }

    return Ok(label);
}

fn main() {

    let label = find_stuff(MYPATH).unwrap();

    println!("{}", label.id);
}
<commit_msg>Implement location of mda rawlocn<commit_after>extern crate byteorder;
extern crate crc;

use std::fs::File;
use std::io::{Read, Result, Error, Seek, SeekFrom};
use std::io::ErrorKind::Other;

use byteorder::{LittleEndian, ByteOrder};

use crc::{crc32, Hasher32};

const LABEL_SCAN_SECTORS: usize = 4;
const MYPATH: &'static str = "/dev/mapper/luks-291e9250-200e-4c36-8e5e-66aa257669ed";
const ID_LEN: usize = 32;
const MDA_MAGIC: &'static [u8] = b"\x20\x4c\x56\x4d\x32\x20\x78\x5b\x35\x41\x25\x72\x30\x4e\x2a\x3e";
const INITIAL_CRC: u32 = 0xf597a6cf;
const SECTOR_SIZE: usize = 512;

#[derive(Debug)]
struct Label {
    id: String,
    sector: u64,
    crc: u32,
    offset: u32,
    label: String,
}

#[derive(Debug)]
struct PvArea {
    offset: u64,
    size: u64,
}

#[derive(Debug)]
struct PvHeader {
    uuid: String,
    size: u64, // in bytes
    ext_version: u32,
    ext_flags: u32,
    data_areas: Vec<PvArea>,
    metadata_areas: Vec<PvArea>,
    bootloader_areas: Vec<PvArea>,
}

fn get_label(buf: &[u8]) -> Result<Label> {
    for x in 0..LABEL_SCAN_SECTORS {
        let sec_buf = &buf[x*SECTOR_SIZE..x*SECTOR_SIZE+SECTOR_SIZE];
        if &sec_buf[..8] == b"LABELONE" {
            let crc = LittleEndian::read_u32(&sec_buf[16..20]);
            crc32_ok(crc, &sec_buf[20..SECTOR_SIZE]);

            let sector = LittleEndian::read_u64(&sec_buf[8..16]);
            if sector != x as u64 {
                println!("sector field is {} in sector {}", sector, x);
            }

            return Ok(Label{
                id: String::from_utf8_lossy(&sec_buf[..8]).into_owned(),
                sector: sector,
                crc: crc,
                offset: LittleEndian::read_u32(&sec_buf[20..24]) + (x*SECTOR_SIZE as usize) as u32,
                label: String::from_utf8_lossy(&sec_buf[24..32]).into_owned(),
            })
        }
    }

    Err(Error::new(Other, "bad"))
}

#[derive(Debug)]
struct PvAreaIter<'a> {
    area: &'a[u8],
}

fn iter_pv_area<'a>(buf: &'a[u8]) -> PvAreaIter<'a> {
    PvAreaIter { area: buf }
}

impl<'a> Iterator for PvAreaIter<'a> {
    type Item = PvArea;

    fn next (&mut self) -> Option<PvArea> {
        let off = LittleEndian::read_u64(&self.area[..8]);
        let size = LittleEndian::read_u64(&self.area[8..16]);

        if off == 0 {
            None
        }
        else {
            self.area = &self.area[16..];
            Some(PvArea {
                offset: off,
                size: size,
            })
        }
    }
}

//
// PV HEADER LAYOUT:
// - static header (uuid and size)
// - 0+ data areas
// - blank entry
// - 0+ metadata areas
// - blank entry
// - 8 bytes of pvextension header
// - if version > 0
//   - list of bootloader areas
//
fn get_pv_header(buf: &[u8]) -> Result<PvHeader> {

    let mut da_buf = &buf[ID_LEN+8..];

    let da_vec: Vec<_> = iter_pv_area(da_buf).collect();

    // move slice past any actual entries plus blank
    // terminating entry
    da_buf = &da_buf[(da_vec.len()+1)*16..];

    let md_vec: Vec<_> = iter_pv_area(da_buf).collect();

    da_buf = &da_buf[(md_vec.len()+1)*16..];

    let ext_version = LittleEndian::read_u32(&da_buf[..4]);
    let mut ext_flags = 0;
    let mut ba_vec = Vec::new();

    if ext_version != 0 {
        ext_flags = LittleEndian::read_u32(&da_buf[4..8]);

        da_buf = &da_buf[8..];

        ba_vec = iter_pv_area(da_buf).collect();
    }

    Ok(PvHeader{
        uuid: String::from_utf8_lossy(&buf[..ID_LEN]).into_owned(),
        size: LittleEndian::read_u64(&buf[ID_LEN..ID_LEN+8]),
        ext_version: ext_version,
        ext_flags: ext_flags,
        data_areas: da_vec,
        metadata_areas: md_vec,
        bootloader_areas: ba_vec,
    })
}

fn crc32_ok(val: u32, buf: &[u8]) -> bool {
    let mut digest = crc32::Digest::new(INITIAL_CRC);
    digest.write(&buf);
    let crc32 = digest.sum32();

    // TODO: all our crcs are failing, how come?
    if val != crc32 {
        println!("CRC32: input {:x} != calculated {:x}", val, crc32);
    }
    val == crc32
}

#[derive(Debug)]
struct RawLocn {
    offset: u64,
    size: u64,
    checksum: u32,
    flags: u32,
}

#[derive(Debug)]
struct RawLocnIter<'a> {
    area: &'a[u8],
}

fn iter_raw_locn<'a>(buf: &'a[u8]) -> RawLocnIter<'a> {
    RawLocnIter { area: buf }
}

impl<'a> Iterator for RawLocnIter<'a> {
    type Item = RawLocn;

    fn next (&mut self) -> Option<RawLocn> {
        let off = LittleEndian::read_u64(&self.area[..8]);
        let size = LittleEndian::read_u64(&self.area[8..16]);
        let checksum = LittleEndian::read_u32(&self.area[16..20]);
        let flags = LittleEndian::read_u32(&self.area[20..24]);

        if off == 0 {
            None
        }
        else {
            self.area = &self.area[24..];
            Some(RawLocn {
                offset: off,
                size: size,
                checksum: checksum,
                flags: flags,
            })
        }
    }
}

fn parse_mda_header(buf: &[u8]) -> () {

    crc32_ok(LittleEndian::read_u32(&buf[..4]), &buf[4..512]);

    if &buf[4..20] != MDA_MAGIC {
        println!("'{}' doesn't match '{}'", String::from_utf8_lossy(&buf[4..20]),
                 String::from_utf8_lossy(MDA_MAGIC));
    }

    let ver = LittleEndian::read_u32(&buf[20..24]);
    if ver != 1 {
        println!("bad version {}", ver);
    }

    println!("mdah start {}", LittleEndian::read_u64(&buf[24..32]));
    println!("mdah size {}", LittleEndian::read_u64(&buf[32..40]));

    for x in iter_raw_locn(&buf[40..]) {
        println!("rawlocn {:?}", x);
        let start: usize = x.offset as usize;
        let end = start + x.size as usize;
        let s = String::from_utf8_lossy(&buf[start..end]).into_owned();
        let t: String  = s.chars().take_while(|c| *c != ' ' && *c != '{').collect();
        println!("vgname {}", t);
    }
}

fn find_stuff(path: &str) -> Result<Label> {

    let mut f = try!(File::open(path));

    let mut buf = vec![0; LABEL_SCAN_SECTORS * 512];

    try!(f.read(&mut buf));

    let label = try!(get_label(&buf));

    let pvheader = try!(get_pv_header(&buf[label.offset as usize..]));

    for md in &pvheader.metadata_areas {

        println!("mda {:?}", md);

        try!(f.seek(SeekFrom::Start(md.offset)));

        let mut buf = vec![0; md.size as usize];

        try!(f.read(&mut buf));

        parse_mda_header(&buf);
    }

    return Ok(label);
}

fn main() {

    let label = find_stuff(MYPATH).unwrap();

    println!("{}", label.id);
}
<|endoftext|>


<commit_before>extern crate r2d2;
extern crate r2d2_postgres;
extern crate openssl;
#[macro_use] extern crate nickel;
extern crate nickel_postgres;
extern crate uuid;
extern crate serde_json;
extern crate cas;
extern crate cookie;
extern crate core;
extern crate url;
extern crate authtoken;

use std::env;
use std::io::Read;
use r2d2::{NopErrorHandler, PooledConnection};
use r2d2_postgres::{SslMode, PostgresConnectionManager};
use nickel::{Nickel, HttpRouter, QueryString};
use nickel_postgres::{PostgresMiddleware, PostgresRequestExtensions};
use uuid::Uuid;
use nickel::status::StatusCode;
use nickel::extensions::response::Redirect;
use serde_json::Value;
use cas::{CasClient, ServiceResponse, VerifyError};
use url::form_urlencoded::parse as urlparse;
use authtoken::{set_auth_cookie, verify_auth_cookie,
                get_auth_token_from_headers};

macro_rules! try_or_return {
    ( $op:expr, $error:expr ) => {
        match $op {
            Some(v) => v,
            None => return $error
        }
    }
}

macro_rules! try_or {
    ( $op:expr, $error:expr ) => {
        match $op {
            Ok(v) => v,
            Err(e) => {
                println!("error: {:?}", e);
                return $error;
            }
        }
    }
}

fn create_tables(conn: PooledConnection<PostgresConnectionManager>) {
    let _r = conn.execute(
            "CREATE TABLE IF NOT EXISTS services (
                key UUID PRIMARY KEY,
                name VARCHAR NOT NULL
                )",
            &[]
        );

    let _r = conn.execute(
            "CREATE TABLE IF NOT EXISTS users (
                key SERIAL PRIMARY KEY,
                caseid VARCHAR UNIQUE NOT NULL,
                slackid VARCHAR UNIQUE
                )",
            &[]
        );

    let _r = conn.execute(
            "CREATE TABLE IF NOT EXISTS permissions (
                key UUID REFERENCES services,
                username integer REFERENCES users,
                permissions JSONB,
                PRIMARY KEY (key, username)
                )",
            &[]
        );
}

fn main() {
    let mut app = Nickel::new();

    let hmac_secret = env::var("SECRET").expect("No SECRET found");

    let postgres_url = env::var("DATABASE_URL")
        .expect("Failed to get DATABASE_URL");

    let dbpool = PostgresMiddleware::new(&*postgres_url,
                                         SslMode::None,
                                         5,
                                         Box::new(NopErrorHandler)).unwrap();

    create_tables(dbpool.pool.clone().get().unwrap());
    app.utilize(dbpool);
    app.get("/register", middleware! { |request, response|
        let conn = request.db_conn();

        let name = try_or_return!(request.query().get("service_name"),
            response.error(
                StatusCode::BadRequest, "No service_name specified"));

        let key = Uuid::new_v4();

        let r = conn.execute(
            "INSERT INTO services (key, name) VALUES ($1, $2)",
            &[&key, &name]
            );
        println!("{:?}", r);

        key.to_hyphenated_string()
    });

    app.post("/adduser", middleware! { |request, response|
        let conn = request.db_conn();

        let mut body = vec![];
        try_or!(request.origin.read_to_end(&mut body),
                       response.error(StatusCode::InternalServerError,
                                      "Failed"));

        let permissions = try_or!(String::from_utf8(body),
            response.error(StatusCode::InternalServerError, "Failed"));

        let data: Value = try_or_return!(
            serde_json::from_str(&permissions).ok(),
            response.error(StatusCode::InternalServerError, "Failed"));

        let q = request.query();

        let caseid = try_or_return!(q.get("caseid"),
            response.error(StatusCode::BadRequest, "No username specified"));
        let key = try_or_return!(q.get("key").map(|s| Uuid::parse_str(s).ok()),
            response.error(StatusCode::BadRequest, "No key specified"));

        let user_rows = try_or!(conn.query(
                "INSERT INTO users (caseid) VALUES ($1)
                    ON CONFLICT (caseid) DO UPDATE SET caseid=users.caseid
                    RETURNING key",
                &[&caseid]
                ), response.error(StatusCode::InternalServerError,
                                  "Server Error")
            );
        if user_rows.len() != 1 {
            return response.error(StatusCode::InternalServerError,
                                  "Server Error");
        }

        let user = user_rows.get(0);
        let user_key: i32 = user.get(0);

        let r = try_or!(conn.execute(
            "INSERT INTO permissions (key, username, permissions)
                VALUES ($1, $2, $3)
                ON CONFLICT (key, username) DO UPDATE SET
                permissions=excluded.permissions",
                &[&key, &user_key, &data]
            ),
            response.error(StatusCode::InternalServerError, "Server error"));
        println!("{:?}", r);
        format!("You posted {}", permissions)
    });

    app.get("/getperms", middleware! { |request, response|
        let conn = request.db_conn();
        let q = request.query();
        let key = try_or_return!(q.get("key").map(|s| Uuid::parse_str(s).ok()),
            response.error(StatusCode::BadRequest, "No key specified"));

        let caseid = q.get("caseid").unwrap_or("");
        let slackid = q.get("slackid").unwrap_or("");

        let r = try_or!(conn.query(
                "SELECT permissions FROM permissions
                    INNER JOIN users
                    ON (permissions.username = users.key)
                    WHERE (caseid=$1 or slackid=$2) and permissions.key=$3",
                &[&caseid, &slackid, &key]
                ), response.error(StatusCode::InternalServerError,
                                  "Server Error")
            );
        println!("{:?}", r);

        if r.len() < 1 {
            return response.error(StatusCode::NotFound, "User not found");
        }
        let row = r.get(0);
        let s: Value = row.get(0);

        format!("{:?}", s)
    });

    let secret = hmac_secret.clone();
    app.get("/login", middleware! { |request, mut response|
        let base_url = env::var("BASE_URL")
            .unwrap_or("https://login.case.edu".to_string());
        let login_path = env::var("LOGIN_PATH")
            .unwrap_or("/cas/login".to_string());
        let logout_path = env::var("LOGOUT_PATH")
            .unwrap_or("/cas/logout".to_string());
        let verify_path = env::var("VERIFY_PATH")
            .unwrap_or("/cas/serviceValidate".to_string());
        let service_url = env::var("URL")
            .unwrap_or("http://hacsoc-auth.case.edu/login".to_string());

        let cas = try_or!(CasClient::new(&base_url, &login_path, &logout_path,
                                         &verify_path, &service_url),
                          response.error(StatusCode::InternalServerError,
                                         "Server Error"));
        match cas.verify_from_request(&request.origin) {
            Ok(ServiceResponse::Success(v)) => {
                set_auth_cookie(&secret, v, response.headers_mut());
                return response.redirect("/setslackid");
            }
            Ok(ServiceResponse::Failure(e)) => format!("error: {:?}", e),
            Err(VerifyError::NoTicketFound) =>
                return response.redirect(cas.get_login_url()),
            Err(_) => return response.error(StatusCode::InternalServerError,
                                            "Server Error"),
        }
    });

    let secret = hmac_secret.clone();
    app.get("/setslackid", middleware! { |request, response|
        if verify_auth_cookie::<String>(&secret, &request.origin.headers) {
            let data = "";
            return response.render("assets/slackform.html", &data);
        } else {
            return response.redirect("/login");
        }
    });

    let secret = hmac_secret.clone();
    app.post("/setslackid", middleware! { |request, response|
        if verify_auth_cookie::<String>(&secret, &request.origin.headers) {
            let token = match get_auth_token_from_headers(
                &request.origin.headers) {
                Some(v) => v,
                None => return response.redirect("/login")
            };
            let caseid: String = token.data;
            let conn = request.db_conn();
            let mut s: Vec<u8> = Vec::new();
            let _r = try_or!(request.origin.read_to_end(&mut s),
                             response.error(StatusCode::InternalServerError,
                                            "Server Error"));
            let data = urlparse(&s[..]);
            let mut slackid = "".to_string();
            for (name, value) in data {
                if name == "slackid" {
                    slackid = value.to_string();
                    break;
                }
            }

            let r = try_or!(conn.execute("INSERT INTO users (caseid, slackid)
                                    VALUES ($1, $2)
                                    ON CONFLICT (caseid) DO UPDATE SET
                                    slackid=excluded.slackid",
                                    &[&caseid, &slackid]
                                ),
                                response.error(StatusCode::InternalServerError,
                                               "Server Error"));
            println!("{}", r);
            format!("You have successfully associated the slack id {} with the case id {}",
                    slackid, caseid)
        } else {
            return response.redirect("/login");
        }
    });

    let listen = match env::var("LISTEN") {
        Ok(s) => s,
        Err(_) => "127.0.0.1:8080".to_string()
    };

    app.listen(&listen[..]);
}
<commit_msg>Fix getperms to use post<commit_after>extern crate r2d2;
extern crate r2d2_postgres;
extern crate openssl;
#[macro_use] extern crate nickel;
extern crate nickel_postgres;
extern crate uuid;
extern crate serde_json;
extern crate cas;
extern crate cookie;
extern crate core;
extern crate url;
extern crate authtoken;

use std::env;
use std::io::Read;
use r2d2::{NopErrorHandler, PooledConnection};
use r2d2_postgres::{SslMode, PostgresConnectionManager};
use nickel::{Nickel, HttpRouter, QueryString};
use nickel_postgres::{PostgresMiddleware, PostgresRequestExtensions};
use uuid::Uuid;
use nickel::status::StatusCode;
use nickel::extensions::response::Redirect;
use serde_json::Value;
use cas::{CasClient, ServiceResponse, VerifyError};
use url::form_urlencoded::parse as urlparse;
use authtoken::{set_auth_cookie, verify_auth_cookie,
                get_auth_token_from_headers};

macro_rules! try_or_return {
    ( $op:expr, $error:expr ) => {
        match $op {
            Some(v) => v,
            None => return $error
        }
    }
}

macro_rules! try_or {
    ( $op:expr, $error:expr ) => {
        match $op {
            Ok(v) => v,
            Err(e) => {
                println!("error: {:?}", e);
                return $error;
            }
        }
    }
}

fn create_tables(conn: PooledConnection<PostgresConnectionManager>) {
    let _r = conn.execute(
            "CREATE TABLE IF NOT EXISTS services (
                key UUID PRIMARY KEY,
                name VARCHAR NOT NULL
                )",
            &[]
        );

    let _r = conn.execute(
            "CREATE TABLE IF NOT EXISTS users (
                key SERIAL PRIMARY KEY,
                caseid VARCHAR UNIQUE NOT NULL,
                slackid VARCHAR UNIQUE
                )",
            &[]
        );

    let _r = conn.execute(
            "CREATE TABLE IF NOT EXISTS permissions (
                key UUID REFERENCES services,
                username integer REFERENCES users,
                permissions JSONB,
                PRIMARY KEY (key, username)
                )",
            &[]
        );
}

fn main() {
    let mut app = Nickel::new();

    let hmac_secret = env::var("SECRET").expect("No SECRET found");

    let postgres_url = env::var("DATABASE_URL")
        .expect("Failed to get DATABASE_URL");

    let dbpool = PostgresMiddleware::new(&*postgres_url,
                                         SslMode::None,
                                         5,
                                         Box::new(NopErrorHandler)).unwrap();

    create_tables(dbpool.pool.clone().get().unwrap());
    app.utilize(dbpool);
    app.get("/register", middleware! { |request, response|
        let conn = request.db_conn();

        let name = try_or_return!(request.query().get("service_name"),
            response.error(
                StatusCode::BadRequest, "No service_name specified"));

        let key = Uuid::new_v4();

        let r = conn.execute(
            "INSERT INTO services (key, name) VALUES ($1, $2)",
            &[&key, &name]
            );
        println!("{:?}", r);

        key.to_hyphenated_string()
    });

    app.post("/adduser", middleware! { |request, response|
        let conn = request.db_conn();

        let mut body = vec![];
        try_or!(request.origin.read_to_end(&mut body),
                       response.error(StatusCode::InternalServerError,
                                      "Failed"));

        let permissions = try_or!(String::from_utf8(body),
            response.error(StatusCode::InternalServerError, "Failed"));

        let data: Value = try_or_return!(
            serde_json::from_str(&permissions).ok(),
            response.error(StatusCode::InternalServerError, "Failed"));

        let q = request.query();

        let caseid = try_or_return!(q.get("caseid"),
            response.error(StatusCode::BadRequest, "No username specified"));
        let key = try_or_return!(q.get("key").map(|s| Uuid::parse_str(s).ok()),
            response.error(StatusCode::BadRequest, "No key specified"));

        let user_rows = try_or!(conn.query(
                "INSERT INTO users (caseid) VALUES ($1)
                    ON CONFLICT (caseid) DO UPDATE SET caseid=users.caseid
                    RETURNING key",
                &[&caseid]
                ), response.error(StatusCode::InternalServerError,
                                  "Server Error")
            );
        if user_rows.len() != 1 {
            return response.error(StatusCode::InternalServerError,
                                  "Server Error");
        }

        let user = user_rows.get(0);
        let user_key: i32 = user.get(0);

        let r = try_or!(conn.execute(
            "INSERT INTO permissions (key, username, permissions)
                VALUES ($1, $2, $3)
                ON CONFLICT (key, username) DO UPDATE SET
                permissions=excluded.permissions",
                &[&key, &user_key, &data]
            ),
            response.error(StatusCode::InternalServerError, "Server error"));
        println!("{:?}", r);
        format!("You posted {}", permissions)
    });

    app.post("/getperms", middleware! { |request, response|
        let conn = request.db_conn();
        let q = request.query();
        let key = try_or_return!(q.get("key").map(|s| Uuid::parse_str(s).ok()),
            response.error(StatusCode::BadRequest, "No key specified"));

        let caseid = q.get("caseid").unwrap_or("");
        let slackid = q.get("slackid").unwrap_or("");

        let r = try_or!(conn.query(
                "SELECT permissions FROM permissions
                    INNER JOIN users
                    ON (permissions.username = users.key)
                    WHERE (caseid=$1 or slackid=$2) and permissions.key=$3",
                &[&caseid, &slackid, &key]
                ), response.error(StatusCode::InternalServerError,
                                  "Server Error")
            );
        println!("{:?}", r);

        if r.len() < 1 {
            return response.error(StatusCode::NotFound, "User not found");
        }
        let row = r.get(0);
        let s: Value = row.get(0);

        format!("{:?}", s)
    });

    let secret = hmac_secret.clone();
    app.get("/login", middleware! { |request, mut response|
        let base_url = env::var("BASE_URL")
            .unwrap_or("https://login.case.edu".to_string());
        let login_path = env::var("LOGIN_PATH")
            .unwrap_or("/cas/login".to_string());
        let logout_path = env::var("LOGOUT_PATH")
            .unwrap_or("/cas/logout".to_string());
        let verify_path = env::var("VERIFY_PATH")
            .unwrap_or("/cas/serviceValidate".to_string());
        let service_url = env::var("URL")
            .unwrap_or("http://hacsoc-auth.case.edu/login".to_string());

        let cas = try_or!(CasClient::new(&base_url, &login_path, &logout_path,
                                         &verify_path, &service_url),
                          response.error(StatusCode::InternalServerError,
                                         "Server Error"));
        match cas.verify_from_request(&request.origin) {
            Ok(ServiceResponse::Success(v)) => {
                set_auth_cookie(&secret, v, response.headers_mut());
                return response.redirect("/setslackid");
            }
            Ok(ServiceResponse::Failure(e)) => format!("error: {:?}", e),
            Err(VerifyError::NoTicketFound) =>
                return response.redirect(cas.get_login_url()),
            Err(_) => return response.error(StatusCode::InternalServerError,
                                            "Server Error"),
        }
    });

    let secret = hmac_secret.clone();
    app.get("/setslackid", middleware! { |request, response|
        if verify_auth_cookie::<String>(&secret, &request.origin.headers) {
            let data = "";
            return response.render("assets/slackform.html", &data);
        } else {
            return response.redirect("/login");
        }
    });

    let secret = hmac_secret.clone();
    app.post("/setslackid", middleware! { |request, response|
        if verify_auth_cookie::<String>(&secret, &request.origin.headers) {
            let token = match get_auth_token_from_headers(
                &request.origin.headers) {
                Some(v) => v,
                None => return response.redirect("/login")
            };
            let caseid: String = token.data;
            let conn = request.db_conn();
            let mut s: Vec<u8> = Vec::new();
            let _r = try_or!(request.origin.read_to_end(&mut s),
                             response.error(StatusCode::InternalServerError,
                                            "Server Error"));
            let data = urlparse(&s[..]);
            let mut slackid = "".to_string();
            for (name, value) in data {
                if name == "slackid" {
                    slackid = value.to_string();
                    break;
                }
            }

            let r = try_or!(conn.execute("INSERT INTO users (caseid, slackid)
                                    VALUES ($1, $2)
                                    ON CONFLICT (caseid) DO UPDATE SET
                                    slackid=excluded.slackid",
                                    &[&caseid, &slackid]
                                ),
                                response.error(StatusCode::InternalServerError,
                                               "Server Error"));
            println!("{}", r);
            format!("You have successfully associated the slack id {} with the case id {}",
                    slackid, caseid)
        } else {
            return response.redirect("/login");
        }
    });

    let listen = match env::var("LISTEN") {
        Ok(s) => s,
        Err(_) => "127.0.0.1:8080".to_string()
    };

    app.listen(&listen[..]);
}
<|endoftext|>


<commit_before>extern crate futures;
extern crate tokio_core;
extern crate tokio_proto;
extern crate tokio_service;

use std::io;
use std::str;
use std::collections::BTreeMap;
use tokio_core::io::{Codec, EasyBuf};
use tokio_core::io::{Io, Framed};
use tokio_core::net::TcpStream;
use tokio_proto::pipeline::ServerProto;
use tokio_proto::TcpServer;
use tokio_service::Service;
use futures::{future, Future, BoxFuture};

pub struct CliCodec {
    /// Description of the I/O object for the info command
    info: String,

    /// Offset within the incoming EasyBuf at which newline search last ended
    search_offset: usize,
}

impl CliCodec {
    /// Initializes with the given connection info
    fn new(io_info: String) -> CliCodec {
        CliCodec { info: io_info, search_offset: 0 }
    }
}

impl Codec for CliCodec {
    /// Input type is a tuple with the I/O info, the command name, and an optional argument string
    type In = (String, String, Option<String>);

    /// Response type is just a string
    type Out = String;

    /// Find a newline, decode to a tuple of command name and argument string
    fn decode(&mut self, buf: &mut EasyBuf) -> io::Result<Option<Self::In>> {
        // Find newline
        let m = buf
            .as_slice()
            .iter()
            .skip(self.search_offset)
            .position(|&b| b == b'\n');

        match m {
            // Process the line if a newline was found
            Some(idx) => {
                println!("Found newline at position {}, started at {}", idx, self.search_offset); // XXX

                let line = buf.drain_to(self.search_offset + idx);
                buf.drain_to(1);

                self.search_offset = 0;

                match str::from_utf8(line.as_slice()) {
                    // Return the string on successful UTF-8 decode
                    // (TODO: ignore blank lines)
                    Ok(s) => {
                        // TODO: Find a better way to split the string
                        let s = s.trim();

                        let request = match s.find(' ') {
                            Some(i) => {
                                let (cmd, args) = s.split_at(i);
                                (
                                    self.info.clone(),
                                    cmd.trim().to_string(),
                                    Some(args.trim().to_string())
                                )
                            },
                            None => (self.info.clone(), s.to_string(), None)
                        };

                        Ok(Some(request))
                    },

                    // Return an error if invalid UTF-8 is received
                    Err(e) => Err(io::Error::new(io::ErrorKind::Other, format!("invalid UTF-8: {:?}", e))),
                }
            },

            // Save our position if a newline wasn't found
            _ => {
                println!("Haven't received newline yet!  We started at offset {}, now at {}", self.search_offset, buf.len()); // XXX

                self.search_offset = buf.len();

                Ok(None)
            }
        }
    }

    /// Append the String to the outgoing buffer
    fn encode(&mut self, msg: String, buf: &mut Vec<u8>) -> io::Result<()> {
        buf.extend(msg.as_bytes());
        buf.push(b'\n');
        Ok(())
    }
}

pub struct CliProto;

impl ServerProto<TcpStream> for CliProto {
    type Request = (String, String, Option<String>);
    type Response = String;

    type Transport = Framed<TcpStream, CliCodec>;
    type BindTransport = Result<Self::Transport, io::Error>;

    fn bind_transport(&self, io: TcpStream) -> Self::BindTransport {
        let addr = io.peer_addr().unwrap();
        let info = format!("Client address: {}\nClient port: {}", addr.ip(), addr.port());
        Ok(io.framed(CliCodec::new(info)))
    }
}

trait CliCommand {
    fn name(&self) -> &str;
    fn description(&self) -> &str;
    fn call(&self, info: String, args: Option<String>) -> String;
}

#[derive(Default)]
pub struct CliServer<'a> {
    commands: BTreeMap<&'a str, &'a CliCommand>,
}

impl<'a> CliServer<'a> {
    fn new() -> CliServer<'a> {
        CliServer { commands: BTreeMap::new() }
    }

    fn add_command(&mut self, cmd: &'a CliCommand) {
        self.commands.insert(cmd.name(), cmd);
    }
}

impl<'a> Service for CliServer<'a> {
    type Request = (String, String, Option<String>);
    type Response = String;

    type Error = io::Error;

    type Future = BoxFuture<Self::Response, Self::Error>;

    fn call(&self, req: Self::Request) -> Self::Future {
        let (info, cmdname, args) = req;

        match self.commands.get(&cmdname[..]) {
            Some(cmd) => {
                println!("Calling command {} for IO info {:?}", cmdname, info);
                // TODO: have commands return futures?
                future::ok(cmd.call(info, args)).boxed()
            },
            None => {
                println!("No match found for command {}", cmdname);
                future::ok(format!("Unknown command: {}", cmdname)).boxed()
            }
        }
    }
}

// TODO: Consider registering commands by passing two strings and a closure
struct EchoCommand;
impl CliCommand for EchoCommand {
    fn name(&self) -> &str {
        "echo"
    }

    fn description(&self) -> &str {
        "Prints the command line."
    }

    fn call(&self, _info: String, args: Option<String>) -> String {
        match args {
            Some(s) => s,
            None => "".to_string()
        }
    }
}

struct InfoCommand;
impl CliCommand for InfoCommand {
    fn name(&self) -> &str { "info" }
    fn description(&self) -> &str { "Prints connection information." }

    fn call(&self, info: String, _args: Option<String>) -> String {
        info
    }
}

static ECHO: EchoCommand = EchoCommand;
static INFO: InfoCommand = InfoCommand;

fn main() {
    let addr = "0.0.0.0:14311".parse().unwrap();
    let server = TcpServer::new(CliProto, addr);

    println!("Serving on {}", addr);
    server.serve(|| {
        let mut cli = CliServer::new();
        cli.add_command(&ECHO);
        cli.add_command(&INFO);
        Ok(cli)
    });
}
<commit_msg>Partial implementation of > prompt for issue #11.<commit_after>extern crate futures;
extern crate tokio_core;
extern crate tokio_proto;
extern crate tokio_service;

use std::io;
use std::str;
use std::collections::BTreeMap;
use tokio_core::io::{Codec, EasyBuf};
use tokio_core::io::{Io, Framed};
use tokio_core::net::TcpStream;
use tokio_proto::pipeline::ServerProto;
use tokio_proto::TcpServer;
use tokio_service::Service;
use futures::{future, Future, BoxFuture};

pub struct CliCodec {
    /// Description of the I/O object for the info command
    info: String,

    /// Offset within the incoming EasyBuf at which newline search last ended
    search_offset: usize,
}

impl CliCodec {
    /// Initializes with the given connection info
    fn new(io_info: String) -> CliCodec {
        CliCodec { info: io_info, search_offset: 0 }
    }
}

impl Codec for CliCodec {
    /// Input type is a tuple with the I/O info, the command name, and an optional argument string
    type In = (String, String, Option<String>);

    /// Response type is just a string
    type Out = String;

    /// Find a newline, decode to a tuple of command name and argument string
    fn decode(&mut self, buf: &mut EasyBuf) -> io::Result<Option<Self::In>> {
        // Find newline
        let m = buf
            .as_slice()
            .iter()
            .skip(self.search_offset)
            .position(|&b| b == b'\n');

        match m {
            // Process the line if a newline was found
            Some(idx) => {
                println!("Found newline at position {}, started at {}", idx, self.search_offset); // XXX

                let line = buf.drain_to(self.search_offset + idx);
                buf.drain_to(1);

                self.search_offset = 0;

                match str::from_utf8(line.as_slice()) {
                    // Return the string on successful UTF-8 decode
                    // (TODO: ignore blank lines)
                    Ok(s) => {
                        // TODO: Find a better way to split the string
                        let s = s.trim();

                        let request = match s.find(' ') {
                            Some(i) => {
                                let (cmd, args) = s.split_at(i);
                                (
                                    self.info.clone(),
                                    cmd.trim().to_string(),
                                    Some(args.trim().to_string())
                                )
                            },
                            None => (self.info.clone(), s.to_string(), None)
                        };

                        Ok(Some(request))
                    },

                    // Return an error if invalid UTF-8 is received
                    Err(e) => Err(io::Error::new(io::ErrorKind::Other, format!("invalid UTF-8: {:?}", e))),
                }
            },

            // Save our position if a newline wasn't found
            _ => {
                println!("Haven't received newline yet!  We started at offset {}, now at {}", self.search_offset, buf.len()); // XXX

                self.search_offset = buf.len();

                Ok(None)
            }
        }
    }

    /// Append the String to the outgoing buffer
    fn encode(&mut self, msg: String, buf: &mut Vec<u8>) -> io::Result<()> {
        buf.extend(msg.as_bytes());
        buf.extend("\n> ".as_bytes());
        Ok(())
    }
}

pub struct CliProto;

impl ServerProto<TcpStream> for CliProto {
    type Request = (String, String, Option<String>);
    type Response = String;

    type Transport = Framed<TcpStream, CliCodec>;
    type BindTransport = Result<Self::Transport, io::Error>;

    fn bind_transport(&self, io: TcpStream) -> Self::BindTransport {
        let addr = io.peer_addr().unwrap();
        let info = format!("Client address: {}\nClient port: {}", addr.ip(), addr.port());
        Ok(io.framed(CliCodec::new(info)))
    }
}

trait CliCommand {
    fn name(&self) -> &str;
    fn description(&self) -> &str;
    fn call(&self, info: String, args: Option<String>) -> String;
}

#[derive(Default)]
pub struct CliServer<'a> {
    commands: BTreeMap<&'a str, &'a CliCommand>,
}

impl<'a> CliServer<'a> {
    fn new() -> CliServer<'a> {
        CliServer { commands: BTreeMap::new() }
    }

    fn add_command(&mut self, cmd: &'a CliCommand) {
        self.commands.insert(cmd.name(), cmd);
    }
}

impl<'a> Service for CliServer<'a> {
    type Request = (String, String, Option<String>);
    type Response = String;

    type Error = io::Error;

    type Future = BoxFuture<Self::Response, Self::Error>;

    fn call(&self, req: Self::Request) -> Self::Future {
        let (info, cmdname, args) = req;

        match self.commands.get(&cmdname[..]) {
            Some(cmd) => {
                println!("Calling command {} for IO info {:?}", cmdname, info);
                // TODO: have commands return futures?
                future::ok(cmd.call(info, args)).boxed()
            },
            None => {
                println!("No match found for command {}", cmdname);
                future::ok(format!("Unknown command: {}", cmdname)).boxed()
            }
        }
    }
}

// TODO: Consider registering commands by passing two strings and a closure
struct EchoCommand;
impl CliCommand for EchoCommand {
    fn name(&self) -> &str {
        "echo"
    }

    fn description(&self) -> &str {
        "Prints the command line."
    }

    fn call(&self, _info: String, args: Option<String>) -> String {
        match args {
            Some(s) => s,
            None => "".to_string()
        }
    }
}

struct InfoCommand;
impl CliCommand for InfoCommand {
    fn name(&self) -> &str { "info" }
    fn description(&self) -> &str { "Prints connection information." }

    fn call(&self, info: String, _args: Option<String>) -> String {
        info
    }
}

static ECHO: EchoCommand = EchoCommand;
static INFO: InfoCommand = InfoCommand;

fn main() {
    let addr = "0.0.0.0:14311".parse().unwrap();
    let server = TcpServer::new(CliProto, addr);

    println!("Serving on {}", addr);
    server.serve(|| {
        let mut cli = CliServer::new();
        cli.add_command(&ECHO);
        cli.add_command(&INFO);
        Ok(cli)
    });
}
<|endoftext|>


<commit_before>
use std::io;
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::File;
use std::sync::{Arc, Mutex, MutexGuard};
use std::sync::mpsc::{ channel, Sender, Receiver };
use std::thread;

// State Function
struct StateFn<E: std::error::Error> {
    f: fn(l: &Lex<E>)->Option<StateFn<E>>
}

#[derive(Debug)]
struct Pos {
    line: u64,
    col: u64
}

impl Pos {
    fn new()->Pos {
        Pos {
            line: 0,
            col: 0
        }
    }
}

#[derive(Debug)]
enum TokenType {
    Integer,
    Operator
}

#[derive(Debug)]
struct Token {
    pos: Pos,
    typ: TokenType,
    val: String
}

trait Lex<E: std::error::Error> {
    fn next(&self)->Result<char, E>;
}

// State Machine
struct Lexer<R: io::Read+Send> {
    pos: Pos,
    buf: Arc<Mutex<io::Chars<R>>>,
    state: StateFn<io::CharsError>,
    send: Option<Sender<Token>>
}

fn startState<E: std::error::Error>(l: &Lex<E>)->Option<StateFn<E>> {
    unimplemented!()
}

impl<R: io::Read+Send> Lexer<R> {
    fn new(reader: R)->Lexer<R> {
        Lexer {
            pos: Pos::new(),
            buf: Arc::new(Mutex::new(reader.chars())),
            state: StateFn {
                f: startState
            },
            send: None
        }
    }

    fn lex(&'static mut self)->(thread::JoinHandle<()>, Receiver<Token>) {
        let (tx, rx) = channel();
        self.send = Some(tx);
        (thread::spawn(move || {
            loop {
                match (self.state.f)(self) {
                    Some(s) => { self.state = s; }
                    None => { return }
                }
            }
        }), rx)
    }
}

impl<R: io::Read+Send> Lex<io::CharsError> for Lexer<R> {
    fn next(&self)->Result<char, io::CharsError> {
        self.buf.lock().unwrap().next().unwrap()
    }
}

static lexer : &'static mut Lexer<BufReader<File>> = &mut Lexer::new(BufReader::new(File::open("src.f").unwrap()));

fn main() {
    let (th, rx) = lexer.lex();
    println!("{:?}\n", rx.recv().unwrap());
}
<commit_msg>update<commit_after>
#![feature(io)]

use std::io;
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::File;
use std::sync::{Arc, Mutex };
use std::sync::mpsc::{ channel, Sender, Receiver };
use std::thread;

// State Function
struct StateFn<E: std::error::Error> {
    f: fn(l: &Lex<E>)->Option<StateFn<E>>
}

#[derive(Debug)]
struct Pos {
    line: u64,
    col: u64
}

impl Pos {
    fn new()->Pos {
        Pos {
            line: 0,
            col: 0
        }
    }
}

#[derive(Debug)]
enum TokenType {
    Integer,
    Operator
}

#[derive(Debug)]
struct Token {
    pos: Pos,
    typ: TokenType,
    val: String
}

trait Lex<E: std::error::Error> {
    fn next(&self)->Result<char, E>;
    fn emit(&self);
}

// State Machine
struct Lexer<R: io::Read+Send> {
    pos: Pos,
    buf: Arc<Mutex<io::Chars<R>>>,
    state: StateFn<io::CharsError>,
    send: Option<Sender<Token>>
}

fn start_state<E: std::error::Error>(l: &Lex<E>)->Option<StateFn<E>> {
    l.emit();
    None
}

impl<R: io::Read+Send+'static> Lexer<R> {
    fn new(reader: R)->Lexer<R> {
        Lexer {
            pos: Pos::new(),
            buf: Arc::new(Mutex::new(reader.chars())),
            state: StateFn {
                f: start_state
            },
            send: None
        }
    }

    fn lex(mut self)->(thread::JoinHandle<()>, Receiver<Token>) {
        let (tx, rx) = channel();
        self.send = Some(tx);
        (thread::spawn(move || {
            loop {
                match (self.state.f)(&self) {
                    Some(s) => { self.state = s; }
                    None => { return }
                }
            }
        }), rx)
    }
}

impl<R: io::Read+Send> Lex<io::CharsError> for Lexer<R> {
    fn next(&self)->Result<char, io::CharsError> {
        self.buf.lock().unwrap().next().unwrap()
    }

    fn emit(&self) {
        self.send.as_ref().unwrap().send(Token{
            pos: Pos::new(),
            typ: TokenType::Integer,
            val: "Test".to_string()
        }).unwrap();
    }
}

fn main() {
    let lexer = Lexer::new(BufReader::new(File::open("src.f").unwrap()));
    let (th, rx) = lexer.lex();
    println!("{:?}", rx.recv().unwrap());
    th.join().unwrap();
}
<|endoftext|>


<commit_before>#![feature(plugin)]
#![plugin(rocket_codegen)]

extern crate reqwest;
extern crate rocket;
extern crate toml;

use std::fmt::{Display, Formatter, self};
use std::fs::{File, self};
use std::io::Read;
use std::io::Write;
use std::process;

enum Status {
    Unknown,
    OutOfDate,
    UpToDate
}

impl Display for Status {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        match *self {
            Status::Unknown => write!(f, "unknown"),
            Status::OutOfDate => write!(f, "outofdate"),
            Status::UpToDate => write!(f, "uptodate")
        }
    }
}

#[get("/<owner>/<name>")]
fn index(owner: &str, name: &str) -> File {
    // TODO: HEADER 'Cache-Control': 'no-cache, no-store, must-revalidate',
    // TODO: HEADER 'Expires': new Date().toUTCString()
    let status = get_deps_status(owner, name, "dev-dependencies");
    File::open(format!("public/img/status/{}.png", status)).unwrap()
}

fn get_deps_status(owner: &str, name: &str, deps_type: &str) -> Status {
    let cargo_url = format!("https://raw.githubusercontent.com/{}/{}/master/Cargo.toml", owner, name);

    if let Ok(mut resp) = reqwest::get(&*cargo_url) {
        match resp.status() {
            &reqwest::StatusCode::Ok => {
                let mut body = String::new();
                resp.read_to_string(&mut body).ok();
                deps_status_from_cargo(owner, name, body, deps_type)
            },
            _ => Status::Unknown
        }
    } else {
        Status::Unknown
    }
}

fn deps_status_from_cargo(owner: &str, name: &str, cargo: String, deps_type: &str) -> Status {

    if let Some(root) = toml::Parser::new(&*cargo).parse() {
        match root.get(deps_type) {
            Some(val) => {
                if let Some(dependencies) = val.as_table() {
                    // TODO:
                    // 1- Download the Cargo.toml of the project into /tmp/owner/name/Cargo.toml
                    // 2- Create a dummy /tmp/owner/name/src/lib.rs (avoid `cargo update` complaint)
                    let tmp_dir = format!("/tmp/{}/{}", owner, name);
                    let tmp_manifest = format!("{}/Cargo.toml", tmp_dir);
                    let tmp_src_dir = format!("{}/src", tmp_dir);
                    let tmp_src_lib = format!("{}/lib.rs", tmp_src_dir);

                    if let Err(_) = fs::create_dir_all(tmp_src_dir.as_str())
                        .and_then(|_| File::create(tmp_manifest.as_str()))
                        .and_then(|mut file| file.write_all(cargo.as_bytes()))
                        .and_then(|_| File::create(tmp_src_lib.as_str())) {
                            return Status::Unknown;
                        }
                    // 3- `cargo update --manifest-path /tmp/owner/name/Cargo.toml`
                    if let Err(_) = process::Command::new("cargo")
                        .arg("update")
                        .arg("--manifest-path")
                        .arg(tmp_manifest.as_str())
                        .output() {
                            return Status::Unknown;
                        }
                    // 4- Parse the /tmp/owner/name/Cargo.lock generated
                    // 5- Compare each deps with semver
                    dependencies.iter().fold(Status::UpToDate, |oldest, (dep, version)| {
                        println!("{:?}", dep);
                        println!("{:?}", version);
                        Status::OutOfDate
                    })
                } else {
                    Status::UpToDate
                }
            },
            None => Status::UpToDate
        }
    } else {
        Status::Unknown
    }
}

fn main() {
    rocket::ignite().mount("/", routes![index]).launch();
}
<commit_msg>Refactoring<commit_after>#![feature(plugin)]
#![plugin(rocket_codegen)]

extern crate reqwest;
extern crate rocket;
extern crate toml;

use std::fmt::{Display, Formatter, self};
use std::fs::{File, self};
use std::io::Read;
use std::io::Write;
use std::process;

enum Status {
    Unknown,
    OutOfDate,
    UpToDate
}

impl Display for Status {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        match *self {
            Status::Unknown => write!(f, "unknown"),
            Status::OutOfDate => write!(f, "outofdate"),
            Status::UpToDate => write!(f, "uptodate")
        }
    }
}

#[get("/<owner>/<name>")]
fn index(owner: &str, name: &str) -> File {
    // TODO: HEADER 'Cache-Control': 'no-cache, no-store, must-revalidate',
    // TODO: HEADER 'Expires': new Date().toUTCString()
    let status = get_deps_status(owner, name, "dev-dependencies");
    File::open(format!("public/img/status/{}.png", status)).unwrap()
}

fn get_deps_status(owner: &str, name: &str, deps_type: &str) -> Status {
    let cargo_url = format!("https://raw.githubusercontent.com/{}/{}/master/Cargo.toml", owner, name);

    if let Ok(mut resp) = reqwest::get(&*cargo_url) {
        match resp.status() {
            &reqwest::StatusCode::Ok => {
                let mut body = String::new();
                resp.read_to_string(&mut body).ok();
                deps_status_from_cargo(owner, name, body, deps_type)
            },
            _ => Status::Unknown
        }
    } else {
        Status::Unknown
    }
}

fn deps_status_from_cargo(owner: &str, name: &str, cargo: String, deps_type: &str) -> Status {

    let root = match toml::Parser::new(&*cargo).parse() {
        Some(root) => root,
        None => return Status::Unknown
    };

    let dependencies = match root.get(deps_type)
        .and_then(|val| val.as_table()) {
            Some(dependencies) => dependencies,
            None => return Status::UpToDate
        };

    // TODO:
    // 1- Download the Cargo.toml of the project into /tmp/owner/name/Cargo.toml
    // 2- Create a dummy /tmp/owner/name/src/lib.rs (avoid `cargo update` complaint)
    let tmp_dir = format!("/tmp/{}/{}", owner, name);
    let tmp_manifest = format!("{}/Cargo.toml", tmp_dir);
    let tmp_src_dir = format!("{}/src", tmp_dir);
    let tmp_src_lib = format!("{}/lib.rs", tmp_src_dir);

    if let Err(_) = fs::create_dir_all(tmp_src_dir.as_str())
        .and_then(|_| File::create(tmp_manifest.as_str()))
            .and_then(|mut file| file.write_all(cargo.as_bytes()))
            .and_then(|_| File::create(tmp_src_lib.as_str())) {
                return Status::Unknown;
            }
    // 3- `cargo update --manifest-path /tmp/owner/name/Cargo.toml`
    if let Err(_) = process::Command::new("cargo")
        .arg("update")
            .arg("--manifest-path")
            .arg(tmp_manifest.as_str())
            .output() {
                return Status::Unknown;
            }
    // 4- Parse the /tmp/owner/name/Cargo.lock generated
    // 5- Compare each deps with semver
    dependencies.iter().fold(Status::UpToDate, |oldest, (dep, version)| {
        println!("{:?}", dep);
        println!("{:?}", version);
        Status::OutOfDate
    })
}

fn main() {
    rocket::ignite().mount("/", routes![index]).launch();
}
<|endoftext|>


<commit_before>#![feature(plugin)]
#![plugin(rocket_codegen)]

extern crate rocket;
extern crate rocket_contrib;

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

extern crate file;
extern crate rand;

use rocket_contrib::JSON;

use std::collections::HashSet;

use rand::distributions::{IndependentSample, Range};
use rand::Rng;

#[derive(Serialize, Debug, Clone, Copy)]
enum Sex {
    Male,
    Female
}

impl rand::Rand for Sex {
    fn rand<R: Rng>(rng: &mut R) -> Self {
        let variants = [Sex::Male, Sex::Female];
        *rng.choose(&variants).unwrap()
    }
}

#[derive(Serialize, Debug)]
struct Person {
    sex: Sex,
    first_name: String,
    second_name: String,
    last_name: String
}

#[derive(Debug)]
struct NamePool {
    female: Vec<String>,
    male: Vec<String>,
    surname: Vec<String>,
}

impl NamePool {
    fn random_name(&self) -> Person {
        fn random_value(vec: &Vec<String>) -> &String {
            let between = Range::new(0, vec.len() - 1);
            let mut rng = rand::thread_rng();
            let index = between.ind_sample(&mut rng);
            &vec[index]
        }

        let sex: Sex = rand::random();
        let first_name = match sex {
            Sex::Male => random_value(&self.male),
            Sex::Female => random_value(&self.female)
        };

        let person = Person {
            sex: sex,
            first_name: first_name.to_string(),
            second_name: random_value(&self.male).to_string(),
            last_name: random_value(&self.surname).to_string()
        };

        println!("{:?}", person);
        person
    }
}

#[get("/")]
fn index(pool: rocket::State<NamePool>) -> JSON<Person> {
    let person = pool.random_name();
    JSON(person)
}

fn load_name_pool() -> NamePool {
    let female_names = merge_names(&[
        "src/names/female-names-v1-14376.txt",
        "src/names/female-names-v2-16673.txt",
    ]);

    let male_names = merge_names(&[
        "src/names/male-names-v1-14999.txt",
        "src/names/male-names-v2-21904.txt",
    ]);

    let surnames = merge_names(&[
        "src/names/surnames-184624.txt",
    ]);

    NamePool { female: female_names, male: male_names, surname: surnames }
}

fn merge_names(filenames: &[&str]) -> Vec<String> {
    let mut distinct = HashSet::new();
    for filename in filenames {
        let names = load_from_file(filename);
        for item in names {
            distinct.insert(item);
        }
    }

    let mut result = vec![];
    for item in distinct {
        result.push(item);
    }

    result
}

fn load_from_file(filename: &str) -> HashSet<String> {
    let content = Box::new(file::get_text(filename).unwrap_or("".to_string()));
    let mut names = HashSet::new();
    for line in content.as_ref().split_whitespace() {
        names.insert(line.to_string());
    }
    names
}

fn main() {
    let pool = load_name_pool();
    rocket::ignite()
        .manage(pool)
        .mount("/", routes![index]).launch();
}
<commit_msg>Simplify randomization.<commit_after>#![feature(plugin)]
#![plugin(rocket_codegen)]

extern crate rocket;
extern crate rocket_contrib;

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

extern crate file;
extern crate rand;

use rocket_contrib::JSON;

use std::collections::HashSet;

use rand::Rng;

#[derive(Serialize, Debug, Clone, Copy)]
enum Sex {
    Male,
    Female
}

impl rand::Rand for Sex {
    fn rand<R: Rng>(rng: &mut R) -> Self {
        let variants = [Sex::Male, Sex::Female];
        *rng.choose(&variants).unwrap()
    }
}

#[derive(Serialize, Debug)]
struct Person {
    sex: Sex,
    first_name: String,
    second_name: String,
    last_name: String
}

#[derive(Debug)]
struct NamePool {
    female: Vec<String>,
    male: Vec<String>,
    surname: Vec<String>,
}

impl NamePool {
    fn random_name(&self) -> Person {
        fn random_value(vec: &Vec<String>) -> &String {
            // todo unwrap_or
            rand::thread_rng().choose(vec).unwrap()
        }

        let sex: Sex = rand::random();
        let first_name = match sex {
            Sex::Male => random_value(&self.male),
            Sex::Female => random_value(&self.female)
        };

        let person = Person {
            sex: sex,
            first_name: first_name.to_string(),
            second_name: random_value(&self.male).to_string(),
            last_name: random_value(&self.surname).to_string()
        };

        println!("{:?}", person);
        person
    }
}

#[get("/")]
fn index(pool: rocket::State<NamePool>) -> JSON<Person> {
    let person = pool.random_name();
    JSON(person)
}

fn load_name_pool() -> NamePool {
    let female_names = merge_names(&[
        "src/names/female-names-v1-14376.txt",
        "src/names/female-names-v2-16673.txt",
    ]);

    let male_names = merge_names(&[
        "src/names/male-names-v1-14999.txt",
        "src/names/male-names-v2-21904.txt",
    ]);

    let surnames = merge_names(&[
        "src/names/surnames-184624.txt",
    ]);

    NamePool { female: female_names, male: male_names, surname: surnames }
}

fn merge_names(filenames: &[&str]) -> Vec<String> {
    let mut distinct = HashSet::new();
    for filename in filenames {
        let names = load_from_file(filename);
        for item in names {
            distinct.insert(item);
        }
    }

    let mut result = vec![];
    for item in distinct {
        result.push(item);
    }

    result
}

fn load_from_file(filename: &str) -> HashSet<String> {
    let content = Box::new(file::get_text(filename).unwrap_or("".to_string()));
    let mut names = HashSet::new();
    for line in content.as_ref().split_whitespace() {
        names.insert(line.to_string());
    }
    names
}

fn main() {
    let pool = load_name_pool();
    rocket::ignite()
        .manage(pool)
        .mount("/", routes![index]).launch();
}
<|endoftext|>


<commit_before>// Generate an identity like so:
//
// ```bash
// openssl req -x509 -newkey rsa:4096 -nodes -keyout localhost.key -out localhost.crt -days 3650
// openssl pkcs12 -export -out identity.p12 -inkey localhost.key -in localhost.crt --password mypass
//
// ```

extern crate iron;
extern crate hyper_native_tls;

fn main() {
    // Avoid unused errors due to conditional compilation ('native-tls-example' feature is not default)
    use hyper_native_tls::NativeTlsServer;
    use iron::{Iron, Request, Response};
    use iron::status;
    use std::result::Result;

    let ssl = NativeTlsServer::new("identity.p12", "mypass").unwrap();

    match Iron::new(|_: &mut Request| {
        Ok(Response::with((status::Ok, "Hello world!")))
    }).https("127.0.0.1:3000", ssl) {
        Result::Ok(listening) => println!("{:?}", listening),
        Result::Err(err) => panic!("{:?}", err),
    }
    // curl -vvvv https://127.0.0.1:3000/ -k
}<commit_msg>Add dummy message for new connection<commit_after>// Generate an identity like so:
//
// ```bash
// openssl req -x509 -newkey rsa:4096 -nodes -keyout localhost.key -out localhost.crt -days 3650
// openssl pkcs12 -export -out identity.p12 -inkey localhost.key -in localhost.crt --password mypass
//
// ```

extern crate iron;
extern crate hyper_native_tls;

fn main() {
    // Avoid unused errors due to conditional compilation ('native-tls-example' feature is not default)
    use hyper_native_tls::NativeTlsServer;
    use iron::{Iron, Request, Response};
    use iron::status;
    use std::result::Result;

    let ssl = NativeTlsServer::new("identity.p12", "mypass").unwrap();

    match Iron::new(|_: &mut Request| {
        println!("Got an incoming connection!");
        Ok(Response::with((status::Ok, "Hello world!")))
    }).https("127.0.0.1:3000", ssl) {
        Result::Ok(listening) => println!("{:?}", listening),
        Result::Err(err) => panic!("{:?}", err),
    }
    // curl -vvvv https://127.0.0.1:3000/ -k
}<|endoftext|>


<commit_before>#[macro_use]
extern crate regex ;
#[macro_use]
extern crate nom ;

use std::str::FromStr ;
use std::io::Write ;
use std::str ;

use nom::{IResult,digit,multispace};
use nom::IResult::*;

use SExpr::* ;

mod common ;
mod conf ;
mod parse ;
mod solver ;

use common::* ;

#[derive(Debug,Clone)]
struct SVar { pub id: String }

#[derive(Debug,Clone)]
enum SExpr {
  Var(String),
  SVar0(SVar),
  SVar1(SVar),
  BConst(bool),
  IConst(usize),
  RConst(usize,usize),
  Lambda(String, Vec<SExpr>),
}

#[derive(Debug,Clone,Copy)]
struct Offset(usize,usize) ;

impl PrintSmt2<Offset> for SExpr {
  fn to_smt2(& self, writer: & mut Write, offset: Offset) -> IoResUnit {
    match * self {
      Var(ref s) => write!(writer, "|{}|", s),
      SVar0(ref sv) => write!(writer, "|{}@{}|", sv.id, offset.0),
      SVar1(ref sv) => write!(writer, "|{}@{}|", sv.id, offset.1),
      BConst(ref b) => write!(writer, "{}", b),
      IConst(ref i) => write!(writer, "{}", i),
      RConst(ref n, ref d) => write!(writer, "(/ {} {})", n, d),
      Lambda(ref sym, ref args) => {
        try!( write!(writer, "({}", sym) ) ;
        for arg in args {
          try!( arg.to_smt2(writer, offset) )
        } ;
        write!(writer, ")")
      },
    }
  }
}

named!{ var<SExpr>,
  chain!(
    tag!("|") ~
    id: is_not!("@|") ~
    int: opt!(
      preceded!(
        char!('@'),
        alt!( char!('0') | char!('1') )
      )
    ) ~
    tag!("|"),
    || match int {
      None => Var(
        str::from_utf8(id).unwrap().to_string()
      ),
      Some('0') => SVar0(
        SVar {
          id: str::from_utf8(id).unwrap().to_string()
        }
      ),
      Some('1') => SVar1(
        SVar {
          id: str::from_utf8(id).unwrap().to_string()
        }
      ),
      _ => unreachable!(),
    }
  )
}

named!{ b_const<SExpr>,
  map_res!(
    alt!( tag!("true") | tag!("false") ),
    |s| match FromStr::from_str(str::from_utf8(s).unwrap()) {
      Err(e) => Err(e),
      Ok(b) => Ok(BConst(b)),
    }
  )
}

named!{ i_const<SExpr>,
  map_res!(
    map_res!(digit, str::from_utf8),
    |s| match FromStr::from_str(s) {
      Err(e) => Err(e),
      Ok(i) => Ok(IConst(i)),
    }
  )
}

named!{ r_const<SExpr>,
  chain!(
    tag!("(") ~
    opt!(multispace) ~
    tag!("/") ~
    multispace ~
    lhs: digit ~
    multispace ~
    rhs: digit ~
    opt!(multispace) ~
    tag!(")"),
    || RConst(
      FromStr::from_str(str::from_utf8(lhs).unwrap()).unwrap(),
      FromStr::from_str(str::from_utf8(rhs).unwrap()).unwrap()
    )
  )
}

named!{ lambda<SExpr>,
  chain!(
    tag!("(") ~
    opt!(multispace) ~
    sym: alt!(
      tag!("*") | tag!("/")
    ) ~
    multispace ~
    args: separated_list!(
      multispace, sexpr
    ) ~
    opt!(multispace) ~
    tag!(")"),
    || Lambda(
      FromStr::from_str(str::from_utf8(sym).unwrap()).unwrap(),
      args
    )
  )
}

named!{ sexpr<SExpr>,
  alt!(
    i_const | r_const | b_const | var | lambda |
    delimited!(
      char!('('),
      delimited!(
        opt!(multispace),
        sexpr,
        opt!(multispace)
      ),
      char!(')')
    )
  )
}

named!{ top_sexpr<SExpr>,
  delimited!(
    opt!(multispace),
    sexpr,
    opt!(multispace)
  )
}

fn print_parse_result<'a, I>(res: IResult<'a, I, SExpr>) {
  match res {
    Done(_,b) => println!("> {:?}", b),
    Error(e) => println!("> error | {:?}", e),
    Incomplete(n) => println!("> incomplete | {:?}", n),
  } ;
  println!("")
}

pub fn run_common() {
  let bool_str = b"false" ;
  println!("sexpr(\"{}\")", str::from_utf8(bool_str).unwrap()) ;
  print_parse_result(top_sexpr(bool_str)) ;

  let int_str = b"742" ;
  println!("sexpr(\"{}\")", str::from_utf8(int_str).unwrap()) ;
  print_parse_result(top_sexpr(int_str)) ;

  let rat_str = b"(/ 742 5)" ;
  println!("sexpr(\"{}\")", str::from_utf8(rat_str).unwrap()) ;
  print_parse_result(top_sexpr(rat_str)) ;

  let var_str = b"|a fucking identifier|" ;
  println!("sexpr(\"{}\")", str::from_utf8(var_str).unwrap()) ;
  print_parse_result(top_sexpr(var_str)) ;

  let var_str = b"(|a fucking identifier|)" ;
  println!("sexpr(\"{}\")", str::from_utf8(var_str).unwrap()) ;
  print_parse_result(top_sexpr(var_str)) ;

  let svar_str = b"|a fucking state var @0|" ;
  println!("sexpr(\"{}\")", str::from_utf8(svar_str).unwrap()) ;
  print_parse_result(top_sexpr(svar_str)) ;

  let svar_str = b"|a fucking state var @1|" ;
  println!("sexpr(\"{}\")", str::from_utf8(svar_str).unwrap()) ;
  print_parse_result(top_sexpr(svar_str)) ;

  let expr_str = b"(* |svar  @1| 7 (/ 7 352))" ;
  println!("sexpr(\"{}\")", str::from_utf8(expr_str).unwrap()) ;
  print_parse_result(top_sexpr(expr_str)) ;

  let expr_str = b"( (* |svar  @1| 7 (/ 7 352))      )" ;
  println!("sexpr(\"{}\")", str::from_utf8(expr_str).unwrap()) ;
  print_parse_result(top_sexpr(expr_str)) ;

  ()
}

pub fn run_common_file() {
  use std::io::{BufReader} ;
  use std::fs::File ;
  use std::path::Path ;

  use nom::{ReadProducer, Stepper} ;
  use nom::StepperState::* ;

  let path = Path::new("rsc/test") ;
  let f = File::open(path).unwrap() ;
  let reader = BufReader::new(f) ;
  let rp = ReadProducer::new(reader, 1000) ;
  let mut stepper = Stepper::new(rp) ;

  loop {
    match stepper.step(top_sexpr) {
      Value(expr) => println!("| {:?}", expr),
      step => { println!("\\ {:?}", step) ; break }
    }
  } ;

  ()
}

pub fn run_solver() {
  use ::conf::* ;
  use ::solver::* ;
  use std::process::Command ;

  let conf = SolverConf::z3() ;
  let cmd = Command::new("z3") ;

  let mut solver = match Solver::mk(cmd, conf, ()) {
    Ok(solver) => solver,
    Err(e) => panic!("{:?}", e),
  } ;

  let v1 = Var("v1".to_string()) ;
  let sv = SVar{ id: "sv".to_string() } ;
  let sv_at_0 = SVar0(sv) ;
  let lambda1 = Lambda(
    "and".to_string(), vec![v1.clone(), sv_at_0.clone()]
  ) ;
  let lambda2 = Lambda(
    "not".to_string(), vec![sv_at_0.clone()]
  ) ;
  let offset1 = Offset(7,6) ;
  let offset2 = Offset(6,5) ;

  println!("declaring {:?}", v1) ;
  solver.declare_fun(& v1, offset1, &[], "bool") ;
  println!("declaring {:?}, offset is {:?}", sv_at_0, offset1) ;
  solver.declare_fun(& sv_at_0, offset1, &[], "bool") ;
  println!("asserting {:?}, offset is {:?}", lambda1, offset1) ;
  solver.assert(& lambda1, offset1) ;
  println!("check-sat") ;
  solver.check_sat() ;
  match solver.parse_check_sat() {
    Ok(true) => println!("sat"),
    Ok(false) => println!("unsat"),
    Err(e) => println!("error: {:?}", e),
  } ;
  println!("declaring {:?}, offset is {:?}", sv_at_0, offset2) ;
  solver.declare_fun(& sv_at_0, offset2, &[], "bool") ;
  println!("asserting {:?}, offset is {:?}", lambda2, offset2) ;
  solver.assert(& lambda2, offset2) ;
  println!("check-sat") ;
  solver.check_sat() ;
  match solver.parse_check_sat() {
    Ok(true) => println!("sat"),
    Ok(false) => println!("unsat"),
    Err(e) => println!("error: {:?}", e),
  } ;
  println!("asserting {:?}, offset is {:?}", lambda2, offset1) ;
  solver.assert(& lambda2, offset1) ;
  println!("check-sat") ;
  solver.check_sat() ;
  match solver.parse_check_sat() {
    Ok(true) => println!("sat"),
    Ok(false) => println!("unsat"),
    Err(e) => println!("error: {:?}", e),
  } ;
  ()
}

fn main() {
  println!("\n") ;

  run_common() ;

  println!("\n") ;

  run_common_file() ;

  println!("\n") ;

  run_solver() ;

  println!("\n") ;

  ()
}

<commit_msg>Minor modifications in main<commit_after>#[macro_use]
extern crate regex ;
#[macro_use]
extern crate nom ;

use std::str::FromStr ;
use std::io::Write ;
use std::str ;

use nom::{IResult,digit,multispace};
use nom::IResult::*;

use SExpr::* ;

mod common ;
mod conf ;
mod parse ;
mod solver ;

use common::* ;

#[derive(Debug,Clone)]
struct SVar { pub id: String }

#[derive(Debug,Clone)]
enum SExpr {
  Var(String),
  SVar0(SVar),
  SVar1(SVar),
  BConst(bool),
  IConst(usize),
  RConst(usize,usize),
  Lambda(String, Vec<SExpr>),
}

#[derive(Debug,Clone,Copy)]
struct Offset(usize,usize) ;

impl PrintSmt2<Offset> for SExpr {
  fn to_smt2(& self, writer: & mut Write, offset: Offset) -> IoResUnit {
    match * self {
      Var(ref s) => write!(writer, "|{}|", s),
      SVar0(ref sv) => write!(writer, "|{}@{}|", sv.id, offset.0),
      SVar1(ref sv) => write!(writer, "|{}@{}|", sv.id, offset.1),
      BConst(ref b) => write!(writer, "{}", b),
      IConst(ref i) => write!(writer, "{}", i),
      RConst(ref n, ref d) => write!(writer, "(/ {} {})", n, d),
      Lambda(ref sym, ref args) => {
        try!( write!(writer, "({}", sym) ) ;
        for arg in args {
          try!( arg.to_smt2(writer, offset) )
        } ;
        write!(writer, ")")
      },
    }
  }
}

named!{ var<SExpr>,
  chain!(
    tag!("|") ~
    id: is_not!("@|") ~
    int: opt!(
      preceded!(
        char!('@'),
        alt!( char!('0') | char!('1') )
      )
    ) ~
    tag!("|"),
    || match int {
      None => Var(
        str::from_utf8(id).unwrap().to_string()
      ),
      Some('0') => SVar0(
        SVar {
          id: str::from_utf8(id).unwrap().to_string()
        }
      ),
      Some('1') => SVar1(
        SVar {
          id: str::from_utf8(id).unwrap().to_string()
        }
      ),
      _ => unreachable!(),
    }
  )
}

named!{ b_const<SExpr>,
  map_res!(
    alt!( tag!("true") | tag!("false") ),
    |s| match FromStr::from_str(str::from_utf8(s).unwrap()) {
      Err(e) => Err(e),
      Ok(b) => Ok(BConst(b)),
    }
  )
}

named!{ i_const<SExpr>,
  map_res!(
    map_res!(digit, str::from_utf8),
    |s| match FromStr::from_str(s) {
      Err(e) => Err(e),
      Ok(i) => Ok(IConst(i)),
    }
  )
}

named!{ r_const<SExpr>,
  chain!(
    tag!("(") ~
    opt!(multispace) ~
    tag!("/") ~
    multispace ~
    lhs: digit ~
    multispace ~
    rhs: digit ~
    opt!(multispace) ~
    tag!(")"),
    || RConst(
      FromStr::from_str(str::from_utf8(lhs).unwrap()).unwrap(),
      FromStr::from_str(str::from_utf8(rhs).unwrap()).unwrap()
    )
  )
}

named!{ lambda<SExpr>,
  chain!(
    tag!("(") ~
    opt!(multispace) ~
    sym: alt!(
      tag!("*") | tag!("/")
    ) ~
    multispace ~
    args: separated_list!(
      multispace, sexpr
    ) ~
    opt!(multispace) ~
    tag!(")"),
    || Lambda(
      FromStr::from_str(str::from_utf8(sym).unwrap()).unwrap(),
      args
    )
  )
}

named!{ sexpr<SExpr>,
  alt!(
    i_const | r_const | b_const | var | lambda |
    delimited!(
      char!('('),
      delimited!(
        opt!(multispace),
        sexpr,
        opt!(multispace)
      ),
      char!(')')
    )
  )
}

named!{ top_sexpr<SExpr>,
  delimited!(
    opt!(multispace),
    sexpr,
    opt!(multispace)
  )
}

fn print_parse_result<'a, I>(res: IResult<'a, I, SExpr>) {
  match res {
    Done(_,b) => println!("> {:?}", b),
    Error(e) => println!("> error | {:?}", e),
    Incomplete(n) => println!("> incomplete | {:?}", n),
  } ;
  println!("")
}

pub fn run_common() {
  let bool_str = b"false" ;
  println!("sexpr(\"{}\")", str::from_utf8(bool_str).unwrap()) ;
  print_parse_result(top_sexpr(bool_str)) ;

  let int_str = b"742" ;
  println!("sexpr(\"{}\")", str::from_utf8(int_str).unwrap()) ;
  print_parse_result(top_sexpr(int_str)) ;

  let rat_str = b"(/ 742 5)" ;
  println!("sexpr(\"{}\")", str::from_utf8(rat_str).unwrap()) ;
  print_parse_result(top_sexpr(rat_str)) ;

  let var_str = b"|a fucking identifier|" ;
  println!("sexpr(\"{}\")", str::from_utf8(var_str).unwrap()) ;
  print_parse_result(top_sexpr(var_str)) ;

  let var_str = b"(|a fucking identifier|)" ;
  println!("sexpr(\"{}\")", str::from_utf8(var_str).unwrap()) ;
  print_parse_result(top_sexpr(var_str)) ;

  let svar_str = b"|a fucking state var @0|" ;
  println!("sexpr(\"{}\")", str::from_utf8(svar_str).unwrap()) ;
  print_parse_result(top_sexpr(svar_str)) ;

  let svar_str = b"|a fucking state var @1|" ;
  println!("sexpr(\"{}\")", str::from_utf8(svar_str).unwrap()) ;
  print_parse_result(top_sexpr(svar_str)) ;

  let expr_str = b"(* |svar  @1| 7 (/ 7 352))" ;
  println!("sexpr(\"{}\")", str::from_utf8(expr_str).unwrap()) ;
  print_parse_result(top_sexpr(expr_str)) ;

  let expr_str = b"( (* |svar  @1| 7 (/ 7 352))      )" ;
  println!("sexpr(\"{}\")", str::from_utf8(expr_str).unwrap()) ;
  print_parse_result(top_sexpr(expr_str)) ;

  ()
}

pub fn run_common_file() {
  use std::io::{BufReader} ;
  use std::fs::File ;
  use std::path::Path ;

  use nom::{ReadProducer, Stepper} ;
  use nom::StepperState::* ;

  let path = Path::new("rsc/test") ;
  let f = File::open(path).unwrap() ;
  let reader = BufReader::new(f) ;
  let rp = ReadProducer::new(reader, 1000) ;
  let mut stepper = Stepper::new(rp) ;

  loop {
    match stepper.step(top_sexpr) {
      Value(expr) => println!("| {:?}", expr),
      step => { println!("\\ {:?}", step) ; break }
    }
  } ;

  ()
}

pub fn run_solver() {
  use ::conf::* ;
  use ::solver::* ;
  use std::process::Command ;

  let conf = SolverConf::z3() ;
  let cmd = Command::new("z3") ;

  let mut solver = match Solver::mk(cmd, conf, ()) {
    Ok(solver) => solver,
    Err(e) => panic!("{:?}", e),
  } ;

  let v1 = Var("v1".to_string()) ;
  let sv = SVar{ id: "sv".to_string() } ;
  let sv_at_0 = SVar0(sv) ;
  let lambda1 = Lambda(
    "and".to_string(), vec![v1.clone(), sv_at_0.clone()]
  ) ;
  let lambda2 = Lambda(
    "not".to_string(), vec![sv_at_0.clone()]
  ) ;
  let offset1 = Offset(7,6) ;
  let offset2 = Offset(6,5) ;

  println!("declaring {:?}", v1) ;
  solver.declare_fun(& v1, offset1, &[], "bool") ;
  println!("declaring {:?}, offset is {:?}", sv_at_0, offset1) ;
  solver.declare_fun(& sv_at_0, offset1, &[], "bool") ;

  println!("asserting {:?}, offset is {:?}", lambda1, offset1) ;
  solver.assert(& lambda1, offset1) ;

  println!("check-sat") ;
  solver.check_sat() ;
  match solver.parse_check_sat() {
    Ok(true) => println!("sat"),
    Ok(false) => println!("unsat"),
    Err(e) => println!("error: {:?}", e),
  } ;

  println!("declaring {:?}, offset is {:?}", sv_at_0, offset2) ;
  solver.declare_fun(& sv_at_0, offset2, &[], "bool") ;

  println!("asserting {:?}, offset is {:?}", lambda2, offset2) ;
  solver.assert(& lambda2, offset2) ;

  println!("check-sat") ;
  solver.check_sat() ;
  match solver.parse_check_sat() {
    Ok(true) => println!("sat"),
    Ok(false) => println!("unsat"),
    Err(e) => println!("error: {:?}", e),
  } ;

  println!("asserting {:?}, offset is {:?}", lambda2, offset1) ;
  solver.assert(& lambda2, offset1) ;

  println!("check-sat") ;
  solver.check_sat() ;
  match solver.parse_check_sat() {
    Ok(true) => println!("sat"),
    Ok(false) => println!("unsat"),
    Err(e) => println!("error: {:?}", e),
  } ;

  solver.kill() ;

  ()
}

fn main() {
  println!("\n") ;

  run_common() ;

  println!("\n") ;

  run_common_file() ;

  println!("\n") ;

  run_solver() ;

  println!("\n") ;

  ()
}

<|endoftext|>