resolvconf.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #include "lookup.h"
  2. #include "stdio_impl.h"
  3. #include <ctype.h>
  4. #include <errno.h>
  5. #include <string.h>
  6. #include <netinet/in.h>
  7. int __get_resolv_conf(struct resolvconf *conf, char *search, size_t search_sz)
  8. {
  9. char line[256];
  10. unsigned char _buf[256];
  11. FILE *f, _f;
  12. int nns = 0;
  13. conf->ndots = 1;
  14. conf->timeout = 5;
  15. conf->attempts = 2;
  16. if (search) *search = 0;
  17. f = __fopen_rb_ca("/etc/resolv.conf", &_f, _buf, sizeof _buf);
  18. if (!f) switch (errno) {
  19. case ENOENT:
  20. case ENOTDIR:
  21. case EACCES:
  22. goto no_resolv_conf;
  23. default:
  24. return -1;
  25. }
  26. while (fgets(line, sizeof line, f)) {
  27. char *p, *z;
  28. if (!strchr(line, '\n') && !feof(f)) {
  29. /* Ignore lines that get truncated rather than
  30. * potentially misinterpreting them. */
  31. int c;
  32. do c = getc(f);
  33. while (c != '\n' && c != EOF);
  34. continue;
  35. }
  36. if (!strncmp(line, "options", 7) && isspace(line[7])) {
  37. p = strstr(line, "ndots:");
  38. if (p && isdigit(p[6])) {
  39. p += 6;
  40. unsigned long x = strtoul(p, &z, 10);
  41. if (z != p) conf->ndots = x > 15 ? 15 : x;
  42. }
  43. p = strstr(line, "attempts:");
  44. if (p && isdigit(p[9])) {
  45. p += 9;
  46. unsigned long x = strtoul(p, &z, 10);
  47. if (z != p) conf->attempts = x > 10 ? 10 : x;
  48. }
  49. p = strstr(line, "timeout:");
  50. if (p && (isdigit(p[8]) || p[8]=='.')) {
  51. p += 8;
  52. unsigned long x = strtoul(p, &z, 10);
  53. if (z != p) conf->timeout = x > 60 ? 60 : x;
  54. }
  55. continue;
  56. }
  57. if (!strncmp(line, "nameserver", 10) && isspace(line[10])) {
  58. if (nns >= MAXNS) continue;
  59. for (p=line+11; isspace(*p); p++);
  60. for (z=p; *z && !isspace(*z); z++);
  61. *z=0;
  62. if (__lookup_ipliteral(conf->ns+nns, p, AF_UNSPEC) > 0)
  63. nns++;
  64. continue;
  65. }
  66. if (!search) continue;
  67. if ((strncmp(line, "domain", 6) && strncmp(line, "search", 6))
  68. || !isspace(line[6]))
  69. continue;
  70. for (p=line+7; isspace(*p); p++);
  71. size_t l = strlen(p);
  72. /* This can never happen anyway with chosen buffer sizes. */
  73. if (l >= search_sz) continue;
  74. memcpy(search, p, l+1);
  75. }
  76. __fclose_ca(f);
  77. no_resolv_conf:
  78. if (!nns) {
  79. __lookup_ipliteral(conf->ns, "127.0.0.1", AF_UNSPEC);
  80. nns = 1;
  81. }
  82. conf->nns = nns;
  83. return 0;
  84. }