commit 1ef2e876c146f857430f43589399f8d3a65faea1
parent 1c96a2c33cec3aa3b5face8314f2f771db7f3203
Author: Jaromil <jaromil@dyne.org>
Date:   Mon,  9 Nov 2015 12:09:20 +0100
Fixes to sslproto selection in fetchmail
and more cleanups affecting fetch, search and locking
Diffstat:
9 files changed, 92 insertions(+), 53 deletions(-)
diff --git a/doc/Accounts/default.txt b/doc/Accounts/default.txt
@@ -33,9 +33,13 @@ auth plain # or kerberos, etc
 # Server certificate: check or ignore
 cert ignore
 
-# Transport protocol: ssl, tls or plain
-transport tls
+# Possible values are '', 'SSL2' (not supported on all systems),
+# 'SSL23', (use of these two values is discouraged and should only
+# be used as a last resort) 'SSL3', and 'TLS1' (default).
+# transport TLS1
 
+# Add a specific certificate file, checked before installed defaults
+# certfile /path/to/my/private/cert
 
 # Options when fetching
 # to empty your mailbox you can use: fetchall flush
diff --git a/doc/jaromail-manual.org b/doc/jaromail-manual.org
@@ -845,6 +845,10 @@ If filters are updated or one desires to import a maildir into Jaro
 Mail processing it through its filters, the *filter* command is
 provided to (re)filter a maildir. First edit *Filters.txt* with matches for the to: (which includes cc:) and from: header fields, then run:
 
+: jaro update
+
+To tell Jaro Mail to update its internal filters according to the modifications, and then:
+
 : jaro filter my-old-maildir
 
 Beware that filtering is a lengthy operation, especially on big
diff --git a/src/jaro b/src/jaro
@@ -91,7 +91,7 @@ esac
 
 
 # global variables
-vars+=(DEBUG QUIET DRYRUN CALLMUTT MAILDIRS)
+vars+=(DEBUG QUIET DRYRUN CALLMUTT MAILDIRS WORKDIR)
 QUIET=${QUIET:-0}
 DEBUG=${DEBUG:-0}
 DRYRUN=${DRYRUN:-0}
@@ -646,8 +646,10 @@ main() {
 
     fetch)
             account=${account:-default}
-            fetch ${PARAM}
-            filter_maildir incoming
+            fetch ${PARAM} && \
+                update_filters && \
+                filter_maildir incoming && \
+                update_notmuch
         ;;
 
     send)   send ${PARAM}
@@ -675,14 +677,11 @@ main() {
                 [[ -d $p ]] && MAILDIRS=$p
             done
         }
-        MAILDIRS=$MAILDIRS init_inbox
-        MAILDIRS=$MAILDIRS update_filters
-        MAILDIRS=$MAILDIRS update_mutt
-        MAILDIRS=$MAILDIRS update_sieve
-        isfound notmuch && {
-            MAILDIRS=$MAILDIRS nm_setup
-            MAILDIRS=$MAILDIRS nm new 2>&1 | grep -v '^Note: Ignoring'
-        }
+        init_inbox
+        update_filters
+        update_mutt
+        update_sieve
+        update_notmuch
         notice "Initialization completed in $MAILDIRS"
         act "configure accounts in $MAILDIRS/Accounts"
         ;;
diff --git a/src/zlibs/accounts b/src/zlibs/accounts
@@ -57,6 +57,7 @@ read_account() {
     /^port / { printf "port=\"%s\";", $2 }
     /^login/ { printf "login=\"%s\";", $2 }
     /^transport/ { printf "transport=\"%s\";", $2 }
+    /^certfile/ { printf "certfile=\"%s\";", $2 }
     /^imap_port/ { printf "imap_port=\"%s\";", $2 }
     /^smtp_port/ { printf "smtp_port=\"%s\";", $2 }
     /^auth/ { printf "auth=\"%s\";", $2 }
@@ -84,7 +85,8 @@ read_account() {
     { test -z $name }       && { name="$type" }
     { test -z $login }      && { login="$email" } # usually email and login are the same
     { test -z $email }      && { email="$login" } # so if one is specified, deduce the other
-    { test -z $transport }  && { transport=plain }
+    { test -z $transport }  && { transport=TLS1 }
+    { test -z $certfile }   && { certfile="" }
     { test -z $imap_port }  && { imap_port=143 }
     { test -z $smtp_port }  && { smtp_port=25 }
 
@@ -106,6 +108,7 @@ read_account() {
     func "smtp port: $smtp_port"
 
     func "trans: $transport"
+    func "certfile: $certfile"
     func "cert: $cert"
     func "auth: $auth"
     [[ "$password" = "" ]] || func "password: manually set"
diff --git a/src/zlibs/email b/src/zlibs/email
@@ -247,26 +247,27 @@ fetch() {
 
     fi
 
-    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+=(" sslproto ${transport} warnings 3600 and wants mda \"jaro -q deliver\" ")
+
 
     fmconf+=(" antispam 571 550 501 554 ")
 
     [[ $accountopt =~ 'keep' ]] || {
-        error "planning to delete mails from server, account option: $accountopt" }
+        warning "planning to delete mails from server, account option: $accountopt" }
+
+    func "fetch folders: $folders"
+
+    # add folder configuration
+    fmconf+=(" folder ${=folders} ");
 
     # try login without doing anything
-    print "$fmconf" | fetchmail -c -f -
+    flog=("${(f)$(print "$fmconf" | fetchmail -v -c -f -)}")
+
     res=$?
     # examine result
     case $res in
@@ -285,8 +286,10 @@ fetch() {
             unset $fmconf
             return 1
             ;;
+        7)  warning "Mailbox selection failed (${flog[${#flog}]#*\(}"
+            ;;
         *)
-            func "fetchmail returns $ret" ;;
+            func "fetchmail returns $res" ;;
     esac
 
     if [[ $DRYRUN = 0 ]]; then
diff --git a/src/zlibs/filters b/src/zlibs/filters
@@ -95,7 +95,7 @@ update_filters() {
 
     [[ -r "$ff" ]] && { rm -f "$ff" }
     newlock "$ff"
-    sysread -o 1 <<EOF >> "$ff"
+    cat <<EOF >> "$ff"
 # automatically generated by jaromail
 typeset -Al  filter_from
 typeset -alU filter_own
@@ -109,7 +109,9 @@ EOF
     /^#/ {next}
     /^./ { print $1 ";" $2 ";" $3 ";" $4 }' "$MAILDIRS/Filters.txt"`
 
-    # insert filter rules in the cache
+    #
+    func "insert filter rules in the cache"
+
     for f in ${(f)ffilters}; do
         header="${f[(ws:;:)1]}"
         regexp="${f[(ws:;:)2]}"
@@ -117,14 +119,14 @@ EOF
         destination="${f[(ws:;:)4]}"
         case $header in
             to)
-                sysread -o 1 <<EOF >> "$ff"
+                cat <<EOF >> "$ff"
 filter_to+=("${regexp}" "${destination}")
 EOF
                 func "from: <${regexp}> -> ${destination}"
                 maildirmake $MAILDIRS/$destination
                 ;;
             from)
-                sysread -o 1 <<EOF >> "$ff"
+                cat <<EOF >> "$ff"
 filter_from+=("${regexp}" "${destination}")
 EOF
                 func "to: <${regexp}> -> ${destination}"
@@ -144,13 +146,15 @@ EOF
     #     nm new
     # }
 
-    # compile the list of own addresses and aliases
+    #
+    func "compile the list of own addresses and aliases"
+
     for i in `awk '
 /^#/ { next }
 /^$/ { next }
 /^email/ { print $2 }' \
  "$MAILDIRS"/Accounts/*`; do
-        sysread -o 1 <<EOF >> "$ff"
+        cat <<EOF >> "$ff"
 filter_own+=($i)
 EOF
     done
@@ -159,15 +163,18 @@ EOF
 /^#/ { next }
 /^$/ { next }
 { print $1 }' "$MAILDIRS/Aliases.txt"`; do
-            sysread -o 1 <<EOF >> "$ff"
+            cat <<EOF >> "$ff"
 filter_own+=($i)
 EOF
         done
     }
 
+    #
+    func "unlocking and compiling the cache"
+
     unlock "$ff"
     zcompile "$ff"
-    # recursive reload
+    func "recursive reload"
     source "$WORKDIR/zlibs/filters"
     return 0
 }
@@ -175,8 +182,8 @@ EOF
 
 filter_maildir() {
     fn filter_maildir
-    req=(MAILDIR)
-    ckreq
+    req=(MAILDIRS)
+    ckreq || return 1
 
     # Makes glob matching case insensitive
     unsetopt CASE_MATCH
@@ -528,7 +535,7 @@ EOF
     [[ "$gpgkey" = "" ]] || {
         # gpg special settings
 
-        sysread -o 1 <<EOF >> "$MAILDIRS/.mutt"/rc
+        cat <<EOF >> "$MAILDIRS/.mutt"/rc
 ## GnuPG specific settings
 # create a pgp/mime encrypted attachment
 set pgp_encrypt_only_command="gpgewrap gpg --batch --quiet --no-verbose --output - --encrypt --textmode --armor --always-trust --encrypt-to $gpgkey -- -r %r -- '%f'"
@@ -542,7 +549,7 @@ EOF
     }
 
     # MUTT MAILCAP
-    sysread -o 1 <<EOF > $MAILDIRS/.mutt/mailcap
+    cat <<EOF > $MAILDIRS/.mutt/mailcap
 text/plain; iconv -f iso-8859-1 -t utf-8; test=charset=%{charset} \
   && test x`echo \"$charset\" | tr a-z A-Z` = xISO-8859-1; copiousoutput
 text/plain; cat %s
diff --git a/src/zlibs/imap b/src/zlibs/imap
@@ -21,17 +21,23 @@
 # Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
 run_imap_query() {
-    if [ "$transport" = "plain" ]; then
+    fn run_imap_query
+    _trans=${transport:-plain}
+    case $_trans in
+        SSL*) _trans=ssl ;;
+        TLS*) _trans=tls ;;
+    esac
+    if [ "$_trans" = "plain" ]; then
 	    func "running plain imap query via netcat, no encryption"
 	    nc ${imap} ${imap_port} -q 10 2>&1
-    elif [ "$transport" = "tls" ]; then
+    elif [ "$_trans" = "tls" ]; then
         func "running tls imap query via openssl, encrypted"
 	    openssl s_client -quiet -connect ${imap}:${imap_port} 2>&1 
-    elif [ "$transport" = "ssl" ]; then
+    elif [ "$_trans" = "ssl" ]; then
 	    func "running ssl imap query via openssl, encrypted"
 	    openssl s_client -starttls imap -quiet -connect ${imap}:${imap_port} 2>&1 
     else
-        error "unknown transport \"$transport\" for a imap query"
+        error "unknown transport \"$_trans\" for a imap query"
     fi
 }
 
diff --git a/src/zlibs/locking b/src/zlibs/locking
@@ -22,11 +22,12 @@
 
 
 lock() {
-    fn "lock $@"
+    fn "lock $*"
     _file=$1
-    req=(_file)
-    freq=($_file)
-    ckreq || return 1
+    # can't use ckreq as that returns error on file empty
+    [[ -r "$_file" ]] || {
+        error "cannot unlock, file not existing: $_file"
+        return 1 }
 
     if helper.isfound dotlock; then
         dotlock=`command -v dotlock`
@@ -56,10 +57,8 @@ lock() {
 }
 
 newlock() { # lock file, create if not existing
-    fn "newlock $@"
+    fn "newlock $*"
     _file="$1"
-    req=(_file)
-    ckreq || return 1
 
     touch "$_file"
     chmod 600 "$_file"
@@ -112,11 +111,13 @@ pidcheck() { # check if lock belongs to us
 }
 
 unlock() {
-    fn "unlock $@"
+    fn "unlock $*"
     _file="$1"
-    req=(_file)
-    ckreq || return 1
-    
+    # can't use ckreq as that returns error on file empty
+    [[ -r "$_file" ]] || {
+        error "cannot unlock, file not existing: $_file"
+        return 1 }
+
     pidcheck "$_file"
     [[ $? = 0 ]] || { return 1 }
     
@@ -130,9 +131,12 @@ unlock() {
 }
 
 unlink() { # delete a file that we are locking
-    fn "unlink $@"
+    fn "unlink $*"
     _file="$1"
-    ckreq || return 1
+    # can't use ckreq as that returns error on file empty
+    [[ -r "$_file" ]] || {
+        error "cannot unlock, file not existing: $_file"
+        return 1 }
 
     unlock "$_file"
     ${=rm} "$_file"
diff --git a/src/zlibs/search b/src/zlibs/search
@@ -104,6 +104,15 @@ nm_index() {
     notice "Indexing completed"
 }
 
+update_notmuch() {
+    fn update_notmuch
+
+    isfound notmuch && [[ -r $MAILDIRS/.notmuch/xapian ]] && {
+        notice "Updating notmuch indexes"
+        nm_setup
+        nm new 2>&1 | grep -v '^Note: Ignoring'
+    }
+}
 
 search() {
     fn search ${=PARAM}