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 405918fefc557d80115d82dfb8440eccf5293f51
parent 5639b45b94d34e375a80d7b9d8b177fc07f5b27b
Author: Jaromil <jaromil@dyne.org>
Date:   Mon, 19 Mar 2012 20:20:35 +0100

separated install
mutt configuration
some fixes

Diffstat:
Ainstall.sh | 160+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ashare/mutt/colors | 45+++++++++++++++++++++++++++++++++++++++++++++
Ashare/mutt/crypto | 15+++++++++++++++
Ashare/mutt/formats | 26++++++++++++++++++++++++++
Ashare/mutt/general | 131+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ashare/mutt/keybindings | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/postino | 164+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
7 files changed, 528 insertions(+), 62 deletions(-)

diff --git a/install.sh b/install.sh @@ -0,0 +1,160 @@ +#!/usr/bin/zsh + +# Postino install script + +if ! [ -r src/postino ]; then + echo "Error: this script should be run from inside a postino software distribution" + exit 1 +fi + + +WORKDIR=$HOME/.postino +if [ $1 ]; then WORKDIR=$1; fi +# make sure the directory is private +mkdir -p $WORKDIR +chmod 700 $WORKDIR + +source src/postino + +notice "Installing Postino in $WORKDIR" + +if [ $? != 0 ]; then + error "Postino directory $WORKDIR is not private, set its permissions to 700" + error "Refusing to proceed." + exit 1 +fi + +# make sure we have a temp and cache dir +mkdir -p $WORKDIR/tmp $WORKDIR/cache +chmod 700 $WORKDIR/tmp $WORKDIR/cache + +if ! [ -r $WORKDIR/main.conf ]; then + cat <<EOF > $WORKDIR/main.conf +# MAIL USER (the left and right parts of an email) +NAME=user +# @ +DOMAIN=gmail.com + +# SMTP (SEND) +SMTP_ADDRESS=smtp.gmail.com +SMTP_LOGIN=${NAME}@${DOMAIN} +SMTP_PASSWORD=my_secret_pass +SMTP_PORT=25 +# SMTP_CERTIFICATE=gmail.pem + +# IMAP (RECEIVE) +IMAP_ADDRESS=imap.gmail.com +IMAP_LOGIN=${NAME}@${DOMAIN} +IMAP_PASSWORD=my_secret_pass +IMAP_PORT=443 + +# LOCAL FILES +# to change the location of this directory, +# export POSTINO_DIR as env var +# the defaults below should be ok, they place +# mutt, procmail, mstmp and other confs in ~/.postino + +MAILDIRS=$HOME/Mail +MUTTDIR=$WORKDIR/.mutt +PROCMAILDIR=$WORKDIR/.procmail +CERTIFICATES=$HOME/.ssl/certs + +# directory of the sieve filter +# REMOTE_FILTER=/var/mail/... +EOF +else + error "Existing configuration main.conf skipped" +fi + +if ! [ -r $WORKDIR/filters.conf ]; then + cat <<EOF > $WORKDIR/filters.conf +# Example filter configuration for Postino + +# accepted email addresses +to jaromil@dyne.org save priv +to jaromil@kyuzz.org save priv +to jaromil@enemy.org save priv +to jaromil@montevideo.nl save priv + +# mailinglist filters, in order of importance +to crypto@lists.dyne save dyne.crypto +to dynebolic save dyne.dynebolic +to freej save dyne.freej +to frei0r-devel save dyne.frei0r +to taccuino save ml.freaknet +to deadpoets save ml.freaknet +to linux-libre save gnu.linux-libre +to foundations@lists save gnu.foundations +to debian-mentors save debian.mentors +to debian-blends save debian.blends +to freedombox-discuss save debian.freedombox + +# other filters for web 2.0 services +from identi.ca save web.identica +from Twitter save web.twitter +from linkedin save web.linkedin +from googlealerts save web.google +from facebook save web.facebook +from FriendFeed save web.friendfeed +from academia.edu save web.academia + +EOF +else + error "Existing configuration filters.conf skipped" +fi + +source $WORKDIR/main.conf + +# make sure maildirs where to put mails exist +mkdir -p $MAILDIRS +chmod 700 $MAILDIRS +maildirmake $MAILDIRS/known +maildirmake $MAILDIRS/sent +maildirmake $MAILDIRS/priv +maildirmake $MAILDIRS/postponed +maildirmake $MAILDIRS/unsorted + +if ! [ -r $MUTTDIR ]; then + mkdir -p $MUTTDIR + cat<<EOF > $MUTTDIR/rc +# mutt config generated by postino +# don't edit, change main.conf instead +unset use_domain +set hostname = $DOMAIN +set realname = $NAME +set folder = $MAILDIRS +set spoolfile = $MAILDIRS/known/ +set record = $MAILDIRS/sent/ +set postponed= $MAILDIRS/postponed/ +set tmpdir = $WORKDIR/tmp +set query_command = "postino query '%s'" +set sendmail = "postino queue" +set header_cache= $MUTTDIR/cache +set maildir_header_cache_verify=no +set editor = "$EDITOR" +set mailcap_path = "$WORKDIR/mailcap" + +# mailboxes in order of priority +source $MUTTDIR/mboxes +# user tweaked configuration +source $MUTTDIR/general +## end of generated muttrc +########################## + +EOF + cp -f share/mutt/* $MUTTDIR/ + touch $MUTTDIR/mboxes + ln -sf $MUTTDIR/rc $HOME/.muttrc + if [ $? != 0 ]; then + error "Error setting Postino to handle Mutt's default configuration" + error "Set symlink manually: $HOME/.muttrc -> $MUTTDIR/rc" + fi +else + error "Existing configuration for Mutt skipped" +fi + +if ! [ -r $PROCMAILDIR ]; then mkdir -p $PROCMAILDIR; fi + +notice "Installation completed, now edit your personal settings:" +act "$WORKDIR/main.conf" + diff --git a/share/mutt/colors b/share/mutt/colors @@ -0,0 +1,45 @@ +# Postino's color configuration for Mutt +# originally used by Jaromil + +######################################################################## +## Color settings, you can use: +# white - brightwhite # yellow - brightyellow # green - brightgreen +# magenta - brightmagenta # blue - brightblue # black - brightblack + +color normal white default +color tilde white default +color indicator brightgreen default +color tree brightred default # the thread tree in the index menu +color status cyan default +color hdrdefault cyan default +color header brightred default ^(From|Subject|Date|To): +color body magenta default "(ftp|http)://[^ ]+" # point out URLs +color body magenta default [-a-z_0-9.]+@[-a-z_0-9.]+ # e-mail addresses +color underline brightgreen default +color markers brightblack default +color signature green default +color error red default +color attachment brightmagenta default +color search default green # how to hilite search patterns in the pager + +# quoted message +color quoted brightgreen default +color quoted1 green default +color quoted2 brightgreen default +color quoted3 green default +color quoted4 brightgreen default +color quoted5 green default + +# Colours for items in the index +color index cyan default "." +color index white default "~N" # New +color index brightcyan default "~O" # Unread +color index brightgreen default "~N (~x jaromil@* | ~h \"^In-[Rr]eply-[Tt]o: .*jaromil@*")" +color index yellow default "~f jaromil@*" +# color index brightblue default "~g" # gpg signed +color index brightblue default "~G" # gpg encrypted +color index brightgreen default "~F" # Flagged +color index brightred default "~T" # Tagged +color index red default "~f MAILER-DAEMON@*" +color index red default "~f Mailer-Daemon@*" +color index brightblack default "~D" # Deleted diff --git a/share/mutt/crypto b/share/mutt/crypto @@ -0,0 +1,15 @@ +# Postino's GPG configuration for Mutt +# originally used by Jaromil + +#forget the passphrase in 1h +set pgp_timeout = 3600 +set pgp_auto_decode +# set pgp_autosign +set pgp_strict_enc +set pgp_verify_sig = yes + +# # CLEARTEXT INLINE GPG +# set pgp_create_traditional = no +# macro compose \cx "Fgpg --clearsign\nyy" +# macro pager \cv "|gpg --verify;sleep 1\n" +# macro pager \ef "|view-x-face\n" diff --git a/share/mutt/formats b/share/mutt/formats @@ -0,0 +1,26 @@ +# Postino's display format strings for Mutt +# originally used by Jaromil + +set alias_format="%2n %t %-20.20a: %r" + +set attach_format="%2n %D%I%u%t %T%f %d (%s) (%m/%M, %e, %C)" + +set compose_format="Compose %h [Approx. msg size: %l, Atts: %a] %v %>-" + +set date_format="!%a %e.%h'%y at %k:%M:%S %Z" + +set folder_format="%N %3C %d %2l (%5s) %f" + +set message_format="From: <%a>, Sub: %s" + +set index_format="%?M?_%M_ ?%Z %2C %.13d (%-$FCOL.${FCOL}F) %-$SCOL.${SCOL}s %?M?_%M_&(%c/%l?" + +set pager_format="%Z %C/%m %d (%F) %s (%c/%l) %|-" + +set pgp_entry_format="%3n %t%f %4l/0x%k %-4a %2c %u %[%a %e.%h'%y at %k:%M:%S %Z]" + +set status_format="_%r_ %h: %f, %l/%m (%P,%s) [ %?p?PP:%p ?%?t?Tag:%t ?%?d?DEL:%d ?]%?V?, %L/%M only=%V? < %?F?go:%F ?%?n?new:%n ?> %v" + +set forward_format = "[Fwd] %s" + +set hdr_format="%Z %3C %{%b %d} %-19.19L (%5c) %s" diff --git a/share/mutt/general b/share/mutt/general @@ -0,0 +1,131 @@ +# Postino's generic config settings for Mutt +# originally used by Jaromil + +# specific configuration files: +source ~/.mutt/crypto +source ~/.mutt/colors +source ~/.mutt/formats +source ~/.mutt/keybindings + +############### +## SMTP options +unset use_8bitmime +#set sendmail_wait = 0 + + +## Alias options TODO +#set alias_file = ~/.mutt/aliases +#source ~/.mutt/aliases + +################## +## General options +#set locale = "C" +unset suspend +unset wait_key + +set send_charset=utf-8 +set assumed_charset = us-ascii + +#set charset = iso-8859-1 +#set send_charset = us-ascii +#set charset = utf-8 +#set shell = retrieved from passwd file +#set simple_search = "~f %s | ~s %s" + +# Little Brother Database +set query_command = "lbdbq '%s'" + + +############ +## Main menu +#set collapse_unread +set arrow_cursor +set ascii_chars +set auto_tag +unset beep +unset help +set mark_old +unset markers +#set resolve +unset sort_re +set wrap_search = yes +#set mail_check = 5 +set timeout = 300 +set delete = yes +#set reply_regexp = "^(re|aw):[ \t]*" +set sort = threads +#set status_chars = "-*%A" + +#set to_chars = " +TCF" +set sort_aux = reverse-date + +################ +## Pager options +#set prompt_after +unset smart_wrap +set tilde +set pager_stop +# set pager_format = "-%S- %C/%m: %-20.20n %s" +set quote_regexp="^ *[a-zA-Z]*[]>|}=][]>|}:=]*" +auto_view text/html +# also text/plain to convert charset +# auto_view text/plain + +################## +## Compose options +set weed = yes + +################ +## Reply options +set reply_to = ask-yes + +################## +## Sending options +set allow_8bit +#set bounce_delivered +set followup_to = yes +set honor_followup_to = yes +#unset force_name +#unset save_name +#set use_from +set abort_nosubject = no +set abort_unmodified = no +set copy = yes + +################## +## Forward options +set forward_decode = yes +#set forward_format = "[Fwd] %s" +#set mime_forward + +###################### +## Folders and mailbox +set noconfirmappend +#set confirmcreate +#unset mh_purge +#unset save_address +set save_empty +#set folder_format = "%N %F %2l %-8.8u %-8.8g %8s %d %f" +#set move = ask-no +set mbox_type = mbox + +####################################### +## Attaching documents and MIME options +#set attach_sep = newline +#set attach_split +#set fcc_attach +set fcc_clear = no +#set attach_format = "%u%D%t%2n %T%.40d%> [%.7m/%.10M, %.6e, %s] " +#set message_format = "%s" + +################### +## mailcap and MIME +set mailcap_sanitize + +################### +## Printing options +set print_command = lpr +#set print = ask-no + +## end of general muttrc +######################## diff --git a/share/mutt/keybindings b/share/mutt/keybindings @@ -0,0 +1,49 @@ +# Postino's keybindings for mutt +# originally used by Jaromil + +bind index t create-alias +bind index w search +bind index x sync-mailbox +macro index $ '<enter-command>set mark_old=yes<enter>' +bind index a tag-prefix +bind index \; tag-entry + +bind index <pagedown> next-page +bind index <pageup> previous-page +bind index <home> first-entry +bind index <end> last-entry +bind index <right> display-message +bind index <left> noop +bind index < first-entry +bind index \e< first-entry +bind index > last-entry +bind index \e> last-entry + +bind pager w search +bind pager \n noop # PINE prints "No default action for this menu." +bind pager <up> previous-line +bind pager <down> next-line +bind pager <left> previous-entry + +# Little Brother Database settings +# bind index,pager Q query +bind editor <tab> complete-query +macro index,pager A "<pipe-message>lbdb-fetchaddr -a" "add the sender address to lbdb" +macro index,pager + "<pipe-message>lbdb-fetchaddr -a" "add the sender address to lbdb" + +macro pager \ef "|view-x-face<enter>" "display the X-Face included in the mail" + +# Not possible to simulate zoom-out... +macro index z l~T\r + +# mutt sidebar +# bind index,pager \CP sidebar-prev +# bind index,pager \CN sidebar-next +# bind index,pager \CO sidebar-open +# macro index,pager B '<enter-command>toggle sidebar_visible<enter>' +# color sidebar_new yellow default + + + +# for org-remember +# macro index R "|remember-mail\n" diff --git a/src/postino b/src/postino @@ -20,22 +20,32 @@ # this source code; if not, write to: # Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -VERSION=0.5 -DATE=Sept/2011 +VERSION=0.6 +DATE=March/2011 POSTINOEXEC=$0 typeset -a OLDARGS for arg in ${argv}; do OLDARGS+=($arg); done -#declare global variables +########################## +# declare global variables + QUIET=0 -DEBUG=0 +DEBUG=1 + +# default config dir +if [ -z $POSTINO_DIR ]; then + WORKDIR=$HOME/.postino +else + WORKDIR=$POSTINO_DIR +fi + +########################## + + PARAM=() typeset -A global_opts typeset -A opts -# make sure we have a temp dir -mkdir -p $WORKDIR/tmp - autoload colors; colors # standard output message routines @@ -53,20 +63,20 @@ act() { fi } +# make sure the directory is private +chmod 700 $WORKDIR +if [ $? != 0 ]; then + error "Postino directory $WORKDIR is not private, set permissions to 700" + error "Refusing to proceed." + exit 1 +fi + +# make sure we have a temp and cache dir +mkdir -p $WORKDIR/tmp $WORKDIR/cache +chmod 700 $WORKDIR/tmp $WORKDIR/cache -# parse configuration -if [ -r $HOME/.postinorc ]; then source $HOME/.postinorc -else WORKDIR=$HOME/.postino; fi # default -if [ -r $WORKDIR/main.conf ]; then - source $WORKDIR/main.conf -else # first run (main conf not found) - notice "This is the first time you run postino on this machine," - act "we will now call a wizard that will assist you through the configuration" - error "WIZARD TODO" - return 0 -fi # we use pinentry # comes from gpg project and is secure @@ -112,6 +122,24 @@ option_value() { #First argument, the option (something like "-s") <<< ${opts[$1]} } +maildirmake() { + + if [ -z $1 ]; then + error "internal error: missing argument for maildirmake" + return + fi + + if [ -r $1 ]; then + func "maildir exists: $1" + return + fi + + mkdir -p ${1}/cur + mkdir -p ${1}/new + mkdir -p ${1}/tmp + + chmod -R 700 $1 +} queue() { local base; @@ -171,12 +199,12 @@ send() { peek() { # this function will open the MTA to the imap server without fetching mails locally local -aU imap_set #behave like a set; that is, an array with unique elements - imap_set=`awk '!/^#/ { print $1 ";" $2 ";" $3 }' $WORKDIR/receive.conf` + imap_set="${IMAP_LOGIN};${IMAP_ADDRESS};${IMAP_PORT}" for i in ${(f)imap_set}; do + ilogin="${i[(ws:;:)1]}" ihost="${i[(ws:;:)2]}" - ilogin="${i[(ws:;:)3]}" - iname="${i[(ws:;:)1]}" - func "IMAP: $iname $ilogin $ihost:$iport" + iport="${i[(ws:;:)3]}" + func "IMAP: $ilogin $ihost:$iport" # if there is a selection, check if its the one if [ $1 ] && [ "$1" == "$iname" ]; then break; elif ! [ $1 ]; then break; fi # no selection: take first as default @@ -198,44 +226,65 @@ sync() { func "WORKDIR: $WORKDIR" func "MAILDIRS: $MAILDIRS" + # make sure maildirs where to put mails exist + mkdir -p $MAILDIRS + chmod 700 $MAILDIRS + maildirmake $MAILDIRS/known + maildirmake $MAILDIRS/sent + maildirmake $MAILDIRS/priv + maildirmake $MAILDIRS/postponed + maildirmake $MAILDIRS/unsorted + ###### # MUTT - mkdir -p $WORKDIR/mutt - rm -f $WORKDIR/mutt/rc - cat<<EOF > $WORKDIR/mutt/rc + if ! [ -z $MUTTDIR ]; then + mkdir -p $MUTTDIR + rm -f $MUTTDIR/rc + cat<<EOF > $MUTTDIR/rc # mutt config generated by postino unset use_domain -set hostname = "dyne.org" -set realname = "jaromil" -set folder = ~/$MAILDIRS -set spoolfile = ~/$MAILDIRS/known/ -set record = ~/$MAILDIRS/sent/ -set postponed=~/$MAILDIRS/postponed/ +set hostname = $DOMAIN +set realname = $NAME +set folder = $MAILDIRS +set spoolfile = $MAILDIRS/known/ +set record = $MAILDIRS/sent/ +set postponed= $MAILDIRS/postponed/ set tmpdir = $WORKDIR/tmp set query_command = "postino query '%s'" set sendmail = "postino queue" -set header_cache=~/$WORKDIR/mutt/cache +set header_cache= $MUTTDIR/cache set maildir_header_cache_verify=no +set editor = "$EDITOR" +set mailcap_path = "$WORKDIR/mailcap" + # mailboxes in order of priority -source $WORKDIR/mutt/mboxes -## end of postino muttrc +source $MUTTDIR/mboxes EOF - # just the header, will be completed later in procmail loop - rm -f $WORKDIR/mutt/mboxes - echo -n "mailboxes +priv" > $WORKDIR/mutt/mboxes + if [ -r $MUTTDIR/general ]; then + echo "# user tweaked configuration" >> $MUTTDIR/rc + echo "source ${MUTTDIR}/general" >> $MUTTDIR/rc + fi + echo "## end of generated muttrc" >> $MUTTDIR/rc + echo "##########################" >> $MUTTDIR/rc + echo >> $MUTTDIR/rc + # just the header, will be completed later in procmail loop + rm -f $WORKDIR/mutt/mboxes + echo -n "mailboxes +priv" > $WORKDIR/mutt/mboxes + fi + ########## # PROCMAIL - mkdir -p $WORKDIR/procmail - rm -f $WORKDIR/procmail/rc - touch $WORKDIR/procmail/rc - cat<<EOF >> $WORKDIR/procmail/rc + mkdir -p $PROCMAILDIR + rm -f $PROCMAILDIR/rc + touch $PROCMAILDIR/rc + cat<<EOF >> $PROCMAILDIR/rc # procmail configuration file generated by postino MAILDIR=$MAILDIRS DEFAULT=unsorted/ VERBOSE=off -LOGFILE=$WORKDIR/procmail/log +LOGFILE=$PROCMAILDIR/log SHELL = /bin/sh # VERY IMPORTANT UMASK = 007 # James Bond :-) LINEBUF = 8192 # avoid procmail choke @@ -260,25 +309,26 @@ EOF case $header in to) print "ADDR=${address}\tDEST=${destination}\tINCLUDERC=$PMSRC/pf-chkto.rc" \ - >> $WORKDIR/procmail/rc + >> $PROCMAILDIR/rc ;; from) print "ADDR=${address}\tDEST=${destination}\tINCLUDERC=$PMSRC/pf-check.rc" \ - >> $WORKDIR/procmail/rc + >> $PROCMAILDIR/rc ;; *) error "unsupported in filters.conf: $header (skipped)" ;; esac # MUTT (generate mailboxes priority this parser) - echo " \\" >> $WORKDIR/mutt/mboxes - echo -n " +${destination} " >> $WORKDIR/mutt/mboxes + echo " \\" >> $MUTTDIR/mboxes + echo -n " +${destination} " >> $MUTTDIR/mboxes done - echo " \\" >> $WORKDIR/mutt/mboxes - echo " +unsorted" >> $WORKDIR/mutt/mboxes - uniq $WORKDIR/mutt/mboxes > $WORKDIR/tmp/mboxes - mv $WORKDIR/tmp/mboxes $WORKDIR/mutt/mboxes + echo " \\" >> $MUTTDIR/mboxes + echo " +unsorted" >> $MUTTDIR/mboxes + uniq $MUTTDIR/mboxes > $WORKDIR/tmp/mboxes + mv $WORKDIR/tmp/mboxes $MUTTDIR/mboxes + rm -f $WORKDIR/tmp/mboxes cat <<EOF >> $WORKDIR/procmail/rc } @@ -294,18 +344,6 @@ EOF * ? formail -x"From:" | head -n1 | tr 'A-Z' 'a-z' | sed 's/.*\W\([0-9a-z_.-]\+@[0-9a-z_.-]\+\).*/\1/' | xargs lbdbq known/ -# if the destination is known, put it in private folder -:0 -* ? test $PMSRC/pf-chkto.rc -{ - ADDR="(jaromil@dyne.org)" DEST=priv/ INCLUDERC=$PMSRC/pf-chkto.rc - ADDR="(jaromil@nimk.nl)" DEST=priv/ INCLUDERC=$PMSRC/pf-chkto.rc - ADDR="(jaromil@kyuzz.org)" DEST=priv/ INCLUDERC=$PMSRC/pf-chkto.rc - ADDR="(jaromil@enemy.org)" DEST=priv/ INCLUDERC=$PMSRC/pf-chkto.rc - ADDR="(j@rastasoft.org)" DEST=priv/ INCLUDERC=$PMSRC/pf-chkto.rc - ADDR="(denis@roio.net)" DEST=priv/ INCLUDERC=$PMSRC/pf-chkto.rc -} - # if got here, go to unsorted # save the mails @@ -342,6 +380,7 @@ main() subcommands_opts[sync]="" subcommands_opts[conf]="" subcommands_opts[list]="" + subcommands_opts[source]="" # subcommands_opts[mount]=${subcommands_opts[open]} # subcommands_opts[create]="s: -size=s -ignore-swap k: -key=k" ### Detect subcommand @@ -410,6 +449,7 @@ main() peek) peek ;; sync) sync ;; conf) ;; + 'source') return 0 ;; __default) ;; *) error "command \"$subcommand\" not recognized" act "try -h for help"