PageRenderTime 26ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/ndisc6-1.0.1/src/addrinfo.c

#
C | 236 lines | 174 code | 44 blank | 18 comment | 21 complexity | 76a21e81e2f8c7cd907c280e4dc9bb67 MD5 | raw file
Possible License(s): GPL-2.0
  1. /*
  2. * addrinfo.c - converts names to network addresses
  3. * $Id: addrinfo.c 646 2010-05-01 07:49:06Z remi $
  4. */
  5. /*************************************************************************
  6. * Copyright Š 2002-2009 Rémi Denis-Courmont. *
  7. * This program is free software: you can redistribute and/or modify *
  8. * it under the terms of the GNU General Public License as published by *
  9. * the Free Software Foundation, versions 2 or 3 of the license. *
  10. * *
  11. * This program is distributed in the hope that it will be useful, *
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  14. * GNU General Public License for more details. *
  15. * *
  16. * You should have received a copy of the GNU General Public License *
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>. *
  18. *************************************************************************/
  19. #ifdef HAVE_CONFIG_H
  20. # include <config.h>
  21. #endif
  22. #include <gettext.h>
  23. #include <stdio.h>
  24. #include <string.h> /* strchr() */
  25. #include <stdbool.h>
  26. #include <sys/types.h>
  27. #include <sys/socket.h>
  28. #include <netdb.h>
  29. #include <unistd.h>
  30. #include <locale.h>
  31. #ifdef HAVE_GETOPT_H
  32. # include <getopt.h>
  33. #endif
  34. #ifndef AI_IDN
  35. # define AI_IDN 0
  36. #endif
  37. static void
  38. gai_perror (int errval, const char *msg)
  39. {
  40. if (errval == EAI_SYSTEM)
  41. perror (msg);
  42. else
  43. fprintf (stderr, "%s: %s\n", msg, gai_strerror (errval));
  44. }
  45. static int
  46. printnames (const char *name, int family, int aflags, int nflags, bool single)
  47. {
  48. struct addrinfo hints, *res;
  49. memset (&hints, 0, sizeof (hints));
  50. hints.ai_family = family;
  51. hints.ai_socktype = SOCK_DGRAM;
  52. hints.ai_flags = aflags;
  53. int check = getaddrinfo (name, NULL, &hints, &res);
  54. if (check)
  55. {
  56. gai_perror (check, name);
  57. return -1;
  58. }
  59. for (struct addrinfo *ptr = res; ptr != NULL; ptr = ptr->ai_next)
  60. {
  61. char hostname[NI_MAXHOST];
  62. check = getnameinfo (ptr->ai_addr, ptr->ai_addrlen,
  63. hostname, sizeof (hostname),
  64. NULL, 0, nflags);
  65. if (check)
  66. gai_perror (check, name);
  67. else
  68. fputs (hostname, stdout);
  69. if (single)
  70. break;
  71. if (ptr->ai_next != NULL)
  72. fputc (' ', stdout);
  73. }
  74. fputc ('\n', stdout);
  75. freeaddrinfo (res);
  76. return 0;
  77. }
  78. static int
  79. printnamesf (FILE *input, int family, int aflags, int nflags, bool single)
  80. {
  81. do
  82. {
  83. char buf[NI_MAXHOST + 1], *ptr;
  84. if (fgets (buf, sizeof (buf), input) != NULL)
  85. {
  86. ptr = strchr (buf, '\n');
  87. if (ptr != NULL)
  88. *ptr = '\0';
  89. printnames (buf, family, aflags, nflags, single);
  90. }
  91. }
  92. while (!ferror (input) && !feof (input));
  93. if (ferror (input))
  94. {
  95. perror (_("Input error"));
  96. return -1;
  97. }
  98. return 0;
  99. }
  100. static int usage (const char *path)
  101. {
  102. printf (_(
  103. "Usage: %s [-4|-6] [hostnames]\n"
  104. "Converts names to addresses.\n"
  105. "\n"
  106. " -4, --ipv4 only lookup IPv4 addresses\n"
  107. " -6, --ipv6 only lookup IPv6 addresses\n"
  108. " -c, --config only return addresses for locally configured protocols\n"
  109. " -h, --help display this help and exit\n"
  110. " -m, --multiple print multiple results separated by spaces\n"
  111. " -n, --numeric do not perform forward hostname lookup\n"
  112. " -r, --reverse perform reverse address to hostname lookup\n"
  113. " -V, --version display program version and exit\n"), path);
  114. return 0;
  115. }
  116. static int quick_usage (const char *path)
  117. {
  118. fprintf (stderr, _("Try \"%s -h\" for more information.\n"), path);
  119. return 2;
  120. }
  121. static int version (void)
  122. {
  123. printf (_("addrinfo %s (%s)\n"), VERSION, "$Rev: 646 $");
  124. printf (_(" built %s on %s\n"), __DATE__, PACKAGE_BUILD_HOSTNAME);
  125. printf (_("Configured with: %s\n"), PACKAGE_CONFIGURE_INVOCATION);
  126. puts (_("Written by Remi Denis-Courmont\n"));
  127. printf (_("Copyright (C) %u-%u Remi Denis-Courmont\n"), 2002, 2007);
  128. puts (_("This is free software; see the source for copying conditions.\n"
  129. "There is NO warranty; not even for MERCHANTABILITY or\n"
  130. "FITNESS FOR A PARTICULAR PURPOSE.\n"));
  131. return 0;
  132. }
  133. static const struct option lopts[] =
  134. {
  135. { "ipv4", no_argument, NULL, '4' },
  136. { "ipv6", no_argument, NULL, '6' },
  137. { "config", no_argument, NULL, 'c' },
  138. { "help", no_argument, NULL, 'h' },
  139. { "multiple", no_argument, NULL, 'm' },
  140. { "numeric", no_argument, NULL, 'n' },
  141. { "reverse", no_argument, NULL, 'r' },
  142. { "version", no_argument, NULL, 'V' },
  143. { NULL, 0, NULL, 0 }
  144. };
  145. static const char sopts[] = "46chmnrV";
  146. int main (int argc, char *argv[])
  147. {
  148. setlocale (LC_ALL, "");
  149. bindtextdomain (PACKAGE, LOCALEDIR);
  150. textdomain (PACKAGE);
  151. int val, family = AF_UNSPEC, aflags = AI_IDN, nflags = NI_NUMERICHOST;
  152. bool single = true;
  153. while ((val = getopt_long (argc, argv, sopts, lopts, NULL)) != EOF)
  154. switch (val)
  155. {
  156. case '4':
  157. family = AF_INET;
  158. break;
  159. case '6':
  160. family = AF_INET6;
  161. break;
  162. case 'c':
  163. aflags |= AI_ADDRCONFIG;
  164. break;
  165. case 'h':
  166. return usage (argv[0]);
  167. case 'm':
  168. single = false;
  169. break;
  170. case 'n':
  171. aflags |= AI_NUMERICHOST;
  172. break;
  173. case 'r':
  174. nflags &= ~NI_NUMERICHOST;
  175. break;
  176. case 'V':
  177. return version ();
  178. case '?':
  179. default:
  180. return quick_usage (argv[0]);
  181. }
  182. setvbuf (stdout, NULL, _IOLBF, 0);
  183. val = 0;
  184. if (optind < argc)
  185. {
  186. while (optind < argc)
  187. printnames (argv[optind++], family, aflags, nflags, single);
  188. }
  189. else
  190. val = printnamesf (stdin, family, aflags, nflags, single);
  191. return val;
  192. }