Merge branch 'master' of ssh://gnunet.org/gnunet
[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      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 #include <string.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include "nss_gns_query.h"
22 #include <arpa/inet.h>
23 #include <sys/types.h>
24 #include <sys/socket.h>
25 #include <netinet/in.h>
26
27
28 /**
29  * Wrapper function that uses gnunet-gns cli tool to resolve
30  * an IPv4/6 address.
31  *
32  * @param af address family
33  * @param name the name to resolve
34  * @param u the userdata (result struct)
35  * @return -1 on error else 0
36  */
37 int
38 gns_resolve_name (int af,
39                   const char *name,
40                   struct userdata *u)
41 {
42   FILE *p;
43   char *cmd;
44   char line[128];
45   int ret;
46
47   if (AF_INET6 == af)
48   {
49     if (-1 == asprintf (&cmd,
50                         "%s -t AAAA -u %s\n",
51                         "gnunet-gns -r",
52                         name))
53       return -1;
54   }
55   else
56   {
57     if (-1 == asprintf (&cmd,
58                         "%s %s\n",
59                         "gnunet-gns -r -u",
60                         name))
61       return -1;
62   }
63   if (NULL == (p = popen (cmd, "r")))
64   {
65     free (cmd);
66     return -1;
67   }
68   while (NULL != fgets (line,
69                         sizeof(line),
70                         p))
71   {
72     if (u->count >= MAX_ENTRIES)
73       break;
74     if (line[strlen(line)-1] == '\n')
75     {
76       line[strlen(line)-1] = '\0';
77       if (AF_INET == af)
78       {
79         if (inet_pton(af,
80                       line,
81                       &u->data.ipv4[u->count]))
82         {
83           u->count++;
84           u->data_len += sizeof(ipv4_address_t);
85         }
86         else
87         {
88           pclose (p);
89           free (cmd);
90           return -1;
91         }
92       }
93       else if (AF_INET6 == af)
94       {
95         if (inet_pton(af,
96                       line,
97                       &u->data.ipv6[u->count]))
98         {
99           u->count++;
100           u->data_len += sizeof(ipv6_address_t);
101         }
102         else
103         {
104           pclose (p);
105           free (cmd);
106           return -1;
107         }
108       }
109     }
110   }
111   ret = pclose (p);
112   free (cmd);
113   if (4 == ret)
114     return -2; /* not for GNS */
115   if (3 == ret)
116     return -3; /* timeout -> not found */
117   if ( (2 == ret) || (1 == ret) )
118     return -2; /* launch failure -> service unavailable */
119   return 0;
120 }
121
122 /* end of nss_gns_query.c */