Вот решение, которое я придумал:
Я использую Growl и HardwareGrowler для запуска сценария, который записывает файл распознавателя, который dnsmasq настроен для использования.
Может быть, я неправильно понимаю (ситуация с документацией Growl довольно отсутствует), но я подумал, что Growl 2.1 может напрямую запускать сценарий оболочки в правильном каталоге. Я не мог заставить это работать, как бы то ни было. Поэтому вместо этого я использую скрипт правил Applescript, чтобы запустить скрипт оболочки следующим образом ...
В ~/ Библиотека / Сценарии приложений / ком.Growl.GrowlHelperApp / Rules.scpt:
using terms from application "Growl"
on evaluate notification with notification
--Rules go in here
if notification's note title contains "IP Address" then
set shell_result to do shell script "/usr/local/sbin/set_nameservers.sh"
end if
--Ultimately return what you want Growl to do with the notification
end evaluate notification
end using terms from
Затем мой скрипт /usr/local/sbin/set_nameservers.sh:
#!/bin/bash
# locking variables
LOCKDIR="/tmp/nameservers.lock"
PIDFILE="${LOCKDIR}/nameservers.pid"
# Temporary file for discovered nameservers
TMP_NAMESERVERS_FILE="${LOCKDIR}/nameservers.conf"
# List of public nameservers to add to the list
PUB_NAMESERVERS_FILE="/etc/nameservers_public.conf"
# The nameserver list read in by dnsmasq
SYS_NAMESERVERS_FILE="/etc/nameservers.conf"
# Commands
GROWL="/usr/local/bin/growlnotify"
# Setup a lock in case Growl triggers this script multiple times due to multiple network changes
if mkdir "${LOCKDIR}"; then
echo "$$" >"${PIDFILE}";
echo "# DHCP supplied nameserves:" > "${TMP_NAMESERVERS_FILE}";
# 1) For each interface listed by the networksetup command...
while IFS=" " read -r -a interfaces;
do
((int_count = ${#interfaces[@]} - 1));
for ((i = 0; i <= int_count; i++));
do
# 2) Try to get a nameserver from DHCP. (Only the first of multiple is returned)
nameserver=`/usr/sbin/ipconfig getoption ${interfaces[i]} domain_name_server`
# 3) If a nameserver was returned, add it to our configuration.
if [ ${nameserver} ]; then
echo "nameserver" ${nameserver} >> ${TMP_NAMESERVERS_FILE};
fi
done
done <<< `networksetup -listallhardwareports | grep Device | sed 's/Device: //g'`
# 4) If a file of public nameservers exists, add these to our configuration.
if [ -e ${PUB_NAMESERVERS_FILE} ]; then
cat ${PUB_NAMESERVERS_FILE} >> ${TMP_NAMESERVERS_FILE};
fi
cp ${TMP_NAMESERVERS_FILE} ${SYS_NAMESERVERS_FILE};
# Display a Growl notification showing what our new nameserver config looks like.
${GROWL} -d "us.loranz.steve.set_nameservers" \
-N "Nameserver Configuration" \
-m "`cat ${SYS_NAMESERVERS_FILE}`" \
"System nameservers set to:";
rm -rf "${LOCKDIR}";
else
# Display an informational message if we failed to establish a lock.
${GROWL} -d "us.loranz.steve.set_nameservers" \
-N "Nameserver Configuration Failed" \
-m "$0 ($$) failed to run, lock already established by process: " `cat ${PIDFILE}` \
"Failed to set nameservers:";
exit 1;
fi
exit 0
Затем я настроил HardwareGrowler для отображения сетевых событий и Growl для запуска действия ScriptAction для изменения IP-адреса, отключения сетевого канала и сетевого подключения.
Наконец, я установил свой сервер имен в настройках сети на 127.0.0.1, чтобы я нажал dnsmasq.
Затем dnsmasq настраивается со следующими параметрами:
resolv-file=/etc/nameservers.conf
all-servers
Первая строка указывает dnsmasq на файл, в котором скрипт выше заполняется серверами имен, обнаруженными через DHCP, и любыми публичными серверами, которые вы хотите.
Предполагается, что вторая строка позволяет dnsmasq отправлять запрос всем серверам имен, о которых он знает, и принимает первый ответ. Средство распознавания Mac OS X должно устранять необходимость в данных файлах распознавания и поиске домена DHCP ... и полагаться на это сделает вас лучше, чем каждый раз запрашивать каждый сервер в вашем списке. Я могу удалить эту опцию после некоторого дополнительного тестирования и был бы признателен любому, кто еще что-то знает об этом бите.