## 2.2. Adding Startup Items

To automatically start applications, you have two choices: start them when a user logs in, or start them when the system boots up. On most Unix systems, startup applications either reside in the /etc/rc.local script or the /etc/init.d directory. Under Mac OS 9, you could add a startup item by putting its alias in System Folder:Startup Items. Mac OS X has a different approach, described in the following sections.

### 2.2.1. Login Preferences

To start an application each time you log in, use the Login Items panel of System Preferences. This is good for user applications, such as Stickies or an instant messenger program. For system daemons, you should set up a directory in /Library/StartupItems, as described in the next section.

### 2.2.2. Startup Items

If you compile and install a daemon, you'll probably want it to start at boot time. For example, MySQL will build out of the box on Mac OS X (you can download it from http://www.mysql.com).

A startup item is controlled by three things: a folder (such as /Library/StartupItems/MyItem), a shell script with the same name as the directory (such as MyItem), and a property list named StartupParameters.plist. The shell script and the property list must appear at the top level of the startup item's folder. You can also create a Resources directory to hold localized resources, but this is not mandatory.

To set up the MySQL startup item, create the directory /Library/StartupItems/MySQL. Then, create two files in that directory, the startup script MySQL and the property list StartupParameters.plist. The MySQL file should be an executable since it is a shell script. After you set up these two files as directed in the following sections, MySQL will be launched at each boot.

### 2.2.2.1. The startup script

The startup script should be a shell script with `StartService( )`, `StopService( )`, and `RestartService( )` functions. The contents of /Library/StartupItems/MySQL/MySQL are shown in Example 2-3. The function call at the bottom of the script invokes the `RunService( )` function from rc.common, which in turn invokes `StartService( )`, `StopService( )`, or `RestartService( )`, depending on whether the script was invoked with an argument of start, stop, or restart.

#### Example 2-3. A MySQL startup script

>     #!/bin/sh

>     # Source common setup, including hostconfig.
>     #
>     . /etc/rc.common

>     StartService( )
>     {
>         # Don't start unless MySQL is enabled in /etc/hostconfig
>         if [ "${MYSQL:=-NO-}" = "-YES-" ]; then
>             ConsoleMessage "Starting MySQL"
>             /usr/local/mysql/bin/safe_mysqld --user=mysql &
>         fi
>     }

>     StopService( )
>     {
>         ConsoleMessage "Stopping MySQL"
>         /usr/local/mysql/bin/mysqladmin shutdown
>     }

>     RestartService( )
>     {
>         # Don't restart unless MySQL is enabled in /etc/hostconfig
>         if [ "${MYSQL:=-NO-}" = "-YES-" ]; then
>             ConsoleMessage "Restarting MySQL"
>             StopService
>             StartService
>         else
>             StopService
>         fi
>     }

>     RunService "$1"

> TIP: If you are using MySQL version 4 (in beta as of this writing), replace /usr/local/mysql/bin/safe_mysqld with /usr/local/mysql/bin/mysqld_safe.

Because it consults the settings of the `$MYSQL` environment variable, the startup script won't do anything unless you've enabled MySQL in the /etc/hostconfig file. To do this, add the following line to /etc/hostconfig:

>     MYSQL=-YES-

Mac OS X does not recognize any special connections between hostconfig entries and startup scripts. Instead, the startup script sources the /etc/rc.common file, which in turn sources hostconfig. The directives in hostconfig are merely environment variables, and the startup script checks the value of the variables that control its behavior (in this case, `$MYSQL`).

You can manually start, stop, and restart MySQL by invoking this script from the command line:

>     /Library/StartupItems/MySQL/MySQL start
>     /Library/StartupItems/MySQL/MySQL restart
>     /Library/StartupItems/MySQL/MySQL stop

### 2.2.2.2. The property list

The property list can be in XML or NeXT format, and the list contains attributes that describe the item and determine its place in the startup sequence. The NeXT format uses NeXTSTEP-style property lists, as shown in Example 2-4.

#### Example 2-4. The MySQL startup parameters as a NeXT property list

>     {
>       Description     = "MySQL";
>       Provides        = ("MySQL");
>       Requires        = ("Network");
>       OrderPreference = "Late";
>     }

Over time, Apple will probably phase out legacy formats such as NeXT property lists, so it is best if you use XML property lists. The XML format adheres to the PropertyList.dtd Document Type Definition (DTD). You can use your favorite text editor or the Property List Editor (/Developer/Applications) to create your own property list. Example 2-5 shows the property list in XML.

#### Example 2-5. The MySQL startup parameters as an XML property list

>     <?xml version="1.0" encoding="UTF-8"?>
>     <!DOCTYPE plist
>       SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
>     <plist version="0.9">
>     <dict>
>         <key>Description</key>
>         <string>MySQL</string>
>         <key>Provides</key>
>         <array>
>             <string>MySQL</string>
>         </array>
>         <key>Requires</key>
>         <array>
>             <string>Network</string>
>         </array>
>         <key>OrderPreference</key>
>         <string>Late</string>
>     </dict>
>     </plist>

The following list describes the various keys you can use in a startup parameters property list.

`Description`
  This is a phrase that describes the item.
`Provides`
  This is an array of services that the item provides (for example, Apache provides Web Server). These services should be globally unique. In the event that SystemStarter finds two items that provide the same service, it will start the first one it finds.
`Requires`
  This is an array of services that the item depends on. It should correspond to another item's `Provides` attribute. If a required service cannot be started, the system won't start the item.
`Uses`
  This is similar to `Requires`, but it is a weaker association. If SystemStarter can find a matching service, it will start it. If it can't, the dependent item will still start.
`OrderPreference`
  The `Requires` and `Uses` attributes imply a particular order, in that dependent items will be started after the services they depend on. You can specify `First`, `Early`, `None` (the default), `Late`, or `Last` here. SystemStarter will do its best to satisfy this preference, but dependency orders prevail.

Copyright © 2003 O'Reilly & Associates. All rights reserved.