#!/usr/bin/perl -w ###################################################################### # # cyrus2dovecot # # V E R S I O N : # 0.1 # # A U T H O R : # Jan Trukenmüller # http://trukenmueller.de # # L O C A T I O N : # http://trukenmueller.de/cyrus2dovecot # # W H A T : # This script converts a CYRUS mail directory into a DOVECOT mail # directory. # Perhaps the resulting mail directory can also be used with other # allpications using the 'Maildir' format, but I only tested it with # Dovecot. # # F E A T U R E S : # - The conversion works even if the cyrus server is offline - e.g. # because it is broken and cannot be started any more. The cyrus # databases may also be broken, because they are not needed. Only # the mail directory and it's plaintext mail files are used for # the conversion. # - The complete mail directory and all subdirectories are converted # in a single run. # # B U G S : # - All the converted Mails are marked as unread. # - Only one Mail account can be converted at a time # - probably a lot more... # # R E Q U R E M E N T S : # This script runs on a Gentoo Linux system with Cyrus 2.2.12 and # Dovecot 1.0_rc29. It should also run on other UNIX-like systems. # A Perl interpreter is also required. # # I N S T A L L A T I O N : # Copy the script to a good looking place inside your file system, # e.g. /usr/local/bin. Than make it executable. # # U S A G E : # cyrus2dovecot # is the directory of your cyrus mailbox, # is the directory of dovecot # E X A M P L E : # cyrus2dovecot /var/spool/imap/j/user/joe /home/joe/Maildir # # O W N R I S K : # You can use this script at your own risk. The author does not take # the responsibility for any damage the script may cause directly or # indirectly. # # L I C E N C E : # Well, there is no licence. # Anyone may freely use, modify and redistribute this script. # However, if you make any changes I would appreciate if you inform # me about what you changed and why you did it. # # W H Y : # The Cyrus server I used is broken and does not start any more. This # was the right time for me to switch to another IMAP server. I # decided to use Dovecot. # In order to convert my mails I tried out two programs: # cyrus2courier (http://www.madness.at/projects/#c2c) and # cyrus2maildir.py (http://www.majid.info/mylos/weblog/2006/03/08-1.html) # Both did not work for me. Perhaps they need the Cyrus IMAP server # working, or at least a consistend Cyrus database - I don't know, # because I didn't look so deep into the code. # So I wrote this conversion script to be independent from a working # Cyrus server. # # This script was the work of one evening. Time to go to bed now. # ###################################################################### use strict; my $src = shift || ""; my $target = shift || ""; usage('') unless( $src && $target ); usage("Source directory does not exist: $src") unless( -e $src ); system "mkdir '" . $target . "'" unless -e $target; usage("Cannot create target directory: $target") unless( -e $target ); system "mkdir '" . "$target/cur" . "'" unless -e "$target/cur"; system "mkdir '" . "$target/new" . "'" unless -e "$target/new"; system "mkdir '" . "$target/tmp" . "'" unless -e "$target/tmp"; convert_dir( $src, $target, '.INBOX', '' ); sub usage{ my $msg = shift; if($msg){ print "\nERROR: $msg\n\n"; } print "\tusage: \t$0 example: \t$0 /var/spool/imap/j/user/joe /home/joe/Maildir\n\n"; exit 1; } sub convert_dir{ my $s = shift; # source directory my $t = shift; # root of the target directory my $sub = shift; # subdirectory under $t my $dh = shift; # directory handle $dh .= 'x'; no strict 'refs'; opendir $dh, $s or die "Can't open $s for reading: $!\n"; while (my $file = readdir $dh){ next if $file =~ /^\.{1,2}$/; # ignore '.' and '..' if( -d "$s/$file" ){ # It's a directory. system "mkdir '" . "$t/$sub.$file" . "'" unless -e "$t/$sub.$file"; usage("Cannot create target directory: $t/$sub.$file") unless( -e "$t/$sub.$file" ); system "mkdir '" . "$t/$sub.$file/cur" . "'" unless -e "$t/$sub.$file/cur"; system "mkdir '" . "$t/$sub.$file/new" . "'" unless -e "$t/$sub.$file/new"; system "mkdir '" . "$t/$sub.$file/tmp" . "'" unless -e "$t/$sub.$file/tmp"; system "echo '" . substr( $sub, 1 ) . ".$file' >> $t/subscriptions"; # recursion convert_dir("$s/$file", $t, "$sub.$file", $dh); }else{ # It's a normal file. next if $file =~ /^cyrus\.(cache|header|index)$/; # ignore cyrus' binary files if( $sub eq '.INBOX' ){ system "cp '$s/$file' '$t/cur'"; }else{ system "cp '$s/$file' '$t/$sub/cur'"; } } } closedir $dh; }