Read entries
This commit is contained in:
parent
04a47e18e4
commit
9f8232f7f1
4 changed files with 119 additions and 1 deletions
|
@ -8,3 +8,4 @@ license = "MIT OR Apache-2.0"
|
|||
publish = false
|
||||
|
||||
[dependencies]
|
||||
nom = "^7.1"
|
||||
|
|
82
src/entry.rs
Normal file
82
src/entry.rs
Normal file
|
@ -0,0 +1,82 @@
|
|||
use nom::bytes::streaming::{tag, take_till1, take_while1};
|
||||
use nom::IResult;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Entry {
|
||||
session_id: String,
|
||||
token: String,
|
||||
data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Entry {
|
||||
pub fn get_session_id(&self) -> &str {
|
||||
&self.session_id
|
||||
}
|
||||
|
||||
pub fn get_token(&self) -> &str {
|
||||
&self.token
|
||||
}
|
||||
|
||||
pub fn get_data(&self) -> &[u8] {
|
||||
&self.data
|
||||
}
|
||||
|
||||
pub fn is_end_of_message(&self) -> bool {
|
||||
self.data == vec![b'.']
|
||||
}
|
||||
|
||||
pub fn from_bytes(input: &[u8]) -> Result<Entry, String> {
|
||||
let (_, entry) = parse_entry(input).map_err(|e| format!("parsing error: {e}"))?;
|
||||
Ok(entry)
|
||||
}
|
||||
}
|
||||
|
||||
fn is_eol(c: u8) -> bool {
|
||||
c == b'\n'
|
||||
}
|
||||
|
||||
fn is_body_char(c: u8) -> bool {
|
||||
!(c as char).is_control()
|
||||
}
|
||||
|
||||
fn is_parameter_char(c: u8) -> bool {
|
||||
is_body_char(c) && (c as char) != '|'
|
||||
}
|
||||
|
||||
fn parse_string_parameter(input: &[u8]) -> IResult<&[u8], String> {
|
||||
let (input, s) = take_while1(is_parameter_char)(input)?;
|
||||
Ok((input, String::from_utf8(s.to_vec()).unwrap()))
|
||||
}
|
||||
|
||||
fn parse_delimiter(input: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
tag("|")(input)
|
||||
}
|
||||
|
||||
fn parse_data(input: &[u8]) -> IResult<&[u8], Vec<u8>> {
|
||||
let (input, s) = take_till1(is_eol)(input)?;
|
||||
Ok((input, s.to_vec()))
|
||||
}
|
||||
|
||||
fn parse_entry(input: &[u8]) -> IResult<&[u8], Entry> {
|
||||
let (input, _type) = tag("filter")(input)?;
|
||||
let (input, _) = parse_delimiter(input)?;
|
||||
let (input, _version) = parse_string_parameter(input)?;
|
||||
let (input, _) = parse_delimiter(input)?;
|
||||
let (input, _timestamp) = parse_string_parameter(input)?;
|
||||
let (input, _) = parse_delimiter(input)?;
|
||||
let (input, _subsystem) = tag("smtp-in")(input)?;
|
||||
let (input, _) = parse_delimiter(input)?;
|
||||
let (input, _phase) = tag("data-line")(input)?;
|
||||
let (input, _) = parse_delimiter(input)?;
|
||||
let (input, session_id) = parse_string_parameter(input)?;
|
||||
let (input, _) = parse_delimiter(input)?;
|
||||
let (input, token) = parse_string_parameter(input)?;
|
||||
let (input, _) = parse_delimiter(input)?;
|
||||
let (input, data) = parse_data(input)?;
|
||||
let entry = Entry {
|
||||
session_id,
|
||||
token,
|
||||
data,
|
||||
};
|
||||
Ok((input, entry))
|
||||
}
|
|
@ -6,7 +6,9 @@ pub fn read_config() {
|
|||
let stdin = std::io::stdin();
|
||||
loop {
|
||||
buffer.clear();
|
||||
stdin.read_line(&mut buffer).unwrap();
|
||||
if stdin.read_line(&mut buffer).unwrap() == 0 {
|
||||
crate::eof();
|
||||
}
|
||||
let entry = buffer.trim_end();
|
||||
if entry == CONFIG_END {
|
||||
return;
|
||||
|
|
33
src/main.rs
33
src/main.rs
|
@ -1,6 +1,39 @@
|
|||
mod entry;
|
||||
mod handshake;
|
||||
|
||||
use entry::Entry;
|
||||
use std::io::{BufRead, BufReader};
|
||||
|
||||
const DEFAULT_BUFF_SIZE: usize = 1024;
|
||||
|
||||
fn main() {
|
||||
handshake::read_config();
|
||||
handshake::register_filter();
|
||||
loop {
|
||||
match read_line() {
|
||||
Ok(entry) => {
|
||||
if !entry.is_end_of_message() {
|
||||
println!("Debug: {entry:?}");
|
||||
} else {
|
||||
println!("Debug: end of message: {entry:?}");
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("{err}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_line() -> Result<Entry, String> {
|
||||
let mut buffer = Vec::with_capacity(DEFAULT_BUFF_SIZE);
|
||||
let mut stdin = BufReader::new(std::io::stdin());
|
||||
if stdin.read_until(b'\n', &mut buffer).unwrap() == 0 {
|
||||
crate::eof();
|
||||
}
|
||||
Entry::from_bytes(&buffer)
|
||||
}
|
||||
|
||||
fn eof() {
|
||||
std::process::exit(0x2a)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue