20-resolv.conf revision e86eee143ed21592f88a46623a81f71002430459
1# Generate /etc/resolv.conf
2# Support resolvconf(8) if available
3# We can merge other dhcpcd resolv.conf files into one like resolvconf,
4# but resolvconf is preferred as other applications like VPN clients
5# can readily hook into it.
6# Also, resolvconf can configure local nameservers such as bind
7# or dnsmasq. This is important as the libc resolver isn't that powerful.
8
9resolv_conf_dir="$state_dir/resolv.conf"
10
11build_resolv_conf()
12{
13	local cf="$state_dir/resolv.conf.$interface"
14	local interfaces= header= search= srvs= servers= x=
15
16	# Build a list of interfaces
17	interfaces=$(list_interfaces "$resolv_conf_dir")
18
19	# Build the resolv.conf
20	if [ -n "$interfaces" ]; then
21		# Build the header
22		for x in ${interfaces}; do
23			header="$header${header:+, }$x"
24		done
25
26		# Build the search list
27		domain=$(cd "$resolv_conf_dir"; \
28			key_get_value "domain " ${interfaces})
29		search=$(cd "$resolv_conf_dir"; \
30			key_get_value "search " ${interfaces})
31		set -- ${domain}
32		unset domain
33		if [ -n "$2" ]; then
34			search="$search $@"
35		elif [ -n "$1" ]; then
36			domain="domain $1\n"
37		fi
38		[ -n "$search" ] && search="search $(uniqify $search)\n"
39
40		# Build the nameserver list
41		srvs=$(cd "$resolv_conf_dir"; \
42			key_get_value "nameserver " ${interfaces})
43		for x in $(uniqify ${srvs}); do
44			servers="${servers}nameserver $x\n"
45		done
46	fi
47	header="$signature_base${header:+ $from }$header"
48
49	# Assemble resolv.conf using our head and tail files
50	[ -f "$cf" ] && rm -f "$cf"
51	[ -d "$resolv_conf_dir" ] || mkdir -p "$resolv_conf_dir"
52	echo "$header" > "$cf"
53	if [ -f /etc/resolv.conf.head ]; then
54		cat /etc/resolv.conf.head >> "$cf"
55	else
56		echo "# /etc/resolv.conf.head can replace this line" >> "$cf"
57	fi
58	printf "$domain$search$servers" >> "$cf"
59	if [ -f /etc/resolv.conf.tail ]; then
60		cat /etc/resolv.conf.tail >> "$cf"
61	else
62		echo "# /etc/resolv.conf.tail can replace this line" >> "$cf"
63	fi
64	cat "$cf" > /etc/resolv.conf
65	chmod 644 /etc/resolv.conf
66	rm -f "$cf"
67}
68
69add_resolv_conf()
70{
71	local x= conf="$signature\n"
72
73	# If we don't have any configuration, remove it
74	if [ -z "$new_domain_name_servers" -a \
75		-z "$new_domain_name" -a \
76		-z "$new_domain_search" ]; then
77		remove_resolv_conf
78		return $?
79	fi
80
81	if [ -n "$new_domain_name" ]; then
82		set -- $new_domain_name
83		new_domain_name="$1"
84		conf="${conf}domain $new_domain_name\n"
85		# Support RFC violating search in domain
86		if [ -z "$new_domain_search" -a -n "$2" ]; then
87			new_domain_search="$@"
88		fi
89	fi
90	if [ -n "$new_domain_search" ]; then
91		conf="${conf}search $new_domain_search\n"
92	fi
93	for x in ${new_domain_name_servers}; do
94		conf="${conf}nameserver $x\n"
95	done
96	if type resolvconf >/dev/null 2>&1; then
97		[ -n "$metric" ] && export IF_METRIC="$metric"
98		printf "$conf" | resolvconf -a "$interface"
99		return $?
100	fi
101
102	if [ -e "$resolv_conf_dir/$interface" ]; then
103		rm -f "$resolv_conf_dir/$interface"
104	fi
105	[ -d "$resolv_conf_dir" ] || mkdir -p "$resolv_conf_dir"
106	printf "$conf" > "$resolv_conf_dir/$interface"
107	build_resolv_conf
108}
109
110remove_resolv_conf()
111{
112	if type resolvconf >/dev/null 2>&1; then
113		resolvconf -d "$interface" -f
114	else
115		if [ -e "$resolv_conf_dir/$interface" ]; then
116			rm -f "$resolv_conf_dir/$interface"
117		fi
118		build_resolv_conf
119	fi
120}
121
122if $if_up; then
123	add_resolv_conf
124elif $if_down; then
125	remove_resolv_conf
126fi
127