diff options
author | Taylor Yu <catalyst@torproject.org> | 2019-04-09 12:22:31 -0500 |
---|---|---|
committer | Taylor Yu <catalyst@torproject.org> | 2019-04-30 13:18:46 -0500 |
commit | 61976a4b1ca5dc9c7f9494ee3bf17a96c1182cf0 (patch) | |
tree | 3ba92d054ad6d2a55d9d1089dabd552f61f0c596 /src/feature/control/control_proto.c | |
parent | 482437754a7a30b651f096d4432a42aa61bd3b17 (diff) | |
download | tor-61976a4b1ca5dc9c7f9494ee3bf17a96c1182cf0.tar.gz tor-61976a4b1ca5dc9c7f9494ee3bf17a96c1182cf0.zip |
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.
Diffstat (limited to 'src/feature/control/control_proto.c')
-rw-r--r-- | src/feature/control/control_proto.c | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/src/feature/control/control_proto.c b/src/feature/control/control_proto.c index 4756a02632..7bd237de94 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); +} |