MEDIUM: server: Break out set weight processing code

Break out set weight processing code.
This is in preparation for reusing the code.

Also, remove duplicate check in nested if clauses.
{px->lbprm.algo & BE_LB_PROP_DYN) is checked by
the immediate outer if clause, so there is no need
to check it a second time.

Signed-off-by: Simon Horman <horms@verge.net.au>
diff --git a/include/proto/server.h b/include/proto/server.h
index 408427b..ded640a 100644
--- a/include/proto/server.h
+++ b/include/proto/server.h
@@ -59,6 +59,13 @@
 void srv_dump_kws(char **out);
 
 /*
+ * Parses weight_str and configures sv accordingly.
+ * Returns NULL on success, error message string otherwise.
+ */
+const char *server_parse_weight_change_request(struct server *sv,
+					       const char *weight_str);
+
+/*
  * Local variables:
  *  c-indent-level: 8
  *  c-basic-offset: 8
diff --git a/src/dumpstats.c b/src/dumpstats.c
index 5954e8c..0c3c2ae 100644
--- a/src/dumpstats.c
+++ b/src/dumpstats.c
@@ -1089,72 +1089,18 @@
 	}
 	else if (strcmp(args[0], "set") == 0) {
 		if (strcmp(args[1], "weight") == 0) {
-			struct proxy *px;
 			struct server *sv;
-			int w;
+			const char *warning;
 
 			sv = expect_server_admin(s, si, args[2]);
 			if (!sv)
 				return 1;
-			px = sv->proxy;
 
-			/* if the weight is terminated with '%', it is set relative to
-			 * the initial weight, otherwise it is absolute.
-			 */
-			if (!*args[3]) {
-				si->applet.ctx.cli.msg = "Require <weight> or <weight%>.\n";
+			warning = server_parse_weight_change_request(sv, args[3]);
+			if (warning) {
+				si->applet.ctx.cli.msg = warning;
 				si->applet.st0 = STAT_CLI_PRINT;
-				return 1;
-			}
-
-			w = atoi(args[3]);
-			if (strchr(args[3], '%') != NULL) {
-				if (w < 0 || w > 100) {
-					si->applet.ctx.cli.msg = "Relative weight can only be set between 0 and 100% inclusive.\n";
-					si->applet.st0 = STAT_CLI_PRINT;
-					return 1;
-				}
-				w = sv->iweight * w / 100;
-			}
-			else {
-				if (w < 0 || w > 256) {
-					si->applet.ctx.cli.msg = "Absolute weight can only be between 0 and 256 inclusive.\n";
-					si->applet.st0 = STAT_CLI_PRINT;
-					return 1;
-				}
-			}
-
-			if (w && w != sv->iweight && !(px->lbprm.algo & BE_LB_PROP_DYN)) {
-				si->applet.ctx.cli.msg = "Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.\n";
-				si->applet.st0 = STAT_CLI_PRINT;
-				return 1;
 			}
-
-			sv->uweight = w;
-
-			if (px->lbprm.algo & BE_LB_PROP_DYN) {
-			/* we must take care of not pushing the server to full throttle during slow starts */
-				if ((sv->state & SRV_WARMINGUP) && (px->lbprm.algo & BE_LB_PROP_DYN))
-					sv->eweight = (BE_WEIGHT_SCALE * (now.tv_sec - sv->last_change) + sv->slowstart - 1) / sv->slowstart;
-				else
-					sv->eweight = BE_WEIGHT_SCALE;
-				sv->eweight *= sv->uweight;
-			} else {
-				sv->eweight = sv->uweight;
-			}
-
-			/* static LB algorithms are a bit harder to update */
-			if (px->lbprm.update_server_eweight)
-				px->lbprm.update_server_eweight(sv);
-			else if (sv->eweight) {
-				if (px->lbprm.set_server_status_up)
-					px->lbprm.set_server_status_up(sv);
-			}
-			else {
-				if (px->lbprm.set_server_status_down)
-					px->lbprm.set_server_status_down(sv);
-			}
-
 			return 1;
 		}
 		else if (strcmp(args[1], "timeout") == 0) {
diff --git a/src/server.c b/src/server.c
index 568d042..7a2774c 100644
--- a/src/server.c
+++ b/src/server.c
@@ -157,6 +157,64 @@
 }
 
 /*
+ * Parses weight_str and configures sv accordingly.
+ * Returns NULL on success, error message string otherwise.
+ */
+const char *server_parse_weight_change_request(struct server *sv,
+					       const char *weight_str)
+{
+	struct proxy *px;
+	int w;
+
+	px = sv->proxy;
+
+	/* if the weight is terminated with '%', it is set relative to
+	 * the initial weight, otherwise it is absolute.
+	 */
+	if (!*weight_str)
+		return "Require <weight> or <weight%>.\n";
+
+	w = atoi(weight_str);
+	if (strchr(weight_str, '%') != NULL) {
+		if (w < 0 || w > 100)
+			return "Relative weight must be positive.\n";
+		w = sv->iweight * w / 100;
+	}
+	else if (w < 0 || w > 256)
+		return "Absolute weight can only be between 0 and 256 inclusive.\n";
+
+	if (w && w != sv->iweight && !(px->lbprm.algo & BE_LB_PROP_DYN))
+		return "Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.\n";
+
+	sv->uweight = w;
+
+	if (px->lbprm.algo & BE_LB_PROP_DYN) {
+	/* we must take care of not pushing the server to full throttle during slow starts */
+		if ((sv->state & SRV_WARMINGUP))
+			sv->eweight = (BE_WEIGHT_SCALE * (now.tv_sec - sv->last_change) + sv->slowstart - 1) / sv->slowstart;
+		else
+			sv->eweight = BE_WEIGHT_SCALE;
+		sv->eweight *= sv->uweight;
+	} else {
+		sv->eweight = sv->uweight;
+	}
+
+	/* static LB algorithms are a bit harder to update */
+	if (px->lbprm.update_server_eweight)
+		px->lbprm.update_server_eweight(sv);
+	else if (sv->eweight) {
+		if (px->lbprm.set_server_status_up)
+			px->lbprm.set_server_status_up(sv);
+	}
+	else {
+		if (px->lbprm.set_server_status_down)
+			px->lbprm.set_server_status_down(sv);
+	}
+
+	return NULL;
+}
+
+/*
  * Local variables:
  *  c-indent-level: 8
  *  c-basic-offset: 8