mirror of
https://github.com/Llewellynvdm/conky.git
synced 2024-12-27 04:32:55 +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:
parent
8ff9b58c3b
commit
abeadb59d7
@ -190,40 +190,37 @@ 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(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(apcupsd.host);
|
||||
if (!he) {
|
||||
herror("gethostbyname");
|
||||
break;
|
||||
}
|
||||
#endif /* HAVE_GETHOSTBYNAME_R */
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = 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;
|
||||
}
|
||||
|
106
src/mail.cc
106
src/mail.cc
@ -659,11 +659,12 @@ static void imap_thread(thread_handle &handle, struct mail_s *mail)
|
||||
unsigned long old_unseen = ULONG_MAX;
|
||||
unsigned long old_messages = ULONG_MAX;
|
||||
struct stat stat_buf;
|
||||
struct hostent *he_res = 0;
|
||||
struct sockaddr_in their_addr; // connector's address information
|
||||
int has_idle = 0;
|
||||
int threadfd = handle.readfd();
|
||||
char resolved_host = 0;
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *ai, *rp;
|
||||
char portbuf[8];
|
||||
|
||||
while (fail < mail->retries) {
|
||||
struct timeval fetchtimeout;
|
||||
@ -671,23 +672,19 @@ static void imap_thread(thread_handle &handle, struct mail_s *mail)
|
||||
fd_set fdset;
|
||||
|
||||
if (!resolved_host) {
|
||||
#ifdef HAVE_GETHOSTBYNAME_R
|
||||
int he_errno;
|
||||
struct hostent he;
|
||||
char hostbuff[2048];
|
||||
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);
|
||||
|
||||
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));
|
||||
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) {
|
||||
@ -695,22 +692,18 @@ static void imap_thread(thread_handle &handle, struct mail_s *mail)
|
||||
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;
|
||||
@ -1011,32 +1004,29 @@ static void pop3_thread(thread_handle &handle, struct mail_s *mail)
|
||||
unsigned int fail = 0;
|
||||
unsigned long old_unseen = ULONG_MAX;
|
||||
struct stat stat_buf;
|
||||
struct hostent *he_res = 0;
|
||||
struct sockaddr_in their_addr; // connector's address information
|
||||
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
|
||||
int he_errno;
|
||||
struct hostent he;
|
||||
char hostbuff[2048];
|
||||
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);
|
||||
|
||||
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));
|
||||
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 +1034,18 @@ static void pop3_thread(thread_handle &handle, struct mail_s *mail)
|
||||
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;
|
||||
|
@ -145,29 +145,39 @@ void print_tcp_ping(struct text_object *obj, char *p, int p_max_size)
|
||||
void print_read_tcpip(struct text_object *obj, char *p, int p_max_size, int protocol)
|
||||
{
|
||||
int sock, received;
|
||||
struct sockaddr_in addr;
|
||||
struct hostent* he;
|
||||
fd_set readfds;
|
||||
struct timeval tv;
|
||||
struct read_tcpip_data *rtd = (struct read_tcpip_data *) obj->data.opaque;
|
||||
ssize_t written; //only used to to suppress warning (gcc wants the returnvalue of write() in a var)
|
||||
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 = protocol==IPPROTO_TCP ? SOCK_STREAM : SOCK_DGRAM;
|
||||
hints.ai_flags = 0;
|
||||
hints.ai_protocol = protocol;
|
||||
snprintf(portbuf, 8, "%d", rtd->port);
|
||||
if (getaddrinfo(rtd->host, portbuf, &hints, &airesult)) {
|
||||
NORM_ERR("%s: Problem with resolving the hostname", protocol == IPPROTO_TCP ? "read_tcp" : "read_udp");
|
||||
return;
|
||||
}
|
||||
if ((sock = socket(he->h_addrtype, protocol == IPPROTO_TCP ? SOCK_STREAM : SOCK_DGRAM, protocol)) == -1) {
|
||||
NORM_ERR("%s: Couldn't create a socket", protocol == IPPROTO_TCP ? "read_tcp" : "read_udp");
|
||||
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);
|
||||
return;
|
||||
}
|
||||
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) {
|
||||
if(protocol == IPPROTO_TCP) {
|
||||
NORM_ERR("read_tcp: Couldn't create a connection");
|
||||
} else {
|
||||
@ -175,8 +185,10 @@ void print_read_tcpip(struct text_object *obj, char *p, int p_max_size, int prot
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(protocol == IPPROTO_UDP)
|
||||
written = write(sock, NULL, 0); //when using udp send a zero-length packet to let the other end know of our existence
|
||||
if(protocol == IPPROTO_UDP) {
|
||||
//when using udp send a zero-length packet to let the other end know of our existence
|
||||
(void) write(sock, NULL, 0);
|
||||
}
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(sock, &readfds);
|
||||
tv.tv_sec = 1;
|
||||
|
Loading…
Reference in New Issue
Block a user