#![doc(html_root_url = "https://docs.rs/milter-sys/0.1.1")]
#![allow(non_camel_case_types)]
use libc::{c_char, c_int, c_uchar, c_uint, c_ulong, c_void, size_t};
pub const SMFI_VERSION: c_int = 0x1000001;
pub const SMFI_PROT_VERSION: c_int = 6;
pub const MILTER_LEN_BYTES: size_t = 4;
pub const MILTER_OPTLEN: size_t = MILTER_LEN_BYTES * 3;
pub const MILTER_CHUNK_SIZE: size_t = 65535;
pub const MILTER_MAX_DATA_SIZE: size_t = 65535;
pub const SMFI_V1_ACTS: c_ulong = 0xf;
pub const SMFI_V2_ACTS: c_ulong = 0x3f;
pub const SMFI_CURR_ACTS: c_ulong = 0x1ff;
pub const SMFIA_UNKNOWN: c_uchar = b'U';
pub const SMFIA_UNIX: c_uchar = b'L';
pub const SMFIA_INET: c_uchar = b'4';
pub const SMFIA_INET6: c_uchar = b'6';
pub const SMFIC_ABORT: c_uchar = b'A';
pub const SMFIC_BODY: c_uchar = b'B';
pub const SMFIC_CONNECT: c_uchar = b'C';
pub const SMFIC_MACRO: c_uchar = b'D';
pub const SMFIC_BODYEOB: c_uchar = b'E';
pub const SMFIC_HELO: c_uchar = b'H';
pub const SMFIC_QUIT_NC: c_uchar = b'K';
pub const SMFIC_HEADER: c_uchar = b'L';
pub const SMFIC_MAIL: c_uchar = b'M';
pub const SMFIC_EOH: c_uchar = b'N';
pub const SMFIC_OPTNEG: c_uchar = b'O';
pub const SMFIC_QUIT: c_uchar = b'Q';
pub const SMFIC_RCPT: c_uchar = b'R';
pub const SMFIC_DATA: c_uchar = b'T';
pub const SMFIC_UNKNOWN: c_uchar = b'U';
pub const SMFIR_ADDRCPT: c_uchar = b'+';
pub const SMFIR_DELRCPT: c_uchar = b'-';
pub const SMFIR_ADDRCPT_PAR: c_uchar = b'2';
pub const SMFIR_SHUTDOWN: c_uchar = b'4';
pub const SMFIR_ACCEPT: c_uchar = b'a';
pub const SMFIR_REPLBODY: c_uchar = b'b';
pub const SMFIR_CONTINUE: c_uchar = b'c';
pub const SMFIR_DISCARD: c_uchar = b'd';
pub const SMFIR_CHGFROM: c_uchar = b'e';
pub const SMFIR_CONN_FAIL: c_uchar = b'f';
pub const SMFIR_ADDHEADER: c_uchar = b'h';
pub const SMFIR_INSHEADER: c_uchar = b'i';
pub const SMFIR_SETSYMLIST: c_uchar = b'l';
pub const SMFIR_CHGHEADER: c_uchar = b'm';
pub const SMFIR_PROGRESS: c_uchar = b'p';
pub const SMFIR_QUARANTINE: c_uchar = b'q';
pub const SMFIR_REJECT: c_uchar = b'r';
pub const SMFIR_SKIP: c_uchar = b's';
pub const SMFIR_TEMPFAIL: c_uchar = b't';
pub const SMFIR_REPLYCODE: c_uchar = b'y';
pub const SMFIP_NOCONNECT: c_ulong = 0x1;
pub const SMFIP_NOHELO: c_ulong = 0x2;
pub const SMFIP_NOMAIL: c_ulong = 0x4;
pub const SMFIP_NORCPT: c_ulong = 0x8;
pub const SMFIP_NOBODY: c_ulong = 0x10;
pub const SMFIP_NOHDRS: c_ulong = 0x20;
pub const SMFIP_NOEOH: c_ulong = 0x40;
pub const SMFIP_NR_HDR: c_ulong = 0x80;
pub const SMFIP_NOHREPL: c_ulong = SMFIP_NR_HDR;
pub const SMFIP_NOUNKNOWN: c_ulong = 0x100;
pub const SMFIP_NODATA: c_ulong = 0x200;
pub const SMFIP_SKIP: c_ulong = 0x400;
pub const SMFIP_RCPT_REJ: c_ulong = 0x800;
pub const SMFIP_NR_CONN: c_ulong = 0x1000;
pub const SMFIP_NR_HELO: c_ulong = 0x2000;
pub const SMFIP_NR_MAIL: c_ulong = 0x4000;
pub const SMFIP_NR_RCPT: c_ulong = 0x8000;
pub const SMFIP_NR_DATA: c_ulong = 0x10000;
pub const SMFIP_NR_UNKN: c_ulong = 0x20000;
pub const SMFIP_NR_EOH: c_ulong = 0x40000;
pub const SMFIP_NR_BODY: c_ulong = 0x80000;
pub const SMFIP_HDR_LEADSPC: c_ulong = 0x100000;
pub const SMFIP_MDS_256K: c_ulong = 0x10000000;
pub const SMFIP_MDS_1M: c_ulong = 0x20000000;
pub const SMFI_V1_PROT: c_ulong = 0x3f;
pub const SMFI_V2_PROT: c_ulong = 0x7f;
pub const SMFI_CURR_PROT: c_ulong = 0x1fffff;
pub const SMFI_INTERNAL: c_ulong = 0x70000000;
pub const MI_SUCCESS: c_int = 0;
pub const MI_FAILURE: c_int = -1;
pub const SMFIF_NONE: c_ulong = 0x0;
pub const SMFIF_ADDHDRS: c_ulong = 0x1;
pub const SMFIF_CHGBODY: c_ulong = 0x2;
pub const SMFIF_MODBODY: c_ulong = SMFIF_CHGBODY;
pub const SMFIF_ADDRCPT: c_ulong = 0x4;
pub const SMFIF_DELRCPT: c_ulong = 0x8;
pub const SMFIF_CHGHDRS: c_ulong = 0x10;
pub const SMFIF_QUARANTINE: c_ulong = 0x20;
pub const SMFIF_CHGFROM: c_ulong = 0x40;
pub const SMFIF_ADDRCPT_PAR: c_ulong = 0x80;
pub const SMFIF_SETSYMLIST: c_ulong = 0x100;
pub const SMFIM_NOMACROS: c_int = -1;
pub const SMFIM_FIRST: c_int = 0;
pub const SMFIM_CONNECT: c_int = 0;
pub const SMFIM_HELO: c_int = 1;
pub const SMFIM_ENVFROM: c_int = 2;
pub const SMFIM_ENVRCPT: c_int = 3;
pub const SMFIM_DATA: c_int = 4;
pub const SMFIM_EOM: c_int = 5;
pub const SMFIM_EOH: c_int = 6;
pub const SMFIM_LAST: c_int = 6;
pub const SMFIS_CONTINUE: c_int = 0;
pub const SMFIS_REJECT: c_int = 1;
pub const SMFIS_DISCARD: c_int = 2;
pub const SMFIS_ACCEPT: c_int = 3;
pub const SMFIS_TEMPFAIL: c_int = 4;
pub const SMFIS_NOREPLY: c_int = 7;
pub const SMFIS_SKIP: c_int = 8;
pub const SMFIS_ALL_OPTS: c_int = 10;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct smfi_str {
_private: [u8; 0],
}
pub type SMFICTX = smfi_str;
pub type SMFICTX_PTR = *mut smfi_str;
pub type smfiDesc_str = smfiDesc;
pub type smfiDesc_ptr = *mut smfiDesc;
pub type sfsistat = c_int;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct smfiDesc {
pub xxfi_name: *mut c_char,
pub xxfi_version: c_int,
pub xxfi_flags: c_ulong,
pub xxfi_connect: Option<unsafe extern "C" fn(ctx: *mut SMFICTX, hostname: *mut c_char, hostaddr: *mut libc::sockaddr) -> sfsistat>,
pub xxfi_helo: Option<unsafe extern "C" fn(ctx: *mut SMFICTX, helohost: *mut c_char) -> sfsistat>,
pub xxfi_envfrom: Option<unsafe extern "C" fn(ctx: *mut SMFICTX, argv: *mut *mut c_char) -> sfsistat>,
pub xxfi_envrcpt: Option<unsafe extern "C" fn(ctx: *mut SMFICTX, argv: *mut *mut c_char) -> sfsistat>,
pub xxfi_header: Option<unsafe extern "C" fn(ctx: *mut SMFICTX, headerf: *mut c_char, headerv: *mut c_char) -> sfsistat>,
pub xxfi_eoh: Option<unsafe extern "C" fn(ctx: *mut SMFICTX) -> sfsistat>,
pub xxfi_body: Option<unsafe extern "C" fn(ctx: *mut SMFICTX, bodyp: *mut c_uchar, bodylen: size_t) -> sfsistat>,
pub xxfi_eom: Option<unsafe extern "C" fn(ctx: *mut SMFICTX) -> sfsistat>,
pub xxfi_abort: Option<unsafe extern "C" fn(ctx: *mut SMFICTX) -> sfsistat>,
pub xxfi_close: Option<unsafe extern "C" fn(ctx: *mut SMFICTX) -> sfsistat>,
pub xxfi_unknown: Option<unsafe extern "C" fn(ctx: *mut SMFICTX, arg: *const c_char) -> sfsistat>,
pub xxfi_data: Option<unsafe extern "C" fn(ctx: *mut SMFICTX) -> sfsistat>,
pub xxfi_negotiate: Option<
unsafe extern "C" fn(
ctx: *mut SMFICTX,
f0: c_ulong,
f1: c_ulong,
f2: c_ulong,
f3: c_ulong,
pf0: *mut c_ulong,
pf1: *mut c_ulong,
pf2: *mut c_ulong,
pf3: *mut c_ulong,
) -> sfsistat,
>,
}
extern "C" {
pub fn smfi_opensocket(rmsocket: c_int) -> c_int;
pub fn smfi_register(descr: smfiDesc) -> c_int;
pub fn smfi_main() -> c_int;
pub fn smfi_setbacklog(obacklog: c_int) -> c_int;
pub fn smfi_setdbg(level: c_int) -> c_int;
pub fn smfi_settimeout(otimeout: c_int) -> c_int;
pub fn smfi_setconn(oconn: *mut c_char) -> c_int;
pub fn smfi_stop() -> c_int;
pub fn smfi_setmaxdatasize(sz: size_t) -> size_t;
pub fn smfi_version(pmajor: *mut c_uint, pminor: *mut c_uint, ppl: *mut c_uint) -> c_int;
pub fn smfi_getsymval(ctx: *mut SMFICTX, symname: *mut c_char) -> *mut c_char;
pub fn smfi_setreply(ctx: *mut SMFICTX, rcode: *mut c_char, xcode: *mut c_char, message: *mut c_char) -> c_int;
pub fn smfi_setmlreply(ctx: *mut SMFICTX, rcode: *const c_char, xcode: *const c_char, ...) -> c_int;
pub fn smfi_addheader(ctx: *mut SMFICTX, headerf: *mut c_char, headerv: *mut c_char) -> c_int;
pub fn smfi_chgheader(ctx: *mut SMFICTX, headerf: *mut c_char, index: c_int, headerv: *mut c_char) -> c_int;
pub fn smfi_insheader(ctx: *mut SMFICTX, index: c_int, headerf: *mut c_char, headerv: *mut c_char) -> c_int;
pub fn smfi_chgfrom(ctx: *mut SMFICTX, mail: *mut c_char, args: *mut c_char) -> c_int;
pub fn smfi_addrcpt(ctx: *mut SMFICTX, rcpt: *mut c_char) -> c_int;
pub fn smfi_addrcpt_par(ctx: *mut SMFICTX, rcpt: *mut c_char, args: *mut c_char) -> c_int;
pub fn smfi_delrcpt(ctx: *mut SMFICTX, rcpt: *mut c_char) -> c_int;
pub fn smfi_progress(ctx: *mut SMFICTX) -> c_int;
pub fn smfi_replacebody(ctx: *mut SMFICTX, bodyp: *mut c_uchar, bodylen: c_int) -> c_int;
pub fn smfi_quarantine(ctx: *mut SMFICTX, reason: *mut c_char) -> c_int;
pub fn smfi_setpriv(ctx: *mut SMFICTX, privatedata: *mut c_void) -> c_int;
pub fn smfi_getpriv(ctx: *mut SMFICTX) -> *mut c_void;
pub fn smfi_setsymlist(ctx: *mut SMFICTX, stage: c_int, macros: *mut c_char) -> c_int;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn all_current_protocol_opts() {
let protocol_opts = SMFIP_NOCONNECT
| SMFIP_NOHELO
| SMFIP_NOMAIL
| SMFIP_NORCPT
| SMFIP_NOBODY
| SMFIP_NOHDRS
| SMFIP_NOEOH
| SMFIP_NR_HDR
| SMFIP_NOUNKNOWN
| SMFIP_NODATA
| SMFIP_SKIP
| SMFIP_RCPT_REJ
| SMFIP_NR_CONN
| SMFIP_NR_HELO
| SMFIP_NR_MAIL
| SMFIP_NR_RCPT
| SMFIP_NR_DATA
| SMFIP_NR_UNKN
| SMFIP_NR_EOH
| SMFIP_NR_BODY
| SMFIP_HDR_LEADSPC;
assert_eq!(protocol_opts, SMFI_CURR_PROT);
}
#[test]
fn smfi_version_returns_version() {
let (mut a, mut b, mut c) = (0, 0, 0);
let result = unsafe { smfi_version(&mut a, &mut b, &mut c) };
assert_eq!(result, MI_SUCCESS);
assert_eq!((a, b, c), (1, 0, 1));
}
#[test]
fn register_milter() {
let desc = smfiDesc {
xxfi_name: "test\0".as_ptr() as _,
xxfi_version: SMFI_VERSION,
xxfi_flags: 0,
xxfi_connect: None,
xxfi_helo: None,
xxfi_envfrom: None,
xxfi_envrcpt: None,
xxfi_header: None,
xxfi_eoh: None,
xxfi_body: None,
xxfi_eom: None,
xxfi_abort: None,
xxfi_close: None,
xxfi_unknown: None,
xxfi_data: None,
xxfi_negotiate: None,
};
let result = unsafe { smfi_register(desc) };
assert_eq!(result, MI_SUCCESS);
}
}