commit 2143dbf0a452894c24c9ef5b313cd542018344db
parent 1ea3f5cc38350085ccb1232ed35f94c79b006eb4
Author: Jaromil <jaromil@dyne.org>
Date:   Fri, 26 Dec 2014 12:22:32 +0100
various generic code cleanups and reorganization
Diffstat:
| M | src/zlibs/accounts |  |  | 25 | ++++++++++++------------- | 
| M | src/zlibs/email |  |  | 497 | ++++++++++++++++++++++++++++++++++++++++--------------------------------------- | 
| M | src/zlibs/filters |  |  | 378 | ++++++++++++++++++++++++++++++++++++++++---------------------------------------- | 
| M | src/zlibs/helpers |  |  | 303 | ++++++++++++++++++++++++++++++++++++++++++------------------------------------- | 
4 files changed, 610 insertions(+), 593 deletions(-)
diff --git a/src/zlibs/accounts b/src/zlibs/accounts
@@ -28,7 +28,7 @@
 read_account() {
     typeset -al all
     unset name email imap imap_port smtp smtp_port \
-	    host login transport auth cert options folders exclude
+        host login transport auth cert options folders exclude
     # parse arguments
 
     { test "$account" = "" } && { account="default" }
@@ -38,13 +38,13 @@ read_account() {
     acct="$MAILDIRS/Accounts/$account";
     { test -r "$acct" } || {
         acct="$MAILDIRS/Accounts/$account.txt"
-	{ test -r "$acct" } || {
-	    error "no account found: $acct"
-	    act "Refine your argument using '-a accountname'"
-	    act "Available accounts:"
-	    ls "$MAILDIRS/Accounts/"
-	    return 1
-	}
+        { test -r "$acct" } || {
+            error "no account found: $acct"
+            act "Refine your argument using '-a accountname'"
+            act "Available accounts:"
+            ls "$MAILDIRS/Accounts/"
+            return 1
+        }
     }
 
     ttmp=`awk '
@@ -66,8 +66,8 @@ read_account() {
     /^exclude/ { printf "exclude=("; for(i=2;i<=NF;i++) printf "%s ", $i; printf ");" }
     ' "$acct"`
     { test $? = 0 } || {
-	error "Error parsing account: $acct"
-	return 1 }
+    error "Error parsing account: $acct"
+    return 1 }
 
     eval "$ttmp"
     # check required fields
@@ -86,12 +86,12 @@ read_account() {
     { test -z $transport }  && { transport=plain }
     { test -z $imap_port }  && { imap_port=143 }
     { test -z $smtp_port }  && { smtp_port=25 }
-    
+
     { test -z $auth }       && { auth=plain }
     { test -z $cert }       && { cert=ignore }
     { test -z $accountopt } && { accountopt=keep }
     # cert and password can be missing
-    
+
     func "name: $name"
     func "email: $email"
     func "login: $login"
@@ -113,4 +113,3 @@ read_account() {
 
     return 0
 }
-
diff --git a/src/zlibs/email b/src/zlibs/email
@@ -21,21 +21,10 @@
 # Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
 # extract all emails found in stdin, one per line
-extract_emails() {
-awk '{ for (i=1;i<=NF;i++)
-	 if ( $i ~ /[[:alnum:]]@[[:alnum:]]/ ) {
-	   gsub(/<|>|,/ , "" , $i); print $i } }'
-}
-
 compose() {
     # no args, open in compose mode
-    tmp="${TMPDIR}/compose.$datestamp.$RANDOM"
-    _res=0;
-    echo "To: ${PARAM[@]}" > $tmp
-    ${=mutt} -F $MUTTDIR/rc -H $tmp
-    _res=$?
-    rm -f $tmp
-    return $_res
+    ${=mutt} -F $MUTTDIR/rc -H <(print "To: ${PARAM[@]}")
+    return $?
 }
 
 
@@ -57,33 +46,33 @@ queue() {
 
     maildirmake "$MAILDIRS/outbox"
     { test $? = 0 } || {
-	act "updating outbox format to Maildir"
-	# silently migrate the outbox from the old format to the new
-	tmpp=(`find "$MAILDIRS/outbox" -type f`)
-	if [ ${#tmpp} = 0 ]; then
-	    # the old format outbox is just empty
-	    rmdir "$MAILDIRS/outbox"
-	    maildirmake "$MAILDIRS/outbox"
-	else
-	    # there are some mails to be sent in the old format outbox
-	    # preserve them while migrating to the new format
-	    # this code is less interesting, since it handles an old
-	    # format in JaroMail
-	    tmppp="$TMPDIR/jaro-outbox-migration-$RANDOM"
-	    mkdir -p $tmppp
-	    mv "$MAILDIRS/outbox/*" $tmppp/
-	    rmdir "$MAILDIRS/outbox"
-	    maildirmake "$MAILDIRS/outbox"
-	    # here we devince two useful arrays:
-	    # bodies: the list of mail bodies to send
-	    # corresponding to files with same name and extension .msmtp
-	    bodies=(`find "$tmppp" -type f -name '*.mail'`)
-	    for i in ${bodies}; do
-		cat "$i" | deliver outbox
-		{ test $? = 0 } && { rm "$i" }
-	    done
-	    rmdir $tmppp
-	fi
+    act "updating outbox format to Maildir"
+    # silently migrate the outbox from the old format to the new
+    tmpp=(`find "$MAILDIRS/outbox" -type f`)
+    if [ ${#tmpp} = 0 ]; then
+        # the old format outbox is just empty
+        rmdir "$MAILDIRS/outbox"
+        maildirmake "$MAILDIRS/outbox"
+    else
+        # there are some mails to be sent in the old format outbox
+        # preserve them while migrating to the new format
+        # this code is less interesting, since it handles an old
+        # format in JaroMail
+        tmppp="$TMPDIR/jaro-outbox-migration-$RANDOM"
+        mkdir -p $tmppp
+        mv "$MAILDIRS/outbox/*" $tmppp/
+        rmdir "$MAILDIRS/outbox"
+        maildirmake "$MAILDIRS/outbox"
+        # here we devince two useful arrays:
+        # bodies: the list of mail bodies to send
+        # corresponding to files with same name and extension .msmtp
+        bodies=(`find "$tmppp" -type f -name '*.mail'`)
+        for i in ${bodies}; do
+        cat "$i" | deliver outbox
+        { test $? = 0 } && { rm "$i" }
+        done
+        rmdir $tmppp
+    fi
     }
     ${=mkdir} "$MAILDIRS/outbox/send"
 
@@ -93,60 +82,60 @@ queue() {
     if [[ "${=queue_to}" =~ '@jaromail.group' ]]; then
 
 
-	groupfile="`print ${=queue_to}|cut -d@ -f1`"
-	act "email recipients are in group ${groupfile}"
-
-	{ test -r "$MAILDIRS/Groups/$groupfile" } || {
-	    maildirmake "$MAILDIRS/postponed"
-	    mv "${TMPDIR}/${queue_body}.mail" "$MAILDIRS/postponed/new"
-	    unlock "$MAILDIRS/outbox"
-	    error "Group not found: $groupfile"
-	    return 1 }
-
-	recipients=`cat "$MAILDIRS/Groups/$groupfile" | grep -v '^#'`
-	groupnum=`print ${recipients} | wc -l`
-	groupmode=`head -n1 "$MAILDIRS/Groups/$groupfile" | awk '/^#mode/ { print $2 } { next }'`
-	{ test "$groupmode" = "" } && { groupmode="individual" }
-	act "$groupnum recipients in total, sending mode $groupmode"
-
-
-	case $groupmode in
-
-	    # individual group mode hides other recipients and send
-	    # multiple mail envelopes with each single recipient in To:
-	    individual)
-		for i in ${(f)recipients}; do
-		    ig=${base}-${RANDOM}
-		    cat "${TMPDIR}/${queue_body}.mail" | \
-			awk '/^To:/ { print "'"To: $i"'"; next } { print $0 }' \
-			> "${MAILDIRS}/outbox/new/${ig}.mail"
-		done
-		;;
-
-	    # carboncopy group mode sends a single envelope where all
-	    # recipients can see and reply to each other
-	    carboncopy|cc)
-		cc=""
-		for i in ${(f)recipients}; do
-		    if [ "$cc" = "" ]; then cc="$i"
-		    else cc+=", $i"; fi
-		done
-		ig=${base}-${RANDOM}
-		cat "${TMPDIR}/${queue_body}.mail" | \
-		    awk '/^To:/ { print "'"To: $cc"'"; print "'"Reply-To: $cc"'"; next }
-				{ print $0 }' \
-				    > "${MAILDIRS}/outbox/new/${ig}.mail"
-		;;
-	esac
+    groupfile="`print ${=queue_to}|cut -d@ -f1`"
+    act "email recipients are in group ${groupfile}"
+
+    { test -r "$MAILDIRS/Groups/$groupfile" } || {
+        maildirmake "$MAILDIRS/postponed"
+        mv "${TMPDIR}/${queue_body}.mail" "$MAILDIRS/postponed/new"
+        unlock "$MAILDIRS/outbox"
+        error "Group not found: $groupfile"
+        return 1 }
+
+    recipients=`cat "$MAILDIRS/Groups/$groupfile" | grep -v '^#'`
+    groupnum=`print ${recipients} | wc -l`
+    groupmode=`head -n1 "$MAILDIRS/Groups/$groupfile" | awk '/^#mode/ { print $2 } { next }'`
+    { test "$groupmode" = "" } && { groupmode="individual" }
+    act "$groupnum recipients in total, sending mode $groupmode"
+
+
+    case $groupmode in
+
+        # individual group mode hides other recipients and send
+        # multiple mail envelopes with each single recipient in To:
+        individual)
+        for i in ${(f)recipients}; do
+            ig=${base}-${RANDOM}
+            cat "${TMPDIR}/${queue_body}.mail" | \
+            awk '/^To:/ { print "'"To: $i"'"; next } { print $0 }' \
+            > "${MAILDIRS}/outbox/new/${ig}.mail"
+        done
+        ;;
+
+        # carboncopy group mode sends a single envelope where all
+        # recipients can see and reply to each other
+        carboncopy|cc)
+        cc=""
+        for i in ${(f)recipients}; do
+            if [ "$cc" = "" ]; then cc="$i"
+            else cc+=", $i"; fi
+        done
+        ig=${base}-${RANDOM}
+        cat "${TMPDIR}/${queue_body}.mail" | \
+            awk '/^To:/ { print "'"To: $cc"'"; print "'"Reply-To: $cc"'"; next }
+                { print $0 }' \
+                    > "${MAILDIRS}/outbox/new/${ig}.mail"
+        ;;
+    esac
 
     else
-	# recipients are set in the email envelope
-	cat "$TMPDIR/$queue_body.mail" | deliver "outbox"
+    # recipients are set in the email envelope
+    cat "$TMPDIR/$queue_body.mail" | deliver "outbox"
     fi
 
     unlock "$MAILDIRS/outbox"
     { test -r "${TMPDIR}/${queue_body}.mail" } && {
-	${=rm} "${TMPDIR}/${queue_body}.mail" }
+    ${=rm} "${TMPDIR}/${queue_body}.mail" }
 
     return 0
 }
@@ -159,25 +148,25 @@ fetchall() {
     accts=`${=find} $MAILDIRS/Accounts -type f | grep -v README`
     notice "Fetching mail for all accounts: ${#accts} found"
     for i in ${(f)accts}; do
-	account=`basename $i`
-	fetch
-	if [ $? != 0 ]; then res=1; fi
-	# returns an error if just one of the accounts did
+        account=`basename $i`
+        fetch
+        if [ $? != 0 ]; then res=1; fi
+        # returns an error if just one of the accounts did
     done
     return $res
 }
 
 fetch() {
     { test "$account" = "" } && {
-	fetchall; return $? }
+        fetchall; return $? }
 
-# setup global account variables
+    # setup global account variables
     read_account ${account}
-# name login host protocol port auth folders accountopt
+    # name login host protocol port auth folders accountopt
 
     { test  $? != 0 } && {
-	error "Invalid account: $account"
-	return 1
+        error "Invalid account: $account"
+        return 1
     }
 
     notice "Fetching email for account ${account}"
@@ -189,7 +178,9 @@ fetch() {
     host=$imap
     port=$imap_port
     ask_password
-    { test $? = 0 } || { error "Impossible to fetch email for account ${account}"; return 1 }
+    { test $? = 0 } || {
+        error "Impossible to fetch email for account ${account}";
+        return 1 }
 
     # this puts total size in $imap_info
     # experimental only, commented out for now
@@ -202,21 +193,31 @@ fetch() {
 
     # notice "Total occupation is `human_size ${imap_info[${#imap_info}]}`"
 
-	fmconf=("poll $imap with proto IMAP user \"$login\" there with password \"$password\"")
-    
-	if ! [ -z $accountopt ]; then # add option configuration
-	    fmconf+=(" ${accountopt} "); fi
-    
-	# if no folders specified, use all
-	[[ "$folders" == "" ]] && {
-	    folders=(`imap_list_folders`) }
-	act "${#folders} folders found"
-    
-    # unset here because listing folders still needs a pass
-	unset password
+    fmconf=("poll $imap with proto IMAP user \"$login\" there with password \"$password\"")
+
+    if ! [ -z $accountopt ]; then # add option configuration
+        fmconf+=(" ${accountopt} "); fi
+
+    # check if folders on commandline
+    if [[ "$PARAM[@]" = "" ]]; then
+
+        # if no folders specified, use all
+        [[ "$folders" == "" ]] && {
+            folders=(`imap_list_folders`) }
+        act "${#folders} folders found"
+
+    else
+
+        act "commanded to fetch folders: ${PARAM[@]}"
+        folders=(${PARAM[@]})
+
+    fi
+
+    # unset here because listing folders still needed a pass
+    unset password
 
     # nothing to download, bail out with error
-	[[ ${#folders} == "0" ]] && return 1
+    [[ ${#folders} == "0" ]] && return 1
 
     # remove excludes
     [[ ${#exclude} == "0" ]] || {
@@ -226,60 +227,60 @@ fetch() {
         done
     }
     func "fetch folders: $folders"
-    
-	# add folder configuration
-	fmconf+=(" folder ${=folders} ");
-    
-	fmconf+=(" ${transport} warnings 3600 and wants mda \"jaro -q deliver\" ")
-    
-	if [ "$cert" = "check" ]; then
-	    # we now use system-wide certs
-	    fmconf+=(" sslcertck ") # sslcertpath '$WORKDIR/certs'
-	fi
-    
-    
-	fmconf+=(" antispam 571 550 501 554 ")
-    
-	print $accountopt | grep 'keep' > /dev/null
-	{ test $? = 0 } || {
-	    error "planning to delete mails from server, account option: $accountopt" }
-    
-	# try login without doing anything
-	print "$fmconf" | fetchmail -c -f -
-	res=$?
-	# examine result
-	case $ret in
-	    1)
-		    notice "No mails for $name"
-		    unset $fmconf
-		    return 1
-		    ;;
-	    2)
-		    error "Invalid or unknown certificate for $imap"
-		    unset $fmconf
-		    return 1
-		    ;;
-	    3)
-		    error "Invalid password for user $login at $imap"
-		    unset $fmconf
-		    return 1
-		    ;;
-	    *)
-		    func "fetchmail returns $ret" ;;
-	esac
+
+    # add folder configuration
+    fmconf+=(" folder ${=folders} ");
+
+    fmconf+=(" ${transport} warnings 3600 and wants mda \"jaro -q deliver\" ")
+
+    if [ "$cert" = "check" ]; then
+        # we now use system-wide certs
+        fmconf+=(" sslcertck ") # sslcertpath '$WORKDIR/certs'
+    fi
+
+
+    fmconf+=(" antispam 571 550 501 554 ")
+
+    print $accountopt | grep 'keep' > /dev/null
+    { test $? = 0 } || {
+        error "planning to delete mails from server, account option: $accountopt" }
+
+    # try login without doing anything
+    print "$fmconf" | fetchmail -c -f -
+    res=$?
+    # examine result
+    case $ret in
+        1)
+            notice "No mails for $name"
+            unset $fmconf
+            return 1
+            ;;
+        2)
+            error "Invalid or unknown certificate for $imap"
+            unset $fmconf
+            return 1
+            ;;
+        3)
+            error "Invalid password for user $login at $imap"
+            unset $fmconf
+            return 1
+            ;;
+        *)
+            func "fetchmail returns $ret" ;;
+    esac
 
     if [[ $DRYRUN = 0 ]]; then
-        
-	    act "please wait while downloading mails to incoming..."
-        
-	    print " $fmconf " | fetchmail -f -
-        
+
+        act "please wait while downloading mails to incoming..."
+
+        print " $fmconf " | fetchmail -f -
+
     else
         act "dryrun: nothing will be fetched really."
     fi
 
-	unset $fmconf
-    
+    unset $fmconf
+
     return 0
 }
 
@@ -295,13 +296,13 @@ send() {
     queue_outbox=`${=find} "${MAILDIRS}/outbox" -type f`
     queue_outbox_num=`${=find} "${MAILDIRS}/outbox" -type f|wc -l`
     { test "$queue_outbox_num" = "0" } && {
-	act "Outbox is empty, no mails to send."
-	return 0 }
+    act "Outbox is empty, no mails to send."
+    return 0 }
 
     read_account ${account}
     { test  $? != 0 } && {
-	error "Invalid account: $account"
-	return 1
+    error "Invalid account: $account"
+    return 1
     }
 
     # defaults
@@ -310,8 +311,8 @@ send() {
 
     is_online ${smtp} ${smtp_port}
     { test $? = 0 } || {
-	error "Smtp host not reachable: $smtp_host:$smtp_port"
-	return 1 }
+    error "Smtp host not reachable: $smtp_host:$smtp_port"
+    return 1 }
 
     notice "Sending out $queue_outbox_num mails via account ${account}"
 
@@ -325,18 +326,18 @@ send() {
     port=$smtp_port
     ask_password
     { test $? = 0 } || {
-	error "Error retrieving password for $login on $smtp"
-	unset password
-	unlock "${MAILDIRS}/outbox"
-	return 1 }
+    error "Error retrieving password for $login on $smtp"
+    unset password
+    unlock "${MAILDIRS}/outbox"
+    return 1 }
 
     for qbody in ${(f)queue_outbox}; do
 
-	# check if this is an anonymous mail
-	hdr "$qbody" | grep -i '^from: anon' > /dev/null
-	if [ $? = 0 ]; then
-	    anoncfg="${TMPDIR}/${smtp}.anon.$RANDOM"
-	    cat <<EOF > "$anoncfg"
+    # check if this is an anonymous mail
+    hdr "$qbody" | grep -i '^from: anon' > /dev/null
+    if [ $? = 0 ]; then
+        anoncfg="${TMPDIR}/${smtp}.anon.$RANDOM"
+        cat <<EOF > "$anoncfg"
 REMAIL		n
 POOLSIZE	0
 SENDPOOLTIME	0m
@@ -354,19 +355,19 @@ VERBOSE=2
 
 EOF
 
-	    act "Sending out anonymous email via mixmaster"
-	    recipients=(`cat $qbody | fetchaddr -a -x to | cut -d, -f1`)
-	    recipients+=(`cat $qbody | fetchaddr -a -x cc | cut -d, -f1`)
-	    for r in ${recipients}; do
-		act "Sending to: ${r}"
+        act "Sending out anonymous email via mixmaster"
+        recipients=(`cat $qbody | fetchaddr -a -x to | cut -d, -f1`)
+        recipients+=(`cat $qbody | fetchaddr -a -x cc | cut -d, -f1`)
+        for r in ${recipients}; do
+        act "Sending to: ${r}"
 
-		# parse subject line
-		anonsubj=`hdr "$qbody" | awk '
+        # parse subject line
+        anonsubj=`hdr "$qbody" | awk '
 /^Subject: / { for(i=2;i<=NF;i++) printf "%s ", $i }'`
-		act "Subject: $anonsubj"
+        act "Subject: $anonsubj"
 
-		# strip headers and send via mixmaster
-		cat  "$qbody" | awk '
+        # strip headers and send via mixmaster
+        cat  "$qbody" | awk '
 BEGIN { head=1 }
 /^To: /           { print $0; next }
 /^Cc: /           { print $0; next }
@@ -381,26 +382,26 @@ BEGIN { head=1 }
 /^$/ { head=0 }
 { if(head==0) print $0 }
 ' | tee -a "$qbody.anon" | mixmaster --config=$anoncfg -m --to="$r" --subject="$anonsubj"
-		res=$?
-		mv "$qbody.anon" "$qbody"
-		func "mixmaster returns $res"
-	    done
+        res=$?
+        mv "$qbody.anon" "$qbody"
+        func "mixmaster returns $res"
+        done
 
-	    ${=rm} $anoncfg
+        ${=rm} $anoncfg
 
-	else # normal send with msmtp
+    else # normal send with msmtp
 
-	    act "Sending out email"
-	    hdr "$qbody" | awk '
+        act "Sending out email"
+        hdr "$qbody" | awk '
 /^From:/ { print " .  " $0 }
 /^To:/   { print " .  " $0 }
 /^Cc:/   { print " .  " $0 }
 /^Subject:/ { print " .  " $0 }
 '
 
-	    tmp="$TMPDIR/msmtp.$host.$datestamp.$RANDOM"
-	    newlock "$tmp"
-	    cat <<EOF > "$tmp"
+        tmp="$TMPDIR/msmtp.$host.$datestamp.$RANDOM"
+        newlock "$tmp"
+        cat <<EOF > "$tmp"
 account default
 from ${email}
 user ${login}
@@ -413,25 +414,25 @@ logfile "${MAILDIRS}/logs/msmtp.log"
 auth ${auth}
 password ${password}
 EOF
-	    tsize=`stat -c '%s' "$qbody"`
-	    act "sending $tsize bytes over the network ..."
-	    msmtp -C "$tmp" -t < "${qbody}"
-	    res=$?
-	    #	    unlink "$tmp"
-	    unlock "$tmp"
-	    rm -f "$tmp"
-	fi
-
-	# evaluate results
-	if [ "$res" != "0" ]; then
-	    error "Error sending mail, skipped"
-	else
-	    notice "Mail sent succesfully"
-	    # whitelist those to whom we send mails
-	    cat "$qbody" | "$WORKDIR/bin/jaro" -q learn recipient
-	    cat "$qbody" | deliver sent
-	    { test $? = 0 } && { rm "$qbody" }
-	fi
+        tsize=`stat -c '%s' "$qbody"`
+        act "sending $tsize bytes over the network ..."
+        msmtp -C "$tmp" -t < "${qbody}"
+        res=$?
+        #       unlink "$tmp"
+        unlock "$tmp"
+        rm -f "$tmp"
+    fi
+
+    # evaluate results
+    if [ "$res" != "0" ]; then
+        error "Error sending mail, skipped"
+    else
+        notice "Mail sent succesfully"
+        # whitelist those to whom we send mails
+        cat "$qbody" | "$WORKDIR/bin/jaro" -q learn recipient
+        cat "$qbody" | deliver sent
+        { test $? = 0 } && { rm "$qbody" }
+    fi
 
     done
 
@@ -447,8 +448,8 @@ EOF
 peek() {
     read_account ${account}
     { test  $? != 0 } && {
-	error "Invalid account: $account"
-	return 1
+    error "Invalid account: $account"
+    return 1
     }
 
     is_online ${imap} ${imap_port}
@@ -458,53 +459,53 @@ peek() {
 
     folder=""
     if ! [ -z ${1} ]; then
-	folder="${1}"
-	act "opening folder ${folder}"
+    folder="${1}"
+    act "opening folder ${folder}"
     fi
 
     case $transport in
-	ssl|tls) act "using secure connection (SSL)"
-	    iproto="imaps" ;;
-	plain) act "using clear text connection"
-	    iproto="imap"  ;;
-	*)
-	    error "Unknown transport: $transport"
-	    error "Configuration error in imap account ${account}"
-	    return 1 ;;
+    ssl|tls) act "using secure connection (SSL)"
+        iproto="imaps" ;;
+    plain) act "using clear text connection"
+        iproto="imap"  ;;
+    *)
+        error "Unknown transport: $transport"
+        error "Configuration error in imap account ${account}"
+        return 1 ;;
     esac
     # escape at sign in login
     ilogin=`print $login | sed 's/@/\\@/'`
 
     { test $DRYRUN != 1 } && {
 
-	type=imap
-	host=$imap
-	port=$imap_port
-	ask_password
-
-	{ test $? != 0 } && {
-	    error "Error retrieving password for $login on $imap"
-	    unset password all; return 1
-	}
-	tmp="$TMPDIR/$imap.peek.$RANDOM"
-	newlock "$tmp"
-	cat <<EOF >> "$tmp"
+    type=imap
+    host=$imap
+    port=$imap_port
+    ask_password
+
+    { test $? != 0 } && {
+        error "Error retrieving password for $login on $imap"
+        unset password all; return 1
+    }
+    tmp="$TMPDIR/$imap.peek.$RANDOM"
+    newlock "$tmp"
+    cat <<EOF >> "$tmp"
 set imap_pass = "${password}"
 # set imap_peek = yes
 EOF
-	unset password
-	print "source '$tmp'" > "$TMPDIR/muttpass"
-	# when peeking don't mark unread messages as Old
-	# and sort date received with no threading (latest up)
-	cat <<EOF >> "$TMPDIR/muttpass"
+    unset password
+    print "source '$tmp'" > "$TMPDIR/muttpass"
+    # when peeking don't mark unread messages as Old
+    # and sort date received with no threading (latest up)
+    cat <<EOF >> "$TMPDIR/muttpass"
 unset mark_old
 set sort=reverse-date-received
 EOF
-	(sleep 1;
-	    cp /dev/null "$TMPDIR/muttpass"
-	    unlink "$tmp" # secure delete in ram
-	) &
-	${=mutt} -F $MUTTDIR/rc	-f ${iproto}://${ilogin}@${imap}:${imap_port}/${folder}
+    (sleep 1;
+        cp /dev/null "$TMPDIR/muttpass"
+        unlink "$tmp" # secure delete in ram
+    ) &
+    ${=mutt} -F $MUTTDIR/rc	-f ${iproto}://${ilogin}@${imap}:${imap_port}/${folder}
 
     } # DRYRUN
     return $?
diff --git a/src/zlibs/filters b/src/zlibs/filters
@@ -55,23 +55,23 @@ init_inbox() {
     ${=mkdir} "$MAILDIRS/tmp"
 
     { test -d "$MAILDIRS/Accounts" } || {
-	${=mkdir} "$MAILDIRS/Accounts"
-	cp "$WORKDIR"/Accounts/* "$MAILDIRS/Accounts/" }
+    ${=mkdir} "$MAILDIRS/Accounts"
+    cp "$WORKDIR"/Accounts/* "$MAILDIRS/Accounts/" }
 
     { test -r "$MAILDIRS"/Manual.pdf } || {
-	cp "$WORKDIR"/jaromail-manual.pdf "$MAILDIRS"/Manual.pdf }
+    cp "$WORKDIR"/jaromail-manual.pdf "$MAILDIRS"/Manual.pdf }
 
     { test -r "$MAILDIRS"/Identity.txt } || {
-	cp "$WORKDIR"/Identity.txt "$MAILDIRS"/Identity.txt }
+    cp "$WORKDIR"/Identity.txt "$MAILDIRS"/Identity.txt }
 
     { test -r "$MAILDIRS"/Filters.txt } || {
-	cp "$WORKDIR"/Filters.txt "$MAILDIRS"/Filters.txt }
+    cp "$WORKDIR"/Filters.txt "$MAILDIRS"/Filters.txt }
 
     { test -r "$MAILDIRS"/Aliases.txt } || {
-	cp "$WORKDIR"/Aliases.txt "$MAILDIRS"/Aliases.txt }
+    cp "$WORKDIR"/Aliases.txt "$MAILDIRS"/Aliases.txt }
 
     { test -r "$MAILDIRS"/Applications.txt } || {
-	cp "$WORKDIR"/Applications.txt "$MAILDIRS"/Applications.txt }
+    cp "$WORKDIR"/Applications.txt "$MAILDIRS"/Applications.txt }
 
     return 0
 }
@@ -80,8 +80,8 @@ init_inbox() {
 # the cache consists of array and maps declarations for zsh
 update_filters() {
     { test -r "$MAILDIRS/Filters.txt" } || {
-	error "Filters not found in $MAILDIRS/Filters.txt"
-	return 1 }
+    error "Filters not found in $MAILDIRS/Filters.txt"
+    return 1 }
 
     notice "Updating filters..."
 
@@ -106,30 +106,30 @@ EOF
 
     # insert filter rules in the cache
     for f in ${(f)ffilters}; do
-	header="${f[(ws:;:)1]}"
-	regexp="${f[(ws:;:)2]}"
-	action="${f[(ws:;:)3]}"
-	destination="${f[(ws:;:)4]}"
-	case $header in
-	    to)
-		cat <<EOF >> "$ff"
+    header="${f[(ws:;:)1]}"
+    regexp="${f[(ws:;:)2]}"
+    action="${f[(ws:;:)3]}"
+    destination="${f[(ws:;:)4]}"
+    case $header in
+        to)
+        cat <<EOF >> "$ff"
 filter_to+=("${regexp}" "${destination}")
 EOF
-		func "from: <${regexp}> -> ${destination}"
-		maildirmake $MAILDIRS/$destination
-		;;
-	    from)
-		cat <<EOF >> "$ff"
+        func "from: <${regexp}> -> ${destination}"
+        maildirmake $MAILDIRS/$destination
+        ;;
+        from)
+        cat <<EOF >> "$ff"
 filter_from+=("${regexp}" "${destination}")
 EOF
-		func "to: <${regexp}> -> ${destination}"
-		maildirmake $MAILDIRS/$destination
-		;;
-
-	    *)
-		error "invalid filter: $f"
-		;;
-	esac
+        func "to: <${regexp}> -> ${destination}"
+        maildirmake $MAILDIRS/$destination
+        ;;
+
+        *)
+        error "invalid filter: $f"
+        ;;
+    esac
     done
 
     # compile the list of own addresses and aliases
@@ -138,19 +138,19 @@ EOF
 /^$/ { next }
 /^email/ { print $2 }' \
  "$MAILDIRS"/Accounts/*`; do
-	cat <<EOF >> "$ff"
+    cat <<EOF >> "$ff"
 filter_own+=($i)
 EOF
     done
     { test -r $MAILDIRS/Aliases.txt } && {
-	for i in `awk '
+    for i in `awk '
 /^#/ { next }
 /^$/ { next }
 { print $1 }' "$MAILDIRS/Aliases.txt"`; do
-	    cat <<EOF >> "$ff"
+        cat <<EOF >> "$ff"
 filter_own+=($i)
 EOF
-	done
+    done
     }
 
     unlock "$ff"
@@ -170,151 +170,151 @@ filter_maildir() {
     # be there.
     maildircheck "$MAILDIRS/unsorted"
     { test $? = 0 } || {
-	error "Invalid fallback maildir destination, operation aborted."
-	func "Returning error to caller."
-	return 1; }
+    error "Invalid fallback maildir destination, operation aborted."
+    func "Returning error to caller."
+    return 1; }
 
     # loads up the filter cache (zsh compiled arrays)
     { test -r "$MAILDIRS/cache/filters" } && {
-	source $MAILDIRS/cache/filters
-	ownfilters=1 }
+    source $MAILDIRS/cache/filters
+    ownfilters=1 }
 
     { test "$1" = "" } && { mdinput=incoming }
 
     maildircheck "$MAILDIRS/$mdinput"
     { test $? = 0 } || {
-	error "Invalid maildir to filter: $mdinput"
-	return 1; }
+    error "Invalid maildir to filter: $mdinput"
+    return 1; }
 
     numm=`${=find} "$MAILDIRS/$mdinput" -maxdepth 2 -type f|wc -l`
     mails=`${=find} "$MAILDIRS/$mdinput" -maxdepth 2 -type f`
 
     { test "$numm" = "0" } && {
-	error "Nothing to filter inside maildir $mdinput"
-	return 1 }
+    error "Nothing to filter inside maildir $mdinput"
+    return 1 }
 
     notice "Filtering maildir: $mdinput ($numm mails}"
     c=0
 
     for m in ${(f)mails}; do
-	match=0
-	c=$(($c + 1))
-
-	list="blacklist"
-	hdr "$m" | sender_isknown
-	{ test $? = 0 } && {
-	    cat "$m" | deliver zz.blacklist
-	    { test $? = 0 } && { rm "$m" }
-	    act "$c\t\t/ $numm\t\t->\tzz.blacklist"
-	    continue }
-
-	hdr "$m" | awk '/Sender.*mailman-bounce/ { exit 1 }'
-	{ test $? = 0 } || {
-	    act "$c\t\t/ $numm\t\t->\tzz.bounces"
-	    cat "$m" | deliver zz.bounces
-	    { test $? = 0 } && { rm "$m" }
-	    continue }
-
-	{ test "$ownfilters" = "1" } && {
-
-	    func "processing through own filters"
-	    ffrom=`hdr "$m" | ${WORKDIR}/bin/fetchaddr -x From -a`
-
-	    # run all filter regexps on the from: field
-	    { test "$ffrom" = "" } || {
-		femail="${ffrom[(ws:,:)1]}"
-		for exp in ${(k)filter_from}; do
-		    # special zsh parsing in PCRE (=~)
-		    if [[ "$femail" =~ "$exp" ]]; then
-			# if destination maildir is same as input, skip
-			{ test "${filter_from[$exp]}" = "$mdinput" } && {
-			    act "$c\t\t/ $numm"
-			    match=1; break }
-			act "$c\t\t/ $numm\t\t-> ${filter_from[$exp]}"
-			cat "$m" | deliver ${filter_from[$exp]}
-			if [ $? = 0 ]; then
-			    func "from filter match: $exp"
-			    match=1; rm "$m"; break
-			else
-			    error "Error filtering to maildir ${filter_from[$exp]}"
-			    error "File: $m"
-			    continue
-			fi
-		    fi
-		done
-	    }
-	    { test "$match" = "1" } && { continue }
-
-	    typeset -alU ftos
-	    # recompile the array of destination addresses
-	    ftos=(`hdr "$m" | ${WORKDIR}/bin/fetchaddr -x cc -a | cut -d, -f1`)
-	    ftos+=(`hdr "$m" | ${WORKDIR}/bin/fetchaddr -x to -a | cut -d, -f1`)
-
-	    # run all filter regexps on the to: and cc: fields
-	    { test "$ftos" = "" } || {
-		for ft in ${(f)ftos}; do
-		    for exp in ${(k)filter_to}; do
-			# special zsh parsing in PCRE (=~)
-			if [[ "$ft" =~ "$exp" ]]; then
-			    # if destination maildir is same as input, skip
-			    { test "${filter_to[$exp]}" = "$mdinput" } && {
-				act "$c\t\t/ $numm"
-				match=1; break }
-			    act "$c\t\t/ $numm\t\t-> ${filter_to[$exp]}"
-			    cat "$m" | deliver ${filter_to[$exp]}
-			    if [ $? = 0 ]; then
-				func "to filter match: $exp"
-				match=1; rm "$m"; break
-			    else
-				error "Error filtering to maildir ${filter_to[$exp]}"
-				error "File: $m"
-				continue
-			    fi
-			fi
-		    done
-		    { test "$match" = "1" } && { break }
-		done
-	    }
-
-	    { test "$match" = "1" } && { func "own filter match"; continue }
-
-	} # own filters
-
-	list="whitelist"
-	hdr "$m" | sender_isknown
-	{ test $? = 0 } && {
-	    act "$c\t\t/ $numm\t\t-> known"
-	    cat "$m" | deliver known
-	    { test $? = 0 } && { rm "$m" }
-	    continue }
-
-	hdr "$m" | awk '/X-Spam-Flag.*YES/ { exit 1 }'
-	{ test $? = 0 } || {
-	    act "$c\t\t/ $numm\t\t-> zz.spam"
-	    cat "$m" | deliver zz.spam
-	    { test $? = 0 } && { rm "$m" }
-	    continue }
-
-	# parse own email and aliases
-	match=0
-	for f in $ftos; do
-	    # check if destination address is in filter_own array
-	    if [[ ${filter_own[(r)$f]} == ${f} ]] ; then
-		act "$c\t\t/ $numm\t\t-> priv"
-		cat "$m" | deliver priv
-		{ test $? = 0 } && { rm "$m"; match=1; break }
-	    fi
-	done
-	{ test "$match" = "1" } && { continue }
-
-	# if here then file to unsorted
-	if [ "$mdinput" = "unsorted" ]; then
-	    act "$c\t\t/ $numm"
-	else
-	    act "$c\t\t/ $numm\t\t-> unsorted"
-	    cat "$m" | deliver unsorted
-	    { test $? = 0 } && { rm "$m" }
-	fi
+    match=0
+    c=$(($c + 1))
+
+    list="blacklist"
+    hdr "$m" | sender_isknown
+    { test $? = 0 } && {
+        cat "$m" | deliver zz.blacklist
+        { test $? = 0 } && { rm "$m" }
+        act "$c\t\t/ $numm\t\t->\tzz.blacklist"
+        continue }
+
+    hdr "$m" | awk '/Sender.*mailman-bounce/ { exit 1 }'
+    { test $? = 0 } || {
+        act "$c\t\t/ $numm\t\t->\tzz.bounces"
+        cat "$m" | deliver zz.bounces
+        { test $? = 0 } && { rm "$m" }
+        continue }
+
+    { test "$ownfilters" = "1" } && {
+
+        func "processing through own filters"
+        ffrom=`hdr "$m" | ${WORKDIR}/bin/fetchaddr -x From -a`
+
+        # run all filter regexps on the from: field
+        { test "$ffrom" = "" } || {
+            femail="${ffrom[(ws:,:)1]}"
+            for exp in ${(k)filter_from}; do
+                # special zsh parsing in PCRE (=~)
+                if [[ "$femail" =~ "$exp" ]]; then
+                    # if destination maildir is same as input, skip
+                    { test "${filter_from[$exp]}" = "$mdinput" } && {
+                        act "$c\t\t/ $numm"
+                        match=1; break }
+                    act "$c\t\t/ $numm\t\t-> ${filter_from[$exp]}"
+                    cat "$m" | deliver ${filter_from[$exp]}
+                    if [ $? = 0 ]; then
+                        func "from filter match: $exp"
+                        match=1; rm "$m"; break
+                    else
+                        error "Error filtering to maildir ${filter_from[$exp]}"
+                        error "File: $m"
+                        continue
+                    fi
+                fi
+            done
+        }
+        { test "$match" = "1" } && { continue }
+
+        typeset -alU ftos
+        # recompile the array of destination addresses
+        ftos=(`hdr "$m" | ${WORKDIR}/bin/fetchaddr -x cc -a | cut -d, -f1`)
+        ftos+=(`hdr "$m" | ${WORKDIR}/bin/fetchaddr -x to -a | cut -d, -f1`)
+
+        # run all filter regexps on the to: and cc: fields
+        { test "$ftos" = "" } || {
+        for ft in ${(f)ftos}; do
+            for exp in ${(k)filter_to}; do
+            # special zsh parsing in PCRE (=~)
+            if [[ "$ft" =~ "$exp" ]]; then
+                # if destination maildir is same as input, skip
+                { test "${filter_to[$exp]}" = "$mdinput" } && {
+                act "$c\t\t/ $numm"
+                match=1; break }
+                act "$c\t\t/ $numm\t\t-> ${filter_to[$exp]}"
+                cat "$m" | deliver ${filter_to[$exp]}
+                if [ $? = 0 ]; then
+                func "to filter match: $exp"
+                match=1; rm "$m"; break
+                else
+                error "Error filtering to maildir ${filter_to[$exp]}"
+                error "File: $m"
+                continue
+                fi
+            fi
+            done
+            { test "$match" = "1" } && { break }
+        done
+        }
+
+        { test "$match" = "1" } && { func "own filter match"; continue }
+
+    } # own filters
+
+    list="whitelist"
+    hdr "$m" | sender_isknown
+    { test $? = 0 } && {
+        act "$c\t\t/ $numm\t\t-> known"
+        cat "$m" | deliver known
+        { test $? = 0 } && { rm "$m" }
+        continue }
+
+    hdr "$m" | awk '/X-Spam-Flag.*YES/ { exit 1 }'
+    { test $? = 0 } || {
+        act "$c\t\t/ $numm\t\t-> zz.spam"
+        cat "$m" | deliver zz.spam
+        { test $? = 0 } && { rm "$m" }
+        continue }
+
+    # parse own email and aliases
+    match=0
+    for f in $ftos; do
+        # check if destination address is in filter_own array
+        if [[ ${filter_own[(r)$f]} == ${f} ]] ; then
+        act "$c\t\t/ $numm\t\t-> priv"
+        cat "$m" | deliver priv
+        { test $? = 0 } && { rm "$m"; match=1; break }
+        fi
+    done
+    { test "$match" = "1" } && { continue }
+
+    # if here then file to unsorted
+    if [ "$mdinput" = "unsorted" ]; then
+        act "$c\t\t/ $numm"
+    else
+        act "$c\t\t/ $numm\t\t-> unsorted"
+        cat "$m" | deliver unsorted
+        { test $? = 0 } && { rm "$m" }
+    fi
 
     done
 
@@ -387,29 +387,29 @@ EOF
 
     wwwtext=w3m
     if command -v elinks > /dev/null; then
-	cat <<EOF >> $MUTTDIR/mailcap
+    cat <<EOF >> $MUTTDIR/mailcap
 text/html; elinks -dump -dump-charset %{charset} %s; nametemplate=%s.html; copiousoutput
 EOF
     elif command -v w3m > /dev/null; then
-	cat <<EOF >> $MUTTDIR/mailcap
+    cat <<EOF >> $MUTTDIR/mailcap
 text/html; w3m -I %{charset} -T text/html %s; nametemplate=%s.html; copiousoutput
 EOF
     elif command -v lynx > /dev/null; then
-	cat <<EOF >> $MUTTDIR/mailcap
+    cat <<EOF >> $MUTTDIR/mailcap
 text/html; lynx -dump -assume_charset=%{charset} %s; nametemplate=%s.html; copiousoutput
 EOF
     fi
 
     { test -r "${MAILDIRS}/Applications.txt" } && {
 
-	# here is the tweak to open attachments
-	# with Mutt without blocking it (fork)
+    # here is the tweak to open attachments
+    # with Mutt without blocking it (fork)
 
     apptypes=`cat "${MAILDIRS}/Applications.txt"`
     for t in ${(f)apptypes}; do
-	eval `print $t | awk '
+    eval `print $t | awk '
     { print "_type=" $1 "; _app=" $2 ";" }'`
-	cat <<EOF >> $MUTTDIR/mailcap
+    cat <<EOF >> $MUTTDIR/mailcap
 ${_type}; a="${TMPDIR}" && f=\`basename %s\` && rm -f "\$a"/"\$f" && cp %s "\$a"/"\$f" && ${_app} "\$a"/"\$f"
 EOF
     done
@@ -428,9 +428,9 @@ EOF
     for f in `cat "$MAILDIRS/Filters.txt" | awk '
     /^#/ {next}
     /^./ { print $4 }'`; do
-	# MUTT (generate mailboxes priority this parser)
-	print  " \\" >> $MUTTDIR/mboxes
-	print -n " +${f} " >> $MUTTDIR/mboxes
+    # MUTT (generate mailboxes priority this parser)
+    print  " \\" >> $MUTTDIR/mboxes
+    print -n " +${f} " >> $MUTTDIR/mboxes
     done
     print " \\" >> $MUTTDIR/mboxes
     print " +unsorted.ml +unsorted" >> $MUTTDIR/mboxes
@@ -456,10 +456,10 @@ $condition [
 EOF
     c=${#sieve_filter_array}
     for i in $sieve_filter_array; do
-	print -n "\"$i\"" >> "$MAILDIRS/Filters.sieve"
-	c=$(( $c - 1 ))
-	{ test $c != 0 } && { print -n "," >> "$MAILDIRS/Filters.sieve" }
-	print >> "$MAILDIRS/Filters.sieve"
+    print -n "\"$i\"" >> "$MAILDIRS/Filters.sieve"
+    c=$(( $c - 1 ))
+    { test $c != 0 } && { print -n "," >> "$MAILDIRS/Filters.sieve" }
+    print >> "$MAILDIRS/Filters.sieve"
     done
 
     cat <<EOF >> "$MAILDIRS/Filters.sieve"
@@ -480,12 +480,12 @@ sieve_complex_filter() {
     [[ ${#sieve_filter_map} == 0 ]] && { return 1 }
     condition="$1"
     func "Sieve complex filter entries: ${#sieve_filter_map}"
-    
+
     for fil in ${(k)sieve_filter_map}; do
-	print "$condition \"${fil}\" { fileinto :create \"${sieve_filter_map[$fil]}\"; stop; }" \
-	    >> "$MAILDIRS/Filters.sieve"
+    print "$condition \"${fil}\" { fileinto :create \"${sieve_filter_map[$fil]}\"; stop; }" \
+        >> "$MAILDIRS/Filters.sieve"
     done
-    
+
     return 0
 }
 
@@ -509,17 +509,17 @@ EOF
     sieve_filter_array=()
     newlock "$TMPDIR/blacklist.sieve.$id"
     cat <<EOF | ${SQL} -batch ${addressbook} \
-	>> "$TMPDIR/blacklist.sieve.$id"
+    >> "$TMPDIR/blacklist.sieve.$id"
 SELECT email FROM blacklist;
 EOF
     for i in `cat "$TMPDIR/blacklist.sieve.$id"`; do
-	sieve_filter_array+=("$i"); done
+    sieve_filter_array+=("$i"); done
     unlink "$TMPDIR/blacklist.sieve.$id"
 
     { test "${#sieve_filter_array}" = "0" } || {
-	sieve_filter \
-	    'if header :contains "From"' \
-	    zz.blacklist
+    sieve_filter \
+        'if header :contains "From"' \
+        zz.blacklist
     }
 
     # bounces
@@ -554,19 +554,19 @@ EOF
     sieve_filter_array=()
     newlock "$TMPDIR/whitelist.sieve.$id"
     cat <<EOF | ${SQL} -batch ${addressbook} \
-	>> "$TMPDIR/whitelist.sieve.$id"
+    >> "$TMPDIR/whitelist.sieve.$id"
 SELECT email FROM whitelist;
 
 EOF
 
     for i in `cat "$TMPDIR/whitelist.sieve.$id"`; do
-	sieve_filter_array+=("$i"); done
+    sieve_filter_array+=("$i"); done
 
     unlink "$TMPDIR/whitelist.sieve.$id"
 
     sieve_filter \
-	'if header :contains "From"' \
-	INBOX
+    'if header :contains "From"' \
+    INBOX
 
     cat <<EOF >> "$MAILDIRS/Filters.sieve"
 # spam
@@ -579,8 +579,8 @@ EOF
     # own addresses and aliases
     sieve_filter_array=($filter_own)
     sieve_filter \
-	'if header :contains [ "To","Cc" ] ' \
-	priv
+    'if header :contains [ "To","Cc" ] ' \
+    priv
 
     # unsorted
     cat <<EOF >> "$MAILDIRS/Filters.sieve"
diff --git a/src/zlibs/helpers b/src/zlibs/helpers
@@ -27,6 +27,23 @@
 # which mutt binary to use
 mutt="mutt"
 
+# extract all emails found in a text from stdin
+# outputs them one per line
+extract_emails() {
+awk '{ for (i=1;i<=NF;i++)
+     if ( $i ~ /[[:alnum:]]@[[:alnum:]]/ ) {
+       gsub(/<|>|,/ , "" , $i); print $i } }'
+}
+
+# parses stdin and converts some characters to html
+escape_html() {
+    sed -e '
+s/\&/\&/g
+s/>/\>/g
+s/</\</g
+s/"/\"/g
+'
+}
 
 
 autostart() {
@@ -34,44 +51,44 @@ autostart() {
 # no argument passed. open first folder with new mail
     { test -z ${1} } && {
 
-	{ test ! -r $MUTTDIR/rc } \
-	    && { error "Jaro Mail is not yet configured."
-		 error "To configure, edit the files in $MAILDIRS/Accounts"
-		 return 1 }
+    { test ! -r $MUTTDIR/rc } \
+        && { error "Jaro Mail is not yet configured."
+         error "To configure, edit the files in $MAILDIRS/Accounts"
+         return 1 }
 
-	${=mutt} -F $MUTTDIR/rc ${=muttflags} -Z
-	return $?
+    ${=mutt} -F $MUTTDIR/rc ${=muttflags} -Z
+    return $?
     }
 
     # argument passed: determine if an email
     print "${1}" \
-	| tr 'A-Z' 'a-z' \
-	| grep '^[a-zA-Z0-9._%+-]*@[a-zA-Z0-9]*[\.[a-zA-Z0-9]*]*[a-zA-Z0-9]$' \
-	> /dev/null
+    | tr 'A-Z' 'a-z' \
+    | grep '^[a-zA-Z0-9._%+-]*@[a-zA-Z0-9]*[\.[a-zA-Z0-9]*]*[a-zA-Z0-9]$' \
+    > /dev/null
     { test $? = 0 } && {
-	notice "Composing message to: ${@}"
-	# its an email, TODO see if we have it in our addressbook
-	${=mutt} -F $MUTTDIR/rc ${=muttflags} ${=@}
-	return 0
+    notice "Composing message to: ${@}"
+    # its an email, TODO see if we have it in our addressbook
+    ${=mutt} -F $MUTTDIR/rc ${=muttflags} ${=@}
+    return 0
     }
 
     # or a directory of file
     { test -r "$1" } && {
-	# is it a maildir? then open
-	{ maildircheck ${1} } && {
-	    ${=mutt} -F $MUTTDIR/rc ${=muttflags} -f ${1}
-	    return 0 }
-	# is it a regular file? then attach it
-	{ test -f "$1" } && {
-	    ${=mutt} -F $MUTTDIR/rc ${=muttflags} -a ${=@}
-	    return 0 }
+    # is it a maildir? then open
+    { maildircheck ${1} } && {
+        ${=mutt} -F $MUTTDIR/rc ${=muttflags} -f ${1}
+        return 0 }
+    # is it a regular file? then attach it
+    { test -f "$1" } && {
+        ${=mutt} -F $MUTTDIR/rc ${=muttflags} -a ${=@}
+        return 0 }
     }
 
     # or the name of a folder in Jaro Mail
     { maildircheck "$MAILDIRS/$1" } && {
-	notice "Opening folder ${1}"
-	${=mutt} -F $MUTTDIR/rc ${=muttflags} -f "$MAILDIRS/${1}"
-	return 0
+    notice "Opening folder ${1}"
+    ${=mutt} -F $MUTTDIR/rc ${=muttflags} -f "$MAILDIRS/${1}"
+    return 0
     }
 
     return $?
@@ -81,8 +98,8 @@ autostart() {
 # short utility to print only mail headers
 hdr() {
     { test -r "$1" } || {
-	error "hdr() called on non existing file: $1"
-	return 1 }
+        error "hdr() called on non existing file: $1"
+        return 1 }
     awk '{ print $0 }
 /^$/ { exit }' "$1"
 }
@@ -90,8 +107,8 @@ hdr() {
 # short utility to print only mail body
 body() {
     { test -r "$1" } || {
-	error "body() called on non existing file: $1"
-	return 1 }
+    error "body() called on non existing file: $1"
+    return 1 }
     awk '
 BEGIN { head=1 }
 /^$/ { head=0 }
@@ -109,7 +126,7 @@ BEGIN { head=1 }
 # however the default is nano if nothing else is choosen.
 jarovim() {
     vim -c 'set fo=tcrq' -c 'set tw=72' \
-	-c 'map <C-j> {gq}' -c 'imap <C-j> <esc>{gq}i' \
+    -c 'map <C-j> {gq}' -c 'imap <C-j> <esc>{gq}i' \
         "${@}"
     return $?
 }
@@ -119,27 +136,27 @@ edit_file() {
     { test ${JARO_EDITOR} } && { _editor="$JARO_EDITOR" }
     { test "$_editor" = "" } && { _editor=vim }
     case $_editor in
-	# refine settings for email
-	vi|vim) jarovim "${PARAM}"; return $? ;;
-	emacs) emacsclient -a emacs "${PARAM}"; return $? ;;
-	*) ${=_editor} "${PARAM}"; return $? ;;
+    # refine settings for email
+    vi|vim) jarovim "${PARAM}"; return $? ;;
+    emacs) emacsclient -a emacs "${PARAM}"; return $? ;;
+    *) ${=_editor} "${PARAM}"; return $? ;;
     esac
 
     # if we are here we need to guess
     case $OS in
-	MAC) open -t ${=PARAM} ;;
-	GNU)
-	    ps ax|grep '[e]macs' > /dev/null
-	    if [ $? = 0 ]; then
-		emacsclient -a ${=PARAM}
-	    elif command -v vim > /dev/null; then
-		jarovim ${=PARAM}
-	    elif command -v nano > /dev/null; then
-		nano -m -S -Q ">" -I -E -D -T 4 -U -W -c -i -k -r 72 ${=PARAM}
-	    else
-		error "No editor found, please configure the JARO_EDITOR environment variable."
-	    fi
-	    ;;
+    MAC) open -t ${=PARAM} ;;
+    GNU)
+        ps ax|grep '[e]macs' > /dev/null
+        if [ $? = 0 ]; then
+        emacsclient -a ${=PARAM}
+        elif command -v vim > /dev/null; then
+        jarovim ${=PARAM}
+        elif command -v nano > /dev/null; then
+        nano -m -S -Q ">" -I -E -D -T 4 -U -W -c -i -k -r 72 ${=PARAM}
+        else
+        error "No editor found, please configure the JARO_EDITOR environment variable."
+        fi
+        ;;
     esac
     return $?
 }
@@ -149,8 +166,8 @@ edit_file() {
 open_folder() {
     notice "Opening folder ${1}"
     { maildircheck ${MAILDIRS}/${1} } && {
-	${=mutt} -F $MUTTDIR/rc ${=muttflags} -f "$MAILDIRS/${1}"
-	return $? }
+    ${=mutt} -F $MUTTDIR/rc ${=muttflags} -f "$MAILDIRS/${1}"
+    return $? }
     return 1
 }
 
@@ -158,12 +175,12 @@ open_folder() {
 ## Open a File
 preview_file() {
     case $OS in
-	GNU)
-	    xdg-open "${PARAM}" &
-	    ;;
-	MAC)
-	    open -g "${PARAM}"
-	    ;;
+    GNU)
+        xdg-open "${PARAM}" &
+        ;;
+    MAC)
+        open -g "${PARAM}"
+        ;;
     esac
 }
 
@@ -173,8 +190,8 @@ preview_file() {
 is_online() {
     func "Test if we are online"
     { test "$FORCE" = "1" } && {
-	act "Internet check skipped (--force in use)"
-	return 0
+    act "Internet check skipped (--force in use)"
+    return 0
     }
     _res=1
     _host=${1:-8.8.8.8}
@@ -182,95 +199,95 @@ is_online() {
 
     _mode=inet # or host
     { test "$_port" = "NONE" } || { _mode=host }
-    
+
     case $_mode in
-	inet)
-	    func "trying to ping ${_host}"
-	    ping -c1 -n ${_host} 2>&1 > /dev/null
-	    { test $? = 0 } || {
-		error "Internet seems unreachable"
-		act "Network connection is checked with a ping to 8.8.8.8"
-		act "if your network doesn't allows it to pass, use -f to force."
-		error "Operation aborted."
-		exit 1
-	    }
-	    act "Internet seems to be reachable"
-	    ;;
-	host)
-	    func "trying to connect ${_host} port ${_port}"
-	    nc -w 16 -z ${_host} ${_port} > /dev/null
-	    { test $? = 0 } || {
-		error "Host unreachable: $_host"
-		act "Network connection is checked with 16s timeout"
-		act "if you want to bypass this check, use -f to force."
-		error "Operation aborted."
-		return 1
-	    }
-	    act "Host $_host responds on port $_port"
-	    ;;
+    inet)
+        func "trying to ping ${_host}"
+        ping -c1 -n ${_host} 2>&1 > /dev/null
+        { test $? = 0 } || {
+        error "Internet seems unreachable"
+        act "Network connection is checked with a ping to 8.8.8.8"
+        act "if your network doesn't allows it to pass, use -f to force."
+        error "Operation aborted."
+        exit 1
+        }
+        act "Internet seems to be reachable"
+        ;;
+    host)
+        func "trying to connect ${_host} port ${_port}"
+        nc -w 16 -z ${_host} ${_port} > /dev/null
+        { test $? = 0 } || {
+        error "Host unreachable: $_host"
+        act "Network connection is checked with 16s timeout"
+        act "if you want to bypass this check, use -f to force."
+        error "Operation aborted."
+        return 1
+        }
+        act "Host $_host responds on port $_port"
+        ;;
     esac
     return 0
 }
-    
+
 
 # opens and closes a ramdisk for temporary files
 # users can do this explicitly between session to speed up operations
 ramdisk() {
     case $OS in
-	GNU)
-	    # TODO
-	    # not so urgent, since usually /dev/shm is mounted and writable
-	    ;;
-	MAC)
-	    case ${PARAM[1]} in
-		open)
-		    mount | grep 'JaroTmp' > /dev/null
-		    { test $? = 0 } && {
-			error "A Jaro Mail ramdisk is already open"
-			return 1 }
-		    { test -z ${PARAM[2]} } && { size=10 } || { size=${PARAM[2]} }
-		    act "Creating ramdisk of ${size}MB"
-
-		    # 2048 is a megabyte here
-		    devsize=$((1024*2*$size))
-		    devname=`hdid -nomount ram://${devsize}`
-		    act "Mounting ramdisk on $devname"
-		    diskutil eraseVolume HFS+ JaroTmp `basename $devname` > /dev/null
-		    { test $? != 0 } && {
-			error "Error initializing ramdisk"
-			hdiutil detach `basename $devname`
-			return 1 }
-		    notice "Operation successful, ramdisk ready on /Volume/JaroTmp"
-		    TMPRAM=1
-		    ;;
-		close)
-		    devname=`mount | awk '/JaroTmp/ {print $1}'`
-		    { test "$devname" = "" } && {
-			error "No ramdisk seems to be open"
-			return 1 }
-		    act "Unmounting ramdisk: $devname"
-		    diskutil unmount /Volumes/JaroTmp > /dev/null
-		    hdiutil detach `basename $devname` > /dev/null
-		    notice "Ramdisk succesfully detached"
-		    TMPRAM=0
-		    ;;
-	    esac
-	    ;;
+    GNU)
+        # TODO
+        # not so urgent, since usually /dev/shm is mounted and writable
+        ;;
+    MAC)
+        case ${PARAM[1]} in
+        open)
+            mount | grep 'JaroTmp' > /dev/null
+            { test $? = 0 } && {
+            error "A Jaro Mail ramdisk is already open"
+            return 1 }
+            { test -z ${PARAM[2]} } && { size=10 } || { size=${PARAM[2]} }
+            act "Creating ramdisk of ${size}MB"
+
+            # 2048 is a megabyte here
+            devsize=$((1024*2*$size))
+            devname=`hdid -nomount ram://${devsize}`
+            act "Mounting ramdisk on $devname"
+            diskutil eraseVolume HFS+ JaroTmp `basename $devname` > /dev/null
+            { test $? != 0 } && {
+            error "Error initializing ramdisk"
+            hdiutil detach `basename $devname`
+            return 1 }
+            notice "Operation successful, ramdisk ready on /Volume/JaroTmp"
+            TMPRAM=1
+            ;;
+        close)
+            devname=`mount | awk '/JaroTmp/ {print $1}'`
+            { test "$devname" = "" } && {
+            error "No ramdisk seems to be open"
+            return 1 }
+            act "Unmounting ramdisk: $devname"
+            diskutil unmount /Volumes/JaroTmp > /dev/null
+            hdiutil detach `basename $devname` > /dev/null
+            notice "Ramdisk succesfully detached"
+            TMPRAM=0
+            ;;
+        esac
+        ;;
     esac
 }
 
 human_size() {
     { test $1 -gt 0 } || {
-	error "human_size() called with zero argument"
-	return 1 }
+    error "human_size() called with zero argument"
+    return 1 }
     # megabytes
     { test $1 -gt 1048576 } && {
-	print -n "$(( $1 / 1024 / 1024 )) MB"
-	return 0}
+    print -n "$(( $1 / 1024 / 1024 )) MB"
+    return 0}
     # kilobytes
     { test $1 -gt 1024 } && {
-	print -n "$(( $1 / 1024 )) KB"
-	return 0}
+    print -n "$(( $1 / 1024 )) KB"
+    return 0}
     # bytes
     print -n "$1 Bytes"
     return 0
@@ -287,40 +304,40 @@ cert() {
     cc=Equifax_Secure_Certificate_Authority
     if ! [ -r $MAILDIRS/certs/${cc}.pem ]; then
 
-	curl -o $MAILDIRS/certs/${cc}.pem \
-	    "https://www.geotrust.com/resources/root_certificates/certificates/${cc}.cer"
-	openssl x509 -in \
-	    $MAILDIRS/certs/${cc}.pem -fingerprint \
-	    -subject -issuer -serial -hash -noout
+    curl -o $MAILDIRS/certs/${cc}.pem \
+        "https://www.geotrust.com/resources/root_certificates/certificates/${cc}.cer"
+    openssl x509 -in \
+        $MAILDIRS/certs/${cc}.pem -fingerprint \
+        -subject -issuer -serial -hash -noout
     fi
     notice "Google CA succesfully installed"
 
 #	dyne|autistici|freaknet)
     cc=Autistici_Certificate_Authority
     if ! [ -r $MAILDIRS/certs/${cc}.pem ]; then
-	curl -o $MAILDIRS/certs/${cc}.pem \
-	    "http://ca.autistici.org/ca.pem"
-	openssl x509 -in \
-	    $MAILDIRS/certs/${cc}.pem \
-	    -fingerprint -subject -issuer -serial -hash -noout
+    curl -o $MAILDIRS/certs/${cc}.pem \
+        "http://ca.autistici.org/ca.pem"
+    openssl x509 -in \
+        $MAILDIRS/certs/${cc}.pem \
+        -fingerprint -subject -issuer -serial -hash -noout
     fi
     notice "Aut/Inv CA succesfully installed"
 
 #	riseup)
     cc=RiseupCA
     if ! [ -r $MAILDIRS/certs/${cc}.pem ]; then
-	curl -o $MAILDIRS/certs/${cc}.pem "https://help.riseup.net/assets/43052/RiseupCA.pem"
-	openssl x509 -in \
-	    $MAILDIRS/certs/${cc}.pem \
-	    -fingerprint -subject -issuer -serial -hash -noout
+    curl -o $MAILDIRS/certs/${cc}.pem "https://help.riseup.net/assets/43052/RiseupCA.pem"
+    openssl x509 -in \
+        $MAILDIRS/certs/${cc}.pem \
+        -fingerprint -subject -issuer -serial -hash -noout
     fi
     notice "Riseup CA succesfully installed"
 
     act "refreshing certificates"
     c_rehash $MAILDIRS/certs > /dev/null
     if [ $? != 0 ]; then
-	error "Error refreshing certificates in $MAILDIRS/certs"
-	c_rehash $MAILDIRS/certs
+    error "Error refreshing certificates in $MAILDIRS/certs"
+    c_rehash $MAILDIRS/certs
     fi
     notice "Done importing most common certificates."
     return 0