#!/bin/sh # # Export a Kmail message store using IMAP # # Version 1.0 # Copyright (C) 2006 Graham R. Cobb # This script is released under the GPL. # # This creates a directory tree for use with the dovecot IMAP server # containing softlinks to appropriate folders in the Kmail directory # # Note: maildir folders are exported to the target directory but mbox # folders are exported to a separate .../mbox directory. This is because # dovecot cannot handle maildir and mbox in the same directory. # # Usage: imap-export # # Note: if rebuilding the directory tree it may be easiest just to # completely remove the dovecot tree (e.g. with rm -rf ~/dovecot) # before running this. If not, you may want to set the "force" # flag to "-f". # # Do we want to overwrite existing links? #force="-f" force="" # This function calculates the mail folder containment # hierarchy corresponding to a Kmail on-disk directory # # $1 - directory filespec # $2 - base directory # # The function outputs the hierarchy in the form # //subfolder/... # function get_hierarchy () { h=$1 # Remove the base directory prefix if [[ $h == $2* ]] then l=${#2} h=${h:$l} fi # echo $h # Replace each occurence of /..directory # with / re='(.*)/\.([^/]*)\.directory(.*)' while [[ $h =~ $re ]] do # echo $h analyses as ${BASH_REMATCH[1]} ${BASH_REMATCH[2]} ${BASH_REMATCH[3]} h=${BASH_REMATCH[1]}/${BASH_REMATCH[2]}${BASH_REMATCH[3]} done echo $h } # # Argument handling # if [[ $# == 4 && "$1" == --recurse ]] then # Recursive invocation: record subdir and calculate hierarchy subdir=$2 kmailroot=$3 imaproot=$4 hierarchy=`get_hierarchy "$subdir" "$kmailroot"` # echo Subdir: $subdir Kmailroot: $kmailroot Imaproot: $imaproot Hierarchy: $hierarchy elif [[ $# != 2 || -z "$1" || -z "$2" ]] then echo "Wrong arguments($#):" $0 $* echo Usage: $0 "" "" # Note the --recurse flag is for internal use only exit 2 else # User invocation kmailroot=$1 subdir=$1 imaproot=$2 hierarchy="" fi mboxroot=$imaproot/mbox # # There are four types of files to worry about: # # 1) Maildir folders. These are directories, which contain a cur/ directory, # and are not of the form "..directory". # They are linked into the appropriate place in the dovecot directory. # Note that any dots are removed from these folder names (and any parent folders) # # 2) Mbox folders. These are ordinary files, the name does not start with a dot, # the contents start with "From". They are linked into the dovecot mbox hierarchy. # # 3) Subfolders. These are directories with names of the form "..directory". # They are recursed into. # # 4) Everything else is ignored. This includes ordinary directories. # # There are some special cases: # # Any maildir called "inbox" will be renamed "real-inbox" # for f in "$subdir"/* "$subdir"/.* do # echo $f fname=`basename "$f"` if [[ $fname == . || $fname == .. ]] ; then continue; fi # echo $fname # Is it a maildir directory? if [[ -d "$f" && -d "$f/cur" && $fname != .*.directory ]] then echo Maildir folder $fname # Special case "inbox" if [[ $fname == inbox ]] ; then fname=real-inbox ; fi # The directory hierarchy must be turned into a filename # hierarchy... # Remove any . from name newname=${fname//./} # Remove any . from hierarchy h=${hierarchy//./} # Replace / in hierarchy with . h=${h//\//.} ln -s $force "$f" "$imaproot/$h.$newname" # Maildir done # Is it mbox? elif [[ -f "$f" && -s "$f" && $fname != .* && `head --bytes=4 "$f"` == From ]] then echo Mbox folder $fname # As mbox doesn't allow a folder to contain both messages # and other folders at the same time, we modify the # parent directory hierarchy so each containing folder name # ends with a dot. # To do this we replace each / with ./ add an extra dot # at the end and remove the unwanted dot at the start h=${hierarchy//\//.\/}. h=${h:1} mkdir -p "$mboxroot$h" ln -s $force "$f" "$mboxroot$h/$fname" # Mbox done # Subfolder ? elif [[ -d "$f" && $fname == .*.directory ]] then echo Subfolder $fname # Remove leading dot sub=${fname:1} # Remove trailing .directory sub=${sub%.directory} # Recursively call script to handle the subdirectory $0 --recurse "$f" "$kmailroot" "$imaproot" else : echo Ignored $fname fi done