<commit_before>mod collision;

use std::cell::Cell;

struct Coordinates {
    x: Cell<i32>,
    y: Cell<i32>,
}

fn main() {
    let bike_one = Coordinates { x: Cell::new(0), y: Cell::new(50) };
    let bike_two = Coordinates { x: Cell::new(0), y: Cell::new(50) };
    let mut one_pos = vec![];
    let mut two_pos = vec![];
    let mut all_pos = vec![];
    let mut bike_stats = vec![];

    move_up(&bike_one.y);
    move_up(&bike_two.y);
    add_positions(&mut one_pos, &bike_one.y, &bike_one.x);
    add_positions(&mut two_pos, &bike_two.y, &bike_two.x);
    combined_positions(&mut all_pos, &mut one_pos, &mut two_pos);
    collision::alive_or_dead(&mut one_pos, &mut two_pos, &mut bike_stats);

    move_down(&bike_one.y);
    move_down(&bike_two.y);
    add_positions(&mut one_pos, &bike_one.y, &bike_one.x);
    add_positions(&mut two_pos, &bike_two.y, &bike_two.x);
    combined_positions(&mut all_pos, &mut one_pos, &mut two_pos);
    collision::alive_or_dead(&mut one_pos, &mut two_pos, &mut bike_stats);

    move_right(&bike_one.x);
    move_right(&bike_two.x);
    add_positions(&mut one_pos, &bike_one.y, &bike_one.x);
    add_positions(&mut two_pos, &bike_two.y, &bike_two.x);
    combined_positions(&mut all_pos, &mut one_pos, &mut two_pos);
    collision::alive_or_dead(&mut one_pos, &mut two_pos, &mut bike_stats);

    move_left(&bike_one.x);
    move_left(&bike_two.x);
    add_positions(&mut one_pos, &bike_one.y, &bike_one.x);
    add_positions(&mut two_pos, &bike_two.y, &bike_two.x);
    combined_positions(&mut all_pos, &mut one_pos, &mut two_pos);
    collision::alive_or_dead(&mut one_pos, &mut two_pos, &mut bike_stats);

    println!("Bike One");
    println!("X is {:?}, Y is {:?}", bike_one.x, bike_one.y);
    println!("{:?}", one_pos);

    println!("Bike Two");
    println!("X is {:?}, Y is {:?}", bike_two.x, bike_two.y);
    println!("{:?}", two_pos);

    println!("Final combined positions are: {:?}", all_pos)

}

fn add_positions<'a>(v_cc: &'a mut Vec<i32>, y: &Cell<i32>, x: &Cell<i32>) -> &'a mut Vec<i32> {
    v_cc.push(x.get());
    v_cc.push(y.get());
    v_cc
}

fn combined_positions<'a>(a_p: &'a mut Vec<i32>, o_p: &mut Vec<i32>, t_p: &mut Vec<i32>) -> &'a mut Vec<i32> {
    a_p.extend_from_slice(o_p);
    a_p.extend_from_slice(t_p);
    a_p
}

fn move_up(y_cord: &Cell<i32>) -> &Cell<i32> {
    y_cord.set(y_cord.get() + 1);
    y_cord
}

fn move_down(y_cord: &Cell<i32>) -> &Cell<i32> {
    y_cord.set(y_cord.get() - 1);
    y_cord
}

fn move_right(x_cord: &Cell<i32>) -> &Cell<i32> {
    x_cord.set(x_cord.get() + 1);
    x_cord
}

fn move_left(x_cord: &Cell<i32>) -> &Cell<i32> {
    x_cord.set(x_cord.get() - 1);
    x_cord
}

#[test]
fn it_can_move() {
    let bike_one = Coordinates { x: Cell::new(0), y: Cell::new(0) };

    assert_eq!(0, bike_one.y.get());

    // test it can move up and that move logic is valid

    move_up(&bike_one.y);
    move_up(&bike_one.y);
    move_up(&bike_one.y);
    move_up(&bike_one.y);

    assert_eq!(4, bike_one.y.get());

    for _ in 0..19 { // _ instead of x so that rust does not complain about x not being used
        move_up(&bike_one.y); // moves up 19 times
    }

    assert_eq!(23, bike_one.y.get());

    // test it can move down

    for _ in 0..19 {
        move_down(&bike_one.y);
    }

    assert_eq!(4, bike_one.y.get());

    // test it can move right

    for _ in 0..19 {
        move_right(&bike_one.x);
    }

    assert_eq!(19, bike_one.x.get());

    // test it can move left

    for _ in 0..10 {
        move_left(&bike_one.x);
    }

    assert_eq!(9, bike_one.x.get());
}

#[test]
fn it_can_log_all_positions() {
    let bike_one = Coordinates { x: Cell::new(0), y: Cell::new(50) };
    let bike_two = Coordinates { x: Cell::new(100), y: Cell::new(50) };
    let mut one_pos = vec![];
    let mut two_pos = vec![];
    let mut all_pos = vec![];

    move_up(&bike_one.y);
    move_up(&bike_two.y);
    add_positions(&mut one_pos, &bike_one.y, &bike_one.x);

    assert_eq!(51, bike_one.x.get() + bike_one.y.get());

    add_positions(&mut two_pos, &bike_two.y, &bike_two.x);

    assert_eq!(151, bike_two.x.get() + bike_two.y.get());

    combined_positions(&mut all_pos, &mut one_pos, &mut two_pos);

    let sum = all_pos.iter().fold(0, |acc, &x| acc + x);

    assert_eq!(202, sum);
}
<commit_msg>shortened LOC - more test driven now so less need for cargo run to prove it works - just cargo test<commit_after>mod collision;

use std::cell::Cell;

struct Coordinates {
    x: Cell<i32>,
    y: Cell<i32>,
}

fn main() {
    let bike_one = Coordinates { x: Cell::new(0), y: Cell::new(50) };
    let bike_two = Coordinates { x: Cell::new(0), y: Cell::new(50) };
    let mut one_pos = vec![];
    let mut two_pos = vec![];
    let mut all_pos = vec![];
    let mut bike_stats = vec![];

    move_up(&bike_one.y);
    move_down(&bike_two.y);
    add_positions(&mut one_pos, &bike_one.y, &bike_one.x);
    add_positions(&mut two_pos, &bike_two.y, &bike_two.x);
    combined_positions(&mut all_pos, &mut one_pos, &mut two_pos);
    collision::alive_or_dead(&mut one_pos, &mut two_pos, &mut bike_stats);

    move_right(&bike_one.x);
    move_left(&bike_two.x);
    add_positions(&mut one_pos, &bike_one.y, &bike_one.x);
    add_positions(&mut two_pos, &bike_two.y, &bike_two.x);
    combined_positions(&mut all_pos, &mut one_pos, &mut two_pos);
    collision::alive_or_dead(&mut one_pos, &mut two_pos, &mut bike_stats);

    println!("Bike One: X is {:?}, Y is {:?}\nPositions: {:?}\n", bike_one.x, bike_one.y, one_pos);
    println!("Bike Two: X is {:?}, Y is {:?}\nPositions: {:?}\n", bike_two.x, bike_two.y, two_pos);
    println!("Combined positions are: {:?}", all_pos)
}

fn add_positions<'a>(v_cc: &'a mut Vec<i32>, y: &Cell<i32>, x: &Cell<i32>) -> &'a mut Vec<i32> {
    v_cc.push(x.get());
    v_cc.push(y.get());
    v_cc
}

fn combined_positions<'a>(a_p: &'a mut Vec<i32>, o_p: &mut Vec<i32>, t_p: &mut Vec<i32>) -> &'a mut Vec<i32> {
    a_p.extend_from_slice(o_p);
    a_p.extend_from_slice(t_p);
    a_p
}

fn move_up(y_cord: &Cell<i32>) -> &Cell<i32> {
    y_cord.set(y_cord.get() + 1);
    y_cord
}

fn move_down(y_cord: &Cell<i32>) -> &Cell<i32> {
    y_cord.set(y_cord.get() - 1);
    y_cord
}

fn move_right(x_cord: &Cell<i32>) -> &Cell<i32> {
    x_cord.set(x_cord.get() + 1);
    x_cord
}

fn move_left(x_cord: &Cell<i32>) -> &Cell<i32> {
    x_cord.set(x_cord.get() - 1);
    x_cord
}

#[test]
fn it_can_move() {
    let bike_one = Coordinates { x: Cell::new(0), y: Cell::new(0) };
    assert_eq!(0, bike_one.y.get());

    move_up(&bike_one.y);
    move_up(&bike_one.y);
    move_up(&bike_one.y);
    move_up(&bike_one.y);
    assert_eq!(4, bike_one.y.get());

    for _ in 0..19 {
        move_up(&bike_one.y);
    }
    assert_eq!(23, bike_one.y.get());

    for _ in 0..19 {
        move_down(&bike_one.y);
    }
    assert_eq!(4, bike_one.y.get());

    for _ in 0..19 {
        move_right(&bike_one.x);
    }
    assert_eq!(19, bike_one.x.get());

    for _ in 0..10 {
        move_left(&bike_one.x);
    }
    assert_eq!(9, bike_one.x.get());
}

#[test]
fn it_can_log_all_positions() {
    let bike_one = Coordinates { x: Cell::new(0), y: Cell::new(50) };
    let bike_two = Coordinates { x: Cell::new(100), y: Cell::new(50) };
    let mut one_pos = vec![];
    let mut two_pos = vec![];
    let mut all_pos = vec![];

    move_up(&bike_one.y);
    move_up(&bike_two.y);
    add_positions(&mut one_pos, &bike_one.y, &bike_one.x);
    assert_eq!(51, bike_one.x.get() + bike_one.y.get());

    add_positions(&mut two_pos, &bike_two.y, &bike_two.x);
    assert_eq!(151, bike_two.x.get() + bike_two.y.get());

    combined_positions(&mut all_pos, &mut one_pos, &mut two_pos);
    let sum = all_pos.iter().fold(0, |acc, &x| acc + x);
    assert_eq!(202, sum);
}
<|endoftext|>


<commit_before>use std::net::{TcpListener, TcpStream};

extern crate rust_ofp;
use rust_ofp::ofp_controller::OfpController;
use rust_ofp::ofp_controller::openflow0x01::OF0x01Controller;
use rust_ofp::openflow0x01::{SwitchFeatures, PacketIn, Pattern};
use rust_ofp::openflow0x01::message::{add_flow, Message};

fn main() {
    struct OF0x01;
    impl OF0x01Controller for OF0x01 {
        fn switch_connected(_: u64, _: SwitchFeatures, stream: &mut TcpStream) {
            let prio = 0;
            let pat = Pattern::match_all();
            let message = Message::FlowMod(add_flow(prio, pat, vec![]));
            Self::send_message(1000, message, stream)
        }

        fn switch_disconnected(_: u64) {
        }

        fn packet_in(_: u64, _: u32, _: PacketIn, _: &mut TcpStream) {
        }
    }

    let listener = TcpListener::bind(("127.0.0.1", 6633)).unwrap();
    for stream in listener.incoming() {
        match stream {
            Ok(mut stream) => {
                std::thread::spawn(move || OF0x01::handle_client_connected(&mut stream));
            }
            Err(_) => {
                // connection failed
                panic!("Connection failed")
            }
        }
    }
}
<commit_msg>Fix trait impl for exe controller<commit_after>use std::net::{TcpListener, TcpStream};

extern crate rust_ofp;
use rust_ofp::ofp_controller::OfpController;
use rust_ofp::ofp_controller::openflow0x01::OF0x01Controller;
use rust_ofp::openflow0x01::{SwitchFeatures, PacketIn, Pattern};
use rust_ofp::openflow0x01::message::{add_flow, Message};

fn main() {
    struct OF0x01;
    impl OF0x01Controller for OF0x01 {
        fn new() -> OF0x01 {
            OF0x01 {}
        }

        fn switch_connected(&mut self, _: u64, _: SwitchFeatures, stream: &mut TcpStream) {
            let prio = 0;
            let pat = Pattern::match_all();
            let message = Message::FlowMod(add_flow(prio, pat, vec![]));
            Self::send_message(1000, message, stream)
        }

        fn switch_disconnected(&mut self, _: u64) {}

        fn packet_in(&mut self, _: u64, _: u32, _: PacketIn, _: &mut TcpStream) {}
    }

    let listener = TcpListener::bind(("127.0.0.1", 6633)).unwrap();
    for stream in listener.incoming() {
        match stream {
            Ok(mut stream) => {
                std::thread::spawn(move || OF0x01::handle_client_connected(&mut stream));
            }
            Err(_) => {
                // connection failed
                panic!("Connection failed")
            }
        }
    }
}
<|endoftext|>


<commit_before>#[macro_use] extern crate conrod;
extern crate gfx_device_gl;
extern crate graphics;
extern crate piston;
extern crate piston_window;
extern crate sdl2_window;
extern crate vecmath as vecmath_lib;

use std::path::Path;

use conrod::{Labelable, Positionable, Sizeable, Widget};
use piston::window::{AdvancedWindow, WindowSettings};
use piston_window::{Context, G2d, OpenGL, PistonWindow};
use piston::event_loop::*;
use piston::input::*;
use sdl2_window::Sdl2Window;

mod map;
mod vecmath;

/// A transition requested by a game state.
enum StateTransition {
    /// Stay on this state.
    Continue,
    /// End this state and pop it from the stack.
    End,
    /// Pop this state and replace it with this new state.
    Replace(Box<GameState>),
    /// Keep this state, but pause it and push the state on top of the stack.
    Push(Box<GameState>),
}

/// A state the game can be in.
///
/// The application consists of a stack of states, that can each push other
/// states on the stack and/or pop themselves.
/// Examples of states are the main menu, the character selection, or the game
/// itself; starting the game finishes the character selection, but the main
/// menu remains accessible.
trait GameState {
    fn handle_event(&mut self, event: &piston::input::Event<piston::input::Input>,
                    resources: &mut Resources) -> StateTransition
    {
        StateTransition::Continue
    }
    fn update(&mut self, dt: f64) -> StateTransition;
    fn draw(&mut self, c: Context, g: &mut G2d);
    fn pause(&mut self, resources: &mut Resources) {}
    fn resume(&mut self, resources: &mut Resources) {}
}

struct Resources {
    window: PistonWindow<Sdl2Window>,
    width: u32,
    height: u32,
}

struct App {
    states: Vec<Box<GameState>>,
    resources: Resources,
}

impl App {
    fn new() -> App {
        let width = 200;
        let height = 200;

        // Change this to OpenGL::V2_1 if not working.
        let opengl = OpenGL::V3_2;

        // Create an SDL2 window.
        let window: PistonWindow<Sdl2Window> = WindowSettings::new(
                "fluffy-fiesta",
                [width, height]
            )
            .opengl(opengl)
            .build()
            .unwrap();

        let mut app = App {
            states: Vec::new(),
            resources: Resources {
                window: window,
            width: width,
            height: height,
            },
        };
        let game = Game::new(&mut app.resources);
        app.states.push(Box::new(game));
        app
    }

    fn run(&mut self) {
        loop {
            let transition: StateTransition = if let Some(state) = self.states.last_mut() {
                Self::handle_state(&mut self.resources, state)
            } else {
                break
            };
            match transition {
                StateTransition::Continue => panic!("App::run() got Transition::Continue"),
                StateTransition::End => {
                    self.states.pop().expect("Transition::End with no states");
                }
                StateTransition::Replace(state) => {
                    self.states.pop().expect("Transition::Replace with no states");
                    self.states.push(state);
                }
                StateTransition::Push(state) => {
                    self.states.push(state);
                }
            }
        }
    }

    fn handle_state(resources: &mut Resources, state: &mut Box<GameState>) -> StateTransition {
        state.resume(resources);

        let mut events = resources.window.events();
        while let Some(event) = events.next(&mut resources.window) {
            // Handle generic event
            let transition = state.handle_event(&event, resources);
            match transition {
                StateTransition::Continue => {},
                t => {
                    state.pause(resources);
                    return t;
                }
            }

            // Call update method
            if let Some(u) = event.update_args() {
                let transition = state.update(u.dt);
                match transition {
                    StateTransition::Continue => {},
                    t => {
                        state.pause(resources);
                        return t;
                    }
                }
            }

            // Call draw method
            resources.window.draw_2d(&event, |c, g| state.draw(c, g));
        }
        state.pause(resources);
        StateTransition::End
    }
}

fn main() {
    let mut app = App::new();
    app.run();
}

widget_ids!(struct GameWidgetIds { canvas, resume, quit });

struct Game {
    rotation: f64,  // Rotation for the square.
    ui: conrod::Ui,
    widget_ids: GameWidgetIds,
    capture: bool,
    ui_on: bool,
    // FIXME: Spelling out gfx_device_gl (and direct dep) shouldn't be necessary
    image_map: conrod::image::Map<piston_window::Texture<gfx_device_gl::Resources>>,
    text_texture_cache: conrod::backend::piston_window::GlyphCache,
}

impl Game {
    fn new(resources: &mut Resources) -> Game {
        // Construct our `Ui`.
        let mut ui = conrod::UiBuilder::new().build();

        // Generate the widget identifiers.
        let ids = GameWidgetIds::new(ui.widget_id_generator());

        // Add a `Font` to the `Ui`'s `font::Map` from file.
        let font_path = Path::new("assets/NotoSans-Regular.ttf");
        assert!(font_path.exists());
        ui.fonts.insert_from_file(font_path).unwrap();

        // Create a texture to use for efficiently caching text on the GPU.
        let text_texture_cache =
            conrod::backend::piston_window::GlyphCache::new(&mut resources.window,
                                                            resources.width,
                                                            resources.height);

        // The image map describing each of our widget->image mappings (in our case, none).
        let image_map = conrod::image::Map::new();

        Game {
            rotation: 0.0,
            ui: ui,
            widget_ids: ids,
            capture: false,
            ui_on: false,
            image_map: image_map,
            text_texture_cache: text_texture_cache,
        }
    }
}

impl GameState for Game {
    fn handle_event(&mut self, event: &piston::input::Event<piston::input::Input>,
                    resources: &mut Resources) -> StateTransition
    {
        // Convert the piston event to a conrod event.
        if let Some(ce) = conrod::backend::piston_window::convert_event(event.clone(), &mut resources.window) {
            self.ui.handle_event(ce);
        }

        if self.ui_on {
            let ui = &mut self.ui.set_widgets();

            // Create a background canvas upon which we'll place the button.
            conrod::widget::Canvas::new().floating(true).w_h(100.0, 70.0).pad(10.0).middle()
                .set(self.widget_ids.canvas, ui);

            // Draw the buttons.
            if conrod::widget::Button::new()
                .mid_top_of(self.widget_ids.canvas)
                .w_h(80.0, 20.0)
                .label("Resume")
                .set(self.widget_ids.resume, ui)
                .was_clicked()
            {
                self.ui_on = false;
            }

            if conrod::widget::Button::new()
                .down(10.0)
                .w_h(80.0, 20.0)
                .label("Quit")
                .set(self.widget_ids.quit, ui)
                .was_clicked()
            {
                return StateTransition::End;
            }
        }

        if let Some(Button::Mouse(button)) = event.press_args() {
            println!("Pressed mouse button '{:?}'", button);
        }

        if let Some(Button::Keyboard(key)) = event.press_args() {
            println!("Pressed key '{:?}'", key);
            if key == Key::Escape {
                println!("ui on");
                self.ui_on = true;
                if self.capture {
                    self.capture = false;
                    resources.window.set_capture_cursor(false);
                }
            } else if !self.ui_on && key == Key::C {
                self.capture = !self.capture;
                resources.window.set_capture_cursor(self.capture);
                println!("capture {}", if self.capture { "on" } else { "off" });
            }
        }

        StateTransition::Continue
    }

    fn update(&mut self, dt: f64) -> StateTransition {
        // Rotate 2 radians per second.
        self.rotation += 2.0 * dt;

        StateTransition::Continue
    }

    fn draw(&mut self, c: Context, g: &mut G2d) {
        use graphics::*;

        const GREEN: [f32; 4] = [0.0, 1.0, 0.0, 1.0];
        const RED:   [f32; 4] = [1.0, 0.0, 0.0, 1.0];

        let square = rectangle::square(0.0, 0.0, 150.0);
        let rotation = self.rotation;
        let (x, y) = (100.0, 100.0);

        // Clear the screen.
        clear(GREEN, g);

        let transform = c.transform.trans(x, y)
                                   .rot_rad(rotation)
                                   .trans(-75.0, -75.0);

        // Draw a box rotating around the middle of the screen.
        rectangle(RED, square, transform, g);

        if self.ui_on {
            let primitives = self.ui.draw();
            fn texture_from_image<T>(img: &T) -> &T { img };
            conrod::backend::piston_window::draw(c, g, primitives,
                                                 &mut self.text_texture_cache,
                                                 &self.image_map,
                                                 texture_from_image);
        }
    }
}
<commit_msg>Make the menu into a separate game state<commit_after>#[macro_use] extern crate conrod;
extern crate gfx_device_gl;
extern crate graphics;
extern crate piston;
extern crate piston_window;
extern crate sdl2_window;
extern crate vecmath as vecmath_lib;

use std::path::Path;

use conrod::{Labelable, Positionable, Sizeable, Widget};
use piston::window::{AdvancedWindow, WindowSettings};
use piston_window::{Context, G2d, OpenGL, PistonWindow};
use piston::event_loop::*;
use piston::input::*;
use sdl2_window::Sdl2Window;

mod map;
mod vecmath;

/// A transition requested by a game state.
enum StateTransition {
    /// Stay on this state.
    Continue,
    /// End this state and pop it from the stack.
    End,
    /// Pop this state and replace it with this new state.
    Replace(Box<GameState>),
    /// Keep this state, but pause it and push the state on top of the stack.
    Push(Box<GameState>),
    /// Quit the game completely.
    Quit,
}

/// A state the game can be in.
///
/// The application consists of a stack of states, that can each push other
/// states on the stack and/or pop themselves.
/// Examples of states are the main menu, the character selection, or the game
/// itself; starting the game finishes the character selection, but the main
/// menu remains accessible.
trait GameState {
    fn handle_event(&mut self, event: &piston::input::Event<piston::input::Input>,
                    resources: &mut Resources) -> StateTransition
    {
        StateTransition::Continue
    }
    fn update(&mut self, dt: f64) -> StateTransition;
    fn draw(&mut self, c: Context, g: &mut G2d);
    fn pause(&mut self, resources: &mut Resources) {}
    fn resume(&mut self, resources: &mut Resources) {}
}

struct Resources {
    window: PistonWindow<Sdl2Window>,
    width: u32,
    height: u32,
}

struct App {
    states: Vec<Box<GameState>>,
    resources: Resources,
}

impl App {
    fn new() -> App {
        let width = 200;
        let height = 200;

        // Change this to OpenGL::V2_1 if not working.
        let opengl = OpenGL::V3_2;

        // Create an SDL2 window.
        let window: PistonWindow<Sdl2Window> = WindowSettings::new(
                "fluffy-fiesta",
                [width, height]
            )
            .opengl(opengl)
            .build()
            .unwrap();

        let mut app = App {
            states: Vec::new(),
            resources: Resources {
                window: window,
            width: width,
            height: height,
            },
        };
        let game = Game::new(&mut app.resources);
        app.states.push(Box::new(game));
        app
    }

    fn run(&mut self) {
        loop {
            let transition: StateTransition = if let Some(state) = self.states.last_mut() {
                Self::handle_state(&mut self.resources, state)
            } else {
                break
            };
            match transition {
                StateTransition::Continue => panic!("App::run() got Transition::Continue"),
                StateTransition::End => {
                    self.states.pop().expect("Transition::End with no states");
                }
                StateTransition::Replace(state) => {
                    self.states.pop().expect("Transition::Replace with no states");
                    self.states.push(state);
                }
                StateTransition::Push(state) => {
                    self.states.push(state);
                }
                StateTransition::Quit => break,
            }
        }
    }

    fn handle_state(resources: &mut Resources, state: &mut Box<GameState>) -> StateTransition {
        state.resume(resources);

        let mut events = resources.window.events();
        while let Some(event) = events.next(&mut resources.window) {
            // Handle generic event
            let transition = state.handle_event(&event, resources);
            match transition {
                StateTransition::Continue => {},
                t => {
                    state.pause(resources);
                    return t;
                }
            }

            // Call update method
            if let Some(u) = event.update_args() {
                let transition = state.update(u.dt);
                match transition {
                    StateTransition::Continue => {},
                    t => {
                        state.pause(resources);
                        return t;
                    }
                }
            }

            // Call draw method
            resources.window.draw_2d(&event, |c, g| state.draw(c, g));
        }
        state.pause(resources);
        StateTransition::End
    }
}

fn main() {
    let mut app = App::new();
    app.run();
}

struct Game {
    rotation: f64,  // Rotation for the square.
    capture: bool,
}

impl Game {
    fn new(resources: &mut Resources) -> Game {
        Game {
            rotation: 0.0,
            capture: false,
        }
    }
}

impl GameState for Game {
    fn handle_event(&mut self, event: &piston::input::Event<piston::input::Input>,
                    resources: &mut Resources) -> StateTransition
    {
        if let Some(Button::Mouse(button)) = event.press_args() {
            println!("Pressed mouse button '{:?}'", button);
        }

        if let Some(Button::Keyboard(key)) = event.press_args() {
            println!("Pressed key '{:?}'", key);
            if key == Key::Escape {
                println!("ui on");
                return StateTransition::Push(Box::new(PauseMenu::new(resources)));
            } else if key == Key::C {
                self.capture = !self.capture;
                resources.window.set_capture_cursor(self.capture);
                println!("capture {}", if self.capture { "on" } else { "off" });
            }
        }

        StateTransition::Continue
    }

    fn update(&mut self, dt: f64) -> StateTransition {
        // Rotate 2 radians per second.
        self.rotation += 2.0 * dt;

        StateTransition::Continue
    }

    fn draw(&mut self, c: Context, g: &mut G2d) {
        use graphics::*;

        const GREEN: [f32; 4] = [0.0, 1.0, 0.0, 1.0];
        const RED:   [f32; 4] = [1.0, 0.0, 0.0, 1.0];

        let square = rectangle::square(0.0, 0.0, 150.0);
        let rotation = self.rotation;
        let (x, y) = (100.0, 100.0);

        // Clear the screen.
        clear(GREEN, g);

        let transform = c.transform.trans(x, y)
                                   .rot_rad(rotation)
                                   .trans(-75.0, -75.0);

        // Draw a box rotating around the middle of the screen.
        rectangle(RED, square, transform, g);
    }

    fn pause(&mut self, resources: &mut Resources) {
        if self.capture {
            resources.window.set_capture_cursor(false);
        }
    }

    fn resume(&mut self, resources: &mut Resources) {
        if self.capture {
            resources.window.set_capture_cursor(self.capture);
        }
    }
}

widget_ids!(struct GameWidgetIds { canvas, resume, quit });

struct PauseMenu {
    ui: conrod::Ui,
    widget_ids: GameWidgetIds,
    // FIXME: Spelling out gfx_device_gl (and direct dep) shouldn't be necessary
    image_map: conrod::image::Map<piston_window::Texture<gfx_device_gl::Resources>>,
    text_texture_cache: conrod::backend::piston_window::GlyphCache,
}

impl PauseMenu {
    fn new(resources: &mut Resources) -> PauseMenu {
        // Construct our `Ui`.
        let mut ui = conrod::UiBuilder::new().build();

        // Generate the widget identifiers.
        let ids = GameWidgetIds::new(ui.widget_id_generator());

        // Add a `Font` to the `Ui`'s `font::Map` from file.
        let font_path = Path::new("assets/NotoSans-Regular.ttf");
        assert!(font_path.exists());
        ui.fonts.insert_from_file(font_path).unwrap();

        // Create a texture to use for efficiently caching text on the GPU.
        let text_texture_cache =
            conrod::backend::piston_window::GlyphCache::new(&mut resources.window,
                                                            resources.width,
                                                            resources.height);

        // The image map describing each of our widget->image mappings (in our case, none).
        let image_map = conrod::image::Map::new();

        PauseMenu {
            ui: ui,
            widget_ids: ids,
            image_map: image_map,
            text_texture_cache: text_texture_cache,
        }
    }
}

impl GameState for PauseMenu {
    fn handle_event(&mut self, event: &piston::input::Event<piston::input::Input>,
                    resources: &mut Resources) -> StateTransition
    {
        // Convert the piston event to a conrod event.
        if let Some(ce) = conrod::backend::piston_window::convert_event(event.clone(), &mut resources.window) {
            self.ui.handle_event(ce);
        }

        let ui = &mut self.ui.set_widgets();

        // Create a background canvas upon which we'll place the button.
        conrod::widget::Canvas::new().floating(true).w_h(100.0, 70.0).pad(10.0).middle()
            .set(self.widget_ids.canvas, ui);

        // Draw the buttons.
        if conrod::widget::Button::new()
            .mid_top_of(self.widget_ids.canvas)
            .w_h(80.0, 20.0)
            .label("Resume")
            .set(self.widget_ids.resume, ui)
            .was_clicked()
        {
            StateTransition::End
        } else if conrod::widget::Button::new()
            .down(10.0)
            .w_h(80.0, 20.0)
            .label("Quit")
            .set(self.widget_ids.quit, ui)
            .was_clicked()
        {
            StateTransition::Quit
        } else {
            StateTransition::Continue
        }
    }

    fn update(&mut self, df: f64) -> StateTransition {
        StateTransition::Continue
    }

    fn draw(&mut self, c: Context, g: &mut G2d) {
        let primitives = self.ui.draw();
        fn texture_from_image<T>(img: &T) -> &T { img };
        conrod::backend::piston_window::draw(c, g, primitives,
                                             &mut self.text_texture_cache,
                                             &self.image_map,
                                             texture_from_image);
    }
}
<|endoftext|>


<commit_before>#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]

extern crate walkdir;

use std::ffi::OsString;
use std::env;
use std::path::PathBuf;
use std::process::{Command, Output};
use walkdir::WalkDirIterator;

fn announce(banner: &str) {
    let mut line = String::new();
    for _ in 0..banner.len() {
        line.push('-');
    }
    println!("{}", line);
    println!("{}", banner);
    println!("{}", line);
}

fn print_ident(buf: Vec<u8>) {
    for line in String::from_utf8_lossy(&buf[..]).lines() {
        println!("        {}", line);
    }
}

fn announce_path(path: PathBuf) -> PathBuf {
    println!("{}:", path.file_name().unwrap().to_str().unwrap());
    path
}

fn report_output(output: Output) {
    if output.status.success() {
        print_ident(output.stdout);
    } else {
        print_ident(output.stderr);
    }
    println!("");
}

const CARGO: &'static str = "cargo";
const MIN_DEPTH: usize = 1;
const MAX_DEPTH: usize = 1;

fn main() {
    let mut cmd = Command::new(CARGO);
    let mut banner = String::from("Executing ") + CARGO;
    for arg in env::args().skip(2) {
        cmd.arg(OsString::from(&arg));
        banner = banner + " " + &arg;
    }

    announce(&banner);

    let cwd = env::current_dir().unwrap();
    walkdir::WalkDir::new(cwd)
        .min_depth(MIN_DEPTH)
        .max_depth(MAX_DEPTH)
        .into_iter()
        .filter_entry(|e| e.path().join("Cargo.toml").exists())
        .map(|e| e.ok().unwrap().path().to_path_buf())
        .map(announce_path)
        .map(|p| cmd.current_dir(p).output().unwrap())
        .map(report_output)
        .last();
}
<commit_msg>De-unwrapify<commit_after>#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]

extern crate walkdir;

use std::ffi::OsString;
use std::env;
use std::path::PathBuf;
use std::process::{Command, Output};
use walkdir::WalkDirIterator;

fn announce(banner: &str) {
    let mut line = String::new();
    for _ in 0..banner.len() {
        line.push('-');
    }
    println!("{}", line);
    println!("{}", banner);
    println!("{}", line);
}

fn print_ident(buf: Vec<u8>) {
    for line in String::from_utf8_lossy(&buf[..]).lines() {
        println!("        {}", line);
    }
}

fn announce_path(path: PathBuf) -> PathBuf {
    path.file_name()
        .and_then(|p| p.to_str())
        .map(|p| println!("{}:", p));
    path
}

fn report_output(output: Output) {
    if output.status.success() {
        print_ident(output.stdout);
    } else {
        print_ident(output.stderr);
    }
    println!("");
}

const CARGO: &'static str = "cargo";
const MIN_DEPTH: usize = 1;
const MAX_DEPTH: usize = 1;

fn main() {
    let mut cmd = Command::new(CARGO);
    let mut banner = String::from("Executing ") + CARGO;
    for arg in env::args().skip(2) {
        cmd.arg(OsString::from(&arg));
        banner = banner + " " + &arg;
    }

    announce(&banner);

    let cwd = env::current_dir().unwrap();
    walkdir::WalkDir::new(cwd)
        .min_depth(MIN_DEPTH)
        .max_depth(MAX_DEPTH)
        .into_iter()
        .filter_entry(|e| e.path().join("Cargo.toml").exists())
        .filter_map(|e| e.ok())
        .map(|e| e.path().to_path_buf())
        .map(announce_path)
        .map(|p| cmd.current_dir(p).output().map(report_output))
        .last();
}
<|endoftext|>


<commit_before>extern crate rustc_serialize;
#[macro_use]
extern crate aws_abacus;
#[macro_use]
extern crate log;
extern crate walkdir;
extern crate env_logger;
extern crate docopt;
use docopt::Docopt;
use std::path;
use aws_abacus::elb_log_files;
extern crate chrono;
use chrono::{DateTime, UTC};
use aws_abacus::elb_log_files::ParsingResult;
use std::collections::HashMap;
extern crate urlparse;
use urlparse::{Url, urlparse};

fn main() {
    env_logger::init().unwrap();
    let args: Args = Docopt::new(USAGE)
                            .and_then(|d| d.decode())
                            .unwrap_or_else(|e| e.exit());

    let log_location = &path::Path::new(&args.arg_log_location);
    debug!("Running summary on {}.", log_location.to_str().unwrap());

    let start: Option<DateTime<UTC>> = if args.flag_benchmark {
        Some(UTC::now())
    } else {
        None
    };

    let mut number_of_files = 0;
    let mut number_of_records = 0;
    let mut filenames = Vec::new();
    let mut agg: HashMap<AggregateELBRecord, i64> = HashMap::new();
    match elb_log_files::file_list(log_location, &mut filenames) {
        Ok(num_files) => {
            number_of_files = num_files;
            debug!("Found {} files.", number_of_files);
            number_of_records = elb_log_files::process_files(&filenames, &mut |parsing_result: ParsingResult| {
                parsing_result_handler(parsing_result, &mut agg);
            });
            debug!("Processed {} records in {} files.", number_of_records, num_files);
        },
        Err(e) => {
            println!("ERROR: {}", e);
        },
    };

    for (aggregate, total) in &agg {
        println!("{},{},{},{}", aggregate.system_name, aggregate.day, aggregate.client_address, total);
    };

    match start {
        Some(s) => {
            let end = UTC::now();
            let time = end - s;
            println!("Processed {} files having {} records in {} milliseconds and produced {} aggregates.",
                number_of_files,
                number_of_records,
                time.num_milliseconds(),
                agg.len()
            );
        },
        None => {},
    };
}

#[derive(Clone, Debug, Eq, Hash, PartialEq)]
struct AggregateELBRecord {
    day: String,
    client_address: String,
    system_name: String,
    // public_id: u64,
}

fn parsing_result_handler(parsing_result: ParsingResult, aggregation: &mut HashMap<AggregateELBRecord, i64>) -> () {
    match parsing_result {
        Ok(elb_record) => {
            let url = urlparse(&elb_record.request_url);
            let aer = AggregateELBRecord {
                day: elb_record.timestamp.format("%Y-%m-%d").to_string(),
                client_address: elb_record.client_address.ip().to_string(),
                system_name: parse_system_name(&url).unwrap_or("UNDEFINED_SYSTEM".to_owned()),
                // public_id: elb_record.sent_bytes
            };
            aggregate_record(aer, aggregation);
        },

        Err(errors) => {

        }
    }
}

fn parse_system_name(url: &Url) -> Option<String> {
    match url.get_parsed_query() {
        Some(query_map) => {
            match query_map.get("system") {
                Some(systems) => {
                    Some(systems[0].clone())
                },

                None => {
                    None
                }
            }
        },

        None => {
            None
        }
    }
}

fn aggregate_record(aggregate_record: AggregateELBRecord, aggregation: &mut HashMap<AggregateELBRecord, i64>) -> () {
    let total = aggregation.entry(aggregate_record).or_insert(0);
    *total += 1;
}

const USAGE: &'static str = "
aws-abacus

Usage:
  aws-abacus <log-location>
  aws-abacus (-d | --debug | -b | --benchmark) <log-location>
  aws-abacus (-h | --help)

Options:
  -h --help     Show this screen.
  -d --debug    Turn on debug output
";

#[derive(Debug, RustcDecodable)]
struct Args {
    arg_log_location: String,
    flag_debug: bool,
    flag_benchmark: bool,
}

#[cfg(test)]
mod tests {

    use std::collections::HashMap;
    use ::AggregateELBRecord;
    use ::aggregate_record;

    const TEST_RECORD: &'static str = "2015-08-15T23:43:05.302180Z elb-name 172.16.1.6:54814 \
    172.16.1.5:9000 0.000039 0.145507 0.00003 200 200 0 7582 \
    \"GET http://some.domain.com:80/path0/path1?param0=p0&param1=p1 HTTP/1.1\"\
    ";

    #[test]
	fn inserting_two_records_with_different_values_creates_two_entries_each_recorded_once() {
        let mut agg: HashMap<AggregateELBRecord, i64> = HashMap::new();

        let ar0 = AggregateELBRecord {
            day: "2015-08-15".to_owned(),
            client_address: "172.16.1.6:54814".to_owned(),
            system_name: "sys1".to_owned(),
            public_id: 8880
        };

        let ar1 = AggregateELBRecord {
            day: "2015-08-15".to_owned(),
            client_address: "172.16.1.6:54814".to_owned(),
            system_name: "sys1".to_owned(),
            public_id: 8888
        };

        aggregate_record(ar0, &mut agg);
        aggregate_record(ar1, &mut agg);

        assert_eq!(agg.len(), 2);
        for (_, total) in agg {
            assert_eq!(total, 1)
        }
	}

    #[test]
	fn inserting_two_records_with_the_same_values_increases_the_total_correctly() {
        let mut agg: HashMap<AggregateELBRecord, i64> = HashMap::new();

        let ar0 = AggregateELBRecord {
            day: "2015-08-15".to_owned(),
            client_address: "172.16.1.6:54814".to_owned(),
            system_name: "sys1".to_owned(),
            public_id: 8888
        };

        let ar1 = ar0.clone();
        let ar3 = ar0.clone();

        aggregate_record(ar0, &mut agg);
        aggregate_record(ar1, &mut agg);

        assert_eq!(agg[&ar3], 2);
	}
}
<commit_msg>Reformatted some code.  Got rid of references to the public Id for now.<commit_after>extern crate rustc_serialize;
#[macro_use]
extern crate aws_abacus;
#[macro_use]
extern crate log;
extern crate walkdir;
extern crate env_logger;
extern crate docopt;
use docopt::Docopt;
use std::path;
use aws_abacus::elb_log_files;
extern crate chrono;
use chrono::{DateTime, UTC};
use aws_abacus::elb_log_files::ParsingResult;
use std::collections::HashMap;
extern crate urlparse;
use urlparse::{Url, urlparse};

fn main() {
    env_logger::init().unwrap();
    let args: Args = Docopt::new(USAGE)
                            .and_then(|d| d.decode())
                            .unwrap_or_else(|e| e.exit());

    let log_location = &path::Path::new(&args.arg_log_location);
    debug!("Running summary on {}.", log_location.to_str().unwrap());

    let start: Option<DateTime<UTC>> = if args.flag_benchmark {
        Some(UTC::now())
    } else {
        None
    };

    let mut number_of_files = 0;
    let mut number_of_records = 0;
    let mut filenames = Vec::new();
    let mut agg: HashMap<AggregateELBRecord, i64> = HashMap::new();
    match elb_log_files::file_list(log_location, &mut filenames) {
        Ok(num_files) => {
            number_of_files = num_files;
            debug!("Found {} files.", number_of_files);
            number_of_records = elb_log_files::process_files(&filenames, &mut |parsing_result: ParsingResult| {
                parsing_result_handler(parsing_result, &mut agg);
            });
            debug!("Processed {} records in {} files.", number_of_records, num_files);
        },
        Err(e) => {
            println!("ERROR: {}", e);
        },
    };

    for (aggregate, total) in &agg {
        println!(
            "{},{},{},{}",
            aggregate.system_name,
            aggregate.day,
            aggregate.client_address,
            total
        );
    };

    match start {
        Some(s) => {
            let end = UTC::now();
            let time = end - s;
            println!("Processed {} files having {} records in {} milliseconds and produced {} aggregates.",
                number_of_files,
                number_of_records,
                time.num_milliseconds(),
                agg.len()
            );
        },
        None => {},
    };
}

#[derive(Clone, Debug, Eq, Hash, PartialEq)]
struct AggregateELBRecord {
    day: String,
    client_address: String,
    system_name: String,
}

fn parsing_result_handler(parsing_result: ParsingResult, aggregation: &mut HashMap<AggregateELBRecord, i64>) -> () {
    match parsing_result {
        Ok(elb_record) => {
            let url = urlparse(&elb_record.request_url);
            let aer = AggregateELBRecord {
                day: elb_record.timestamp.format("%Y-%m-%d").to_string(),
                client_address: elb_record.client_address.ip().to_string(),
                system_name: parse_system_name(&url).unwrap_or("UNDEFINED_SYSTEM".to_owned()),
            };
            aggregate_record(aer, aggregation);
        },

        Err(errors) => {

        }
    }
}

fn parse_system_name(url: &Url) -> Option<String> {
    match url.get_parsed_query() {
        Some(query_map) => {
            match query_map.get("system") {
                Some(systems) => {
                    Some(systems[0].clone())
                },

                None => {
                    None
                }
            }
        },

        None => {
            None
        }
    }
}

fn aggregate_record(aggregate_record: AggregateELBRecord, aggregation: &mut HashMap<AggregateELBRecord, i64>) -> () {
    let total = aggregation.entry(aggregate_record).or_insert(0);
    *total += 1;
}

const USAGE: &'static str = "
aws-abacus

Usage:
  aws-abacus <log-location>
  aws-abacus (-d | --debug | -b | --benchmark) <log-location>
  aws-abacus (-h | --help)

Options:
  -h --help     Show this screen.
  -d --debug    Turn on debug output
";

#[derive(Debug, RustcDecodable)]
struct Args {
    arg_log_location: String,
    flag_debug: bool,
    flag_benchmark: bool,
}

#[cfg(test)]
mod tests {

    use std::collections::HashMap;
    use ::AggregateELBRecord;
    use ::aggregate_record;

    const TEST_RECORD: &'static str = "2015-08-15T23:43:05.302180Z elb-name 172.16.1.6:54814 \
    172.16.1.5:9000 0.000039 0.145507 0.00003 200 200 0 7582 \
    \"GET http://some.domain.com:80/path0/path1?param0=p0&param1=p1 HTTP/1.1\"\
    ";

    #[test]
	fn inserting_two_records_with_different_values_creates_two_entries_each_recorded_once() {
        let mut agg: HashMap<AggregateELBRecord, i64> = HashMap::new();

        let ar0 = AggregateELBRecord {
            day: "2015-08-15".to_owned(),
            client_address: "172.16.1.6:54814".to_owned(),
            system_name: "sys1".to_owned(),
            public_id: 8880
        };

        let ar1 = AggregateELBRecord {
            day: "2015-08-15".to_owned(),
            client_address: "172.16.1.6:54814".to_owned(),
            system_name: "sys1".to_owned(),
            public_id: 8888
        };

        aggregate_record(ar0, &mut agg);
        aggregate_record(ar1, &mut agg);

        assert_eq!(agg.len(), 2);
        for (_, total) in agg {
            assert_eq!(total, 1)
        }
	}

    #[test]
	fn inserting_two_records_with_the_same_values_increases_the_total_correctly() {
        let mut agg: HashMap<AggregateELBRecord, i64> = HashMap::new();

        let ar0 = AggregateELBRecord {
            day: "2015-08-15".to_owned(),
            client_address: "172.16.1.6:54814".to_owned(),
            system_name: "sys1".to_owned(),
            public_id: 8888
        };

        let ar1 = ar0.clone();
        let ar3 = ar0.clone();

        aggregate_record(ar0, &mut agg);
        aggregate_record(ar1, &mut agg);

        assert_eq!(agg[&ar3], 2);
	}
}
<|endoftext|>


<commit_before>extern crate lancelot;
extern crate log;

use failure::{Error, Fail};
use log::{error, info, trace};
use std::env;
use std::process;

use lancelot::arch::*;
use lancelot::workspace::Workspace;

// TODO: removeme
use goblin::{Object};

#[derive(Debug, Fail)]
pub enum MainError {
    #[fail(display = "foo")]
    Foo,
}

pub struct Config {
    pub mode: u8,
    pub filename: String,
}

impl Config {
    pub fn from_args(args: env::Args) -> Result<Config, &'static str> {
        let args: Vec<String> = args.collect();

        if args.len() < 3 {
            return Err("not enough arguments: provide `lancelot.exe 32|64 /path/to/input`");
        }

        let mode = match args[1].as_ref() {
            "32" => 32,
            "64" => 64,
            _ => return Err("invalid mode, pick one of `32` or `64`"),
        };

        let filename = args[2].clone();
        trace!("config: parsed filename: {:?}", filename);

        Ok(Config { mode, filename })
    }
}

pub fn setup_logging(_args: &Config) {
    simplelog::TermLogger::init(simplelog::LevelFilter::Info, simplelog::Config::default())
        .expect("failed to setup logging");
}

pub fn run(args: &Config) -> Result<(), Error> {
    info!("filename: {:?}", args.filename);

    if args.mode == 32 {
        let mut ws = Workspace::<Arch32>::from_file(&args.filename)?.load()?;
    } else if args.mode == 64 {
        let mut ws = Workspace::<Arch64>::from_file(&args.filename)?.load()?;

        if ws.loader.get_name() == "Windows/64/PE" {
            if let Ok(Object::PE(pe)) = Object::parse(&ws.buf) {
                let entry = pe.entry;
                let exports: Vec<usize> = pe.exports.iter().map(|exp| exp.offset).collect();

                info!("PE entry: {:#x}", entry);
                ws.make_insn(entry as i64);
                for export in exports.iter() {
                    info!("export: {:#x}", export);
                    ws.make_insn(*export as i64);
                }
                ws.analyze();
            }
        }
    }

    Ok(())
}

fn main() {
    let args = Config::from_args(env::args()).unwrap_or_else(|err| {
        eprintln!("error parsing arguments: {}", err);
        process::exit(1);
    });

    setup_logging(&args);

    if let Err(e) = run(&args) {
        error!("{:?}", e)
    }
}
<commit_msg>main: filter out re-exports<commit_after>extern crate lancelot;
extern crate log;

use failure::{Error, Fail};
use log::{error, info, trace};
use std::env;
use std::process;

use lancelot::arch::*;
use lancelot::workspace::Workspace;

// TODO: removeme
use goblin::{Object};

#[derive(Debug, Fail)]
pub enum MainError {
    #[fail(display = "foo")]
    Foo,
}

pub struct Config {
    pub mode: u8,
    pub filename: String,
}

impl Config {
    pub fn from_args(args: env::Args) -> Result<Config, &'static str> {
        let args: Vec<String> = args.collect();

        if args.len() < 3 {
            return Err("not enough arguments: provide `lancelot.exe 32|64 /path/to/input`");
        }

        let mode = match args[1].as_ref() {
            "32" => 32,
            "64" => 64,
            _ => return Err("invalid mode, pick one of `32` or `64`"),
        };

        let filename = args[2].clone();
        trace!("config: parsed filename: {:?}", filename);

        Ok(Config { mode, filename })
    }
}

pub fn setup_logging(_args: &Config) {
    simplelog::TermLogger::init(simplelog::LevelFilter::Info, simplelog::Config::default())
        .expect("failed to setup logging");
}

pub fn run(args: &Config) -> Result<(), Error> {
    info!("filename: {:?}", args.filename);

    if args.mode == 32 {
        let mut ws = Workspace::<Arch32>::from_file(&args.filename)?.load()?;
    } else if args.mode == 64 {
        let mut ws = Workspace::<Arch64>::from_file(&args.filename)?.load()?;

        if ws.loader.get_name() == "Windows/64/PE" {
            if let Ok(Object::PE(pe)) = Object::parse(&ws.buf) {
                let entry = pe.entry;
                let exports: Vec<usize> = pe.exports.iter()
                    // re-exports are simply strings that point to a `DLL.export_name` ASCII string.
                    // therefore, they're not functions/code.
                    .filter(|exp| exp.reexport.is_none())
                    .map(|exp| exp.rva).collect();

                info!("PE entry: {:#x}", entry);
                ws.make_insn(entry as i64);
                ws.analyze();
                for export in exports.iter() {
                    info!("export: {:#x}", export);
                    ws.make_insn(*export as i64);
                    ws.analyze();
                }
            }
        }
    }

    Ok(())
}

fn main() {
    let args = Config::from_args(env::args()).unwrap_or_else(|err| {
        eprintln!("error parsing arguments: {}", err);
        process::exit(1);
    });

    setup_logging(&args);

    if let Err(e) = run(&args) {
        error!("{:?}", e)
    }
}
<|endoftext|>


<commit_before>use std::any::Any;
use std::collections::VecDeque;
use std::sync::{Arc, Mutex, Weak};

enum Message {
    Command(String),
    Data(Box<Any + Send>),
}

type ActorRef = Arc<Mutex<Actor>>;

trait Actor {
    fn receive(&mut self, Message);
    fn handle_message(&mut self);
    fn send_message(&self, actor_ref: ActorRef, message: Message);
}

struct Printer {
    _name: String,
    message_queue: VecDeque<Message>,
    actor_system: Weak<ActorSystem>,
}

impl Printer {
    fn new(name: String, actor_system: Weak<ActorSystem>) -> Printer {
        Printer {
            _name: name,
            message_queue: VecDeque::new(),
            actor_system: actor_system,
        }
    }
}

impl Actor for Printer {
    fn receive(&mut self, message: Message) {
        self.message_queue.push_back(message);
    }

    fn handle_message(&mut self) {
        let message = self.message_queue.pop_front().unwrap();

        match message {
            Message::Command(command) => {
                println!("Received Command: ({})", command)
            },
            Message::Data(truc) => {
                match truc.downcast_ref::<String>() {
                    Some(s) => println!("Received data: ({})", s),
                    None => println!("Message is dropped"),
                }
            }
        }
    }

    fn send_message(&self, actor_ref: ActorRef, message: Message) {
        self.actor_system.upgrade().unwrap().send_to_actor(actor_ref, message);
    }

}

struct ActorSystem {
    // TODO(gamazeps): Use an unordered container instead.
    // There is currently an issue with having an ActorRef as a Arc<Mutex<Actor + Eq + Hash>>.
    actors_table: Mutex<Vec<ActorRef>>,
    actors_queue: Arc<Mutex<VecDeque<ActorRef>>>,
    myself: Mutex<Option<Weak<ActorSystem>>>,
}

impl ActorSystem {
    fn new() -> Arc<ActorSystem> {
        Arc::new(ActorSystem {
            actors_table: Mutex::new(Vec::new()),
            actors_queue: Arc::new(Mutex::new(VecDeque::new())),
            myself: Mutex::new(None),
        })
    }

    fn init(me: Arc<ActorSystem>) {
        *me.myself.lock().unwrap() = Some(Arc::downgrade(&me));
    }

    fn myself(&self) -> Option<Weak<ActorSystem>> {
        self.myself.lock().unwrap().clone()
    }

    fn spawn_actor(&self, name: String) -> ActorRef {
        let actor_ref = Arc::new(Mutex::new(Printer::new(name, self.myself().unwrap())));
        {
            let mut actors_table = self.actors_table.lock().unwrap();
            actors_table.push(actor_ref.clone());
        }
        actor_ref
    }

    fn send_to_actor(&self, actor_ref: ActorRef, message: Message) {
        {
            let mut actor = actor_ref.lock().unwrap();
            actor.receive(message);
        }
        {
            let mut actors_queue = self.actors_queue.lock().unwrap();
            actors_queue.push_back(actor_ref);
        }
    }

    fn handle_actor_message(&self) {
        let actor_ref;
        {
            actor_ref = self.actors_queue.lock().unwrap().pop_front();
        }
        if let Some(actor) = actor_ref {
            actor.lock().unwrap().handle_message();
        }
    }
}

fn main() {
    let message = "This is a message".to_string();
    let command = "This is a command".to_string();

    let actor_system = ActorSystem::new();
    ActorSystem::init(actor_system.clone());
    let actor_ref_1 = actor_system.spawn_actor("actor_1".to_string());
    let actor_ref_2 = actor_system.spawn_actor("actor_2".to_string());

    {
        let actor = actor_ref_1.lock().unwrap();
        actor.send_message(actor_ref_2.clone(), Message::Command(command));
        actor.send_message(actor_ref_2.clone(), Message::Data(Box::new(message)));
        actor.send_message(actor_ref_2.clone(), Message::Data(Box::new(3i32)));
    }

    actor_system.handle_actor_message();
    actor_system.handle_actor_message();
    actor_system.handle_actor_message();
}
<commit_msg>WIP - broadcast being implemented<commit_after>use std::any::Any;
use std::collections::VecDeque;
use std::sync::{Arc, Mutex, Weak};

#[derive(Clone)]
enum Message {
    Command(String),
    Data(Box<Any + Send>),
}

type ActorRef = Arc<Mutex<Actor>>;

trait Actor {
    fn receive(&mut self, Message);
    fn handle_message(&mut self);
    fn send_message(&self, actor_ref: ActorRef, message: Message);
    fn broadcast(&self, message: Message);
}

struct Printer {
    _name: String,
    message_queue: VecDeque<Message>,
    actor_system: Weak<ActorSystem>,
    known_actors: Vec<ActorRef>,
}

impl Printer {
    fn new(name: String, actor_system: Weak<ActorSystem>, known_actors: Vec<ActorRef>) -> Printer {
        Printer {
            _name: name,
            message_queue: VecDeque::new(),
            actor_system: actor_system,
            known_actors: known_actors,
        }
    }
}

impl Actor for Printer {
    fn receive(&mut self, message: Message) {
        self.message_queue.push_back(message);
    }

    fn handle_message(&mut self) {
        let message = self.message_queue.pop_front().unwrap();

        match message {
            Message::Command(command) => {
                println!("Received Command: ({})", command)
            },
            Message::Data(truc) => {
                match truc.downcast_ref::<String>() {
                    Some(s) => println!("Received data: ({})", s),
                    None => println!("Message is dropped"),
                }
            }
        }
    }

    fn send_message(&self, actor_ref: ActorRef, message: Message) {
        self.actor_system.upgrade().unwrap().send_to_actor(actor_ref, message);
    }

    fn broadcast(&self, message: Message) {
        for actor_ref in self.known_actors.iter() {
            self.send_message(actor_ref.clone(), message.clone());
        }
    }
}

struct ActorSystem {
    // TODO(gamazeps): Use an unordered container instead.
    // There is currently an issue with having an ActorRef as a Arc<Mutex<Actor + Eq + Hash>>.
    actors_table: Mutex<Vec<ActorRef>>,
    actors_queue: Arc<Mutex<VecDeque<ActorRef>>>,
    myself: Mutex<Option<Weak<ActorSystem>>>,
}

impl ActorSystem {
    fn new() -> Arc<ActorSystem> {
        Arc::new(ActorSystem {
            actors_table: Mutex::new(Vec::new()),
            actors_queue: Arc::new(Mutex::new(VecDeque::new())),
            myself: Mutex::new(None),
        })
    }

    fn init(me: Arc<ActorSystem>) {
        *me.myself.lock().unwrap() = Some(Arc::downgrade(&me));
    }

    fn myself(&self) -> Option<Weak<ActorSystem>> {
        self.myself.lock().unwrap().clone()
    }

    fn spawn_actor(&self, name: String, known_actors: Vec<ActorRef>) -> ActorRef {
        let actor_ref = Arc::new(Mutex::new(Printer::new(name, self.myself().unwrap(), known_actors)));
        {
            let mut actors_table = self.actors_table.lock().unwrap();
            actors_table.push(actor_ref.clone());
        }
        actor_ref
    }

    fn send_to_actor(&self, actor_ref: ActorRef, message: Message) {
        {
            let mut actor = actor_ref.lock().unwrap();
            actor.receive(message);
        }
        {
            let mut actors_queue = self.actors_queue.lock().unwrap();
            actors_queue.push_back(actor_ref);
        }
    }

    fn handle_actor_message(&self) {
        let actor_ref;
        {
            actor_ref = self.actors_queue.lock().unwrap().pop_front();
        }
        if let Some(actor) = actor_ref {
            actor.lock().unwrap().handle_message();
        }
    }

}

fn main() {
    let message = "This is a message".to_string();
    let command = "This is a command".to_string();

    let actor_system = ActorSystem::new();
    ActorSystem::init(actor_system.clone());
    let actor_ref_2 = actor_system.spawn_actor("actor_2".to_string(), Vec::new());
    let actor_ref_1 = actor_system.spawn_actor("actor_1".to_string(), vec![actor_ref_2.clone()]);

    {
        let actor = actor_ref_1.lock().unwrap();
        actor.broadcast(Message::Command(command));
        actor.broadcast(Message::Data(Box::new(message)));
        actor.broadcast(Message::Data(Box::new(3i32)));
    }

    actor_system.handle_actor_message();
    actor_system.handle_actor_message();
    actor_system.handle_actor_message();
}
<|endoftext|>


<commit_before>//! Implementation of a simple uTP client and server.
#[macro_use]
extern crate log;
extern crate env_logger;
extern crate getopts;
extern crate daemonize;
extern crate udt;
extern crate crypto;
extern crate byteorder;
extern crate rand;
extern crate sodiumoxide;
extern crate rustc_serialize;

use daemonize::{Daemonize};
use std::process::Command;
use std::net::{UdpSocket, SocketAddr, SocketAddrV4};
use std::str;
use std::env;
use std::fs::File;
use std::str::FromStr;
use std::path::Path;
use std::ffi::OsStr;
use std::io::{Cursor, Error, Seek, SeekFrom, ErrorKind, stderr, Read, Write};
use getopts::Options;
use udt::*;
use byteorder::{ReadBytesExt, WriteBytesExt, LittleEndian};
use sodiumoxide::crypto::secretbox;
use sodiumoxide::crypto::secretbox::xsalsa20poly1305::{NONCEBYTES, Key, Nonce};
use rustc_serialize::hex::{FromHex, ToHex};

fn print_usage(program: &str, opts: Options) {
    let brief = format!("Usage: {} [options] REMOTE-LOCATION", program);
    print!("{}", opts.usage(&brief));
}

fn send_file(stream: UdtSocket, filename: &str, key: Key) -> Result<(), Error> {
    let mut f = File::open(filename).unwrap();

    let mut filesize = 0u64;
    let mut buf = vec![0; 1024 * 1024];
    loop {
        match try!(f.read(&mut buf)) {
            0    => { break },
            read => { filesize += read as u64 },
        }
    }

    let mut wtr = vec![];
    wtr.write_u64::<LittleEndian>(filesize).unwrap();
    match stream.sendmsg(&wtr[..]) {
        Ok(0) => {
            return Err(Error::new(ErrorKind::WriteZero, "failed to write filesize header before timeout"))
        },
        Err(e) => {
            return Err(Error::new(ErrorKind::Other, format!("{:?}", e)))
        }
        _ => {
            // println!("wrote filesize of {:.2}kb.", filesize as f64 / 1024f64);
        }
    }
    // let mut total = 0;
    let mut payload = vec![0; 1300];
    f.seek(SeekFrom::Start(0)).unwrap();
    loop {
        match f.read(&mut payload) {
            Ok(0) => {
                // println!("\nEOF.");
                stream.sendmsg(&vec![0;0]).unwrap();
                break;
            }
            Ok(read) => {
                let nonce = secretbox::gen_nonce();
                let Nonce(noncebytes) = nonce;
                let mut hdr = vec![0u8; 1 + NONCEBYTES];
                hdr[0] = NONCEBYTES as u8;
                hdr[1..].clone_from_slice(&noncebytes);

                let mut sealed = secretbox::seal(&payload[0..read], &nonce, &key);
                let mut msg = Vec::with_capacity(hdr.len() + sealed.len());
                msg.extend_from_slice(&hdr);
                msg.append(&mut sealed);
                match stream.sendmsg(&msg[..]) {
                    Ok(_) =>  { }
                    Err(e) => {
                        stream.close().expect("Error closing stream");
                        panic!("{:?}", e);
                    }
                }
            },
            Err(e) => {
                stream.close().expect("Error closing stream");
                panic!("{:?}", e);
            }
        }
    }

    stream.close().expect("Error closing stream.");
    // println!("all done!");
    Ok(())
}

fn get_open_port(start: u16, end: u16) -> Result<u16, ()> {
    assert!(end >= start);
    let mut p = start;
    loop {
        match UdpSocket::bind(&format!("0.0.0.0:{}", p)[..]) {
            Ok(_) => {
                return Ok(p);
            }
            Err(_) => {
                p += 1;
                if p > end {
                    return Err(());
                }
            }
        }
    }
}

fn recv_file(sock: UdtSocket, filesize: u64, filename: &str, key: Key) -> Result<(), Error> {
    let mut f = File::create(filename).unwrap();
    let mut total = 0u64;
    loop {
        let buf = try!(sock.recvmsg(8192).map_err(|e| Error::new(ErrorKind::Other, format!("{:?}", e))));
        if buf.len() < 1 {
            return Err(Error::new(ErrorKind::InvalidInput, "empty message"));
        }
        let noncelen = buf[0] as usize;
        if total == 0 {
            let Nonce(noncebytes) = secretbox::gen_nonce();
            println!("new nonce is {}", noncebytes.len());
            println!("NONCEBYTES {}", NONCEBYTES);
            println!("nonce len {}", noncelen);
        }
        if noncelen != NONCEBYTES {
            return Err(Error::new(ErrorKind::InvalidInput, "nonce bytes unexpected len"));
        }
        if buf.len() < (1 + noncelen) {
            return Err(Error::new(ErrorKind::InvalidInput, "nonce != nonce_len"));
        }
        let mut noncebytes = [0u8; NONCEBYTES];
        noncebytes.copy_from_slice(&buf[1..1+noncelen]);
        let nonce = Nonce(noncebytes);

        let unsealed = try!(secretbox::open(&buf[1+noncelen..], &nonce, &key).map_err(|_| Error::new(ErrorKind::InvalidInput, "failed to decrypt")));

        total += unsealed.len() as u64;
        f.write_all(&unsealed[..]).unwrap();
        print!("\rreceived {}kb / {}kb ({:.1}%)", total/1024, filesize/1024, (total as f64/1024f64) / (filesize as f64/1024f64) * 100f64);
        if total >= filesize {
            println!("\nEOF");
            break;
        }
    }
    let _ = sock.close();
    Ok(())
}

fn main() {
    enum Mode {Server, Client}
    env_logger::init().expect("Error starting logger");

    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();
    let mut opts = Options::new();
    // opts.optopt("o", "output", "set output file name", "NAME");
    opts.optflag("s", "server", "server mode");
    opts.optflag("p", "port-range", "server listening port range");
    opts.optflag("h", "help", "print this help menu");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m }
        Err(f) => { panic!(f.to_string()) }
    };

    if matches.opt_present("h") {
        print_usage(&program, opts);
        return;
    }

    let input = if !matches.free.is_empty() {
        matches.free[0].clone()
    } else {
        print_usage(&program, opts);
        return;
    };

    // Parse the mode argument
    let mode: Mode = match matches.opt_present("s") {
        true => Mode::Server,
        false => Mode::Client
    };

    match mode {
        Mode::Server => {
            let sshconnstr = env::var("SSH_CONNECTION").unwrap_or(String::from("0.0.0.0 0 0.0.0.0 22")).trim().to_owned();
            let sshconn: Vec<&str> = sshconnstr.split(" ").collect();
            let ip = sshconn[2];
            let port = get_open_port(55000, 55100).unwrap();
            let key = secretbox::gen_key();
            match key {
                Key(keybytes) => { println!("shoop 0 {} {} {}", ip, port, keybytes.to_hex()) }
            }

            let daemonize = Daemonize::new();
            match daemonize.start() {
                Ok(_) => { let _ = writeln!(&mut stderr(), "daemonized"); }
                Err(_) => { let _ = writeln!(&mut stderr(), "RWRWARWARARRR"); }
            }

            udt::init();
            let sock = UdtSocket::new(SocketFamily::AFInet, SocketType::Datagram).unwrap();
            // sock.setsockopt(UdtOpts::UDP_RCVBUF, 5590000i32).unwrap();
            // sock.setsockopt(UdtOpts::UDP_SNDBUF, 5590000i32).unwrap();
            sock.setsockopt(UdtOpts::UDP_RCVBUF, 1024000i32).unwrap();
            sock.setsockopt(UdtOpts::UDP_SNDBUF, 1024000i32).unwrap();
            sock.bind(SocketAddr::V4(SocketAddrV4::from_str(&format!("{}:{}", ip, port)[..]).unwrap())).unwrap();

            sock.listen(1).unwrap();

            let (stream, _) = sock.accept().unwrap();
            // dbg(format!("Received new connection from peer {:?}", peer));

            if let Ok(version) = stream.recvmsg(1) {
                // dbg(format!("frand using protocol version {}.", version[0]));
                if version[0] == 0x00 {
                    send_file(stream, &input, key).unwrap();
                } else {
                    panic!("Unrecognized version.");
                }
            } else {
                panic!("Failed to receive version byte from client.");
            }
        }
        Mode::Client => {
            let sections: Vec<&str> = input.split(":").collect();
            let addr: String = sections[0].to_owned();
            let path: String = sections[1].to_owned();
            let cmd = format!("~/bin/shoop -s {}", path);
            println!("addr: {}, path: {}, cmd: {}", addr, path, cmd);

            let output = Command::new("ssh")
                                 .arg(addr.to_owned())
                                 .arg(cmd)
                                 .output()
                                 .unwrap_or_else(|e| {
                                     panic!("failed to execute process: {}", e);
                                 });
            let infostring = String::from_utf8_lossy(&output.stdout).to_owned().trim().to_owned();
            let info: Vec<&str> = infostring.split(" ").collect();
            if info.len() != 5 {
                panic!("unexpected response format from server");
            }

            let (magic, version, ip, port, keyhex) = (info[0], info[1], info[2], info[3], info[4]);
            println!("connecting to {}:{}", ip, port);
            if magic != "shoop" || version != "0" {
                panic!("response from server.. i don't know what it means. what does it mean? help me i am so confused.");
            }

            let mut keybytes = [0u8; 32];
            keybytes.copy_from_slice(&keyhex.from_hex().unwrap()[..]);
            let key = Key(keybytes);
            println!("got key {}", keyhex);

            udt::init();
            let sock = UdtSocket::new(SocketFamily::AFInet, SocketType::Datagram).unwrap();
            sock.setsockopt(UdtOpts::UDP_RCVBUF, 1024000i32).unwrap();
            sock.setsockopt(UdtOpts::UDP_SNDBUF, 1024000i32).unwrap();
            let addr: SocketAddr = SocketAddr::V4(SocketAddrV4::from_str(&format!("{}:{}", ip, port)[..]).unwrap());
            match sock.connect(addr) {
               Ok(()) => {
                   println!("connected!");
               },
               Err(e) => {
                   panic!("errrrrrrr {:?}", e);
               }
            }

            sock.sendmsg(&[0u8; 1]).unwrap();
            println!("checking if server is frand");

            match sock.recvmsg(8) {
               Ok(msg) => {
                   if msg.len() == 0 {
                       panic!("failed to get filesize from server, probable timeout.");
                   }
                   let mut rdr = Cursor::new(msg);
                   let filesize = rdr.read_u64::<LittleEndian>().unwrap();
                   println!("got reported filesize of {}", filesize);
                   let filename = Path::new(&path).file_name().unwrap_or(OsStr::new("outfile")).to_str().unwrap_or("outfile");
                   println!("writing to {}", filename);
                   recv_file(sock, filesize, filename, key).unwrap();
               }
               Err(e) => {
                   panic!("{:?}", e);
               }
            }
        }
    }
}

<commit_msg>AWWW MAN THE CRYPTO<commit_after>//! Implementation of a simple uTP client and server.
#[macro_use]
extern crate log;
extern crate env_logger;
extern crate getopts;
extern crate daemonize;
extern crate udt;
extern crate crypto;
extern crate byteorder;
extern crate rand;
extern crate sodiumoxide;
extern crate rustc_serialize;

use daemonize::{Daemonize};
use std::process::Command;
use std::net::{UdpSocket, SocketAddr, SocketAddrV4};
use std::str;
use std::env;
use std::fs::File;
use std::str::FromStr;
use std::path::Path;
use std::ffi::OsStr;
use std::io::{Cursor, Error, Seek, SeekFrom, ErrorKind, stderr, Read, Write};
use getopts::Options;
use udt::*;
use byteorder::{ReadBytesExt, WriteBytesExt, LittleEndian};
use sodiumoxide::crypto::secretbox;
use sodiumoxide::crypto::secretbox::xsalsa20poly1305::{NONCEBYTES, Key, Nonce};
use rustc_serialize::hex::{FromHex, ToHex};

fn print_usage(program: &str, opts: Options) {
    let brief = format!("Usage: {} [options] REMOTE-LOCATION", program);
    print!("{}", opts.usage(&brief));
}

fn send_file(stream: UdtSocket, filename: &str, key: Key) -> Result<(), Error> {
    let mut f = File::open(filename).unwrap();

    let mut filesize = 0u64;
    let mut buf = vec![0; 1024 * 1024];
    loop {
        match try!(f.read(&mut buf)) {
            0    => { break },
            read => { filesize += read as u64 },
        }
    }

    let mut wtr = vec![];
    wtr.write_u64::<LittleEndian>(filesize).unwrap();
    match stream.sendmsg(&wtr[..]) {
        Ok(0) => {
            return Err(Error::new(ErrorKind::WriteZero, "failed to write filesize header before timeout"))
        },
        Err(e) => {
            return Err(Error::new(ErrorKind::Other, format!("{:?}", e)))
        }
        _ => {
            // println!("wrote filesize of {:.2}kb.", filesize as f64 / 1024f64);
        }
    }
    // let mut total = 0;
    let mut payload = vec![0; 1300];
    f.seek(SeekFrom::Start(0)).unwrap();
    loop {
        match f.read(&mut payload) {
            Ok(0) => {
                // println!("\nEOF.");
                stream.sendmsg(&vec![0;0]).unwrap();
                break;
            }
            Ok(read) => {
                let nonce = secretbox::gen_nonce();
                let Nonce(noncebytes) = nonce;
                let mut hdr = vec![0u8; 1 + NONCEBYTES];
                hdr[0] = NONCEBYTES as u8;
                hdr[1..].clone_from_slice(&noncebytes);

                let mut sealed = secretbox::seal(&payload[0..read], &nonce, &key);
                let mut msg = Vec::with_capacity(hdr.len() + sealed.len());
                msg.extend_from_slice(&hdr);
                msg.append(&mut sealed);
                match stream.sendmsg(&msg[..]) {
                    Ok(_) =>  { }
                    Err(e) => {
                        stream.close().expect("Error closing stream");
                        panic!("{:?}", e);
                    }
                }
            },
            Err(e) => {
                stream.close().expect("Error closing stream");
                panic!("{:?}", e);
            }
        }
    }

    stream.close().expect("Error closing stream.");
    // println!("all done!");
    Ok(())
}

fn get_open_port(start: u16, end: u16) -> Result<u16, ()> {
    assert!(end >= start);
    let mut p = start;
    loop {
        match UdpSocket::bind(&format!("0.0.0.0:{}", p)[..]) {
            Ok(_) => {
                return Ok(p);
            }
            Err(_) => {
                p += 1;
                if p > end {
                    return Err(());
                }
            }
        }
    }
}

fn recv_file(sock: UdtSocket, filesize: u64, filename: &str, key: Key) -> Result<(), Error> {
    let mut f = File::create(filename).unwrap();
    let mut total = 0u64;
    loop {
        let buf = try!(sock.recvmsg(8192).map_err(|e| Error::new(ErrorKind::Other, format!("{:?}", e))));
        if buf.len() < 1 {
            return Err(Error::new(ErrorKind::InvalidInput, "empty message"));
        }
        let noncelen = buf[0] as usize;
        if noncelen != NONCEBYTES {
            return Err(Error::new(ErrorKind::InvalidInput, "nonce bytes unexpected len"));
        }
        if buf.len() < (1 + noncelen) {
            return Err(Error::new(ErrorKind::InvalidInput, "nonce != nonce_len"));
        }
        let mut noncebytes = [0u8; NONCEBYTES];
        noncebytes.copy_from_slice(&buf[1..1+noncelen]);
        let nonce = Nonce(noncebytes);

        let unsealed = try!(secretbox::open(&buf[1+noncelen..], &nonce, &key).map_err(|_| Error::new(ErrorKind::InvalidInput, "failed to decrypt")));

        total += unsealed.len() as u64;
        f.write_all(&unsealed[..]).unwrap();
        print!("\rreceived {}kb / {}kb ({:.1}%)", total/1024, filesize/1024, (total as f64/1024f64) / (filesize as f64/1024f64) * 100f64);
        if total >= filesize {
            println!("\nEOF");
            break;
        }
    }
    let _ = sock.close();
    Ok(())
}

fn main() {
    enum Mode {Server, Client}
    env_logger::init().expect("Error starting logger");

    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();
    let mut opts = Options::new();
    // opts.optopt("o", "output", "set output file name", "NAME");
    opts.optflag("s", "server", "server mode");
    opts.optflag("p", "port-range", "server listening port range");
    opts.optflag("h", "help", "print this help menu");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m }
        Err(f) => { panic!(f.to_string()) }
    };

    if matches.opt_present("h") {
        print_usage(&program, opts);
        return;
    }

    let input = if !matches.free.is_empty() {
        matches.free[0].clone()
    } else {
        print_usage(&program, opts);
        return;
    };

    // Parse the mode argument
    let mode: Mode = match matches.opt_present("s") {
        true => Mode::Server,
        false => Mode::Client
    };

    match mode {
        Mode::Server => {
            let sshconnstr = env::var("SSH_CONNECTION").unwrap_or(String::from("0.0.0.0 0 0.0.0.0 22")).trim().to_owned();
            let sshconn: Vec<&str> = sshconnstr.split(" ").collect();
            let ip = sshconn[2];
            let port = get_open_port(55000, 55100).unwrap();
            let key = secretbox::gen_key();
            match key {
                Key(keybytes) => { println!("shoop 0 {} {} {}", ip, port, keybytes.to_hex()) }
            }

            let daemonize = Daemonize::new();
            match daemonize.start() {
                Ok(_) => { let _ = writeln!(&mut stderr(), "daemonized"); }
                Err(_) => { let _ = writeln!(&mut stderr(), "RWRWARWARARRR"); }
            }

            udt::init();
            let sock = UdtSocket::new(SocketFamily::AFInet, SocketType::Datagram).unwrap();
            // sock.setsockopt(UdtOpts::UDP_RCVBUF, 5590000i32).unwrap();
            // sock.setsockopt(UdtOpts::UDP_SNDBUF, 5590000i32).unwrap();
            sock.setsockopt(UdtOpts::UDP_RCVBUF, 1024000i32).unwrap();
            sock.setsockopt(UdtOpts::UDP_SNDBUF, 1024000i32).unwrap();
            sock.bind(SocketAddr::V4(SocketAddrV4::from_str(&format!("{}:{}", ip, port)[..]).unwrap())).unwrap();

            sock.listen(1).unwrap();

            let (stream, _) = sock.accept().unwrap();
            // dbg(format!("Received new connection from peer {:?}", peer));

            if let Ok(version) = stream.recvmsg(1) {
                // dbg(format!("frand using protocol version {}.", version[0]));
                if version[0] == 0x00 {
                    send_file(stream, &input, key).unwrap();
                } else {
                    panic!("Unrecognized version.");
                }
            } else {
                panic!("Failed to receive version byte from client.");
            }
        }
        Mode::Client => {
            let sections: Vec<&str> = input.split(":").collect();
            let addr: String = sections[0].to_owned();
            let path: String = sections[1].to_owned();
            let cmd = format!("~/bin/shoop -s {}", path);
            println!("addr: {}, path: {}, cmd: {}", addr, path, cmd);

            let output = Command::new("ssh")
                                 .arg(addr.to_owned())
                                 .arg(cmd)
                                 .output()
                                 .unwrap_or_else(|e| {
                                     panic!("failed to execute process: {}", e);
                                 });
            let infostring = String::from_utf8_lossy(&output.stdout).to_owned().trim().to_owned();
            let info: Vec<&str> = infostring.split(" ").collect();
            if info.len() != 5 {
                panic!("unexpected response format from server");
            }

            let (magic, version, ip, port, keyhex) = (info[0], info[1], info[2], info[3], info[4]);
            println!("connecting to {}:{}", ip, port);
            if magic != "shoop" || version != "0" {
                panic!("response from server.. i don't know what it means. what does it mean? help me i am so confused.");
            }

            let mut keybytes = [0u8; 32];
            keybytes.copy_from_slice(&keyhex.from_hex().unwrap()[..]);
            let key = Key(keybytes);
            println!("got key {}", keyhex);

            udt::init();
            let sock = UdtSocket::new(SocketFamily::AFInet, SocketType::Datagram).unwrap();
            sock.setsockopt(UdtOpts::UDP_RCVBUF, 1024000i32).unwrap();
            sock.setsockopt(UdtOpts::UDP_SNDBUF, 1024000i32).unwrap();
            let addr: SocketAddr = SocketAddr::V4(SocketAddrV4::from_str(&format!("{}:{}", ip, port)[..]).unwrap());
            match sock.connect(addr) {
               Ok(()) => {
                   println!("connected!");
               },
               Err(e) => {
                   panic!("errrrrrrr {:?}", e);
               }
            }

            sock.sendmsg(&[0u8; 1]).unwrap();
            println!("checking if server is frand");

            match sock.recvmsg(8) {
               Ok(msg) => {
                   if msg.len() == 0 {
                       panic!("failed to get filesize from server, probable timeout.");
                   }
                   let mut rdr = Cursor::new(msg);
                   let filesize = rdr.read_u64::<LittleEndian>().unwrap();
                   println!("got reported filesize of {}", filesize);
                   let filename = Path::new(&path).file_name().unwrap_or(OsStr::new("outfile")).to_str().unwrap_or("outfile");
                   println!("writing to {}", filename);
                   recv_file(sock, filesize, filename, key).unwrap();
               }
               Err(e) => {
                   panic!("{:?}", e);
               }
            }
        }
    }
}

<|endoftext|>


<commit_before>extern crate xmltree;
extern crate svd_parser as svd;

#[macro_use]
mod write;

use xmltree::Element;
use svd::*;

macro_rules! try {
    ($e:expr) => {
        $e.expect(concat!(file!(), ":", line!(), " ", stringify!($e)))
    }
}

fn u32_str(text: &str) -> Option<u32> {
    let text = text.trim();
    if text.starts_with("0x") || text.starts_with("0X") {
        u32::from_str_radix(&text["0x".len()..], 16).ok()
    } else if text.starts_with('#') {
        // Handle strings in the binary form of:
        // #01101x1
        // along with don't care character x (replaced with 0)
        u32::from_str_radix(&str::replace(&text["#".len()..], "x", "0"), 2).ok()
    } else {
        text.parse().ok()
    }
}

trait StringEx {
    fn fix_id(&self) -> String;
}

impl StringEx for String {
    fn fix_id(&self) -> String {
        self.replace("/", "_")
            .replace(" ", "_")
            .replace("__", "_")
            .replace("__", "_")
    }
}

trait ElementExt {
    fn get_attribute<K>(&self, k: K) -> Option<String>
        where String: PartialEq<K> + std::convert::From<K>;
    fn debug(&self);
}

impl ElementExt for Element {
    fn get_attribute<K>(&self, k: K) -> Option<String>
        where String: PartialEq<K> + std::convert::From<K>
    {
        //self.get_child(k).map(|c| try!(c.text.clone()))
        self.attributes.get(&String::from(k)).map(|v| v.clone())
    }

    fn debug(&self) {
        println!("<{} {:?}>", self.name, self.attributes);
        for c in &self.children {
            println!("{}: {:?}", c.name, c.attributes)
        }
        println!("</{}>", self.name);
    }
}

/// Parses the contents of a dslib module file (XML)
pub fn parse_module(xml: &str) -> Option<Peripheral> {
    let tree = &try!(Element::parse(xml.as_bytes()));
    parse_peripheral(tree)
}

/// Parses the contents of a dslib device file (XML)
pub fn parse_device_file(xml: &str) -> Device {
    let tree = &try!(Element::parse(xml.as_bytes()));
    parse_device(tree)
}

fn main() {
    let xml = include_str!("../targetdb/devices/CC430F5123.xml");
    let original = parse_device_file(xml);
    let out_svd = write::write_device(&original);

    let parsed = svd::parse(&out_svd);

    println!("{}", out_svd);

    assert_eq!(original, parsed);
}

fn parse_device(tree: &Element) -> Device {
    assert_eq!(tree.name, "device");

    Device {
        name: try!(tree.get_attribute("partnum")),
        peripherals: try!(tree.get_child("cpu"))
            .children
            .iter()
            .filter_map(parse_instance)
            .collect(),
        defaults: Defaults {
            size: Some(16),
            reset_value: Some(0x0),
            reset_mask: Some(0xffff),
            access: Some(Access::ReadWrite),
        },
    }
}

fn parse_instance(tree: &Element) -> Option<Peripheral> {
    assert_eq!(tree.name, "instance");

    let xmlpath = try!(tree.get_attribute("xmlpath"));
    let xml = try!(tree.get_attribute("xml"));

    use std::io::Read;
    use std::fs::File;
    use std::path::PathBuf;

    let file_path = PathBuf::from("targetdb/devices").join(xmlpath).join(xml);

    let mut file = File::open(file_path).unwrap();
    let mut contents = String::new();
    file.read_to_string(&mut contents).unwrap();

    parse_module(&contents)
}

fn parse_peripheral(tree: &Element) -> Option<Peripheral> {
    assert_eq!(tree.name, "module");

    match tree.get_attribute("hidden") {
        Some(ref s) if s == "true" => {
            return None;
        }
        _ => {}
    }

    let base_address = tree.children
        .iter()
        .map(|x| try!(u32_str(&try!(x.get_attribute("offset")))))
        .min()
        .unwrap();

    Some(Peripheral {
             name: try!(tree.get_attribute("id")).fix_id(),
             group_name: tree.get_attribute("id"),
             description: tree.get_attribute("description"),
             base_address: base_address,
             interrupt: vec![],
             registers: Some(tree.children
                                 .iter()
                                 .filter_map(|x| parse_register(x, base_address))
                                 .collect::<Vec<_>>()),
             derived_from: None,
         })
}

fn parse_register(tree: &Element, base_address: u32) -> Option<Register> {
    let r = parse_register_info(tree, base_address);
    Some(Register::Single(r))
}

fn parse_register_info(tree: &Element, base_address: u32) -> RegisterInfo {
    assert_eq!(tree.name, "register");

    RegisterInfo {
        name: try!(tree.get_attribute("acronym")).fix_id(),
        description: try!(tree.get_attribute("description")),
        address_offset: try!(u32_str(&try!(tree.get_attribute("offset")))) - base_address,
        size: u32_str(&try!(tree.get_attribute("width"))),
        access: None,
        reset_value: None,
        reset_mask: None,
        fields: match tree.children.len() {
            0 => None,
            _ => {
                Some(tree.children
                         .iter()
                         .map(parse_field)
                         .collect::<Vec<_>>())
            }
        },
        write_constraint: None,
    }
}

fn parse_field(tree: &Element) -> Field {
    assert_eq!(tree.name, "bitfield");

    Field {
        name: try!(tree.get_attribute("id")).fix_id(),
        description: tree.get_attribute("description"),
        bit_range: BitRange {
            offset: try!(u32_str(&try!(tree.get_attribute("begin")))),
            width: try!(u32_str(&try!(tree.get_attribute("width")))),
        },
        access: tree.get_attribute("rwaccess").map(parse_access),
        enumerated_values: match tree.children.len() {
            0 => vec![],
            _ => {
                vec![EnumeratedValues {
                         name: None,
                         usage: None,
                         derived_from: None,
                         values: tree.children
                             .iter()
                             .map(parse_enum)
                             .collect::<Vec<_>>(),
                     }]
            }
        },
        write_constraint: None,
    }
}

fn parse_access(text: String) -> Access {
    match text.as_str() {
        "RW" => Access::ReadWrite,
        "RO" => Access::ReadOnly,
        _ => panic!("bad access"),
    }
}

fn parse_enum(tree: &Element) -> EnumeratedValue {
    assert_eq!(tree.name, "bitenum");

    EnumeratedValue {
        name: try!(tree.get_attribute("id")).fix_id(),
        description: tree.get_attribute("description"),
        value: u32_str(&try!(tree.get_attribute("value"))),
        is_default: None,
    }
}
<commit_msg>remove aliased registers<commit_after>extern crate xmltree;
extern crate svd_parser as svd;

#[macro_use]
mod write;

use std::io::Write;
use xmltree::Element;
use svd::*;

macro_rules! try {
    ($e:expr) => {
        $e.expect(concat!(file!(), ":", line!(), " ", stringify!($e)))
    }
}

fn u32_str(text: &str) -> Option<u32> {
    let text = text.trim();
    if text.starts_with("0x") || text.starts_with("0X") {
        u32::from_str_radix(&text["0x".len()..], 16).ok()
    } else if text.starts_with('#') {
        // Handle strings in the binary form of:
        // #01101x1
        // along with don't care character x (replaced with 0)
        u32::from_str_radix(&str::replace(&text["#".len()..], "x", "0"), 2).ok()
    } else {
        text.parse().ok()
    }
}

trait StringEx {
    fn fix_id(&self) -> String;
}

impl StringEx for String {
    fn fix_id(&self) -> String {
        self.replace("/", "_")
            .replace(" ", "_")
            .replace("__", "_")
            .replace("__", "_")
    }
}

trait ElementExt {
    fn get_attribute<K>(&self, k: K) -> Option<String>
        where String: PartialEq<K> + std::convert::From<K>;
    fn debug(&self);
}

impl ElementExt for Element {
    fn get_attribute<K>(&self, k: K) -> Option<String>
        where String: PartialEq<K> + std::convert::From<K>
    {
        //self.get_child(k).map(|c| try!(c.text.clone()))
        self.attributes.get(&String::from(k)).map(|v| v.clone())
    }

    fn debug(&self) {
        println!("<{} {:?}>", self.name, self.attributes);
        for c in &self.children {
            println!("{}: {:?}", c.name, c.attributes)
        }
        println!("</{}>", self.name);
    }
}

/// Parses the contents of a dslib module file (XML)
pub fn parse_module(xml: &str) -> Option<Peripheral> {
    let tree = &try!(Element::parse(xml.as_bytes()));
    parse_peripheral(tree)
}

/// Parses the contents of a dslib device file (XML)
pub fn parse_device_file(xml: &str) -> Device {
    let tree = &try!(Element::parse(xml.as_bytes()));
    parse_device(tree)
}

fn main() {
    let xml = include_str!("../targetdb/devices/CC430F5123.xml");
    let original = parse_device_file(xml);
    let out_svd = write::write_device(&original);

    let parsed = svd::parse(&out_svd);

    println!("{}", out_svd);

    assert_eq!(original, parsed);
}

fn parse_device(tree: &Element) -> Device {
    assert_eq!(tree.name, "device");

    Device {
        name: try!(tree.get_attribute("partnum")),
        peripherals: try!(tree.get_child("cpu"))
            .children
            .iter()
            .filter_map(parse_instance)
            .collect(),
        defaults: Defaults {
            size: Some(16),
            reset_value: Some(0x0),
            reset_mask: Some(0xffff),
            access: Some(Access::ReadWrite),
        },
    }
}

fn parse_instance(tree: &Element) -> Option<Peripheral> {
    assert_eq!(tree.name, "instance");

    let xmlpath = try!(tree.get_attribute("xmlpath"));
    let xml = try!(tree.get_attribute("xml"));

    use std::io::Read;
    use std::fs::File;
    use std::path::PathBuf;

    let file_path = PathBuf::from("targetdb/devices").join(xmlpath).join(xml);

    let mut file = File::open(file_path).unwrap();
    let mut contents = String::new();
    file.read_to_string(&mut contents).unwrap();

    parse_module(&contents)
}

fn get_addr_info(r: &Register) -> (u32, u32) {
    match r {
        &Register::Single(ref ri) => (ri.address_offset, try!(ri.size)),
        _ => panic!("arrays are not supported"),
    }
}

fn format_register(r: &Register) -> String {
    let mut s = format!("{:?}", r);
    match s.find("access") {
        Some(x) => {
            s.truncate(x);
        }
        None => {}
    }
    s
}

fn parse_peripheral(tree: &Element) -> Option<Peripheral> {
    assert_eq!(tree.name, "module");

    match tree.get_attribute("hidden") {
        Some(ref s) if s == "true" => {
            return None;
        }
        _ => {}
    }

    let base_address = tree.children
        .iter()
        .map(|x| try!(u32_str(&try!(x.get_attribute("offset")))))
        .min()
        .unwrap();

    let mut regs = tree.children
        .iter()
        .filter_map(|x| parse_register(x, base_address))
        .collect::<Vec<_>>();

    regs.sort_by_key(|r| {
                         let (a, _) = get_addr_info(r);
                         a
                     });

    regs = regs.iter()
        .filter_map(|r| {
            let (r_addr, r_size) = get_addr_info(r);

            for x in &regs {
                if x == r {
                    continue;
                }
                let (x_addr, x_size) = get_addr_info(x);
                if x_addr == r_addr && x_size < r_size {
                    writeln!(std::io::stderr(), "Removing    {}", format_register(r)).ok();
                    writeln!(std::io::stderr(), "In favor of {}", format_register(x)).ok();
                    return None;
                }
            }
            Some(r.clone())
        })
        .collect::<Vec<_>>();

    Some(Peripheral {
             name: try!(tree.get_attribute("id")).fix_id(),
             group_name: tree.get_attribute("id"),
             description: tree.get_attribute("description"),
             base_address: base_address,
             interrupt: vec![],
             registers: Some(regs),
             derived_from: None,
         })
}

fn parse_register(tree: &Element, base_address: u32) -> Option<Register> {
    let r = parse_register_info(tree, base_address);
    Some(Register::Single(r))
}

fn parse_register_info(tree: &Element, base_address: u32) -> RegisterInfo {
    assert_eq!(tree.name, "register");

    RegisterInfo {
        name: try!(tree.get_attribute("acronym")).fix_id(),
        description: try!(tree.get_attribute("description")),
        address_offset: try!(u32_str(&try!(tree.get_attribute("offset")))) - base_address,
        size: u32_str(&try!(tree.get_attribute("width"))),
        access: None,
        reset_value: None,
        reset_mask: None,
        fields: match tree.children.len() {
            0 => None,
            _ => {
                Some(tree.children
                         .iter()
                         .map(parse_field)
                         .collect::<Vec<_>>())
            }
        },
        write_constraint: None,
    }
}

fn parse_field(tree: &Element) -> Field {
    assert_eq!(tree.name, "bitfield");

    Field {
        name: try!(tree.get_attribute("id")).fix_id(),
        description: tree.get_attribute("description"),
        bit_range: BitRange {
            offset: try!(u32_str(&try!(tree.get_attribute("begin")))),
            width: try!(u32_str(&try!(tree.get_attribute("width")))),
        },
        access: tree.get_attribute("rwaccess").map(parse_access),
        enumerated_values: match tree.children.len() {
            0 => vec![],
            _ => {
                vec![EnumeratedValues {
                         name: None,
                         usage: None,
                         derived_from: None,
                         values: tree.children
                             .iter()
                             .map(parse_enum)
                             .collect::<Vec<_>>(),
                     }]
            }
        },
        write_constraint: None,
    }
}

fn parse_access(text: String) -> Access {
    match text.as_str() {
        "RW" => Access::ReadWrite,
        "RO" => Access::ReadOnly,
        _ => panic!("bad access"),
    }
}

fn parse_enum(tree: &Element) -> EnumeratedValue {
    assert_eq!(tree.name, "bitenum");

    EnumeratedValue {
        name: try!(tree.get_attribute("id")).fix_id(),
        description: tree.get_attribute("description"),
        value: u32_str(&try!(tree.get_attribute("value"))),
        is_default: None,
    }
}
<|endoftext|>


<commit_before>#![feature(net)]
extern crate nickel;
#[macro_use] extern crate nickel_macros;
extern crate mustache;
extern crate "rustc-serialize" as rustc_serialize;

use std::collections::HashMap;
use std::net::IpAddr;
use nickel::*;
// use mustache::*;
use rustc_serialize::Encodable;

struct View<T>(&'static str, T);

impl<T: Encodable> ResponseFinalizer for View<T> {
    fn respond<'a>(self, res: Response<'a>) -> MiddlewareResult<'a> {
        let View(path, data) = self;
        let stream = try!(res.render(path, &data));

        Ok(Halt(stream))
    }
}

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

   nickel.utilize(StaticFilesHandler::new("public/"));

   nickel.utilize(middleware! { |request|
     println!("Request: {:?}", request.origin.uri);
     });

   nickel.utilize(router!(

   get "**" => |request, response| {
      let mut data = HashMap::new();
      data.insert("title", "nickel-bootstrap");
      data.insert("message", "Welcome to");
      data.insert("message_line_two", "You can edit this to get started...");

      View("templates/all_for_one.mustache", data)
   }

   ));

   nickel.listen(IpAddr::new_v4(127,0,0,1), 6767);
}
<commit_msg>housekeeping<commit_after>#![feature(net)]
extern crate nickel;
#[macro_use] extern crate nickel_macros;
extern crate "rustc-serialize" as rustc_serialize;

use std::collections::HashMap;
use std::net::IpAddr;
use nickel::*;
use rustc_serialize::Encodable;

struct View<T>(&'static str, T);

impl<T: Encodable> ResponseFinalizer for View<T> {
    fn respond<'a>(self, res: Response<'a>) -> MiddlewareResult<'a> {
        let View(path, data) = self;
        let stream = try!(res.render(path, &data));

        Ok(Halt(stream))
    }
}

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

   nickel.utilize(StaticFilesHandler::new("public/"));

   nickel.utilize(middleware! { |request|
     println!("Request: {:?}", request.origin.uri);
     });

   nickel.utilize(router!(

   get "**" => |request, response| {
      let mut data = HashMap::new();
      data.insert("title", "nickel-bootstrap");
      data.insert("message", "Welcome to");
      data.insert("message_line_two", "You can edit this to get started...");

      View("templates/all_for_one.mustache", data)
   }

   ));

   nickel.listen(IpAddr::new_v4(127,0,0,1), 6767);
}
<|endoftext|>