Mac OS X LocationChanger

LocationChanger is a simple shell script and launchd description. The script gets launched after every network change.

When running it gathers some information, figures out the location and sets Location accordingly. I also have it start or stop synergy and a proxy over ssh to forward the synergy socket if at work.

You need this launchd item in ~/Library/LaunchAgents/LocationChanger.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
	"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>tech.inhelsinki.nl.locationchanger</string>
	<key>ProgramArguments</key>
	<array>
		<string>/Users/USERNAME/bin/locationchanger</string>
	</array>
	<key>WatchPaths</key>
	<array>
		<string>/Library/Preferences/SystemConfiguration</string>
	</array>
</dict>
</plist>

edit USERNAME to be your own username

and the locationchanger script, which I put in ~/bin/locationchanger and make it executable (chmod 755 ~/bin/locationchanger):

#!/bin/bash

# automatically change configuration of Mac OS X based on location
# author: Onne Gorter <o.gorter@gmail.com>
# url: http://tech.inhelsinki.nl/locationchanger/
# version: 0.4

# redirect all IO to /dev/null (comment this out if you want to debug)
exec 1>/dev/null 2>/dev/null

# get a little breather before we get data for things to settle down
sleep 2

# get various system information
SSID=`/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -I\
 | grep ' SSID:' | cut -d ':' -f 2 | tr -d ' '`
EN0IP=`ifconfig en0 | grep 'inet ' | cut -d' ' -f 2`
EN1IP=`ifconfig en1 | grep 'inet ' | cut -d' ' -f 2`

LOCATION=

# locations (use to be used Location name here)
ATHOME=Home
ATWORK=Work

# detect HOME
ATHOME_SSID=homessid
ATHOME_EN0IP=192.168.255.
ATHOME_EN1IP=192.168.255.

# detect Work
ATWORK_SSID=workssid
ATWORK_EN0IP=255.
ATWORK_EN1IP=255.


if [ -z $LOCATION ]; then
	case $SSID in
		$ATHOME_SSID	) LOCATION="$ATHOME";;
		$ATWORK_SSID	) LOCATION="$ATWORK";;
	esac
        REASON=SSID
fi

if [ -z $LOCATION ]; then
	case $EN0IP in
		$ATHOME_EN0IP*	) LOCATION="$ATHOME";;
		$ATWORK_EN0IP*	) LOCATION="$ATWORK";;
	esac
        REASON=EN0IP
fi

if [ -z $LOCATION ]; then
	case $EN1IP in
		$ATHOME_EN1IP*	) LOCATION="$ATHOME";;
		$ATWORK_EN1IP*	) LOCATIOn="$ATWORK";;
	esac
        REASON=EN1IP
fi

if [ -z $LOCATION ]; then
	# still didn't get a location, so do automatic
	LOCATION="automatic"
        REASON=Fallback
fi

case $LOCATION in
	$ATWORK )
		scselect $ATWORK
		#lpoptions -d "Work Printer"
		
		# get some time to figure ip addresses out ...
		sleep 3
		if ping -c 1 linux; then
			# if necesairy, start a proxy for synergy on host 'linux'
			ps -x | grep -E '[0-9] ssh.*-R24800:'  || \
				ssh -fN linux -R24800:127.0.0.1:24800 
			# if not running, start synergys with display name macosx
			ps -x | grep -E '[0-9] synergys'  || \
				synergys -n macosx
		fi
	;;
	
	$ATHOME )
		# do some stuff here if you want to
		scselect $ATHOME
		#lpoptions -d "Home Printer"
	;;

	automatic )
		# do some stuff here if you want to
		scselect Automatic
		#lpoptions -d "Default Printer"
	;;
	
esac

# do some stuff here that needs to happen after every network change

echo `date` "Location: $LOCATION - $REASON" >> $HOME/.locationchanger.log

exit 0

After putting the scripts in place (and don't forget to make locationchanger executable), you can test locationchanger by launching it.

It logs every event to ~/.locationchanger.log, so you can look at that file to see if everything went ok.

Then either reboot or use launchctl load ~/Library/LaunchAgents/LocationChanger.plist.


Ideas:

Use /usr/bin/lpoptions -d This Printer to change the default printer based on your location. Look at ~/.lpoptions file for the current default printer.

Use arp -a to detect remote hardware address. Might just work incase you are on a network that does not give you an IP address automatically and Mac OS X assigned an auto-IP.

Use applescript to change default SMTP; something like this: osascript -e 'tell application "Mail" to set smtp server of account "ACCOUNT" to smtp server "smtp.provider.com"'

Or even more extreme, using a combination of applescript + normal script: stop iChat, copy other preference file that has other accounts enabled to ~/Library/Preferences/com.apple.iChat.plist. And start iChat again ... stopping iChat: osascript -e 'tell application "iChat" to quit'

Last modified: 2007-11-19 20:14 GMT