[MINOR] stats_dump_errors_to_buffer: use buffer_feed_chunk()

We can simplify the code in the stats functions using buffer_feed_chunk()
instead of buffer_write_chunk(). Let's start with this function. This
patch also fixed an issue where we could dump past the end of the capture
buffer if it is shorter than the captured request.
diff --git a/include/proto/dumpstats.h b/include/proto/dumpstats.h
index 7a92c98..4dd9e34 100644
--- a/include/proto/dumpstats.h
+++ b/include/proto/dumpstats.h
@@ -51,7 +51,7 @@
 int stats_dump_http(struct session *s, struct buffer *rep, struct uri_auth *uri);
 int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri);
 void stats_dump_sess_to_buffer(struct session *s, struct buffer *rep);
-void stats_dump_errors_to_buffer(struct session *s, struct buffer *rep);
+int stats_dump_errors_to_buffer(struct session *s, struct buffer *rep);
 
 
 #endif /* _PROTO_DUMPSTATS_H */
diff --git a/src/dumpstats.c b/src/dumpstats.c
index 8b95933..6c8c97b 100644
--- a/src/dumpstats.c
+++ b/src/dumpstats.c
@@ -429,9 +429,7 @@
 					si->st0 = 1; // end of command, send prompt
 				break;
 			case 5:	/* errors dump */
-				stats_dump_errors_to_buffer(s, res);
-				si->ib->flags |= BF_READ_PARTIAL; /* remove this once we use buffer_feed */
-				if (s->ana_state == STATS_ST_CLOSE)
+				if (stats_dump_errors_to_buffer(s, res))
 					si->st0 = 1; // end of command, send prompt
 				break;
 			default: /* abnormal state or lack of space for prompt */
@@ -1738,7 +1736,7 @@
 
 	chunk_printf(out, "  %05d%c ", ptr, (ptr == *line) ? ' ' : '+');
 
-	while (ptr < err->len) {
+	while (ptr < err->len && ptr < sizeof(err->buf)) {
 		c = err->buf[ptr];
 		if (isprint(c) && isascii(c) && c != '\\') {
 			if (out->len > end - 2)
@@ -1780,22 +1778,15 @@
  * It dumps the errors logged in proxies onto the output buffer <rep>.
  * Expects to be called with client socket shut down on input.
  * s->data_ctx must have been zeroed first, and the flags properly set.
- * It automatically clears the HIJACK bit from the response buffer.
+ * It returns 0 as long as it does not complete, non-zero upon completion.
  */
-void stats_dump_errors_to_buffer(struct session *s, struct buffer *rep)
+int stats_dump_errors_to_buffer(struct session *s, struct buffer *rep)
 {
 	extern const char *monthname[12];
 	struct chunk msg;
 
-	if (unlikely(rep->flags & (BF_WRITE_ERROR|BF_SHUTW))) {
-		s->data_state = DATA_ST_FIN;
-		buffer_stop_hijack(rep);
-		s->ana_state = STATS_ST_CLOSE;
-		return;
-	}
-
-	if (s->ana_state != STATS_ST_REP)
-		return;
+	if (unlikely(rep->flags & (BF_WRITE_ERROR|BF_SHUTW)))
+		return 1;
 
 	chunk_init(&msg, trash, sizeof(trash));
 
@@ -1874,9 +1865,9 @@
 				break;
 			}
 
-			if (buffer_write_chunk(rep, &msg) >= 0) {
+			if (buffer_feed_chunk(rep, &msg) >= 0) {
 				/* Socket buffer full. Let's try again later from the same point */
-				return;
+				return 0;
 			}
 			s->data_ctx.errors.ptr = 0;
 			s->data_ctx.errors.sid = es->sid;
@@ -1886,24 +1877,24 @@
 			/* the snapshot changed while we were dumping it */
 			chunk_printf(&msg,
 				     "  WARNING! update detected on this snapshot, dump interrupted. Please re-check!\n");
-			if (buffer_write_chunk(rep, &msg) >= 0)
-				return;
+			if (buffer_feed_chunk(rep, &msg) >= 0)
+				return 0;
 			goto next;
 		}
 
 		/* OK, ptr >= 0, so we have to dump the current line */
-		while (s->data_ctx.errors.ptr < es->len) {
+		while (s->data_ctx.errors.ptr < es->len && s->data_ctx.errors.ptr < sizeof(es->buf)) {
 			int newptr;
 			int newline;
 
 			newline = s->data_ctx.errors.bol;
 			newptr = dump_error_line(&msg, es, &newline, s->data_ctx.errors.ptr);
 			if (newptr == s->data_ctx.errors.ptr)
-				return;
+				return 0;
 
-			if (buffer_write_chunk(rep, &msg) >= 0) {
+			if (buffer_feed_chunk(rep, &msg) >= 0) {
 				/* Socket buffer full. Let's try again later from the same point */
-				return;
+				return 0;
 			}
 			s->data_ctx.errors.ptr = newptr;
 			s->data_ctx.errors.bol = newline;
@@ -1919,8 +1910,7 @@
 	}
 
 	/* dump complete */
-	buffer_stop_hijack(rep);
-	s->ana_state = STATS_ST_CLOSE;
+	return 1;
 }