Add IPv6 support from the IMAP account plug-in

This commit is contained in:
Pierre Pronchery 2015-03-14 14:16:41 +01:00
parent 6c8a534afa
commit d521872a5e

View File

@ -161,7 +161,7 @@ static int _pop3_refresh(POP3 * pop3, AccountFolder * folder,
static POP3Command * _pop3_command(POP3 * pop3, POP3Context context,
char const * command);
static int _pop3_lookup(POP3 * pop3, char const * hostname, uint16_t port,
struct sockaddr_in * sa);
struct addrinfo ** ai);
static int _pop3_parse(POP3 * pop3);
/* events */
@ -376,18 +376,19 @@ static POP3Command * _pop3_command(POP3 * pop3, POP3Context context,
/* pop3_lookup */
static int _pop3_lookup(POP3 * pop3, char const * hostname, uint16_t port,
struct sockaddr_in * sa)
struct addrinfo ** ai)
{
struct hostent * he;
struct addrinfo hints;
int res;
if(hostname == NULL)
return -error_set_code(1, "%s", strerror(errno));
if((he = gethostbyname(hostname)) == NULL)
return -error_set_code(1, "%s", hstrerror(h_errno));
memset(sa, 0, sizeof(*sa));
sa->sin_family = AF_INET;
sa->sin_port = htons(port);
sa->sin_addr.s_addr = *((uint32_t*)he->h_addr_list[0]);
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
if((res = getaddrinfo(hostname, NULL, &hints, ai)) != 0)
return -error_set_code(1, "%s", gai_strerror(res));
return 0;
}
@ -661,7 +662,8 @@ static gboolean _on_connect(gpointer data)
char const * hostname;
char const * p;
uint16_t port;
struct sockaddr_in sa;
struct addrinfo * ai;
struct sockaddr_in * sa;
int res;
char buf[128];
@ -679,7 +681,7 @@ static gboolean _on_connect(gpointer data)
return FALSE;
port = (unsigned long)p;
/* lookup the address */
if(_pop3_lookup(pop3, hostname, port, &sa) != 0)
if(_pop3_lookup(pop3, hostname, port, &ai) != 0)
{
helper->error(helper->account, error_get(), 1);
return FALSE;
@ -697,8 +699,14 @@ static gboolean _on_connect(gpointer data)
/* FIXME report properly as a warning instead */
helper->error(NULL, strerror(errno), 1);
/* report the current status */
snprintf(buf, sizeof(buf), "Connecting to %s (%s:%u)", hostname,
inet_ntoa(sa.sin_addr), port);
if(ai->ai_family == AF_INET)
{
sa = (struct sockaddr_in *)ai->ai_addr;
snprintf(buf, sizeof(buf), "Connecting to %s (%s:%u)", hostname,
inet_ntoa(sa->sin_addr), port);
}
else
snprintf(buf, sizeof(buf), "Connecting to %s", hostname);
_pop3_event_status(pop3, AS_CONNECTING, buf);
/* connect to the remote host */
if((connect(pop3->fd, (struct sockaddr *)&sa, sizeof(sa)) != 0
@ -709,10 +717,12 @@ static gboolean _on_connect(gpointer data)
strerror(errno));
helper->error(helper->account, buf, 1);
_pop3_stop(pop3);
freeaddrinfo(ai);
return FALSE;
}
pop3->wr_source = g_io_add_watch(pop3->channel, G_IO_OUT,
_on_watch_can_connect, pop3);
freeaddrinfo(ai);
return FALSE;
}
@ -761,7 +771,8 @@ static gboolean _on_watch_can_connect(GIOChannel * source,
socklen_t s = sizeof(res);
char const * hostname = pop3->config[P3CV_HOSTNAME].value;
uint16_t port = (unsigned long)pop3->config[P3CV_PORT].value;
struct sockaddr_in sa;
struct addrinfo * ai;
struct sockaddr_in * sa;
SSL_CTX * ssl_ctx;
char buf[128];
@ -780,11 +791,19 @@ static gboolean _on_watch_can_connect(GIOChannel * source,
return FALSE;
}
/* XXX remember the address instead */
if(_pop3_lookup(pop3, hostname, port, &sa) == 0)
if(_pop3_lookup(pop3, hostname, port, &ai) == 0)
{
snprintf(buf, sizeof(buf), "Connected to %s (%s:%u)",
hostname, inet_ntoa(sa.sin_addr), port);
if(ai->ai_family == AF_INET)
{
sa = (struct sockaddr_in *)ai->ai_addr;
snprintf(buf, sizeof(buf), "Connected to %s (%s:%u)",
hostname, inet_ntoa(sa->sin_addr),
port);
}
else
snprintf(buf, sizeof(buf), "Connected to %s", hostname);
_pop3_event_status(pop3, AS_CONNECTED, buf);
freeaddrinfo(ai);
}
pop3->wr_source = 0;
/* setup SSL */