From 31d90e1d8794d95f16b76ef9c022e2237d77c633 Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Wed, 4 Mar 2020 14:09:55 +0200 Subject: [PATCH] Add managesieve.rs --- Cargo.toml | 6 ++ src/managesieve.rs | 144 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 src/managesieve.rs diff --git a/Cargo.toml b/Cargo.toml index dba20cdb..9cb8b828 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,11 +11,17 @@ homepage = "https://meli.delivery" repository = "https://git.meli.delivery/meli/meli.git" keywords = ["mail", "mua", "maildir", "terminal", "imap"] categories = ["command-line-utilities", "email"] +default-run = "meli" [[bin]] name = "meli" path = "src/bin.rs" + +[[bin]] +name = "managesieve" +path = "src/managesieve.rs" + [dependencies] xdg = "2.1.0" crossbeam = "0.7.2" diff --git a/src/managesieve.rs b/src/managesieve.rs new file mode 100644 index 00000000..5e2f9a5b --- /dev/null +++ b/src/managesieve.rs @@ -0,0 +1,144 @@ +/* + * meli - managesieve REPL + * + * Copyright 2020 Manos Pitsidianakis + * + * This file is part of meli. + * + * meli 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. + * + * meli 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 meli. If not, see . + */ + +#[macro_use] +extern crate melib; +use melib::*; + +use std::alloc::System; +use std::collections::VecDeque; +use std::path::{Path, PathBuf}; +extern crate notify_rust; +extern crate xdg_utils; +#[macro_use] +extern crate serde_derive; +extern crate linkify; +extern crate uuid; + +extern crate fnv; +extern crate termion; + +#[macro_use] +extern crate nom; + +extern crate serde_json; +extern crate smallvec; + +use melib::backends::imap::managesieve::new_managesieve_connection; +use melib::AccountSettings; +use melib::Result; + +mod unix; +use unix::*; + +#[macro_use] +pub mod types; +use crate::types::*; + +#[macro_use] +pub mod terminal; +use crate::terminal::*; + +#[macro_use] +pub mod execute; +use crate::execute::*; + +pub mod state; +use crate::state::*; + +pub mod components; +use crate::components::*; + +#[macro_use] +pub mod conf; +use crate::conf::*; + +pub mod workers; +use crate::workers::*; + +#[cfg(feature = "sqlite3")] +pub mod sqlite3; + +pub mod cache; +pub mod mailcap; +pub mod plugins; + +/// Opens an interactive shell on a managesieve server. Suggested use is with rlwrap(1) +/// +/// # Example invocation: +/// ```sh +/// ./manage_sieve server_hostname server_username server_password server_port"); +/// ``` +/// +/// `danger_accept_invalid_certs` is turned on by default, so no certificate validation is performed. + +fn main() -> Result<()> { + let mut args = std::env::args().skip(1).collect::>(); + if args.len() != 2 { + eprintln!("Usage: manage_sieve CONFIG_PATH ACCOUNT_NAME"); + std::process::exit(1); + } + + let (config_path, account_name) = ( + std::mem::replace(&mut args[0], String::new()), + std::mem::replace(&mut args[1], String::new()), + ); + std::env::set_var("MELI_CONFIG", config_path); + let settings = conf::Settings::new()?; + if !settings.accounts.contains_key(&account_name) { + eprintln!( + "Account not found. available accounts: {}", + settings + .accounts + .keys() + .cloned() + .collect::>() + .join(", ") + ); + std::process::exit(1); + } + let mut conn = new_managesieve_connection(&settings.accounts[&account_name].account)?; + conn.connect()?; + let mut res = String::with_capacity(8 * 1024); + + let mut input = String::new(); + println!("managesieve shell: use 'logout'"); + loop { + use std::io; + use std::io::Write; + input.clear(); + print!("> "); + io::stdout().flush(); + match io::stdin().read_line(&mut input) { + Ok(_) => { + if input.trim().eq_ignore_ascii_case("logout") { + break; + } + conn.send_command(input.as_bytes()).unwrap(); + conn.read_lines(&mut res, String::new()).unwrap(); + println!("out: {}", res.trim()); + } + Err(error) => println!("error: {}", error), + } + } + + Ok(()) +}