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