jaromail

a commandline tool to easily and privately handle your e-mail
git clone git://parazyd.org/jaromail.git
Log | Files | Refs | Submodules | README

commit 1314f1273127f57899212cfdffdcdd07aa29737c
parent 01db0c425889d10a0fb659a6c0f04086adcd3f88
Author: Jaromil <jaromil@dyne.org>
Date:   Thu, 24 May 2012 11:31:44 +0200

fixes to procmail filtering and lbdb

new "learn" command correctly learns new addresses from emails in stdin

Diffstat:
ATODO | 18++++++++++++++++++
Mbuild-gnu.sh | 16+++++++++-------
Minstall.sh | 53+++++++++++++++++++++++++++++++++++++----------------
Msrc/jaro | 116++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
Msrc/lbdb/fetchaddr.c | 1+
Msrc/lbdb/lbdb-fetchaddr.sh.in | 6+++---
6 files changed, 157 insertions(+), 53 deletions(-)

diff --git a/TODO b/TODO @@ -0,0 +1,18 @@ + + +* Maildirs + + Remove duplicates from maildirs (garbage collection) + + Backup system with expiration date + +* GTD + + Integration with org-remember via org-protocol + +* Install + + Full integration with the Tomb process creation + +* Mutt + + Find out how to make mouse selection work + +* Stats + + Have some fancy statistics + diff --git a/build-gnu.sh b/build-gnu.sh @@ -26,14 +26,16 @@ case $distro in gcc -O2 -c -static fetchaddr.c helpers.c rfc2047.c rfc822.c; \ gcc -O2 -static -o fetchaddr fetchaddr.o helpers.o rfc2047.o rfc822.o; cd - > /dev/null - echo "gnome-keyring" - cd src/gnome-keyring - [ -x jaro-gnome-keyring ] || \ - gcc `pkg-config --cflags --libs glib-2.0 gnome-keyring-1` \ - -O2 -o jaro-gnome-keyring jaro-gnome-keyring.c - cd - > /dev/null + echo + # echo "gnome-keyring" + # cd src/gnome-keyring + # [ -x jaro-gnome-keyring ] || \ + # gcc `pkg-config --cflags --libs glib-2.0 gnome-keyring-1` \ + # -O2 -o jaro-gnome-keyring jaro-gnome-keyring.c + # cd - > /dev/null echo "Done compiling." - echo "Now run ./install.sh and jaromail will be ready in ~/Mail/jaro" + echo "Now run ./install.sh and Jaro Mail will be ready in ~/Mail" + echo "or \"./install.sh path\" to install it somewhere else." ;; *) diff --git a/install.sh b/install.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env zsh +#!/usr/bin/env zsh # jaromail install script # @@ -36,7 +36,7 @@ MUTTDIR=$WORKDIR/.mutt umask 007 # James Bond ;^) -source src/jaro +source src/jaro source # make sure the directory is private ${=mkdir} $MAILDIRS @@ -96,47 +96,64 @@ Directory containing account information Each file contains a different account: imap, pop or gmail each account contains all information needed to connect it -For example a file named imap.gmail.txt should contain: +Examples are: imap.default.txt and smtp.default.txt -----8<----8<----8<----8<----8<----8<----8<----8<----8<---- +One can have multiple accounts named otherwise than default +EOF + cat <<EOF > $WORKDIR/Accounts/imap.default.txt # Name and values are separated by spaces or tabs +# comments start the line with a hash # Name appearing in From: field -name Anonymous +name To Be Configured + +# Email address (default is same as login) +email unknown@gmail.com +# Internet address host imap.gmail.com +# Username login USERNAME@gmail.com +# Authentication type auth plain # or kerberos, etc +# Identity certificate: check or ignore +cert ignore + +# Transport protocol transport ssl +# Service port port 993 -cert /path/to/cert +# Options when fetching +# to empty your mailbox you can use: fetchall flush +# by default this is 'keep': don't delete mails from server +options keep # the password field will be filled in automatically - -----8<----8<----8<----8<----8<----8<----8<----8<----8<---- - -Or a file named smtp.gmail.txt should contain: - -----8<----8<----8<----8<----8<----8<----8<----8<----8<---- +EOF + cat <<EOF > $WORKDIR/Accounts/smtp.default.txt # Name and values are separated by spaces or tabs +# comments start the line with a hash -name USERNAME gmail +# Name for this account +name To Be Configured +# Internet address host smtp.gmail.com +# Username login USERNAME@gmail.com +# Transport protocol transport ssl # or "tls" or "plain" +# Service port port 465 - -----8<----8<----8<----8<----8<----8<----8<----8<----8<---- - +# port 25 EOF act "Default accounts directory created" else @@ -193,6 +210,7 @@ chmod +x $WORKDIR/.lbdb/* ln -sf $WORKDIR/.lbdb/lbdb-fetchaddr $WORKDIR/bin/ ln -sf $WORKDIR/.lbdb/lbdbq $WORKDIR/bin/ +# OS specific lbdb rules case $OS in GNU) echo "METHODS=(m_inmail)" > ${WORKDIR}/.lbdb/lbdb.rc @@ -228,6 +246,9 @@ EOF esac notice "Installation completed" #, now edit your personal settings:" + + +# OS specific post install rules case $OS in GNU) ;; diff --git a/src/jaro b/src/jaro @@ -49,6 +49,10 @@ typeset -A opts # global variables for accounts typeset -h name login host protocol port password auth folders accountopt +# global variable for exit code +typeset exitcode +exitcode=0 + autoload colors; colors # standard output message routines @@ -66,22 +70,29 @@ act() { fi } + # what operating system are we in? use os_detect() # simplifying modes of operation: GNU or MAC -case $(uname) in - Linux) OS=GNU - notice "Jaro Mail v$VERSION running on GNU/Linux" ;; - - Darwin) OS=MAC - notice "Jaro Mail v$VERSION running on Mac/OSX" ;; - - *) OS=GNU # default - error "Running on an unknown operating system, assuming GNU" ;; -esac - +if [ "$1" != "-q" ]; then # honor quiet flag + case $(uname) in + Linux) OS=GNU + notice "Jaro Mail v$VERSION running on GNU/Linux" ;; + + Darwin) OS=MAC + notice "Jaro Mail v$VERSION running on Mac/OSX" ;; + + *) OS=GNU # default + error "Running on an unknown operating system, assuming GNU" ;; + esac +fi -if [ -z $MAILDIRS ]; then - MAILDIRS=$HOME/Mail +if [ -z $MAILDIRS ]; then + # check if we are inside the directory + if [ -r jaro/bin/jaro ]; then + MAILDIRS=`pwd` + else # else use default + MAILDIRS=$HOME/Mail + fi fi @@ -256,13 +267,15 @@ read_account() { ttmp=`cat $acct | awk ' /^#/ { next } /^name/ { printf "name=\""; for(i=2;i<=NF;i++) printf "%s ", $i; printf "\";" } + /^email/ { printf "email=\"%s\";", $2 } /^host/ { printf "host=\"%s\";", $2 } /^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 } - /^options/ { printf "accountopt=\"%s\";", $2 } + /^cert/ { printf "cert=\"%s\";", $2 } + /^options/ { printf "accountopt=\""; for(i=2;i<=NF;i++) printf "%s ", $i; printf "\";" } /^folders/ { printf "folders=\"%s\";", $2 } '` eval "$ttmp" @@ -271,14 +284,17 @@ read_account() { { test -z $login } && { error "Field missing in account $acct: login"; return 1 } # fill in defaults { test -z $name } && { name="$type" } + { test -z $email } && { email="$login" } { test -z $transport } && { transport=ssl } { test -z $port } && { port=993 } { test -z $auth } && { auth=plain } + { test -z $cert } && { cert=ignore } { test -z $accountopt } && { accountopt=keep } # cert and password can be missing func "type: $type" func "name: $name" + func "email: $email" func "host: $host" func "login: $login" func "trans: $transport" @@ -470,16 +486,25 @@ fetch() { cat <<EOF > $WORKDIR/tmp/$host.fetch poll $host with proto IMAP user "$login" there with password "$password" EOF + unset password + if ! [ -z $accountopt ]; then # add option configuration echo "${accountopt}" >> $WORKDIR/tmp/$host.fetch; fi + if ! [ -z $folders ]; then # add folder configuration echo "folder ${folders}" >> $WORKDIR/tmp/$host.fetch; fi + cat <<EOF >> $WORKDIR/tmp/$host.fetch ssl warnings 3600 and wants mda "procmail -m $PROCMAILDIR/rc" +EOF + if [ "$cert" = "check" ]; then + cat <<EOF >> $WORKDIR/tmp/$host.fetch sslcertck sslcertpath '$WORKDIR/certs' +EOF + fi + cat <<EOF >> $WORKDIR/tmp/$host.fetch antispam 571 550 501 554 EOF - unset password # try login without doing anything fetchmail -c -f $WORKDIR/tmp/$host.fetch @@ -653,7 +678,7 @@ set spoolfile = $MAILDIRS/known/ set record = $MAILDIRS/sent/ set postponed= $MAILDIRS/postponed/ set tmpdir = $WORKDIR/tmp -set query_command = "$WORKDIR/bin/jaro query '%s'" +set query_command = "$WORKDIR/bin/jaro -q query '%s'" set sendmail = "$WORKDIR/bin/jaro queue" set header_cache= $WORKDIR/cache set maildir_header_cache_verify=no @@ -693,6 +718,7 @@ EOF ########## # PROCMAIL + act "generating procmail filters" ${=mkdir} $PROCMAILDIR rm -f $PROCMAILDIR/rc touch $PROCMAILDIR/rc @@ -723,8 +749,9 @@ EOF ####### echo "# filters generated from Accounts" >> $PROCMAILDIR/rc typeset -al accts - for f in `cat $WORKDIR/Accounts/* | awk '/^login/ { print $2 }'`; do - echo "ADDR=${f}\tDEST=priv\tINCLUDERC=\$PMSRC/pf-chkto.rc" >> $PROCMAILDIR/rc + for f in `cat $WORKDIR/Accounts/* | awk '/^email/ { print $2 }'`; do + echo "ADDR=${f}\tDEST=priv/\tINCLUDERC=\$PMSRC/pf-chkto.rc" >> $PROCMAILDIR/rc + act "private account: <${f}>" done ####### @@ -737,12 +764,14 @@ EOF destination="${f[(ws:;:)4]}" case $header in to) - print "ADDR=${address}\tDEST=${destination}\tINCLUDERC=\$PMSRC/pf-chkto.rc" \ + print "ADDR=${address}\tDEST=${destination}/\tINCLUDERC=\$PMSRC/pf-chkto.rc" \ >> $PROCMAILDIR/rc + act "messages to <${address}> in folder: ${destination}" ;; from) - print "ADDR=${address}\tDEST=${destination}\tINCLUDERC=\$PMSRC/pf-check.rc" \ + print "ADDR=${address}\tDEST=${destination}/\tINCLUDERC=\$PMSRC/pf-check.rc" \ >> $PROCMAILDIR/rc + act "messages from <${address}> in folder: {$destination}" ;; *) error "unsupported filter: $header (skipped)" @@ -770,7 +799,7 @@ EOF # if the sender is known (ldbd recognizes it) then put mail in high priority 'known' :0 w: -* ? formail -x"From:" | head -n1 | tr 'A-Z' 'a-z' | sed 's/.*\W\([0-9a-z_.-]\+@[0-9a-z_.-]\+\).*/\1/' | xargs \$JARO query +* ? formail -x"From:" | head -n1 | tr 'A-Z' 'a-z' | sed 's/.*\W\([0-9a-z_.-]\+@[0-9a-z_.-]\+\).*/\1/' | xargs \$JARO -q query known/ # if got here, go to unsorted @@ -783,6 +812,29 @@ known/ EOF return 0 +} # end of update() + + +query() { + if [ $QUIET = 1 ]; then + ${WORKDIR}/bin/lbdbq ${@} > /dev/null + exitcode=$? + else + act -n "Query known address <${@}> in " + ${WORKDIR}/.lbdb/lbdbq ${@} + exitcode=$? + fi +} + +learn() { + if [ $QUIET = 1 ]; then + ${WORKDIR}/bin/lbdb-fetchaddr -a > /dev/null + exitcode=$? + else + act "Learning new address from mail pipe in stdin" + ${WORKDIR}/bin/lbdb-fetchaddr -a + exitcode=$? + fi } usage() { @@ -814,12 +866,14 @@ Internal commands: update refresh configurations queue add into outbox query query a name from addressbook + learn learn known addresses from mails piped in stdin + -For more informations on Jaro Mail read the manual: man jaro Please report bugs on <http://bugs.dyne.org>. EOF } +# TODO: For more informations on Jaro Mail read the manual: man jaro main() { @@ -845,6 +899,7 @@ main() subcommands_opts[peek]="" subcommands_opts[update]="" subcommands_opts[query]="" + subcommands_opts[learn]="" subcommands_opts[source]="" subcommands_opts[cert]="" # subcommands_opts[mount]=${subcommands_opts[open]} @@ -866,7 +921,8 @@ main() fi if [[ -z ${(k)subcommands_opts[$subcommand]} ]]; then #there's no such subcommand error "Subcommand '$subcommand' doesn't exist" - exit 127 + exitcode=1 + return 1 fi argv=(${oldstar}) unset oldstar @@ -878,12 +934,12 @@ main() zparseopts -M -E -D -Aopts ${cmd_opts} if [[ $? != 0 ]]; then error "Some error occurred during option processing." - exit 127 + exitcode=1 + return 1 fi fi #build PARAM (array of arguments) and check if there are unrecognized options local ok=0 -# PARAM=() for arg in $*; do if [[ $arg == '--' || $arg == '-' ]]; then ok=1 @@ -891,7 +947,8 @@ main() elif [[ $arg[1] == '-' ]]; then if [[ $ok == 0 ]]; then error "unrecognized option $arg" - exit 127 + exitcode=1 + return 1 fi fi PARAM+=$arg @@ -916,8 +973,12 @@ main() read) mutt -F $MUTTDIR/rc ;; cert) cert ${PARAM} ;; compose) mutt -F $MUTTDIR/rc ${PARAM} ;; + update) update ;; - query) ${WORKDIR}/.lbdb/lbdbq ${PARAM} ;; + + query) query ${PARAM} ;; + learn) learn ${PARAM} ;; + 'source') return 0 ;; __default) ;; *) error "command \"$subcommand\" not recognized" @@ -931,3 +992,4 @@ main() check_bin main $@ cleanexit +return $exitcode diff --git a/src/lbdb/fetchaddr.c b/src/lbdb/fetchaddr.c @@ -32,6 +32,7 @@ #include "rfc2047.h" #define MAXHDRS 21 +#define HAVE_ICONV 1 struct header { diff --git a/src/lbdb/lbdb-fetchaddr.sh.in b/src/lbdb/lbdb-fetchaddr.sh.in @@ -31,7 +31,7 @@ fetchaddr=@libdir@/fetchaddr db=@LBDB_FILE@ datefmt='%Y-%m-%d %H:%M' -additional_param="" +additional_param=() usage() { echo "Usage: $0 [OPTIONS]" @@ -78,7 +78,7 @@ do fi ;; -a) - additional_param="$additional_param $1" + additional_param+=($1) ;; *) if [ $# -eq 1 ] @@ -120,7 +120,7 @@ else exit 1 fi -if $fetchaddr $additional_param -d "$datefmt" $hdrlist $charset >> $db ; then +if $fetchaddr ${=additional_param} -d "$datefmt" $hdrlist $charset >> $db ; then touch $db.dirty fi