2947e80de71c3dfd498580289fd07a48c2f9c61a
[oweals/gnunet.git] / src / gns / nss / nss_gns_query.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2012 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Affero General Public License for more details.
14 */
15 #include <string.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include "nss_gns_query.h"
19 #include <arpa/inet.h>
20 #include <sys/types.h>
21 #include <sys/socket.h>
22 #include <netinet/in.h>
23
24
25 /**
26  * Wrapper function that uses gnunet-gns cli tool to resolve
27  * an IPv4/6 address.
28  *
29  * @param af address family
30  * @param name the name to resolve
31  * @param u the userdata (result struct)
32  * @return -1 on error else 0
33  */
34 int
35 gns_resolve_name (int af,
36                   const char *name,
37                   struct userdata *u)
38 {
39   FILE *p;
40   char *cmd;
41   char line[128];
42   int ret;
43
44   if (AF_INET6 == af)
45   {
46     if (-1 == asprintf (&cmd,
47                         "%s -t AAAA -u %s\n",
48                         "gnunet-gns -r", name))
49       return -1;
50   }
51   else
52   {
53     if (-1 == asprintf (&cmd,
54                         "%s %s\n",
55                         "gnunet-gns -r -u", name))
56       return -1;
57   }
58   if (NULL == (p = popen (cmd, "r")))
59   {
60     free (cmd);
61     return -1;
62   }
63   while (NULL != fgets (line, sizeof(line), p))
64   {
65     if (u->count >= MAX_ENTRIES)
66       break;
67     if (line[strlen(line)-1] == '\n')
68     {
69       line[strlen(line)-1] = '\0';
70       if (AF_INET == af)
71       {
72         if (inet_pton(af, line, &(u->data.ipv4[u->count])))
73         {
74           u->count++;
75           u->data_len += sizeof(ipv4_address_t);
76         }
77         else
78         {
79           pclose (p);
80           free (cmd);
81           return -1;
82         }
83       }
84       else if (AF_INET6 == af)
85       {
86         if (inet_pton(af, line, &(u->data.ipv6[u->count])))
87         {
88           u->count++;
89           u->data_len += sizeof(ipv6_address_t);
90         }
91         else
92         {
93           pclose (p);
94           free (cmd);
95           return -1;
96         }
97       }
98     }
99   }
100   ret = pclose (p);
101   free (cmd);
102   if (4 == ret)
103     return -2; /* not for GNS */
104   if (3 == ret)
105     return -3; /* timeout */
106   return 0;
107 }
108 /* end of nss_gns_query.c */