1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2024-11-15 09:44:04 +00:00

Use getaddrinfo instead of gethostbyname

Patches conky to use getaddrinfo instead of gethostbyname everywhere. gethostbyname is rather
flawed and doesn't support IPv6 properly.

Patch contributed by Pascal Bleser
This commit is contained in:
Pavel Labath 2010-08-15 14:56:46 +02:00
parent a25985f00b
commit 74392a5491
3 changed files with 94 additions and 97 deletions

View File

@ -164,44 +164,41 @@ int update_apcupsd(void) {
memcpy(apc.items[i], "N/A", 4); // including \0
do {
struct hostent* he = 0;
struct sockaddr_in addr;
struct addrinfo hints;
struct addrinfo *ai, *rp;
int res;
short sz = 0;
#ifdef HAVE_GETHOSTBYNAME_R
struct hostent he_mem;
int he_errno;
char hostbuff[2048];
#endif
char portbuf[8];
//
// connect to apcupsd daemon
//
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("socket");
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = 0;
hints.ai_protocol = 0;
snprintf(portbuf, 8, "%d", info.apcupsd.port);
res = getaddrinfo(info.apcupsd.host, portbuf, &hints, &ai);
if (res != 0) {
NORM_ERR("APCUPSD getaddrinfo: %s", gai_strerror(res));
break;
}
#ifdef HAVE_GETHOSTBYNAME_R
if (gethostbyname_r(info.apcupsd.host, &he_mem, hostbuff, sizeof(hostbuff), &he, &he_errno) || !he ) {
NORM_ERR("APCUPSD gethostbyname_r: %s", hstrerror(h_errno));
break;
for (rp = ai; rp != NULL; rp = rp->ai_next) {
sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (sock == -1) {
continue;
}
if (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1) {
break;
}
close(sock);
}
#else /* HAVE_GETHOSTBYNAME_R */
he = gethostbyname(info.apcupsd.host);
if (!he) {
herror("gethostbyname");
break;
}
#endif /* HAVE_GETHOSTBYNAME_R */
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = info.apcupsd.port;
memcpy(&addr.sin_addr, he->h_addr, he->h_length);
if (connect(sock, (struct sockaddr*)&addr, sizeof(struct sockaddr)) < 0) {
freeaddrinfo(ai);
if (rp == NULL) {
// no error reporting, the daemon is probably not running
break;
}
//
// send status request - "status" - 6B
//

View File

@ -659,14 +659,13 @@ static void *imap_thread(void *arg)
unsigned long old_unseen = ULONG_MAX;
unsigned long old_messages = ULONG_MAX;
struct stat stat_buf;
struct hostent he, *he_res = 0;
int he_errno;
char hostbuff[2048];
struct sockaddr_in their_addr; // connector's address information
struct mail_s *mail = (struct mail_s *)arg;
int has_idle = 0;
int threadfd = timed_thread_readfd(mail->p_timed_thread);
char resolved_host = 0;
struct addrinfo hints;
struct addrinfo *ai, *rp;
char portbuf[8];
while (fail < mail->retries) {
struct timeval fetchtimeout;
@ -674,19 +673,19 @@ static void *imap_thread(void *arg)
fd_set fdset;
if (!resolved_host) {
#ifdef HAVE_GETHOSTBYNAME_R
if (gethostbyname_r(mail->host, &he, hostbuff, sizeof(hostbuff), &he_res, &he_errno)) { // get the host info
NORM_ERR("IMAP gethostbyname_r: %s", hstrerror(h_errno));
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = 0;
hints.ai_protocol = 0;
snprintf(portbuf, 8, "%lu", mail->port);
res = getaddrinfo(mail->host, portbuf, &hints, &ai);
if (res != 0) {
NORM_ERR("IMAP getaddrinfo: %s", gai_strerror(res));
fail++;
break;
}
#else /* HAVE_GETHOSTBYNAME_R */
if ((he_res = gethostbyname(mail->host)) == NULL) { // get the host info
herror("gethostbyname");
fail++;
break;
}
#endif /* HAVE_GETHOSTBYNAME_R */
resolved_host = 1;
}
if (fail > 0) {
@ -694,22 +693,18 @@ static void *imap_thread(void *arg)
mail->user, mail->host, fail + 1, mail->retries);
}
do {
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
fail++;
break;
for (rp = ai; rp != NULL; rp = rp->ai_next) {
sockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (sockfd == -1) {
continue;
}
if (connect(sockfd, rp->ai_addr, rp->ai_addrlen) != -1) {
break;
}
close(sockfd);
}
// host byte order
their_addr.sin_family = AF_INET;
// short, network byte order
their_addr.sin_port = htons(mail->port);
their_addr.sin_addr = *((struct in_addr *) he_res->h_addr);
// zero the rest of the struct
memset(&(their_addr.sin_zero), '\0', 8);
if (connect(sockfd, (struct sockaddr *) &their_addr,
sizeof(struct sockaddr)) == -1) {
freeaddrinfo(ai);
if (rp == NULL) {
perror("connect");
fail++;
break;
@ -1012,31 +1007,30 @@ static void *pop3_thread(void *arg)
unsigned int fail = 0;
unsigned long old_unseen = ULONG_MAX;
struct stat stat_buf;
struct hostent he, *he_res = 0;
int he_errno;
char hostbuff[2048];
struct sockaddr_in their_addr; // connector's address information
struct mail_s *mail = (struct mail_s *)arg;
char resolved_host = 0;
struct addrinfo hints;
struct addrinfo *ai, *rp;
char portbuf[8];
while (fail < mail->retries) {
struct timeval fetchtimeout;
int res;
fd_set fdset;
if (!resolved_host) {
#ifdef HAVE_GETHOSTBYNAME_R
if (gethostbyname_r(mail->host, &he, hostbuff, sizeof(hostbuff), &he_res, &he_errno)) { // get the host info
NORM_ERR("POP3 gethostbyname_r: %s", hstrerror(h_errno));
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = 0;
hints.ai_protocol = 0;
snprintf(portbuf, 8, "%lu", mail->port);
res = getaddrinfo(mail->host, portbuf, &hints, &ai);
if (res != 0) {
NORM_ERR("POP3 getaddrinfo: %s", gai_strerror(res));
fail++;
break;
}
#else /* HAVE_GETHOSTBYNAME_R */
if ((he_res = gethostbyname(mail->host)) == NULL) { // get the host info
herror("gethostbyname");
fail++;
break;
}
#endif /* HAVE_GETHOSTBYNAME_R */
resolved_host = 1;
}
if (fail > 0) {
@ -1044,22 +1038,18 @@ static void *pop3_thread(void *arg)
mail->user, mail->host, fail + 1, mail->retries);
}
do {
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
fail++;
break;
for (rp = ai; rp != NULL; rp = rp->ai_next) {
sockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (sockfd == -1) {
continue;
}
if (connect(sockfd, rp->ai_addr, rp->ai_addrlen) != -1) {
break;
}
close(sockfd);
}
// host byte order
their_addr.sin_family = AF_INET;
// short, network byte order
their_addr.sin_port = htons(mail->port);
their_addr.sin_addr = *((struct in_addr *) he_res->h_addr);
// zero the rest of the struct
memset(&(their_addr.sin_zero), '\0', 8);
if (connect(sockfd, (struct sockaddr *) &their_addr,
sizeof(struct sockaddr)) == -1) {
freeaddrinfo(ai);
if (rp == NULL) {
perror("connect");
fail++;
break;

View File

@ -66,28 +66,38 @@ void parse_read_tcp_arg(struct text_object *obj, const char *arg, void *free_at_
void print_read_tcp(struct text_object *obj, char *p, int p_max_size)
{
int sock, received;
struct sockaddr_in addr;
struct hostent* he;
fd_set readfds;
struct timeval tv;
struct read_tcp_data *rtd = obj->data.opaque;
struct addrinfo hints;
struct addrinfo* airesult, *rp;
char portbuf[8];
if (!rtd)
return;
if (!(he = gethostbyname(rtd->host))) {
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = 0;
hints.ai_protocol = 0;
snprintf(portbuf, 8, "%d", rtd->port);
if (getaddrinfo(rtd->host, portbuf, &hints, &airesult)) {
NORM_ERR("read_tcp: Problem with resolving the hostname");
return;
}
if ((sock = socket(he->h_addrtype, SOCK_STREAM, 0)) == -1) {
NORM_ERR("read_tcp: Couldn't create a socket");
return;
for (rp = airesult; rp != NULL; rp = rp->ai_next) {
sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (sock == -1) {
continue;
}
if (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1) {
break;
}
close(sock);
}
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = rtd->port;
memcpy(&addr.sin_addr, he->h_addr, he->h_length);
if (connect(sock, (struct sockaddr*)&addr, sizeof(struct sockaddr)) != 0) {
freeaddrinfo(airesult);
if (rp == NULL) {
NORM_ERR("read_tcp: Couldn't create a connection");
return;
}