1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
use std::io::{BufRead, BufReader};
use std::net::Shutdown;
use std::os::fd::FromRawFd;
use std::os::unix::net::UnixStream;
use std::str::FromStr;
use varlink::{ConnectionHandler, ErrorKind, Stream, VarlinkService};
mod cmd;
#[path = "de_jmhoffmann_jwebmail_mail-storage.rs"]
mod de_jmhoffmann_jwebmail_mailstorage;
mod rfc822;
use cmd::MailStorage;
fn main() {
simplelog::TermLogger::init(
simplelog::LevelFilter::Info,
simplelog::Config::default(),
simplelog::TerminalMode::Stderr,
simplelog::ColorChoice::Never,
)
.unwrap();
let mail_storage = MailStorage::default();
let myinterface = de_jmhoffmann_jwebmail_mailstorage::new(Box::new(mail_storage));
let service = VarlinkService::new(
"de.jmhoffmann.jwebmail.mail-storage.varlink",
"jwebmails storage service",
"1.0.1",
"https://fehcom.de/cgit/jwebmail2/",
vec![Box::new(myinterface)],
);
if let Ok(listen_fds) = std::env::var("LISTEN_FDS") {
let lfds = u8::from_str(&listen_fds).expect("env variable `LISTEN_FDS` must be an integer");
if lfds < 1 {
log::error!("No file descriptor to receive commands from!");
return;
} else if lfds == 1 {
let uds = unsafe { UnixStream::from_raw_fd(3) };
accept_con(&service, uds);
} else {
let listen_fdnames = std::env::var("LISTEN_FDNAMES")
.expect("when multiple `LISTEN_FDS` are available `LISTEN_FDNAMES` must be set");
listen_fdnames
.split(':')
.enumerate()
.filter(|(_, name)| *name == "varlink")
.take(1)
.for_each(|(i, _)| {
accept_con(&service, unsafe { UnixStream::from_raw_fd(3 + i as i32) })
});
}
} else {
log::error!("No file descriptor to receive commands from!");
}
}
/// mostly a copy from varlink::listen
fn accept_con(service: &VarlinkService, mut uds: UnixStream) {
let (r, mut w) = uds.split().unwrap();
let mut br = BufReader::new(r);
let mut iface: Option<String> = None;
loop {
match service.handle(&mut br, &mut w, iface.clone()) {
Ok((_, i)) => {
iface = i;
match br.fill_buf() {
Err(_) => break,
Ok(buf) if buf.is_empty() => break,
_ => {}
}
}
Err(err) => {
match err.kind() {
ErrorKind::ConnectionClosed | ErrorKind::SerdeJsonDe(_) => {}
_ => {
eprintln!("Worker error: {:?}", err);
}
}
let _ = uds.shutdown(Shutdown::Both);
break;
}
}
}
}
|