Package: dovecot-imapd
Version: 1.0.rc15-2
Severity: normal
Tags: patch
I found myself needing to run two dovecot-auth servers (one for the IMAP
server and one for deliver), which necessitated running two independent
dovecot master daemons. Rather than create a copy of the init.d script,
I thought it would be much nicer if I could simply simlink to the
existing one and put any custom parameters in an equivalently named
/etc/default file. While making the modifications to accommodate this, I
noticed the init.d script could use updating to match the skeleton
script supplied with Etch. Attached is a version of the script that
accomplishes both of these things.
Some items of note:
NAME is automatically determined by deriving it from $0:
NAME=${0##*/}
This permits the simlink behavior I mentioned above.
A new CONF variable was introduced to track the name of the
configuration file:
CONF=/etc/dovecot/${NAME}.conf
As well as a bit of code to report an error and exit if it isn't readable.
I changed the description from:
DESC="mail server"
to:
DESC="IMAP/POP3 mail server"
I modified the regular expression that extracts the 'protocols' settings
from the conf file to permit tabs before the directive.
I added code to extract the location of the PID file from the conf file:
# determine the location of the PID file
# overide by setting base_dir in conf file or PIDBASE in /etc/defaults/$NAME
PIDBASE=${PIDBASE:-`sed -r "s/^[ \t]*base_dir[ \t]*=[ \t]*([^
\t]*)/\1/;t;d" ${CO$
PIDFILE=${PIDBASE:-/var/run/dovecot/}master.pid
The skeleton do_stop() function needed to be modified to make use of the
PIDFILE variable for both kill attempts, otherwise the script would kill
other dovecot master daemons besides the one started from the currently
running script.
(Also, that function made use of $NAME, which if derived from the script
name, won't necessarily reflect the name of the executable, so I
replaced it with ${DAEMON##*/}. Perhaps passing --exec $DAEMON to the
start-stop-daemon script would have the same end-result. Neither should
really matter if the PIDFILE is present.)
This chunk of code:
if grep protocols /etc/dovecot/dovecot.conf | sed 's/#.*$//' | tr -d '"' | \
egrep -q '[^#]*(\bpop3s?\b|\bimaps?\b)';
then
if [ -x /usr/lib/dovecot/imap-login -a -x /usr/lib/dovecot/imap ] \
|| [ -x /usr/lib/dovecot/pop3-login -a -x /usr/lib/dovecot/pop3 ];
then
echo -n "Starting $DESC: $NAME"
start-stop-daemon --start --quiet --oknodo --exec $DAEMON $OPTIONS
echo "."
fi
fi
from the old start case was left out. I didn't see the point in testing
for the presence of those package sub-components. They're supposed to be
an integral part of the Dovecot package, and if they're missing, it
suggests a broken installation, not a removed package that should be
silently ignored. (I presume the dovecot master process will complain
appropriately if any required modules are missing.)
These tests also prevent using the dovecot master process to launch only
an auth process. They assume your config includes imap or pop3 sections,
which may not be the case if you are only running deliver. (Not
inconceivable that a site might have one machine running deliver saving
mail to a shared file system, with other machines used to run IMAP/POP3.)
Of course diff against /etc/init.d/skeleton in initscripts 2.86.ds1-38
and the existing script in 1.0.rc15-2 for the full list of changes.
-Tom
#! /bin/sh
### BEGIN INIT INFO
# Provides: dovecot
# Required-Start: $syslog
# Required-Stop: $syslog
# Should-Start: $local_fs
# Should-Stop: $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Dovecot init script
# Description: Init script for dovecot services
### END INIT INFO
# Author: Miquel van Smoorenburg <[EMAIL PROTECTED]>.
# Modified for Debian GNU/Linux
# by Ian Murdock <[EMAIL PROTECTED]>.
#
# Do NOT "set -e"
# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC="IMAP/POP3 mail server"
NAME=${0##*/}
DAEMON=/usr/sbin/dovecot
DAEMON_ARGS=""
SCRIPTNAME=/etc/init.d/$NAME
CONF=/etc/dovecot/${NAME}.conf
# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions
# cong file readable?
if [ ! -r ${CONF} ]; then
[ "$VERBOSE" != no ] && log_daemon_msg "${CONF}: not readable" "$NAME" \
&& log_end_msg 1;
exit 1;
fi
# The init script should do nothing if dovecot or another imap/pop3 server
# is being run from inetd, and dovecot is configured to run as an imap or
# pop3 service
for p in `sed -r "s/^ *(([^:]+|\[[^]]+]|\*):)?(pop3s?|imaps?)[ \t].*/\3/;t;d" \
/etc/inetd.conf`
do
for q in `sed -r "s/^[ \t]*protocols[ \t]*=[
\t]*(([^\"]*)|\"(.*)\")/\2\3/;t;d" \
${CONF}`
do
if [ $p = $q ]; then
exit 0
fi
done
done
# determine the location of the PID file
# overide by setting base_dir in conf file or PIDBASE in /etc/defaults/$NAME
PIDBASE=${PIDBASE:-`sed -r "s/^[ \t]*base_dir[ \t]*=[ \t]*([^ \t]*)/\1/;t;d"
${CONF}`}
PIDFILE=${PIDBASE:-/var/run/dovecot/}master.pid
#
# Function that starts the daemon/service
#
do_start()
{
# Return
# 0 if daemon has been started
# 1 if daemon was already running
# 2 if daemon could not be started
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON
--test > /dev/null \
|| return 1
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
$DAEMON_ARGS \
|| return 2
}
#
# Function that stops the daemon/service
#
do_stop()
{
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile
$PIDFILE --name ${DAEMON##*/}
RETVAL="$?"
[ "$RETVAL" = 2 ] && return 2
# Wait for children to finish too if this is a daemon that forks
# and if the daemon is only ever run from this initscript.
# If the above conditions are not satisfied then add some other code
# that waits for the process to drop all resources that could be
# needed by services started subsequently. A last resort is to
# sleep for some time.
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --pidfile
$PIDFILE --name ${DAEMON##*/}
[ "$?" = 2 ] && return 2
# Many daemons don't delete their pidfiles when they exit.
rm -f $PIDFILE
return "$RETVAL"
}
#
# Function that sends a SIGHUP to the daemon/service
#
do_reload() {
#
# If the daemon can reload its configuration without
# restarting (for example, when it is sent a SIGHUP),
# then implement that here.
#
start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name
$NAME
return 0
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
#reload|force-reload)
#
# If do_reload() is not implemented then leave this commented out
# and leave 'force-reload' as an alias for 'restart'.
#
#log_daemon_msg "Reloading $DESC" "$NAME"
#do_reload
#log_end_msg $?
#;;
restart|force-reload)
#
# If the "reload" option is implemented then remove the
# 'force-reload' alias
#
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
exit 3
;;
esac
: