diff --git a/dovecot.init b/dovecot.init new file mode 100755 index 0000000..b8259e5 --- /dev/null +++ b/dovecot.init @@ -0,0 +1,108 @@ +#!/bin/bash +# +# /etc/rc.d/init.d/dovecot +# +# Starts the dovecot daemon +# +# chkconfig: - 65 35 +# description: Dovecot Imap Server +# processname: dovecot +# config: /etc/dovecot.conf +# config: /etc/sysconfig/dovecot +# pidfile: /var/run/dovecot/master.pid + +### BEGIN INIT INFO +# Provides: dovecot +# Required-Start: $local_fs $network +# Required-Stop: $local_fs $network +# Should-Start: $remote_fs +# Should-Stop: $remote_fs +# Default-Start: +# Default-Stop: 0 1 2 3 4 5 6 +# Short-Description: start and stop Dovecot Imap server +# Description: Dovecot is an IMAP server for Linux/UNIX-like systems, +# written with security primarily in mind. It also contains +# a small POP3 server. +### END INIT INFO + +# Source function library. +. /etc/init.d/functions + +if [ -f /etc/sysconfig/dovecot -a $UID -eq 0 ]; then + . /etc/sysconfig/dovecot +fi + +RETVAL=0 +prog="Dovecot Imap" +exec="/usr/sbin/dovecot" +config="/etc/dovecot.conf" +pidfile="/var/run/dovecot/master.pid" +lockfile="/var/lock/subsys/dovecot" + +start() { + [ $UID -eq 0 ] || exit 4 + [ -x $exec ] || exit 5 + [ -f $config ] || exit 6 + + echo -n $"Starting $prog: " + daemon --pidfile $pidfile $exec $OPTIONS + RETVAL=$? + [ $RETVAL -eq 0 ] && touch $lockfile + echo +} + +stop() { + [ $UID -eq 0 ] || exit 4 + echo -n $"Stopping $prog: " + killproc -p $pidfile $exec + RETVAL=$? + [ $RETVAL -eq 0 ] && rm -f $lockfile + echo +} + +reload() { + [ $UID -eq 0 ] || exit 4 + echo -n $"Reloading $prog: " + killproc -p $pidfile $exec -HUP + RETVAL=$? + echo +} + +# +# See how we were called. +# +case "$1" in + start) + start + ;; + stop) + stop + ;; + reload) + reload + ;; + force-reload|restart) + stop + sleep 1 + start + RETVAL=$? + ;; + condrestart|try-restart) + if [ -f $lockfile ]; then + stop + sleep 3 + start + fi + ;; + status) + status -p $pidfile $exec + RETVAL=$? + ;; + *) + echo $"Usage: $0 {condrestart|try-restart|start|stop|restart|reload|force-reload|status}" + RETVAL=2 + [ "$1" = 'usage' ] && RETVAL=0 +esac + +exit $RETVAL + diff --git a/migrate-folders b/migrate-folders new file mode 100755 index 0000000..ede6213 --- /dev/null +++ b/migrate-folders @@ -0,0 +1,195 @@ +#!/bin/bash + +# author: G.R.Keech +# 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 + diff --git a/migrate-users b/migrate-users new file mode 100755 index 0000000..d5d48d4 --- /dev/null +++ b/migrate-users @@ -0,0 +1,77 @@ +#!/bin/bash +# file: migrate-users +# author: Richard Keech + +# 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. diff --git a/perfect_maildir.pl b/perfect_maildir.pl new file mode 100755 index 0000000..4667d65 --- /dev/null +++ b/perfect_maildir.pl @@ -0,0 +1,147 @@ +#!/usr/bin/perl -w + +# "Simple but Perfect" mbox to Maildir converter v0.3 +# Copyright (C) 2001-2003 Philip Mak +# +# 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 = ) { + # 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 = ) { + 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";