gnunet-gns.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2012-2013, 2017-2018 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file gnunet-gns.c
  18. * @brief command line tool to access distributed GNS
  19. * @author Christian Grothoff
  20. */
  21. #include "platform.h"
  22. #include <gnunet_util_lib.h>
  23. #include <gnunet_dnsparser_lib.h>
  24. #include <gnunet_gnsrecord_lib.h>
  25. #include <gnunet_namestore_service.h>
  26. #include <gnunet_gns_service.h>
  27. /**
  28. * Configuration we are using.
  29. */
  30. static const struct GNUNET_CONFIGURATION_Handle *cfg;
  31. /**
  32. * Handle to GNS service.
  33. */
  34. static struct GNUNET_GNS_Handle *gns;
  35. /**
  36. * GNS name to lookup. (-u option)
  37. */
  38. static char *lookup_name;
  39. /**
  40. * record type to look up (-t option)
  41. */
  42. static char *lookup_type;
  43. /**
  44. * raw output
  45. */
  46. static int raw;
  47. /**
  48. * Desired record type.
  49. */
  50. static uint32_t rtype;
  51. /**
  52. * Handle to lookup request
  53. */
  54. static struct GNUNET_GNS_LookupWithTldRequest *lr;
  55. /**
  56. * Global return value.
  57. * 0 on success (default),
  58. * 1 on internal failures
  59. * 2 on launch failure,
  60. * 4 if the name is not a GNS-supported TLD,
  61. */
  62. static int global_ret;
  63. /**
  64. * Task run on shutdown. Cleans up everything.
  65. *
  66. * @param cls unused
  67. */
  68. static void
  69. do_shutdown (void *cls)
  70. {
  71. (void) cls;
  72. if (NULL != lr)
  73. {
  74. GNUNET_GNS_lookup_with_tld_cancel (lr);
  75. lr = NULL;
  76. }
  77. if (NULL != gns)
  78. {
  79. GNUNET_GNS_disconnect (gns);
  80. gns = NULL;
  81. }
  82. }
  83. /**
  84. * Function called with the result of a GNS lookup.
  85. *
  86. * @param cls the 'const char *' name that was resolved
  87. * @param was_gns #GNUNET_NO if TLD did not indicate use of GNS
  88. * @param rd_count number of records returned
  89. * @param rd array of @a rd_count records with the results
  90. */
  91. static void
  92. process_lookup_result (void *cls,
  93. int was_gns,
  94. uint32_t rd_count,
  95. const struct GNUNET_GNSRECORD_Data *rd)
  96. {
  97. const char *name = cls;
  98. const char *typename;
  99. char* string_val;
  100. lr = NULL;
  101. if (GNUNET_NO == was_gns)
  102. {
  103. global_ret = 4; /* not for GNS */
  104. GNUNET_SCHEDULER_shutdown ();
  105. return;
  106. }
  107. if (! raw)
  108. {
  109. if (0 == rd_count)
  110. printf ("No results.\n");
  111. else
  112. printf ("%s:\n",
  113. name);
  114. }
  115. for (uint32_t i=0; i<rd_count; i++)
  116. {
  117. if ( (rd[i].record_type != rtype) &&
  118. (GNUNET_GNSRECORD_TYPE_ANY != rtype) )
  119. continue;
  120. typename = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type);
  121. string_val = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
  122. rd[i].data,
  123. rd[i].data_size);
  124. if (NULL == string_val)
  125. {
  126. fprintf (stderr,
  127. "Record %u of type %d malformed, skipping\n",
  128. (unsigned int) i,
  129. (int) rd[i].record_type);
  130. continue;
  131. }
  132. if (raw)
  133. printf ("%s\n",
  134. string_val);
  135. else
  136. printf ("Got `%s' record: %s\n",
  137. typename,
  138. string_val);
  139. GNUNET_free (string_val);
  140. }
  141. GNUNET_SCHEDULER_shutdown ();
  142. }
  143. /**
  144. * Main function that will be run.
  145. *
  146. * @param cls closure
  147. * @param args remaining command-line arguments
  148. * @param cfgfile name of the configuration file used (for saving, can be NULL!)
  149. * @param c configuration
  150. */
  151. static void
  152. run (void *cls,
  153. char *const *args,
  154. const char *cfgfile,
  155. const struct GNUNET_CONFIGURATION_Handle *c)
  156. {
  157. (void) cls;
  158. (void) args;
  159. (void) cfgfile;
  160. cfg = c;
  161. gns = GNUNET_GNS_connect (cfg);
  162. if (NULL == gns)
  163. {
  164. fprintf (stderr,
  165. _("Failed to connect to GNS\n"));
  166. global_ret = 2;
  167. return;
  168. }
  169. GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
  170. NULL);
  171. if (NULL != lookup_type)
  172. rtype = GNUNET_GNSRECORD_typename_to_number (lookup_type);
  173. else
  174. rtype = GNUNET_DNSPARSER_TYPE_A;
  175. if (UINT32_MAX == rtype)
  176. {
  177. fprintf (stderr,
  178. _("Invalid typename specified, assuming `ANY'\n"));
  179. rtype = GNUNET_GNSRECORD_TYPE_ANY;
  180. }
  181. lr = GNUNET_GNS_lookup_with_tld (gns,
  182. lookup_name,
  183. rtype,
  184. GNUNET_GNS_LO_DEFAULT,
  185. &process_lookup_result,
  186. lookup_name);
  187. if (NULL == lr)
  188. {
  189. global_ret = 2;
  190. GNUNET_SCHEDULER_shutdown ();
  191. return;
  192. }
  193. }
  194. /**
  195. * The main function for gnunet-gns.
  196. *
  197. * @param argc number of arguments from the command line
  198. * @param argv command line arguments
  199. * @return 0 ok, 1 on error
  200. */
  201. int
  202. main (int argc,
  203. char *const *argv)
  204. {
  205. struct GNUNET_GETOPT_CommandLineOption options[] = {
  206. GNUNET_GETOPT_option_mandatory
  207. (GNUNET_GETOPT_option_string ('u',
  208. "lookup",
  209. "NAME",
  210. gettext_noop ("Lookup a record for the given name"),
  211. &lookup_name)),
  212. GNUNET_GETOPT_option_string ('t',
  213. "type",
  214. "TYPE",
  215. gettext_noop ("Specify the type of the record to lookup"),
  216. &lookup_type),
  217. GNUNET_GETOPT_option_flag ('r',
  218. "raw",
  219. gettext_noop ("No unneeded output"),
  220. &raw),
  221. GNUNET_GETOPT_OPTION_END
  222. };
  223. int ret;
  224. if (GNUNET_OK !=
  225. GNUNET_STRINGS_get_utf8_args (argc, argv,
  226. &argc, &argv))
  227. return 2;
  228. GNUNET_log_setup ("gnunet-gns",
  229. "WARNING",
  230. NULL);
  231. ret = GNUNET_PROGRAM_run (argc, argv,
  232. "gnunet-gns",
  233. _("GNUnet GNS resolver tool"),
  234. options,
  235. &run, NULL);
  236. GNUNET_free ((void*) argv);
  237. if (GNUNET_OK != ret)
  238. return 1;
  239. return global_ret;
  240. }
  241. /* end of gnunet-gns.c */