diff options
| -rw-r--r-- | polyp/log.c | 8 | ||||
| -rw-r--r-- | polyp/polyplib-browser.c | 8 | ||||
| -rw-r--r-- | polyp/polyplib-context.c | 4 | ||||
| -rw-r--r-- | polyp/protocol-esound.c | 9 | ||||
| -rw-r--r-- | polyp/socket-client.c | 82 | 
5 files changed, 91 insertions, 20 deletions
diff --git a/polyp/log.c b/polyp/log.c index 530fa691..78736a47 100644 --- a/polyp/log.c +++ b/polyp/log.c @@ -32,6 +32,8 @@  #include "xmalloc.h"  #include "util.h" +#define ENV_LOGLEVEL "POLYP_LOG" +  static char *log_ident = NULL;  static enum pa_log_target log_target = PA_LOG_STDERR;  static void (*user_log_func)(enum pa_log_level l, const char *s) = NULL; @@ -64,11 +66,15 @@ void pa_log_set_target(enum pa_log_target t, void (*func)(enum pa_log_level l, c  }  void pa_log_levelv(enum pa_log_level level, const char *format, va_list ap) { +    const char *e;      assert(level < PA_LOG_LEVEL_MAX); +    if ((e = getenv(ENV_LOGLEVEL))) +        maximal_level = atoi(e); +          if (level > maximal_level)          return; -     +      switch (log_target) {          case PA_LOG_STDERR:              vfprintf(stderr, format, ap); diff --git a/polyp/polyplib-browser.c b/polyp/polyplib-browser.c index 7e56e2ce..2e75a42d 100644 --- a/polyp/polyplib-browser.c +++ b/polyp/polyplib-browser.c @@ -55,7 +55,6 @@ static void io_callback(struct pa_mainloop_api*a, struct pa_io_event*e, int fd,      }  } -  static sw_result resolve_reply(      sw_discovery discovery,      sw_discovery_oid oid, @@ -134,9 +133,16 @@ static sw_result resolve_reply(                  i.user_name = c;                  c = NULL;              } else if (!strcmp(key, "fqdn")) { +                size_t l; +                                  pa_xfree((char*) i.fqdn);                  i.fqdn = c;                  c = NULL; +                 +                l = strlen(a); +                assert(l+1 <= sizeof(a)); +                strncat(a, " ", sizeof(a)-l-1); +                strncat(a, i.fqdn, sizeof(a)-l-2);              } else if (!strcmp(key, "cookie")) {                  if (pa_atou(c, &cookie) < 0) diff --git a/polyp/polyplib-context.c b/polyp/polyplib-context.c index e7ccda3e..bca7d7ea 100644 --- a/polyp/polyplib-context.c +++ b/polyp/polyplib-context.c @@ -508,7 +508,7 @@ static int try_next_connection(struct pa_context *c) {              goto finish;          } -/*          pa_log(__FILE__": Trying to connect to %s...\n", u);  */ +        pa_log_debug(__FILE__": Trying to connect to %s...\n", u);            pa_xfree(c->server);          c->server = pa_xstrdup(u); @@ -535,7 +535,7 @@ static void on_connection(struct pa_socket_client *client, struct pa_iochannel*i      assert(client && c && c->state == PA_CONTEXT_CONNECTING);      pa_context_ref(c); -     +      pa_socket_client_unref(client);      c->client = NULL; diff --git a/polyp/protocol-esound.c b/polyp/protocol-esound.c index 744ad4ed..d99b721c 100644 --- a/polyp/protocol-esound.c +++ b/polyp/protocol-esound.c @@ -764,7 +764,8 @@ static int do_read(struct connection *c) {          assert(c->read_data && c->read_data_length < handler->data_length);          if ((r = pa_iochannel_read(c->io, (uint8_t*) c->read_data + c->read_data_length, handler->data_length - c->read_data_length)) <= 0) { -            pa_log(__FILE__": read() failed: %s\n", r == 0 ? "EOF" : strerror(errno)); +            if (r != 0) +                pa_log_warn(__FILE__": read() failed: %s\n", strerror(errno));              return -1;          } @@ -784,7 +785,8 @@ static int do_read(struct connection *c) {          assert(c->scache.memchunk.memblock && c->scache.name && c->scache.memchunk.index < c->scache.memchunk.length);          if ((r = pa_iochannel_read(c->io, (uint8_t*) c->scache.memchunk.memblock->data+c->scache.memchunk.index, c->scache.memchunk.length-c->scache.memchunk.index)) <= 0) { -            pa_log(__FILE__": read() failed: %s\n", r == 0 ? "EOF" : strerror(errno)); +            if (r!= 0) +                pa_log_warn(__FILE__": read() failed: %s\n", strerror(errno));              return -1;          } @@ -841,7 +843,8 @@ static int do_read(struct connection *c) {          }          if ((r = pa_iochannel_read(c->io, (uint8_t*) c->playback.current_memblock->data+c->playback.memblock_index, l)) <= 0) { -            pa_log(__FILE__": read() failed: %s\n", r == 0 ? "EOF" : strerror(errno)); +            if (r != 0) +                pa_log(__FILE__": read() failed: %s\n", strerror(errno));              return -1;          } diff --git a/polyp/socket-client.c b/polyp/socket-client.c index 8ac04a8b..01f66371 100644 --- a/polyp/socket-client.c +++ b/polyp/socket-client.c @@ -46,11 +46,14 @@  #include "log.h"  #include "parseaddr.h" +#define CONNECT_TIMEOUT 5 +  struct pa_socket_client {      int ref;      struct pa_mainloop_api *mainloop;      int fd;      struct pa_io_event *io_event; +    struct pa_time_event *timeout_event;      struct pa_defer_event *defer_event;      void (*callback)(struct pa_socket_client*c, struct pa_iochannel *io, void *userdata);      void *userdata; @@ -72,6 +75,7 @@ static struct pa_socket_client*pa_socket_client_new(struct pa_mainloop_api *m) {      c->fd = -1;      c->io_event = NULL;      c->defer_event = NULL; +    c->timeout_event = NULL;      c->callback = NULL;      c->userdata = NULL;      c->local = 0; @@ -85,6 +89,25 @@ static struct pa_socket_client*pa_socket_client_new(struct pa_mainloop_api *m) {      return c;  } +static void free_events(struct pa_socket_client *c) { +    assert(c); +     +    if (c->io_event) { +        c->mainloop->io_free(c->io_event); +        c->io_event = NULL; +    } +     +    if (c->defer_event) { +        c->mainloop->defer_free(c->defer_event); +        c->defer_event = NULL; +    } +     +    if (c->timeout_event) { +        c->mainloop->time_free(c->timeout_event); +        c->timeout_event = NULL; +    } +} +  static void do_call(struct pa_socket_client *c) {      struct pa_iochannel *io = NULL;      int error; @@ -108,7 +131,7 @@ static void do_call(struct pa_socket_client *c) {      }      if (error != 0) { -/*         pa_log(__FILE__": connect(): %s\n", strerror(error)); */ +        pa_log_debug(__FILE__": connect(): %s\n", strerror(error));           errno = error;          goto finish;      } @@ -120,6 +143,8 @@ finish:      if (!io && c->fd >= 0)          close(c->fd);      c->fd = -1; + +    free_events(c);      assert(c->callback);      c->callback(c, io, c->userdata); @@ -130,16 +155,12 @@ finish:  static void connect_fixed_cb(struct pa_mainloop_api *m, struct pa_defer_event *e, void *userdata) {      struct pa_socket_client *c = userdata;      assert(m && c && c->defer_event == e); -    m->defer_free(c->defer_event); -    c->defer_event = NULL;      do_call(c);  }  static void connect_io_cb(struct pa_mainloop_api*m, struct pa_io_event *e, int fd, enum pa_io_event_flags f, void *userdata) {      struct pa_socket_client *c = userdata;      assert(m && c && c->io_event == e && fd >= 0); -    m->io_free(c->io_event); -    c->io_event = NULL;      do_call(c);  } @@ -247,10 +268,10 @@ fail:  void socket_client_free(struct pa_socket_client *c) {      assert(c && c->mainloop); -    if (c->io_event) -        c->mainloop->io_free(c->io_event); -    if (c->defer_event) -        c->mainloop->defer_free(c->defer_event); + + +    free_events(c); +          if (c->fd >= 0)          close(c->fd); @@ -305,7 +326,7 @@ static void asyncns_cb(struct pa_mainloop_api*m, struct pa_io_event *e, int fd,      assert(m && c && c->asyncns_io_event == e && fd >= 0);      if (asyncns_wait(c->asyncns, 0) < 0) -        goto finish; +        goto fail;      if (!asyncns_isdone(c->asyncns, c->asyncns_query))          return; @@ -314,22 +335,53 @@ static void asyncns_cb(struct pa_mainloop_api*m, struct pa_io_event *e, int fd,      c->asyncns_query = NULL;      if (ret != 0 || !res) -        goto finish; +        goto fail;      if (res->ai_addr)          sockaddr_prepare(c, res->ai_addr, res->ai_addrlen);      asyncns_freeaddrinfo(res); +    goto finish; + +fail: +    errno == EHOSTUNREACH; +    do_call(c); +      finish:      m->io_free(c->asyncns_io_event);      c->asyncns_io_event = NULL; -    do_call(c);  }  #endif +static void timeout_cb(struct pa_mainloop_api *m, struct pa_time_event *e, const struct timeval *tv, void *userdata) { +    struct pa_socket_client *c = userdata; +    assert(m); +    assert(e); +    assert(tv); +    assert(c); + +    if (c->fd >= 0) { +        close(c->fd); +        c->fd = -1; +    } + +    errno = ETIMEDOUT; +    do_call(c); +} + +static void start_timeout(struct pa_socket_client *c) { +    struct timeval tv; +    assert(c); +    assert(!c->timeout_event); + +    gettimeofday(&tv, NULL); +    pa_timeval_add(&tv, CONNECT_TIMEOUT * 1000000); +    c->timeout_event = c->mainloop->time_new(c->mainloop, &tv, timeout_cb, c); +} +  struct pa_socket_client* pa_socket_client_new_string(struct pa_mainloop_api *m, const char*name, uint16_t default_port) {      struct pa_socket_client *c = NULL;      struct pa_parsed_address a; @@ -344,6 +396,7 @@ struct pa_socket_client* pa_socket_client_new_string(struct pa_mainloop_api *m,      switch (a.type) {          case PA_PARSED_ADDRESS_UNIX:              c = pa_socket_client_new_unix(m, a.path_or_host); +            start_timeout(c);              break;          case PA_PARSED_ADDRESS_TCP4:  /* Fallthrough */ @@ -371,6 +424,7 @@ struct pa_socket_client* pa_socket_client_new_string(struct pa_mainloop_api *m,                  c->asyncns_io_event = m->io_new(m, asyncns_fd(c->asyncns), PA_IO_EVENT_INPUT, asyncns_cb, c);                  c->asyncns_query = asyncns_getaddrinfo(c->asyncns, a.path_or_host, port, &hints);                  assert(c->asyncns_query); +                start_timeout(c);              }  #else              { @@ -382,8 +436,10 @@ struct pa_socket_client* pa_socket_client_new_string(struct pa_mainloop_api *m,                  if (ret < 0 || !res)                      goto finish; -                if (res->ai_addr) +                if (res->ai_addr) {                      c = pa_socket_client_new_sockaddr(m, res->ai_addr, res->ai_addrlen); +                    start_timeout(c); +                }                  freeaddrinfo(res);              }  | 
