[tor-commits] [tor/master] Factor out control reply output

dgoulet at torproject.org dgoulet at torproject.org
Fri May 3 14:57:34 UTC 2019


commit 61976a4b1ca5dc9c7f9494ee3bf17a96c1182cf0
Author: Taylor Yu <catalyst at torproject.org>
Date:   Tue Apr 9 12:22:31 2019 -0500

    Factor out control reply output
    
    Create a set of abstractions for controller commands and events to
    output replies to the control channel.  The control protocol has a
    relatively consistent SMTP-like structure, so it's helpful when code
    that implements control commands and events doesn't explicitly format
    everything on its own.
---
 src/feature/control/control_proto.c | 106 ++++++++++++++++++++++++++++++++++++
 src/feature/control/control_proto.h |  24 ++++++++
 2 files changed, 130 insertions(+)

diff --git a/src/feature/control/control_proto.c b/src/feature/control/control_proto.c
index 4756a0263..7bd237de9 100644
--- a/src/feature/control/control_proto.c
+++ b/src/feature/control/control_proto.c
@@ -168,3 +168,109 @@ send_control_done(control_connection_t *conn)
 {
   connection_write_str_to_buf("250 OK\r\n", conn);
 }
+
+/** Write a reply to the control channel.
+ *
+ * @param conn control connection
+ * @param code numeric result code
+ * @param c separator character, usually ' ', '-', or '+'
+ * @param s string
+ */
+void
+control_write_reply(control_connection_t *conn, int code, int c, const char *s)
+{
+  connection_printf_to_buf(conn, "%03d%c%s\r\n", code, c, s);
+}
+
+/** Write a formatted reply to the control channel.
+ *
+ * @param conn control connection
+ * @param code numeric result code
+ * @param c separator character, usually ' ', '-', or '+'
+ * @param fmt format string
+ * @param ap va_list from caller
+ */
+void
+control_vprintf_reply(control_connection_t *conn, int code, int c,
+                      const char *fmt, va_list ap)
+{
+  char *buf = NULL;
+  int len;
+
+  len = tor_vasprintf(&buf, fmt, ap);
+  if (len < 0) {
+    log_err(LD_BUG, "Unable to format string for controller.");
+    tor_assert(0);
+  }
+  control_write_reply(conn, code, c, buf);
+  tor_free(buf);
+}
+
+/** Write an EndReplyLine */
+void
+control_write_endreply(control_connection_t *conn, int code, const char *s)
+{
+  control_write_reply(conn, code, ' ', s);
+}
+
+/** Write a formatted EndReplyLine */
+void
+control_printf_endreply(control_connection_t *conn, int code,
+                        const char *fmt, ...)
+{
+  va_list ap;
+
+  va_start(ap, fmt);
+  control_vprintf_reply(conn, code, ' ', fmt, ap);
+  va_end(ap);
+}
+
+/** Write a MidReplyLine */
+void
+control_write_midreply(control_connection_t *conn, int code, const char *s)
+{
+  control_write_reply(conn, code, '-', s);
+}
+
+/** Write a formatted MidReplyLine */
+void
+control_printf_midreply(control_connection_t *conn, int code, const char *fmt,
+                        ...)
+{
+  va_list ap;
+
+  va_start(ap, fmt);
+  control_vprintf_reply(conn, code, '-', fmt, ap);
+  va_end(ap);
+}
+
+/** Write a DataReplyLine */
+void
+control_write_datareply(control_connection_t *conn, int code, const char *s)
+{
+  control_write_reply(conn, code, '+', s);
+}
+
+/** Write a formatted DataReplyLine */
+void
+control_printf_datareply(control_connection_t *conn, int code, const char *fmt,
+                         ...)
+{
+  va_list ap;
+
+  va_start(ap, fmt);
+  control_vprintf_reply(conn, code, '+', fmt, ap);
+  va_end(ap);
+}
+
+/** Write a CmdData */
+void
+control_write_data(control_connection_t *conn, const char *data)
+{
+  char *esc = NULL;
+  size_t esc_len;
+
+  esc_len = write_escaped_data(data, strlen(data), &esc);
+  connection_buf_add(esc, esc_len, TO_CONN(conn));
+  tor_free(esc);
+}
diff --git a/src/feature/control/control_proto.h b/src/feature/control/control_proto.h
index 5720b2260..101b808d8 100644
--- a/src/feature/control/control_proto.h
+++ b/src/feature/control/control_proto.h
@@ -21,4 +21,28 @@ size_t write_escaped_data(const char *data, size_t len, char **out);
 size_t read_escaped_data(const char *data, size_t len, char **out);
 void send_control_done(control_connection_t *conn);
 
+void control_write_reply(control_connection_t *conn, int code, int c,
+                         const char *s);
+void control_vprintf_reply(control_connection_t *conn, int code, int c,
+                           const char *fmt, va_list ap)
+  CHECK_PRINTF(4, 0);
+void control_write_endreply(control_connection_t *conn, int code,
+                            const char *s);
+void control_printf_endreply(control_connection_t *conn, int code,
+                             const char *fmt, ...)
+  CHECK_PRINTF(3, 4);
+void control_write_midreply(control_connection_t *conn, int code,
+                            const char *s);
+void control_printf_midreply(control_connection_t *conn, int code,
+                             const char *fmt,
+                             ...)
+  CHECK_PRINTF(3, 4);
+void control_write_datareply(control_connection_t *conn, int code,
+                             const char *s);
+void control_printf_datareply(control_connection_t *conn, int code,
+                              const char *fmt,
+                              ...)
+  CHECK_PRINTF(3, 4);
+void control_write_data(control_connection_t *conn, const char *data);
+
 #endif /* !defined(TOR_CONTROL_PROTO_H) */





More information about the tor-commits mailing list