fix test case, implement base32 argument parser logic
[oweals/gnunet.git] / src / util / gnunet-resolver.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2010 GNUnet e.V.
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      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      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, USA.
19 */
20
21 /**
22  * @file util/gnunet-resolver.c
23  * @brief tool to test resolver
24  * @author Christian Grothoff
25  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "gnunet_resolver_service.h"
29
30 #define GET_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
31
32 /**
33  * Flag for reverse lookup.
34  */
35 static int reverse;
36
37
38 /**
39  * Prints each hostname obtained from DNS.
40  *
41  * @param cls closure (unused)
42  * @param hostname one of the names for the host, NULL
43  *        on the last call to the callback
44  */
45 static void
46 print_hostname (void *cls,
47                 const char *hostname)
48 {
49   if (NULL == hostname)
50     return;
51   FPRINTF (stdout, "%s\n", hostname);
52 }
53
54
55 /**
56  * Callback function to display address.
57  *
58  * @param cls closure (unused)
59  * @param addr one of the addresses of the host, NULL for the last address
60  * @param addrlen length of the address
61  */
62 static void
63 print_sockaddr (void *cls, const struct sockaddr *addr, socklen_t addrlen)
64 {
65   if (NULL == addr)
66     return;
67   FPRINTF (stdout, "%s\n", GNUNET_a2s (addr, addrlen));
68 }
69
70
71 /**
72  * Main function that will be run by the scheduler.
73  *
74  * @param cls closure
75  * @param args remaining command-line arguments
76  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
77  * @param cfg configuration
78  */
79 static void
80 run (void *cls, char *const *args, const char *cfgfile,
81      const struct GNUNET_CONFIGURATION_Handle *cfg)
82 {
83   const struct sockaddr *sa;
84   socklen_t salen;
85   struct sockaddr_in v4;
86   struct sockaddr_in6 v6;
87
88   if (args[0] == NULL)
89     return;
90   if (! reverse)
91   {
92     GNUNET_RESOLVER_ip_get (args[0], AF_UNSPEC, GET_TIMEOUT, &print_sockaddr, NULL);
93     return;
94   }
95
96   sa = NULL;
97   memset (&v4, 0, sizeof (v4));
98   v4.sin_family = AF_INET;
99 #if HAVE_SOCKADDR_IN_SIN_LEN
100   v4.sin_len = sizeof (v4);
101 #endif
102   if (1 == inet_pton (AF_INET,
103                       args[0],
104                       &v4.sin_addr))
105   {
106     sa = (struct sockaddr *) &v4;
107     salen = sizeof (v4);
108   }
109   memset (&v6, 0, sizeof (v6));
110   v6.sin6_family = AF_INET6;
111 #if HAVE_SOCKADDR_IN_SIN_LEN
112   v6.sin6_len = sizeof (v6);
113 #endif
114   if (1 == inet_pton (AF_INET6,
115                       args[0],
116                       &v6.sin6_addr))
117   {
118     sa = (struct sockaddr *) &v6;
119     salen = sizeof (v6);
120   }
121   if (NULL == sa)
122   {
123     fprintf (stderr,
124              "`%s' is not a valid IP: %s\n",
125              args[0],
126              strerror (errno));
127     return;
128   }
129   GNUNET_RESOLVER_hostname_get (sa, salen,
130                                 GNUNET_YES,
131                                 GET_TIMEOUT,
132                                 &print_hostname,
133                                 NULL);
134 }
135
136
137 /**
138  * The main function to access GNUnet's DNS resolver.
139  *
140  * @param argc number of arguments from the command line
141  * @param argv command line arguments
142  * @return 0 ok, 1 on error
143  */
144 int
145 main (int argc, char *const *argv)
146 {
147   struct GNUNET_GETOPT_CommandLineOption options[] = {
148     GNUNET_GETOPT_OPTION_SET_ONE ('r',
149                                   "reverse",
150                                   gettext_noop ("perform a reverse lookup"),
151                                   &reverse),
152     GNUNET_GETOPT_OPTION_END
153   };
154   int ret;
155
156   if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
157     return 2;
158
159   ret = (GNUNET_OK ==
160          GNUNET_PROGRAM_run (argc, argv, "gnunet-resolver [hostname]",
161                              gettext_noop ("Use build-in GNUnet stub resolver"),
162                              options, &run, NULL)) ? 0 : 1;
163   GNUNET_free ((void*) argv);
164   return ret;
165 }
166
167 /* end of gnunet-resolver.c */