diff options
-rw-r--r-- | src/listen.c | 133 |
1 files changed, 69 insertions, 64 deletions
diff --git a/src/listen.c b/src/listen.c index 8575e2bec..379dfb8d5 100644 --- a/src/listen.c +++ b/src/listen.c @@ -43,13 +43,72 @@ int * listenSockets = NULL; int numberOfListenSockets = 0; -static int establishListen(unsigned int port, ConfigParam * param) { - int allowReuse = ALLOW_REUSE; +static void establishListen(unsigned int port, + struct sockaddr * addrp, + socklen_t addrlen) +{ + int pf; int sock; + int allowReuse = ALLOW_REUSE; + + switch(addrp->sa_family) { + case AF_INET: + pf = PF_INET; + break; +#ifdef HAVE_IPV6 + case AF_INET6: + pf = PF_INET6; + break; +#endif + case AF_UNIX: + pf = PF_UNIX; + break; + default: + ERROR("unknown address family: %i\n",addrp->sa_family); + exit(EXIT_FAILURE); + } + + if((sock = socket(pf,SOCK_STREAM,0)) < 0) { + ERROR("socket < 0\n"); + exit(EXIT_FAILURE); + } + + if(fcntl(sock, F_SETFL ,fcntl(sock, F_GETFL) | O_NONBLOCK) < 0) { + ERROR("problems setting nonblocking on listen socket: %s\n", + strerror(errno)); + exit(EXIT_FAILURE); + } + + if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&allowReuse, + sizeof(allowReuse))<0) + { + ERROR("problems setsockopt'ing: %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + + if(bind(sock,addrp,addrlen)<0) { + ERROR("unable to bind port %u", port); + ERROR(": %s\n", strerror(errno)); + ERROR("maybe MPD is still running?\n"); + exit(EXIT_FAILURE); + } + + if(listen(sock,5)<0) { + ERROR("problems listen'ing: %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + + numberOfListenSockets++; + listenSockets = + realloc(listenSockets,sizeof(int)*numberOfListenSockets); + + listenSockets[numberOfListenSockets-1] = sock; +} + +static void parseListenConfigParam(unsigned int port, ConfigParam * param) { struct sockaddr * addrp; socklen_t addrlen; struct sockaddr_in sin; - int pf; #ifdef HAVE_IPV6 struct sockaddr_in6 sin6; @@ -68,14 +127,13 @@ static int establishListen(unsigned int port, ConfigParam * param) { sin6.sin6_addr = in6addr_any; addrp = (struct sockaddr *) &sin6; addrlen = sizeof(struct sockaddr_in6); + establishListen(port, addrp, addrlen); } - else #endif - { - sin.sin_addr.s_addr = INADDR_ANY; - addrp = (struct sockaddr *) &sin; - addrlen = sizeof(struct sockaddr_in); - } + sin.sin_addr.s_addr = INADDR_ANY; + addrp = (struct sockaddr *) &sin; + addrlen = sizeof(struct sockaddr_in); + establishListen(port, addrp, addrlen); } else { struct hostent * he; @@ -112,57 +170,9 @@ static int establishListen(unsigned int port, ConfigParam * param) { param->value, param->line); exit(EXIT_FAILURE); } - } - switch(addrp->sa_family) { - case AF_INET: - pf = PF_INET; - break; -#ifdef HAVE_IPV6 - case AF_INET6: - pf = PF_INET6; - break; -#endif - case AF_UNIX: - pf = PF_UNIX; - break; - default: - ERROR("unknown address family: %i\n",addrp->sa_family); - exit(EXIT_FAILURE); + establishListen(port, addrp, addrlen); } - - if((sock = socket(pf,SOCK_STREAM,0)) < 0) { - ERROR("socket < 0\n"); - exit(EXIT_FAILURE); - } - - if(fcntl(sock, F_SETFL ,fcntl(sock, F_GETFL) | O_NONBLOCK) < 0) { - ERROR("problems setting nonblocking on listen socket: %s\n", - strerror(errno)); - exit(EXIT_FAILURE); - } - - if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&allowReuse, - sizeof(allowReuse))<0) - { - ERROR("problems setsockopt'ing: %s\n", strerror(errno)); - exit(EXIT_FAILURE); - } - - if(bind(sock,addrp,addrlen)<0) { - ERROR("unable to bind port %u", port); - if(param) ERROR(" (for address at line %i)", param->line); - ERROR(": %s\n", strerror(errno)); - ERROR("maybe MPD is still running?\n"); - exit(EXIT_FAILURE); - } - - if(listen(sock,5)<0) { - ERROR("problems listen'ing: %s\n", strerror(errno)); - exit(EXIT_FAILURE); - } - - return sock; } void listenOnPort(void) { @@ -186,12 +196,7 @@ void listenOnPort(void) { } do { - numberOfListenSockets++; - listenSockets = realloc(listenSockets, - sizeof(int)*numberOfListenSockets); - - listenSockets[numberOfListenSockets-1] = - establishListen(port, param); + parseListenConfigParam(port, param); } while ((param = getNextConfigParam(CONF_BIND_TO_ADDRESS, param))); } |