MEDIUM: cli: Use the sedesc to report and detect end of processing

It is the same kind of change than for the cache applet. Idea is to use the SE
desc instead of the channel or the SC to report end-of-input, end-of-stream and
errors.

Truncated commands are now reported on error. Other changes are the same than
for the cache applet. We now set SE_FL_EOS flag instead of calling cf_shutr()
and calls to cf_shutw are removed.
diff --git a/src/cli.c b/src/cli.c
index 32b1c2c..1c942e1 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -893,14 +893,12 @@
 	int reql;
 	int len;
 
-	if (unlikely(sc->state == SC_ST_DIS || sc->state == SC_ST_CLO))
+	if (unlikely(se_fl_test(appctx->sedesc, (SE_FL_EOS|SE_FL_ERROR|SE_FL_SHR|SE_FL_SHW))))
 		goto out;
 
 	/* Check if the input buffer is available. */
-	if (res->buf.size == 0) {
-		/* buf.size==0 means we failed to get a buffer and were
-		 * already subscribed to a wait list to get a buffer.
-		 */
+	if (!b_size(&res->buf)) {
+		sc_need_room(sc);
 		goto out;
 	}
 
@@ -913,10 +911,7 @@
 			appctx->cli_level = bind_conf->level;
 		}
 		else if (appctx->st0 == CLI_ST_END) {
-			/* Let's close for real now. We just close the request
-			 * side, the conditions below will complete if needed.
-			 */
-			sc_shutw(sc);
+			se_fl_set(appctx->sedesc, SE_FL_EOS);
 			free_trash_chunk(appctx->chunk);
 			appctx->chunk = NULL;
 			break;
@@ -928,6 +923,7 @@
 			if (!appctx->chunk) {
 				appctx->chunk = alloc_trash_chunk();
 				if (!appctx->chunk) {
+					se_fl_set(appctx->sedesc, SE_FL_ERROR);
 					appctx->st0 = CLI_ST_END;
 					continue;
 				}
@@ -960,6 +956,7 @@
 			if (reql <= 0) { /* closed or EOL not found */
 				if (reql == 0)
 					break;
+				se_fl_set(appctx->sedesc, SE_FL_ERROR);
 				appctx->st0 = CLI_ST_END;
 				continue;
 			}
@@ -987,6 +984,7 @@
 			 */
 			len = reql - 1;
 			if (str[len] != '\n') {
+				se_fl_set(appctx->sedesc, SE_FL_ERROR);
 				appctx->st0 = CLI_ST_END;
 				continue;
 			}
@@ -1143,13 +1141,13 @@
 				break;
 			}
 
-			/* Now we close the output if one of the writers did so,
-			 * or if we're not in interactive mode and the request
-			 * buffer is empty. This still allows pipelined requests
-			 * to be sent in non-interactive mode.
+			/* Now we close the output if we're not in interactive
+			 * mode and the request buffer is empty. This still
+			 * allows pipelined requests to be sent in
+			 * non-interactive mode.
 			 */
-			if (((res->flags & (CF_SHUTW|CF_SHUTW_NOW))) ||
-			   (!(appctx->st1 & APPCTX_CLI_ST1_PROMPT) && !co_data(req) && (!(appctx->st1 & APPCTX_CLI_ST1_PAYLOAD)))) {
+			if (!(appctx->st1 & APPCTX_CLI_ST1_PROMPT) && !co_data(req) && (!(appctx->st1 & APPCTX_CLI_ST1_PAYLOAD))) {
+				se_fl_set(appctx->sedesc, SE_FL_EOI);
 				appctx->st0 = CLI_ST_END;
 				continue;
 			}
@@ -1175,27 +1173,6 @@
 		}
 	}
 
-	if ((res->flags & CF_SHUTR) && (sc->state == SC_ST_EST)) {
-		DPRINTF(stderr, "%s@%d: sc to buf closed. req=%08x, res=%08x, st=%d\n",
-			__FUNCTION__, __LINE__, req->flags, res->flags, sc->state);
-		/* Other side has closed, let's abort if we have no more processing to do
-		 * and nothing more to consume. This is comparable to a broken pipe, so
-		 * we forward the close to the request side so that it flows upstream to
-		 * the client.
-		 */
-		sc_shutw(sc);
-	}
-
-	if ((req->flags & CF_SHUTW) && (sc->state == SC_ST_EST) && (appctx->st0 < CLI_ST_OUTPUT)) {
-		DPRINTF(stderr, "%s@%d: buf to sc closed. req=%08x, res=%08x, st=%d\n",
-			__FUNCTION__, __LINE__, req->flags, res->flags, sc->state);
-		/* We have no more processing to do, and nothing more to send, and
-		 * the client side has closed. So we'll forward this state downstream
-		 * on the response buffer.
-		 */
-		sc_shutr(sc);
-	}
-
  out:
 	DPRINTF(stderr, "%s@%d: st=%d, rqf=%x, rpf=%x, rqh=%lu, rqs=%lu, rh=%lu, rs=%lu\n",
 		__FUNCTION__, __LINE__,