Change location automatically based on network

Jan 18, '05 09:19:00AM

Contributed by: richwiss

It always bothered me that when I went from one place to another (work, home, friend's house) that I had to manually choose from my pre-configured Locations from the Apple menu. It seemed to me that there was enough information available to set the Location automatically whenever the wireless network changed.

So I messed around a lot, did a lot of googling and poking around, and came up with the following solution.

First, I had to have a way of changing the Location based on the wireless network I was connected to. If all the networks you connect to have unique SSIDs, this script works fine. If this is not true for you, it should be possible to change it to recognize the MAC address of the router or access point instead of the SSID, but I haven't had luck with that yet.

#!/bin/sh

#get the ssid of the network you are on
#shown on two lines; should be one with a space
ssid=`ioreg -l -n AirPortDriver | grep APCurrentSSID 
 | sed 's/^.*= "\(.*\)".*$/\1/; s/ /_/g'`

#fill in your own values for ssid and location below
if [ $ssid = "workrtr" ]
then
    location="Work"
elif [ $ssid = "homertr" ]
then
    location="Home"
elif [ $ssid = "friend" ]
then
    location="Joe"
else
    location="Automatic"
fi

#update the location
newloc=`/usr/sbin/scselect ${location} | sed 's/^.*(\(.*\)).*$/\1/'`

echo ${newloc}

#exit with error if the location didn't match what you expected
if [ ${location} != ${newloc} ]
then
    exit 1
fi

exit 0
I'm not sure where these scripts should go, but let's call it update-location.sh, put it in /root, and chmod 700 /root/update-location.sh to make it executable. Next, we have to find a script that OS X calls when the wireless network changes. The one I chose is in the Kicker bundle. There may be better places, but this is the only one that I found that worked reliably. In /System -> Library -> SystemConfiguration -> Kicker.bundle -> Contents -> Resources, you will find a file named set-hostname. You need to be root to modify this, and you should make a backup (cp set-hostname set-hostname-backup) before you begin. At the end of the script, just before exit 0, add the following line:
location=`/root/update-location.sh`
If you want to play nice with the system.log, you can also add this just below:
logger -i -p daemon.notice -t set-hostname setting location to "${location}"
That's it! I think there's a small (finite) loop that happens when scselect is called from update-locations.sh -- I think set-hostname is called again, which will again call update-locations.sh. But, the loop only runs through twice, possibly because scselect hasn't changed anything the next time through the loop. This is a little rough, so it's possible this needs a little tweaking by someone who knows more than I do. Note that I have the Developer Tools installed, and I am running 10.3.7.

Comments (38)


Mac OS X Hints
http://hints.macworld.com/article.php?story=2005010613401823