blob: 62e046d680df30d08ed821b8262435569c7f3266 [file] [log] [blame]
#!/bin/bash
source /usr/share/network/lib.sh || exit
exec_over_conf_dirs() {
local fun="$1"
shift
declare -A basemap=()
local oldshopt="$(shopt -p nullglob)"
shopt -s nullglob
local i=0
local dir
local file
for dir in "$@"; do
for file in "$dir"/*; do
basemap["${file##*/}$i"]="$file"
done
(( i+=1 ))
done
$oldshopt
local key
for key in $(printf "%s\n" "${!basemap[@]}" | sort -r); do
"$fun" "${basemap[$key]}" || return
done
}
gbmc_line_to_ips() {
local ip="$1"
[[ -z $ip ]] && return
local -a ipbytes
ip_to_bytes ipbytes "$ip" || return
ip="$(ip_bytes_to_str ipbytes)" || return
shift
local host
for host in "$@"; do
ip_to_hosts["$ip"]+=" $host"
ip_hosts["$ip $host"]=0
done
}
gbmc_hosts_read() {
local file="$1"
echo "Building /etc/hosts from $file" >&2
while read -r line; do
gbmc_line_to_ips ${line%%#*}
done <"$file"
}
gbmc_hosts_gen_int() {
local -A ip_to_hosts=()
local -A ip_hosts=()
exec_over_conf_dirs gbmc_hosts_read /{run,etc,usr/share}/hosts.d || return
echo '# Autogenerated, re-execute `gbmc-hosts-gen.sh` after configured in' >&$hostsfd
echo '# /run/hosts.d/*' >&$hostsfd
echo '# /etc/hosts.d/*' >&$hostsfd
echo '# /usr/share/hosts.d/*' >&$hostsfd
local ip
local host
for ip in "${!ip_to_hosts[@]}"; do
local line="$ip"
for host in "${ip_to_hosts["$ip"]}"; do
(( ip_hosts["$ip $host"] == 0 )) || continue
ip_hosts["$ip $host"]=1
line+=" $host"
done
if [[ $line != $ip ]]; then
echo "$line" >&$hostsfd
fi
done
}
gbmc_hosts_gen() {
local lockfd
local hostsfd
local rc=0
exec {lockfd}<>/run/hosts && \
flock "$lockfd" && \
rm -f /run/.hosts && \
exec {hostsfd}<>/run/.hosts && \
gbmc_hosts_gen_int && \
mv /run/.hosts /run/hosts || rc=$?
exec {hostsfd}>&-
exec {lockfd}>&-
return $rc
}
gbmc_hosts_gen