Simple configuration editing script
-----------------------------------

Those function let you edit easily the dovecot.conf, dovecot-sql.conf, ...
file.

This code is far from perfect but is usable though.

---%<-------------------------------------------------------------------------
#!/bin/sh
# edit-dovecot.sh
bl='[[:blank:] ]*';
ESC_SEQ="\x1b["
COL_RESET=$ESC_SEQ"39;49;00m"
COL_RED=$ESC_SEQ"31;01m"
COL_GREEN=$ESC_SEQ"32;01m"
COL_YELLOW=$ESC_SEQ"33;01m"
ACT="$COL_YELLOW(==)$COL_RESET"
INF="$COL_GREEN(II)$COL_RESET"
WAR="$COL_MAGENTA(WW)$COL_RESET"

# section name[|lines to skip]
# [ start line ]
# [ end line ]
getSectionCoord() {
    local nom="$1" && shift
    local skip=1
    local skipe='$'
    [ $# -gt 0 ] && skip=$1
    [ $# -gt 1 ] && skipe=$2
    [ $(expr "$nom" : ".*|[0-9]\+$") -gt 0 ] &&
    skip="${nom##*|}"&& nom="${nom%%|*}"
    local cmd="$skip,$skipe"'{/^[[:space:] #]*'"$nom$bl"'{/{=;q}}'
    #echo "sed -n '$cmd' $CONFIG_SOURCE_FILE" > /dev/stderr
    local begin=$(sed -n "$cmd" $CONFIG_SOURCE_FILE)
    local end=$(sed -n "$begin"'{
:main
n
/^[[:space:] #]*}'"$bl"'$/{=;q}
/{/ b skip1
b main
:skip1
n
/^[[:space:] #]*}'"$bl"'$/ b main
/{/ b skip2
b skip1
:skip2
n
/^[[:space:] #]*}'"$bl"'$/ b skip1
/{/ b skip3
b skip2
:skip3
n
/^[[:space:] #]*}'"$bl"'$/ b skip2
/{/{a\
# too much branch : quitting
q
}
b skip3
}' "$CONFIG_SOURCE_FILE")
    [ -z "$begin" ] && echo "1^1" && /bin/echo -e "$WAR $begin^$end not found
for $nom"> /dev/stderr && return 1
    echo "$begin^$end"
}
## getSubSectionCoord, getSection, commentSection, unCommentSection :
# arg 1 : section name
# arg 2 : [ sub-section name ]
# arg n : [ sub-sub-section name ...]
getSubSectionCoord() {
    local sc;
    while [ $# -gt 0 ]; do
        local s=${sc%%^*}
        local e=${sc##*^}
        if [ -z "$s" ]; then
            sc=$(getSectionCoord "$1")
        else
            [ -n "$e" ] && sc=$(getSectionCoord "$1" "$s" "$e")
            [ -z "$e" ] && sc=$(getSectionCoord "$1" "$s")
        fi
        #echo "$sc - $1" > /dev/stderr
        shift
    done;
    echo $sc
}
getSection() {
    local c=$(getSubSectionCoord "$@")
    sed -n "${c%%^*},${c##*^}p" "$CONFIG_SOURCE_FILE"
}
commentSection() {
    local ssc=$(getSubSectionCoord "$@")
    sed -i "${ssc%%^*},${ssc##*^}s@^\($bl[a-zA-Z{}]\)@#\1@"
"$CONFIG_SOURCE_FILE" # with p
}
# variable value section,[...]
setVar() {
    [ "$CONFIG_SOURCE_FILE" = "$DOVECOT_CONF_PATH" ] &&
    checkIfSet "$@" &&
    return 0
    local uneVar="$1"
    local uneVal="$2"
    shift && shift
    for i in "$@"; do
        unCommentSection "$i"
    done
    local ssc=$(getSubSectionCoord "$@")
    local s=1 && local e='$'
    [ -n "$ssc" ] && s="${ssc%%^*}" && e="${ssc##*^}"
    #echo "$s -> $e" > /dev/stderr
    sed -i "$s,$e{
:main
/^\($bl\)#*$bl$uneVar$bl=$bl/{
\@$uneVal\$@{s/#//;b end}
s@^\($bl\)#*$bl$uneVar.*\$@\1$uneVar = $uneVal@
t end
}
${e} {i\
$uneVar = $uneVal
b end
}
n; b main;
:end
n;b end
}
" "$CONFIG_SOURCE_FILE"
    return $?
}
unCommentSection() {
    local innerDirectives=""
    local c=$(getSectionCoord "$1") && shift
    [ "$1" = "-r" ] &&
innerDirectives="s@^\($bl\)#\($bl[a-zA-Z_]*\)$bl=$bl\(.*\)@\1\2 = \3@"
    local s=${c%%^*}
    local e=${c##*^}
    sed -i "$s,$e{
${s}"'s/#//
# main loop
:main
n
'"$e"'{s/#//;b theEnd}
/{/ b skip
'"$innerDirectives"'
b main
# inner brackets skip look
:skip
# maybe useful here too ? : $e{s/#//;b theEnd}
n
/}/{b main}
b skip
# nothing until the end
:theEnd
n;b theEnd
}' "$CONFIG_SOURCE_FILE"
}
setVarOfFile() {
    CONFIG_SOURCE_FILE="$1" && shift
    setVar "$@"
    CONFIG_SOURCE_FILE="$DOVECOT_CONF_PATH"
}
checkIfSet() {
    ## fixme : sed since correct section beginning
    ## eg:strip substr beginning of $i in the loop from $uneVar (example with
'auth_')
    local uneVar="$1"
    local uneVal="$2"
    shift && shift
    local prot=''
    for i in "$@"; do
        [ -z "$prot" ] &&
        prot=$(echo "$i"|sed -n 's/.*\(pop3\|imap\).*/\1/p')

        [ $(expr "$i" : "auth") ] &&
        uneVar="$(echo "$uneVar"|sed 's/auth_*//')"
    done
    [ -n "$prot" ] && prot="($prot)"
    if [ -n "$(dovecot -a|grep -F "$uneVar$prot: $uneVal")" ]; then
        /bin/echo -e "$INF $uneVar$prot\t: ${COL_GREEN}$uneVal${COL_RESET}
equals"&&
        return 0;
    else
        /bin/echo -e "$ACT $uneVar$prot\t: ${COL_YELLOW}$uneVal${COL_RESET}
set"&&
        return 1
    fi
}
---%<-------------------------------------------------------------------------

-------------------------------------------------------------------------------

 * Some examples of use :

---%<-------------------------------------------------------------------------
#!/bin/sh
. './edit-dovecot.sh'
CONFIG_SOURCE_FILE="/tmp/dovecot.conf"
FQDN="mydomain.local"
POSTFIX_MAIL_DIR="/var/spool/postfix"
DOVECOT_SSL_ONLY=1
STATIC_USER_DB=1
AUTH_WITH_PAM=1
#DOVECOT_SQL_PATH=/tmp/dovecot-sql.conf
/bin/echo -e "$ACT Customization of $CONFIG_SOURCE_FILE"
if [ $DOVECOT_DEBUG -eq 1 ]; then
    setVar auth_verbose yes 'auth default'
    setVar auth_debug yes 'auth default'
    setVar auth_debug_passwords yes 'auth default'
    setVar mail_debug yes
    setVar verbose_ssl yes
    setVar verbose_proctitle yes
fi
#setVar maildir_copy_preserve_filename yes
#setVar disable_plaintext_auth yes
#setVar mail_location "maildir:$POSTFIX_MAIL_DIR/%u@%d"
# |50 because to skip example comment at the beginning of dovecot.conf
if [ $DOVECOT_SSL_ONLY -eq 1 ]; then
    setVar 'listen' '127.0.0.1:143' 'protocol imap|50'
    setVar 'listen' '127.0.0.1:110' 'protocol pop3|50'
else
    setVar 'listen' '*:143' 'protocol imap|50'
    setVar 'listen' '*:110' 'protocol pop3|50'
fi
setVar 'ssl_listen' '*:993' 'protocol imap|50'
setVar 'ssl_listen' '*:995' 'protocol pop3|50'
setVar 'pop3_uidl_format' '%08Xu%08Xv' 'protocol pop3|50'
setVar ssl_cert_file "/etc/ssl/$FQDN/popImap/dovecotPopImap.pem"
setVar ssl_key_file "/etc/ssl/$FQDN/popImap/dovecotPopImap.key"
setVar first_valid_uid 1001
setVar last_valid_uid 1001
setVar auth_default_realm "$FQDN" 'auth default'
setVar maildir_copy_with_hardlinks yes
setVar mail_privileged_group mail
setVar user nobody 'auth default'
setVar mechanisms 'login plain' 'auth default'
if [ $STATIC_USER_DB -eq 1 ]; then
    commentSection 'auth default' 'userdb passwd'
    commentSection 'auth default' 'userdb sql'
    setVar args 'uid=1001 gid=1001 home=/var/spool/maildirs/%u/home
mail=/var/spool/maildirs/%u' 'auth default' 'userdb static'
else
    commentSection 'auth default' 'userdb passwd'
    commentSection 'auth default' 'userdb static'
    setVar args "$DOVECOT_SQL_PATH" 'auth default' 'userdb sql'
fi
if [ $AUTH_WITH_PAM -eq 1 ]; then
    setVar args 'cache_key=%u smtp' 'auth default' 'passdb pam'
    commentSection 'auth default' 'passdb sql'
else
    setVar args "$DOVECOT_SQL_PATH" 'auth default' 'passdb sql'
    commentSection 'auth default' 'passdb pam'
fi
if [ -n "$DOVECOT_SQL_PATH" ]; then
    /bin/echo -e "$ACT Customization of $DOVECOT_SQL_PATH"
    setVarOfFile "$DOVECOT_SQL_PATH" driver "mysql"
    setVarOfFile "$DOVECOT_SQL_PATH" connect "host=/var/run/mysqld/mysqld.sock
dbname=db user=auser password=apass"
    setVarOfFile "$DOVECOT_SQL_PATH" default_pass_scheme "PLAIN-MD5"
    setVarOfFile "$DOVECOT_SQL_PATH" user_query "SELECT
concat('$POSTFIX_MAIL_DIR/',maildir,'/home') AS home,
concat('$POSTFIX_MAIL_DIR/',maildir) AS mail, 1001 AS uid, 1001 AS gid, quota
FROM mailbox WHERE username = '%u'"

    [ $AUTH_WITH_PAM -ne 1 ] &&
    setVarOfFile "$DOVECOT_SQL_PATH" password_query "SELECT password FROM
mailbox WHERE username = '%u' AND active = '1'"
fi
---%<-------------------------------------------------------------------------

(This file was created from the wiki on 2008-06-20 04:42)
