use std::{ffi::CString, path::Path};
use crate::core::SC;
use suricata_sys::sys::{SCFatalErrorOnInitStatic, SCLogLevel};
pub static mut LEVEL: SCLogLevel = SCLogLevel::SC_LOG_NOTSET;
#[no_mangle]
pub unsafe extern "C" fn SCSetRustLogLevel(level: SCLogLevel) {
LEVEL = level;
}
fn basename(filename: &str) -> &str {
let path = Path::new(filename);
if let Some(os_str) = path.file_name() {
if let Some(basename) = os_str.to_str() {
return basename;
}
}
return filename;
}
pub fn fatalerror(message: &str) {
unsafe {
SCFatalErrorOnInitStatic(to_safe_cstring(message).as_ptr());
}
}
pub fn sclog(level: SCLogLevel, file: &str, line: u32, function: &str, message: &str) {
let filename = basename(file);
let noext = &filename[0..filename.len() - 3];
sc_log_message(level, filename, line, function, noext, message);
}
pub fn sc_log_message(
level: SCLogLevel, filename: &str, line: std::os::raw::c_uint, function: &str, module: &str,
message: &str,
) -> std::os::raw::c_int {
unsafe {
if let Some(c) = SC {
return (c.SCLogMessage)(
level,
to_safe_cstring(filename).as_ptr(),
line,
to_safe_cstring(function).as_ptr(),
to_safe_cstring(module).as_ptr(),
to_safe_cstring(message).as_ptr(),
);
}
}
println!("{}:{} <{:?}> -- {}", filename, line, level, message);
return 0;
}
fn to_safe_cstring(val: &str) -> CString {
let mut safe = Vec::with_capacity(val.len());
for c in val.as_bytes() {
if *c != 0 {
safe.push(*c);
}
}
match CString::new(safe) {
Ok(cstr) => cstr,
_ => CString::new("<failed to encode string>").unwrap(),
}
}
#[macro_export(local_inner_macros)]
macro_rules! function {
() => {{
fn __f() {}
fn type_name_of<T>(_: T) -> &'static str {
std::any::type_name::<T>()
}
let name = type_name_of(__f);
&name[..name.len() - 5]
}};
}
#[macro_export]
macro_rules!do_log {
($level:expr, $($arg:tt)*) => {
#[allow(unused_unsafe)]
if unsafe { $crate::debug::LEVEL as i32 } >= $level as i32 {
$crate::debug::sclog($level, file!(), line!(), $crate::function!(),
&(format!($($arg)*)));
}
}
}
#[macro_export]
macro_rules!SCLogError {
($($arg:tt)*) => {
$crate::do_log!(suricata_sys::sys::SCLogLevel::SC_LOG_ERROR, $($arg)*);
};
}
#[macro_export]
macro_rules!SCLogWarning {
($($arg:tt)*) => {
$crate::do_log!(suricata_sys::sys::SCLogLevel::SC_LOG_WARNING, $($arg)*);
};
}
#[macro_export]
macro_rules!SCLogNotice {
($($arg:tt)*) => {
$crate::do_log!(suricata_sys::sys::SCLogLevel::SC_LOG_NOTICE, $($arg)*);
}
}
#[macro_export]
macro_rules!SCLogInfo {
($($arg:tt)*) => {
$crate::do_log!(suricata_sys::sys::SCLogLevel::SC_LOG_INFO, $($arg)*);
}
}
#[macro_export]
macro_rules!SCLogPerf {
($($arg:tt)*) => {
$crate::do_log!(suricata_sys::sys::SCLogLevel::SC_LOG_PERF, $($arg)*);
}
}
#[macro_export]
macro_rules!SCLogConfig {
($($arg:tt)*) => {
$crate::do_log!(suricata_sys::sys::SCLogLevel::SC_LOG_CONFIG, $($arg)*);
}
}
#[cfg(feature = "debug")]
#[macro_export]
macro_rules!SCLogDebug {
($($arg:tt)*) => {
do_log!(suricata_sys::sys::SCLogLevel::SC_LOG_DEBUG, $($arg)*);
}
}
#[cfg(not(feature = "debug"))]
#[macro_export]
macro_rules! SCLogDebug {
($($arg:tt)*) => {};
}
#[macro_export]
macro_rules!SCFatalErrorOnInit {
($($arg:tt)*) => {
$crate::debug::fatalerror(&format!($($arg)*));
}
}
#[cfg(not(feature = "debug-validate"))]
#[macro_export]
macro_rules! debug_validate_bug_on (
($item:expr) => {};
);
#[cfg(feature = "debug-validate")]
#[macro_export]
macro_rules! debug_validate_bug_on (
($item:expr) => {
if $item {
panic!("Condition check failed");
}
};
);
#[cfg(not(feature = "debug-validate"))]
#[macro_export]
macro_rules! debug_validate_fail (
($msg:expr) => {};
);
#[cfg(feature = "debug-validate")]
#[macro_export]
macro_rules! debug_validate_fail (
($msg:expr) => {
if true {
panic!($msg);
}
};
);
#[macro_export]
macro_rules! unwrap_or_return (
($e:expr, $r:expr) => {
match $e {
Ok(x) => x,
Err(_) => return $r,
}
};
);