mirror of
https://github.com/Llewellynvdm/conky.git
synced 2024-11-15 17:47:09 +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
a25985f00b
commit
74392a5491
@ -164,40 +164,37 @@ int update_apcupsd(void) {
|
|||||||
memcpy(apc.items[i], "N/A", 4); // including \0
|
memcpy(apc.items[i], "N/A", 4); // including \0
|
||||||
|
|
||||||
do {
|
do {
|
||||||
struct hostent* he = 0;
|
struct addrinfo hints;
|
||||||
struct sockaddr_in addr;
|
struct addrinfo *ai, *rp;
|
||||||
|
int res;
|
||||||
short sz = 0;
|
short sz = 0;
|
||||||
#ifdef HAVE_GETHOSTBYNAME_R
|
char portbuf[8];
|
||||||
struct hostent he_mem;
|
|
||||||
int he_errno;
|
|
||||||
char hostbuff[2048];
|
|
||||||
#endif
|
|
||||||
//
|
//
|
||||||
// connect to apcupsd daemon
|
// connect to apcupsd daemon
|
||||||
//
|
//
|
||||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
memset(&hints, 0, sizeof(struct addrinfo));
|
||||||
if (sock < 0) {
|
hints.ai_family = AF_UNSPEC;
|
||||||
perror("socket");
|
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;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_GETHOSTBYNAME_R
|
for (rp = ai; rp != NULL; rp = rp->ai_next) {
|
||||||
if (gethostbyname_r(info.apcupsd.host, &he_mem, hostbuff, sizeof(hostbuff), &he, &he_errno) || !he ) {
|
sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
||||||
NORM_ERR("APCUPSD gethostbyname_r: %s", hstrerror(h_errno));
|
if (sock == -1) {
|
||||||
break;
|
continue;
|
||||||
|
}
|
||||||
|
if (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
close(sock);
|
||||||
}
|
}
|
||||||
#else /* HAVE_GETHOSTBYNAME_R */
|
freeaddrinfo(ai);
|
||||||
he = gethostbyname(info.apcupsd.host);
|
if (rp == NULL) {
|
||||||
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) {
|
|
||||||
// no error reporting, the daemon is probably not running
|
// no error reporting, the daemon is probably not running
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
106
src/mail.c
106
src/mail.c
@ -659,14 +659,13 @@ static void *imap_thread(void *arg)
|
|||||||
unsigned long old_unseen = ULONG_MAX;
|
unsigned long old_unseen = ULONG_MAX;
|
||||||
unsigned long old_messages = ULONG_MAX;
|
unsigned long old_messages = ULONG_MAX;
|
||||||
struct stat stat_buf;
|
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;
|
struct mail_s *mail = (struct mail_s *)arg;
|
||||||
int has_idle = 0;
|
int has_idle = 0;
|
||||||
int threadfd = timed_thread_readfd(mail->p_timed_thread);
|
int threadfd = timed_thread_readfd(mail->p_timed_thread);
|
||||||
char resolved_host = 0;
|
char resolved_host = 0;
|
||||||
|
struct addrinfo hints;
|
||||||
|
struct addrinfo *ai, *rp;
|
||||||
|
char portbuf[8];
|
||||||
|
|
||||||
while (fail < mail->retries) {
|
while (fail < mail->retries) {
|
||||||
struct timeval fetchtimeout;
|
struct timeval fetchtimeout;
|
||||||
@ -674,19 +673,19 @@ static void *imap_thread(void *arg)
|
|||||||
fd_set fdset;
|
fd_set fdset;
|
||||||
|
|
||||||
if (!resolved_host) {
|
if (!resolved_host) {
|
||||||
#ifdef HAVE_GETHOSTBYNAME_R
|
memset(&hints, 0, sizeof(struct addrinfo));
|
||||||
if (gethostbyname_r(mail->host, &he, hostbuff, sizeof(hostbuff), &he_res, &he_errno)) { // get the host info
|
hints.ai_family = AF_UNSPEC;
|
||||||
NORM_ERR("IMAP gethostbyname_r: %s", hstrerror(h_errno));
|
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++;
|
fail++;
|
||||||
break;
|
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;
|
resolved_host = 1;
|
||||||
}
|
}
|
||||||
if (fail > 0) {
|
if (fail > 0) {
|
||||||
@ -694,22 +693,18 @@ static void *imap_thread(void *arg)
|
|||||||
mail->user, mail->host, fail + 1, mail->retries);
|
mail->user, mail->host, fail + 1, mail->retries);
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
|
for (rp = ai; rp != NULL; rp = rp->ai_next) {
|
||||||
perror("socket");
|
sockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
||||||
fail++;
|
if (sockfd == -1) {
|
||||||
break;
|
continue;
|
||||||
|
}
|
||||||
|
if (connect(sockfd, rp->ai_addr, rp->ai_addrlen) != -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
close(sockfd);
|
||||||
}
|
}
|
||||||
|
freeaddrinfo(ai);
|
||||||
// host byte order
|
if (rp == NULL) {
|
||||||
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) {
|
|
||||||
perror("connect");
|
perror("connect");
|
||||||
fail++;
|
fail++;
|
||||||
break;
|
break;
|
||||||
@ -1012,31 +1007,30 @@ static void *pop3_thread(void *arg)
|
|||||||
unsigned int fail = 0;
|
unsigned int fail = 0;
|
||||||
unsigned long old_unseen = ULONG_MAX;
|
unsigned long old_unseen = ULONG_MAX;
|
||||||
struct stat stat_buf;
|
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;
|
struct mail_s *mail = (struct mail_s *)arg;
|
||||||
char resolved_host = 0;
|
char resolved_host = 0;
|
||||||
|
struct addrinfo hints;
|
||||||
|
struct addrinfo *ai, *rp;
|
||||||
|
char portbuf[8];
|
||||||
|
|
||||||
while (fail < mail->retries) {
|
while (fail < mail->retries) {
|
||||||
struct timeval fetchtimeout;
|
struct timeval fetchtimeout;
|
||||||
int res;
|
int res;
|
||||||
fd_set fdset;
|
fd_set fdset;
|
||||||
if (!resolved_host) {
|
if (!resolved_host) {
|
||||||
#ifdef HAVE_GETHOSTBYNAME_R
|
memset(&hints, 0, sizeof(struct addrinfo));
|
||||||
if (gethostbyname_r(mail->host, &he, hostbuff, sizeof(hostbuff), &he_res, &he_errno)) { // get the host info
|
hints.ai_family = AF_UNSPEC;
|
||||||
NORM_ERR("POP3 gethostbyname_r: %s", hstrerror(h_errno));
|
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++;
|
fail++;
|
||||||
break;
|
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;
|
resolved_host = 1;
|
||||||
}
|
}
|
||||||
if (fail > 0) {
|
if (fail > 0) {
|
||||||
@ -1044,22 +1038,18 @@ static void *pop3_thread(void *arg)
|
|||||||
mail->user, mail->host, fail + 1, mail->retries);
|
mail->user, mail->host, fail + 1, mail->retries);
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
|
for (rp = ai; rp != NULL; rp = rp->ai_next) {
|
||||||
perror("socket");
|
sockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
||||||
fail++;
|
if (sockfd == -1) {
|
||||||
break;
|
continue;
|
||||||
|
}
|
||||||
|
if (connect(sockfd, rp->ai_addr, rp->ai_addrlen) != -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
close(sockfd);
|
||||||
}
|
}
|
||||||
|
freeaddrinfo(ai);
|
||||||
// host byte order
|
if (rp == NULL) {
|
||||||
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) {
|
|
||||||
perror("connect");
|
perror("connect");
|
||||||
fail++;
|
fail++;
|
||||||
break;
|
break;
|
||||||
|
@ -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)
|
void print_read_tcp(struct text_object *obj, char *p, int p_max_size)
|
||||||
{
|
{
|
||||||
int sock, received;
|
int sock, received;
|
||||||
struct sockaddr_in addr;
|
|
||||||
struct hostent* he;
|
|
||||||
fd_set readfds;
|
fd_set readfds;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
struct read_tcp_data *rtd = obj->data.opaque;
|
struct read_tcp_data *rtd = obj->data.opaque;
|
||||||
|
struct addrinfo hints;
|
||||||
|
struct addrinfo* airesult, *rp;
|
||||||
|
char portbuf[8];
|
||||||
|
|
||||||
if (!rtd)
|
if (!rtd)
|
||||||
return;
|
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");
|
NORM_ERR("read_tcp: Problem with resolving the hostname");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((sock = socket(he->h_addrtype, SOCK_STREAM, 0)) == -1) {
|
for (rp = airesult; rp != NULL; rp = rp->ai_next) {
|
||||||
NORM_ERR("read_tcp: Couldn't create a socket");
|
sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
||||||
return;
|
if (sock == -1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
close(sock);
|
||||||
}
|
}
|
||||||
memset(&addr, 0, sizeof(addr));
|
freeaddrinfo(airesult);
|
||||||
addr.sin_family = AF_INET;
|
if (rp == NULL) {
|
||||||
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) {
|
|
||||||
NORM_ERR("read_tcp: Couldn't create a connection");
|
NORM_ERR("read_tcp: Couldn't create a connection");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user