<commit_before>extern crate discord;

use std::env;
use discord::{Discord, State};
use discord::model::Event;

pub fn main() {
    // Log in to Discord using a bot token from the environment
    let discord = Discord::from_bot_token(&env::var("DISCORD_TOKEN").expect("Expected token"))
        .expect("login failed");

    // establish websocket and voice connection
    let (mut connection, ready) = discord.connect().expect("connect failed");
    println!(
        "[Ready] {} is serving {} servers",
        ready.user.username,
        ready.servers.len()
    );
    let mut state = State::new(ready);
    connection.sync_calls(&state.all_private_channels());

    // receive events forever
    loop {
        let event = match connection.recv_event() {
            Ok(event) => event,
            Err(err) => {
                println!("[Warning] Receive error: {:?}", err);
                if let discord::Error::WebSocket(..) = err {
                    // Handle the websocket connection being dropped
                    let (new_connection, ready) = discord.connect().expect("connect failed");
                    connection = new_connection;
                    state = State::new(ready);
                    println!("[Ready] Reconnected successfully.");
                }
                if let discord::Error::Closed(..) = err {
                    break;
                }
                continue;
            }
        };
        state.update(&event);

        match event {
            Event::MessageCreate(message) => {
                use std::ascii::AsciiExt;
                // safeguard: stop if the message is from us
                if message.author.id == state.user().id {
                    continue;
                }

                // reply to a command if there was one
                let mut split = message.content.split(' ');
                let first_word = split.next().unwrap_or("");
                let argument = split.next().unwrap_or("");

                //Section of avaliable commands.
                if first_word.eq_ignore_ascii_case("!help") {
                    if argument.eq_ignore_ascii_case("commands") {
                        warn(discord.send_message(
                            message.channel_id,
                            "help, about, uber, distrowiki, and sourcecode are the avaliable commands. (!dj is buggy)",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("about") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Displays info about me. No arguments available.",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("uber") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Uber an object (I'm picky).",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("distrowiki") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Finds the wiki of the specified distro. Arguments include Arch, Ubuntu, Debian, Antergos, Mint, CentOS, OpenBSD, Opensuse, Sabayon, KaliLinux, Solus, and Gentoo.",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("sourcecode") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Displays where I am on GitHub. No arguments available",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("help") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Are you trying to break me?",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("[args]") {
                        warn(discord.send_message(
                            message.channel_id,
                            "You're helpless.",
                            "",
                            false,
                        ))
                    } else {
                        warn(discord.send_message(
                            message.channel_id,
                            "Umm, you gotta use it like this. !help [args] Try using the `commands` argument.",
                            "",
                            false,
                        ))
                    }
                }

                //Fun Commands.
                if first_word.eq_ignore_ascii_case("!about") {
                    warn(discord.send_message(
                        message.channel_id,
                        "I have no clue. All I know is that I was written by Arroz in a language called Rust, and my code is still being developed.",
                        "",
                        false,
                    ))
                }
                if first_word.eq_ignore_ascii_case("!wheresteal") {
                    warn(discord.send_message(
                        message.channel_id,
                        "Go ask him, I know nothing ;_;",
                        "",
                        false,
                    ))
                }
                if first_word.eq_ignore_ascii_case("!hello") {
                    warn(discord.send_message(
                        message.channel_id,
                        "https://www.tenor.co/xA8B.gif",
                        "",
                        false,
                    ))
                }
                if first_word.eq_ignore_ascii_case("!uber") {
                    if argument.eq_ignore_ascii_case("ddog75") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Alright, 10 minutes.",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("aspire") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Not the meatballs.",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("nic") {
                        warn(discord.send_message(
                            message.channel_id,
                            "NOT THE BEES!!!",
                            "",
                            false,
                        ))
                    } else {
                        warn(discord.send_message(
                            message.channel_id,
                            "Fuck off!",
                            "",
                            false,
                        ))
                    }
                }
                if first_word.eq_ignore_ascii_case("!sourcecode") {
                    warn(discord.send_message(
                        message.channel_id,
                        "Okay, here you go. https://github.com/aarroz/rice_bot2",
                        "",
                        false,
                    ))
                }
                //Section that prints wikis for linux distributions.
                if first_word.eq_ignore_ascii_case("!distrowiki") {
                    if argument.eq_ignore_ascii_case("arch") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Here's the Arch Wiki! https://wiki.archlinux.org/",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("ubuntu") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Here's the Ubuntu Wiki! https://wiki.ubuntu.com/",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("debian") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Here's the Debian Wiki! https://wiki.debian.org/",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("antergos") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Here's the Antergos Wiki! https://antergos.com/wiki/",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("centos") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Here's the CentOS Wiki! https://wiki.centos.org/",
                            "",
                            false,
                        ))
                    }
                    //Sorry OpenBSD users.
                    else if argument.eq_ignore_ascii_case("openbsd") {
                        warn(discord.send_message(
                            message.channel_id,
                            "No, just no.",
                            "",
                            false,
                        ))
                    }
                    //Not sorry.
                    else if argument.eq_ignore_ascii_case("gentoo") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Here's the Gentoo Wiki! https://wiki.gentoo.org/wiki/Main_Page",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("opensuse") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Here's the OpenSuse Wiki! https://en.opensuse.org/Portal:Wiki",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("sabayon") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Here's the Sabayon Wiki! https://wiki.sabayon.org/",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("kalilinux") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Heres's the KaliLinux Wiki! https://en.wikipedia.org/wiki/Kali_Linux",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("mint") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Here's the Mint newbie page! https://forums.linuxmint.com/viewforum.php?f=90",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("solus") {
                        warn(discord.send_message(
                            message.channel_id,
                            "There is no wiki for solus, however there is the help page! https://solus-project.com/help-center/home/",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("windows") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Thats not a distro.",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("macos") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Sure its close to linux, but I'm too tired to have that argument.",
                            "",
                            false,
                        ))
                    } else {
                        warn(discord.send_message(
                            message.channel_id,
                            "Please use a distro from !help distrowiki.",
                            "",
                            false,
                        ))
                    }
                }
                // Command for using dj.
                if first_word.eq_ignore_ascii_case("!dj") {
                    let vchan = state.find_voice_user(message.author.id);
                    if argument.eq_ignore_ascii_case("stop") {
                        vchan.map(|(sid, _)| connection.voice(sid).stop());
                    } else if argument.eq_ignore_ascii_case("quit") {
                        vchan.map(|(sid, _)| connection.drop_voice(sid));
                    } else if argument.eq_ignore_ascii_case("halloween") {
                        let output = if let Some((server_id, channel_id)) = vchan {
                            match discord::voice::open_ytdl_stream("https://youtu.be/iQuVFBSPGcU") {
                                Ok(stream) => {
                                    let voice = connection.voice(server_id);
                                    voice.set_deaf(true);
                                    voice.connect(channel_id);
                                    voice.play(stream);
                                    String::new()
                                }
                                Err(error) => format!("Error: {}", error),
                            }
                        } else {
                            "You must be in a voice channel to DJ".to_owned()
                        };
                        if !output.is_empty() {
                            warn(discord.send_message(message.channel_id, &output, "", false));
                        }
                    } else {
                        let output = if let Some((server_id, channel_id)) = vchan {
                            match discord::voice::open_ytdl_stream(argument) {
                                Ok(stream) => {
                                    let voice = connection.voice(server_id);
                                    voice.set_deaf(true);
                                    voice.connect(channel_id);
                                    voice.play(stream);
                                    String::new()
                                }
                                Err(error) => format!("Error: {}", error),
                            }
                        } else {
                            "You must be in a voice channel to DJ".to_owned()
                        };
                        if !output.is_empty() {
                            warn(discord.send_message(message.channel_id, &output, "", false));
                        }
                    }
                }
            }
            Event::VoiceStateUpdate(server_id, _) => {
                // If someone moves/hangs up, and we are in a voice channel,
                if let Some(cur_channel) = connection.voice(server_id).current_channel() {
                    // and our current voice channel is empty, disconnect from voice
                    match server_id {
                        Some(server_id) => if let Some(srv) =
                            state.servers().iter().find(|srv| srv.id == server_id)
                        {
                            if srv.voice_states
                                .iter()
                                .filter(|vs| vs.channel_id == Some(cur_channel))
                                .count() <= 1
                            {
                                connection.voice(Some(server_id)).disconnect();
                            }
                        },
                        None => if let Some(call) = state.calls().get(&cur_channel) {
                            if call.voice_states.len() <= 1 {
                                connection.voice(server_id).disconnect();
                            }
                        },
                    }
                }
            }
            _ => {} // discard other events
        }
    }
}

fn warn<T, E: ::std::fmt::Debug>(result: Result<T, E>) {
    match result {
        Ok(_) => {}
        Err(err) => println!("[Warning] {:?}", err),
    }
}
<commit_msg>Wheres fate?<commit_after>extern crate discord;

use std::env;
use discord::{Discord, State};
use discord::model::Event;

pub fn main() {
    // Log in to Discord using a bot token from the environment
    let discord = Discord::from_bot_token(&env::var("DISCORD_TOKEN").expect("Expected token"))
        .expect("login failed");

    // establish websocket and voice connection
    let (mut connection, ready) = discord.connect().expect("connect failed");
    println!(
        "[Ready] {} is serving {} servers",
        ready.user.username,
        ready.servers.len()
    );
    let mut state = State::new(ready);
    connection.sync_calls(&state.all_private_channels());

    // receive events forever
    loop {
        let event = match connection.recv_event() {
            Ok(event) => event,
            Err(err) => {
                println!("[Warning] Receive error: {:?}", err);
                if let discord::Error::WebSocket(..) = err {
                    // Handle the websocket connection being dropped
                    let (new_connection, ready) = discord.connect().expect("connect failed");
                    connection = new_connection;
                    state = State::new(ready);
                    println!("[Ready] Reconnected successfully.");
                }
                if let discord::Error::Closed(..) = err {
                    break;
                }
                continue;
            }
        };
        state.update(&event);

        match event {
            Event::MessageCreate(message) => {
                use std::ascii::AsciiExt;
                // safeguard: stop if the message is from us
                if message.author.id == state.user().id {
                    continue;
                }

                // reply to a command if there was one
                let mut split = message.content.split(' ');
                let first_word = split.next().unwrap_or("");
                let argument = split.next().unwrap_or("");

                //Section of avaliable commands.
                if first_word.eq_ignore_ascii_case("!help") {
                    if argument.eq_ignore_ascii_case("commands") {
                        warn(discord.send_message(
                            message.channel_id,
                            "help, about, uber, distrowiki, and sourcecode are the avaliable commands. (!dj is buggy)",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("about") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Displays info about me. No arguments available.",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("uber") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Uber an object (I'm picky).",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("distrowiki") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Finds the wiki of the specified distro. Arguments include Arch, Ubuntu, Debian, Antergos, Mint, CentOS, OpenBSD, Opensuse, Sabayon, KaliLinux, Solus, and Gentoo.",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("sourcecode") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Displays where I am on GitHub. No arguments available",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("help") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Are you trying to break me?",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("[args]") {
                        warn(discord.send_message(
                            message.channel_id,
                            "You're helpless.",
                            "",
                            false,
                        ))
                    } else {
                        warn(discord.send_message(
                            message.channel_id,
                            "Umm, you gotta use it like this. !help [args] Try using the `commands` argument.",
                            "",
                            false,
                        ))
                    }
                }

                //Fun Commands.
                if first_word.eq_ignore_ascii_case("!about") {
                    warn(discord.send_message(
                        message.channel_id,
                        "I have no clue. All I know is that I was written by Arroz in a language called Rust, and my code is still being developed.",
                        "",
                        false,
                    ))
                }
                if first_word.eq_ignore_ascii_case("!wheresteal") {
                    warn(discord.send_message(
                        message.channel_id,
                        "How about where's Fate?! DOES ANYONE CARE ABOUT FATE?",
                        "",
                        false,
                    ))
                }
                if first_word.eq_ignore_ascii_case("!hello") {
                    warn(discord.send_message(
                        message.channel_id,
                        "https://www.tenor.co/xA8B.gif",
                        "",
                        false,
                    ))
                }
                if first_word.eq_ignore_ascii_case("!uber") {
                    if argument.eq_ignore_ascii_case("ddog75") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Alright, 10 minutes.",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("aspire") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Not the meatballs.",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("nic") {
                        warn(discord.send_message(
                            message.channel_id,
                            "NOT THE BEES!!!",
                            "",
                            false,
                        ))
                    } else {
                        warn(discord.send_message(
                            message.channel_id,
                            "Fuck off!",
                            "",
                            false,
                        ))
                    }
                }
                if first_word.eq_ignore_ascii_case("!sourcecode") {
                    warn(discord.send_message(
                        message.channel_id,
                        "Okay, here you go. https://github.com/aarroz/rice_bot2",
                        "",
                        false,
                    ))
                }
                //Section that prints wikis for linux distributions.
                if first_word.eq_ignore_ascii_case("!distrowiki") {
                    if argument.eq_ignore_ascii_case("arch") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Here's the Arch Wiki! https://wiki.archlinux.org/",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("ubuntu") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Here's the Ubuntu Wiki! https://wiki.ubuntu.com/",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("debian") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Here's the Debian Wiki! https://wiki.debian.org/",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("antergos") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Here's the Antergos Wiki! https://antergos.com/wiki/",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("centos") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Here's the CentOS Wiki! https://wiki.centos.org/",
                            "",
                            false,
                        ))
                    }
                    //Sorry OpenBSD users.
                    else if argument.eq_ignore_ascii_case("openbsd") {
                        warn(discord.send_message(
                            message.channel_id,
                            "No, just no.",
                            "",
                            false,
                        ))
                    }
                    //Not sorry.
                    else if argument.eq_ignore_ascii_case("gentoo") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Here's the Gentoo Wiki! https://wiki.gentoo.org/wiki/Main_Page",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("opensuse") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Here's the OpenSuse Wiki! https://en.opensuse.org/Portal:Wiki",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("sabayon") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Here's the Sabayon Wiki! https://wiki.sabayon.org/",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("kalilinux") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Heres's the KaliLinux Wiki! https://en.wikipedia.org/wiki/Kali_Linux",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("mint") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Here's the Mint newbie page! https://forums.linuxmint.com/viewforum.php?f=90",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("solus") {
                        warn(discord.send_message(
                            message.channel_id,
                            "There is no wiki for solus, however there is the help page! https://solus-project.com/help-center/home/",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("windows") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Thats not a distro.",
                            "",
                            false,
                        ))
                    } else if argument.eq_ignore_ascii_case("macos") {
                        warn(discord.send_message(
                            message.channel_id,
                            "Sure its close to linux, but I'm too tired to have that argument.",
                            "",
                            false,
                        ))
                    } else {
                        warn(discord.send_message(
                            message.channel_id,
                            "Please use a distro from !help distrowiki.",
                            "",
                            false,
                        ))
                    }
                }
                // Command for using dj.
                if first_word.eq_ignore_ascii_case("!dj") {
                    let vchan = state.find_voice_user(message.author.id);
                    if argument.eq_ignore_ascii_case("stop") {
                        vchan.map(|(sid, _)| connection.voice(sid).stop());
                    } else if argument.eq_ignore_ascii_case("quit") {
                        vchan.map(|(sid, _)| connection.drop_voice(sid));
                    } else if argument.eq_ignore_ascii_case("halloween") {
                        let output = if let Some((server_id, channel_id)) = vchan {
                            match discord::voice::open_ytdl_stream("https://youtu.be/iQuVFBSPGcU") {
                                Ok(stream) => {
                                    let voice = connection.voice(server_id);
                                    voice.set_deaf(true);
                                    voice.connect(channel_id);
                                    voice.play(stream);
                                    String::new()
                                }
                                Err(error) => format!("Error: {}", error),
                            }
                        } else {
                            "You must be in a voice channel to DJ".to_owned()
                        };
                        if !output.is_empty() {
                            warn(discord.send_message(message.channel_id, &output, "", false));
                        }
                    } else {
                        let output = if let Some((server_id, channel_id)) = vchan {
                            match discord::voice::open_ytdl_stream(argument) {
                                Ok(stream) => {
                                    let voice = connection.voice(server_id);
                                    voice.set_deaf(true);
                                    voice.connect(channel_id);
                                    voice.play(stream);
                                    String::new()
                                }
                                Err(error) => format!("Error: {}", error),
                            }
                        } else {
                            "You must be in a voice channel to DJ".to_owned()
                        };
                        if !output.is_empty() {
                            warn(discord.send_message(message.channel_id, &output, "", false));
                        }
                    }
                }
            }
            Event::VoiceStateUpdate(server_id, _) => {
                // If someone moves/hangs up, and we are in a voice channel,
                if let Some(cur_channel) = connection.voice(server_id).current_channel() {
                    // and our current voice channel is empty, disconnect from voice
                    match server_id {
                        Some(server_id) => if let Some(srv) =
                            state.servers().iter().find(|srv| srv.id == server_id)
                        {
                            if srv.voice_states
                                .iter()
                                .filter(|vs| vs.channel_id == Some(cur_channel))
                                .count() <= 1
                            {
                                connection.voice(Some(server_id)).disconnect();
                            }
                        },
                        None => if let Some(call) = state.calls().get(&cur_channel) {
                            if call.voice_states.len() <= 1 {
                                connection.voice(server_id).disconnect();
                            }
                        },
                    }
                }
            }
            _ => {} // discard other events
        }
    }
}

fn warn<T, E: ::std::fmt::Debug>(result: Result<T, E>) {
    match result {
        Ok(_) => {}
        Err(err) => println!("[Warning] {:?}", err),
    }
}
<|endoftext|>


<commit_before>extern crate rand;
use std::net::{Ipv4Addr, SocketAddrV4, UdpSocket};
use std::io::{BufReader, Read, Error};
use std::fs::File;

#[ repr(u16) ]
enum PacketType{
    RRQ = 1,
    WRQ,
    DATA,
    ACK,
    ERROR
}

static NETASCII: &'static str = "netascii";
static OCTET: &'static str = "octet";

fn create_rrq_wrq_packet(p_type: PacketType, file_name: String, mode : &'static str)->Vec<u8>{
    let mut v = Vec::with_capacity(2+file_name.len()+1+mode.len()+1);
    v.push(0);
    v.push(p_type as u8);
    v.extend(file_name.as_bytes());
    v.push(0);//zero terminator
    v.extend(mode.as_bytes());
    v.push(0);//zero terminator
    v
}

struct FileStream<'a, Read>{
    file_name : String,
    start : u64,
    end:u64,
    buf:Option<&'a mut[u8]>,
    reader : BufReader<Read>
}

impl<'a> FileStream<'a, std::fs::File>{ //std::fs::File because we are talking concrete implementation
    fn new(file_name:String)->Option<Self>{
        let f = match std::fs::File::open(file_name.clone()){
            Ok(handle) => Some(handle),
            Err(msg) => None

        };
        if f.is_some(){
            let mut fs = FileStream{
                file_name:file_name,
                start: 0,
                end: 0,
                reader : BufReader::with_capacity(512, f.unwrap()),
                buf : None
            };
            //fs.reader.read(&mut buf);
            Some(fs)
        }
        else{
            None
        }
    }
}

impl<'a> Iterator for FileStream<'a, std::fs::File>{
    type Item = [u8;512];
    fn next(&mut self)->Option<Self::Item>{
        let mut arr = [0;512];
        self.reader.read(&mut arr);
        let mut i = 0usize;
        for c in self.buf.as_mut().unwrap().iter_mut(){
            *c = arr[i];
        }
        Some(arr)
    }
}

/*
fn create_data_packet()->Vec<u8>{

}
*/

fn recv() -> Result<(), Error> {
    // Define the local connection information
    let ip = Ipv4Addr::new(127, 0, 0, 1);
    let connection = SocketAddrV4::new(ip, 69);

    // Bind the socket
    let socket = try!(UdpSocket::bind(connection));

    // Read from the socket
    let mut buf = [0; 10];
    let (amt, src) = try!(socket.recv_from(&mut buf));

    // Print only the valid data (slice)
    println!("recvr recvd: {:?}", &buf[0 .. amt]);
    println!("recv sending...");
    socket.send_to(&[5,4,3], src);

    Ok(())
}

fn send() -> Result<(), Error> {
    // Define the local connection (to send the data from)
    let ip = Ipv4Addr::new(127, 0, 0, 1);
    //TODO generate port # using rand
    let connection = SocketAddrV4::new(ip, 9992);

    // Bind the socket
    let socket = try!(UdpSocket::bind(connection));

    // Define the remote connection (to send the data to)
    let connection2 = SocketAddrV4::new(ip, 69);

    // Send data via the socket
    let buf = &[0x01, 0x02, 0x03];
    try!(socket.send_to(buf, connection2));
    println!("sender sent {:?}", buf);

    let mut buf  = [0; 10];
    socket.recv_from(&mut buf);

    println!("sender recvd {:?}", buf);
    Ok(())
}

fn main() {

    let args : Vec<_> = std::env::args().collect();
    println!("{}", args[1]);
    if args[1] == "0"{
        println!("passed 0");
        recv();
    }
    else{
        println!("passed 1");
        send();
    }
}
<commit_msg>Return tuple of data and num of bytes read from the iterator<commit_after>extern crate rand;
use std::net::{Ipv4Addr, SocketAddrV4, UdpSocket};
use std::io::{BufReader, Read, Error};
use std::fs::File;

#[ repr(u16) ]
enum PacketType{
    RRQ = 1,
    WRQ,
    DATA,
    ACK,
    ERROR
}

static NETASCII: &'static str = "netascii";
static OCTET: &'static str = "octet";

fn create_rrq_wrq_packet(p_type: PacketType, file_name: String, mode : &'static str)->Vec<u8>{
    let mut v = Vec::with_capacity(2+file_name.len()+1+mode.len()+1);
    v.push(0);
    v.push(p_type as u8);
    v.extend(file_name.as_bytes());
    v.push(0);//zero terminator
    v.extend(mode.as_bytes());
    v.push(0);//zero terminator
    v
}

struct FileStream<'a, Read>{
    file_name : String,
    start : u64,
    end:u64,
    buf:Option<&'a mut[u8]>,
    reader : BufReader<Read>
}

impl<'a> FileStream<'a, std::fs::File>{ //std::fs::File because we are talking concrete implementation
    fn new(file_name:String)->Option<Self>{
        let f = match std::fs::File::open(file_name.clone()){
            Ok(handle) => Some(handle),
            Err(msg) => None

        };
        if f.is_some(){
            let mut fs = FileStream{
                file_name:file_name,
                start: 0,
                end: 0,
                reader : BufReader::with_capacity(512, f.unwrap()),
                buf : None
            };
            //fs.reader.read(&mut buf);
            Some(fs)
        }
        else{
            None
        }
    }
}

impl<'a> Iterator for FileStream<'a, std::fs::File>{
    type Item = ([u8;512], usize);
    fn next(&mut self)->Option<Self::Item>{
        let mut arr = [0;512];
        let num_bytes_read = self.reader.read(&mut arr);
        let mut i = 0usize;
        for c in self.buf.as_mut().unwrap().iter_mut(){
            *c = arr[i];
        }
        Some((arr, num_bytes_read.unwrap()))
    }
}

/*
fn create_data_packet()->Vec<u8>{

}
*/

fn recv() -> Result<(), Error> {
    // Define the local connection information
    let ip = Ipv4Addr::new(127, 0, 0, 1);
    let connection = SocketAddrV4::new(ip, 69);

    // Bind the socket
    let socket = try!(UdpSocket::bind(connection));

    // Read from the socket
    let mut buf = [0; 10];
    let (amt, src) = try!(socket.recv_from(&mut buf));

    // Print only the valid data (slice)
    println!("recvr recvd: {:?}", &buf[0 .. amt]);
    println!("recv sending...");
    socket.send_to(&[5,4,3], src);

    Ok(())
}

fn send() -> Result<(), Error> {
    // Define the local connection (to send the data from)
    let ip = Ipv4Addr::new(127, 0, 0, 1);
    //TODO generate port # using rand
    let connection = SocketAddrV4::new(ip, 9992);

    // Bind the socket
    let socket = try!(UdpSocket::bind(connection));

    // Define the remote connection (to send the data to)
    let connection2 = SocketAddrV4::new(ip, 69);

    // Send data via the socket
    let buf = &[0x01, 0x02, 0x03];
    try!(socket.send_to(buf, connection2));
    println!("sender sent {:?}", buf);

    let mut buf  = [0; 10];
    socket.recv_from(&mut buf);

    println!("sender recvd {:?}", buf);
    Ok(())
}

fn main() {

    let args : Vec<_> = std::env::args().collect();
    println!("{}", args[1]);
    if args[1] == "0"{
        println!("passed 0");
        recv();
    }
    else{
        println!("passed 1");
        send();
    }
}
<|endoftext|>


<commit_before>//
// main.rs
// Copyright (C) 2017 Szymon Urbaś <szymon.urbas@aol.com>
// Distributed under terms of the BSD (2-clause) license.
//
// Created on: 13 Mar 2017 21:03:41 +0100 (CET)
//

extern crate rand;
extern crate cursive;

use std::thread;
use std::time;

mod process;
mod scheduler;
mod fcfs;
mod tui;

use scheduler::*;
use tui::*;

/// Length of a single system clock tick (frequency of actual, real time)
const CLOCK_HZ: u64 = 50;
/// Switch context every <value> clock ticks
const SYSTEM_HZ: usize = 8;

fn main() {
  let mut tui = tui::new();

  let scenarios = {
    (0..32).map(|_| (0..3).map(|_| SYSTEM_HZ).collect::<Vec<usize>>()).collect::<Vec<Vec<usize>>>()
  };

  tui.add_result(format!("Testing the FCFS scheduler"));
  for (run, scenario) in scenarios.iter().enumerate() {
    let scheduler = fcfs::new();
    let avg = run_simulation(&mut tui, scheduler, scenario.clone());
    tui.add_result(format!("#{:02}: Average waiting time: {:02.2}", run, avg));
  }

  tui.update();

  loop {}
}

fn run_simulation<S>(mut tui: &mut Tui, mut scheduler: S, mut process_list: Vec<usize>) -> f64
where S: Scheduler {
  let mut clock_tick = 0;
  let mut process_spawner = process::new_spawner();
  let mut average_waiting_time = 0f64;
  let mut num_of_spawned_procs = 1;

  tui.set_header(format!("Using algorithm: {}", scheduler.name()));
  tui.debug(format!("{:05}: Starting simulation using {}", clock_tick, scheduler.name()));

  // vectors only support the pop (from the back) operation so
  // reverse it (so we pop from the front)
  process_list.reverse();

  // Add the equivalent of the 'init' process
  scheduler.add_process(process_spawner.spawn(process_list.pop().unwrap()));

  loop {
    // update the process view
    scheduler.list_processes(&mut tui);
    // update all the views
    tui.update();

    if !scheduler.has_processes() {
      // if there's no more processes - end the simulation
      // if a process can only be created by another process - there's
      // nothing else to do
      break;
    }

    // simulate executing the current process
    tui.debug(format!("{:05}: Executing {}", clock_tick, scheduler.current_proc().unwrap().name));
    scheduler.current_proc_mut().unwrap().record_execution();

    // Simulate other processes creating new processes
    // Assume that you can't create new processes, if there's none already
    if clock_tick % SYSTEM_HZ == 0 {
      if let Some(burst_time) = process_list.pop() {
        let new_proc = process_spawner.spawn(burst_time);
        tui.debug(format!("{:05}: Spawning {}", clock_tick, new_proc.name));
        scheduler.add_process(new_proc);
        num_of_spawned_procs += 1;
      }
    }

    if scheduler.current_proc().unwrap().done_executing() {
      tui.debug(format!("{:05}: Killing process {}", clock_tick, scheduler.current_proc().unwrap().name));
      scheduler.kill_current_proc();
    }

    if scheduler.has_processes() {
      if clock_tick % SYSTEM_HZ == SYSTEM_HZ - 1 {
        tui.debug(format!("{:05}: Triggering a scheduling round", clock_tick));
        scheduler.schedule();
        tui.debug(format!("{:05}: {} was waiting {} clock ticks", clock_tick, scheduler.current_proc().unwrap().name, scheduler.current_proc().unwrap().waiting_time));
        average_waiting_time -= average_waiting_time / num_of_spawned_procs as f64;
        average_waiting_time += scheduler.current_proc().unwrap().waiting_time as f64 / num_of_spawned_procs as f64;
      }

      // increase the waiting time for every process
      scheduler.increase_waiting_times();
    }

    thread::sleep(time::Duration::from_millis(1000 / CLOCK_HZ));

    clock_tick += 1;
  }

  average_waiting_time
}

/*
 * vi: ts=2 sw=2 expandtab
 */

<commit_msg>Add a macro so running a simulation is easier<commit_after>//
// main.rs
// Copyright (C) 2017 Szymon Urbaś <szymon.urbas@aol.com>
// Distributed under terms of the BSD (2-clause) license.
//
// Created on: 13 Mar 2017 21:03:41 +0100 (CET)
//

extern crate rand;
extern crate cursive;

use std::thread;
use std::time;

mod process;
mod scheduler;
mod fcfs;
mod tui;

use scheduler::*;
use tui::*;

/// Length of a single system clock tick (frequency of actual, real time)
const CLOCK_HZ: u64 = 50;
/// Switch context every <value> clock ticks
const SYSTEM_HZ: usize = 8;

fn main() {
  let mut tui = tui::new();

  let scenarios = {
    (0..32).map(|_| (0..3).map(|_| SYSTEM_HZ).collect::<Vec<usize>>()).collect::<Vec<Vec<usize>>>()
  };

  macro_rules! run_simulation {
    ($scheduler:ident) => (
      for (run, scenario) in scenarios.iter().enumerate() {
        let scheduler = $scheduler::new();
        let name = scheduler.name().clone();
        let avg = run_simulation(&mut tui, scheduler, scenario.clone());
        tui.add_result(format!("{}: #{:02}: Average waiting time: {:02.2}", name, run, avg));
      }
    )
  }

  run_simulation!(fcfs);

  tui.update();

  loop {}
}

fn run_simulation<S>(mut tui: &mut Tui, mut scheduler: S, mut process_list: Vec<usize>) -> f64
where S: Scheduler {
  let mut clock_tick = 0;
  let mut process_spawner = process::new_spawner();
  let mut average_waiting_time = 0f64;
  let mut num_of_spawned_procs = 1;

  tui.set_header(format!("Using algorithm: {}", scheduler.name()));
  tui.debug(format!("{:05}: Starting simulation using {}", clock_tick, scheduler.name()));

  // vectors only support the pop (from the back) operation so
  // reverse it (so we pop from the front)
  process_list.reverse();

  // Add the equivalent of the 'init' process
  scheduler.add_process(process_spawner.spawn(process_list.pop().unwrap()));

  loop {
    // update the process view
    scheduler.list_processes(&mut tui);
    // update all the views
    tui.update();

    if !scheduler.has_processes() {
      // if there's no more processes - end the simulation
      // if a process can only be created by another process - there's
      // nothing else to do
      break;
    }

    // simulate executing the current process
    tui.debug(format!("{:05}: Executing {}", clock_tick, scheduler.current_proc().unwrap().name));
    scheduler.current_proc_mut().unwrap().record_execution();

    // Simulate other processes creating new processes
    // Assume that you can't create new processes, if there's none already
    if clock_tick % SYSTEM_HZ == 0 {
      if let Some(burst_time) = process_list.pop() {
        let new_proc = process_spawner.spawn(burst_time);
        tui.debug(format!("{:05}: Spawning {}", clock_tick, new_proc.name));
        scheduler.add_process(new_proc);
        num_of_spawned_procs += 1;
      }
    }

    if scheduler.current_proc().unwrap().done_executing() {
      tui.debug(format!("{:05}: Killing process {}", clock_tick, scheduler.current_proc().unwrap().name));
      scheduler.kill_current_proc();
    }

    if scheduler.has_processes() {
      if clock_tick % SYSTEM_HZ == SYSTEM_HZ - 1 {
        tui.debug(format!("{:05}: Triggering a scheduling round", clock_tick));
        scheduler.schedule();
        tui.debug(format!("{:05}: {} was waiting {} clock ticks", clock_tick, scheduler.current_proc().unwrap().name, scheduler.current_proc().unwrap().waiting_time));
        average_waiting_time -= average_waiting_time / num_of_spawned_procs as f64;
        average_waiting_time += scheduler.current_proc().unwrap().waiting_time as f64 / num_of_spawned_procs as f64;
      }

      // increase the waiting time for every process
      scheduler.increase_waiting_times();
    }

    thread::sleep(time::Duration::from_millis(1000 / CLOCK_HZ));

    clock_tick += 1;
  }

  average_waiting_time
}

/*
 * vi: ts=2 sw=2 expandtab
 */

<|endoftext|>


<commit_before>use std::env;
use std::error;
use std::process;

#[macro_use] mod utils;

mod commands;
mod fat;

fn main() {
    let mut arg_iter = env::args();
    let name = arg_iter.next().unwrap();
    let command: String;
    match arg_iter.next() {
        Some(arg) => command = arg,
        None => {
            usage(name);
            process::exit(-1);
        }
    }

    // check for command
    let args: Vec<String> = arg_iter.collect();
    match commands::get_command(&command) {
        Some(cmd_func) =>
            if let Err(e) = cmd_func(&args) {
                error(e);
            },

        None => error(errorf!("command \"{}\" not recognized", command)),
    }
}

fn usage(name: String) {
    println!("{}:", name);
    commands::usages();
}

fn error(err: Box<error::Error>) {
    println!("error: {}", err);
    process::exit(-1);
}
<commit_msg>Clean up main<commit_after>use std::env;
use std::error;
use std::process;

#[macro_use] mod utils;

mod commands;
mod fat;

fn main() {
    let mut arg_iter = env::args();
    let name = arg_iter.next().unwrap();
    let command: String;
    match arg_iter.next() {
        Some(arg) => command = arg,
        None => {
            usage(name);
            process::exit(-1);
        }
    }

    // check for command
    let args: Vec<String> = arg_iter.collect();
    let cmd_func_opt = commands::get_command(&command);
    if let None = cmd_func_opt {
        error(errorf!("command \"{}\" not recognized", command));
    }

    let cmd_func = cmd_func_opt.unwrap();
    if let Err(e) = cmd_func(&args) {
        error(e);
    }
}

fn usage(name: String) {
    println!("{}:", name);
    commands::usages();
}

fn error(err: Box<error::Error>) {
    println!("error: {}", err);
    process::exit(-1);
}
<|endoftext|>


<commit_before>
mod curses;

use std::ffi::CString;

use curses::*;

enum DrawMe {
    Rec { width : i32, height : i32, x : i32, y : i32 },
    /*
    Character
    */
}

enum Mode { Normal, EnterRec, MoveRec }

fn inc_width( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width + 1, height: height, x: x, y: y },
        _ => panic!( "inc width encounters non-rec" ),
    }
}

fn inc_height( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height + 1, x: x, y: y },
        _ => panic!( "inc height encounters non-rec" ),
    }
}

fn dec_width( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width - 1, height: height, x: x, y: y },
        _ => panic!( "dec width encounters non-rec" ),
    }
}

fn dec_height( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height - 1, x: x, y: y },
        _ => panic!( "dec height encounters non-rec" ),
    }
}

fn inc_x( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height, x: x + 1, y: y },
        _ => panic!( "inc x encounters non-rec" ),
    }
}

fn inc_y( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height, x: x, y: y + 1 },
        _ => panic!( "inc y encounters non-rec" ),
    }
}

fn dec_x( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height, x: x - 1, y: y },
        _ => panic!( "dec x encounters non-rec" ),
    }
}

fn dec_y( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height, x: x, y: y - 1 },
        _ => panic!( "dec y encounters non-rec" ),
    }
}
fn mod_rec<F>( maybe_d : Option<DrawMe>, f : F ) -> Option<DrawMe>
    where F : Fn( DrawMe ) -> DrawMe {

    match maybe_d {
        Some( d ) => Some( f( d ) ),
        None => { None },
    }
}

unsafe fn render_shape( s : &DrawMe ) {
    match s {
        &DrawMe::Rec { width, height, x, y } => render_rec( width, height, x, y ),
        _ => (),
    }
}

unsafe fn render_rec( w : i32, h : i32, x : i32, y : i32 ) {
    let dot = CString::new( "." ).unwrap();
    let h_line = CString::new( "-" ).unwrap();
    let v_line = CString::new( "|" ).unwrap();
    let plus = CString::new( "+" ).unwrap();

    let mut h2 = h + 2;
    while h2 > 0 {
        let d : &CString = if h2 == h + 2 {
            &h_line
        } else if h2 == 1 {
            &h_line
        } else {
            &dot
        };
        let mut w2 = w;

        let other_d : &CString = if h2 == h + 2 {
            &plus
        } else if h2 == 1 {
            &plus
        } else {
            &v_line
        };
        mvprintw( y + h2 + UserY, x + w2 + 1 + UserX, other_d.as_ptr() );
        while w2 > 0 {
            mvprintw( y + h2 + UserY, x + w2 + UserX, d.as_ptr() );
            w2 -= 1;
        }
        mvprintw( y + h2 + UserY, x + UserX, other_d.as_ptr() );
        h2 -= 1;
    }
}

static mut UserX : i32 = 0;
static mut UserY : i32 = 0;

fn main() {
    let mut x = 0;
    let mut y = 0;
    unsafe {
        initscr();
        cbreak();
        noecho();

        let mut c = getch();
        let mut shapes : Vec<DrawMe> = vec! [];
        let mut mode : Mode = Mode::Normal;
        let mut active_rec : Option<DrawMe> = None;

        while c as u8 as char != 'q' {
            let c2 = c as u8 as char;

            match c2 {
                'r' => {
                    match mode {
                        Mode::Normal => {
                            active_rec = Some( DrawMe::Rec { width: 0, height: 0, x: x - UserX, y: y - UserY });
                            mode = Mode::EnterRec;
                        },
                        Mode::EnterRec => {
                            mode = Mode::MoveRec;
                        },
                        Mode::MoveRec => {
                            mode = Mode::Normal;
                            shapes.push( active_rec.unwrap() );
                            active_rec = None;
                        },
                    }
                },
                'j' => {
                    match mode {
                        Mode::Normal => {
                            y+=1;
                        },
                        Mode::EnterRec => {
                            active_rec = mod_rec( active_rec, inc_height );
                        },
                        Mode::MoveRec => {
                            active_rec = mod_rec( active_rec, inc_y );
                        },
                    }
                },
                'k' => {
                    match mode {
                       Mode::Normal => {
                           y-=1;
                       },
                       Mode::EnterRec => {
                            active_rec = mod_rec( active_rec, dec_height );
                       },
                       Mode::MoveRec => {
                            active_rec = mod_rec( active_rec, dec_y );
                       },
                    }
                },
                'l' => {
                    match mode {
                        Mode::Normal => {
                            x+=1;
                        },
                        Mode::EnterRec => {
                            active_rec = mod_rec( active_rec, inc_width );
                        },
                        Mode::MoveRec => {
                            active_rec = mod_rec( active_rec, inc_x );
                        },
                    }
                },
                'h' => {
                    match mode {
                        Mode::Normal => {
                            x-=1;
                        },
                        Mode::EnterRec => {
                            active_rec = mod_rec( active_rec, dec_width );
                        },
                        Mode::MoveRec => {
                            active_rec = mod_rec( active_rec, dec_x );
                        },
                    }
                },
                'J' => {
                    match mode {
                        Mode::Normal => {
                            UserY += 1;
                        },
                        _ => {},
                    }
                },
                'K' => {
                    match mode {
                        Mode::Normal => {
                            UserY -= 1;
                        },
                        _ => {},
                    }
                },
                'L' => {
                    match mode {
                        Mode::Normal => {
                            UserX += 1;
                        },
                        _ => {},
                    }
                },
                'H' => {
                    match mode {
                        Mode::Normal => {
                            UserX -= 1;
                        },
                        _ => {},
                    }
                },
                _ => (),
            }

            clear();

            match active_rec {
                Some( ref shape ) => render_shape( &shape ),
                None => {},
            }

            for s in &shapes {
                render_shape( s );
            }

            cursor_move( y, x );
            refresh();

            c = getch();
        }

        endwin();
    }
}

<commit_msg>adding new todos<commit_after>
mod curses;

use std::ffi::CString;

use curses::*;

// TODO delete active rectangle
// TODO save to file (just save shape coords and types, etc)
// TODO load file

// TODO use struct with common fields and use an enum for unshared ones
enum DrawMe {
    Rec { width : i32, height : i32, x : i32, y : i32 },
    /*
    Character
    */
}

enum Mode { Normal, EnterRec, MoveRec }

fn inc_width( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width + 1, height: height, x: x, y: y },
        _ => panic!( "inc width encounters non-rec" ),
    }
}

fn inc_height( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height + 1, x: x, y: y },
        _ => panic!( "inc height encounters non-rec" ),
    }
}

fn dec_width( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width - 1, height: height, x: x, y: y },
        _ => panic!( "dec width encounters non-rec" ),
    }
}

fn dec_height( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height - 1, x: x, y: y },
        _ => panic!( "dec height encounters non-rec" ),
    }
}

fn inc_x( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height, x: x + 1, y: y },
        _ => panic!( "inc x encounters non-rec" ),
    }
}

fn inc_y( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height, x: x, y: y + 1 },
        _ => panic!( "inc y encounters non-rec" ),
    }
}

fn dec_x( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height, x: x - 1, y: y },
        _ => panic!( "dec x encounters non-rec" ),
    }
}

fn dec_y( d : DrawMe ) -> DrawMe {
    match d {
        DrawMe::Rec { width, height, x, y } => DrawMe::Rec { width: width, height: height, x: x, y: y - 1 },
        _ => panic!( "dec y encounters non-rec" ),
    }
}
fn mod_rec<F>( maybe_d : Option<DrawMe>, f : F ) -> Option<DrawMe>
    where F : Fn( DrawMe ) -> DrawMe {

    match maybe_d {
        Some( d ) => Some( f( d ) ),
        None => { None },
    }
}

unsafe fn render_shape( s : &DrawMe ) {
    match s {
        &DrawMe::Rec { width, height, x, y } => render_rec( width, height, x, y ),
        _ => (),
    }
}

unsafe fn render_rec( w : i32, h : i32, x : i32, y : i32 ) {
    let dot = CString::new( "." ).unwrap();
    let h_line = CString::new( "-" ).unwrap();
    let v_line = CString::new( "|" ).unwrap();
    let plus = CString::new( "+" ).unwrap();

    let mut h2 = h + 2;
    while h2 > 0 {
        let d : &CString = if h2 == h + 2 {
            &h_line
        } else if h2 == 1 {
            &h_line
        } else {
            &dot
        };
        let mut w2 = w;

        let other_d : &CString = if h2 == h + 2 {
            &plus
        } else if h2 == 1 {
            &plus
        } else {
            &v_line
        };
        mvprintw( y + h2 + UserY, x + w2 + 1 + UserX, other_d.as_ptr() );
        while w2 > 0 {
            mvprintw( y + h2 + UserY, x + w2 + UserX, d.as_ptr() );
            w2 -= 1;
        }
        mvprintw( y + h2 + UserY, x + UserX, other_d.as_ptr() );
        h2 -= 1;
    }
}

static mut UserX : i32 = 0;
static mut UserY : i32 = 0;

fn main() {
    let mut x = 0;
    let mut y = 0;
    unsafe {
        initscr();
        cbreak();
        noecho();

        let mut c = getch();
        let mut shapes : Vec<DrawMe> = vec! [];
        let mut mode : Mode = Mode::Normal;
        let mut active_rec : Option<DrawMe> = None;

        while c as u8 as char != 'q' {
            let c2 = c as u8 as char;

            match c2 {
                'r' => {
                    match mode {
                        Mode::Normal => {
                            active_rec = Some( DrawMe::Rec { width: 0, height: 0, x: x - UserX, y: y - UserY });
                            mode = Mode::EnterRec;
                        },
                        Mode::EnterRec => {
                            mode = Mode::MoveRec;
                        },
                        Mode::MoveRec => {
                            mode = Mode::Normal;
                            shapes.push( active_rec.unwrap() );
                            active_rec = None;
                        },
                    }
                },
                'j' => {
                    match mode {
                        Mode::Normal => {
                            y+=1;
                        },
                        Mode::EnterRec => {
                            active_rec = mod_rec( active_rec, inc_height );
                        },
                        Mode::MoveRec => {
                            active_rec = mod_rec( active_rec, inc_y );
                        },
                    }
                },
                'k' => {
                    match mode {
                       Mode::Normal => {
                           y-=1;
                       },
                       Mode::EnterRec => {
                            active_rec = mod_rec( active_rec, dec_height );
                       },
                       Mode::MoveRec => {
                            active_rec = mod_rec( active_rec, dec_y );
                       },
                    }
                },
                'l' => {
                    match mode {
                        Mode::Normal => {
                            x+=1;
                        },
                        Mode::EnterRec => {
                            active_rec = mod_rec( active_rec, inc_width );
                        },
                        Mode::MoveRec => {
                            active_rec = mod_rec( active_rec, inc_x );
                        },
                    }
                },
                'h' => {
                    match mode {
                        Mode::Normal => {
                            x-=1;
                        },
                        Mode::EnterRec => {
                            active_rec = mod_rec( active_rec, dec_width );
                        },
                        Mode::MoveRec => {
                            active_rec = mod_rec( active_rec, dec_x );
                        },
                    }
                },
                'J' => {
                    match mode {
                        Mode::Normal => {
                            UserY += 1;
                        },
                        _ => {},
                    }
                },
                'K' => {
                    match mode {
                        Mode::Normal => {
                            UserY -= 1;
                        },
                        _ => {},
                    }
                },
                'L' => {
                    match mode {
                        Mode::Normal => {
                            UserX += 1;
                        },
                        _ => {},
                    }
                },
                'H' => {
                    match mode {
                        Mode::Normal => {
                            UserX -= 1;
                        },
                        _ => {},
                    }
                },
                _ => (),
            }

            clear();

            match active_rec {
                Some( ref shape ) => render_shape( &shape ),
                None => {},
            }

            for s in &shapes {
                render_shape( s );
            }

            cursor_move( y, x );
            refresh();

            c = getch();
        }

        endwin();
    }
}

<|endoftext|>


<commit_before>extern crate cairo_sys;
extern crate cairo;
extern crate chrono;
extern crate futures;
extern crate mio;
extern crate pango;
extern crate pangocairo;
extern crate tokio_core;
extern crate tokio_timer;
extern crate xcb_util;
extern crate xcb;

use std::rc::Rc;

use futures::{Async, Future, Poll, Stream};
use mio::unix::EventedFd;

mod text;
use text::*;
mod widgets;
use widgets::*;
mod window;
use window::*;

fn main() {
    let (conn, screen_idx) = xcb::Connection::connect_with_xlib_display().unwrap();
    let conn = Rc::new(conn);

    let w = Window::new(conn.clone(), screen_idx as usize);

    use tokio_core::reactor::{Core, Handle, PollEvented};

    let mut core = Core::new().unwrap();
    let handle = core.handle();

    struct XcbEventStream<'a> {
        conn: Rc<xcb::Connection>,
        poll: PollEvented<EventedFd<'a>>,
        would_block: bool,
    };

    impl<'a> XcbEventStream<'a> {
        fn new(conn: Rc<xcb::Connection>,
               conn_fd: &'a std::os::unix::io::RawFd,
               handle: &Handle)
               -> XcbEventStream<'a> {
            // XXX Lifetime of the connection?
            XcbEventStream {
                conn: conn,
                poll: PollEvented::new(EventedFd(conn_fd), &handle).unwrap(),
                would_block: true,
            }
        }
    }

    impl<'a> Stream for XcbEventStream<'a> {
        type Item = xcb::GenericEvent;
        type Error = ();

        fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
            if self.would_block {
                match self.poll.poll_read() {
                    Async::Ready(()) => self.would_block = false,
                    Async::NotReady => return Ok(Async::NotReady),
                }
            }

            match self.conn.poll_for_event() {
                Some(event) => Ok(Async::Ready(Some(event))),
                None => {
                    self.would_block = true;
                    self.poll.need_read();
                    Ok(Async::NotReady)
                }
            }
        }
    }

    let inactive_attr = Attributes {
        font: pango::FontDescription::from_string("Envy Code R 27"),
        fg_color: Color::white(),
        bg_color: None,
        padding: Padding::new(10.0, 10.0, 5.0, 5.0),
    };
    let active_attr = inactive_attr.with_bg_color(Some(Color::blue()));

    let conn_fd = unsafe { xcb::ffi::base::xcb_get_file_descriptor(conn.get_raw_conn()) };
    let stream = XcbEventStream::new(conn.clone(), &conn_fd, &handle);

    let widgets: Vec<Box<Widget>> = vec![
        Box::new(Pager::new(active_attr, inactive_attr.clone())) as Box<Widget>,
        Box::new(ActiveWindowTitle::new(inactive_attr.clone())) as Box<Widget>,
        Box::new(Clock::new(inactive_attr.clone())) as Box<Widget>,
    ];

    let widget_list = widgets::WidgetList::new(widgets);

    struct MainLoop<'a> {
        xcb_stream: XcbEventStream<'a>,
        widget_list: WidgetList,
        window: Window,
    }

    impl<'a> Future for MainLoop<'a> {
        type Item = ();
        type Error = ();

        fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
            match self.widget_list.poll() {
                Ok(Async::Ready(texts)) => self.window.expose(self.widget_list.texts()),
                Ok(Async::NotReady) => {},
                Err(e) => return Err(e),
            }
            match self.xcb_stream.poll() {
                Ok(Async::Ready(event)) => {
                    if let Some(event) = event {
                        let r = event.response_type() & !0x80;
                        match r {
                            xcb::EXPOSE => self.window.expose(self.widget_list.texts()),
                            _ => {}
                        }
                    }
                },
                Ok(Async::NotReady) => {},
                Err(e) => return Err(e),
            }
            Ok(Async::NotReady)
        }
    }

    let fut = MainLoop {
        xcb_stream: stream,
        widget_list: widget_list,
        window: w,
    };

    core.run(fut).unwrap();
}
<commit_msg>Use new texts when available.<commit_after>extern crate cairo_sys;
extern crate cairo;
extern crate chrono;
extern crate futures;
extern crate mio;
extern crate pango;
extern crate pangocairo;
extern crate tokio_core;
extern crate tokio_timer;
extern crate xcb_util;
extern crate xcb;

use std::rc::Rc;

use futures::{Async, Future, Poll, Stream};
use mio::unix::EventedFd;

mod text;
use text::*;
mod widgets;
use widgets::*;
mod window;
use window::*;

fn main() {
    let (conn, screen_idx) = xcb::Connection::connect_with_xlib_display().unwrap();
    let conn = Rc::new(conn);

    let w = Window::new(conn.clone(), screen_idx as usize);

    use tokio_core::reactor::{Core, Handle, PollEvented};

    let mut core = Core::new().unwrap();
    let handle = core.handle();

    struct XcbEventStream<'a> {
        conn: Rc<xcb::Connection>,
        poll: PollEvented<EventedFd<'a>>,
        would_block: bool,
    };

    impl<'a> XcbEventStream<'a> {
        fn new(conn: Rc<xcb::Connection>,
               conn_fd: &'a std::os::unix::io::RawFd,
               handle: &Handle)
               -> XcbEventStream<'a> {
            // XXX Lifetime of the connection?
            XcbEventStream {
                conn: conn,
                poll: PollEvented::new(EventedFd(conn_fd), &handle).unwrap(),
                would_block: true,
            }
        }
    }

    impl<'a> Stream for XcbEventStream<'a> {
        type Item = xcb::GenericEvent;
        type Error = ();

        fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
            if self.would_block {
                match self.poll.poll_read() {
                    Async::Ready(()) => self.would_block = false,
                    Async::NotReady => return Ok(Async::NotReady),
                }
            }

            match self.conn.poll_for_event() {
                Some(event) => Ok(Async::Ready(Some(event))),
                None => {
                    self.would_block = true;
                    self.poll.need_read();
                    Ok(Async::NotReady)
                }
            }
        }
    }

    let inactive_attr = Attributes {
        font: pango::FontDescription::from_string("Envy Code R 27"),
        fg_color: Color::white(),
        bg_color: None,
        padding: Padding::new(10.0, 10.0, 5.0, 5.0),
    };
    let active_attr = inactive_attr.with_bg_color(Some(Color::blue()));

    let conn_fd = unsafe { xcb::ffi::base::xcb_get_file_descriptor(conn.get_raw_conn()) };
    let stream = XcbEventStream::new(conn.clone(), &conn_fd, &handle);

    let widgets: Vec<Box<Widget>> = vec![
        Box::new(Pager::new(active_attr, inactive_attr.clone())) as Box<Widget>,
        Box::new(ActiveWindowTitle::new(inactive_attr.clone())) as Box<Widget>,
        Box::new(Clock::new(inactive_attr.clone())) as Box<Widget>,
    ];

    let widget_list = widgets::WidgetList::new(widgets);

    struct MainLoop<'a> {
        xcb_stream: XcbEventStream<'a>,
        widget_list: WidgetList,
        window: Window,
    }

    impl<'a> Future for MainLoop<'a> {
        type Item = ();
        type Error = ();

        fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
            match self.widget_list.poll() {
                Ok(Async::Ready(Some(texts))) => self.window.expose(texts),
                Err(e) => return Err(e),
                _ => {}
            }
            match self.xcb_stream.poll() {
                Ok(Async::Ready(Some(event))) => {
                    let r = event.response_type() & !0x80;
                    match r {
                        xcb::EXPOSE => self.window.expose(self.widget_list.texts()),
                        _ => {}
                    }
                },
                Err(e) => return Err(e),
                _ => {},
            }
            Ok(Async::NotReady)
        }
    }

    let fut = MainLoop {
        xcb_stream: stream,
        widget_list: widget_list,
        window: w,
    };

    core.run(fut).unwrap();
}
<|endoftext|>


<commit_before>extern crate rand;
extern crate crossbeam;

use std::sync::mpsc::sync_channel;
use std::thread;
use std::time::Duration;

mod text;

fn main() {
    crossbeam::scope(|scope| {
        use rand::SeedableRng;
        let mut lex = text::Lexicon::new(rand::Isaac64Rng::from_seed(&[1, 2, 3, 4]));
        let nowhere = lex.source("nowhere".to_string());
        let nobody = lex.author(nowhere.clone(), "nobody".to_string());
        lex.tell(nowhere.clone(), nobody.clone(), "nothing is good".to_string());
        lex.tell(nowhere.clone(), nobody.clone(), "everything is good".to_string());
        lex.tell(nowhere.clone(), nobody.clone(), "nothing is bad".to_string());
        let (sender, receiver) = sync_channel(0);
        scope.spawn(move || {
            thread::sleep(Duration::from_millis(5000));
            sender.send(()).ok().unwrap();
        });
        while let Err(_) = receiver.try_recv() {
            lex.think();
        }
        lex.show_categories();
        for _ in 0..32 {
            println!("lex says: {}", lex.initiate(nowhere.clone()).unwrap());
        }
    });
}
<commit_msg>add cli<commit_after>extern crate rand;
extern crate crossbeam;

mod text;
mod cli;

fn main() {
    use rand::SeedableRng;
    let mut lex = text::Lexicon::new(rand::Isaac64Rng::from_seed(&[1, 2, 3, 4]));
    for decision in cli::new() {
        use cli::Decision;
        match decision {
            Decision::None => {
                lex.think();
            },
        }
    }
}
<|endoftext|>


<commit_before>#![warn(rust_2018_idioms)]

use tokio::io::AsyncWriteExt;
use tokio::net::{TcpListener, TcpStream};

use futures::FutureExt;
use std::error::Error;
use std::{env, io};

use nix::sys::socket::{getsockopt, sockopt, InetAddr};
use std::net::SocketAddr;
use std::os::unix::io::AsRawFd;

use bytes::BytesMut;
use tokio::net::tcp::{ReadHalf, WriteHalf};
use tokio::time;

const BUF_SIZE: usize = 1024 * 1024;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let listen_addr = env::args()
        .nth(1)
        .unwrap_or_else(|| "127.0.0.1:1080".to_string());

    let timeout = env::args()
        .nth(2)
        .unwrap_or_else(|| "3600".to_string()).parse::<u64>().unwrap();

    let timeout = time::Duration::from_secs(timeout);

    println!("Listening on: {}", listen_addr);

    let listener = TcpListener::bind(listen_addr).await?;

    while let Ok((inbound, client_addr)) = listener.accept().await {
        let server_addr = getsockopt(inbound.as_raw_fd(), sockopt::OriginalDst).unwrap();
        let server_addr = InetAddr::V4(server_addr).to_std();
        eprintln!(
            "[INFO]{} -> {}: connection incoming",
            client_addr, server_addr
        );
        if inbound.local_addr().unwrap() == server_addr {
            eprintln!(
                "[WARN]{} -> {}: connection from local network",
                client_addr, server_addr
            );
            continue;
        }
        let transfer = transfer(inbound, server_addr, timeout).map(move |r| {
            if let Err(e) = r {
                println!(
                    "[INFO]{} -> {}: connection closed with error; {}",
                    client_addr, server_addr, e
                );
            }
        });
        tokio::spawn(transfer);
    }

    Ok(())
}

async fn transfer(mut inbound: TcpStream, proxy_addr: SocketAddr, timeout: time::Duration) -> Result<(), Box<dyn Error>> {
    let mut outbound = TcpStream::connect(proxy_addr).await?;

    inbound.set_nodelay(true)?;
    outbound.set_nodelay(true)?;

    let client_addr = inbound.peer_addr().unwrap();
    let server_addr = outbound.peer_addr().unwrap();

    let (mut ri, mut wi) = inbound.split();
    let (mut ro, mut wo) = outbound.split();

    tokio::try_join!(
        copy_one_direction(&mut ro, &mut wi, timeout),
        copy_one_direction(&mut ri, &mut wo, timeout)
    )?;
    eprintln!(
        "[INFO]{} -> {}: connection closed",
        client_addr, server_addr
    );

    Ok(())
}

async fn copy_one_direction(
    from: &mut ReadHalf<'_>,
    to: &mut WriteHalf<'_>,
    timeout: time::Duration,
) -> std::io::Result<()> {
    loop {
        if let Err(_) = time::timeout(timeout,from.readable()).await {
            break
        }
        {
            let mut buf = BytesMut::with_capacity(BUF_SIZE);
            match from.try_read_buf(&mut buf) {
                Ok(0) => {
                    break;
                }
                Ok(_n) => {
                    to.write_all_buf(&mut buf).await?;
                }
                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                    continue;
                }
                Err(e) => {
                    return Err(e.into());
                }
            }
        }
    }
    to.shutdown().await
}
<commit_msg>cargo clippy<commit_after>#![warn(rust_2018_idioms)]

use tokio::io::AsyncWriteExt;
use tokio::net::{TcpListener, TcpStream};

use futures::FutureExt;
use std::error::Error;
use std::{env, io};

use nix::sys::socket::{getsockopt, sockopt, InetAddr};
use std::net::SocketAddr;
use std::os::unix::io::AsRawFd;

use bytes::BytesMut;
use tokio::net::tcp::{ReadHalf, WriteHalf};
use tokio::time;

const BUF_SIZE: usize = 1024 * 1024;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let listen_addr = env::args()
        .nth(1)
        .unwrap_or_else(|| "127.0.0.1:1080".to_string());

    let timeout = env::args()
        .nth(2)
        .unwrap_or_else(|| "3600".to_string()).parse::<u64>().unwrap();

    let timeout = time::Duration::from_secs(timeout);

    println!("Listening on: {}", listen_addr);

    let listener = TcpListener::bind(listen_addr).await?;

    while let Ok((inbound, client_addr)) = listener.accept().await {
        let server_addr = getsockopt(inbound.as_raw_fd(), sockopt::OriginalDst).unwrap();
        let server_addr = InetAddr::V4(server_addr).to_std();
        eprintln!(
            "[INFO]{} -> {}: connection incoming",
            client_addr, server_addr
        );
        if inbound.local_addr().unwrap() == server_addr {
            eprintln!(
                "[WARN]{} -> {}: connection from local network",
                client_addr, server_addr
            );
            continue;
        }
        let transfer = transfer(inbound, server_addr, timeout).map(move |r| {
            if let Err(e) = r {
                println!(
                    "[INFO]{} -> {}: connection closed with error; {}",
                    client_addr, server_addr, e
                );
            }
        });
        tokio::spawn(transfer);
    }

    Ok(())
}

async fn transfer(mut inbound: TcpStream, proxy_addr: SocketAddr, timeout: time::Duration) -> Result<(), Box<dyn Error>> {
    let mut outbound = TcpStream::connect(proxy_addr).await?;

    inbound.set_nodelay(true)?;
    outbound.set_nodelay(true)?;

    let client_addr = inbound.peer_addr().unwrap();
    let server_addr = outbound.peer_addr().unwrap();

    let (mut ri, mut wi) = inbound.split();
    let (mut ro, mut wo) = outbound.split();

    tokio::try_join!(
        copy_one_direction(&mut ro, &mut wi, timeout),
        copy_one_direction(&mut ri, &mut wo, timeout)
    )?;
    eprintln!(
        "[INFO]{} -> {}: connection closed",
        client_addr, server_addr
    );

    Ok(())
}

async fn copy_one_direction(
    from: &mut ReadHalf<'_>,
    to: &mut WriteHalf<'_>,
    timeout: time::Duration,
) -> std::io::Result<()> {
    loop {
        if (time::timeout(timeout,from.readable()).await).is_err() {
            break
        }
        {
            let mut buf = BytesMut::with_capacity(BUF_SIZE);
            match from.try_read_buf(&mut buf) {
                Ok(0) => {
                    break;
                }
                Ok(_n) => {
                    to.write_all_buf(&mut buf).await?;
                }
                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                    continue;
                }
                Err(e) => {
                    return Err(e);
                }
            }
        }
    }
    to.shutdown().await
}
<|endoftext|>


<commit_before>use std::io::{Write, BufWriter};
use std::fs::File;
mod vector;
use vector::Vec3;
mod ray;
use ray::Ray;

fn main() {
  let nx = 300;
  let ny = 200;
  let data = format!("{}\n{} {}\n{}\n", "P3", nx, ny, 255);
  let f = File::create("target/image.ppm").expect("Unable to create file");
  let mut f = BufWriter::new(f);
  f.write_all(data.as_bytes()).expect("Unable to write data");

  for j in (0..ny).rev() {
    for i in 0..nx {
      let color = Vec3::new(i as f64 / nx as f64, j as f64 / ny as f64, 0.5);

      let ir = (255.99*color.i) as i32;
      let ig = (255.99*color.j) as i32;
      let ib = (255.99*color.k) as i32;
      f.write_all(format!("{} {} {}\n", ir, ig, ib).as_bytes()).expect("Unable to write data");
    }
  }
}<commit_msg>Use ray for calculating blue-white blend<commit_after>use std::io::{Write, BufWriter};
use std::fs::File;
mod vector;
use vector::Vec3;
mod ray;
use ray::Ray;

fn color(ray : Ray) -> Vec3 {
  let unit_direction = ray.direction().unit_vector();
  let t = 0.5 * (unit_direction.y() + 1.0);
  return Vec3::new(1.0,1.0,1.0) * (1.0 - t) + Vec3::new(0.5,0.7,1.0) * t;
}

fn main() {
  let nx = 200;
  let ny = 100;
  let data = format!("{}\n{} {}\n{}\n", "P3", nx, ny, 255);
  let f = File::create("target/image.ppm").expect("Unable to create file");
  let mut f = BufWriter::new(f);
  f.write_all(data.as_bytes()).expect("Unable to write data");

  let lower_left_corner = Vec3::new(-2.0, -1.0, -1.0);
  let horizontal = Vec3::new(4.0, 0.0, 0.0);
  let vertical = Vec3::new(0.0, 2.0, 0.0);
  let origin = Vec3::new(0.0, 0.0, 0.0);

  for j in (0..ny).rev() {
    for i in 0..nx {
      let u = i as f64 / nx as f64;
      let v = j as f64 / ny as f64;
      let r = Ray::new(origin, lower_left_corner + horizontal * u + vertical * v);
      let col = color(r);

      let ir = (255.99*col.r()) as i32;
      let ig = (255.99*col.g()) as i32;
      let ib = (255.99*col.b()) as i32;
      f.write_all(format!("{} {} {}\n", ir, ig, ib).as_bytes()).expect("Unable to write data");
    }
  }
}<|endoftext|>


<commit_before>//! Main module of way-cooler

#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate dbus_macros;

#[cfg(not(test))]
extern crate rustwlc;

extern crate getopts;

#[cfg(test)]
extern crate dummy_rustwlc as rustwlc;

#[macro_use]
extern crate log;
extern crate env_logger;

#[macro_use]
extern crate hlua;
extern crate rustc_serialize;
#[macro_use]
extern crate json_macro;

extern crate nix;

extern crate petgraph;

extern crate uuid;

extern crate dbus;

use std::env;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::Path;
use getopts::Options;
use log::LogLevel;

use nix::sys::signal::{SigHandler, SigSet, SigAction, SaFlags};
use nix::sys::signal;

use rustwlc::types::LogType;

#[macro_use] // As it happens, it's important to declare the macros first.
mod macros;
mod convert;

mod callbacks;
mod keys;

mod lua;
mod registry;
mod commands;
mod ipc;

mod layout;

const VERSION: &'static str = env!("CARGO_PKG_VERSION");
const MODULE_PATH: &'static str = "/proc/modules";

/// Callback to route wlc logs into env_logger
fn log_handler(level: LogType, message: &str) {
    match level {
        LogType::Info => info!("wlc: {}", message),
        LogType::Warn => warn!("wlc: {}", message),
        LogType::Error => error!("wlc: {}", message),
        LogType::Wayland => info!("wayland: {}", message)
    }
}

/// Formats the log strings properly
fn log_format(record: &log::LogRecord) -> String {
    let color = match record.level() {
        LogLevel::Info => "",
        LogLevel::Trace => "\x1B[37m",
        LogLevel::Debug => "\x1B[37m",
        LogLevel::Warn =>  "\x1B[33m",
        LogLevel::Error => "\x1B[31m",
    };
    let location = record.location();
    let file = location.file();
    let line = location.line();
    let mut module_path = location.module_path();
    if let Some(index) = module_path.find("way_cooler::") {
        let index = index + "way_cooler::".len();
        module_path = &module_path[index..];
    }
    format!("{} {} [{}] \x1B[37m{}:{}\x1B[0m{0} {} \x1B[0m",
            color, record.level(), module_path, file, line, record.args())
}

/// Checks the loaded modules, and reports any problematic proprietary ones
fn detect_proprietary() {
    if env::var("DISPLAY").is_ok() {
        // If DISPLAY is present, we are running embedded
        return
    }
    match File::open(Path::new(MODULE_PATH)) {
        Ok(file) => {
            let reader = BufReader::new(&file);
            for line in reader.lines() {
                if let Ok(line) = line {
                    if line.contains("nvidia") {
                        error!("Warning: Proprietary nvidia graphics drivers are installed, \
                               but they are not compatible with Wayland. Consider using nouveau drivers for Wayland.");
                        break;
                    } else if line.contains("fglrx") {
                        error!("Warning: Proprietary AMD graphics drivers are installed, but they are not compatible with Wayland. \
                               Consider using radeon drivers for Waylad.");
                        break;
                    }
                }
            }
        },
        Err(err) => {
            warn!("Could not read proprietary modules at \"{}\", because: {:#?}",
                  MODULE_PATH, err);
        }
    }
}

/// Initializes the logging system.
/// Can be called from within test methods.
pub fn init_logs() {
    // Prepare log builder
    let mut builder = env_logger::LogBuilder::new();
    builder.format(log_format);
    builder.filter(None, log::LogLevelFilter::Trace);
    if env::var("WAY_COOLER_LOG").is_ok() {
        builder.parse(&env::var("WAY_COOLER_LOG").expect("Asserted unwrap!"));
    }
    builder.init().expect("Unable to initialize logging!");
    info!("Logger initialized, setting wlc handlers.");
}

/// Handler for signals, should close the ipc
extern "C" fn sig_handle(_: nix::libc::c_int) {
    rustwlc::terminate();
}

fn main() {
    let args: Vec<String> = env::args().collect();

    let mut opts = Options::new();
    opts.optflag("", "version", "show version information");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => {
            println!("{}", f.to_string());
            std::process::exit(1);
        }
    };
    if matches.opt_present("version") {
        println!("Way Cooler {}", VERSION);
        println!("Way Cooler IPC version {}", ipc::VERSION);
        return
    }
    println!("Launching way-cooler...");

    let sig_action = SigAction::new(SigHandler::Handler(sig_handle), SaFlags::empty(), SigSet::empty());
    unsafe {signal::sigaction(signal::SIGINT, &sig_action).unwrap() };

    // Start logging first
    init_logs();
    // Detect proprietary modules loaded, and warn about them.
    detect_proprietary();

    // Initialize callbacks
    callbacks::init();

    // Handle wlc logs
    rustwlc::log_set_rust_handler(log_handler);

    // Prepare to launch wlc
    let run_wlc = rustwlc::init2().expect("Unable to initialize wlc!");

    // (Future config initialization goes here)
    // Initialize commands
    commands::init();
    // Add API to registry
    registry::init();
    // Register Alt+Esc keybinding
    keys::init();
    // Start listening for clients
    ipc::init();

    // Hand control over to wlc's event loop
    info!("Running wlc...");
    run_wlc();
}
<commit_msg>Cleaned up main.rs<commit_after>//! Main module of way-cooler

#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate dbus_macros;
#[cfg(not(test))]
extern crate rustwlc;
extern crate getopts;
#[cfg(test)]
extern crate dummy_rustwlc as rustwlc;
#[macro_use]
extern crate log;
extern crate env_logger;
#[macro_use]
extern crate hlua;
extern crate rustc_serialize;
#[macro_use]
extern crate json_macro;
extern crate nix;
extern crate petgraph;
extern crate uuid;
extern crate dbus;

#[macro_use]
mod macros;
mod convert;

mod callbacks;
mod keys;

mod lua;
mod registry;
mod commands;
mod ipc;

mod layout;

use std::env;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::Path;

use getopts::Options;
use log::LogLevel;
use nix::sys::signal::{self, SigHandler, SigSet, SigAction, SaFlags};

use rustwlc::types::LogType;

const VERSION: &'static str = env!("CARGO_PKG_VERSION");
const DRIVER_MOD_PATH: &'static str = "/proc/modules";

/// Callback to route wlc logs into env_logger
fn log_handler(level: LogType, message: &str) {
    match level {
        LogType::Info => info!("wlc: {}", message),
        LogType::Warn => warn!("wlc: {}", message),
        LogType::Error => error!("wlc: {}", message),
        LogType::Wayland => info!("wayland: {}", message)
    }
}

/// Formats the log strings properly
fn log_format(record: &log::LogRecord) -> String {
    let color = match record.level() {
        LogLevel::Info => "",
        LogLevel::Trace => "\x1B[37m",
        LogLevel::Debug => "\x1B[37m",
        LogLevel::Warn =>  "\x1B[33m",
        LogLevel::Error => "\x1B[31m",
    };
    let location = record.location();
    let file = location.file();
    let line = location.line();
    let mut module_path = location.module_path();
    if let Some(index) = module_path.find("way_cooler::") {
        let index = index + "way_cooler::".len();
        module_path = &module_path[index..];
    }
    format!("{} {} [{}] \x1B[37m{}:{}\x1B[0m{0} {} \x1B[0m",
            color, record.level(), module_path, file, line, record.args())
}

/// Checks the loaded modules, and reports any problematic proprietary ones
fn detect_proprietary() {
    // If DISPLAY is present, we are running embedded
    if env::var("DISPLAY").is_ok() {
        return
    }
    match File::open(Path::new(DRIVER_MOD_PATH)) {
        Ok(file) => {
            let reader = BufReader::new(&file);
            for line in reader.lines() {
                if let Ok(line) = line {
                    if line.contains("nvidia") {
                        error!("Warning: Proprietary nvidia graphics drivers are installed, \
                               but they are not compatible with Wayland. \
                               Consider using nouveau drivers for Wayland.");
                        break;
                    } else if line.contains("fglrx") {
                        error!("Warning: Proprietary AMD graphics drivers are installed, \
                                but they are not compatible with Wayland. \
                               Consider using radeon drivers for Waylad.");
                        break;
                    }
                }
            }
        },
        Err(err) => {
            warn!("Could not read proprietary modules at \"{}\", because: {:#?}",
                  DRIVER_MOD_PATH, err);
            warn!("If you are running proprietary AMD or Nvidia graphics drivers, \
                   Way Cooler may not work for you");
        }
    }
}

/// Initializes the logging system.
pub fn init_logs() {
    let mut builder = env_logger::LogBuilder::new();
    builder.format(log_format);
    builder.filter(None, log::LogLevelFilter::Trace);
    if env::var("WAY_COOLER_LOG").is_ok() {
        builder.parse(&env::var("WAY_COOLER_LOG")
                      .expect("WAY_COOLER_LOG not defined"));
    }
    builder.init().expect("Unable to initialize logging!");
    info!("Logger initialized, setting wlc handlers.");
}

/// Handler for signals
extern "C" fn sig_handle(_: nix::libc::c_int) {
    rustwlc::terminate();
}

fn main() {
    let args: Vec<String> = env::args().collect();

    let mut opts = Options::new();
    opts.optflag("", "version", "show version information");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => {
            println!("{}", f.to_string());
            std::process::exit(1);
        }
    };
    if matches.opt_present("version") {
        println!("Way Cooler {}", VERSION);
        println!("Way Cooler IPC version {}", ipc::VERSION);
        return
    }
    println!("Launching way-cooler...");

    let sig_action = SigAction::new(SigHandler::Handler(sig_handle), SaFlags::empty(),
                                    SigSet::empty());
    unsafe {signal::sigaction(signal::SIGINT, &sig_action).unwrap() };

    init_logs();
    detect_proprietary();
    // This prepares wlc, doesn't run main loop until run_wlc is called
    let run_wlc = rustwlc::init2().expect("Unable to initialize wlc!");
    rustwlc::log_set_rust_handler(log_handler);
    callbacks::init();
    commands::init();
    registry::init();
    keys::init();
    ipc::init();

    info!("Running wlc...");
    run_wlc();
}
<|endoftext|>