Merged from silc_1_0_branch.
[silc.git] / apps / irssi / src / core / net-nonblock.c
index 6af87a96fac464da4be0e2bff820605772ea01d4..ce6be49af5dc679eebc8d16fc1f61fd1eac3d7bd 100644 (file)
@@ -73,13 +73,15 @@ static int g_io_channel_read_block(GIOChannel *channel, void *data, int len)
 
 /* nonblocking gethostbyname(), ip (IPADDR) + error (int, 0 = not error) is
    written to pipe when found PID of the resolver child is returned */
-int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe)
+int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe,
+                              int reverse_lookup)
 {
        RESOLVED_IP_REC rec;
        const char *errorstr;
 #ifndef WIN32
        int pid;
 #endif
+       int len;
 
        g_return_val_if_fail(addr != NULL, FALSE);
 
@@ -103,6 +105,13 @@ int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe)
        rec.error = net_gethostbyname(addr, &rec.ip4, &rec.ip6);
        if (rec.error == 0) {
                errorstr = NULL;
+               if (reverse_lookup) {
+                       /* reverse lookup the IP, ignore any error */
+                       if (rec.ip4.family != 0)
+                               net_gethostbyaddr(&rec.ip4, &rec.host4);
+                       if (rec.ip6.family != 0)
+                               net_gethostbyaddr(&rec.ip6, &rec.host6);
+               }
        } else {
                errorstr = net_gethosterror(rec.error);
                rec.errlen = errorstr == NULL ? 0 : strlen(errorstr)+1;
@@ -111,6 +120,22 @@ int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe)
         g_io_channel_write_block(pipe, &rec, sizeof(rec));
        if (rec.errlen != 0)
                g_io_channel_write_block(pipe, (void *) errorstr, rec.errlen);
+       else {
+               if (rec.host4) {
+                       len = strlen(rec.host4) + 1;
+                       g_io_channel_write_block(pipe, (void *) &len, 
+                                                      sizeof(int));
+                       g_io_channel_write_block(pipe, (void *) rec.host4,
+                                                      len);
+               }
+               if (rec.host6) {
+                       len = strlen(rec.host6) + 1;
+                       g_io_channel_write_block(pipe, (void *) &len,
+                                                      sizeof(int));
+                       g_io_channel_write_block(pipe, (void *) rec.host6,
+                                                      len);
+               }
+       }
 
 #ifndef WIN32
        if (pid == 0)
@@ -124,8 +149,12 @@ int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe)
 /* get the resolved IP address */
 int net_gethostbyname_return(GIOChannel *pipe, RESOLVED_IP_REC *rec)
 {
+       int len;
+
        rec->error = -1;
        rec->errorstr = NULL;
+       rec->host4 = NULL;
+       rec->host6 = NULL;
 
 #ifndef WIN32
        fcntl(g_io_channel_unix_get_fd(pipe), F_SETFL, O_NONBLOCK);
@@ -143,6 +172,17 @@ int net_gethostbyname_return(GIOChannel *pipe, RESOLVED_IP_REC *rec)
                   reason, just ignore it. */
                rec->errorstr = g_malloc0(rec->errlen+1);
                 g_io_channel_read_block(pipe, rec->errorstr, rec->errlen);
+       } else {
+               if (rec->host4) {
+                       g_io_channel_read_block(pipe, &len, sizeof(int));
+                       rec->host4 = g_malloc0(len);
+                       g_io_channel_read_block(pipe, rec->host4, len);
+               }
+               if (rec->host6) {
+                       g_io_channel_read_block(pipe, &len, sizeof(int));
+                       rec->host6 = g_malloc0(len);
+                       g_io_channel_read_block(pipe, rec->host6, len);
+               }
        }
 
        return 0;
@@ -244,7 +284,7 @@ int net_connect_nonblock(const char *server, int port, const IPADDR *my_ip,
        rec->pipes[1] = g_io_channel_unix_new(fd[1]);
 
        /* start nonblocking host name lookup */
-       net_gethostbyname_nonblock(server, rec->pipes[1]);
+       net_gethostbyname_nonblock(server, rec->pipes[1], 0);
        rec->tag = g_input_add(rec->pipes[0], G_INPUT_READ,
                               (GInputFunction) simple_readpipe, rec);