Index: src/shttpd.c
===================================================================
RCS file: /cvsroot/shttpd/shttpd/src/shttpd.c,v
retrieving revision 1.14
diff -u -r1.14 shttpd.c
--- src/shttpd.c	27 Jul 2007 11:15:53 -0000	1.14
+++ src/shttpd.c	28 Nov 2007 04:57:46 -0000
@@ -153,10 +153,11 @@
  * Setup listening socket on given port, return socket
  */
 static int
-open_listening_port(int port)
+open_listening_port(unsigned long iface, int port)
 {
 	int		sock, on = 1;
 	struct usa	sa;
+	char	*addr_buf;
 
 #ifdef _WIN32
 	{WSADATA data;	WSAStartup(MAKEWORD(2,2), &data);}
@@ -165,7 +166,7 @@
 	sa.len				= sizeof(sa.u.sin);
 	sa.u.sin.sin_family		= AF_INET;
 	sa.u.sin.sin_port		= htons((uint16_t) port);
-	sa.u.sin.sin_addr.s_addr	= htonl(INADDR_ANY);
+	sa.u.sin.sin_addr.s_addr	= iface;
 
 	if ((sock = socket(PF_INET, SOCK_STREAM, 6)) == -1)
 		goto fail;
@@ -187,7 +188,8 @@
 fail:
 	if (sock != -1)
 		(void) closesocket(sock);
-	elog(E_LOG, NULL, "open_listening_port(%d): %s", port, strerror(errno));
+	addr_buf = inet_ntoa(sa.u.sin.sin_addr);
+	elog(E_LOG, NULL, "open_listening_port(%s:%d): %s", addr_buf, port, strerror(errno));
 	return (-1);
 }
 
@@ -749,22 +751,51 @@
 {
 	struct listener	*l;
 	int		sock;
+	char	*buf;
+	struct sockaddr_in	iface;
+	size_t	len;
+	const char	*s = ctx->interfaces;
 
-	if ((sock = open_listening_port(port)) == -1) {
-		elog(E_FATAL, NULL, "cannot open port %d", port);
-	} else if ((l = calloc(1, sizeof(*l))) == NULL) {
-		(void) closesocket(sock);
-		elog(E_FATAL, NULL, "cannot allocate listener");
-	} else if (is_ssl && ctx->ssl_ctx == NULL) {
-		(void) closesocket(sock);
-		elog(E_FATAL, NULL, "cannot add SSL socket, "
-		    "please specify certificate file");
-	} else {
-		l->is_ssl = is_ssl;
-		l->sock	= sock;
-		l->ctx	= ctx;
-		LL_TAIL(&listeners, &l->link);
-		DBG(("shttpd_listen: added socket %d", sock));
+	FOR_EACH_WORD_IN_LIST(s, len) {
+		if ((buf = my_strndup(s, len)) != NULL) {
+#ifdef _WIN32
+			if (INADDR_NONE != (iface.sin_addr.s_addr = inet_addr(buf))) {
+#else
+			if (inet_aton(buf, &iface.sin_addr) != 0) {
+#endif
+				if ((sock = open_listening_port(iface.sin_addr.s_addr, port)) == -1) {
+					free(buf);
+					elog(E_FATAL, NULL, "cannot open port %d", port);
+				} else if ((l = calloc(1, sizeof(*l))) == NULL) {
+					free(buf);
+					(void) closesocket(sock);
+					elog(E_FATAL, NULL, "cannot allocate listener");
+				} else if (is_ssl && ctx->ssl_ctx == NULL) {
+					free(buf);
+					(void) closesocket(sock);
+					elog(E_FATAL, NULL, "cannot add SSL socket, "
+					"please specify certificate file");
+				} else {
+					l->is_ssl = is_ssl;
+					l->sock	= sock;
+					l->ctx	= ctx;
+					LL_TAIL(&listeners, &l->link);
+					DBG(("shttpd_listen: added socket %d", sock));
+					free(buf);
+					break; /* Break the loop after the first successful iteration
+					        * for now; maybe in the future another API call could
+					        * be added to handle binding to multiple interfaces. */
+				}
+			}
+			else {
+				/* Invalid IP address string. */
+				free(buf);
+				elog(E_FATAL, NULL, "interface address is invalid");
+			}
+		}
+		else {
+			elog(E_FATAL, NULL, "cannot allocate interfaces buffer");
+		}
 	}
 
 	return (sock);
Index: src/defs.h
===================================================================
RCS file: /cvsroot/shttpd/shttpd/src/defs.h,v
retrieving revision 1.12
diff -u -r1.12 defs.h
--- src/defs.h	10 Jul 2007 09:45:55 -0000	1.12
+++ src/defs.h	28 Nov 2007 04:57:44 -0000
@@ -25,6 +25,7 @@
 
 #define	HTPASSWD	".htpasswd"	/* Passwords file name		*/
 #define	DFLT_IO_SIZ	"16384"		/* Default max request size	*/
+#define LISTENING_INTERFACES "0.0.0.0" /* Default listening interfaces */
 #define	LISTENING_PORTS	"80"		/* Default listening ports	*/
 #define	INDEX_FILES	"index.html index.htm index.php index.cgi"
 #define	CGI_EXT		".cgi .pl .php"	/* Default CGI extensions	*/
@@ -298,6 +299,7 @@
 	char	*auth_realm;		/* Auth realm			*/
 	char	*global_passwd_file;	/* Global passwords file	*/
 	char	*uid;			/* Run as user			*/
+	char	*interfaces;	/* Listening interfaces	*/
 	char	*ports;			/* Listening ports		*/
 	int	dirlist;		/* Directory listing		*/
 	int	gui;			/* Show GUI flag		*/
Index: src/config.c
===================================================================
RCS file: /cvsroot/shttpd/shttpd/src/config.c,v
retrieving revision 1.8
diff -u -r1.8 config.c
--- src/config.c	10 Jul 2007 09:43:57 -0000	1.8
+++ src/config.c	28 Nov 2007 04:57:43 -0000
@@ -124,6 +124,8 @@
 		OFS(document_root), "directory", NULL, OPT_DIR},
 	{'i', "index_files", "Index files", set_str, OFS(index_files),
 		"file_list", INDEX_FILES, OPT_ADVANCED},
+	{'f', "listen_interfaces", "Listening interfaces", set_str,
+		OFS(interfaces), "interfaces", LISTENING_INTERFACES, OPT_ADVANCED},
 	{'p', "listen_ports", "Listening ports", set_str,
 		OFS(ports), "ports", LISTENING_PORTS, OPT_ADVANCED},
 	{'D', "list_directories", "Directory listing", set_int,
