summaryrefslogtreecommitdiff
path: root/src/sock.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/sock.rs')
-rw-r--r--src/sock.rs72
1 files changed, 46 insertions, 26 deletions
diff --git a/src/sock.rs b/src/sock.rs
index faccb46..42a5d90 100644
--- a/src/sock.rs
+++ b/src/sock.rs
@@ -164,6 +164,26 @@ pub struct BootstrapStatus {
// TODO: warning/reason/count/recommendation
}
+impl BootstrapStatus {
+ // Parses the part after the severity and "BOOTSTRAP " string.
+ fn parse(sev: Severity, buf: &mut &str) -> Result<Box<BootstrapStatus>> {
+ let mut bs = Box::new(BootstrapStatus {
+ severity: sev,
+ progress: 0,
+ tag: String::new(),
+ summary: String::new(),
+ });
+ // TODO: Can the order of these arguments change?
+ cons(buf, "PROGRESS=")?;
+ bs.progress = cons_u8(buf)?;
+ cons(buf, " TAG=")?;
+ bs.tag = cons_keyword(buf)?.to_owned();
+ cons(buf, " SUMMARY=")?;
+ bs.summary = QuotedString::parse(buf)?;
+ Ok(bs)
+ }
+}
+
/// Tor log message severity.
#[derive(Debug,PartialEq,Eq,PartialOrd,Ord,Clone,Copy)]
@@ -175,6 +195,17 @@ pub enum Severity {
Err
}
+impl Severity {
+ fn parse(buf: &mut &str) -> Result<Severity> {
+ if cons(buf, "DEBUG" ).is_ok() { Ok(Severity::Debug ) }
+ else if cons(buf, "INFO" ).is_ok() { Ok(Severity::Info ) }
+ else if cons(buf, "NOTICE").is_ok() { Ok(Severity::Notice) }
+ else if cons(buf, "WARN" ).is_ok() { Ok(Severity::Warn ) }
+ else if cons(buf, "ERR" ).is_ok() { Ok(Severity::Err ) }
+ else { Err(err!(Parse)) }
+ }
+}
+
/// An asynchronous event received from Tor. These are returned by `read_event()`.
#[derive(Debug)]
@@ -543,27 +574,29 @@ impl Sock {
Ok(res)
}
+ /// Returns the latest bootstrap status. This is a convenience wrapper around
+ /// `getinfo(&["status/bootstrap-phase"])`.
+ pub fn bootstrap_status(&self) -> Result<Box<BootstrapStatus>> {
+ let ret = self.getinfo(&["status/bootstrap-phase"])?;
+ let mut buf = &ret[0].1[..];
+ let sev = Severity::parse(&mut buf)?;
+ cons(&mut buf, " BOOTSTRAP ")?;
+ BootstrapStatus::parse(sev, &mut buf)
+ }
+
pub fn setevents(&self, events: EventList) -> Result<()> {
self.cmd(events.cmd()).map(|_|())
}
/// Read an event from the socket. This method blocks until an event has been received.
+ // TODO: Differentiate between fatal and temporary errors.
pub fn read_event(&self) -> Result<Event> {
- fn extract_sev(buf: &mut &str) -> Result<Severity> {
- if cons(buf, "DEBUG " ).is_ok() { Ok(Severity::Debug ) }
- else if cons(buf, "INFO " ).is_ok() { Ok(Severity::Info ) }
- else if cons(buf, "NOTICE ").is_ok() { Ok(Severity::Notice) }
- else if cons(buf, "WARN " ).is_ok() { Ok(Severity::Warn ) }
- else if cons(buf, "ERR " ).is_ok() { Ok(Severity::Err ) }
- else { Err(err!(Parse)) }
- }
-
loop {
let mut ret = self.get_reply(true)?;
let ev = ret.remove(0);
let mut buf = &ev.text[..];
- if let Ok(sev) = extract_sev(&mut buf) {
+ if let Ok(sev) = Severity::parse(&mut buf) {
let s = if ev.data.is_empty() {
buf.trim().to_owned()
} else {
@@ -572,22 +605,9 @@ impl Sock {
return Ok(Event::Log(sev, s))
} else if cons(&mut buf, "STATUS_CLIENT ").is_ok() {
- let sev = extract_sev(&mut buf)?;
- if cons(&mut buf, "BOOTSTRAP ").is_ok() {
- let mut bs = Box::new(BootstrapStatus {
- severity: sev,
- progress: 0,
- tag: String::new(),
- summary: String::new(),
- });
- // TODO: Can the order of these arguments change?
- cons(&mut buf, "PROGRESS=")?;
- bs.progress = cons_u8(&mut buf)?;
- cons(&mut buf, " TAG=")?;
- bs.tag = cons_keyword(&mut buf)?.to_owned();
- cons(&mut buf, " SUMMARY=")?;
- bs.summary = QuotedString::parse(&mut buf)?;
- return Ok(Event::Bootstrap(bs))
+ let sev = Severity::parse(&mut buf)?;
+ if cons(&mut buf, " BOOTSTRAP ").is_ok() {
+ return Ok(Event::Bootstrap(BootstrapStatus::parse(sev, &mut buf)?))
}
}
}