hello,
i was working on a script to emulate this hint from macosxhints.com:
http://www.macosxhints.com/article.php?story=20050420025219402
the script came along pretty well, does most of the things i’d like it to. however, at the end i need to set the DNS servers in the Network Preference Pane but i can’t find an acceptable way to do this. i have to leave it up to the user to do the setting (instructed from a display dialog box). therefore the script is not perfect, but if you understand what you are trying to do this will go a long way to getting things up and running.
as usual, i’d love to answer any questions or get any comments. here’s the code:
(* localCachingDNS will take care of most of the settings and set up the
DNS server. You'll have to set your DNS entries to 127.0.0.1 for each
active interface you have in order to use the local DNS server *)
property rndcConf : "/usr/sbin/rndc-confgen > /etc/rndc.conf"
property rndcKeyGen : "/usr/bin/head -n 6 /etc/rndc.conf > /etc/rndc.key"
property startDNS : "/System/Library/StartupItems/BIND/BIND"
global tempDNS
global myDNS1
global myDNS2
(* letsGo() handles most of the initial config. checks your current DNS
servers, but will let you use different ones if you desire *)
on letsGo()
set tempDNS to {missing value}
set currDNS to (do shell script "/bin/cat /etc/resolv.conf | grep 'nameserver'")
set howMany to (count paragraphs of currDNS)
set x to 1
repeat while x ≤ howMany
if word 2 of paragraph x of currDNS is not "127.0.0.1" then
if tempDNS is {missing value} then
set tempDNS to word 2 of paragraph x of currDNS as list
else
set tempDNS to tempDNS & word 2 of paragraph x of currDNS
end if
end if
set x to (x + 1)
end repeat
try
set myDNS1 to item 1 of tempDNS
set myDNS2 to item 2 of tempDNS
on error
set myQ to button returned of (display dialog "You'll need to set your DNS numbers by hand. Click \"Ok\" to continue.")
if myQ is "Ok" then
getDns()
end if
end try
set myQ to button returned of (display dialog "Your current DNS servers are: " & return & myDNS1 & return & " and " & return & myDNS2 & return & "Would you like to keep these or enter different ones?" buttons {"Keep", "Don't Keep"} default button "Keep")
if myQ is "Keep" then
doMain()
else
getDns()
end if
end letsGo
(* doMain() just runs the other handlers in the proper order. used for organizational
purposes only *)
on doMain()
doShell(rndcConf)
doShell(rndcKeyGen)
setHostConfig()
setNamedConf(myDNS1, myDNS2)
mkBINDDir()
setLocalPref()
doShell(startDNS)
end doMain
(* getDns() gets DNS numbers from the user if needed *)
on getDns()
set firstQ to "You will need to enter two valid ip addresses to your DNS servers for this to work." & return & "Please enter the first DNS server's ip address: "
set secondQ to "Please enter the second DNS server's ip address: "
set myDNS1 to text returned of (display dialog firstQ default answer "")
set myDNS2 to text returned of (display dialog secondQ default answer "")
checkDNS(myDNS1)
checkDNS(myDNS2)
doMain()
end getDns
(* checkDNS(address) checks the users input for a valid ip address *)
on checkDNS(address)
set badAns to address & " is not a valid DNS entry. Please try again."
set ASTD to AppleScript's text item delimiters
set AppleScript's text item delimiters to "."
set howMany to (count text items of address)
set TI to text items of address
set AppleScript's text item delimiters to ASTD
if howMany is not 4 then
display dialog badAns
getDns()
return
end if
set x to 1
repeat while x ≤ howMany
tell (text item x of TI) as number
if it ≥ 0 and it < 256 then
set x to (x + 1)
else
display dialog badAns
getDns()
exit repeat
end if
end tell
end repeat
end checkDNS
(* doShell(a) is just an idea i had to save some typing. i did not implement it in each handler *)
on doShell(a)
do shell script a with administrator privileges
end doShell
(* setHostConfig() makes sure the DNS server is in /etc/hostconfig and is on when the computer boots *)
on setHostConfig()
do shell script "#!/bin/sh
if [ ! -f /etc/hostconfig.OS-X_Original_DO_NOT_DELETE ]; then
cp -p /etc/hostconfig /etc/hostconfig.OS-X_Original_DO_NOT_DELETE
fi
if [ -f /etc/hostconfig.OS-X_Original_DO_NOT_DELETE ]; then
cp -p /etc/hostconfig.OS-X_Original_DO_NOT_DELETE /etc/hostconfig
fi" with administrator privileges
set isDNSServer to "no"
try
set isDNSServer to (do shell script "/bin/cat /etc/hostconfig | /usr/bin/grep DNSSERVER")
end try
--display dialog isDNSServer
if isDNSServer is "no" then
do shell script "/bin/echo DNSSERVER=-YES- >> /etc/hostconfig" with administrator privileges
else if isDNSServer is "DNSSERVER=-NO-" then
do shell script "/usr/bin/sed 's/DNSSERVER=-NO-/DNSSERVER=-YES-/' /etc/hostconfig.OS-X_Original_DO_NOT_DELETE > /etc/hostconfig" with administrator privileges
end if
end setHostConfig
(* setNamedConf(a, b) creates settings needed by our new DNS server *)
on setNamedConf(a, b)
do shell script "#!/bin/sh
if [ ! -f /etc/named.conf.OS-X_Original_DO_NOT_DELETE ]; then
cp -p /etc/named.conf /etc/named.conf.OS-X_Original_DO_NOT_DELETE
fi
if [ -f /etc/named.conf.OS-X_Original_DO_NOT_DELETE ]; then
cp -p /etc/named.conf.OS-X_Original_DO_NOT_DELETE /etc/named.conf
fi" with administrator privileges
set isForward to "no"
try
set isForward to (do shell script "/bin/cat /etc/named.conf | /usr/bin/grep 'forwarders {'")
--display dialog isForward
end try
if isForward is "no" then
do shell script "/bin/echo 'forwarders {
" & a & ";
" & b & ";
" & "};' >> /etc/named.conf" with administrator privileges
else if isForward is "forwarders {" then
--display dialog "Sed Command"
do shell script "/usr/bin/sed '
/^forwarders {/ {
N
N
N
/\\n};/ {
s/forwarders {.*\\n.*\\n.*\\n};/\\
forwarders {\\
" & a & ";\\
" & b & ";\\
};/
}
}' /etc/named.conf.OS-X_Original_DO_NOT_DELETE > /etc/named.conf" with administrator privileges
end if
end setNamedConf
(* mkBINDDir() creates our 'StartupItem' in the proper OS X way *)
on mkBINDDir()
try
do shell script "/bin/mkdir /System/Library/StartupItems/BIND" with administrator privileges
end try
do shell script "/bin/echo " & quoted form of "#!/bin/sh
. /etc/rc.common
if [ \"${DNSSERVER}\" = \"-YES-\" ]; then
ConsoleMessage \"Starting BIND DNS Server\"
/usr/sbin/named
fi" & " > /System/Library/StartupItems/BIND/BIND" with administrator privileges
do shell script "/bin/chmod +x /System/Library/StartupItems/BIND/BIND" with administrator privileges
do shell script "/bin/echo " & quoted form of "{
Description = \"Local Caching DNS Server\";
Provides = (\"DNS Server\");
OrderPreference = \"None\";
Messages =
{
start = \"Starting BIND DNS Server\";
stop = \"Stopping BIND DNS Server\";
};
}
" & " > /System/Library/StartupItems/BIND/StartupParameters.plist" with administrator privileges
end mkBINDDir
(* setLocalPref() just lets the user know to set DNS servers to the proper setting in the
Network Preference Pane. wish i had a better way of doing this *)
on setLocalPref()
tell application "System Preferences"
activate
set current pane to pane "com.apple.preference.network"
display dialog "Please take out any 'DNS Servers' and replace them with '127.0.0.1'"
end tell
end setLocalPref
(* Here's where the program starts *)
letsGo()
display dialog "The script is finished. Enjoy your new Internet."
many thanks to Adam Bell and Bruce Phillips for help checking user entry of ip addresses. also, i implemented Adam’s idea of getting the currently set DNS numbers–works great.
cheers.