return (nread);
}
+/*
+ * Reads a line terminated by either '\r\n', '\n\r' or '\r' or '\n'.
+ * The returned buffer needs to be freed by the called.
+ */
+
+char *
+evbuffer_readline(struct evbuffer *buffer)
+{
+ char *data = EVBUFFER_DATA(buffer);
+ size_t len = EVBUFFER_LENGTH(buffer);
+ char *line;
+ int i;
+
+ for (i = 0; i < len; i++) {
+ if (data[i] == '\r' || data[i] == '\n')
+ break;
+ }
+
+ if (i == len)
+ return (NULL);
+
+ if ((line = malloc(i + 1)) == NULL) {
+ fprintf(stderr, "%s: out of memory\n", __func__);
+ evbuffer_drain(buffer, i);
+ return (NULL);
+ }
+
+ memcpy(line, data, i);
+ line[i] = '\0';
+
+ /*
+ * Some protocols terminate a line with '\r\n', so check for
+ * that, too.
+ */
+ if ( i < len - 1 ) {
+ char fch = data[i], sch = data[i+1];
+
+ /* Drain one more character if needed */
+ if ( (sch == '\r' || sch == '\n') && sch != fch )
+ i += 1;
+ }
+
+ evbuffer_drain(buffer, i + 1);
+
+ return (line);
+}
+
/* Adds data to an event buffer */
static inline void
int evbuffer_expand(struct evbuffer *, size_t);
int evbuffer_add(struct evbuffer *, void *, size_t);
int evbuffer_remove(struct evbuffer *, void *, size_t);
+char *evbuffer_readline(struct evbuffer *);
int evbuffer_add_buffer(struct evbuffer *, struct evbuffer *);
int evbuffer_add_printf(struct evbuffer *, char *fmt, ...);
void evbuffer_drain(struct evbuffer *, size_t);