#!/usr/bin/env bash
WORKDIR="/opt/valet-linux"
DNSFILE="${WORKDIR}/dns-servers"
DNSHEAD="${WORKDIR}/custom-nameservers"
LOGFILE="${WORKDIR}/watch.log"
VRESOLV="${WORKDIR}/resolv.conf"
RESOLV="/etc/resolv.conf"
function unique() {
# Function to remove duplicated lines (even when they are not contiguous)
# cat -n puts line numbers
# sort -uk2 sort and remove duplicates (ignoring line numbers)
# sort -nk1 sort by line number
# cut -f2- remove line numbers
cat -n | sort -uk2 | sort -nk1 | cut -f2-
}
function symlinkResolv() {
if [[ $(readlink -f "$RESOLV") != "$VRESOLV" ]]; then
if [[ ! -f "${RESOLV}.bak" ]]; then
mv "$RESOLV" "${RESOLV}.bak"
fi
ln -sf "$VRESOLV" "${RESOLV}.tmp"
mv "${RESOLV}.tmp" "$RESOLV"
fi
}
function getDirs() {
DIRS=()
local TARRAY=()
readarray -t TARRAY <<< "$(find /run -path '/run/user' -prune -o -path '/run/media' -prune -o ! -readable -prune -o -name 'resolv.conf' -print)"
# Find nameserver files in the /run/NetworkManager folder (as they do not have a standard name)
if [[ ! -f "/run/NetworkManager/resolv.conf" && -d "/run/NetworkManager" ]]; then
TARRAY=(${TARRAY[@]} '/run/NetworkManager/')
fi
# Find nameserver files in the /run/resolvconf/interface folder (as they do not have a standard name)
if [[ -d "/run/resolvconf/interface" ]]; then
TARRAY=(${TARRAY[@]} '/run/resolvconf/interface/')
fi
for ENTRY in "${TARRAY[@]}"; do
local TMP=${ENTRY%/*}
DIRS=(${DIRS[@]} "$TMP")
done
}
function updateNameservers() {
# Read all of the nameserver files at once, filter lines starting with 'nameserver'
# and exclude the ones containing 127.0.0.1 (localhost)
getFiles
echo "${FILES[@]}" | tee "${WORKDIR}/resolvfiles.log" &>/dev/null
cat "$DNSHEAD" | unique | tee "$DNSFILE" &>/dev/null
cat "${FILES[@]}" | grep -i '^nameserver' | grep -v '127.0.0.1' | unique | tee -a "$DNSFILE" &>/dev/null
symlinkResolv
cat "${FILES[@]}" | grep -v '^nameserver' | grep -v '^#' | unique | tee "$VRESOLV" &>/dev/null
echo 'nameserver 127.0.0.1' >> "$VRESOLV"
# Add "search" and "domain" directives to /etc/resolv.conf
# chattr -i "$RESOLV" && \
# cat "${FILES[@]}" | grep -v '^nameserver' | grep -v '^#' | unique | tee "$VRESOLV" &>/dev/null && \
# echo 'nameserver 127.0.0.1' >> "$VRESOLV" && \
# chattr +i "$RESOLV"
}
function getFiles() {
FILES=()
local TARRAY=()
for DIR in "${DIRS[@]}"; do
readarray -t TARRAY <<< "$(find ${DIR} -path ! -readable -prune -o -name 'resolv.conf' -print)"
# Find nameserver files in the /run/resolvconf/interface folder (as they do not have a standard name)
if [[ "$DIR" = "/run/resolvconf/interface" ]]; then
readarray -t TARRAY <<< "$(find ${DIR} ! -readable -prune -o -type f -print)"
fi
FILES=(${FILES[@]} ${TARRAY[@]})
done
}
function watchDirs() {
local WATCHERS=(${DIRS[@]} "$DNSHEAD")
# Log which directories are being watched
echo "Watching the following directories for changes:" >> "$LOGFILE"
for DIR in "${DIRS[@]}"; do
echo " - $DIR" >> "$LOGFILE"
done
# Watch directories for changes in files
inotifywait -q -m -e modify -e create -e delete --format "%w%f" "${WATCHERS[@]}" | while read change; do
updateNameservers
done &
}
function main() {
# Create dns file in case it does not exists
touch "$DNSHEAD"
touch "$DNSFILE"
# Clear log file
if [[ -f "$LOGFILE" ]]; then
rm "$LOGFILE"
fi
touch "$LOGFILE"
getDirs
updateNameservers
watchDirs
}
################################################################################
function start {
if [[ $(pgrep -f 'inotifywait -q -m -e modify') ]]; then
echo -e "Valet DNS Watcher is already running..."
else
echo -e "Starting Valet DNS Watcher..."
main
sleep 2 && echo $(pgrep -f 'inotifywait -q -m -e modify') > "${WORKDIR}/watch.pid"
echo -e "Valet DNS Watcher started succesfully."
fi
}
function stop {
echo -e "Stopping Valet DNS Watcher...\n"
pkill -f "inotifywait -q -m -e modify"
rm "$LOGFILE" && touch "$LOGFILE"
if [[ ! $(pgrep -f 'inotifywait -q -m -e modify') ]]; then
echo -e "\nValet DNS Watcher stopped succesfully."
fi
}
function restart {
echo -e "Stopping Valet DNS Watcher..."
if [[ $(pgrep -f 'inotifywait -q -m -e modify') ]]; then
pkill -f "inotifywait -q -m -e modify"
fi
echo -e "Starting Valet DNS Watcher..."
main
if [[ $(pgrep -f 'inotifywait -q -m -e modify') ]]; then
echo -e "Valet DNS Watcher restarted succesfully."
fi
}
function status {
if [[ -f "$LOGFILE" ]]; then
echo -e "Valet DNS service is running correctly.\n"
cat '/opt/valet-linux/watch.log'
else
echo "Valet DNS service is not running."
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
status
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
esac
exit 0
|