#!/bin/sh #---------------------------------------------------------------------------------- # /var/install/bin/mail-dovecot-convert-to-maildir - convert mbox/mbx mailboxes to # maildir format # # Copyright (c) 2020-2025 The Eisfair Team, team(at)eisfair(dot)org # # Creation: 2020-06-01 jed # Last Update: $Id$ # # Usage: ./mail-dovecot-convert-to-maildir [--quiet] [command] # # --convert-public-mailbox - convert imappublic mailbox # --convert-shared-mailbox - convert imapshared mailbox # # --convert-user-mailbox user [maildir] # - covert mailbox of a user # --check-user-maildir-tree user [maildir] # - check maildir tree of a user # --check-user-subscriptions user # - check mailbox subscriptions of a user # --check-filter-files - check user specific (.forward) and # system filter files # # Information: It has been decided to not convert any email archive folders # outside of the default home directory of a user yet. These # folders need to be converted manually, if desired. # # 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. #---------------------------------------------------------------------------------- # read eislib . /var/install/include/eislib . /var/install/include/jedlib # activate debug output #debug=true if ${debug:-false} then exec 2> /tmp/$(basename ${0})-trace$$.log set -x ask_debug=true export ask_debug fi #---------------------------------------------------------------------------------------- # show wait #---------------------------------------------------------------------------------------- show_wait () { local _sw_colpos myecho --pack ${module_name} --force-output -n " wait [ " _sw_colpos=1 while [ -n "`ps --no-headers $!`" ] do myecho --pack ${module_name} --force-output --info -n "." sleep 1 _sw_colpos=`expr ${_sw_colpos} + 1` if [ "${_sw_colpos}" -ge 52 ] then myecho --pack ${module_name} --force-output " ]" myecho --pack ${module_name} --force-output -n " wait [ " _sw_colpos=1 fi done if [ ${_sw_colpos} -eq 1 ] then myecho --pack ${module_name} --force-output --info -n "." fi myecho --pack ${module_name} --force-output " ] " } #---------------------------------------------------------------------------------------- # print main menu # # $sel_values contains space separated list of menu options #---------------------------------------------------------------------------------------- print_main_menu () { local _pmm_output clrhome mecho --info "Convert mailboxes from MBOX/MBX to MAILDIR format" echo _pmm_output=`${varlib_path}/mail status | grep -v '^Fetchmail' | sed '2,4s/^.*$/ &/g'` mecho -n --info "Status: " echo "${_pmm_output}" echo "${_pmm_output}" | grep -q -E ": running|: enabled" if [ $? -eq 0 ] then echo mecho --warn "Attention: It is urgently recommended to stop the imap/smtp servers" if [ "${START_ARCHIMAP}" = 'yes' ] then mecho --warn " and the archimap service BEFORE you start any conversion" mecho --warn " to prevent unexpected results and loss of email!" else mecho --warn " BEFORE you start any conversion process to prevent unexpected" mecho --warn " results and loss of email!" fi fi echo echo -n "1 - convert public mailboxes" if `active_public_shared_folders_exist 'public'` then sel_values="1" echo else sel_values="" mecho --warn " - none configured!" fi echo -n "2 - convert shared mailboxes" if `active_public_shared_folders_exist 'shared'` then if [ -z "${sel_values}" ] then sel_values="2" else sel_values="${sel_values} 2" fi echo else mecho --warn " - none configured!" fi echo echo "3 - convert mailboxes of a single user" echo "4 - convert mailboxes of all users" echo echo "5 - check subscriptions of a single user" echo "6 - check subscriptions of all users" echo echo "7 - check filter files for save commands" if [ -z "${sel_values}" ] then sel_values="3 4 5 6 7" else sel_values="${sel_values} 3 4 5 6 7" fi echo } #---------------------------------------------------------------------------------------- # check if valid menu selection # # input: $1 - value to check # $2 - string of available menu values # # return: 0 - valid value, entry found # 1 - invalid value, entry not found #---------------------------------------------------------------------------------------- is_valid_menu_selection () { local _ivms_sval=$1 # value to check local _ivms_ret if [ -z "${_ivms_sval}" ] then # empty string - invalid value _ivms_ret=1 else shift _ivms_sel_values=" $* " # string of available menu values echo "${_ivms_sel_values}" | grep -q " ${_ivms_sval} " _ivms_ret=$? fi return ${_ivms_ret} } #---------------------------------------------------------------------------------------- # check if active imappublic/imapshared folders have been configured # # input : $1 - public/shared # # return: 0 - active folders found # 1 - no active folders found #---------------------------------------------------------------------------------------- active_public_shared_folders_exist () { local _apsfe_switch=$1 local _apsfe_type=`echo "${_apsfe_switch}" | tr '[:lower:]' '[:upper:]'` local _apsfe_ret=1 local _apsfe_num local _apsfe_idx local _apsfe_active eval _apsfe_num="\$IMAP_${_apsfe_type}_FOLDER_N" _apsfe_idx=1 while [ ${_apsfe_idx} -le ${_apsfe_num} ] do eval _apsfe_active="\$IMAP_${_apsfe_type}_FOLDER_${_apsfe_idx}_ACTIVE" if [ "${_apsfe_active}" = 'yes' ] then _apsfe_ret=0 break fi _apsfe_idx=`expr ${_apsfe_idx} + 1` done return ${_apsfe_ret} } #---------------------------------------------------------------------------------------- # active mail user exists # # input: $1 - user name or '*all*' # # return: 0 - mail user exists # 1 - mail user doesn't exist #---------------------------------------------------------------------------------------- active_mail_user_exists () { local _amue_check_user=$1 local _amue_ret=1 local _amue_idx local _amue_active local _amue_user local _amue_homedir local _amue_maildir if [ -n "${_amue_check_user}" ] then if [ "${_amue_check_user}" = '*all*' ] then _amue_ret=0 else if [ "${MAIL_USER_USE_MAILONLY_PASSWORDS}" = 'yes' -a "${_amue_check_user}" != 'imappublic' -a "${_amue_check_user}" != 'imapshared' ] then # different passwords are enabled if [ ${MAIL_USER_N} -gt 0 ] then _amue_idx=`set | grep "^MAIL_USER_[0-9]*_USER=${_amue_check_user}$" | sed 's/MAIL_USER_\([0-9]*\)_.*$/\1/'` if [ -n "${_amue_idx}" ] then eval _amue_active='$MAIL_USER_'${_amue_idx}'_ACTIVE' # if [ \( "${_amue_active}" = 'yes' -a ${_amue_idx} -le ${MAIL_USER_N} \) ] if [ ${_amue_idx} -le ${MAIL_USER_N} ] then _amue_ret=0 fi fi fi else if getent passwd ${_amue_check_user} >/dev/null 2>&1 then # user exists, get home directory _amue_homedir=`getent passwd ${_amue_check_user} | cut -d: -f6` if [ -n "${_amue_homedir}" ] then # user exists ... _amue_maildir="${_amue_homedir}/${mail_subdir}" if [ -d "${_amue_maildir}" ] then _amue_ret=0 fi fi fi fi fi fi return ${_amue_ret} } #---------------------------------------------------------------------------------------- # create maildir sub directories (/cur, /new, /tmp) if they don't exist # # input : $1 - user name # $2 - full directory path #---------------------------------------------------------------------------------------- create_maildir_subdirs () { local _cms_user="$1" local _cms_gid='' local _cms_group='' local _cms_dir="$2" local _cms_header=0 local _cms_output='' local _cms_homedir='' local _cms_rights='' if [ -n "${_cms_user}" ] then if getent passwd ${_cms_user} >/dev/null 2>&1 then # user exists, get home directory _cms_homedir=`getent passwd ${_cms_user} | cut -d: -f6` if [ -n "${_cms_homedir}" ] then # user exists ... # get directory ownership and access rights for DNAME in "${_cms_homedir}/${mail_subdir}/cur" "${_cms_homedir}/${mail_subdir}" "${_cms_homedir}" do if [ -L "${DNAME}" ] then # symbolic link found, get absolute path DNAME="`readlink -f "${DNAME}"`" fi if [ -d "${DNAME}" ] then _cms_rights=`get_accessrights "${DNAME}"` break fi done if [ -z "${_cms_rights}" ] then # build default ownership and access rights string _cms_gid=`getent passwd ${_cms_user} | cut -d: -f4` _cms_group=`getent group ${_cms_gid} | cut -d: -f1` _cms_rights="0700:${_cms_user}:${_cms_group}" fi if [ -n "${_cms_dir}" ] then for SUB in cur new tmp do if [ ! -d "${_cms_dir}/${SUB}" ] then # create directories if [ ${_cms_header} -eq 0 ] then _cms_header=1 _cms_output="directory '${_cms_dir}/${SUB}" else _cms_output="${_cms_output}, ../${SUB}" fi if [ ! -d "${_cms_dir}/${SUB}" ] then mkdir -p "${_cms_dir}/${SUB}" fi # setting ownership and access rights set_accessrights -R "${_cms_dir}" "${_cms_rights}" fi done # output confirmation message if [ ${_cms_header} -eq 1 ] then echo "${_cms_output}' created." fi else echo "ERROR: create_maildir_subdirs - no directory given." fi fi else echo "ERROR: user '${_cms_user}' not found!" fi else echo "ERROR: no user name given!" fi } #---------------------------------------------------------------------------------------- # convert imappublic/imapshared folders # # input: $1 - switch 'public' or 'shared' #---------------------------------------------------------------------------------------- convert_public_shared_folders () { local _cpsf_switch=$1 local _cpsf_dir_mask local _cpsf_file_mask local _cpsf_type=`echo "${_cpsf_switch}" | tr '[:lower:]' '[:upper:]'` local _cpsf_datestamp=`date +"%Y-%d-%m %H:%M:%S"` local _cpsf_homedir='' local _cpsf_num local _cpsf_def_group local _cpsf_idx local _cpsf_active local _cpsf_name local _cpsf_group local _cpsf_mailbox_with_path local _cpsf_dest_file local _cpsf_outout local _cpsf_mailbox_num local _cpsf_mailbox_total if [ -n "${_cpsf_switch}" ] then case ${_cpsf_switch} in public ) _cpsf_dir_mask='0777' _cpsf_file_mask='0666' ;; shared ) _cpsf_dir_mask='0770' _cpsf_file_mask='0660' ;; esac if getent passwd imap${_cpsf_switch} >/dev/null 2>&1 then # user exists, get home directory _cpsf_homedir=`getent passwd imap${_cpsf_switch} | cut -d: -f6` echo -n "User name : "; mecho --warn "imap${_cpsf_switch}" echo -n "Directory : "; mecho --warn "${_cpsf_homedir}" echo eval _cpsf_num="\$IMAP_${_cpsf_type}_FOLDER_N" eval _cpsf_def_group='$IMAP_SHARED_PUBLIC_USERGROUP' _cpsf_idx=1 while [ ${_cpsf_idx} -le ${_cpsf_num} ] do eval _cpsf_active="\$IMAP_${_cpsf_type}_FOLDER_${_cpsf_idx}_ACTIVE" if [ "${_cpsf_active}" = 'yes' ] then eval _cpsf_name="\$IMAP_${_cpsf_type}_FOLDER_${_cpsf_idx}_NAME" eval _cpsf_group="\$IMAP_${_cpsf_type}_FOLDER_${_cpsf_idx}_USERGROUP" if [ -z "${_cpsf_group}" ] then _cpsf_group=${_cpsf_def_group} fi # check if folder has been given echo "${_cpsf_name}" | grep -q '/' if [ $? -eq 0 ] then # 'Auto/Meine-Frau' -> 'Meine-Frau' _cpsf_name="`basename "${_cpsf_name}"`" fi if [ -d "${_cpsf_homedir}" -a ! -d "${_cpsf_homedir}.PANDA" ] then # start conversion process only once if [ ! -L "${_cpsf_homedir}/${mail_subdir}" ] then # symbolic link '.imapmail' doesn't exist cd ${_cpsf_homedir} 2>/dev/null if [ $? -eq 0 ] then # create symbolic link because it is # required by the conversion tool ln -s . ${mail_subdir} fi fi for NAME in `find ${_cpsf_homedir} -type f -name "${_cpsf_name}*" | sort` do _cpsf_mailbox_with_path=`echo "${NAME}" | sed "s|^${_cpsf_homedir}/\(.*\)$|\1|"` # replace '/' by '.' (dots) _cpsf_dest_file="${_cpsf_homedir}.MAILDIR/`echo "/${_cpsf_mailbox_with_path}" | sed 's|\/|\.|g'`" if [ ! -d "${_cpsf_dest_file}" ] then echo "Converting ${_cpsf_switch} folder '${_cpsf_mailbox_with_path}' ..." { echo echo "${_cpsf_datestamp} - Converting ${_cpsf_switch} folder '${_cpsf_mailbox_with_path}' ..." echo } >> ${dovecot_logfile} _cpsf_outout=`${uw2dovecot_prog} -u ${_cpsf_homedir}/${mail_subdir} -i ${_cpsf_homedir}/${_cpsf_mailbox_with_path} \ -s '' -m ${_cpsf_dest_file} -r "${dovecot_dot_replacement}" -v` _cpsf_mailbox_num=`echo "${_cpsf_outout}" | grep -v "^Total conversion:" | wc -l` _cpsf_mailbox_total=`echo "${_cpsf_outout}" | grep "^Total conversion:" | cut -d: -f2 | sed 's/^ *//'` echo "-> ${_cpsf_mailbox_num} mailbox(es) with ${_cpsf_mailbox_total} converted." echo echo "${_cpsf_outout}" >> ${dovecot_logfile} fi done if [ -d "${_cpsf_homedir}.MAILDIR" ] then # setting access rights and ownership find ${_cpsf_homedir}.MAILDIR -type d -exec chmod ${_cpsf_dir_mask} {} \; find ${_cpsf_homedir}.MAILDIR -type f -exec chmod ${_cpsf_file_mask} {} \; chown -R imap${_cpsf_switch}:${_cpsf_group} ${_cpsf_homedir}.MAILDIR fi fi fi _cpsf_idx=`expr ${_cpsf_idx} + 1` done else mecho --error "user 'imap${_cpsf_switch}' not found!" fi else mecho --error "switch (public/shared) not given!" fi } #---------------------------------------------------------------------------------------- # rename imappublic/imapshared folders to activate MAILDIR format # # 1. convert: /home/imap[public/shared] -> /home/imap[public/shared].MAILDIR # 2. rename : /home/imap[public/shared] -> /home/imap[public/shared].PANDA # 3. rename : /home/imap[public/shared].MAILDIR -> /home/imap[public/shared] # # input: $1 - switch 'public' or 'shared' #---------------------------------------------------------------------------------------- rename_public_shared_folder () { local _rpsf_switch=$1 local _rpsf_type=`echo "${_rpsf_switch}" | tr '[:lower:]' '[:upper:]'` local _rpsf_datestamp=`date +"%Y-%d-%m %H:%M:%S"` local _rpsf_homedir='' local _rpsf_found=0 if [ -n "${_rpsf_switch}" ] then if getent passwd imap${_rpsf_switch} >/dev/null 2>&1 then # user exists, get home directory _rpsf_homedir=`getent passwd imap${_rpsf_switch} | cut -d: -f6` if [ -d "${_rpsf_homedir}" -a -d "${_rpsf_homedir}.MAILDIR" -a ! -d "${_rpsf_homedir}/${mail_subdir}.PANDA" -a -L "${_rpsf_homedir}/${mail_subdir}" ] then echo "Renaming maildir-folder of 'imap${_rpsf_switch}' folder ..." { echo echo "-> Renaming maildir-folder of 'imap${_rpsf_switch}' folder ..." echo } >> ${dovecot_logfile} # rename original directory to .PANDA if [ ! -d "${_rpsf_homedir}.PANDA" ] then mv -n -v "${_rpsf_homedir}" "${_rpsf_homedir}.PANDA" | tee -a ${dovecot_logfile} if [ ! -d "${_rpsf_homedir}" ] then # rename .MAILDIR directory to original name mv -n -v "${_rpsf_homedir}.MAILDIR" "${_rpsf_homedir}" | tee -a ${dovecot_logfile} # restore .archimap* and .forward* files echo _rpsf_found=0 for FNAME in `find "${_rpsf_homedir}.PANDA" -type f -name ".archimap*" -or -name ".forward*" | sort` do if [ ${_rpsf_found} -eq 0 ] then _rpsf_found=1 echo "Restore .archimap* and .forward* files ..." { echo echo "-> Restore .archimap* and .forward* files ..." echo } >> ${dovecot_logfile} fi cp -n -p -v "${FNAME}" "${_rpsf_homedir}/" done else mecho --error "unable to rename directory '${_rpsf_homedir}.MAILDIR' because" mecho --error "the target directory '${_rpsf_homedir}' already exists!" { echo "ERROR: unable to rename directory '${_rpsf_homedir}.MAILDIR' because" echo " the target directory '${_rpsf_homedir}' already exists!" } >> ${dovecot_logfile} fi else mecho --error "unable to rename directory '${_rpsf_homedir}' because the" mecho --error "target directory '${_rpsf_homedir}.PANDA' already exists!" { echo "ERROR: unable to rename directory '${_rpsf_homedir}' because the" echo " target directory '${_rpsf_homedir}.PANDA' already exists!" } >> ${dovecot_logfile} fi fi else mecho --error "user 'imap${_rpsf_switch}' not found!" fi else mecho --error "switch (public/shared) not given!" fi } #---------------------------------------------------------------------------------------- # convert folders of single user # # input: $1 - user name #---------------------------------------------------------------------------------------- convert_single_user_folders () { local _csuf_user=$1 local _csuf_datestamp=`date +"%Y-%d-%m %H:%M:%S"` local _csuf_homedir='' local _csuf_output local _csuf_mailbox_num local _csuf_mailbox_total local _csuf_spool_num local _csuf_inbox_type if [ -n "${_csuf_user}" ] then if getent passwd ${_csuf_user} >/dev/null 2>&1 then # user exists, get home directory _csuf_homedir=`getent passwd ${_csuf_user} | cut -d: -f6` # different passwords are enabled echo echo "Converting folders of user '${_csuf_user}' ..." { echo echo "${_csuf_datestamp} - Converting folders of user '${_csuf_user}' ..." } >> ${dovecot_logfile} if [ -d "${_csuf_homedir}/${mail_subdir}" ] then # personal mail folder exists if [ "${_csuf_user}" != 'imappublic' -a "${_csuf_user}" != 'imapshared' ] then if [ ! -f "${_csuf_homedir}/${mail_subdir}/INBOX" ] then # create missing INBOX file ${mailutil_bin} create -verbose "#driver.unix:${_csuf_homedir}/${mail_subdir}/INBOX" >/dev/null 2>&1 if [ $? -eq 0 ] then echo "-> create new empty inbox folder ${_csuf_homedir}/${mail_subdir}/INBOX" fi fi fi if [ -f "${_csuf_homedir}/${mail_subdir}/INBOX" ] then # personal inbox exists if [ -f ${mail_spool_path}/${_csuf_user} ] then # mail spool file exists, check if it contains email # No new messages, 0 total in /var/spool/mail/frank # 2 new message(s) (2 unseen), 2 total in /var/spool/mail/frank _csuf_spool_num=`${mailutil_bin} check ${mail_spool_path}/${_csuf_user} | sed 's/^.*, \([0-9]*\) total.*/\1/'` if [ -z "${_csuf_spool_num}" ] then _csuf_spool_num=0 fi if [ "`/usr/bin/head -c 5 ${_csuf_homedir}/${mail_subdir}/INBOX`" = '*mbx*' ] then _csuf_inbox_type='mbx' else _csuf_inbox_type='unix' fi if [ ${_csuf_spool_num} -gt 0 ] then # move mail from spool file to personal inbox file # # [Assigning new unique identifiers to all messages] # /var/spool/mail/frank [2 message(s)] => #driver.mbx:/home/frank/.imapmail/INBOX # # [Ok 2 messages(s)] # [Expunged 2 messages] _csuf_output=`${mailutil_bin} appenddelete -verbose "${mail_spool_path}/${_csuf_user}" \ "#driver.${_csuf_inbox_type}:${_csuf_homedir}/${mail_subdir}/INBOX"` echo "${_csuf_output}" | grep -q '^\[Ok' if [ $? -eq 0 ] then echo "-> moved ${_csuf_spool_num} message(s) from ${mail_spool_path}/${_csuf_user} to ${_csuf_inbox_type}:${_csuf_homedir}/${mail_subdir}/INBOX" fi echo "${_csuf_output}" >> ${dovecot_logfile} fi fi # .imapmail/INBOX: Converting mbx file (3 messages) # .imapmail/Drafts: Converting mbx file (0 messages) # .imapmail/Sent: Converting mbx file (127 messages) # .imapmail/Ablage_PC/ownCloud-Projekt: Converting mbox file (76 messages) # ... # Total conversion: 2572 messages # make sure the file exists to prevent an error when executing uw2dovecot.pl if [ ! -f ${_csuf_homedir}/.mailboxlist ] then touch ${_csuf_homedir}/.mailboxlist chown ${_csuf_user}: ${_csuf_homedir}/.mailboxlist chmod 0600 ${_csuf_homedir}/.mailboxlist fi { echo "${uw2dovecot_prog} -u ${_csuf_homedir}/${mail_subdir} -i ${_csuf_homedir}/${mail_subdir}/INBOX -s ${_csuf_homedir}/.mailboxlist -m ${_csuf_homedir}/${mail_subdir}.MAILDIR -r "${dovecot_dot_replacement}" -v" echo } >> ${dovecot_logfile} ( ${uw2dovecot_prog} -u ${_csuf_homedir}/${mail_subdir} -i ${_csuf_homedir}/${mail_subdir}/INBOX \ -s ${_csuf_homedir}/.mailboxlist -m ${_csuf_homedir}/${mail_subdir}.MAILDIR \ -r "${dovecot_dot_replacement}" -v | tee -a ${dovecot_logfile} > ${tmp_file} ) & # entertain the user show_wait # evaluate exit code wait $! _csuf_mailbox_num=`grep -i "^${_csuf_homedir}" ${tmp_file} | wc -l` _csuf_mailbox_total=`grep -i "^Total conversion:" ${tmp_file} | cut -d: -f2` rm -f ${tmp_file} echo "-> converted ${_csuf_mailbox_num} mailbox(es) with ${_csuf_mailbox_total}." echo # { # echo "${_csuf_output}" # } >> ${dovecot_logfile} else mecho --error "Inbox '${_csuf_homedir}/${mail_subdir}/INBOX' doesn't exist!" fi else mecho --error "directory '${_csuf_homedir}/${mail_subdir}' doesn't exist!" fi else mecho --error "user '${_csuf_user}' not found!" fi else mecho --error "no user name given!" fi } #---------------------------------------------------------------------------------------- # check maildir tree structure of a single users mailbox # # input : $1 - user name # $2 - optional: mail directory #---------------------------------------------------------------------------------------- check_single_user_tree_structure () { local _csuts_user=$1 local _csuts_maildir="$2" local _csuts_homedir='' local _csuts_dot_count local _csuts_idx local _csuts_sub_path if [ -n "${_csuts_user}" ] then if [ -z "${_csuts_maildir}" ] then if getent passwd ${_csuts_user} >/dev/null 2>&1 then # user exists, get home directory _csuts_homedir=`getent passwd ${_csuts_user} | cut -d: -f6` fi _csuts_maildir="${_csuts_homedir}/${mail_subdir}" fi if [ -d ${_csuts_maildir}/cur ] then # personal mail folder exists echo "-> checking if all sub-directories of the mailbox tree exist ..." echo rm -f ${tmp_file} # check if all maildir specific sub directories exist in the mailbox tree, # because it's now allowed to store sub directories AND messages in a folder. # # 1. find all mail directories # 2. strip mail directory from path # 3. skip the mail directory and the INBOX sub directories # 4. remove all maildir specific sub directories # 5. sort and make list uniq find ${_csuts_maildir} -type d | sed "s|^${_csuts_maildir}/[.]*||" | \ grep -E -v "^${_csuts_maildir}$|^cur$|^new$|^tmp$" | \ sed -e 's|/cur$||' -e 's|/new$||' -e 's|/tmp$||' | sort | uniq > ${tmp_file} while read -r DNAME do if [ -n "${DNAME}" ] then # -> 'Ablage.Bekannte.Sport.Tom' _csuts_dot_count=`echo "${DNAME}" | awk -F. '{print NF-1}'` if [ ${_csuts_dot_count} -gt 0 ] then # dot(s) found _csuts_idx=1 while [ ${_csuts_idx} -le ${_csuts_dot_count} ] do # -> 'Ablage' # 'Ablage.Bekannte' # 'Ablage.Bekannte.Sport' _csuts_sub_path=`echo "${DNAME}" | cut -d. -f1-${_csuts_idx}` create_maildir_subdirs "${_csuts_user}" "${_csuts_maildir}/.${_csuts_sub_path}" | tee -a ${dovecot_logfile} _csuts_idx=`expr ${_csuts_idx} + 1` done fi # full mail folder path create_maildir_subdirs "${_csuts_user}" "${_csuts_maildir}/.${DNAME}" | tee -a ${dovecot_logfile} fi done < ${tmp_file} rm -f ${tmp_file} echo "Done." | tee -a ${dovecot_logfile} else mecho --error "directory '${_csuts_maildir}/cur' doesn't exist!" fi else mecho --error "no user name given!" fi } #---------------------------------------------------------------------------------------- # rename .imapmail folder of a single user to activate MAILDIR format # # input: $1 - user name # # 1. convert: /home/ralf/.imapmail -> /home/ralf/.imapmail.MAILDIR # 2. rename : /home/ralf/.imapmail -> /home/ralf/.imapmail.PANDA # 3. rename : /home/ralf/.imapmail.MAILDIR -> /home/ralf/.imapmail #---------------------------------------------------------------------------------------- rename_single_user_folder () { local _rsuf_user=$1 local _rsuf_datestamp=`date +"%Y-%d-%m %H:%M:%S"` local _rsuf_homedir='' local _rsuf_maildir='' local _rsuf_rights local _rsuf_rights_usergroup local _rsuf_error=0 if [ -n "${_rsuf_user}" ] then if getent passwd ${_rsuf_user} >/dev/null 2>&1 then # user exists, get home directory _rsuf_homedir=`getent passwd ${_rsuf_user} | cut -d: -f6` _rsuf_maildir="${_rsuf_homedir}/${mail_subdir}" if [ -d "${_rsuf_maildir}" -a -d "${_rsuf_maildir}.MAILDIR" ] then echo "Activating maildir-folder of user '${_rsuf_user}' ..." { echo echo "${_rsuf_datestamp} - Activating maildir-folder of user '${_rsuf_user}' ..." } >> ${dovecot_logfile} # -> '0666:tim:nogroup' if [ -L "${_rsuf_maildir}" ] then # symbolic link found, get absolute path _rsuf_maildir="`readlink -f "${_rsuf_maildir}"`" fi _rsuf_rights=`get_accessrights "${_rsuf_maildir}"` if [ ! -d "${_rsuf_maildir}.OLD" ] then # move .imapmail directory to .imapmail.OLD mv -n -v "${_rsuf_maildir}" "${_rsuf_maildir}.PANDA" | tee -a ${dovecot_logfile} else # error _rsuf_error=1 mecho --error "unable to rename directory '${_rsuf_maildir}' because the" mecho --error "target directory '${_rsuf_maildir}.PANDA' already exists!" { echo "ERROR: unable to rename directory '${_rsuf_maildir}' because the" echo " target directory '${_rsuf_maildir}.PANDA' already exists!" } >> ${dovecot_logfile} fi if [ ! -d "${_rsuf_maildir}" ] then # move .imapmail.MAILDIR directory to .imapmail mv -n -v "${_rsuf_maildir}.MAILDIR" "${_rsuf_maildir}" | tee -a ${dovecot_logfile} else # error _rsuf_error=1 mecho --error "unable to rename directory '${_rsuf_maildir}.MAILDIR' because" mecho --error "the target directory '${_rsuf_maildir}' already exists!" { echo "ERROR: unable to rename directory '${_rsuf_maildir}.MAILDIR' because" echo " the target directory '${_rsuf_maildir}' already exists!" } >> ${dovecot_logfile} fi if [ ${_rsuf_error} -eq 0 -a -d "${_rsuf_maildir}" ] then # set ownership and access rights only if renaming was successful _rsuf_datestamp=`date +"%Y-%d-%m %H:%M:%S"` echo echo "Setting access rights (${_rsuf_rights}) of '${_rsuf_maildir}' ..." { echo echo "${_rsuf_datestamp} - Setting access rights (${_rsuf_rights}) of '${_rsuf_maildir}' ..." } >> ${dovecot_logfile} # '1666:tim:nogroup' -> 'tim:nogroup' _rsuf_rights_usergroup=`echo "${_rsuf_rights}" | cut -d: -f2-` ( chown -R ${_rsuf_rights_usergroup} "${_rsuf_homedir}/${mail_subdir}" ) & # entertain the user show_wait # evaluate exit code wait $! set_accessrights "${_rsuf_maildir}" "${_rsuf_rights}" else # error mecho --error "unable to set the ownership and access rights of the directory" mecho --error "'${_rsuf_maildir}' because the directory renaming failed." { echo "ERROR: unable to set the ownership and access rights of the directory" echo " '${_rsuf_maildir}' because the directory renaming failed." } >> ${dovecot_logfile} fi echo "Done." | tee -a ${dovecot_logfile} else mecho --error "directory '${_rsuf_maildir}' and/or '../${mail_subdir}.MAILDIR' doesn't exist!" fi else mecho --error "user '${_rsuf_user}' not found!" fi else mecho --error "no user name given!" fi } #---------------------------------------------------------------------------------------- # rename files of a single user # # input: $1 - user name #---------------------------------------------------------------------------------------- rename_single_user_files () { local _rsusf_user=$1 local _rsusf_datestamp=`date +"%Y-%d-%m %H:%M:%S"` local _rsusf_srcfile local _rsusf_destfile # disable mbox spool file _rsusf_srcfile="${mail_spool_path}/${_rsusf_user}" _rsusf_destfile="${_rsusf_srcfile}.PANDA" if [ -f "${_rsusf_srcfile}" ] then echo "Renaming mail spool file of user '${_rsusf_user}' ..." { echo echo "${_rsusf_datestamp} - Renaming mail spool file of user '${_rsusf_user}' ..." } >> ${dovecot_logfile} if [ ! -f "${_rsusf_destfile}" ] then mv -v "${_rsusf_srcfile}" "${_rsusf_destfile}" | tee -a ${dovecot_logfile} else echo "ERROR: destination file '${_rsusf_destfile}' already exists!" | tee -a ${dovecot_logfile} fi fi _rsusf_srcfile="${homedir}/.mailboxlist" _rsusf_destfile="${_rsusf_srcfile}.PANDA" if [ -f "${_rsusf_srcfile}" ] then echo "Renaming file '${_rsusf_srcfile}' of user '${_rsusf_user}' ..." { echo echo "${_rsusf_datestamp} - Renaming file '${_rsusf_srcfile}' of user '${_rsusf_user}' ..." } >> ${dovecot_logfile} if [ ! -f "${_rsusf_destfile}" ] then mv -n -v "${_rsusf_srcfile}" "${_rsusf_destfile}" | tee -a ${dovecot_logfile} else echo "ERROR: destination file '${_rsusf_destfile}' already exists!" | tee -a ${dovecot_logfile} fi fi echo "Done." | tee -a ${dovecot_logfile} } #---------------------------------------------------------------------------------------- # check subscription table of a single user # # input: $1 - user name #---------------------------------------------------------------------------------------- check_single_user_subscriptions () { local _csus_user=$1 local _csus_homedir='' local _csus_public_homedir='' local _csus_shared_homedir='' local _csus_folder='' local _csus_folder_type='USER' local _csus_subscription_file local _csus_subscription_old_file local _csus_subscription_tmp_file if [ -n "${_csus_user}" ] then if getent passwd ${_csus_user} >/dev/null 2>&1 then # user exists, get home directory _csus_homedir=`getent passwd ${_csus_user} | cut -d: -f6`/${mail_subdir} _csus_subscription_file=${_csus_homedir}/subscriptions _csus_subscription_old_file=${_csus_subscription_file}.OLD _csus_subscription_tmp_file=${_csus_subscription_file}.TMP if [ -f ${_csus_subscription_file} ] then # backup original subscription file echo "Checking subscriptions ..." cp ${_csus_subscription_file} ${_csus_subscription_old_file} # set ownership of backup file chown ${_csus_user}: ${_csus_subscription_old_file} rm -f ${_csus_subscription_tmp_file} # create empty tmp file to prevent grep errors touch ${_csus_subscription_tmp_file} sleep 1 while read -r SUB do # process subscribed folders case ${SUB} in ${public_prefix_old}/* ) # #public/* _csus_folder_type='PUBLIC-PANDA' if getent passwd imappublic >/dev/null 2>&1 then # user exists, get home directory _csus_public_homedir=`getent passwd imappublic | cut -d: -f6` fi if [ -z "${_csus_public_homedir}" ] then _csus_public_homedir="/home/imappublic" fi _csus_folder=`echo "${SUB}" | sed "s|^${public_prefix_old}/||"` ;; ${shared_prefix_old}/* ) # #shared/* _csus_folder_type='SHARED-PANDA' if getent passwd imapshared >/dev/null 2>&1 then # user exists, get home directory _csus_shared_homedir=`getent passwd imapshared | cut -d: -f6` fi if [ -z "${_csus_shared_homedir}" ] then _csus_shared_homedir="/home/imapshared" fi _csus_folder=`echo "${SUB}" | sed "s|^${shared_prefix_old}/||"` ;; ${public_prefix_new}/* ) # Public/* _csus_folder_type='PUBLIC-DOVECOT' if getent passwd imappublic >/dev/null 2>&1 then # user exists, get home directory _csus_public_homedir=`getent passwd imappublic | cut -d: -f6` fi if [ -z "${_csus_public_homedir}" ] then _csus_public_homedir="/home/imappublic" fi _csus_folder=`echo "${SUB}" | sed "s|^${public_prefix_new}/||"` ;; ${shared_prefix_new}/* ) # Shared/* _csus_folder_type='SHARED-DOVECOT' if getent passwd imapshared >/dev/null 2>&1 then # user exists, get home directory _csus_shared_homedir=`getent passwd imapshared | cut -d: -f6` fi if [ -z "${_csus_shared_homedir}" ] then _csus_shared_homedir="/home/imapshared" fi _csus_folder=`echo "${SUB}" | sed "s|^${shared_prefix_new}/||"` ;; * ) _csus_folder_type='USER' _csus_folder="`printf '%s\n' "${SUB}"`" ;; esac echo "- Subscription: ${SUB}" # echo " Folder : ${_csus_folder}" case ${_csus_folder_type} in PUBLIC-PANDA ) if [ -n "${_csus_public_homedir}" -a -n "${_csus_folder}" ] then # check if directory exists if [ -d ${_csus_public_homedir}/.${_csus_folder} ] then # check if up-to-date 'Public/...' entry already exists # make sure that escape characters are correctly escaped # grep -q "^${public_prefix_new}/.`printf '%q\n' "${_csus_folder}" | \ grep -q "^${public_prefix_new}/`printf '%q\n' "${_csus_folder}" | \ sed -e 's|\\\{|{|g' -e 's|\\\}|}|g'` *$" ${_csus_subscription_tmp_file} if [ $? -ne 0 ] then # entry doesn't exist, add it echo "${public_prefix_new}/${_csus_folder}" >> ${_csus_subscription_tmp_file} else mecho --warn " -> skipping subscription '${public_prefix_new}/.${_csus_folder}' because it already exists." fi else mecho --warn " -> removing subscription '${SUB}' because no corresponding folder found." fi else mecho --warn " -> removing subscription of an empty folder because it isn't required anymore." fi ;; PUBLIC-DOVECOT ) if [ -n "${_csus_public_homedir}" -a -n "${_csus_folder}" ] then # check if directory exists if [ -d ${_csus_public_homedir}/.${_csus_folder} ] then # check if up-to-date 'Public/...' entry already exists # make sure that escape characters are correctly escaped # grep -q "^${public_prefix_new}/.`printf '%q\n' "${_csus_folder}" | \ grep -q "^${public_prefix_new}/`printf '%q\n' "${_csus_folder}" | \ sed -e 's|\\\{|{|g' -e 's|\\\}|}|g'` *$" ${_csus_subscription_tmp_file} if [ $? -ne 0 ] then # entry doesn't exist, add it echo "${public_prefix_new}/${_csus_folder}" >> ${_csus_subscription_tmp_file} else mecho --warn " -> skipping '${public_prefix_new}/.${_csus_folder}' because it already exists." fi else mecho --warn " -> removing subscription '${SUB}' because no corresponding folder found." fi else mecho --warn " -> removing subscription of an empty folder because it isn't required anymore." fi ;; SHARED-PANDA ) # check if directory exists if [ -n "${_csus_shared_homedir}" -a -n "${_csus_folder}" ] then if [ -d ${_csus_shared_homedir}/.${_csus_folder} ] then # check if up-to-date 'Shared/...' entry already exists # make sure that escape characters are correctly escaped # grep -q "^${shared_prefix_new}/.`printf '%q\n' "${_csus_folder}" | \ grep -q "^${shared_prefix_new}/`printf '%q\n' "${_csus_folder}" | \ sed -e 's|\\\{|{|g' -e 's|\\\}|}|g'` *$" ${_csus_subscription_tmp_file} if [ $? -ne 0 ] then # entry doesn't exist, add it echo "${shared_prefix_new}/${_csus_folder}" >> ${_csus_subscription_tmp_file} else mecho --warn " -> skipping subscription '${shared_prefix_new}/.${_csus_folder}' because it already exists." fi else mecho --warn " -> removing subscription '${SUB}' because no corresponding folder found." fi else mecho --warn " -> removing subscription of an empty folder because it isn't required anymore." fi ;; SHARED-DOVECOT ) # check if directory exists if [ -n "${_csus_shared_homedir}" -a -n "${_csus_folder}" ] then if [ -d ${_csus_shared_homedir}/.${_csus_folder} ] then # check if up-to-date 'Public/...' entry already exists # make sure that escape characters are correctly escaped # grep -q "^${shared_prefix_new}/.`printf '%q\n' "${_csus_folder}" | \ grep -q "^${shared_prefix_new}/`printf '%q\n' "${_csus_folder}" | \ sed -e 's|\\\{|{|g' -e 's|\\\}|}|g'` *$" ${_csus_subscription_tmp_file} if [ $? -ne 0 ] then # entry doesn't exist, add it echo "${shared_prefix_new}/${_csus_folder}" >> ${_csus_subscription_tmp_file} else mecho --warn " -> skipping '${shared_prefix_new}/.${_csus_folder}' because iz already exists." fi else mecho --warn " -> removing subscription '${SUB}' because no corresponding folder found." fi else mecho --warn " -> removing subscription of an empty folder because it isn't required anymore." fi ;; * ) if [ "${_csus_folder}" = 'INBOX' ] then # check if directory exists if [ -d ${_csus_homedir}/cur ] then # check if INBOX entry already exists # make sure that escape characters are correctly escaped grep -q "^`printf '%q\n' "${_csus_folder}" | \ sed -e 's|\\\{|{|g' -e 's|\\\}|}|g'` *$" ${_csus_subscription_tmp_file} if [ $? -ne 0 ] then # entry doesn't exist, add it echo "${_csus_folder}" >> ${_csus_subscription_tmp_file} else mecho --warn " -> skipping subscription '${_csus_folder}' because it already exists." fi else mecho --warn " -> removing subscription '${SUB}' because no corresponding folder found." fi # check if directory exists elif [ -n "${_csus_homedir}" -a -n "${_csus_folder}" ] then if [ -d "${_csus_homedir}/.${_csus_folder}" ] then # check if folder entry already exists # make sure that escape characters are correctly escaped grep -q "^`printf '%q\n' "${_csus_folder}" | \ sed -e 's|\\\{|{|g' -e 's|\\\}|}|g'` *$" ${_csus_subscription_tmp_file} if [ $? -ne 0 ] then # entry doesn't exist, add it echo "${_csus_folder}" >> ${_csus_subscription_tmp_file} else mecho --warn " -> skipping subscription '${_csus_folder}' because it already exists." fi else mecho --warn " -> removing subscription '${SUB}' because no corresponding folder found." fi else mecho --warn " -> removing subscription of an empty folder because it isn't required anymore." fi ;; esac done < ${_csus_subscription_old_file} # sort subscription file # 1. place INBOX at the top of the list # 2. add all other top level folders, except public/shared folders next # 3. add public/shared folders # 4. append all remaining folders { # 1. add INBOX echo 'INBOX' # 2. add top level folders first grep "^[^\.]*$" ${_csus_subscription_tmp_file} | grep -E -v "^INBOX|^${public_prefix_new}/|^${shared_prefix_new}/" | sort # 3. grep public/shared folders grep -E "^${public_prefix_new}/|^${shared_prefix_new}/" ${_csus_subscription_tmp_file} | sort # 4. grep all remaining folders grep -v "^[^\.]*$" ${_csus_subscription_tmp_file} | sort } > ${_csus_subscription_file} rm -f ${_csus_subscription_tmp_file} echo "Done." | tee -a ${dovecot_logfile} else mecho --warn "-> unable to check subscriptions, because asubscription file '${_csus_subscription_file}' doesn't exist." fi else mecho --error "user '${_csus_user}' not found!" fi else mecho --error "no user name given!" fi } #---------------------------------------------------------------------------------------- # check exim filter files #---------------------------------------------------------------------------------------- check_filter_files () { local _cff_output='' echo "checking user specific filter files ..." for FNAME in `find /home -maxdepth 2 -type f -name "\.forward*"` do grep -q 'save ' ${FNAME} if [ $? -eq 0 ] then echo "- file: ${FNAME}" _cff_output="---vvv`printf "%0.s-" {1..49}`\n" _cff_output="${_cff_output}`grep -n -C2 'save ' ${FNAME}` | sed 's/^\([0-9]*\)-\(.*\)$/\1 \2/g'" _cff_output="${_cff_output}\n---^^^`printf "%0.s-" {1..49}`\n" echo -e "${_cff_output}" | sed 's/^/ /g' fi done echo "checking system filter files ..." for FNAME in `find ${exim_spool_path} -maxdepth 1 -type f -name "custom-systemfilter.*"` do grep -q 'save ' ${FNAME} if [ $? -eq 0 ] then echo "- file: ${FNAME}" _cff_output="---vvv`printf "%0.s-" {1..49}`\n" _cff_output="${_cff_output}`grep -n -C2 'save ' ${FNAME}` | sed 's/^\([0-9]*\)-\(.*\)$/\1 \2/g'" _cff_output="${_cff_output}\n---^^^`printf "%0.s-" {1..49}`\n" echo -e "${_cff_output}" | sed 's/^/ /g' fi done } #======================================================================================== # main #======================================================================================== pgmname=`basename $0` log_path=/var/log mail_spool_path=/var/spool/mail varlib_path=/var/lib/mail mailutil_bin=/usr/bin/mailutil uw2dovecot_prog=/usr/bin/uw2dovecot.pl archimap_file=/etc/config.d/archimap mail_file=/etc/config.d/mail mail_subdir='.imapmail' dovecot_logfile=${log_path}/mail-dovecot-convertion.log dovecot_separator='/' dovecot_dot_replacement='\2e' exim_spool_path=/var/spool/exim public_prefix_old='#public' public_prefix_new='#Public' shared_prefix_old='#shared' shared_prefix_new='#Shared' ask_bin=/var/install/bin/ask ask_tmpfile=/tmp/${pgmname}-ask.$$ START_MAIL='no' MAIL_USER_USE_MAILONLY_PASSWORDS='no' MAIL_USER_N='0' IMAP_PUBLIC_FOLDER_N='0' IMAP_SHARED_FOLDER_N='0' START_ARCHIMAP='no' # extract only required parameters to keep environment slim tmp_file=/var/tmp/${pgmname}.$$ { grep -E "^START_MAIL|^POP3IMAP_MAILBOX_FORMAT|^MAIL_USER_USE_MAILONLY_PASSWORDS|^MAIL_USER_N|^MAIL_USER_[0-9]*_ACTIVE|^MAIL_USER_[0-9]*_USER|^IMAP_SHARED_PUBLIC_USERGROUP|^IMAP_SHARED_FOLDER_N|^IMAP_SHARED_FOLDER_[0-9]*_ACTIVE|^IMAP_SHARED_FOLDER_[0-9]*_NAME|^IMAP_SHARED_FOLDER_[0-9]*_USERGROUP|^IMAP_PUBLIC_FOLDER_N|^IMAP_PUBLIC_FOLDER_[0-9]*_ACTIVE|^IMAP_PUBLIC_FOLDER_[0-9]*_NAME|^IMAP_PUBLIC_[0-9]*_USERGROUP" ${mail_file} if [ -f ${archimap_file} ] then grep "^START_ARCHIMAP" ${archimap_file} fi } > ${tmp_file} . ${tmp_file} rm -f ${tmp_file} # JED TESTING ONLY! #IMAP_PUBLIC_FOLDER_N=0 #IMAP_SHARED_FOLDER_N=0 force_quiet_run=false if [ $# -gt 0 ] then # read parameter(s) while [ $# -gt 0 ] do case $1 in --quiet ) force_quiet_run=true shift ;; * ) cmd=$1 break ;; esac done fi if is_root "`whoami`" then if [ "${START_MAIL}" = 'yes' ] then case ${cmd} in --check-filter-files ) echo "Check user specific and system filter files" echo check_filter_files ;; --convert-public-mailbox ) user='imappublic' if active_mail_user_exists "${user}" then # user exists echo "Convert '${user}' mailbox" echo convert_public_shared_folders 'public' else echo echo "Error: user '${user}' not activated or doesn't exist." fi ;; --convert-shared-mailbox ) user='imapshared' if active_mail_user_exists "${user}" then # user exists echo "Convert '${user}' mailbox" echo convert_public_shared_folders 'shared' else echo echo "Error: user '${user}' not activated or doesn't exist." fi ;; --convert-user-mailbox|--check-user-maildir-tree|--check-user-subscriptions ) user=$2 maildir=$3 if [ -n "${user}" ] then if active_mail_user_exists "${user}" then # user exists if getent passwd ${user} >/dev/null 2>&1 then # user exists, get home directory homedir=`getent passwd ${user} | cut -d: -f6` if [ -z "${maildir}" ] then maildir="${homedir}/${mail_subdir}" fi case ${cmd} in --convert-user-mailbox ) echo echo "Convert '${user}' mailbox" echo echo "User name : ${user}" echo "Directory : ${homedir}" echo if [ -d "${maildir}" ] then convert_single_user_folders "${user}" fi ;; --check-user-maildir-tree ) echo echo "Check maildir tree of user '${user}'" echo echo "User name : ${user}" echo "Directory : ${homedir}" echo if [ -d "${maildir}" ] then check_single_user_tree_structure "${user}" "${maildir}" fi ;; --check-user-subscriptions ) echo echo "Check subscriptions of user '${user}'" echo echo "User name : ${user}" echo "Directory : ${homedir}" echo if [ -d "${maildir}" ] then check_single_user_subscriptions "${user}" fi ;; esac fi fi fi ;; * ) # interactive mode endflag=0 until [ ${endflag} -eq 1 ] do sel_values='' print_main_menu ${ask_bin} "Please select (`echo "${sel_values}" | sed 's/ /,/g'`), (q)uit?" 'q' '+' > ${ask_tmpfile} rc=$? read choice < ${ask_tmpfile} rm -f ${ask_tmpfile} if [ ${rc} = 255 ] then exit 1 fi case ${choice} in [qQ] ) # quit endflag=1 ;; [1-7] ) # check input and run command if is_valid_menu_selection ${choice} ${sel_values} then echo case ${choice} in 1|2 ) # convert imappublic/imapshared folders if [ "${choice}" = '1' ] then # imappublic folder_type='public' else # imapshared folder_type='shared' fi if getent passwd imap${folder_type} >/dev/null 2>&1 then # user exists, get home directory homedir=`getent passwd imap${folder_type} | cut -d: -f6` ${ask_bin} "Please confirm that the 'imap${folder_type}' mailbox should be converted" 'no' > ${ask_tmpfile} rc=$? read yesno < ${ask_tmpfile} rm -f ${ask_tmpfile} if [ ${rc} = 255 ] then exit 1 fi case ${yesno} in Y|y|yes ) clrhome mecho --info "Convert 'imap${folder_type}' mailbox" echo if [ ! -d "${homedir}.PANDA" ] then convert_public_shared_folders "${folder_type}" rename_public_shared_folder "${folder_type}" else mecho --warn "Warning: The mailbox of the user 'imap${folder_type}' has already been converted!" fi ;; esac else echo mecho --error "Error: user 'imap${folder_type}' doesn't exist, try again!" fi ;; 3 ) # convert a single user folders ${ask_bin} "Name of user whos mailbox should be converted, (q)uit" 'q' '+' > ${ask_tmpfile} rc=$? read user < ${ask_tmpfile} rm -f ${ask_tmpfile} if [ ${rc} = 255 ] then exit 1 fi if active_mail_user_exists "${user}" then # user exists if getent passwd ${user} >/dev/null 2>&1 then # user exists, get home directory homedir=`getent passwd ${user} | cut -d: -f6` ${ask_bin} "Please confirm that the mailboxes of '${user}' should be converted" 'no' > ${ask_tmpfile} rc=$? read yesno < ${ask_tmpfile} rm -f ${ask_tmpfile} if [ ${rc} = 255 ] then exit 1 fi case ${yesno} in Y|y|yes ) yesno='' ${ask_bin} "Please confirm that missing maildir sub-directories should be created" 'no' > ${ask_tmpfile} rc=$? read yesno < ${ask_tmpfile} rm -f ${ask_tmpfile} if [ ${rc} = 255 ] then exit 1 fi clrhome mecho --info "Convert '${user}' mailbox" echo if [ ! -d "${homedir}/${mail_subdir}.PANDA" ] then convert_single_user_folders "${user}" case ${yesno} in Y|y|yes ) check_single_user_tree_structure "${user}" "${homedir}/${mail_subdir}.MAILDIR" ;; * ) ;; esac rename_single_user_folder "${user}" rename_single_user_files "${user}" else mecho --warn "Warning: The mailbox of the user '${user}' has already been converted!" fi ;; esac else echo mecho --error "Error: user '${user}' doesn't exist, try again!" fi else echo mecho --error "Error: user '${user}' not activated, try again!" fi ;; 4 ) # convert all users folders ${ask_bin} "Please confirm that the mailboxes of all users should be converted" 'no' > ${ask_tmpfile} rc=$? read yesno < ${ask_tmpfile} rm -f ${ask_tmpfile} if [ ${rc} = 255 ] then exit 1 fi case ${yesno} in Y|y|yes ) clrhome mecho --info "Convert mailboxes of all users" echo if active_mail_user_exists '*all*' then yesno='' ${ask_bin} "Please confirm that missing maildir sub directories should be created" 'no' > ${ask_tmpfile} rc=$? read yesno < ${ask_tmpfile} rm -f ${ask_tmpfile} if [ ${rc} = 255 ] then exit 1 fi if [ "${MAIL_USER_USE_MAILONLY_PASSWORDS}" = 'yes' ] then idx=1 while [ ${idx} -le ${MAIL_USER_N} ] do eval active='$MAIL_USER_'${idx}'_ACTIVE' eval user='$MAIL_USER_'${idx}'_USER' if [ "${active}" = 'yes' ] then if getent passwd ${user} >/dev/null 2>&1 then # user exists, get home directory homedir=`getent passwd ${user} | cut -d: -f6` echo if [ ! -d "${homedir}/${mail_subdir}.PANDA" ] then convert_single_user_folders "${user}" case ${yesno} in Y|y|yes ) check_single_user_tree_structure "${user}" "${homedir}/${mail_subdir}.MAILDIR" ;; * ) ;; esac rename_single_user_folder "${user}" rename_single_user_files "${user}" else echo mecho --warn "Warning: The mailbox of the user '${user}' has already been converted!" fi else echo mecho --error "Error: user '${user}' doesn't exist, try again!" fi fi idx=`expr ${idx} + 1` done else # loop over all system users, except imappublic/imapshared for user in `getent passwd | grep -E -v "^imappublic:^imapshared:" | cut -d: -f1 | sort` do if getent passwd ${user} >/dev/null 2>&1 then # user exists, get home directory homedir=`getent passwd ${user} | cut -d: -f6` if [ -n "${homedir}" ] then maildir="${homedir}/${mail_subdir}" if [ -d "${maildir}" ] then echo if [ ! -d "${homedir}/${mail_subdir}.PANDA" ] then convert_single_user_folders "${user}" case ${yesno} in Y|y|yes ) check_single_user_tree_structure "${user}" "${homedir}/${mail_subdir}.MAILDIR" ;; * ) ;; esac rename_single_user_folder "${user}" rename_single_user_files "${user}" else echo mecho --warn "Warning: The mailbox of the user '${user}' has already been converted!" fi fi fi fi done fi fi ;; esac ;; 5 ) ${ask_bin} "Name of user whos subscriptions should be checked, (q)uit" 'q' '+' > ${ask_tmpfile} rc=$? read user < ${ask_tmpfile} rm -f ${ask_tmpfile} if [ ${rc} = 255 ] then exit 1 fi if active_mail_user_exists "${user}" then if getent passwd ${user} >/dev/null 2>&1 then # user exists, get home directory homedir=`getent passwd ${user} | cut -d: -f6` ${ask_bin} "Please confirm that the subscriptions of '${user}' should be checked" 'no' > ${ask_tmpfile} rc=$? read yesno < ${ask_tmpfile} rm -f ${ask_tmpfile} if [ ${rc} = 255 ] then exit 1 fi case ${yesno} in Y|y|yes ) clrhome mecho --info "Check subscriptions of user '${user}'" echo echo -n "User name : "; mecho --warn "${user}" echo -n "Directory : "; mecho --warn "${homedir}" echo check_single_user_subscriptions "${user}" ;; esac else echo mecho --error "Error: user '${user}' doesn't exist, try again!" fi else echo mecho --error "Error: user '${user}' not activated, try again!" fi ;; 6 ) ${ask_bin} "Please confirm that the subscriptions of all users should be checked" 'no' > ${ask_tmpfile} rc=$? read yesno < ${ask_tmpfile} rm -f ${ask_tmpfile} if [ ${rc} = 255 ] then exit 1 fi case ${yesno} in Y|y|yes ) clrhome mecho --info "Check subscriptions of user '${user}'" if active_mail_user_exists '*all*' then if [ "${MAIL_USER_USE_MAILONLY_PASSWORDS}" = 'yes' ] then idx=1 while [ ${idx} -le ${MAIL_USER_N} ] do eval active='$MAIL_USER_'${idx}'_ACTIVE' eval user='$MAIL_USER_'${idx}'_USER' if [ "${active}" = 'yes' ] then if getent passwd ${user} >/dev/null 2>&1 then # user exists, get home directory homedir=`getent passwd ${user} | cut -d: -f6` echo -n "User name : "; mecho --warn "${user}" echo -n "Directory : "; mecho --warn "${homedir}" echo check_single_user_subscriptions "${user}" else echo mecho --error "Error: user '${user}' doesn't exist, try again!" fi fi idx=`expr ${idx} + 1` done else # loop over all system users, except imappublic/imapshared for user in `getent passwd | grep -E -v "^imappublic:|^imapshared:" | cut -d: -f1 | sort` do if getent passwd ${user} >/dev/null 2>&1 then # user exists, get home directory homedir=`getent passwd ${user} | cut -d: -f6` if [ -n "${homedir}" ] then maildir="${homedir}/${mail_subdir}" if [ -d "${maildir}" ] then echo -n "User name : "; mecho --warn "${user}" echo -n "Directory : "; mecho --warn "${homedir}" echo check_single_user_subscriptions "${user}" fi fi fi done fi fi ;; esac ;; 7 ) clrhome mecho --info "Check user specific and system filter files" echo check_filter_files ;; esac else echo mecho --error "Error: input not in range, try again!" fi anykey ;; * ) # error echo mecho --error "Error: input not in range, try again!" anykey ;; esac done ;; esac else mecho --error "START_MAIL='no' has been set, although an enabled mail package is required." fi else mecho --error "You need root equivalent rights to use this script!" fi #========================================================================================= # end #========================================================================================= exit 0