diff --git a/Cargo.lock b/Cargo.lock index 343f695..317792b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,6 +5,7 @@ dependencies = [ "conch-parser 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "conch-runtime 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "vt6 0.0.1", ] [[package]] @@ -713,6 +714,10 @@ name = "void" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "vt6" +version = "0.0.1" + [[package]] name = "winapi" version = "0.2.8" diff --git a/Cargo.toml b/Cargo.toml index d7ccf4e..8f3bd59 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,4 @@ authors = ["lærling "] conch-parser = "^0.1.0" conch-runtime = "^0.1.4" tokio-core = "^0.1.17" +vt6 = { path = "../vt6.rs/vt6" } \ No newline at end of file diff --git a/src/connection.rs b/src/connection.rs new file mode 100644 index 0000000..69e94ac --- /dev/null +++ b/src/connection.rs @@ -0,0 +1,90 @@ +/******************************************************************************* + * + * Copyright 2018 lærling + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * + *******************************************************************************/ + +use std::env::vars; +use std::io; +use std::io::Write; +use std::os::unix::net::UnixStream; +use std::path::PathBuf; +use std::io::Error; +use std::io::ErrorKind; +use vt6::common::core::msg::Message; +use std::io::Read; + +const BUF_SIZE: usize = 1024; + +/// Encapsulates the server connection +pub struct Connection { + stream: UnixStream, + buffer: [u8; BUF_SIZE], +} + +impl Connection { + + /// finds the vt6 socket and connects to it, returning a new connection object + pub fn new() -> Result { + + if let Some(vt6_socket_var) = vars().find(|var| var.0 == "VT6") { + let con = Connection { + stream: match UnixStream::connect(PathBuf::from(&vt6_socket_var.1)) { + Ok(stream) => stream, + Err(e) => { + eprintln!("Cannot connect to socket '{}'", vt6_socket_var.1); + panic!(e); // TODO: Only in debug profile, else exit with 1 + }, + }, + buffer: [0; BUF_SIZE], + }; + return Ok(con); + } + + Err(Error::new(ErrorKind::NotFound, "VT6 server socket not found.")) + } + + /// sends a message and waits for the response (synchronously) + pub fn send_and_receive(&mut self, msg: &str) -> (Message, usize) { + + // send + self.stream.write_all(msg.as_bytes()).unwrap(); // TODO: Use vt6 messages + + // read until there is something that can be parsed + let mut buffer_offset: usize = 0; + loop { + + // read into buffer... + let bytes_read = match self.stream.read(&mut self.buffer[buffer_offset..]) { + Ok(b) => b, + Err(e) => { + eprintln!("Connection to server socket lost"); + panic!(e); // TODO: Only in debug profile, else exit with 1 + } + }; + + // adjust offset for next read + buffer_offset += bytes_read; + + // ...until there is something that can be parsed + match Message::parse(&self.buffer[..buffer_offset]) { + Ok(_) => break, + Err(_) => {}, // continue + } + } + + return Message::parse(&self.buffer[..buffer_offset]).unwrap(); + } +} diff --git a/src/main.rs b/src/main.rs index 9b05c30..2e88bec 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,6 +19,7 @@ extern crate conch_parser; extern crate conch_runtime; extern crate tokio_core; +extern crate vt6; use conch_parser::lexer::Lexer; use conch_parser::parse::DefaultParser; @@ -32,6 +33,8 @@ use std::option::Option; use tokio_core::reactor::Core; use std::process::exit; +mod connection; + fn repl(script: &mut T) -> io::Result<()> { // make event loop @@ -79,6 +82,12 @@ fn repl(script: &mut T) -> io::Result<()> { fn main() { + // FIXME temp + let mut con = connection::Connection::new().unwrap(); + println!("main: core: {}", con.send_and_receive("{3|4:want,4:core,1:1,}").0); + println!("main: LmAo: {}", con.send_and_receive("{3|4:want,4:LmAo,1:1,}").0); + std::process::exit(0); + // evaluate command line argument let eval_result = match env::args().nth(1) {