[MINOR] acl: add new keyword "connslots"

I'm in the process of setting up one haproxy instance now, and I find
the following acl option useful. I'm not too sure why this option has
not been available before, but I find this useful for my own usage, so
I'm submitting this patch in the hope that it will be useful as well.

The basic idea is to be able to measure the available connection slots
still available (connection, + queue) - anything beyond that can be
redirected to a different backend. 'connslots' = number of available
server connection slots, + number of available server queue slots. In
the case where we encounter srv maxconn = 0, or srv maxqueue = 0 (in
which case we dont need to care about connslots) the value you get is
-1. Note also that this code does not take care of dynamic connections
at this point in time.

The reason why I'm using this new acl (as opposed to 'nbsrv') is that
'nbsrv' only measures servers that are actually *down*. Whereas this
other acl is more fine-grained, and looks into the number of conn
slots available as well.

diff --git a/src/backend.c b/src/backend.c
index 986c070..c8a84be 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -2048,10 +2048,47 @@
 	return 1;
 }
 
+/* set test->i to the number of enabled servers on the proxy */
+static int
+acl_fetch_connslots(struct proxy *px, struct session *l4, void *l7, int dir,
+		    struct acl_expr *expr, struct acl_test *test)
+{
+	struct server *iterator;
+	test->flags = ACL_TEST_F_VOL_TEST;
+	if (expr->arg_len) {
+		/* another proxy was designated, we must look for it */
+		for (px = proxy; px; px = px->next)
+			if ((px->cap & PR_CAP_BE) && !strcmp(px->id, expr->arg.str))
+				break;
+	}
+	if (!px)
+		return 0;
+
+	test->i = 0;
+	iterator = px->srv;
+	while (iterator) {
+		if ((iterator->state & 1) == 0) {
+			iterator = iterator->next;
+			continue;
+		}
+		if (iterator->maxconn == 0 || iterator->maxqueue == 0) {
+			test->i = -1;
+			return 1;
+		}
+
+		test->i += (iterator->maxconn - iterator->cur_sess)
+			+  (iterator->maxqueue - iterator->nbpend);
+		iterator = iterator->next;
+	}
+
+	return 1;
+}
+
 
 /* Note: must not be declared <const> as its list will be overwritten */
 static struct acl_kw_list acl_kws = {{ },{
-	{ "nbsrv",   acl_parse_int,   acl_fetch_nbsrv,    acl_match_int, ACL_USE_NOTHING },
+	{ "nbsrv",    acl_parse_int,   acl_fetch_nbsrv,     acl_match_int, ACL_USE_NOTHING },
+	{ "connlots", acl_parse_int,   acl_fetch_connslots, acl_match_int, ACL_USE_NOTHING },
 	{ NULL, NULL, NULL, NULL },
 }};