enhance documentation, clean-up installation

This commit is contained in:
John Dennis 2004-12-14 20:49:25 +00:00
parent 43539f916b
commit 6cf645eca7
6 changed files with 1397 additions and 21 deletions

628
dovecot-conf.patch Normal file
View File

@ -0,0 +1,628 @@
diff -r -u dovecot-0.99.11.orig/configure.in dovecot-0.99.11/configure.in
--- dovecot-0.99.11.orig/configure.in 2004-09-04 05:20:19.000000000 -0400
+++ dovecot-0.99.11/configure.in 2004-11-19 16:36:37.000000000 -0500
@@ -21,6 +21,20 @@
# check posix headers
AC_CHECK_HEADERS(sys/time.h)
+AC_ARG_WITH(logindir,
+[ --with-logindir=DIR LOGIN directory (LOCALSTATEDIR/run/dovecot)],
+ logindir="$withval",
+ logindir=\${localstatedir}/run/dovecot/login
+)
+AC_SUBST(logindir)
+
+AC_ARG_WITH(docdir,
+[ --with-docdir=DIR directory for documentation (DATADIR/doc/dovecot)],
+ docdir="$withval",
+ docdir=\${datadir}/doc/dovecot
+)
+AC_SUBST(docdir)
+
AC_ARG_ENABLE(ipv6,
[ --enable-ipv6 Enable IPv6 support (default)],
if test x$enableval = xno; then
@@ -180,6 +194,8 @@
)
AC_SUBST(ssldir)
+AM_CONDITIONAL(BUILD_SSL, test "$want_gnutls" = "yes" -o "$want_openssl" = "yes" )
+
AC_ARG_WITH(pop3d,
[ --with-pop3d Build POP3 server (default)],
if test x$withval = xno; then
@@ -1121,6 +1137,13 @@
AC_MSG_RESULT($i_cv_type_in6_addr)
fi
+if test $i_cv_type_in6_addr = yes; then
+ listenaddr='[[::]]'
+else
+ listenaddr='*'
+fi
+AC_SUBST(listenaddr)
+
dnl **
dnl ** storage classes
dnl **
@@ -1148,7 +1171,9 @@
AC_OUTPUT(
Makefile
+dovecot.conf
doc/Makefile
+doc/mkcert.sh
src/Makefile
src/lib/Makefile
src/lib-charset/Makefile
diff -r -u dovecot-0.99.11.orig/doc/Makefile.am dovecot-0.99.11/doc/Makefile.am
--- dovecot-0.99.11.orig/doc/Makefile.am 2004-05-25 14:21:10.000000000 -0400
+++ dovecot-0.99.11/doc/Makefile.am 2004-11-19 12:21:31.000000000 -0500
@@ -1,4 +1,4 @@
-docdir = $(datadir)/doc/dovecot
+exampledir=$(docdir)/examples
doc_DATA = \
auth.txt \
@@ -10,10 +10,13 @@
nfs.txt \
securecoding.txt
-EXTRA_DIST = \
+example_DATA = \
mkcert.sh \
dovecot-openssl.cnf \
dovecot-ldap.conf \
dovecot-mysql.conf \
- dovecot-pgsql.conf \
+ dovecot-pgsql.conf
+
+EXTRA_DIST = \
+ $(example_DATA) \
$(doc_DATA)
diff -r -u dovecot-0.99.11.orig/Makefile.am dovecot-0.99.11/Makefile.am
--- dovecot-0.99.11.orig/Makefile.am 2003-05-05 12:46:57.000000000 -0400
+++ dovecot-0.99.11/Makefile.am 2004-11-22 16:08:01.000000000 -0500
@@ -1,7 +1,18 @@
SUBDIRS = src doc
confdir = $(sysconfdir)
-conf_DATA = dovecot-example.conf
+conf_DATA = dovecot.conf
+
+doc_DATA = \
+ AUTHORS \
+ COPYING \
+ COPYING.LGPL \
+ ChangeLog \
+ INSTALL \
+ NEWS \
+ README \
+ TODO
+
EXTRA_DIST = \
config.rpath \
diff -N -u dovecot-0.99.11.orig/doc/mkcert.sh.in dovecot-0.99.11/doc/mkcert.sh.in
--- dovecot-0.99.11.orig/doc/mkcert.sh.in 1969-12-31 19:00:00.000000000 -0500
+++ dovecot-0.99.11/doc/mkcert.sh.in 2004-11-19 13:47:38.000000000 -0500
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+# Generates a self-signed certificate.
+# Edit dovecot-openssl.cnf before running this.
+
+OPENSSL=${OPENSSL-openssl}
+SSLDIR=${SSLDIR-@ssldir@}
+OPENSSLCONFIG=${OPENSSLCONFIG-dovecot-openssl.cnf}
+
+CERTFILE=$SSLDIR/certs/@PACKAGE@.pem
+KEYFILE=$SSLDIR/private/@PACKAGE@.pem
+
+if [ ! -d $SSLDIR/certs ]; then
+ echo "$SSLDIR/certs directory doesn't exist"
+fi
+
+if [ ! -d $SSLDIR/private ]; then
+ echo "$SSLDIR/private directory doesn't exist"
+fi
+
+if [ -f $CERTFILE ]; then
+ echo "$CERTFILE already exists, won't overwrite"
+ exit 1
+fi
+
+if [ -f $KEYFILE ]; then
+ echo "$KEYFILE already exists, won't overwrite"
+ exit 1
+fi
+
+$OPENSSL req -new -x509 -nodes -config $OPENSSLCONFIG -out $CERTFILE -keyout $KEYFILE -days 365 || exit 2
+chmod 0600 $KEYFILE
+echo
+$OPENSSL x509 -subject -fingerprint -noout -in $CERTFILE || exit 2
diff -N -u dovecot-0.99.11.orig/dovecot.conf.in dovecot-0.99.11/dovecot.conf.in
--- dovecot-0.99.11.orig/dovecot.conf.in 1969-12-31 19:00:00.000000000 -0500
+++ dovecot-0.99.11/dovecot.conf.in 2004-11-19 16:42:03.000000000 -0500
@@ -0,0 +1,481 @@
+## Dovecot 1.0 configuration file
+
+# Base directory where to store runtime data.
+#base_dir = @localstatedir@/run/dovecot/
+
+# Protocols we want to be serving:
+# imap imaps pop3 pop3s
+#protocols = imap imaps
+
+# IP or host address where to listen in for connections. It's not currently
+# possible to specify multiple addresses. "*" listens in all IPv4 interfaces.
+# "[::]" listens in all IPv6 interfaces, but may also listen in all IPv4
+# interfaces depending on the operating system. You can specify ports with
+# "host:port".
+imap_listen = @listenaddr@
+pop3_listen = @listenaddr@
+
+# IP or host address where to listen in for SSL connections. Defaults
+# to above non-SSL equilevants if not specified.
+#imaps_listen = @listenaddr@
+#pop3s_listen = @listenaddr@
+
+# Disable SSL/TLS support.
+@BUILD_SSL_TRUE@ssl_disable = no
+
+# PEM encoded X.509 SSL/TLS certificate and private key. They're opened before
+# dropping root privileges, so keep the key file unreadable by anyone but
+# root. Included doc/mkcert.sh can be used to easily generate self-signed
+# certificate, just make sure to update the domains in dovecot-openssl.cnf
+@BUILD_SSL_TRUE@ssl_cert_file = @ssldir@/certs/@PACKAGE@.pem
+@BUILD_SSL_TRUE@ssl_key_file = @ssldir@/private/@PACKAGE@.pem
+
+# SSL parameter file. Master process generates this file for login processes.
+# It contains Diffie Hellman and RSA parameters.
+@BUILD_SSL_TRUE@ssl_parameters_file = @localstatedir@/run/dovecot/ssl-parameters.dat
+
+# How often to regenerate the SSL parameters file. Generation is quite CPU
+# intensive operation. The value is in hours, 0 disables regeneration
+# entirely.
+@BUILD_SSL_TRUE@ssl_parameters_regenerate = 24
+
+# Disable LOGIN command and all other plaintext authentications unless
+# SSL/TLS is used (LOGINDISABLED capability). Note that 127.*.*.* and
+# IPv6 ::1 addresses are considered secure, this setting has no effect if
+# you connect from those addresses.
+#disable_plaintext_auth = yes
+
+# Use this logfile instead of syslog(). /dev/stderr can be used if you want to
+# use stderr for logging (ONLY /dev/stderr - otherwise it is closed).
+#log_path =
+
+# For informational messages, use this logfile instead of the default
+#info_log_path =
+
+# Prefix for each line written to log file. % codes are in strftime(3)
+# format.
+#log_timestamp = "%b %d %H:%M:%S "
+
+##
+## Login processes
+##
+
+# Directory where authentication process places authentication UNIX sockets
+# which login needs to be able to connect to. The sockets are created when
+# running as root, so you don't have to worry about permissions. Note that
+# everything in this directory is deleted when Dovecot is started.
+#login_dir = @logindir@
+
+# chroot login process to the login_dir. Only reason not to do this is if you
+# wish to run the whole Dovecot without roots.
+#login_chroot = yes
+
+
+##
+## IMAP login process
+##
+
+login = imap
+
+# Executable location.
+#login_executable = @libexecdir@/dovecot/imap-login
+
+# User to use for the login process. Create a completely new user for this,
+# and don't use it anywhere else. The user must also belong to a group where
+# only it has access, it's used to control access for authentication process.
+#login_user = dovecot
+
+# Set max. process size in megabytes. If you don't use
+# login_process_per_connection you might need to grow this.
+#login_process_size = 32
+
+# Should each login be processed in it's own process (yes), or should one
+# login process be allowed to process multiple connections (no)? Yes is more
+# secure, espcially with SSL/TLS enabled. No is faster since there's no need
+# to create processes all the time.
+#login_process_per_connection = yes
+
+# Number of login processes to create. If login_process_per_user is
+# yes, this is the number of extra processes waiting for users to log in.
+#login_processes_count = 3
+
+# Maximum number of extra login processes to create. The extra process count
+# usually stays at login_processes_count, but when multiple users start logging
+# in at the same time more extra processes are created. To prevent fork-bombing
+# we check only once in a second if new processes should be created - if all
+# of them are used at the time, we double their amount until limit set by this
+# setting is reached. This setting is used only if login_process_per_use is yes.
+#login_max_processes_count = 128
+
+# Maximum number of connections allowed in login state. When this limit is
+# reached, the oldest connections are dropped. If login_process_per_user
+# is no, this is a per-process value, so the absolute maximum number of users
+# logging in actually login_processes_count * max_logging_users.
+#login_max_logging_users = 256
+
+##
+## POP3 login process
+##
+
+# Settings default to same as above, so you don't have to set anything
+# unless you want to override them.
+
+login = pop3
+
+# Exception to above rule being the executable location.
+#login_executable = @libexecdir@/dovecot/pop3-login
+
+##
+## Mail processes
+##
+
+# Maximum number of running mail processes. When this limit is reached,
+# new users aren't allowed to log in.
+#max_mail_processes = 1024
+
+# Show more verbose process titles (in ps). Currently shows user name and
+# IP address. Useful for seeing who are actually using the IMAP processes
+# (eg. shared mailboxes or if same uid is used for multiple accounts).
+#verbose_proctitle = no
+
+# Show protocol level SSL errors.
+@BUILD_SSL_TRUE@verbose_ssl = no
+
+# Valid UID range for users, defaults to 500 and above. This is mostly
+# to make sure that users can't log in as daemons or other system users.
+# Note that denying root logins is hardcoded to dovecot binary and can't
+# be done even if first_valid_uid is set to 0.
+#first_valid_uid = 500
+#last_valid_uid = 0
+
+# Valid GID range for users, defaults to non-root/wheel. Users having
+# non-valid GID as primary group ID aren't allowed to log in. If user
+# belongs to supplementary groups with non-valid GIDs, those groups are
+# not set.
+#first_valid_gid = 1
+#last_valid_gid = 0
+
+# Grant access to these extra groups for mail processes. Typical use would be
+# to give "mail" group write access to /var/mail to be able to create dotlocks.
+#mail_extra_groups =
+
+# ':' separated list of directories under which chrooting is allowed for mail
+# processes (ie. /var/mail will allow chrooting to /var/mail/foo/bar too).
+# This setting doesn't affect login_chroot or auth_chroot variables.
+# WARNING: Never add directories here which local users can modify, that
+# may lead to root exploit. Usually this should be done only if you don't
+# allow shell access for users. See doc/configuration.txt for more information.
+#valid_chroot_dirs =
+
+# Default chroot directory for mail processes. This can be overridden by
+# giving /./ in user's home directory (eg. /home/./user chroots into /home).
+#mail_chroot =
+
+# Default MAIL environment to use when it's not set. By leaving this empty
+# dovecot tries to do some automatic detection as described in
+# doc/mail-storages.txt. There's a few special variables you can use:
+#
+# %u - username
+# %n - user part in user@domain, same as %u if there's no domain
+# %d - domain part in user@domain, empty if user there's no domain
+# %h - home directory
+#
+# You can also limit a width of string by giving the number of max. characters
+# after the '%' character. For example %1u gives the first character of
+# username. Some examples:
+#
+# default_mail_env = maildir:/var/mail/%1u/%u/Maildir
+# default_mail_env = mbox:~/mail/:INBOX=/var/mail/%u
+# default_mail_env = mbox:/var/mail/%d/%n/:INDEX=/var/indexes/%d/%n
+#
+#default_mail_env =
+
+# Space-separated list of fields to cache for all mails. Currently these
+# fields are allowed followed by a list of commands they speed up:
+#
+# Envelope - FETCH ENVELOPE and SEARCH FROM, TO, CC, BCC, SUBJECT,
+# SENTBEFORE, SENTON, SENTSINCE, HEADER MESSAGE-ID,
+# HEADER IN-REPLY-TO
+# Body - FETCH BODY
+# Bodystructure - FETCH BODY, BODYSTRUCTURE
+# MessagePart - FETCH BODY[1.2.3] (ie. body parts), RFC822.SIZE,
+# SEARCH SMALLER, LARGER, also speeds up BODY/BODYSTRUCTURE
+# generation. This is always set with mbox mailboxes, and
+# also default with Maildir.
+#
+# Different IMAP clients work in different ways, that's why Dovecot by default
+# only caches MessagePart which speeds up most operations. Whenever client
+# does something where caching could be used, the field is automatically marked
+# to be cached later. For example after FETCH BODY the BODY will be cached
+# for all new messages. Normally you should leave this alone, unless you know
+# what most of your IMAP clients are. Caching more fields than needed makes
+# the index files larger and generate useless I/O.
+#
+# With maildir there's one extra optimization - if nothing is cached, indexing
+# the maildir becomes much faster since it's not opening any of the mail files.
+# This could be useful if your IMAP clients access only new mails.
+
+#mail_cache_fields = MessagePart
+
+# Space-separated list of fields that Dovecot should never set to be cached.
+# Useful if you want to save disk space at the cost of more I/O when the fields
+# needed.
+#mail_never_cache_fields =
+
+# Workarounds for various client bugs:
+# oe6-fetch-no-newmail:
+# Never send EXISTS/RECENT when replying to FETCH command. Outlook Express
+# seems to think they are FETCH replies and gives user "Message no longer
+# in server" error. Note that OE6 still breaks even with this workaround
+# if synchronization is set to "Headers Only".
+# outlook-idle:
+# Outlook and Outlook Express never abort IDLE command, so if no mail
+# arrives in half a hour, Dovecot closes the connection. This is still
+# fine, except Outlook doesn't connect back so you don't see if new mail
+# arrives.
+# outlook-pop3-no-nuls:
+# Outlook and Outlook Express hang if mails contain NUL characters.
+# This setting replaces them with 0x80 character.
+#client_workarounds =
+
+# Dovecot can notify client of new mail in selected mailbox soon after it's
+# received. This setting specifies the minimum interval in seconds between
+# new mail notifications to client - internally they may be checked more or
+# less often. Setting this to 0 disables the checking.
+# NOTE: Evolution client breaks with this option when it's trying to APPEND.
+#mailbox_check_interval = 0
+
+# Like mailbox_check_interval, but used for IDLE command.
+#mailbox_idle_check_interval = 30
+
+# Allow full filesystem access to clients. There's no access checks other than
+# what the operating system does for the active UID/GID. It works with both
+# maildir and mboxes, allowing you to prefix mailboxes names with eg. /path/
+# or ~user/.
+#mail_full_filesystem_access = no
+
+# Maximum allowed length for custom flag name. It's only forced when trying
+# to create new flags.
+#mail_max_flag_length = 50
+
+# Save mails with CR+LF instead of plain LF. This makes sending those mails
+# take less CPU, especially with sendfile() syscall with Linux and FreeBSD.
+# But it also creates a bit more disk I/O which may just make it slower.
+#mail_save_crlf = no
+
+# Use mmap() instead of read() to read mail files. read() seems to be a bit
+# faster with my Linux/x86 and it's better with NFS, so that's the default.
+#mail_read_mmaped = no
+
+# By default LIST command returns all entries in maildir beginning with dot.
+# Enabling this option makes Dovecot return only entries which are directories.
+# This is done by stat()ing each entry, so it causes more disk I/O.
+# (For systems setting struct dirent->d_type, this check is free and it's
+# done always regardless of this setting)
+#maildir_stat_dirs = no
+
+# Copy mail to another folders using hard links. This is much faster than
+# actually copying the file. This is problematic only if something modifies
+# the mail in one folder but doesn't want it modified in the others. I don't
+# know any MUA which would modify mail files directly. IMAP protocol also
+# requires that the mails don't change, so it would be problematic in any case.
+# If you care about performance, enable it.
+#maildir_copy_with_hardlinks = no
+
+# Check if mails' content has been changed by external programs. This slows
+# down things as extra stat() needs to be called for each file. If changes are
+# noticed, the message is treated as a new message, since IMAP protocol
+# specifies that existing messages are immutable.
+#maildir_check_content_changes = no
+
+# Which locking methods to use for locking mbox. There's three available:
+# dotlock: Create <mailbox>.lock file. This is the oldest and most NFS-safe
+# solution. If you want to use /var/mail/ like directory, the users
+# will need write access to that directory.
+# fcntl : Use this if possible. Works with NFS too if lockd is used.
+# flock : May not exist in all systems. Doesn't work with NFS.
+#
+# You can use both fcntl and flock too; if you do the order they're declared
+# with is important to avoid deadlocks if other MTAs/MUAs are using both fcntl
+# and flock. Some operating systems don't allow using both of them
+# simultaneously, eg. BSDs. If dotlock is used, it's always created first.
+#mbox_locks = dotlock fcntl
+
+# Should we create dotlock file even when we want only a read-lock? Setting
+# this to yes hurts the performance when the mailbox is accessed simultaneously
+# by multiple processes, but it's needed for reliable reading if no other
+# locking methods are available.
+#mbox_read_dotlock = no
+
+# Maximum time in seconds to wait for lock (all of them) before aborting.
+#mbox_lock_timeout = 300
+
+# If dotlock exists but the mailbox isn't modified in any way, override the
+# lock file after this many seconds.
+#mbox_dotlock_change_timeout = 30
+
+# umask to use for mail files and directories
+#umask = 0077
+
+# Drop all privileges before exec()ing the mail process. This is mostly
+# meant for debugging, otherwise you don't get core dumps. Note that setting
+# this to yes means that log file is opened as the logged in user, which
+# might not work. It could also be a small security risk if you use single UID
+# for multiple users, as the users could ptrace() each others processes then.
+#mail_drop_priv_before_exec = no
+
+##
+## IMAP process
+##
+
+# Executable location
+#imap_executable = @libexecdir@/dovecot/imap
+
+# Set max. process size in megabytes. Most of the memory goes to mmap()ing
+# files, so it shouldn't harm much even if this limit is set pretty high.
+#imap_process_size = 256
+
+# Support for dynamically loadable modules.
+#imap_use_modules = no
+#imap_modules = @moduledir@/imap
+
+##
+## POP3 process
+##
+
+# Executable location
+#pop3_executable = @libexecdir@/dovecot/pop3
+
+# Set max. process size in megabytes. Most of the memory goes to mmap()ing
+# files, so it shouldn't harm much even if this limit is set pretty high.
+#pop3_process_size = 256
+
+# Support for dynamically loadable modules.
+#pop3_use_modules = no
+#pop3_modules = @moduledir@/pop3
+
+##
+## Authentication processes
+##
+
+# An Authentication process is a child process used by Dovecot that
+# handles the authentication steps. The steps cover an authentication
+# mechanism (auth_mechanisms, how the client authenticates in the IMAP or
+# POP3 protocol), which password database should be queried (auth_passdb),
+# and which user database should be queried (auth_userdb, to obtain
+# UID, GID, and location of the user's mailbox/home directory).
+#
+# You can have multiple processes, though a typical configuration will
+# have only one. Each time "auth = xx" is seen, a new process
+# definition is started. The point of multiple processes is to be able
+# to set stricter permissions. (See auth_user below.)
+#
+# Just remember that only one Authentication process is asked for the
+# password, so you can't have different passwords accessible through
+# different process definitions (unless they have different
+# auth_mechanisms, and you're ok with having different password for
+# each mechanisms).
+
+# Authentication process name.
+auth = default
+
+# Specifies how the client authenticates in the IMAP protocol.
+# Space separated list of permitted authentication mechanisms:
+# anonymous plain digest-md5 cram-md5
+#
+# anonymous - No authentication required.
+# plain - The password is sent as plain text. All IMAP/POP3 clients
+# support this, and the password can be encrypted by Dovecot to match
+# any of the encryption schemes used in password databases.
+# digest-md5 and cram-md5 - both encrypt the password so it is more
+# secure in transit, but are not well supported by clients, and
+# require that the password database use a matching encryption
+# scheme (or be in plaintext).
+#
+# See auth.txt for more details.
+#
+# If you are using SSL there is less benefit to digest-md5 and
+# cram-md5 as the communication is already encrypted.
+auth_mechanisms = plain
+
+# Space separated list of realms for SASL authentication mechanisms that need
+# them. You can leave it empty if you don't want to support multiple realms.
+# Many clients simply use the first one listed here, so keep the default realm
+# first.
+#auth_realms =
+
+# Default realm/domain to use if none was specified. This is used for both
+# SASL realms and appending @domain to username in plaintext logins.
+#auth_default_realm =
+
+# Where user database is kept:
+# passwd: /etc/passwd or similiar, using getpwnam()
+# passwd-file <path>: passwd-like file with specified location
+# static uid=<uid> gid=<gid> home=<dir template>: static settings
+# vpopmail: vpopmail library
+# ldap <config path>: LDAP, see doc/dovecot-ldap.conf
+# pgsql <config path>: a PostgreSQL database, see doc/dovecot-pgsql.conf
+auth_userdb = passwd
+
+# Where password database is kept:
+# passwd: /etc/passwd or similiar, using getpwnam()
+# shadow: /etc/shadow or similiar, using getspnam()
+# pam [<service> | *]: PAM authentication
+# passwd-file <path>: passwd-like file with specified location
+# vpopmail: vpopmail authentication
+# ldap <config path>: LDAP, see doc/dovecot-ldap.conf
+# pgsql <config path>: a PostgreSQL database, see doc/dovecot-pgsql.conf
+auth_passdb = pgsql @sysconfdir@/dovecot-pgsql.conf
+
+#auth_executable = @libexecdir@/dovecot/dovecot-auth
+
+# Set max. process size in megabytes.
+#auth_process_size = 256
+
+# User to use for the process. This user needs access to only user and
+# password databases, nothing else. Only shadow and pam authentication
+# requires roots, so use something else if possible. Note that passwd
+# authentication with BSDs internally accesses shadow files, which also
+# requires roots.
+auth_user = root
+
+# Directory where to chroot the process. Most authentication backends don't
+# work if this is set, and there's no point chrooting if auth_user is root.
+#auth_chroot =
+
+# Number of authentication processes to create
+#auth_count = 1
+
+# List of allowed characters in username. If the user-given username contains
+# a character not listed in here, the login automatically fails. This is just
+# an extra check to make sure user can't exploit any potential quote escaping
+# vulnerabilities with SQL/LDAP databases. If you want to allow all characters,
+# set this value to empty.
+#auth_username_chars = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@
+
+# Username to use for users logging in with ANONYMOUS SASL mechanism
+#auth_anonymous_username = anonymous
+
+# More verbose logging. Useful for figuring out why authentication isn't
+# working.
+#auth_verbose = no
+
+# Even more verbose logging for debugging purposes. Shows for example SQL
+# queries.
+#auth_debug = no
+
+# digest-md5 authentication process. It requires special MD5 passwords which
+# /etc/shadow and PAM doesn't support, so we never need roots to handle it.
+# Note that the passwd-file is opened before chrooting and dropping root
+# privileges, so it may be 0600-root owned file.
+
+#auth = digest_md5
+#auth_mechanisms = digest-md5
+#auth_realms =
+#auth_userdb = passwd-file /etc/passwd.imap
+#auth_passdb = passwd-file /etc/passwd.imap
+#auth_user = imapauth
+#auth_chroot =
+
+# if you plan to use only passwd-file, you don't need the two auth processes,
+# simply set "auth_methods = plain digest-md5"

View File

@ -1,13 +1,17 @@
Summary: Dovecot Secure imap server
Name: dovecot
Version: 0.99.11
Release: 2.FC4.1
Release: 6.devel
License: LGPL
Group: System Environment/Daemons
Source: %{name}-%{version}.tar.gz
Source1: dovecot.init
Source2: dovecot.pam
Patch100: dovecot-0.99.10.4-conf.patch
Source3: maildir-migration.txt
Source4: migrate-folders
Source5: migrate-users
Source6: perfect_maildir.pl
Patch100: dovecot-conf.patch
# Patches 500+ from upstream fixes
URL: http://dovecot.procontrol.fi/
@ -19,8 +23,12 @@ BuildRequires: openldap-devel
BuildRequires: pam-devel
BuildRequires: pkgconfig
BuildRequires: zlib-devel
BuildRequires: gettext-devel
Prereq: openssl, /sbin/chkconfig, /usr/sbin/useradd
%define docdir %{_docdir}/%{name}-%{version}
%define ssldir /usr/share/ssl
%description
Dovecot is an IMAP server for Linux/UNIX-like systems, written with security
primarily in mind. It also contains a small POP3 server. It supports mail
@ -35,21 +43,25 @@ in either of maildir or mbox formats.
%build
rm -f ./configure
aclocal
autoconf
automake -a -f
autoconf -f
%configure \
--with-docdir=%{docdir} \
--with-logindir=/var/run/dovecot-login \
--with-mbox-locks=fcntl \
--with-pgsql \
--with-mysql \
--with-ssl=openssl \
--with-ssldir=/usr/share/ssl \
--with-ssldir=%{ssldir} \
--with-ldap
make
%install
rm -rf $RPM_BUILD_ROOT
%makeinstall
make DESTDIR=$RPM_BUILD_ROOT install
rm -rf $RPM_BUILD_ROOT/%{_datadir}/%{name}
install -m 644 dovecot-example.conf $RPM_BUILD_ROOT/%{_sysconfdir}/dovecot.conf
mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/rc.d/init.d
install -m 755 %{SOURCE1} $RPM_BUILD_ROOT/%{_sysconfdir}/rc.d/init.d/dovecot
@ -57,17 +69,19 @@ mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/pam.d
install -m 644 %{SOURCE2} $RPM_BUILD_ROOT/%{_sysconfdir}/pam.d/dovecot
# generate ghost .pem file
mkdir -p $RPM_BUILD_ROOT/%{_datadir}/ssl/{certs,private}
touch $RPM_BUILD_ROOT/%{_datadir}/ssl/{certs,private}/dovecot.pem
chmod 600 $RPM_BUILD_ROOT/%{_datadir}/ssl/{certs,private}/dovecot.pem
mkdir -p $RPM_BUILD_ROOT/%{ssldir}/{certs,private}
touch $RPM_BUILD_ROOT/%{ssldir}/{certs,private}/dovecot.pem
chmod 600 $RPM_BUILD_ROOT/%{ssldir}/{certs,private}/dovecot.pem
mkdir -p $RPM_BUILD_ROOT/var/run/dovecot
chmod 700 $RPM_BUILD_ROOT/var/run/dovecot
mkdir -p $RPM_BUILD_ROOT/var/run/dovecot-login
# the dovecot make install installs docs. blah.
rm -rf $RPM_BUILD_ROOT/%{_docdir}/%{name}
rm -f $RPM_BUILD_ROOT/etc/dovecot-example.conf
install -m755 -d $RPM_BUILD_ROOT%{docdir}/UW-to-Dovecot-Migration
for f in maildir-migration.txt migrate-folders migrate-users perfect_maildir.pl
do
install -m644 $RPM_SOURCE_DIR/$f $RPM_BUILD_ROOT%{docdir}/UW-to-Dovecot-Migration
done
%pre
/usr/sbin/useradd -c "dovecot" -u 97 -s /sbin/nologin -r -d /usr/libexec/dovecot dovecot 2>/dev/null || :
@ -75,8 +89,8 @@ rm -f $RPM_BUILD_ROOT/etc/dovecot-example.conf
%post
/sbin/chkconfig --add dovecot
# create a ssl cert
if [ ! -f %{_datadir}/ssl/certs/dovecot.pem ]; then
pushd %{_datadir}/ssl &>/dev/null
if [ ! -f %{ssldir}/certs/dovecot.pem ]; then
pushd %{ssldir} &>/dev/null
umask 077
cat << EOF | openssl req -new -x509 -days 365 -nodes -out certs/dovecot.pem -keyout private/dovecot.pem &>/dev/null
--
@ -107,12 +121,12 @@ rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
%doc doc/*.txt doc/dovecot-openssl.cnf doc/mkcert.sh INSTALL AUTHORS ChangeLog COPYING TODO README NEWS COPYING.LGPL
%doc %{docdir}
%config(noreplace) %{_sysconfdir}/dovecot.conf
%config %{_sysconfdir}/rc.d/init.d/dovecot
%config %{_sysconfdir}/pam.d/dovecot
%attr(0600,root,root) %ghost %config(missingok,noreplace) %verify(not md5 size mtime) %{_datadir}/ssl/certs/dovecot.pem
%attr(0600,root,root) %ghost %config(missingok,noreplace) %verify(not md5 size mtime) %{_datadir}/ssl/private/dovecot.pem
%attr(0600,root,root) %ghost %config(missingok,noreplace) %verify(not md5 size mtime) %{ssldir}/certs/dovecot.pem
%attr(0600,root,root) %ghost %config(missingok,noreplace) %verify(not md5 size mtime) %{ssldir}/private/dovecot.pem
%dir %{_libexecdir}/%{name}
%{_libexecdir}/%{name}/*
%{_sbindir}/dovecot

315
maildir-migration.txt Normal file
View File

@ -0,0 +1,315 @@
Replacing UW-IMAP with Dovecot on Red Hat Enterprise Linux 3.
G.R.Keech <rkeech@redhat.com>
2004-11-09
Version 1.0
Summary
The IMAP server in Red Hat Enterprise Linux version 3 (RHEL3) is the
University of Washington (UW) implemenation. UW IMAP uses the mbox
mail storage format which has been found to have significant
scalability and performance issues. This paper describes how to
replace UW IMAP with the Dovecot IMAP server which uses the maildir
mail storage format and, consequently, is significantly faster.
Maildir vs Mbox
Format issues. The mbox format holds email with one file corresponding
to an entire mail folder. Maildir, on the other hand, stores messages
one directory per folder, with each message being a single file. The
mbox format doesn't scale well when many users have large mail folders
which are polled frequently. When the sum of sizes of all the
frequently polled mail greatly exceed the system's RAM, then mail
boxes cannot be effectively cached in RAM. This leads to a situation
where mbox files are being continually re-read with each poll by each
mail client, leading to excessive IO activity and poor performance.
Example. Here is a real example of poor performance using UW IMAP.
The site characteristics were as follows:
* about 116 active mail accounts with users using a mix of both
Outlook express and Outlook;
* Mail clients poll for new mail every five minutes;
* 1GB system RAM in mail server;
* Mail server using Postfix on RHEL3 (kernel 2.4.21-20.EL);
* System has single 3.0GHz P4 processor and SATA disk;
* 112 inboxes totalling 3.3GB (average about 30MB each);
* 8.5GB of filed email in imap folders.
Performance with mbox. When in use the load average on the mail server
was normally between four and six with spikes above 15 not uncommon
and spikes above 20 occasionally. Most of this load was associated
with instances of uw-imap in disk wait state. The user experience in
checking mail was very poor, despite this being a reasonably small
site. When users checked for new mail they frequently encountered
server timeouts. For users with large inboxes, it was not uncommon
for it to take between 60 and 90 seconds just to check for new mail.
Performance with maildir. Once the imap service was changed to
Dovecot, with all the other variables remaining unchanged, the
situation improved dramatically. Load average is very rarely above
0.5 and is usually under 0.2 during working hours. The user
experience was improved significantly. Users no longer
experience timeouts, and the time taken to check for new mail
is usually only two or three seconds and always less than 10 seconds.
Setting up Dovecot
Dovecot. The Dovecot IMAP server will replace UW IMAP in RHEL4. The
Dovecot project is at http://dovecot.procontrol.fi/. It was built for
RHEL3 based on the package from the Beta of RHEL4. The RHEL3 version
used in this migration can be found at
http://people.redhat.com/rkeech/#dovecot.
Operation. Dovecot, unlike uw-imap, runs as a conventional
daemon-based service, ie it is not run from xinetd. When running
A typical process hierarchy when Dovecot is running looks as follows:
dovecot --+--- dovecot-auth
+--- imap
+--- imap-login
One instance of the "imap" process will exist for each mail client
connection. These imap processes execute with the user context of
whichever mail account user is connecting. The main "dovecot" process
runs as root, as does "dovecot-auth". The imap-login processes run
as user "dovecot".
Configuration. Dovecot is configured with /etc/dovecot.conf. The relevant
configuration setting that had to be changed in this case were as follows:
protocols = imap
default_mail_env = maildir:/data/mail2/%u/
User home. In this particular migration, mail account users did not
need shell access and did not need home directories for anything but
mail folder storage. Accordingly it was possible to change the users'
home directories to be the same as the mail spool area. This can be
achieved with (for this example)
usermod -d /data/mail2/<user> <user>
User shell. Mail accounts can function without a user shell. However
if a mail auto-responder (ie "vacation") is used then a shell is necessary.
Under RHEL3 a restricted shell is possible and reduces the security
concerns associated with providing shell access to mail users. For
a restricted version of bash make a sybolic link called "/bin/rbash"
pointing to "/bin/bash", and make /bin/rbash the users' shell.
Postfix delivery. The location of mail delivery by Postfix is set
according to the "mail_spool_directory" parameter. When using uw-imap
this was set to "/var/spool/mail". A trailing slash on the
mail_spool_directory value directs Postfix to use maildir format. The
change to Postfix configuration in this case was done with:
postconf -e "mail_spool_directory = /data/mail2/"
Directory structure. For mail delivery to work with maildir a number
of sub-directories must exist in the user's personal mail spool
directory. If user "fred" has mail delivered to /data/mail2/fred/
then that directory should have subdirectories "cur" "new" and "tmp"
in it. The "new" directory is where incoming mail messages are put.
Other folders structured in subdirectories, eg an imap folder called
"Sent" for user "fred" would be /data/mail2/fred/.Sent, and there would
be a line "Sent" in the file /data/mail2/fred/.subscriptions.
Account creation. In the case where the mail spool area is also the
home directory, then for new accounts to accept maildir mail delivery,
the following directories should be created:
/etc/skel/cur
/etc/skel/tmp
/etc/skel/new
thus when an account is created, the necessary subdirectories are
automatically created in the new user's home for a maildir-style
inbox.
Migrating Mbox folders to Maildirs
Conversion. The tools to convert existing mbox-style mailboxes
and folders to maildir format are not provided with Dovecot or RHEL3.
A tool called perfect_maildir was found on the Net which performs
the conversion for a single folder only. A script was written to
provide for bulk conversion of folders for all users.
Perfect_maildir. The tool lives at http://perfectmaildir.home-dn.net.
Versions prior to 0.3 should not be used. Perfect_maildir is a Perl
script.
Migration plan. The migration to maildir was performed within the
following bounds:
* existing inboxes were in /var/spool/mail
* existing mail folders were under /home/<user>/
* new inboxes and mailfolders were combined under /data/mail2/<user>/
Migration scripts. The scripts prepared to handle the bulk conversion are
"migration-users" and "migrate-folders". migrate-users creates the
necessary new user mail directories under the new base directory, which
in this case was /data/mail2/. In a situation where mail accounts
needed to be setup, without the need to migrate folders then migrate-users
would be sufficient, ie the second script would not be used.
migrate-folders does the main work of the migration by calling perfect_maildir
once for each mbox mailfolder including the users' inbox. migrate-users
must be run before migrate-folders.
Pre-migration. Before migrating, some things to check are:
Will the file system have enough inodes now that the number of files
is much larger? "df -i" will help. Run tune2fs as required to
increase the allowance for inodes.
Will there be a very large number of mail accounts? The maximum
number of subdirectories per directory is 32k. If the number of
accounts does or might exceed this, then change the Dovecot
default_mail_env to suit. See the Dovecot documentation for more
information.
Where do you want dovecot to send its log messages? By default it
uses syslog and sends to the mail facility. This can be changed to
log to a its own log file if it is not convenient to log to maillog.
Migration steps. The actual mail file migration was performed as below
using the scripts from http://people.rehdat.com/rkeech/#maildirmigration
Note, the migration steps described here leave the original mbox inboxes
and mail folders intact. Should the migration fail, then the capacity
to continue using mbox format is retained.
1. Ensure that no new accounts are created until the migration is
complete. Normal email operation can proceed until step X. Do not
change Postfix's mail_spool_directory until step Y.
2. Create a working directory /root/migrate/.
3. Create a list of users whose mailboxes are to be migrated
/root/migrate/userlist-master. The file has one user per line.
4. Create a list of mbox folders (excluding inboxes) to be migrated
/root/migrate/folderlist-master The file has one mbox per line and
excludes the path to the user's home, eg
+-----------------
|fred/Drafts
|fred/private
|fred/Sent
|fred/office
|fred/projectx
|mary/Sent
|mary/private
Check that the folderlist does not contain any folders with characters
likely to be problematic when handled by scripts, ie folders whose names
include quotation marks, comas, pound signs, "&" symbols etc. Any such
folders should have their names changed. The name change in the
folderlist file should reflect the name change on disk. Folder names
with spaces, hyphens, percent signs, and periods are known to be OK.
5. Proceed with a test migration with a small subset of users by
creating /root/migrate/userlist and /root/migrate/folderlist based on
subsets of userlist-master and folderlist-master. The test migration
should be done with accounts that have representative mail in both
inbox and imap folders.
6. Ensure that the new mail base directory is clear. In this example
it means that /data/mail2/ is emtpy.
7. Run migrate-users which should read /root/migrate/userlist and
create the new user mail directories under /data/mail2/. Check that
a directory for each user is created under /data/mail2/.
8. Start dovecot on an alternative port so as not to intefere with the
normal uw-imap. This is done by editing /etc/dovecot.conf with
imap_listen = 1.2.3.4:1043
Obviously change address 1.2.3.4 to correspond to the local server.
Run
service dovecot start
Dovecot should start cleanly.
It is assumed that the "protocols" and "default_mail_env" settings
are already set in /etc/dovecot.conf as described in "Configuration"
above.
9. Run migrate-folders which should reate /root/migrate/folderlist and
populate all the necessary maildirs under each user directory.
This will invoke perfect_maildir.pl as required for each mbox file.
If the mail folders are large the this step could take some time.
10. Test that the files created under /data/mail2/ are visible as
folders via Dovecot by configuring an imap mail client.to point
to port 1043 on the mail server using on of the test migrated accounts.
The imap mail client program should correctly sign on to the
new imap server and the migrated folders should be visible to
the user. The mail client should test that:
a. new folders can be created and deleted.
b. that existing mail from migrated folders is visible and that
it sorts correctly by date
c. test that existing mail can be moved between folders.
d. the mail client should see both an inbox and all other folders
which were in the folderlist.
If step 10 passes (ie folders are visible as expected) then proceed with
full migration per the following steps. Do not proceed further unless
proper and expected mail folder operation is seen in the imap test of
step 10.
11. Prepare new folderlist and userlist files from the respective
master files in the mitrate directory.
12. Remove the test mail folders prepared steps 7 and 9 from the
new base directory (/data/mail2/* in this example).
13. Declare mail as unavailable.
14. Stop incoming mail (service postfix stop) and prevent further
use of imap (chkconfig imap off).
15. Run migrate-users and migrate-folders again.
16. Check a test user on the alternate port like step 10.
If all is OK, then
17. Re-configure dovecot to operate on the normal imap port
by commenting out the imap_listen directive in dovecot.conf.
Re-start dovecot.
18. Check that mail can be read on the normal imap port.
19. Change email delivery into the new folders:
postconf -e "mail_spool_directory = /data/mail2/"
20 Re-start mail
service postfix start
21. Check and double check.
22. Go home.

195
migrate-folders Executable file
View File

@ -0,0 +1,195 @@
#!/bin/bash
# author: G.R.Keech <rkeech@redhat.com>
# name: migrate-folders
# date: 2004-10-20
# This script assists in the conversion of mail boxes
# in mbox format to maildir format.
# See also migrate-users.
# Applicability.
#
# This script is intended for the common case on Red Hat systems
# where mail users have mail folders in their home directories
# under /home, and have inboxes in /var/spool/mail/
#==================================================================
# Change the value of the elements in this section as required.
#This is a list of folders, one per line. This does not
#include the inboxes. This might be prepared starting with
#the output of "find /home -type d".
FOLDERLIST=/root/migrate/folderlist
# folder is the existing mbox folder being migrated.
# It is a path under /home.
# eg if oldfolder is fred/personal, then folder is personal,
# user is fred.
#Specify the location of the new location for mail folders.
#This cannot be the same as the old location because it will
#create directory names that contend with existing file names.
NEWBASE=/var/spool/mail2
#The script to convert invidual mail folders to maildir format.
#http://perfectmaildir.home-dn.net/
FOLDERCONVERT=/usr/local/bin/perfect_maildir.pl
#This is a list of users to have their mail folders created.
#One user per line.
#Suggest create with cut -d: -f1 /etc/passwd > ~/migrate/u1
#then remove inappropriate entries by hand.
USERLIST=/root/migrate/userlist
# Detailed migration information is sent to this file
MIGRATELOG=/tmp/foldermigrationlog-$(date -I)
#=================================================================
echo
echo "Have you created the users' mail directories yet? (y/n)"
echo
read ans
if [ "$ans" != "y" ]
then
echo Good Bye.
echo use the migrate-users script first.
exit 0
fi
echo
echo This will copy existing mbox-style mail folders listed
echo in the file $FOLDERLIST. Maildir-style folders will
echo be created under $NEWBASE
echo
echo "Do you want to continue? (y/n)"
read ans
if [ "$ans" != "y" ]
then
echo Good Bye.
exit 0
fi
echo
echo Note: Detailed folder migration information will be sent to $MIGRATELOG
echo
echo Press enter to start
read ans
if [ ! -x ${FOLDERCONVERT} ]
then
echo Error: file ${FOLDERCONVERT} is not available to execute.
exit 1
fi
if [ ! -d ${NEWBASE} ]
then
echo Error: directory $NEWBASE does not exist
exit 1
fi
if [ ! -f "${USERLIST}" ]
then
echo Error: user list file \"$USERLIST\" does not exist.
exit 1
fi
#-----------------------------------------------------------------
echo
echo Testing that the base of the folderlist entries corresponds to usernames
while read oldfolder
do
user="$(dirname "$oldfolder")"
if grep ^${user}: /etc/passwd &> /dev/null
then
echo -n .
else
echo User \"$user\": is bogus.
echo The string \"$user\" from the file \"$FOLDERLIST\" needs to
echo correspond exactly to a username. Edit the file accordingly.
exit 1
fi
done < $FOLDERLIST
echo
echo PASS
echo
nusers=$(wc -l $USERLIST | awk '{ print $1 }' )
n=1
#-----------------------------------------------------------------
# Iterate through user list and migrate folders.
while read user
do
#-----------------------------------------------------------------
# Step 1: Check stuff
if grep ^${user}: /etc/passwd &> /dev/null
then
echo -n "$n / $nusers : User \"$user\" is OK: "
n=$(( $n + 1 ))
echo "User \"$user\"" >> $MIGRATELOG
inbox=/var/spool/mail/${user}
if [ \( ! -f "${inbox}" \) -o \( ! -s "${inbox}" \) ]
then
echo User \"${user}\" has no inbox to convert.
else
#-----------------------------------------------------------------
# Step 2: Migrate user inboxes from /var/spool/mail/.
newdir="${NEWBASE}/${user}/"
$FOLDERCONVERT "$newdir" < "${inbox}" >> $MIGRATELOG 2>&1
chown -R ${user}:mail "${newdir}"
find "$newdir" -type f -exec chmod 600 {} \;
echo -n " inbox "
fi
#-----------------------------------------------------------------
# Step 3: Migrate other mail folders from user home directories.
while read oldfolder
do
folder=$(basename "${oldfolder}")
fuser="$(dirname "$oldfolder")"
if [ "$user" = "$fuser" ]
then
if [ ! -f "/home/${oldfolder}" ]
then
echo Error folder \"${folder}\" does not exist.
break
fi
if [ ! -d ${NEWBASE}/${fuser} ]
then
echo Error ${NEWBASE}/${fuser} does not exist.
break
fi
newdir="${NEWBASE}/${fuser}/.$folder"
mkdir -p "$newdir"/cur
mkdir -p "$newdir"/new
mkdir -p "$newdir"/tmp
chmod -R 770 "${newdir}"
$FOLDERCONVERT "$newdir" < "/home/$oldfolder" >> $MIGRATELOG 2>&1
chown -R ${user}:mail "${newdir}"
#chmod 600 "$newdir/cur/*"
find "$newdir" -type f -exec chmod 600 {} \;
echo "$folder" >> ${NEWBASE}/${fuser}/.subscriptions
chmod 600 ${NEWBASE}/${fuser}/.subscriptions
chown ${fuser}:mail ${NEWBASE}/${fuser}/.subscriptions
echo -n .
fi
done < $FOLDERLIST
echo
else
echo User "$user: is bogus."
fi
done < $USERLIST
echo
echo
echo To make the new base mail directory active, change the
echo mail_spool_directory setting for postfix using
echo postconf -e \"mail_spool_directory = ${NEWBASE}/\"
echo and change Dovecots default_mail_env setting in
echo /etc/dovecot.conf to
echo default_mail_env = maildir:${NEWBASE}/%u
echo

77
migrate-users Executable file
View File

@ -0,0 +1,77 @@
#!/bin/bash
# file: migrate-users
# author: Richard Keech <rkeech@redhat.com>
# This script assists in the conversion of mail boxes
# in mbox format to maildir format.
# See also migrage-folders.
#This is a list of users to have their mail folders created.
#One user per line.
#Suggest create with cut -d: -f1 /etc/passwd > ~/migrate/u1
#then remove inappropriate entries by hand.
USERLIST=/root/migrate/userlist
#Specify the location of the new location for mail folders.
#This cannot be the same as the old location because it will
#create directory names that contend with existing file names.
NEWBASE=/var/spool/mail2/
echo this will create user mail folders in $NEWBASE from
echo the list of users in $USERLIST.
echo
echo "Do you want to continue? (y/n)"
read ans
if [ "$ans" != "y" ]
then
echo Good Bye.
exit 0
fi
if [ ! -f "$USERLIST" ]
then
echo Error: user list file \"$USERLIST\" does not exist.
exit 1
fi
if [ ! -d "$NEWBASE" ]
then
echo Error: new base directory \"$NEWBASE\" does not exist.
exit 1
fi
while read user
do
if grep ^${user}: /etc/passwd &> /dev/null
then
echo User \"$user\" is OK.
else
echo User \"$user\": is bogus.
exit 1
fi
mkdir ${NEWBASE}/$user
newdir="${NEWBASE}/${user}/"
mkdir -p "$newdir"/cur
mkdir -p "$newdir"/new
mkdir -p "$newdir"/tmp
chmod -R 770 "${newdir}"
chown -R ${user}:mail "$newdir"
done < $USERLIST
echo
echo New mail directories have been created under $NEWBASE
echo
echo If required, prepare a list of existing mbox folders
echo as /root/migrate/folderlist and run migrate-folders.
echo
echo To make the new base mail directory active, change the
echo mail_spool_directory setting for postfix using
echo postconf -e \"mail_spool_directory = ${NEWBASE}/\"
echo and change Dovecots default_mail_env setting in
echo /etc/dovecot.conf to
echo default_mail_env = maildir:${NEWBASE}/%u
echo
echo If you want to migrate existing mail folders then defer
echo the dovecot and postfix changes until the folder migration
echo is complete.

147
perfect_maildir.pl Executable file
View File

@ -0,0 +1,147 @@
#!/usr/bin/perl -w
# "Simple but Perfect" mbox to Maildir converter v0.3
# Copyright (C) 2001-2003 Philip Mak <pmak@aaanime.net>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
use strict;
use Date::Parse qw( str2time );
#### Settings
# This will be used to set the file time (needed for courier-imap and some others)
# $datestyle = "date": extract date from the "Date: " header
# $datestyle = "from": extract date from the "From " mbox header
my $datestyle = "from";
# Use maildir++ format (append the message size to the filename)
my $maildirplus = 0;
####
# Get the hostname
my $hostname = `hostname`;
chomp ($hostname);
# check for valid arguments
my ($maildir) = @ARGV;
if (!$maildir) {
print STDERR "Usage: perfect_maildir ~/Maildir < mbox\n";
exit 1;
} elsif (! -d $maildir) {
print STDERR "Cannot open $maildir\n";
exit 1;
}
# check for writable maildir
unless (-w "$maildir/cur") {
print STDERR "Cannot write to $maildir/cur\n";
exit 1;
}
unless (-w "$maildir/new") {
print STDERR "Cannot write to $maildir/new\n";
exit 1;
}
my $num = 0;
my $time = time;
my $date;
my $delivered_time;
repeat:
# read header
my $headers = '';
my $flags = '';
my $subject = '';
while (my $line = <STDIN>) {
# detect end of headers
last if $line eq "\n";
if ($datestyle eq "from") {
# Get date from the "From " line (this should appears here for the first message only)
$date = $1 if $line =~ /^From [^ ^\t]+[ \t]+(.{24})/;
} elsif ($datestyle eq "date") {
# Get date from the "Date: " header
$date = $1 if $line =~ /^Date: (.*)$/;
}
# strip "From" line from header
$headers .= $line unless $line =~ /^From ./;
# detect flags
$flags .= $1 if $line =~ /^Status: ([A-Z]+)/;
$flags .= $1 if $line =~ /^X-Status: ([A-Z]+)/;
$subject = $1 if $line =~ /^Subject: (.*)$/;
}
$num++;
if ($datestyle =~ /(from|date)/) {
$delivered_time = str2time("$date");
} else {
$delivered_time = $time;
}
# open output file
my $file;
if ($flags =~ /O/) {
$file = sprintf( "%s%05d%s", "$maildir/cur/$delivered_time.", $num, ".$hostname" );
my $extra = '';
$extra .= 'F' if $flags =~ /F/; # flagged
$extra .= 'R' if $flags =~ /A/; # replied
$extra .= 'S' if (($flags =~ /R/) || ($flags =~ /O/)); # seen
$extra .= 'T' if $flags =~ /D/; # trashed
$file .= ":2,$extra" if $extra;
} else {
$file = sprintf( "%s%05d%s", "$maildir/new/$delivered_time.", $num, ".$hostname" );
}
# filter out the "DON'T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA" message or the message doesn't exists
if (($num == 1 and $subject eq "DON'T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA") || (!$headers)) {
$file = '/dev/null';
$num--;
}
open(FILE, ">$file");
print FILE "$headers\n";
while (my $line = <STDIN>) {
if ($datestyle eq "from") {
# Get date from the "From " line (this should appears here for the first message only)
$date = $1 if $line =~ /^From [^ ^\t]+[ \t]+(.{24})/;
}
# End of current message
last if ($line =~ /^From ./);
# unescape "From"
$line =~ s/^>From (.)/From $1/;
print FILE $line;
}
close(FILE);
utime( $time, $delivered_time, $file ) if ($datestyle =~ /(from|date)/);
if ($maildirplus) {
my $size = -s $file;
my $mdplusfile = $file;
$mdplusfile =~ s/\.$hostname/.$hostname,S=$size/;
rename $file,$mdplusfile;
}
goto repeat unless eof(STDIN);
my $elapsed = time - $time;
print "Inserted $num messages into maildir $maildir in $elapsed seconds\n";