github.com/afumu/libc@v0.0.6/musl/src/network/resolvconf.c (about)

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