Stupid Simple Startup Items 
25 September 2002
There are two ways to have a service run at start up. One is the preferred method, StartupItems, and the other, watchdog, works, but is better suited for other tasks. Since watchdog is such a different beast, and only available on Mac OS X Server, we’ll leave that for another article.
On most UNIX systems, services are started by a series of boot scripts. The system goes through each one in order and runs the commands. Adding new services is technically simple since you only need to edit the script, but it can be incredibly frustrating when you get the commands out of order, or when it just plain doesn’t work.
The crafty engineers at Apple have solved a lot of the inflexibility of the traditional boot scripts with StartupItems. This is an incredibly elegant solution where instead of one master script every item is self-contained. Each of these scripts has an associated XML .plist file that tells the operating system basic information about the service or services the script provides. The system then dynamically determines the order in which the items will start, or if they start at all. The functionality of this really begins to show when you’ve worked with it for a bit.
The system looks for StartupItems in /Library/StartupItems and /System/Library/StartupItems in that order. It will supposedly also check /Network/Library/StartupItems but since these items start up the network services it is tough to check the network before it is available. You can create items and put them in either of the two places, but it is really best for you to put them in /Library/StartupItems instead of in the System. If you don’t already have a folder in the correct place, feel free to make one.
The basic format of a StartupItem is fairly simple. Each item is contained in a folder. Inside that folder are three other items. The first is a shell script that has the same name as the folder. The second item is the XML property list called StartupParameters.plist—this tells the operating system what dependencies the item has, and a suggestion as to when it should run in the startup order among other things. The third item is a folder called Resources that contains any log messages or console messages that your script uses localized into different languages. You can also put any ancillary scripts and other resources your StartupItem might need into here.
For example, our Exim startup script is a folder called Exim. Inside that folder is the shell script that starts Exim, called Exim. Also there is a .plist file which says that this StartupItem provides SMTP services. It needs DirectoryServices going before it can launch, and it uses the file system. Finally it says that it has no preference as to when it should run. When booting, the system reads all of this in and will launch Exim after Directory Services is running and the disks have been mounted. After running Exim it will not launch Sendmail as a daemon since a service already providing SMTP services has been started. Also in the item is a Resources folder that has the phrase “Starting Mail Services” localized into 12 different languages. Not very complicated at all.
The trickiest part of the configuration is the script itself. You can make this as basic as a two line shell script, but you’ll do better by putting a bit more effort into it. If you hork the format in our Exim script you’ll easily be able to get your StartupItem to understand service shutdown requests. This way when you shut down the machine, your services will be gracefully stopped.
Here’s our Exim script:
#!/bin/sh
# Joel Rennich, www.afp548.com, Sept. 2002
# all copyrights waived
. /etc/rc.common
# Script to control Exim
# this is to start it
if [ "$1" == "start" ]
then
ConsoleMessage "Starting Exim"
/usr/exim/bin/exim -bd -q30m
# this is to stop it
elif [ "$1" == "stop" ]
then
ConsoleMessage "Stopping Exim"
kill `cat /var/spool/exim/exim-daemon.pid`
# this is to restart it
elif [ "$1" == "restart" ]
then
ConsoleMessage "Restarting Exim"
kill -HUP `cat /var/spool/exim/exim-daemon.pid`
fi
After the script, the only other thing to worry about is the .plist file. When making this you might want to check /System/Library/StartupItems and see if there is anything there that is close to what you are doing. That will give you a good idea about the format and what dependencies you might have. Then use the Property List Editor application to make your changes.
You can test your items by using the SystemStarter command. For example, to test the Exim script after installing the StartupItem, use the command
sudo SystemStarter stop SMTP
The command will post the result of the operation to the Terminal as this happens and should give you a good idea of what is going on.