diff --git a/src/conf.c b/src/conf.c index c06637ff..5911ce13 100644 --- a/src/conf.c +++ b/src/conf.c @@ -102,7 +102,7 @@ static int _conf_verify_element(char *section, char *key, char *value); static CONF_ELEMENTS conf_elements[] = { { 1, 0, CONF_T_STRING,"general","runas" }, { 1, 0, CONF_T_EXISTPATH,"general","web_root" }, - { 1, 0, CONF_T_INT,"general","port" }, + { 0, 0, CONF_T_INT,"general","port" }, { 1, 0, CONF_T_STRING,"general","admin_pw" }, { 1, 0, CONF_T_MULTICOMMA,"general","mp3_dir" }, { 0, 1, CONF_T_EXISTPATH,"general","db_dir" }, @@ -733,6 +733,7 @@ int conf_read(char *file) { ll_destroy(pllnew); ll_destroy(pllcomment); DPRINTF(E_LOG,L_CONF,"Could not validate config file. Ignoring\n"); + return CONF_E_BADCONFIG; } return CONF_E_SUCCESS; diff --git a/src/conf.h b/src/conf.h index aad40ea0..a93d44ce 100644 --- a/src/conf.h +++ b/src/conf.h @@ -34,6 +34,7 @@ #define CONF_E_BADELEMENT 9 #define CONF_E_PATHEXPECTED 10 #define CONF_E_INTEXPECTED 11 +#define CONF_E_BADCONFIG 12 extern int conf_read(char *file); extern int conf_reload(void); diff --git a/src/main.c b/src/main.c index 52bea133..2b431b38 100644 --- a/src/main.c +++ b/src/main.c @@ -408,7 +408,7 @@ int main(int argc, char *argv[]) { /* start up the web server */ web_root = conf_alloc_string("general","web_root",NULL); ws_config.web_root=web_root; - ws_config.port=conf_get_int("general","port",3689); + ws_config.port=conf_get_int("general","port",0); DPRINTF(E_LOG,L_MAIN|L_WS,"Starting web server from %s on port %d\n", ws_config.web_root, ws_config.port); diff --git a/src/webserver.c b/src/webserver.c index dafa308f..9ca314cf 100644 --- a/src/webserver.c +++ b/src/webserver.c @@ -203,6 +203,8 @@ void ws_unlock_connlist(WS_PRIVATE *pwsp) { */ WSHANDLE ws_start(WSCONFIG *config) { int err; + int ephemeral = 0; + WS_PRIVATE *pwsp; DPRINTF(E_SPAM,L_WS,"Entering ws_start\n"); @@ -232,15 +234,38 @@ WSHANDLE ws_start(WSCONFIG *config) { return NULL; } - DPRINTF(E_INF,L_WS,"Preparing to listen on port %d\n",pwsp->wsconfig.port); + /* this is kind of stupid, but is easier to fix once here + * rather than mucking with differences in sockets on windows/unix + */ - if((pwsp->server_fd = u_open(pwsp->wsconfig.port)) == -1) { - err=errno; - DPRINTF(E_LOG,L_WS,"Could not open port: %s\n",strerror(errno)); - errno=err; - return NULL; + if(pwsp->wsconfig.port == 0) { + pwsp->wsconfig.port = 1024; /* start with default port */ + ephemeral = 1; } + while(1) { + DPRINTF(E_INF,L_WS,"Listening on port %d\n",pwsp->wsconfig.port); + pwsp->server_fd = u_open(pwsp->wsconfig.port); + if(pwsp->server_fd == -1) { + if((!ephemeral) || (errno != EADDRINUSE)) { + err = errno; + DPRINTF(E_LOG,L_WS,"Listen port: %s\n",strerror(errno)); + errno = err; + return NULL; + } + } else { + break; + } + + pwsp->wsconfig.port++; + if(!pwsp->wsconfig.port) { + DPRINTF(E_LOG,L_WS,"Exhausted ports\n"); + return NULL; + } + } + + config->port = pwsp->wsconfig.port; + DPRINTF(E_INF,L_WS,"Starting server thread\n"); if((err=pthread_create(&pwsp->server_tid,NULL,ws_mainthread,(void*)pwsp))) { DPRINTF(E_LOG,L_WS,"Could not spawn thread: %s\n",strerror(err));