return -1;
}
-/** Try to read a single LF-terminated line from <b>buf</b>, and write it,
- * NUL-terminated, into the *<b>data_len</b> byte buffer at <b>data_out</b>.
- * Set *<b>data_len</b> to the number of bytes in the line, not counting the
- * terminating NUL. Return 1 if we read a whole line, return 0 if we don't
- * have a whole line yet, and return -1 if the line length exceeds
- * *<b>data_len</b>.
+/** Try to read a single LF-terminated line from <b>buf</b>, and write it
+ * (including the LF), NUL-terminated, into the *<b>data_len</b> byte buffer
+ * at <b>data_out</b>. Set *<b>data_len</b> to the number of bytes in the
+ * line, not counting the terminating NUL. Return 1 if we read a whole line,
+ * return 0 if we don't have a whole line yet, and return -1 if the line
+ * length exceeds *<b>data_len</b>.
*/
int
fetch_from_buf_line(buf_t *buf, char *data_out, size_t *data_len)
}
}
+/** As fetch_from_buf_line(), but read from a connection's input buffer. */
+int
+connection_fetch_from_buf_line(connection_t *conn, char *data,
+ size_t *data_len)
+{
+ IF_HAS_BUFFEREVENT(conn, {
+ int r;
+ size_t eol_len=0;
+ struct evbuffer *input = bufferevent_get_input(conn->bufev);
+ struct evbuffer_ptr ptr =
+ evbuffer_search_eol(input, NULL, &eol_len, EVBUFFER_EOL_LF);
+ if (ptr.pos == -1)
+ return 0; /* No EOL found. */
+ if ((size_t)ptr.pos+eol_len >= *data_len) {
+ return -1; /* Too long */
+ }
+ *data_len = ptr.pos+eol_len;
+ r = evbuffer_remove(input, data, ptr.pos+eol_len);
+ tor_assert(r >= 0);
+ data[ptr.pos+eol_len] = '\0';
+ return 1;
+ }) ELSE_IF_NO_BUFFEREVENT {
+ return fetch_from_buf_line(conn->inbuf, data, data_len);
+ }
+}
+
/** Return conn-\>outbuf_flushlen: how many bytes conn wants to flush
* from its outbuf. */
int
int connection_handle_read(connection_t *conn);
int connection_fetch_from_buf(char *string, size_t len, connection_t *conn);
+int connection_fetch_from_buf_line(connection_t *conn, char *data,
+ size_t *data_len);
int connection_wants_to_flush(connection_t *conn);
int connection_outbuf_too_full(connection_t *conn);
/* look for LF-terminated "[DEST ip_addr port]"
* where ip_addr is a dotted-quad and port is in string form */
- err = fetch_from_buf_line(conn->_base.inbuf, tmp_buf, &tlen);
+ err = connection_fetch_from_buf_line(TO_CONN(conn), tmp_buf, &tlen);
if (err == 0)
return 0;
if (err < 0) {
/* First, fetch a line. */
do {
data_len = conn->incoming_cmd_len - conn->incoming_cmd_cur_len;
- r = fetch_from_buf_line(conn->_base.inbuf,
+ r = connection_fetch_from_buf_line(TO_CONN(conn),
conn->incoming_cmd+conn->incoming_cmd_cur_len,
&data_len);
if (r == 0)