--- socket.c.orig 2004-10-20 18:18:23.000000000 +0000 +++ socket.c.mod01 2005-04-06 07:33:29.000000000 +0000 @@ -26,9 +26,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -159,6 +161,25 @@ return 0; } +void refresh_resolvers(void) +{ + static time_t resolv_conf_changed = (time_t)NULL; + struct stat s; + + /* This makes the glibc re-read resolv.conf, if it changed + * since our startup. Maybe that should be #ifdef'ed, I don't + * know if it'd work on BSDs. + * Why doesn't the glibc do it by itself? + */ + if (stat("/etc/resolv.conf", &s) == 0) { + if (s.st_mtime > resolv_conf_changed) { + resolv_conf_changed = s.st_mtime; + res_init(); + } + } /* else + we'll have bigger problems. */ +} + gint fd_connect_unix(const gchar *path) { gint sock; @@ -387,7 +408,7 @@ { gint ret; void (*prev_handler)(gint); - + alarm(0); prev_handler = signal(SIGALRM, timeout_handler); if (sigsetjmp(jmpenv, 1)) { @@ -410,7 +431,7 @@ { struct hostent *hp; void (*prev_handler)(gint); - + alarm(0); prev_handler = signal(SIGALRM, timeout_handler); if (sigsetjmp(jmpenv, 1)) { @@ -467,6 +488,8 @@ ad.sin_family = AF_INET; ad.sin_port = htons(port); + refresh_resolvers(); + if (!my_inet_aton(hostname, &ad.sin_addr)) { if ((hp = my_gethostbyname(hostname)) == NULL) { fprintf(stderr, "%s: unknown host.\n", hostname); @@ -494,6 +517,8 @@ struct addrinfo hints, *res, *ai; gchar port_str[6]; + refresh_resolvers(); + memset(&hints, 0, sizeof(hints)); /* hints.ai_flags = AI_CANONNAME; */ hints.ai_family = AF_UNSPEC; @@ -851,6 +876,8 @@ SockLookupData *lookup_data = NULL; gint pipe_fds[2]; pid_t pid; + + refresh_resolvers(); if (pipe(pipe_fds) < 0) { perror("pipe"); @@ -1020,7 +1047,7 @@ #if USE_OPENSSL gint ssl_read(SSL *ssl, gchar *buf, gint len) { - gint ret; + gint err, ret; if (SSL_pending(ssl) == 0) { if (fd_check_io(SSL_get_rfd(ssl), G_IO_IN) < 0) @@ -1029,14 +1056,19 @@ ret = SSL_read(ssl, buf, len); - switch (SSL_get_error(ssl, ret)) { + switch ((err = SSL_get_error(ssl, ret))) { case SSL_ERROR_NONE: return ret; case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: errno = EAGAIN; return -1; + case SSL_ERROR_ZERO_RETURN: + return 0; default: + g_warning("SSL_read() returned error %d, ret = %d\n", err, ret); + if (ret == 0) + return 0; return -1; } } @@ -1315,7 +1347,7 @@ #if USE_OPENSSL gint ssl_peek(SSL *ssl, gchar *buf, gint len) { - gint ret; + gint err, ret; if (SSL_pending(ssl) == 0) { if (fd_check_io(SSL_get_rfd(ssl), G_IO_IN) < 0) @@ -1324,14 +1356,19 @@ ret = SSL_peek(ssl, buf, len); - switch (SSL_get_error(ssl, ret)) { + switch ((err = SSL_get_error(ssl, ret))) { case SSL_ERROR_NONE: return ret; case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: errno = EAGAIN; return -1; + case SSL_ERROR_ZERO_RETURN: + return 0; default: + g_warning("SSL_peek() returned error %d, ret = %d\n", err, ret); + if (ret == 0) + return 0; return -1; } }