[MINOR] maintain a global session list in order to ease debugging

Now the global variable 'sessions' will be a dual-linked list of all
known sessions. The list element is set at the beginning of the session
so that it's easier to follow them all with gdb.
diff --git a/include/proto/session.h b/include/proto/session.h
index cdd01bf..0357757 100644
--- a/include/proto/session.h
+++ b/include/proto/session.h
@@ -3,7 +3,7 @@
   This file defines everything related to sessions.
 
   Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu
-  
+
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation, version 2.1
@@ -27,6 +27,7 @@
 #include <types/session.h>
 
 extern struct pool_head *pool2_session;
+extern struct list sessions;
 
 void session_free(struct session *s);
 
diff --git a/include/types/session.h b/include/types/session.h
index 1177924..a92949b 100644
--- a/include/types/session.h
+++ b/include/types/session.h
@@ -3,7 +3,7 @@
   This file defines everything related to sessions.
 
   Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu
-  
+
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation, version 2.1
@@ -152,6 +152,7 @@
  *    server should eventually be released.
  */
 struct session {
+	struct list list;			/* position in global sessions list */
 	struct task *task;			/* the task associated with this session */
 	/* application specific below */
 	struct proxy *fe;			/* the proxy this session depends on for the client side */
diff --git a/src/client.c b/src/client.c
index d56a33e..78387a1 100644
--- a/src/client.c
+++ b/src/client.c
@@ -53,7 +53,7 @@
 /*
  * FIXME: This should move to the STREAM_SOCK code then split into TCP and HTTP.
  */
-    
+
 /*
  * this function is called on a read event from a listen socket, corresponding
  * to an accept. It tries to accept as many connections as possible.
@@ -106,6 +106,8 @@
 			goto out_close;
 		}
 
+		LIST_ADDQ(&sessions, &s->list);
+
 		s->flags = 0;
 		s->term_trace = 0;
 
@@ -455,6 +457,7 @@
  out_free_task:
 	pool_free2(pool2_task, t);
  out_free_session:
+	LIST_DEL(&s->list);
 	pool_free2(pool2_session, s);
  out_close:
 	close(cfd);
diff --git a/src/proto_uxst.c b/src/proto_uxst.c
index dc2b933..ee684a6 100644
--- a/src/proto_uxst.c
+++ b/src/proto_uxst.c
@@ -411,12 +411,15 @@
 			return 0;
 		}
 
+		LIST_ADDQ(&sessions, &s->list);
+
 		s->flags = 0;
 		s->term_trace = 0;
 
 		if ((t = pool_alloc2(pool2_task)) == NULL) {
 			Alert("out of memory in uxst_event_accept().\n");
 			close(cfd);
+			LIST_DEL(&s->list);
 			pool_free2(pool2_session, s);
 			return 0;
 		}
@@ -428,6 +431,7 @@
 			Alert("accept(): not enough free sockets. Raise -n argument. Giving up.\n");
 			close(cfd);
 			pool_free2(pool2_task, t);
+			LIST_DEL(&s->list);
 			pool_free2(pool2_session, s);
 			return 0;
 		}
@@ -436,6 +440,7 @@
 			Alert("accept(): cannot set the socket in non blocking mode. Giving up\n");
 			close(cfd);
 			pool_free2(pool2_task, t);
+			LIST_DEL(&s->list);
 			pool_free2(pool2_session, s);
 			return 0;
 		}
@@ -467,6 +472,7 @@
 		if ((s->req = pool_alloc2(pool2_buffer)) == NULL) { /* no memory */
 			close(cfd); /* nothing can be done for this fd without memory */
 			pool_free2(pool2_task, t);
+			LIST_DEL(&s->list);
 			pool_free2(pool2_session, s);
 			return 0;
 		}
@@ -475,6 +481,7 @@
 			pool_free2(pool2_buffer, s->req);
 			close(cfd); /* nothing can be done for this fd without memory */
 			pool_free2(pool2_task, t);
+			LIST_DEL(&s->list);
 			pool_free2(pool2_session, s);
 			return 0;
 		}
@@ -577,7 +584,7 @@
 			buffer_shutr(req);
 			t->cli_state = CL_STSHUTR;
 			return 1;
-		}	
+		}
 		/* last server read and buffer empty */
 		else if ((s == SV_STSHUTR || s == SV_STCLOSE) && (rep->flags & BF_EMPTY)) {
 			EV_FD_CLR(t->cli_fd, DIR_WR);
@@ -607,7 +614,7 @@
 					t->flags |= SN_FINST_D;
 			}
 			return 1;
-		}	
+		}
 		/* write timeout */
 		else if (tick_is_expired(rep->wex, now_ms)) {
 			EV_FD_CLR(t->cli_fd, DIR_WR);
diff --git a/src/session.c b/src/session.c
index fb7de4a..8a46962 100644
--- a/src/session.c
+++ b/src/session.c
@@ -26,6 +26,7 @@
 
 
 struct pool_head *pool2_session;
+struct list sessions;
 
 /*
  * frees  the context associated to a session. It must have been removed first.
@@ -74,6 +75,7 @@
 	pool_free2(pool2_requri, txn->uri);
 	pool_free2(pool2_capture, txn->cli_cookie);
 	pool_free2(pool2_capture, txn->srv_cookie);
+	LIST_DEL(&s->list);
 	pool_free2(pool2_session, s);
 
 	/* We may want to free the maximum amount of pools if the proxy is stopping */
@@ -92,6 +94,7 @@
 /* perform minimal intializations, report 0 in case of error, 1 if OK. */
 int init_session()
 {
+	LIST_INIT(&sessions);
 	pool2_session = create_pool("session", sizeof(struct session), MEM_F_SHARED);
 	return pool2_session != NULL;
 }