Skip to content

Commit

Permalink
Add async get_version
Browse files Browse the repository at this point in the history
  • Loading branch information
toblux committed Mar 11, 2024
1 parent e4de98d commit 17741eb
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 10 deletions.
51 changes: 46 additions & 5 deletions src/async_std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,29 @@ use async_trait::async_trait;
#[cfg(unix)]
use async_std::os::unix::net::UnixStream;

use super::{IoResult, DEFAULT_CHUNK_SIZE, END_OF_STREAM, INSTREAM, PING, PONG};
use super::{IoResult, DEFAULT_CHUNK_SIZE, END_OF_STREAM, INSTREAM, PING, PONG, VERSION};

async fn _ping<RW: ReadExt + WriteExt + Unpin>(mut stream: RW) -> IoResult {
stream.write_all(PING).await?;
async fn send_command<RW: ReadExt + WriteExt + Unpin>(
mut stream: RW,
command: &[u8],
expected_response_length: Option<usize>,
) -> IoResult {
stream.write_all(command).await?;
stream.flush().await?;

let capacity = PONG.len();
let mut response = Vec::with_capacity(capacity);
let mut response = match expected_response_length {
Some(len) => Vec::with_capacity(len),
None => Vec::new(),
};

stream.read_to_end(&mut response).await?;
Ok(response)
}

async fn _ping<RW: ReadExt + WriteExt + Unpin>(stream: RW) -> IoResult {
send_command(stream, PING, Some(PONG.len())).await
}

async fn scan<R: ReadExt + Unpin, RW: ReadExt + WriteExt + Unpin>(
mut input: R,
chunk_size: Option<usize>,
Expand Down Expand Up @@ -347,6 +358,36 @@ pub async fn ping<T: AsyncTransportProtocol>(transport_protocol: T) -> IoResult
_ping(stream).await
}

/// Gets the version number from ClamAV
///
/// This function establishes a connection to a ClamAV server and sends the
/// VERSION command to it. If the server is available, it responds with its
/// version number.
///
/// # Arguments
///
/// * `transport_protocol`: The protocol to use (either TCP or a Unix socket connection)
///
/// # Returns
///
/// An [`IoResult`] containing the server's response as a vector of bytes
///
/// # Example
///
/// ```
/// # #[async_std::main]
/// # async fn main() {
/// let transport_protocol = clamav_client::async_std::Tcp("localhost:3310");
/// let version = clamav_client::async_std::get_version(transport_protocol).await.unwrap();
/// # assert!(version.starts_with(b"ClamAV"));
/// # }
/// ```
///
pub async fn get_version<T: AsyncTransportProtocol>(transport_protocol: T) -> IoResult {
let stream = transport_protocol.to_stream().await?;
send_command(stream, VERSION, None).await
}

/// Scans a file for viruses
///
/// This function reads data from a file located at the specified `file_path`
Expand Down
51 changes: 46 additions & 5 deletions src/tokio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,29 @@ use tokio::net::UnixStream;
#[cfg(feature = "tokio-stream")]
use tokio_stream::{Stream, StreamExt};

use super::{IoResult, DEFAULT_CHUNK_SIZE, END_OF_STREAM, INSTREAM, PING, PONG};
use super::{IoResult, DEFAULT_CHUNK_SIZE, END_OF_STREAM, INSTREAM, PING, PONG, VERSION};

async fn _ping<RW: AsyncRead + AsyncWrite + Unpin>(mut stream: RW) -> IoResult {
stream.write_all(PING).await?;
async fn send_command<RW: AsyncRead + AsyncWrite + Unpin>(
mut stream: RW,
command: &[u8],
expected_response_length: Option<usize>,
) -> IoResult {
stream.write_all(command).await?;
stream.flush().await?;

let capacity = PONG.len();
let mut response = Vec::with_capacity(capacity);
let mut response = match expected_response_length {
Some(len) => Vec::with_capacity(len),
None => Vec::new(),
};

stream.read_to_end(&mut response).await?;
Ok(response)
}

async fn _ping<RW: AsyncRead + AsyncWrite + Unpin>(stream: RW) -> IoResult {
send_command(stream, PING, Some(PONG.len())).await
}

async fn scan<R: AsyncRead + Unpin, RW: AsyncRead + AsyncWrite + Unpin>(
mut input: R,
chunk_size: Option<usize>,
Expand Down Expand Up @@ -359,6 +370,36 @@ pub async fn ping<T: AsyncTransportProtocol>(transport_protocol: T) -> IoResult
_ping(stream).await
}

/// Gets the version number from ClamAV
///
/// This function establishes a connection to a ClamAV server and sends the
/// VERSION command to it. If the server is available, it responds with its
/// version number.
///
/// # Arguments
///
/// * `transport_protocol`: The protocol to use (either TCP or a Unix socket connection)
///
/// # Returns
///
/// An [`IoResult`] containing the server's response as a vector of bytes
///
/// # Example
///
/// ```
/// # #[tokio::main(flavor = "current_thread")]
/// # async fn main() {
/// let transport_protocol = clamav_client::tokio::Tcp("localhost:3310");
/// let version = clamav_client::tokio::get_version(transport_protocol).await.unwrap();
/// # assert!(version.starts_with(b"ClamAV"));
/// # }
/// ```
///
pub async fn get_version<T: AsyncTransportProtocol>(transport_protocol: T) -> IoResult {
let stream = transport_protocol.to_stream().await?;
send_command(stream, VERSION, None).await
}

/// Scans a file for viruses
///
/// This function reads data from a file located at the specified `file_path`
Expand Down

0 comments on commit 17741eb

Please sign in to comment.