<commit_before>#![feature(phase, macro_rules)]
#![deny(unused)]

extern crate serialize;
#[phase(plugin, link)] extern crate log;

extern crate cargo;

use std::collections::TreeSet;
use std::os;
use std::io;
use std::io::fs::{mod, PathExtensions};
use std::io::process::{Command,InheritFd,ExitStatus,ExitSignal};

use cargo::{execute_main_without_stdin, handle_error, shell};
use cargo::core::MultiShell;
use cargo::util::{CliError, CliResult};

#[deriving(Decodable)]
struct Flags {
    flag_list: bool,
    flag_verbose: bool,
    arg_command: String,
    arg_args: Vec<String>,
}

const USAGE: &'static str = "
Rust's package manager

Usage:
    cargo <command> [<args>...]
    cargo [options]

Options:
    -h, --help       Display this message
    -V, --version    Print version info and exit
    --list           List installed commands
    -v, --verbose    Use verbose output

Some common cargo commands are:
    build       Compile the current project
    clean       Remove the target directory
    doc         Build this project's and its dependencies' documentation
    new         Create a new cargo project
    run         Build and execute src/main.rs
    test        Run the tests
    bench       Run the benchmarks
    update      Update dependencies listed in Cargo.lock

See 'cargo help <command>' for more information on a specific command.
";

fn main() {
    execute_main_without_stdin(execute, true, USAGE)
}

macro_rules! each_subcommand( ($macro:ident) => ({
    $macro!(bench)
    $macro!(build)
    $macro!(clean)
    $macro!(config_for_key)
    $macro!(config_list)
    $macro!(doc)
    $macro!(fetch)
    $macro!(generate_lockfile)
    $macro!(git_checkout)
    $macro!(help)
    $macro!(locate_project)
    $macro!(login)
    $macro!(new)
    $macro!(owner)
    $macro!(package)
    $macro!(pkgid)
    $macro!(publish)
    $macro!(read_manifest)
    $macro!(run)
    $macro!(test)
    $macro!(update)
    $macro!(verify_project)
    $macro!(version)
    $macro!(yank)
}) )

/**
  The top-level `cargo` command handles configuration and project location
  because they are fundamental (and intertwined). Other commands can rely
  on this top-level information.
*/
fn execute(flags: Flags, shell: &mut MultiShell) -> CliResult<Option<()>> {
    debug!("executing; cmd=cargo; args={}", os::args());
    shell.set_verbose(flags.flag_verbose);

    if flags.flag_list {
        println!("Installed Commands:");
        for command in list_commands().into_iter() {
            println!("    {}", command);
        };
        return Ok(None)
    }

    let (mut args, command) = match flags.arg_command.as_slice() {
        "" | "help" if flags.arg_args.len() == 0 => {
            shell.set_verbose(true);
            let r = cargo::call_main_without_stdin(execute, shell, USAGE,
                                                   ["-h".to_string()], false);
            cargo::process_executed(r, shell);
            return Ok(None)
        }
        "help" => (vec!["-h".to_string()], flags.arg_args[0].as_slice()),
        s => (flags.arg_args.clone(), s),
    };
    args.insert(0, command.to_string());

    macro_rules! cmd( ($name:ident) => (
        if command.as_slice() == stringify!($name).replace("_", "-").as_slice() {
            mod $name;
            shell.set_verbose(true);
            let r = cargo::call_main_without_stdin($name::execute, shell,
                                                   $name::USAGE,
                                                   args.as_slice(),
                                                   false);
            cargo::process_executed(r, shell);
            return Ok(None)
        }
    ) )
    each_subcommand!(cmd)

    execute_subcommand(command.as_slice(), args.as_slice(), shell);
    Ok(None)
}

fn execute_subcommand(cmd: &str, args: &[String], shell: &mut MultiShell) {
    let command = match find_command(cmd) {
        Some(command) => command,
        None => return handle_error(CliError::new("No such subcommand", 127),
                                    shell)
    };
    let status = Command::new(command)
                         .args(args)
                         .stdin(InheritFd(0))
                         .stdout(InheritFd(1))
                         .stderr(InheritFd(2))
                         .status();

    match status {
        Ok(ExitStatus(0)) => (),
        Ok(ExitStatus(i)) => {
            handle_error(CliError::new("", i as uint), shell)
        }
        Ok(ExitSignal(i)) => {
            let msg = format!("subcommand failed with signal: {}", i);
            handle_error(CliError::new(msg, i as uint), shell)
        }
        Err(io::IoError{kind, ..}) if kind == io::FileNotFound =>
            handle_error(CliError::new("No such subcommand", 127), shell),
        Err(err) => handle_error(
            CliError::new(
                format!("Subcommand failed to run: {}", err), 127),
            shell)
    }
}

/// List all runnable commands. find_command should always succeed
/// if given one of returned command.
fn list_commands() -> TreeSet<String> {
    let command_prefix = "cargo-";
    let mut commands = TreeSet::new();
    for dir in list_command_directory().iter() {
        let entries = match fs::readdir(dir) {
            Ok(entries) => entries,
            _ => continue
        };
        for entry in entries.iter() {
            let filename = match entry.filename_str() {
                Some(filename) => filename,
                _ => continue
            };
            if filename.starts_with(command_prefix) &&
                    filename.ends_with(os::consts::EXE_SUFFIX) &&
                    is_executable(entry) {
                let command = filename.slice(
                    command_prefix.len(),
                    filename.len() - os::consts::EXE_SUFFIX.len());
                commands.insert(String::from_str(command));
            }
        }
    }

    macro_rules! add_cmd( ($cmd:ident) => ({
        commands.insert(stringify!($cmd).replace("_", "-"));
    }) )
    each_subcommand!(add_cmd);
    commands
}

fn is_executable(path: &Path) -> bool {
    match fs::stat(path) {
        Ok(io::FileStat{ kind: io::TypeFile, perm, ..}) =>
            perm.contains(io::OTHER_EXECUTE),
        _ => false
    }
}

/// Get `Command` to run given command.
fn find_command(cmd: &str) -> Option<Path> {
    let command_exe = format!("cargo-{}{}", cmd, os::consts::EXE_SUFFIX);
    let dirs = list_command_directory();
    let mut command_paths = dirs.iter().map(|dir| dir.join(command_exe.as_slice()));
    command_paths.find(|path| path.exists())
}

/// List candidate locations where subcommands might be installed.
fn list_command_directory() -> Vec<Path> {
    let mut dirs = vec![];
    match os::self_exe_path() {
        Some(path) => {
            dirs.push(path.join("../lib/cargo"));
            dirs.push(path);
        },
        None => {}
    };
    match std::os::getenv("PATH") {
        Some(val) => {
            for dir in os::split_paths(val).iter() {
                dirs.push(Path::new(dir))
            }
        },
        None => {}
    };
    dirs
}
<commit_msg>Make help command accept -h and --help<commit_after>#![feature(phase, macro_rules)]
#![deny(unused)]

extern crate serialize;
#[phase(plugin, link)] extern crate log;

extern crate cargo;

use std::collections::TreeSet;
use std::os;
use std::io;
use std::io::fs::{mod, PathExtensions};
use std::io::process::{Command,InheritFd,ExitStatus,ExitSignal};

use cargo::{execute_main_without_stdin, handle_error, shell};
use cargo::core::MultiShell;
use cargo::util::{CliError, CliResult};

#[deriving(Decodable)]
struct Flags {
    flag_list: bool,
    flag_verbose: bool,
    arg_command: String,
    arg_args: Vec<String>,
}

const USAGE: &'static str = "
Rust's package manager

Usage:
    cargo <command> [<args>...]
    cargo [options]

Options:
    -h, --help       Display this message
    -V, --version    Print version info and exit
    --list           List installed commands
    -v, --verbose    Use verbose output

Some common cargo commands are:
    build       Compile the current project
    clean       Remove the target directory
    doc         Build this project's and its dependencies' documentation
    new         Create a new cargo project
    run         Build and execute src/main.rs
    test        Run the tests
    bench       Run the benchmarks
    update      Update dependencies listed in Cargo.lock

See 'cargo help <command>' for more information on a specific command.
";

fn main() {
    execute_main_without_stdin(execute, true, USAGE)
}

macro_rules! each_subcommand( ($macro:ident) => ({
    $macro!(bench)
    $macro!(build)
    $macro!(clean)
    $macro!(config_for_key)
    $macro!(config_list)
    $macro!(doc)
    $macro!(fetch)
    $macro!(generate_lockfile)
    $macro!(git_checkout)
    $macro!(help)
    $macro!(locate_project)
    $macro!(login)
    $macro!(new)
    $macro!(owner)
    $macro!(package)
    $macro!(pkgid)
    $macro!(publish)
    $macro!(read_manifest)
    $macro!(run)
    $macro!(test)
    $macro!(update)
    $macro!(verify_project)
    $macro!(version)
    $macro!(yank)
}) )

/**
  The top-level `cargo` command handles configuration and project location
  because they are fundamental (and intertwined). Other commands can rely
  on this top-level information.
*/
fn execute(flags: Flags, shell: &mut MultiShell) -> CliResult<Option<()>> {
    debug!("executing; cmd=cargo; args={}", os::args());
    shell.set_verbose(flags.flag_verbose);

    if flags.flag_list {
        println!("Installed Commands:");
        for command in list_commands().into_iter() {
            println!("    {}", command);
        };
        return Ok(None)
    }

    let (mut args, command) = match flags.arg_command.as_slice() {
        "" | "help" if flags.arg_args.len() == 0 => {
            shell.set_verbose(true);
            let r = cargo::call_main_without_stdin(execute, shell, USAGE,
                                                   ["-h".to_string()], false);
            cargo::process_executed(r, shell);
            return Ok(None)
        }
        "help" if flags.arg_args[0].as_slice() == "-h" ||
                  flags.arg_args[0].as_slice() == "--help" =>
            (flags.arg_args, "help"),
        "help" => (vec!["-h".to_string()], flags.arg_args[0].as_slice()),
        s => (flags.arg_args.clone(), s),
    };
    args.insert(0, command.to_string());

    macro_rules! cmd( ($name:ident) => (
        if command.as_slice() == stringify!($name).replace("_", "-").as_slice() {
            mod $name;
            shell.set_verbose(true);
            let r = cargo::call_main_without_stdin($name::execute, shell,
                                                   $name::USAGE,
                                                   args.as_slice(),
                                                   false);
            cargo::process_executed(r, shell);
            return Ok(None)
        }
    ) )
    each_subcommand!(cmd)

    execute_subcommand(command.as_slice(), args.as_slice(), shell);
    Ok(None)
}

fn execute_subcommand(cmd: &str, args: &[String], shell: &mut MultiShell) {
    let command = match find_command(cmd) {
        Some(command) => command,
        None => return handle_error(CliError::new("No such subcommand", 127),
                                    shell)
    };
    let status = Command::new(command)
                         .args(args)
                         .stdin(InheritFd(0))
                         .stdout(InheritFd(1))
                         .stderr(InheritFd(2))
                         .status();

    match status {
        Ok(ExitStatus(0)) => (),
        Ok(ExitStatus(i)) => {
            handle_error(CliError::new("", i as uint), shell)
        }
        Ok(ExitSignal(i)) => {
            let msg = format!("subcommand failed with signal: {}", i);
            handle_error(CliError::new(msg, i as uint), shell)
        }
        Err(io::IoError{kind, ..}) if kind == io::FileNotFound =>
            handle_error(CliError::new("No such subcommand", 127), shell),
        Err(err) => handle_error(
            CliError::new(
                format!("Subcommand failed to run: {}", err), 127),
            shell)
    }
}

/// List all runnable commands. find_command should always succeed
/// if given one of returned command.
fn list_commands() -> TreeSet<String> {
    let command_prefix = "cargo-";
    let mut commands = TreeSet::new();
    for dir in list_command_directory().iter() {
        let entries = match fs::readdir(dir) {
            Ok(entries) => entries,
            _ => continue
        };
        for entry in entries.iter() {
            let filename = match entry.filename_str() {
                Some(filename) => filename,
                _ => continue
            };
            if filename.starts_with(command_prefix) &&
                    filename.ends_with(os::consts::EXE_SUFFIX) &&
                    is_executable(entry) {
                let command = filename.slice(
                    command_prefix.len(),
                    filename.len() - os::consts::EXE_SUFFIX.len());
                commands.insert(String::from_str(command));
            }
        }
    }

    macro_rules! add_cmd( ($cmd:ident) => ({
        commands.insert(stringify!($cmd).replace("_", "-"));
    }) )
    each_subcommand!(add_cmd);
    commands
}

fn is_executable(path: &Path) -> bool {
    match fs::stat(path) {
        Ok(io::FileStat{ kind: io::TypeFile, perm, ..}) =>
            perm.contains(io::OTHER_EXECUTE),
        _ => false
    }
}

/// Get `Command` to run given command.
fn find_command(cmd: &str) -> Option<Path> {
    let command_exe = format!("cargo-{}{}", cmd, os::consts::EXE_SUFFIX);
    let dirs = list_command_directory();
    let mut command_paths = dirs.iter().map(|dir| dir.join(command_exe.as_slice()));
    command_paths.find(|path| path.exists())
}

/// List candidate locations where subcommands might be installed.
fn list_command_directory() -> Vec<Path> {
    let mut dirs = vec![];
    match os::self_exe_path() {
        Some(path) => {
            dirs.push(path.join("../lib/cargo"));
            dirs.push(path);
        },
        None => {}
    };
    match std::os::getenv("PATH") {
        Some(val) => {
            for dir in os::split_paths(val).iter() {
                dirs.push(Path::new(dir))
            }
        },
        None => {}
    };
    dirs
}
<|endoftext|>


<commit_before>#![allow(unused_variables)]

mod safe {
    use std::slice::from_raw_parts_mut;

    pub fn as_mut_slice<T>(self_: &Vec<T>) -> &mut [T] {
        unsafe {
            from_raw_parts_mut(self_.as_ptr() as *mut T, self_.len()) //~ ERROR shared borrow for mutation
        }
    }
}

fn main() {
    let v = vec![0,1,2];
    let v1 = safe::as_mut_slice(&v);
    let v2 = safe::as_mut_slice(&v);
}
<commit_msg>fix for ptr-to-raw casts properly erasing the tag<commit_after>#![allow(unused_variables)]

mod safe {
    use std::slice::from_raw_parts_mut;

    pub fn as_mut_slice<T>(self_: &Vec<T>) -> &mut [T] {
        unsafe {
            from_raw_parts_mut(self_.as_ptr() as *mut T, self_.len())
        }
    }
}

fn main() {
    let v = vec![0,1,2];
    let v1 = safe::as_mut_slice(&v);
    let v2 = safe::as_mut_slice(&v);
    v1[1] = 5; //~ ERROR does not exist on the stack
    v1[1] = 6;
}
<|endoftext|>


<commit_before>
use clap;
use git2::Repository;
use git2::BranchType;
use gerritlib::error::GGRError;
use gerritlib::error::GGRResult;

/// manage subfunction of `topic` command
///
/// Currently implemented sub commands:
///
/// * create
/// * forget
pub fn manage(x: &clap::ArgMatches) -> GGRResult<()> {
    match x.subcommand() {
        ("create", Some(y)) => { create(y) },
        ("forget", Some(y)) => { forget(y) },
        _ => {
            println!("{}", x.usage());
            Ok(())
        },
    }
}

fn create(y: &clap::ArgMatches) -> GGRResult<()> {
    let branchname = y.value_of("branchname").unwrap();

    let repository_names = y.values_of("repo").unwrap();
    let mut repo;
    if repository_names.count() > 0 {
        println!("Create topic branch \"{}\" at repository:", branchname);
        for (_, subrep) in y.values_of("repo").unwrap().enumerate() {
            let (repo_name, reference_name) = split_repo_reference(subrep);

            print!("* {}: ", &repo_name);
            repo = try!(Repository::open(&repo_name));
            match repo.revparse_single(&reference_name) {
                Ok(object) => {
                    let commit = match object.as_commit() {
                        Some(c) => c,
                        None => { println!("fail (not exists)"); continue},
                    };

                    match repo.branch(branchname, commit, false) {
                        Ok(_) => { println!("done") },
                        Err(e) => { println!("fail ({})", e.message()); },
                    };
                },
                Err(e) => {
                    println!("fail ({})", e.message())
                },
            }
        }
    }

    Ok(())
}

fn forget(y: &clap::ArgMatches) -> GGRResult<()> {
    let branchname = y.value_of("branchname").unwrap();

    let repo = try!(Repository::discover("."));

    /* remove branch on the current repository */
    match repo.find_branch(branchname, BranchType::Local) {
        Ok(mut branch) => {
            print!("* current folder: ");
            if branch.delete().is_err() {
                println!("fail");
            } else {
                println!("done");
            }
        },
        Err(err) => {
            return Err(GGRError::from(err));
        }
    };

    /* remove branch on all submodules */
    if y.is_present("recursive") {
        let submodules = try!(repo.submodules());
        for sm in &submodules {
            let reposub = try!(sm.open());
            match reposub.find_branch(branchname, BranchType::Local) {
                Ok(mut branch) => {
                    print!("* {}: ", sm.path().display());
                    if branch.delete().is_err() {
                        println!("fail");
                    } else {
                        println!("done");
                    }
                },
                Err(err) => {
                    return Err(GGRError::from(err));
                }
            };
        }
    }
    Ok(())
}

/// splits a string to repository and reference
///
/// 't' can have this possible cases and output:
///
/// * 'a':      (repo=a, reference=HEAD)
/// * 'a:b'     (repo=a, reference=b)
/// * 'a:b:c'   (repo=a, reference=b)
fn split_repo_reference(t: &str) -> (String, String) {
    let repo;
    let reference;

    let mut splited = t.split('.');

    if splited.clone().count() >= 2 {
        // unwrap are save in this context
        repo = String::from(splited.next().unwrap());
        reference = String::from(splited.next().unwrap());
    } else {
        reference = String::from("HEAD");
        repo = t.to_owned().to_string();
    }

    (repo, reference)
}

<commit_msg>topic: proper error handling (remove unwrap)<commit_after>
use clap;
use git2::Repository;
use git2::BranchType;
use gerritlib::error::GGRError;
use gerritlib::error::GGRResult;

/// manage subfunction of `topic` command
///
/// Currently implemented sub commands:
///
/// * create
/// * forget
pub fn manage(x: &clap::ArgMatches) -> GGRResult<()> {
    match x.subcommand() {
        ("create", Some(y)) => { create(y) },
        ("forget", Some(y)) => { forget(y) },
        _ => {
            println!("{}", x.usage());
            Ok(())
        },
    }
}

fn create(y: &clap::ArgMatches) -> GGRResult<()> {
    let branchname = match y.value_of("branchname") {
        Some(x) => x,
        None => return Err(GGRError::General("Bad branchname".into())),
    };

    let repository_names = match y.values_of_lossy("repo") {
        Some(x) => x,
        None => return Err(GGRError::General("Bad Reponame".into())),
    };

    let mut repo;
    if repository_names.len() > 0 {
        println!("Create topic branch \"{}\" at repository:", branchname);
        for subrep in repository_names {
            let (repo_name, reference_name) = split_repo_reference(&subrep);

            print!("* {}: ", &repo_name);
            repo = try!(Repository::open(&repo_name));
            match repo.revparse_single(&reference_name) {
                Ok(object) => {
                    let commit = match object.as_commit() {
                        Some(c) => c,
                        None => { println!("fail (not exists)"); continue},
                    };

                    match repo.branch(branchname, commit, false) {
                        Ok(_) => { println!("done") },
                        Err(e) => { println!("fail ({})", e.message()); },
                    };
                },
                Err(e) => {
                    println!("fail ({})", e.message())
                },
            }
        }
    }

    Ok(())
}

fn forget(y: &clap::ArgMatches) -> GGRResult<()> {
    let branchname = match y.value_of("branchname") {
        Some(x) => x,
        None => return Err(GGRError::General("Bad branchname".into())),
    };

    let repo = try!(Repository::discover("."));

    /* remove branch on the current repository */
    match repo.find_branch(branchname, BranchType::Local) {
        Ok(mut branch) => {
            print!("* current folder: ");
            if branch.delete().is_err() {
                println!("fail");
            } else {
                println!("done");
            }
        },
        Err(err) => {
            return Err(GGRError::from(err));
        }
    };

    /* remove branch on all submodules */
    if y.is_present("recursive") {
        let submodules = try!(repo.submodules());
        for sm in &submodules {
            let reposub = try!(sm.open());
            match reposub.find_branch(branchname, BranchType::Local) {
                Ok(mut branch) => {
                    print!("* {}: ", sm.path().display());
                    if branch.delete().is_err() {
                        println!("fail");
                    } else {
                        println!("done");
                    }
                },
                Err(err) => {
                    return Err(GGRError::from(err));
                }
            };
        }
    }
    Ok(())
}

/// splits a string to repository and reference
///
/// 't' can have this possible cases and output:
///
/// * 'a':      (repo=a, reference=HEAD)
/// * 'a:b'     (repo=a, reference=b)
/// * 'a:b:c'   (repo=a, reference=b)
fn split_repo_reference(t: &str) -> (String, String) {
    let repo;
    let reference;

    let mut splited = t.split('.');

    if splited.clone().count() >= 2 {
        // unwrap are save in this context
        repo = String::from(splited.next().unwrap());
        reference = String::from(splited.next().unwrap());
    } else {
        reference = String::from("HEAD");
        repo = t.to_owned().to_string();
    }

    (repo, reference)
}

<|endoftext|>


<commit_before>//! Management of the directory layout of a build
//!
//! The directory layout is a little tricky at times, hence a separate file to
//! house this logic. The current layout looks like this:
//!
//! ```ignore
//! # This is the root directory for all output, the top-level package
//! # places all of its output here.
//! target/
//!
//!     # This is the root directory for all output of *dependencies*
//!     deps/
//!
//!     # Root directory for all compiled examples
//!     examples/
//!
//!     # This is the location at which the output of all custom build
//!     # commands are rooted
//!     build/
//!
//!         # Each package gets its own directory where its build script and
//!         # script output are placed
//!         $pkg1/
//!         $pkg2/
//!         $pkg3/
//!
//!             # Each directory package has a `out` directory where output
//!             # is placed.
//!             out/
//!
//!     # This is the location at which the output of all old custom build
//!     # commands are rooted
//!     native/
//!
//!         # Each package gets its own directory for where its output is
//!         # placed. We can't track exactly what's getting put in here, so
//!         # we just assume that all relevant output is in these
//!         # directories.
//!         $pkg1/
//!         $pkg2/
//!         $pkg3/
//!
//!     # Directory used to store incremental data for the compiler (when
//!     # incremental is enabled.
//!     incremental/
//!
//!     # Hidden directory that holds all of the fingerprint files for all
//!     # packages
//!     .fingerprint/
//! ```

use std::fs;
use std::io;
use std::path::{Path, PathBuf};

use core::Workspace;
use util::{CargoResult, Config, FileLock, Filesystem};

/// Contains the paths of all target output locations.
///
/// See module docs for more information.
pub struct Layout {
    root: PathBuf,
    deps: PathBuf,
    native: PathBuf,
    build: PathBuf,
    incremental: PathBuf,
    fingerprint: PathBuf,
    examples: PathBuf,
    /// The lockfile for a build, will be unlocked when this struct is `drop`ped.
    _lock: FileLock,
}

pub fn is_bad_artifact_name(name: &str) -> bool {
    ["deps", "examples", "build", "native", "incremental"]
        .iter()
        .any(|&reserved| reserved == name)
}

impl Layout {
    /// Calculate the paths for build output, lock the build directory, and return as a Layout.
    ///
    /// This function will block if the directory is already locked.
    ///
    /// Differs from `at` in that this calculates the root path from the workspace target directory,
    /// adding the target triple and the profile (debug, release, ...).
    pub fn new(ws: &Workspace, triple: Option<&str>, dest: &str) -> CargoResult<Layout> {
        let mut path = ws.target_dir();
        // Flexible target specifications often point at filenames, so interpret
        // the target triple as a Path and then just use the file stem as the
        // component for the directory name.
        if let Some(triple) = triple {
            path.push(Path::new(triple)
                .file_stem()
                .ok_or_else(|| format_err!("invalid target"))?);
        }
        path.push(dest);
        Layout::at(ws.config(), path)
    }

    /// Calculate the paths for build output, lock the build directory, and return as a Layout.
    ///
    /// This function will block if the directory is already locked.
    pub fn at(config: &Config, root: Filesystem) -> CargoResult<Layout> {
        // For now we don't do any more finer-grained locking on the artifact
        // directory, so just lock the entire thing for the duration of this
        // compile.
        let lock = root.open_rw(".cargo-lock", config, "build directory")?;
        let root = root.into_path_unlocked();

        Ok(Layout {
            deps: root.join("deps"),
            native: root.join("native"),
            build: root.join("build"),
            incremental: root.join("incremental"),
            fingerprint: root.join(".fingerprint"),
            examples: root.join("examples"),
            root,
            _lock: lock,
        })
    }

    #[cfg(not(target_os = "macos"))]
    fn exclude_from_backups(&self, _: &Path) {}

    #[cfg(target_os = "macos")]
    /// Marks files or directories as excluded from Time Machine on macOS
    ///
    /// This is recommended to prevent derived/temporary files from bloating backups.
    fn exclude_from_backups(&self, path: &Path) {
        use std::ptr;
        use core_foundation::{number, string, url};
        use core_foundation::base::TCFType;

        // For compatibility with 10.7 a string is used instead of global kCFURLIsExcludedFromBackupKey
        let is_excluded_key: Result<string::CFString, _> = "NSURLIsExcludedFromBackupKey".parse();
        let path = url::CFURL::from_path(path, false);
        if let (Some(path), Ok(is_excluded_key)) = (path, is_excluded_key) {
            unsafe {
                url::CFURLSetResourcePropertyForKey(
                    path.as_concrete_TypeRef(),
                    is_excluded_key.as_concrete_TypeRef(),
                    number::kCFBooleanTrue as *const _,
                    ptr::null_mut(),
                );
            }
        }
        // Errors are ignored, since it's an optional feature and failure
        // doesn't prevent Cargo from working
    }

    /// Make sure all directories stored in the Layout exist on the filesystem.
    pub fn prepare(&mut self) -> io::Result<()> {
        if fs::metadata(&self.root).is_err() {
            fs::create_dir_all(&self.root)?;
        }

        self.exclude_from_backups(&self.root);

        mkdir(&self.deps)?;
        mkdir(&self.native)?;
        mkdir(&self.incremental)?;
        mkdir(&self.fingerprint)?;
        mkdir(&self.examples)?;
        mkdir(&self.build)?;

        return Ok(());

        fn mkdir(dir: &Path) -> io::Result<()> {
            if fs::metadata(&dir).is_err() {
                fs::create_dir(dir)?;
            }
            Ok(())
        }
    }

    /// Fetch the root path.
    pub fn dest(&self) -> &Path {
        &self.root
    }
    /// Fetch the deps path.
    pub fn deps(&self) -> &Path {
        &self.deps
    }
    /// Fetch the examples path.
    pub fn examples(&self) -> &Path {
        &self.examples
    }
    /// Fetch the root path.
    pub fn root(&self) -> &Path {
        &self.root
    }
    /// Fetch the incremental path.
    pub fn incremental(&self) -> &Path {
        &self.incremental
    }
    /// Fetch the fingerprint path.
    pub fn fingerprint(&self) -> &Path {
        &self.fingerprint
    }
    /// Fetch the build path.
    pub fn build(&self) -> &Path {
        &self.build
    }
}
<commit_msg>Tweak Layout to allow for non json file targets with internal "."<commit_after>//! Management of the directory layout of a build
//!
//! The directory layout is a little tricky at times, hence a separate file to
//! house this logic. The current layout looks like this:
//!
//! ```ignore
//! # This is the root directory for all output, the top-level package
//! # places all of its output here.
//! target/
//!
//!     # This is the root directory for all output of *dependencies*
//!     deps/
//!
//!     # Root directory for all compiled examples
//!     examples/
//!
//!     # This is the location at which the output of all custom build
//!     # commands are rooted
//!     build/
//!
//!         # Each package gets its own directory where its build script and
//!         # script output are placed
//!         $pkg1/
//!         $pkg2/
//!         $pkg3/
//!
//!             # Each directory package has a `out` directory where output
//!             # is placed.
//!             out/
//!
//!     # This is the location at which the output of all old custom build
//!     # commands are rooted
//!     native/
//!
//!         # Each package gets its own directory for where its output is
//!         # placed. We can't track exactly what's getting put in here, so
//!         # we just assume that all relevant output is in these
//!         # directories.
//!         $pkg1/
//!         $pkg2/
//!         $pkg3/
//!
//!     # Directory used to store incremental data for the compiler (when
//!     # incremental is enabled.
//!     incremental/
//!
//!     # Hidden directory that holds all of the fingerprint files for all
//!     # packages
//!     .fingerprint/
//! ```

use std::fs;
use std::io;
use std::path::{Path, PathBuf};

use core::Workspace;
use util::{CargoResult, Config, FileLock, Filesystem};

/// Contains the paths of all target output locations.
///
/// See module docs for more information.
pub struct Layout {
    root: PathBuf,
    deps: PathBuf,
    native: PathBuf,
    build: PathBuf,
    incremental: PathBuf,
    fingerprint: PathBuf,
    examples: PathBuf,
    /// The lockfile for a build, will be unlocked when this struct is `drop`ped.
    _lock: FileLock,
}

pub fn is_bad_artifact_name(name: &str) -> bool {
    ["deps", "examples", "build", "native", "incremental"]
        .iter()
        .any(|&reserved| reserved == name)
}

impl Layout {
    /// Calculate the paths for build output, lock the build directory, and return as a Layout.
    ///
    /// This function will block if the directory is already locked.
    ///
    /// Differs from `at` in that this calculates the root path from the workspace target directory,
    /// adding the target triple and the profile (debug, release, ...).
    pub fn new(ws: &Workspace, triple: Option<&str>, dest: &str) -> CargoResult<Layout> {
        let mut path = ws.target_dir();
        // Flexible target specifications often point at json files, so interpret
        // the target triple as a Path and then just use the file stem as the
        // component for the directory name in that case.
        if let Some(triple) = triple {
            let triple = Path::new(triple);
            if triple.extension().and_then(|s| s.to_str()) == Some("json") {
                path.push(
                    triple
                        .file_stem()
                        .ok_or_else(|| format_err!("invalid target"))?,
                );
            } else {
                path.push(triple);
            }
        }
        path.push(dest);
        Layout::at(ws.config(), path)
    }

    /// Calculate the paths for build output, lock the build directory, and return as a Layout.
    ///
    /// This function will block if the directory is already locked.
    pub fn at(config: &Config, root: Filesystem) -> CargoResult<Layout> {
        // For now we don't do any more finer-grained locking on the artifact
        // directory, so just lock the entire thing for the duration of this
        // compile.
        let lock = root.open_rw(".cargo-lock", config, "build directory")?;
        let root = root.into_path_unlocked();

        Ok(Layout {
            deps: root.join("deps"),
            native: root.join("native"),
            build: root.join("build"),
            incremental: root.join("incremental"),
            fingerprint: root.join(".fingerprint"),
            examples: root.join("examples"),
            root,
            _lock: lock,
        })
    }

    #[cfg(not(target_os = "macos"))]
    fn exclude_from_backups(&self, _: &Path) {}

    #[cfg(target_os = "macos")]
    /// Marks files or directories as excluded from Time Machine on macOS
    ///
    /// This is recommended to prevent derived/temporary files from bloating backups.
    fn exclude_from_backups(&self, path: &Path) {
        use std::ptr;
        use core_foundation::{number, string, url};
        use core_foundation::base::TCFType;

        // For compatibility with 10.7 a string is used instead of global kCFURLIsExcludedFromBackupKey
        let is_excluded_key: Result<string::CFString, _> = "NSURLIsExcludedFromBackupKey".parse();
        let path = url::CFURL::from_path(path, false);
        if let (Some(path), Ok(is_excluded_key)) = (path, is_excluded_key) {
            unsafe {
                url::CFURLSetResourcePropertyForKey(
                    path.as_concrete_TypeRef(),
                    is_excluded_key.as_concrete_TypeRef(),
                    number::kCFBooleanTrue as *const _,
                    ptr::null_mut(),
                );
            }
        }
        // Errors are ignored, since it's an optional feature and failure
        // doesn't prevent Cargo from working
    }

    /// Make sure all directories stored in the Layout exist on the filesystem.
    pub fn prepare(&mut self) -> io::Result<()> {
        if fs::metadata(&self.root).is_err() {
            fs::create_dir_all(&self.root)?;
        }

        self.exclude_from_backups(&self.root);

        mkdir(&self.deps)?;
        mkdir(&self.native)?;
        mkdir(&self.incremental)?;
        mkdir(&self.fingerprint)?;
        mkdir(&self.examples)?;
        mkdir(&self.build)?;

        return Ok(());

        fn mkdir(dir: &Path) -> io::Result<()> {
            if fs::metadata(&dir).is_err() {
                fs::create_dir(dir)?;
            }
            Ok(())
        }
    }

    /// Fetch the root path.
    pub fn dest(&self) -> &Path {
        &self.root
    }
    /// Fetch the deps path.
    pub fn deps(&self) -> &Path {
        &self.deps
    }
    /// Fetch the examples path.
    pub fn examples(&self) -> &Path {
        &self.examples
    }
    /// Fetch the root path.
    pub fn root(&self) -> &Path {
        &self.root
    }
    /// Fetch the incremental path.
    pub fn incremental(&self) -> &Path {
        &self.incremental
    }
    /// Fetch the fingerprint path.
    pub fn fingerprint(&self) -> &Path {
        &self.fingerprint
    }
    /// Fetch the build path.
    pub fn build(&self) -> &Path {
        &self.build
    }
}
<|endoftext|>


<commit_before>use std::fmt;
use std::fmt::{Show, Formatter};
use std::os;
use std::c_str::CString;
use std::io::process::{Command, ProcessOutput, InheritFd};
use std::collections::HashMap;

use util::{ProcessError, process_error};

#[deriving(Clone,PartialEq)]
pub struct ProcessBuilder {
    program: CString,
    args: Vec<CString>,
    env: HashMap<String, Option<CString>>,
    cwd: Path,
}

impl Show for ProcessBuilder {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        try!(write!(f, "`{}", String::from_utf8_lossy(self.program.as_bytes_no_nul())));

        for arg in self.args.iter() {
            try!(write!(f, " {}", String::from_utf8_lossy(arg.as_bytes_no_nul())));
        }

        write!(f, "`")
    }
}

impl ProcessBuilder {
    pub fn arg<T: ToCStr>(mut self, arg: T) -> ProcessBuilder {
        self.args.push(arg.to_c_str());
        self
    }

    pub fn args<T: ToCStr>(mut self, arguments: &[T]) -> ProcessBuilder {
        self.args.extend(arguments.iter().map(|t| t.to_c_str()));
        self
    }

    pub fn get_args(&self) -> &[CString] {
        self.args.as_slice()
    }

    pub fn cwd(mut self, path: Path) -> ProcessBuilder {
        self.cwd = path;
        self
    }

    pub fn env<T: ToCStr>(mut self, key: &str, val: Option<T>) -> ProcessBuilder {
        self.env.insert(key.to_string(), val.map(|t| t.to_c_str()));
        self
    }

    // TODO: should InheritFd be hardcoded?
    pub fn exec(&self) -> Result<(), ProcessError> {
        let mut command = self.build_command();
        command.stdout(InheritFd(1))
               .stderr(InheritFd(2));

        let msg = || format!("Could not execute process `{}`",
                             self.debug_string());

        let exit = try!(command.status().map_err(|e|
            process_error(msg(), Some(e), None, None)));

        if exit.success() {
            Ok(())
        } else {
            Err(process_error(msg(), None, Some(&exit), None))
        }
    }

    pub fn exec_with_output(&self) -> Result<ProcessOutput, ProcessError> {
        let command = self.build_command();

        let msg = || format!("Could not execute process `{}`",
                             self.debug_string());

        let output = try!(command.output().map_err(|e| {
            process_error(msg(), Some(e), None, None)
        }));

        if output.status.success() {
            Ok(output)
        } else {
            Err(process_error(msg(), None, Some(&output.status),
                              Some(&output)))
        }
    }

    pub fn build_command(&self) -> Command {
        let mut command = Command::new(self.program.as_bytes_no_nul());
        command.cwd(&self.cwd);
        for arg in self.args.iter() {
            command.arg(arg.as_bytes_no_nul());
        }
        for (k, v) in self.env.iter() {
            let k = k.as_slice();
            match *v {
                Some(ref v) => { command.env(k, v.as_bytes_no_nul()); }
                None => { command.env_remove(k); }
            }
        }
        command
    }

    fn debug_string(&self) -> String {
        let program = String::from_utf8_lossy(self.program.as_bytes_no_nul());
        let mut program = program.into_string();
        for arg in self.args.iter() {
            program.push_char(' ');
            let s = String::from_utf8_lossy(arg.as_bytes_no_nul());
            program.push_str(s.as_slice());
        }
        program
    }
}

pub fn process<T: ToCStr>(cmd: T) -> ProcessBuilder {
    ProcessBuilder {
        program: cmd.to_c_str(),
        args: Vec::new(),
        cwd: os::getcwd(),
        env: HashMap::new(),
    }
}
<commit_msg>Inherit stdin when using `cargo run`<commit_after>use std::fmt;
use std::fmt::{Show, Formatter};
use std::os;
use std::c_str::CString;
use std::io::process::{Command, ProcessOutput, InheritFd};
use std::collections::HashMap;

use util::{ProcessError, process_error};

#[deriving(Clone,PartialEq)]
pub struct ProcessBuilder {
    program: CString,
    args: Vec<CString>,
    env: HashMap<String, Option<CString>>,
    cwd: Path,
}

impl Show for ProcessBuilder {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        try!(write!(f, "`{}", String::from_utf8_lossy(self.program.as_bytes_no_nul())));

        for arg in self.args.iter() {
            try!(write!(f, " {}", String::from_utf8_lossy(arg.as_bytes_no_nul())));
        }

        write!(f, "`")
    }
}

impl ProcessBuilder {
    pub fn arg<T: ToCStr>(mut self, arg: T) -> ProcessBuilder {
        self.args.push(arg.to_c_str());
        self
    }

    pub fn args<T: ToCStr>(mut self, arguments: &[T]) -> ProcessBuilder {
        self.args.extend(arguments.iter().map(|t| t.to_c_str()));
        self
    }

    pub fn get_args(&self) -> &[CString] {
        self.args.as_slice()
    }

    pub fn cwd(mut self, path: Path) -> ProcessBuilder {
        self.cwd = path;
        self
    }

    pub fn env<T: ToCStr>(mut self, key: &str, val: Option<T>) -> ProcessBuilder {
        self.env.insert(key.to_string(), val.map(|t| t.to_c_str()));
        self
    }

    // TODO: should InheritFd be hardcoded?
    pub fn exec(&self) -> Result<(), ProcessError> {
        let mut command = self.build_command();
        command.stdout(InheritFd(1))
               .stderr(InheritFd(2))
               .stdin(InheritFd(0));

        let msg = || format!("Could not execute process `{}`",
                             self.debug_string());

        let exit = try!(command.status().map_err(|e|
            process_error(msg(), Some(e), None, None)));

        if exit.success() {
            Ok(())
        } else {
            Err(process_error(msg(), None, Some(&exit), None))
        }
    }

    pub fn exec_with_output(&self) -> Result<ProcessOutput, ProcessError> {
        let command = self.build_command();

        let msg = || format!("Could not execute process `{}`",
                             self.debug_string());

        let output = try!(command.output().map_err(|e| {
            process_error(msg(), Some(e), None, None)
        }));

        if output.status.success() {
            Ok(output)
        } else {
            Err(process_error(msg(), None, Some(&output.status),
                              Some(&output)))
        }
    }

    pub fn build_command(&self) -> Command {
        let mut command = Command::new(self.program.as_bytes_no_nul());
        command.cwd(&self.cwd);
        for arg in self.args.iter() {
            command.arg(arg.as_bytes_no_nul());
        }
        for (k, v) in self.env.iter() {
            let k = k.as_slice();
            match *v {
                Some(ref v) => { command.env(k, v.as_bytes_no_nul()); }
                None => { command.env_remove(k); }
            }
        }
        command
    }

    fn debug_string(&self) -> String {
        let program = String::from_utf8_lossy(self.program.as_bytes_no_nul());
        let mut program = program.into_string();
        for arg in self.args.iter() {
            program.push_char(' ');
            let s = String::from_utf8_lossy(arg.as_bytes_no_nul());
            program.push_str(s.as_slice());
        }
        program
    }
}

pub fn process<T: ToCStr>(cmd: T) -> ProcessBuilder {
    ProcessBuilder {
        program: cmd.to_c_str(),
        args: Vec::new(),
        cwd: os::getcwd(),
        env: HashMap::new(),
    }
}
<|endoftext|>


<commit_before>//! Callback methods for rustwlc
use rustwlc::handle::{WlcOutput, WlcView};
use rustwlc::types::*;
use rustwlc::input::{pointer, keyboard};
use rustwlc::xkb::Keysym;

use super::keys;
use super::keys::{KeyEvent, KeyPress};

/// If the event is handled by way-cooler
const EVENT_HANDLED: bool = true;

/// If the event should be passed through to clients
const EVENT_PASS_THROUGH: bool = false;

// wlc callbacks

pub extern fn output_created(output: WlcOutput) -> bool {
    println!("output_created: {:?}: {}", output, output.get_name());
    return true;
}

pub extern fn output_destroyed(output: WlcOutput) {
    println!("output_destroyed: {:?}", output);
}

pub extern fn output_focus(output: WlcOutput, focused: bool) {
    println!("output_focus: {:?} focus={}", output, focused);
}

pub extern fn output_resolution(output: WlcOutput,
                            old_size_ptr: &Size, new_size_ptr: &Size) {
    println!("output_resolution: {:?} from  {:?} to {:?}",
             output, *old_size_ptr, *new_size_ptr);
}
/*
pub extern fn output_render_pre(output: WlcOutput) {
    //println!("output_render_pre");
}

pub extern fn output_render_post(output: WlcOutput) {
    //println!("output_render_post");
}
*/
pub extern fn view_created(view: WlcView) -> bool {
    println!("view_created: {:?}: \"{}\"", view, view.get_title());
    let output = view.get_output();
    view.set_mask(output.get_mask());
    view.bring_to_front();
    view.focus();
    return true;
}

pub extern fn view_destroyed(view: WlcView) {
    println!("view_destroyed: {:?}", view);
}

pub extern fn view_focus(current: WlcView, focused: bool) {
    println!("view_focus: {:?} {}", current, focused);
    current.set_state(VIEW_ACTIVATED, focused);
}

pub extern fn view_move_to_output(current: WlcView,
                                  o1: WlcOutput, o2: WlcOutput) {
    println!("view_move_to_output: {:?}, {:?}, {:?}", current, o1, o2);
}

pub extern fn view_request_geometry(view: WlcView, geometry: &Geometry) {
    println!("view_request_geometry: {:?} wants {:?}", view, geometry);
    view.set_geometry(EDGE_NONE, geometry);
}

pub extern fn view_request_state(view: WlcView, state: ViewState, handled: bool) {
    println!("view_request_state: {}, {:?}, handled: {}",
    view.get_title(), state, handled);
    view.set_state(state, handled);
}

pub extern fn view_request_move(view: WlcView, dest: &Point) {
    // Called by views when they have a dang resize mouse thing, we should only
    // let it happen in view floating mode
    println!("view_request_move: to {}, start interactive mode.", *dest);
}

pub extern fn view_request_resize(view: WlcView,
                              edge: ResizeEdge, location: &Point) {
    println!("view_request_resize: edge {:?}, to {}, start interactive mode.",
             edge, location);
}

pub extern fn keyboard_key(_view: WlcView, time: u32, mods: &KeyboardModifiers,
                       key: u32, state: KeyState) -> bool {
    println!("keyboard_key: time {}, mods {:?}, key {:?}, state {:?}",
             time, &*mods, key, state);

    if state == KeyState::Pressed {
        // TODO this function will throw an error in Rustwlc right now
        // let mut keys = keyboard::get_current_keys().into_iter()
        //      .map(|&k| Keysym::from(k)).collect();
        let mut keys = vec![Keysym::from(key)];

        let press = KeyPress::new(mods.mods, keys);

        if let Some(action) = keys::get(&press) {
            action();
            return EVENT_HANDLED;
        }
    }

    return EVENT_PASS_THROUGH;
}

pub extern fn pointer_button(view: WlcView, button: u32,
                         mods_ptr: &KeyboardModifiers, key: u32,
                         state: ButtonState, point_ptr: &Point) -> bool {
    println!("pointer_button: pressed {} at {}", key, *point_ptr);
    if state == ButtonState::Pressed && !view.is_root() {
        view.focus();
    }
    false
}

pub extern fn pointer_scroll(_view: WlcView, button: u32,
                         _mods_ptr: &KeyboardModifiers, axis: ScrollAxis,
                         heights: [u64; 2]) -> bool {
    println!("pointer_scroll: press {}, {:?} to {:?}", button, axis, heights);
    false
}

pub extern fn pointer_motion(_view: WlcView, _time: u32, point: &Point) -> bool {
    pointer::set_position(point);
    false
}

/*
pub extern fn touch(view: WlcView, time: u32, mods_ptr: &KeyboardModifiers,
               touch: TouchType, key: i32, point_ptr: &Point) -> bool {
    false
}
*/

pub extern fn compositor_ready() {
    println!("Preparing compositor!");
}
<commit_msg>Add debug to KeyPress<commit_after>//! Callback methods for rustwlc
use rustwlc::handle::{WlcOutput, WlcView};
use rustwlc::types::*;
use rustwlc::input::{pointer, keyboard};
use rustwlc::xkb::Keysym;

use super::keys;
use super::keys::{KeyEvent, KeyPress};

/// If the event is handled by way-cooler
const EVENT_HANDLED: bool = true;

/// If the event should be passed through to clients
const EVENT_PASS_THROUGH: bool = false;

// wlc callbacks

pub extern fn output_created(output: WlcOutput) -> bool {
    println!("output_created: {:?}: {}", output, output.get_name());
    return true;
}

pub extern fn output_destroyed(output: WlcOutput) {
    println!("output_destroyed: {:?}", output);
}

pub extern fn output_focus(output: WlcOutput, focused: bool) {
    println!("output_focus: {:?} focus={}", output, focused);
}

pub extern fn output_resolution(output: WlcOutput,
                            old_size_ptr: &Size, new_size_ptr: &Size) {
    println!("output_resolution: {:?} from  {:?} to {:?}",
             output, *old_size_ptr, *new_size_ptr);
}
/*
pub extern fn output_render_pre(output: WlcOutput) {
    //println!("output_render_pre");
}

pub extern fn output_render_post(output: WlcOutput) {
    //println!("output_render_post");
}
*/
pub extern fn view_created(view: WlcView) -> bool {
    println!("view_created: {:?}: \"{}\"", view, view.get_title());
    let output = view.get_output();
    view.set_mask(output.get_mask());
    view.bring_to_front();
    view.focus();
    return true;
}

pub extern fn view_destroyed(view: WlcView) {
    println!("view_destroyed: {:?}", view);
}

pub extern fn view_focus(current: WlcView, focused: bool) {
    println!("view_focus: {:?} {}", current, focused);
    current.set_state(VIEW_ACTIVATED, focused);
}

pub extern fn view_move_to_output(current: WlcView,
                                  o1: WlcOutput, o2: WlcOutput) {
    println!("view_move_to_output: {:?}, {:?}, {:?}", current, o1, o2);
}

pub extern fn view_request_geometry(view: WlcView, geometry: &Geometry) {
    println!("view_request_geometry: {:?} wants {:?}", view, geometry);
    view.set_geometry(EDGE_NONE, geometry);
}

pub extern fn view_request_state(view: WlcView, state: ViewState, handled: bool) {
    println!("view_request_state: {}, {:?}, handled: {}",
    view.get_title(), state, handled);
    view.set_state(state, handled);
}

pub extern fn view_request_move(view: WlcView, dest: &Point) {
    // Called by views when they have a dang resize mouse thing, we should only
    // let it happen in view floating mode
    println!("view_request_move: to {}, start interactive mode.", *dest);
}

pub extern fn view_request_resize(view: WlcView,
                              edge: ResizeEdge, location: &Point) {
    println!("view_request_resize: edge {:?}, to {}, start interactive mode.",
             edge, location);
}

pub extern fn keyboard_key(_view: WlcView, time: u32, mods: &KeyboardModifiers,
                       key: u32, state: KeyState) -> bool {
    println!("keyboard_key: time {}, mods {:?}, key {:?}, state {:?}",
             time, &*mods, key, state);

    if state == KeyState::Pressed {
        // TODO this function will throw an error in Rustwlc right now
        // let mut keys = keyboard::get_current_keys().into_iter()
        //      .map(|&k| Keysym::from(k)).collect();
        let mut keys = vec![Keysym::from(key)];

        let press = KeyPress::new(mods.mods, keys);

        if let Some(action) = keys::get(&press) {
            println!("Found a key!");
            action();
            return EVENT_HANDLED;
        }
    }

    return EVENT_PASS_THROUGH;
}

pub extern fn pointer_button(view: WlcView, button: u32,
                         mods_ptr: &KeyboardModifiers, key: u32,
                         state: ButtonState, point_ptr: &Point) -> bool {
    println!("pointer_button: pressed {} at {}", key, *point_ptr);
    if state == ButtonState::Pressed && !view.is_root() {
        view.focus();
    }
    false
}

pub extern fn pointer_scroll(_view: WlcView, button: u32,
                         _mods_ptr: &KeyboardModifiers, axis: ScrollAxis,
                         heights: [u64; 2]) -> bool {
    println!("pointer_scroll: press {}, {:?} to {:?}", button, axis, heights);
    false
}

pub extern fn pointer_motion(_view: WlcView, _time: u32, point: &Point) -> bool {
    pointer::set_position(point);
    false
}

/*
pub extern fn touch(view: WlcView, time: u32, mods_ptr: &KeyboardModifiers,
               touch: TouchType, key: i32, point_ptr: &Point) -> bool {
    false
}
*/

pub extern fn compositor_ready() {
    println!("Preparing compositor!");
}
<|endoftext|>


<commit_before>use std::ffi::CString;
use std::ptr::null_mut;

use ffi;
use glib::IsA;
use glib::translate::{FromGlib, ToGlibPtr, from_glib_full, from_glib_none};
use gobject_sys::g_object_get;
use libc::c_void;

use super::{DOMCSSStyleDeclaration, DOMDOMWindow, DOMElement};
use dom_dom_selection::DOMDOMSelection;

pub trait DOMDOMWindowExtManual {
    fn get_computed_style<T: IsA<DOMElement>>(&self, element: &T, pseudo_element: Option<&str>) -> Option<DOMCSSStyleDeclaration>;
    fn get_frame_element(&self) -> Option<DOMElement>;
    fn get_inner_height(&self) -> i64;
    fn get_inner_width(&self) -> i64;
    fn get_selection(&self) -> Option<DOMDOMSelection>;
}

impl DOMDOMWindow {
    fn get_long_property(&self, property_name: &str) -> i64 {
        let property_name = CString::new(property_name).unwrap();
        let mut value: *mut i64 = null_mut();;
        let window: *mut ffi::WebKitDOMDOMWindow = self.to_glib_none().0;
        unsafe {
            g_object_get(window as *mut _, property_name.as_ptr(), &mut value as *mut _, null_mut() as *mut c_void);
        }
        unsafe { *value }
    }
}

impl DOMDOMWindowExtManual for DOMDOMWindow {
    fn get_computed_style<T: IsA<DOMElement>>(&self, element: &T, pseudo_element: Option<&str>) -> Option<DOMCSSStyleDeclaration> {
        unsafe {
            from_glib_full(sys::webkit_dom_dom_window_get_computed_style(self.to_glib_none().0, element.to_glib_none().0, pseudo_element.to_glib_none().0))
        }
    }

    fn get_frame_element(&self) -> Option<DOMElement> {
        let property_name = CString::new("frame-element").unwrap();
        let mut value: *mut ffi::WebKitDOMElement = null_mut();;
        let window: *mut ffi::WebKitDOMDOMWindow = self.to_glib_none().0;
        unsafe {
            g_object_get(window as *mut _, property_name.as_ptr(), &mut value as *mut _, null_mut() as *mut c_void);
        }
        unsafe { from_glib_none(value) }
    }

    fn get_inner_height(&self) -> i64 {
        self.get_long_property("inner-height")
    }

    fn get_inner_width(&self) -> i64 {
        self.get_long_property("inner-width")
    }

    fn get_selection(&self) -> Option<DOMDOMSelection> {
        unsafe { from_glib_none(sys::webkit_dom_dom_window_get_selection(self.to_glib_none().0)) }
    }
}

mod sys {
    use ffi;

    use libc::c_char;
    use dom_dom_selection::sys::WebKitDOMDOMSelection;

    extern "C" {
        pub fn webkit_dom_dom_window_get_computed_style(window: *mut ffi::WebKitDOMDOMWindow, element: *mut ffi::WebKitDOMElement, pseudo_element: *const c_char) -> *mut ffi::WebKitDOMCSSStyleDeclaration;
        pub fn webkit_dom_dom_window_get_selection(window: *mut ffi::WebKitDOMDOMWindow) -> *mut WebKitDOMDOMSelection;
    }
}
<commit_msg>Fixed bug in get_long_property().<commit_after>use std::ffi::CString;
use std::ptr::null_mut;

use ffi;
use glib::IsA;
use glib::translate::{FromGlib, ToGlibPtr, from_glib_full, from_glib_none};
use gobject_sys::g_object_get;
use libc::c_void;

use super::{DOMCSSStyleDeclaration, DOMDOMWindow, DOMElement};
use dom_dom_selection::DOMDOMSelection;

pub trait DOMDOMWindowExtManual {
    fn get_computed_style<T: IsA<DOMElement>>(&self, element: &T, pseudo_element: Option<&str>) -> Option<DOMCSSStyleDeclaration>;
    fn get_frame_element(&self) -> Option<DOMElement>;
    fn get_inner_height(&self) -> i64;
    fn get_inner_width(&self) -> i64;
    fn get_selection(&self) -> Option<DOMDOMSelection>;
}

impl DOMDOMWindow {
    fn get_long_property(&self, property_name: &str) -> i64 {
        let property_name = CString::new(property_name).unwrap();
        let mut value = 0;;
        let window: *mut ffi::WebKitDOMDOMWindow = self.to_glib_none().0;
        unsafe {
            g_object_get(window as *mut _, property_name.as_ptr(), &mut value as *mut _, null_mut() as *mut c_void);
        }
        value
    }
}

impl DOMDOMWindowExtManual for DOMDOMWindow {
    fn get_computed_style<T: IsA<DOMElement>>(&self, element: &T, pseudo_element: Option<&str>) -> Option<DOMCSSStyleDeclaration> {
        unsafe {
            from_glib_full(sys::webkit_dom_dom_window_get_computed_style(self.to_glib_none().0, element.to_glib_none().0, pseudo_element.to_glib_none().0))
        }
    }

    fn get_frame_element(&self) -> Option<DOMElement> {
        let property_name = CString::new("frame-element").unwrap();
        let mut value: *mut ffi::WebKitDOMElement = null_mut();;
        let window: *mut ffi::WebKitDOMDOMWindow = self.to_glib_none().0;
        unsafe {
            g_object_get(window as *mut _, property_name.as_ptr(), &mut value as *mut _, null_mut() as *mut c_void);
        }
        unsafe { from_glib_none(value) }
    }

    fn get_inner_height(&self) -> i64 {
        self.get_long_property("inner-height")
    }

    fn get_inner_width(&self) -> i64 {
        self.get_long_property("inner-width")
    }

    fn get_selection(&self) -> Option<DOMDOMSelection> {
        unsafe { from_glib_none(sys::webkit_dom_dom_window_get_selection(self.to_glib_none().0)) }
    }
}

mod sys {
    use ffi;

    use libc::c_char;
    use dom_dom_selection::sys::WebKitDOMDOMSelection;

    extern "C" {
        pub fn webkit_dom_dom_window_get_computed_style(window: *mut ffi::WebKitDOMDOMWindow, element: *mut ffi::WebKitDOMElement, pseudo_element: *const c_char) -> *mut ffi::WebKitDOMCSSStyleDeclaration;
        pub fn webkit_dom_dom_window_get_selection(window: *mut ffi::WebKitDOMDOMWindow) -> *mut WebKitDOMDOMSelection;
    }
}
<|endoftext|>


<commit_before>// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// ignore-windows
// ignore-wasm32-bare no libc to test ffi with

// issue-53200

#![feature(libc)]
extern crate libc;

use std::env;

// FIXME: more platforms?
#[cfg(target_os = "linux")]
fn main() {
    unsafe { libc::clearenv(); }
    assert_eq!(env::vars().count(), 0);
}

#[cfg(not(target_os = "linux"))]
fn main() {}
<commit_msg>Allow unused_imports lint on test where lint only fires on non-linux targets...<commit_after>// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(unused_imports)]

// ignore-windows
// ignore-wasm32-bare no libc to test ffi with

// issue-53200

#![feature(libc)]
extern crate libc;

use std::env;

// FIXME: more platforms?
#[cfg(target_os = "linux")]
fn main() {
    unsafe { libc::clearenv(); }
    assert_eq!(env::vars().count(), 0);
}

#[cfg(not(target_os = "linux"))]
fn main() {}
<|endoftext|>


<commit_before>

<commit_msg>Removed empty file.<commit_after><|endoftext|>


<commit_before>#![feature(core,collections)]

extern crate collections;
extern crate cql_ffi;

use collections::string::String;

use cql_ffi::*;

#[derive(Debug)]
struct Basic {
    bln:cass_bool_t,
    flt:cass_float_t,
    dbl:cass_double_t,
    i32:cass_int32_t,
    i64:cass_int64_t,
}

fn print_error(future:&mut CassFuture) {unsafe{
    let message = cass_future_error_message(future);
    let message = String::from_raw_parts(message.data as *mut u8,message.length as usize, message.length as usize);
    println!("Error: {:?}", message);
}}

fn create_cluster() -> *mut CassCluster {unsafe{
    let cluster = cass_cluster_new();
    cass_cluster_set_contact_points(cluster, foo.as_ptr() as *const i8);
    cluster
}}

fn connect_session(session:&mut CassSession, cluster:&mut CassCluster) -> CassError {unsafe{
    let future = &mut *cass_session_connect(session, cluster);
    cass_future_wait(future);
    let rc = cass_future_error_code(future);
    match rc {
        CassError::CASS_OK => {},
        _=> print_error(future)
    }
    cass_future_free(future);
    rc
}}

fn execute_query(session: &mut CassSession, query: &str) -> CassError {unsafe{
    let query=str2cass_string(query);
    println!("{:?}",query.length);
   // println!("{:?}", query);
    let statement = cass_statement_new(query, 0);
    let future = &mut *cass_session_execute(session, statement);
    cass_future_wait(future);
    let rc = cass_future_error_code(future);
    match rc {
        CassError::CASS_OK => {},
        _ => print_error(future)
    }
    cass_future_free(future);
    cass_statement_free(statement);
    rc
}}

fn insert_into_basic(session:&mut CassSession, key:&str, basic:&mut Basic) -> CassError {unsafe{
    let query=str2cass_string("INSERT INTO examples.basic (key, bln, flt, dbl, i32, i64) VALUES (?, ?, ?, ?, ?, ?);");
    let statement = cass_statement_new(query, 6);
    cass_statement_bind_string(statement, 0, str2cass_string(key));
    cass_statement_bind_bool(statement, 1, basic.bln);
    cass_statement_bind_float(statement, 2, basic.flt);
    cass_statement_bind_double(statement, 3, basic.dbl);
    cass_statement_bind_int32(statement, 4, basic.i32);
    cass_statement_bind_int64(statement, 5, basic.i64);
    let future = cass_session_execute(session, statement);
    cass_future_wait(future);
    match cass_future_error_code(future) {
        CassError::CASS_OK => {
            print_error(&mut*future);
            cass_future_free(future);
            cass_statement_free(statement);
            CassError::CASS_OK
        },
        err => {panic!(err)}
    }
}}

fn select_from_basic(session:&mut CassSession, key:&str, basic:&mut Basic) -> CassError {unsafe{
    let query = str2cass_string("SELECT * FROM examples.basic WHERE key = ?");
    let statement = cass_statement_new(query, 1);
    let key = key.as_ptr() as *const i8;
    cass_statement_bind_string(statement, 0, cass_string_init(key));
    let future = cass_session_execute(session, statement);
    cass_future_wait(future);
    let rc = cass_future_error_code(future);
    match rc {
        CassError::CASS_OK => {
            let result = cass_future_get_result(future);
            let iterator = cass_iterator_from_result(result);
            if cass_iterator_next(iterator) > 0 {
                let row = cass_iterator_get_row(iterator);
                let ref mut b_bln = basic.bln;
                let ref mut b_dbl = basic.dbl;
                let ref mut b_flt = basic.flt;
                let ref mut b_i32 = basic.i32;
                let ref mut b_i64 = basic.i64;
                cass_value_get_bool(cass_row_get_column(row, 1), b_bln );
                cass_value_get_double(cass_row_get_column(row, 2), b_dbl);
                cass_value_get_float(cass_row_get_column(row, 3), b_flt);
                cass_value_get_int32(cass_row_get_column(row, 4), b_i32);
                cass_value_get_int64(cass_row_get_column(row, 5), b_i64);
                cass_result_free(result);
                cass_iterator_free(iterator);
            }
        },
        _ => {
            //print_error(rc);
            panic!("{:?}",rc);
        }
    }
    cass_future_free(future);
    cass_statement_free(statement);
    rc
}}

fn main() {unsafe{
    let cluster = create_cluster();
    let session = cass_session_new();
    let input = &mut Basic{bln:cass_true, flt:0.001f32, dbl:0.0002f64, i32:1, i64:2 };

    match connect_session(&mut*session, &mut*cluster) {
        CassError::CASS_OK => {
            let output = &mut Basic{bln:0,flt:0f32,dbl:0f64,i32:0,i64:0};
            execute_query(&mut*session, "CREATE KEYSPACE IF NOT EXISTS examples WITH replication = { 'class': 'SimpleStrategy', 'replication_factor': '1' };");
            execute_query(&mut*session, "CREATE TABLE IF NOT EXISTS examples.basic (key text, bln boolean, flt float, dbl double, i32 int, i64 bigint, PRIMARY KEY (key));");
            insert_into_basic(&mut*session, "test", input);
            select_from_basic(&mut*session, "test", output);
            println!("{:?}",input);
            println!("{:?}",output);
            assert!(input.bln == output.bln);
            assert!(input.flt == output.flt);
            assert!(input.dbl == output.dbl);
            assert!(input.i32 == output.i32);
            assert!(input.i64 == output.i64);
            let close_future = cass_session_close(session);
            cass_future_wait(close_future);
            cass_future_free(close_future);
        },
        _ => {}
    }
    cass_cluster_free(cluster);
    cass_session_free(session);
}}
<commit_msg>fixed compile before publishing<commit_after>#![feature(collections)]

extern crate collections;
extern crate cql_ffi;

use collections::string::String;

use cql_ffi::*;

#[derive(Debug)]
struct Basic {
    bln:cass_bool_t,
    flt:cass_float_t,
    dbl:cass_double_t,
    i32:cass_int32_t,
    i64:cass_int64_t,
}

fn print_error(future:&mut CassFuture) {unsafe{
    let message = cass_future_error_message(future);
    let message = String::from_raw_parts(message.data as *mut u8,message.length as usize, message.length as usize);
    println!("Error: {:?}", message);
}}

fn create_cluster() -> *mut CassCluster {unsafe{
    let cluster = cass_cluster_new();
    cass_cluster_set_contact_points(cluster, "127.0.0.1".as_ptr() as *const i8);
    cluster
}}

fn connect_session(session:&mut CassSession, cluster:&mut CassCluster) -> CassError {unsafe{
    let future = &mut *cass_session_connect(session, cluster);
    cass_future_wait(future);
    let rc = cass_future_error_code(future);
    match rc {
        CassError::CASS_OK => {},
        _=> print_error(future)
    }
    cass_future_free(future);
    rc
}}

fn execute_query(session: &mut CassSession, query: &str) -> CassError {unsafe{
    let query=str2cass_string(query);
    println!("{:?}",query.length);
   // println!("{:?}", query);
    let statement = cass_statement_new(query, 0);
    let future = &mut *cass_session_execute(session, statement);
    cass_future_wait(future);
    let rc = cass_future_error_code(future);
    match rc {
        CassError::CASS_OK => {},
        _ => print_error(future)
    }
    cass_future_free(future);
    cass_statement_free(statement);
    rc
}}

fn insert_into_basic(session:&mut CassSession, key:&str, basic:&mut Basic) -> CassError {unsafe{
    let query=str2cass_string("INSERT INTO examples.basic (key, bln, flt, dbl, i32, i64) VALUES (?, ?, ?, ?, ?, ?);");
    let statement = cass_statement_new(query, 6);
    cass_statement_bind_string(statement, 0, str2cass_string(key));
    cass_statement_bind_bool(statement, 1, basic.bln);
    cass_statement_bind_float(statement, 2, basic.flt);
    cass_statement_bind_double(statement, 3, basic.dbl);
    cass_statement_bind_int32(statement, 4, basic.i32);
    cass_statement_bind_int64(statement, 5, basic.i64);
    let future = cass_session_execute(session, statement);
    cass_future_wait(future);
    match cass_future_error_code(future) {
        CassError::CASS_OK => {
            print_error(&mut*future);
            cass_future_free(future);
            cass_statement_free(statement);
            CassError::CASS_OK
        },
        err => {panic!(err)}
    }
}}

fn select_from_basic(session:&mut CassSession, key:&str, basic:&mut Basic) -> CassError {unsafe{
    let query = str2cass_string("SELECT * FROM examples.basic WHERE key = ?");
    let statement = cass_statement_new(query, 1);
    let key = key.as_ptr() as *const i8;
    cass_statement_bind_string(statement, 0, cass_string_init(key));
    let future = cass_session_execute(session, statement);
    cass_future_wait(future);
    let rc = cass_future_error_code(future);
    match rc {
        CassError::CASS_OK => {
            let result = cass_future_get_result(future);
            let iterator = cass_iterator_from_result(result);
            if cass_iterator_next(iterator) > 0 {
                let row = cass_iterator_get_row(iterator);
                let ref mut b_bln = basic.bln;
                let ref mut b_dbl = basic.dbl;
                let ref mut b_flt = basic.flt;
                let ref mut b_i32 = basic.i32;
                let ref mut b_i64 = basic.i64;
                cass_value_get_bool(cass_row_get_column(row, 1), b_bln );
                cass_value_get_double(cass_row_get_column(row, 2), b_dbl);
                cass_value_get_float(cass_row_get_column(row, 3), b_flt);
                cass_value_get_int32(cass_row_get_column(row, 4), b_i32);
                cass_value_get_int64(cass_row_get_column(row, 5), b_i64);
                cass_result_free(result);
                cass_iterator_free(iterator);
            }
        },
        _ => {
            //print_error(rc);
            panic!("{:?}",rc);
        }
    }
    cass_future_free(future);
    cass_statement_free(statement);
    rc
}}

fn main() {unsafe{
    let cluster = create_cluster();
    let session = cass_session_new();
    let input = &mut Basic{bln:cass_true, flt:0.001f32, dbl:0.0002f64, i32:1, i64:2 };

    match connect_session(&mut*session, &mut*cluster) {
        CassError::CASS_OK => {
            let output = &mut Basic{bln:0,flt:0f32,dbl:0f64,i32:0,i64:0};
            execute_query(&mut*session, "CREATE KEYSPACE IF NOT EXISTS examples WITH replication = { 'class': 'SimpleStrategy', 'replication_factor': '1' };");
            execute_query(&mut*session, "CREATE TABLE IF NOT EXISTS examples.basic (key text, bln boolean, flt float, dbl double, i32 int, i64 bigint, PRIMARY KEY (key));");
            insert_into_basic(&mut*session, "test", input);
            select_from_basic(&mut*session, "test", output);
            println!("{:?}",input);
            println!("{:?}",output);
            assert!(input.bln == output.bln);
            assert!(input.flt == output.flt);
            assert!(input.dbl == output.dbl);
            assert!(input.i32 == output.i32);
            assert!(input.i64 == output.i64);
            let close_future = cass_session_close(session);
            cass_future_wait(close_future);
            cass_future_free(close_future);
        },
        _ => {}
    }
    cass_cluster_free(cluster);
    cass_session_free(session);
}}
<|endoftext|>


<commit_before>use std::io::{IoError, TcpListener, Listener, Acceptor, TcpStream, IoResult};
use std::time::duration::Duration;

use knuckle::{cryptobox, sign};
use knuckle::util::random_bytes;
use knuckle::cryptobox::{CryptoBox, Keypair};

use mittens::socks;
use mittens::config::RelayConfig;

struct ServerConnection {
    verify_key: sign::PublicKey,
    cbox: cryptobox::CryptoBox,
    control: TcpStream
}

impl ServerConnection {
    fn new(conf: &RelayConfig) -> IoResult<ServerConnection> {
        let control = try!(TcpStream::connect_timeout(conf.server_addr,
                                                      Duration::seconds(5000)));

        // TODO: REMOVE ME
        let key = Keypair::new();

        Ok(ServerConnection {
            verify_key: conf.verify_key,
            cbox: CryptoBox::from_key_pair(key.sk, key.pk),
            control: control
        })
    }

    /// Challenge the server with a random nonce, ensure that they can
    /// produce a valid signature.
    fn stream_handshake(&mut self) -> IoResult<()> {
        let nonce = random_bytes(128);
        let resp = try!(self.send(nonce.as_slice()));

        let smsg = sign::SignedMsg {
            pk: self.verify_key,
            signed: resp
        };

        match smsg.verify() {
            Some(ref msg) if *msg == nonce => Ok(()),
            _ => Err(IoError::last_error())
        }
    }

    fn rotate_key(&mut self) -> IoResult<()> {
        let key = random_bytes(32);
        try!(self.send(key.as_slice()));

        Ok(())
    }

    fn establish_connection(&mut self) -> IoResult<()> {
        try!(self.stream_handshake());
        try!(self.rotate_key());

        Ok(())
    }

    fn send(&mut self, msg: &[u8]) -> IoResult<Vec<u8>> {
        let ciphertext = self.cbox.encrypt(msg).as_bytes();
        self.send_raw(ciphertext.as_slice())
    }

    fn send_raw(&mut self, msg: &[u8]) -> IoResult<Vec<u8>> {
        try!(self.control.write_be_uint(msg.len()));
        try!(self.control.write(msg.as_slice()));

        let len = try!(self.control.read_be_uint());
        self.control.read_exact(len)
    }
}

pub fn start_relay(conf: RelayConfig) {
    let server_conn = match ServerConnection::new(&conf)
        .and_then(|mut c| c.establish_connection()) {
            Ok(conn) => conn,
            Err(x) => fail!("Failed to establish secure connection: {}", x)
        };

    let listener = TcpListener::bind(conf.relay_host.as_slice(),
                                     conf.relay_port);
    let mut acceptor = listener.listen().unwrap();

    for stream in acceptor.incoming() {
        match stream {
            Err(_) => { /* TODO: handle errors */ }
            Ok(mut stream) => socks::handle_stream(&mut stream)
        }
    }

    drop(acceptor);
}
<commit_msg>Remove unused variable<commit_after>use std::io::{IoError, TcpListener, Listener, Acceptor, TcpStream, IoResult};
use std::time::duration::Duration;

use knuckle::{cryptobox, sign};
use knuckle::util::random_bytes;
use knuckle::cryptobox::{CryptoBox, Keypair};

use mittens::socks;
use mittens::config::RelayConfig;

struct ServerConnection {
    verify_key: sign::PublicKey,
    cbox: cryptobox::CryptoBox,
    control: TcpStream
}

impl ServerConnection {
    fn new(conf: &RelayConfig) -> IoResult<ServerConnection> {
        let control = try!(TcpStream::connect_timeout(conf.server_addr,
                                                      Duration::seconds(5000)));

        // TODO: REMOVE ME
        let key = Keypair::new();

        Ok(ServerConnection {
            verify_key: conf.verify_key,
            cbox: CryptoBox::from_key_pair(key.sk, key.pk),
            control: control
        })
    }

    /// Challenge the server with a random nonce, ensure that they can
    /// produce a valid signature.
    fn stream_handshake(&mut self) -> IoResult<()> {
        let nonce = random_bytes(128);
        let resp = try!(self.send(nonce.as_slice()));

        let smsg = sign::SignedMsg {
            pk: self.verify_key,
            signed: resp
        };

        match smsg.verify() {
            Some(ref msg) if *msg == nonce => Ok(()),
            _ => Err(IoError::last_error())
        }
    }

    fn rotate_key(&mut self) -> IoResult<()> {
        let key = random_bytes(32);
        try!(self.send(key.as_slice()));

        Ok(())
    }

    fn establish_connection(&mut self) -> IoResult<()> {
        try!(self.stream_handshake());
        try!(self.rotate_key());

        Ok(())
    }

    fn send(&mut self, msg: &[u8]) -> IoResult<Vec<u8>> {
        let ciphertext = self.cbox.encrypt(msg).as_bytes();
        self.send_raw(ciphertext.as_slice())
    }

    fn send_raw(&mut self, msg: &[u8]) -> IoResult<Vec<u8>> {
        try!(self.control.write_be_uint(msg.len()));
        try!(self.control.write(msg.as_slice()));

        let len = try!(self.control.read_be_uint());
        self.control.read_exact(len)
    }
}

pub fn start_relay(conf: RelayConfig) {
    let _ = match ServerConnection::new(&conf)
        .and_then(|mut c| c.establish_connection()) {
            Ok(conn) => conn,
            Err(x) => fail!("Failed to establish secure connection: {}", x)
        };

    let listener = TcpListener::bind(conf.relay_host.as_slice(),
                                     conf.relay_port);
    let mut acceptor = listener.listen().unwrap();

    for stream in acceptor.incoming() {
        match stream {
            Err(_) => { /* TODO: handle errors */ }
            Ok(mut stream) => socks::handle_stream(&mut stream)
        }
    }

    drop(acceptor);
}
<|endoftext|>


<commit_before>//! Endpoints that expose metadata about a crate
//!
//! These endpoints provide data that could be obtained directly from the
//! index or cached metadata which was extracted (client side) from the
//! `Cargo.toml` file.

use crate::controllers::frontend_prelude::*;

use crate::models::{
    Category, Crate, CrateCategory, CrateKeyword, CrateVersions, Keyword, RecentCrateDownloads,
    User, Version, VersionOwnerAction,
};
use crate::schema::*;
use crate::views::{
    EncodableCategory, EncodableCrate, EncodableDependency, EncodableKeyword, EncodableVersion,
};

use crate::models::krate::ALL_COLUMNS;

/// Handles the `GET /summary` route.
pub fn summary(req: &mut dyn Request) -> AppResult<Response> {
    use crate::schema::crates::dsl::*;

    let conn = req.db_read_only()?;
    let num_crates = crates.count().get_result(&*conn)?;
    let num_downloads = metadata::table
        .select(metadata::total_downloads)
        .get_result(&*conn)?;

    let encode_crates = |krates: Vec<Crate>| -> AppResult<Vec<_>> {
        let versions = krates.versions().load::<Version>(&*conn)?;
        versions
            .grouped_by(&krates)
            .into_iter()
            .map(|versions| Version::top(versions.into_iter().map(|v| (v.created_at, v.num))))
            .zip(krates)
            .map(|(top_versions, krate)| {
                Ok(krate.minimal_encodable(&top_versions, None, false, None))
            })
            .collect()
    };

    let new_crates = crates
        .order(created_at.desc())
        .select(ALL_COLUMNS)
        .limit(10)
        .load(&*conn)?;
    let just_updated = crates
        .filter(updated_at.ne(created_at))
        .order(updated_at.desc())
        .select(ALL_COLUMNS)
        .limit(10)
        .load(&*conn)?;
    let most_downloaded = crates
        .order(downloads.desc())
        .select(ALL_COLUMNS)
        .limit(10)
        .load(&*conn)?;

    let most_recently_downloaded = crates
        .inner_join(recent_crate_downloads::table)
        .order(recent_crate_downloads::downloads.desc())
        .select(ALL_COLUMNS)
        .limit(10)
        .load(&*conn)?;

    let popular_keywords = keywords::table
        .order(keywords::crates_cnt.desc())
        .limit(10)
        .load(&*conn)?
        .into_iter()
        .map(Keyword::encodable)
        .collect();

    let popular_categories = Category::toplevel(&conn, "crates", 10, 0)?
        .into_iter()
        .map(Category::encodable)
        .collect();

    #[derive(Serialize)]
    struct R {
        num_downloads: i64,
        num_crates: i64,
        new_crates: Vec<EncodableCrate>,
        most_downloaded: Vec<EncodableCrate>,
        most_recently_downloaded: Vec<EncodableCrate>,
        just_updated: Vec<EncodableCrate>,
        popular_keywords: Vec<EncodableKeyword>,
        popular_categories: Vec<EncodableCategory>,
    }
    Ok(req.json(&R {
        num_downloads,
        num_crates,
        new_crates: encode_crates(new_crates)?,
        most_downloaded: encode_crates(most_downloaded)?,
        most_recently_downloaded: encode_crates(most_recently_downloaded)?,
        just_updated: encode_crates(just_updated)?,
        popular_keywords,
        popular_categories,
    }))
}

/// Handles the `GET /crates/:crate_id` route.
pub fn show(req: &mut dyn Request) -> AppResult<Response> {
    let name = &req.params()["crate_id"];
    let conn = req.db_conn()?;
    let krate = Crate::by_name(name).first::<Crate>(&*conn)?;

    let mut versions_and_publishers = krate
        .all_versions()
        .left_outer_join(users::table)
        .select((versions::all_columns, users::all_columns.nullable()))
        .load::<(Version, Option<User>)>(&*conn)?;
    versions_and_publishers.sort_by(|a, b| b.0.num.cmp(&a.0.num));
    let versions = versions_and_publishers
        .iter()
        .map(|(v, _)| v)
        .cloned()
        .collect::<Vec<_>>();
    let versions_publishers_and_audit_actions = versions_and_publishers
        .into_iter()
        .zip(VersionOwnerAction::for_versions(&conn, &versions)?.into_iter())
        .map(|((v, pb), aas)| (v, pb, aas))
        .collect::<Vec<_>>();
    let ids = versions_publishers_and_audit_actions
        .iter()
        .map(|v| v.0.id)
        .collect();

    let kws = CrateKeyword::belonging_to(&krate)
        .inner_join(keywords::table)
        .select(keywords::all_columns)
        .load(&*conn)?;
    let cats = CrateCategory::belonging_to(&krate)
        .inner_join(categories::table)
        .select(categories::all_columns)
        .load(&*conn)?;
    let recent_downloads = RecentCrateDownloads::belonging_to(&krate)
        .select(recent_crate_downloads::downloads)
        .get_result(&*conn)
        .optional()?;

    let badges = badges::table
        .filter(badges::crate_id.eq(krate.id))
        .load(&*conn)?;
    let top_versions = krate.top_versions(&conn)?;

    #[derive(Serialize)]
    struct R {
        #[serde(rename = "crate")]
        krate: EncodableCrate,
        versions: Vec<EncodableVersion>,
        keywords: Vec<EncodableKeyword>,
        categories: Vec<EncodableCategory>,
    }
    Ok(req.json(&R {
        krate: krate.clone().encodable(
            &top_versions,
            Some(ids),
            Some(&kws),
            Some(&cats),
            Some(badges),
            false,
            recent_downloads,
        ),
        versions: versions_publishers_and_audit_actions
            .into_iter()
            .map(|(v, pb, aas)| v.encodable(&krate.name, pb, aas))
            .collect(),
        keywords: kws.into_iter().map(Keyword::encodable).collect(),
        categories: cats.into_iter().map(Category::encodable).collect(),
    }))
}

/// Handles the `GET /crates/:crate_id/:version/readme` route.
pub fn readme(req: &mut dyn Request) -> AppResult<Response> {
    let crate_name = &req.params()["crate_id"];
    let version = &req.params()["version"];

    let redirect_url = req
        .app()
        .config
        .uploader
        .readme_location(crate_name, version);

    if req.wants_json() {
        #[derive(Serialize)]
        struct R {
            url: String,
        }
        Ok(req.json(&R { url: redirect_url }))
    } else {
        Ok(req.redirect(redirect_url))
    }
}

/// Handles the `GET /crates/:crate_id/versions` route.
// FIXME: Not sure why this is necessary since /crates/:crate_id returns
// this information already, but ember is definitely requesting it
pub fn versions(req: &mut dyn Request) -> AppResult<Response> {
    let crate_name = &req.params()["crate_id"];
    let conn = req.db_conn()?;
    let krate = Crate::by_name(crate_name).first::<Crate>(&*conn)?;
    let mut versions_and_publishers: Vec<(Version, Option<User>)> = krate
        .all_versions()
        .left_outer_join(users::table)
        .select((versions::all_columns, users::all_columns.nullable()))
        .load(&*conn)?;
    versions_and_publishers.sort_by(|a, b| b.0.num.cmp(&a.0.num));
    let versions = versions_and_publishers
        .iter()
        .map(|(v, _)| v)
        .cloned()
        .collect::<Vec<_>>();
    let versions = versions_and_publishers
        .into_iter()
        .zip(VersionOwnerAction::for_versions(&conn, &versions)?.into_iter())
        .map(|((v, pb), aas)| v.encodable(crate_name, pb, aas))
        .collect();

    #[derive(Serialize)]
    struct R {
        versions: Vec<EncodableVersion>,
    }
    Ok(req.json(&R { versions }))
}

/// Handles the `GET /crates/:crate_id/reverse_dependencies` route.
pub fn reverse_dependencies(req: &mut dyn Request) -> AppResult<Response> {
    use diesel::dsl::any;

    let name = &req.params()["crate_id"];
    let conn = req.db_conn()?;
    let krate = Crate::by_name(name).first::<Crate>(&*conn)?;
    let (rev_deps, total) = krate.reverse_dependencies(&*conn, &req.query())?;
    let rev_deps: Vec<_> = rev_deps
        .into_iter()
        .map(|dep| dep.encodable(&krate.name))
        .collect();

    let version_ids: Vec<i32> = rev_deps.iter().map(|dep| dep.version_id).collect();

    let versions_and_publishers = versions::table
        .filter(versions::id.eq(any(version_ids)))
        .inner_join(crates::table)
        .left_outer_join(users::table)
        .select((
            versions::all_columns,
            crates::name,
            users::all_columns.nullable(),
        ))
        .load::<(Version, String, Option<User>)>(&*conn)?;
    let versions = versions_and_publishers
        .iter()
        .map(|(v, _, _)| v)
        .cloned()
        .collect::<Vec<_>>();
    let versions = versions_and_publishers
        .into_iter()
        .zip(VersionOwnerAction::for_versions(&conn, &versions)?.into_iter())
        .map(|((version, krate_name, published_by), actions)| {
            version.encodable(&krate_name, published_by, actions)
        })
        .collect();

    #[derive(Serialize)]
    struct R {
        dependencies: Vec<EncodableDependency>,
        versions: Vec<EncodableVersion>,
        meta: Meta,
    }
    #[derive(Serialize)]
    struct Meta {
        total: i64,
    }
    Ok(req.json(&R {
        dependencies: rev_deps,
        versions,
        meta: Meta { total },
    }))
}
<commit_msg>Use read-only replica pool for crate show endpoint<commit_after>//! Endpoints that expose metadata about a crate
//!
//! These endpoints provide data that could be obtained directly from the
//! index or cached metadata which was extracted (client side) from the
//! `Cargo.toml` file.

use crate::controllers::frontend_prelude::*;

use crate::models::{
    Category, Crate, CrateCategory, CrateKeyword, CrateVersions, Keyword, RecentCrateDownloads,
    User, Version, VersionOwnerAction,
};
use crate::schema::*;
use crate::views::{
    EncodableCategory, EncodableCrate, EncodableDependency, EncodableKeyword, EncodableVersion,
};

use crate::models::krate::ALL_COLUMNS;

/// Handles the `GET /summary` route.
pub fn summary(req: &mut dyn Request) -> AppResult<Response> {
    use crate::schema::crates::dsl::*;

    let conn = req.db_read_only()?;
    let num_crates = crates.count().get_result(&*conn)?;
    let num_downloads = metadata::table
        .select(metadata::total_downloads)
        .get_result(&*conn)?;

    let encode_crates = |krates: Vec<Crate>| -> AppResult<Vec<_>> {
        let versions = krates.versions().load::<Version>(&*conn)?;
        versions
            .grouped_by(&krates)
            .into_iter()
            .map(|versions| Version::top(versions.into_iter().map(|v| (v.created_at, v.num))))
            .zip(krates)
            .map(|(top_versions, krate)| {
                Ok(krate.minimal_encodable(&top_versions, None, false, None))
            })
            .collect()
    };

    let new_crates = crates
        .order(created_at.desc())
        .select(ALL_COLUMNS)
        .limit(10)
        .load(&*conn)?;
    let just_updated = crates
        .filter(updated_at.ne(created_at))
        .order(updated_at.desc())
        .select(ALL_COLUMNS)
        .limit(10)
        .load(&*conn)?;
    let most_downloaded = crates
        .order(downloads.desc())
        .select(ALL_COLUMNS)
        .limit(10)
        .load(&*conn)?;

    let most_recently_downloaded = crates
        .inner_join(recent_crate_downloads::table)
        .order(recent_crate_downloads::downloads.desc())
        .select(ALL_COLUMNS)
        .limit(10)
        .load(&*conn)?;

    let popular_keywords = keywords::table
        .order(keywords::crates_cnt.desc())
        .limit(10)
        .load(&*conn)?
        .into_iter()
        .map(Keyword::encodable)
        .collect();

    let popular_categories = Category::toplevel(&conn, "crates", 10, 0)?
        .into_iter()
        .map(Category::encodable)
        .collect();

    #[derive(Serialize)]
    struct R {
        num_downloads: i64,
        num_crates: i64,
        new_crates: Vec<EncodableCrate>,
        most_downloaded: Vec<EncodableCrate>,
        most_recently_downloaded: Vec<EncodableCrate>,
        just_updated: Vec<EncodableCrate>,
        popular_keywords: Vec<EncodableKeyword>,
        popular_categories: Vec<EncodableCategory>,
    }
    Ok(req.json(&R {
        num_downloads,
        num_crates,
        new_crates: encode_crates(new_crates)?,
        most_downloaded: encode_crates(most_downloaded)?,
        most_recently_downloaded: encode_crates(most_recently_downloaded)?,
        just_updated: encode_crates(just_updated)?,
        popular_keywords,
        popular_categories,
    }))
}

/// Handles the `GET /crates/:crate_id` route.
pub fn show(req: &mut dyn Request) -> AppResult<Response> {
    let name = &req.params()["crate_id"];
    let conn = req.db_read_only()?;
    let krate = Crate::by_name(name).first::<Crate>(&*conn)?;

    let mut versions_and_publishers = krate
        .all_versions()
        .left_outer_join(users::table)
        .select((versions::all_columns, users::all_columns.nullable()))
        .load::<(Version, Option<User>)>(&*conn)?;
    versions_and_publishers.sort_by(|a, b| b.0.num.cmp(&a.0.num));
    let versions = versions_and_publishers
        .iter()
        .map(|(v, _)| v)
        .cloned()
        .collect::<Vec<_>>();
    let versions_publishers_and_audit_actions = versions_and_publishers
        .into_iter()
        .zip(VersionOwnerAction::for_versions(&conn, &versions)?.into_iter())
        .map(|((v, pb), aas)| (v, pb, aas))
        .collect::<Vec<_>>();
    let ids = versions_publishers_and_audit_actions
        .iter()
        .map(|v| v.0.id)
        .collect();

    let kws = CrateKeyword::belonging_to(&krate)
        .inner_join(keywords::table)
        .select(keywords::all_columns)
        .load(&*conn)?;
    let cats = CrateCategory::belonging_to(&krate)
        .inner_join(categories::table)
        .select(categories::all_columns)
        .load(&*conn)?;
    let recent_downloads = RecentCrateDownloads::belonging_to(&krate)
        .select(recent_crate_downloads::downloads)
        .get_result(&*conn)
        .optional()?;

    let badges = badges::table
        .filter(badges::crate_id.eq(krate.id))
        .load(&*conn)?;
    let top_versions = krate.top_versions(&conn)?;

    #[derive(Serialize)]
    struct R {
        #[serde(rename = "crate")]
        krate: EncodableCrate,
        versions: Vec<EncodableVersion>,
        keywords: Vec<EncodableKeyword>,
        categories: Vec<EncodableCategory>,
    }
    Ok(req.json(&R {
        krate: krate.clone().encodable(
            &top_versions,
            Some(ids),
            Some(&kws),
            Some(&cats),
            Some(badges),
            false,
            recent_downloads,
        ),
        versions: versions_publishers_and_audit_actions
            .into_iter()
            .map(|(v, pb, aas)| v.encodable(&krate.name, pb, aas))
            .collect(),
        keywords: kws.into_iter().map(Keyword::encodable).collect(),
        categories: cats.into_iter().map(Category::encodable).collect(),
    }))
}

/// Handles the `GET /crates/:crate_id/:version/readme` route.
pub fn readme(req: &mut dyn Request) -> AppResult<Response> {
    let crate_name = &req.params()["crate_id"];
    let version = &req.params()["version"];

    let redirect_url = req
        .app()
        .config
        .uploader
        .readme_location(crate_name, version);

    if req.wants_json() {
        #[derive(Serialize)]
        struct R {
            url: String,
        }
        Ok(req.json(&R { url: redirect_url }))
    } else {
        Ok(req.redirect(redirect_url))
    }
}

/// Handles the `GET /crates/:crate_id/versions` route.
// FIXME: Not sure why this is necessary since /crates/:crate_id returns
// this information already, but ember is definitely requesting it
pub fn versions(req: &mut dyn Request) -> AppResult<Response> {
    let crate_name = &req.params()["crate_id"];
    let conn = req.db_conn()?;
    let krate = Crate::by_name(crate_name).first::<Crate>(&*conn)?;
    let mut versions_and_publishers: Vec<(Version, Option<User>)> = krate
        .all_versions()
        .left_outer_join(users::table)
        .select((versions::all_columns, users::all_columns.nullable()))
        .load(&*conn)?;
    versions_and_publishers.sort_by(|a, b| b.0.num.cmp(&a.0.num));
    let versions = versions_and_publishers
        .iter()
        .map(|(v, _)| v)
        .cloned()
        .collect::<Vec<_>>();
    let versions = versions_and_publishers
        .into_iter()
        .zip(VersionOwnerAction::for_versions(&conn, &versions)?.into_iter())
        .map(|((v, pb), aas)| v.encodable(crate_name, pb, aas))
        .collect();

    #[derive(Serialize)]
    struct R {
        versions: Vec<EncodableVersion>,
    }
    Ok(req.json(&R { versions }))
}

/// Handles the `GET /crates/:crate_id/reverse_dependencies` route.
pub fn reverse_dependencies(req: &mut dyn Request) -> AppResult<Response> {
    use diesel::dsl::any;

    let name = &req.params()["crate_id"];
    let conn = req.db_read_only()?;
    let krate = Crate::by_name(name).first::<Crate>(&*conn)?;
    let (rev_deps, total) = krate.reverse_dependencies(&*conn, &req.query())?;
    let rev_deps: Vec<_> = rev_deps
        .into_iter()
        .map(|dep| dep.encodable(&krate.name))
        .collect();

    let version_ids: Vec<i32> = rev_deps.iter().map(|dep| dep.version_id).collect();

    let versions_and_publishers = versions::table
        .filter(versions::id.eq(any(version_ids)))
        .inner_join(crates::table)
        .left_outer_join(users::table)
        .select((
            versions::all_columns,
            crates::name,
            users::all_columns.nullable(),
        ))
        .load::<(Version, String, Option<User>)>(&*conn)?;
    let versions = versions_and_publishers
        .iter()
        .map(|(v, _, _)| v)
        .cloned()
        .collect::<Vec<_>>();
    let versions = versions_and_publishers
        .into_iter()
        .zip(VersionOwnerAction::for_versions(&conn, &versions)?.into_iter())
        .map(|((version, krate_name, published_by), actions)| {
            version.encodable(&krate_name, published_by, actions)
        })
        .collect();

    #[derive(Serialize)]
    struct R {
        dependencies: Vec<EncodableDependency>,
        versions: Vec<EncodableVersion>,
        meta: Meta,
    }
    #[derive(Serialize)]
    struct Meta {
        total: i64,
    }
    Ok(req.json(&R {
        dependencies: rev_deps,
        versions,
        meta: Meta { total },
    }))
}
<|endoftext|>