commit 7e9e5143b6d13d01ddb7b34d97526fc2f1ff4573
parent 1419876b085267fea58021d8007c9f452d4e7d28
Author: Jaromil <jaromil@dyne.org>
Date: Thu, 28 Jun 2012 18:43:15 +0200
new native imap folder examination using openssl
Diffstat:
5 files changed, 149 insertions(+), 17 deletions(-)
diff --git a/src/jaro b/src/jaro
@@ -67,6 +67,12 @@ typeset -al maildirs
typeset exitcode
exitcode=0
+# global variable for infos on imap folder
+# format: name;num_of_messages;size_in_bytes
+# last entry is grand_total_in_bytes ${imap_info[${#imap_info}]}
+typeset -alU imap_info
+
+
autoload colors; colors
# standard output message routines
@@ -145,8 +151,7 @@ case $OS in
touch /dev/shm/jaromail.test.tmp > /dev/null
{ test $? = 0 } && {
# we can use volatile ram
- rm -f /dev/shm/jaromail.test.tmp
- TMPDIR=/dev/shm/jaromail.$USER
+ TMPDIR=/dev/shm/tmp.jaromail.$USER
TMPRAM=1
}
;;
diff --git a/src/zlibs/accounts b/src/zlibs/accounts
@@ -53,7 +53,8 @@ list_accounts() {
# -a defines which account name other than 'default'
read_account() {
typeset -al all
-
+ unset name email host login transport \
+ port auth cert options folders
# parse arguments
{ test "$1" != "" } && { account=$1 }
@@ -67,8 +68,7 @@ read_account() {
error "No account type specified"
act "Available accounts (excluding symbolic links, omit final .txt):"
list_accounts
- return 1
- }
+ return 1 }
{ test "$account" = "" } && { account=default }
# find the file
@@ -107,7 +107,6 @@ read_account() {
/^login/ { printf "login=\"%s\";", $2 }
/^transport/ { printf "transport=\"%s\";", $2 }
/^port/ { printf "port=\"%s\";", $2 }
- /^password/ { printf "password=\"%s\";", $2 }
/^auth/ { printf "auth=\"%s\";", $2 }
/^cert/ { printf "cert=\"%s\";", $2 }
/^options/ { printf "accountopt=\""; for(i=2;i<=NF;i++) printf "%s ", $i; printf "\";" }
diff --git a/src/zlibs/email b/src/zlibs/email
@@ -98,8 +98,32 @@ fetch() {
{ test $DRYRUN != 1 } && { update }
fi
- notice "Fetching mails for $name"
+ notice "Examining mailbox for $name <$email> on $host"
+
+ # check if its online
+ timeout 2 netcat -z ${host} ${port} > /dev/null
+ { test $? = 0 } || {
+ error "server is off-line or unreachable, skipped"
+ return 1 }
+
+ ask_password $login $host
+
+
+ # skip getting size if Gmail
+ # (imap there lacks support for RFC822.SIZE)
+# { test "$host" != "imap.gmail.com" } && {
+ get_imap_info
+ { test ${imap_info[${#imap_info}]} = 0 } && {
+ # imap account is empty
+ return 0 }
+ notice "Total occupation is `human_size ${imap_info[${#imap_info}]}`"
+# }
+ # this puts total size in $imap_info
+
{ test $DRYRUN != 1 } && {
+
+ { test ${imap_info[${#imap_info}]} -eq 0 } && { return 0 }
+
ask_password $login $host
{ test $? != 0 } && {
error "Error retrieving password for $login on $host"
@@ -112,13 +136,13 @@ fetch() {
poll $host with proto IMAP user "$login" there with password "$password"
EOF
unset password
-
+
if ! [ -z $accountopt ]; then # add option configuration
echo "${accountopt}" >> $tmp; fi
-
+
if ! [ -z $folders ]; then # add folder configuration
echo "folder ${folders}" >> $tmp; fi
-
+
cat <<EOF >> $tmp
ssl warnings 3600 and wants mda "procmail -m $PROCMAILDIR/rc"
EOF
@@ -130,7 +154,7 @@ EOF
cat <<EOF >> $tmp
antispam 571 550 501 554
EOF
-
+
# try login without doing anything
fetchmail -c -f $tmp
# examine result
@@ -152,7 +176,7 @@ EOF
;;
*) ;;
esac
-
+
# archive old procmail log
if [ -r $WORKDIR/log/procmail.log ]; then
newlock $WORKDIR/log/procmail-${datestamp}.log
@@ -162,13 +186,13 @@ EOF
unlock $WORKDIR/log/procmail-${datestamp}.log
fi
act "please wait while downloading mails..."
-
+
cat $tmp | fetchmail -f $tmp
# TODO: substitute this with cat conf | fetchmail -f -
# to avoid writing the password in clear on filesystem
-
+
unlink $tmp
-
+
total=`mailstat -k $WORKDIR/log/procmail.log | tail -n1 | awk '{print $2}'`
briefing=`mailstat -kt $WORKDIR/log/procmail.log |awk '!/procmail/ { print " " $2 "\t" $3 }'|sort -nr`
notice "$total emails fetched"
@@ -213,7 +237,7 @@ send() {
error "Error retrieving password for $login on $host"
unset password all; return 1
}
-
+
tmp=$TMPDIR/$host.send.$RANDOM
newlock $tmp
cat <<EOF > $tmp
@@ -230,7 +254,7 @@ auth ${auth}
password ${password}
EOF
unset password
-
+
for mail in `find $MAILDIRS/outbox -name "*.mail"`; do
smtp=`echo ${mail} | sed -e 's/mail/msmtp/'`
lock ${smtp}
diff --git a/src/zlibs/helpers b/src/zlibs/helpers
@@ -146,6 +146,22 @@ ramdisk() {
esac
}
+human_size() {
+ { test $1 -gt 0 } || {
+ error "human_size() called with zero argument"
+ return 1 }
+ # megabytes
+ { test $1 -gt 1048576 } && {
+ print -n "$(( $1 / 1024 / 1024 )) MB"
+ return 0}
+ # kilobytes
+ { test $1 -gt 1024 } && {
+ print -n "$(( $1 / 1024 )) KB"
+ return 0}
+ # bytes
+ print -n "$1 Bytes"
+ return 0
+}
######
# CERT
diff --git a/src/zlibs/imap b/src/zlibs/imap
@@ -0,0 +1,87 @@
+#!/usr/bin/env zsh
+#
+# Jaro Mail, your humble and faithful electronic postman
+#
+# a tool to easily and privately handle your e-mail communication
+#
+# Copyleft (C) 2010-2012 Denis Roio <jaromil@dyne.org>
+#
+# This source code is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This source code is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# Please refer to the GNU Public License for more details.
+#
+# You should have received a copy of the GNU Public License along with
+# this source code; if not, write to:
+# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+get_imap_info() {
+ { test $name } || {
+ error "get_imap_info() called with no account loaded"
+ return 1 }
+ { test "$type" != "imap" } && {
+ error "get_imap_info() called on a non-imap account: $type.$host"
+ return 1 }
+ { test "$host" = "imap.gmail.com" } && {
+ act "skipping IMAP examination on GMail account"
+ return 1 }
+ func "Querying size on $type.$host"
+
+ c=1
+ tot=0
+ grandtot=0
+ imap_info=()
+ typeset -alU ff
+ id=$RANDOM
+ query=$TMPDIR/imap.size.query.$id
+ newlock $query
+ if [ "$folders" = "" ]; then
+ ff+=(INBOX)
+ else # imap folders are explicit in conf
+ for f in ${(s: :)folders}; do
+ # no composite works, one word each folder
+ ff+=($f); done
+ fi
+
+ for f in ${ff}; do
+ rm -f $query; touch $query
+ cat <<EOF >> $query
+B00000 CAPABILITY
+B00001 LOGIN "${login}" "${password}"
+EOF
+
+ c=$(( $c + 1 ))
+ echo "B0000$c SELECT \"${f}\"" >> $query
+ c=$(( $c + 1 ))
+ echo "B0000$c FETCH 1:* (FLAGS RFC822.SIZE)" >> $query
+ echo >> $query
+
+ typeset -al res
+ for i in `timeout 5 openssl s_client -starttls imap -quiet \
+ -connect ${host}:${port} < $query 2>&1 \
+ | grep RFC822.SIZE | awk '{ print $NF }' \
+ | tr -d '\r' | sed 's/)//'`; do
+ res+=($i); done
+
+ { test $? != 0 } && {
+ error "Error connecting to $host:$port"
+ continue }
+ { test "$res" = "" } && {
+ act "Empty folder $f"
+ continue }
+
+ for rr in ${res}; do
+ tot=$(( ($rr) + $tot ))
+ done
+ act "Folder $f has ${#res} messages (`human_size $tot`)"
+ imap_info+=("$f;${#res};$tot")
+ grandtot=$(( $grandtot + $tot ))
+ done
+ unlink $query
+ imap_info+=($grandtot)
+}+
\ No newline at end of file