## Stopping and Starting ProFTPD

The starting and stopping of a ProFTPD server is a straightforward process, once the means intended for such things are understood. Starting the server is easy. Stopping and/or restarting the server are the more complicated tasks. Stopping and/or restarting can be accomplish either using signals or `ftpshut`, depending on your needs. Use of signals will fulfill most requirements; the `ftpshut` program is used for a specific way of shutting down a `proftpd` server.

Starting `proftpd`
The `ServerType` configured in your `proftpd.conf` determines how you should start your `proftpd` daemon. A `ServerType` of "inetd" means that you are letting inetd/xinetd handle the starting of the server; using "standalone" means that you will probably end up using some kind of script (e.g. `init.d` shell scripts).

All start scripts end up using, in some form or another, the various command-line options supported by `proftpd`:

      /usr/local/sbin/proftpd [options]

where `/usr/local/sbin` is determined by `configure` and `[options]` are described below (or in proftpd(8)):

     -h, --help
         Display proftpd usage
     -n, --nodaemon
         Disable background daemon mode and send all output to stderr)
     -q, --quiet
         Don't send output to stderr when running with -n or --nodaemon
     -d [level], --debug
         Set debugging level (0-9, 9 = most debugging)
     -D [definition], --define
         Set arbitrary IfDefine definition
     -c [config-file], --config
         Specify alternate configuration file
     -p [0|1], --persistent
         Enable/disable default persistent passwd support
     -l, --list
         List all compiled-in modules
     -t, --configtest
         Test the syntax of the specified config
     -v, --version
         Print version number and exit
     -vv, --version-status
         Print extended version information and exit

Signals
You will notice many `proftpd` processess running on your system, but you should not send signals to any of them except the parent, whose PID is in the `PidFile`. That is to say, you should not ever need to send signals to any process except the parent. There are two signals that you can send the parent: `TERM` and `HUP`, which will be described below.

To send a signal to the parent you should issue a command such as:

      kill -TERM `cat /usr/local/var/proftpd.pid`

You can read about its progress by issuing:

      tail -f /usr/local/var/logs/proftpd.log

Modify those examples to match your `SystemLog` and `PidFile` settings.

The `TERM` Signal (stop now)
Sending the `TERM` signal to the daemon parent process causes it to immediately attempt to kill off all of its children. It may take it several seconds to complete killing off its children. The daemon itself then exits. Any transfers in progress are terminated, and no further session requests are served.

Servers run out of `inetd` or `xinetd` (e.g. with a `ServerType` setting of `inetd`) will not need this signal, as their "parent" is the `inetd` or `xinetd` process.

The `HUP` Signal (restart now)
Sending the `HUP` signal to the daemon parent process causes it to re-read its configuration file(s), and re-opens any log files. Then it returns to handling new sessions. Any existing sessions will not be terminated.

Servers run out of `inetd` or `xinetd` will not need this signal; a new server process is started by the superserver process (e.g. `inetd` or `xinetd`) for every session request. This means that any changes to the configuration file will be visible to the next session after saving the changes to the file.

Note that if your configuration file has errors in it when you issue a restart then your parent will not restart, it will exit with an error. To avoid this, perform a syntax check of the file before sending the signal:

      proftpd -t -d5

Example `init.d` script
If your particular Unix/Linux distribution and/or `proftpd` package does not provide an init shell script for `proftpd`, or you want to write your own, here is a simple example script to demonstrate what one would look like:

      #!/bin/sh

      # ProFTPD files
      FTPD_BIN=/usr/local/sbin/proftpd
      FTPD_CONF=/usr/local/etc/proftpd.conf
      PIDFILE=/var/run/proftpd.pid

      # If PIDFILE exists, does it point to a proftpd process?

      if [ -f $PIDFILE ]; then
       pid=`cat $PIDFILE`
      fi

      if [ ! -x $FTPD_BIN ]; then
        echo "$0: $FTPD_BIN: cannot execute"
        exit 1
      fi

      case $1 in

        start)
          if [ -n "$pid" ]; then
            echo "$0: proftpd [PID $pid] already running"
            exit
          fi

          if [ -r $FTPD_CONF ]; then
            echo "Starting proftpd..."

            $FTPD_BIN -c $FTPD_CONF

          else
            echo "$0: cannot start proftpd -- $FTPD_CONF missing"
          fi
          ;;

        stop)
          if [ -n "$pid" ]; then
            echo "Stopping proftpd..."
            kill -TERM $pid

          else
            echo "$0: proftpd not running"
            exit 1
          fi
          ;;

        restart)
          if [ -n "$pid" ]; then
            echo "Rehashing proftpd configuration"
            kill -HUP $pid

          else
            echo "$0: proftpd not running"
            exit 1
          fi
          ;;

        *)
          echo "usage: $0 {start|stop|restart}"
          exit 1
          ;;

      esac

      exit 0

For Mac OSX users, here is an example Launcher/launchd `plist` configuration for `proftpd`:

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
        <plist version="1.0">
          <dict>
            <key>KeepAlive</key>
              <dict>
                <key>SuccessfulExit</key>
                  <true/>
              </dict>
            <key>Label</key>
              <string>org.proftpd.proftpd</string>
            <key>ProgramArguments</key>
              <array>
                <string>/usr/local/sbin/proftpd</string>
                <string>-n</string>
              </array>
            <key>RunAtLoad</key>
              <true/>
            <key>ServiceIPC</key>
              <false/>
          </dict>
        </plist>

This has been reported to run successfully on Mac OSX 10.4 and 10.5.

The `ftpshut` program
The `ftpshut` program that comes as part of ProFTPD can also be used to shut down a `proftpd` server, in a sense. This program does not actually cause the server to stop completely, but rather places the server in an "administrative shutdown" state. This means that the server will still be handling session requests, but will deny incoming requests, telling clients to come back later. `ftpshut` allows the administrator to configure the server to start refusing connections at some future date, and also to disconnect existing sessions at some future date.

The situation in which this ability is most useful (a FAQ) is one where filesystem maintainenance or work needs to be done in the area from which the FTP server is serving files, but the server need not be shutdown. By placing the server in an "administrative shutdown" mode, clients are barred from their file while the adminstrative work is being done. Once completed, the server can be put back in normal operating mode by simply deleting the shutdown message file, described below.

The `ftpshut` program works by creating a file, usually `/etc/shutmsg`, for which the server checks periodically. This file will contain the time at which the server is to place itself in "administrative shutdown" mode, and times (if any) of refusing incoming connections, disconnecting existing connections. Unfortunately, many third-party administration tools use `ftpshut` to shut down `proftpd` servers, rather than using the method above. The problem with this approach is that, once restarted, the server will check for `/etc/shutmsg`, and will not accept incoming connections, leading to this FAQ; the third-party administration tool often forgets to delete that file once done.

Read `ftpshut`'s man page for more detailed information on its usage.

Last Updated: $Date: 2013-07-02 05:46:51 $