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 d24aa11ec30b19b686471df39adfeb4dedaeb12a
parent 5be771df2c7007c957ed2b4b8b2b36ab7739a268
Author: Jaromil <jaromil@dyne.org>
Date:   Thu,  5 Dec 2013 13:32:03 +0100

updates to move all write operations in MAILDIRS. Fixes OSX

Diffstat:
Mbuild/build-osx.sh | 2++
Msrc/jaro | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
Msrc/zlibs/accounts | 46++++++++++++++++++++++++++++------------------
Msrc/zlibs/email | 9++++-----
Msrc/zlibs/filters | 48++++++++++++++++++++++++++++--------------------
Msrc/zlibs/helpers | 24++++++++++++------------
Msrc/zlibs/locking | 9++++++---
7 files changed, 135 insertions(+), 78 deletions(-)

diff --git a/build/build-osx.sh b/build/build-osx.sh @@ -364,3 +364,5 @@ popd mkdir -p build/JaroMail.app/Contents/Resources/ cp -v doc/JaroMail.icns build/JaroMail.app/Contents/Resources/ ./install.sh build/JaroMail.app/Contents/Resources +chmod -R go+rX build/JaroMail.app/Contents/Resources/ +chmod -R go+rx build/JaroMail.app/Contents/Resources/jaro/bin diff --git a/src/jaro b/src/jaro @@ -122,33 +122,45 @@ esac # check if we are inside the directory if [ -r jaro/bin/jaro ]; then MAILDIRS=`pwd` - else # else use default - MAILDIRS=$HOME/Mail + +# check if we are on OSX +elif [ -r /Applications/JaroMail.app ]; then + MAILDIRS=$HOME/Library/Application\ Support/JaroMail + +# else use GNU/Linux default +else + MAILDIRS=$HOME/Mail fi # end override { test "$JAROMAILDIR" = "" } || { MAILDIRS="$JAROMAILDIR" } # default working dir -WORKDIR=$MAILDIRS/jaro + +# check if we are on OSX +if [ -r /Applications/JaroMail.app/Contents/Resources/jaro ]; then + WORKDIR="/Applications/JaroMail.app/Contents/Resources/jaro" +else # use GNU/Linux default + WORKDIR="$MAILDIRS/jaro" +fi # env override { test "$JAROWORKDIR" = "" } || { WORKDIR="${JAROWORKDIR}" } act "Maildirs in $MAILDIRS" act "System in $WORKDIR" -${=mkdir} $MAILDIRS -${=mkdir} $WORKDIR +${=mkdir} "$MAILDIRS" +#${=mkdir} $WORKDIR # make sure the permissions are private -chmod 700 $WORKDIR -chmod 700 $MAILDIRS +#chmod 700 $WORKDIR +chmod 700 "$MAILDIRS" PATH=$WORKDIR/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/opt/local/bin # load our ZLibs if [ -d $WORKDIR/zlibs ]; then - for z in `find $WORKDIR/zlibs/ -type f | grep -v '.zwc$'`; do + for z in `find $WORKDIR/zlibs -type f | grep -v '.zwc$'`; do func "Loading zlib: ${z}" . ${z} done @@ -162,7 +174,7 @@ else fi # temporary directory -TMPDIR=$WORKDIR/tmp +TMPDIR="$MAILDIRS/tmp" case $OS in GNU) touch /dev/shm/jaromail.test.tmp > /dev/null @@ -186,7 +198,7 @@ esac act "Using temporary directory in volatile RAM" } -# make sure we have a temp and cache dir +# make sure we have a temp dir ${=mkdir} "$TMPDIR" { test $? != 0 } && { error "Cannot create temporary directory: $TMPDIR" @@ -195,17 +207,34 @@ ${=mkdir} "$TMPDIR" # make sure we have an addressbook # use the one in RAM if present, for acceleration hostname=$(hostname) # gather the current hostname -addressbook=$WORKDIR/addressbook + + +ACCOUNTS="$MAILDIRS/Accounts" +KEYRING="$MAILDIRS/Keyring" +addressbook="$MAILDIRS/Addressbook" + +# backward compatibility tests for old paths in JaroMail <1.3 +{ test -r $WORKDIR/Accounts } && { test ! -r $ACCOUNTS } && { + act "Updating accounts location: $ACCOUNTS" + cp -r $WORKDIR/Accounts $ACCOUNTS } + +{ test -r $WORKDIR/keyring } && { test ! -r $KEYRING } && { + act "Updating keyring location: $KEYRING" + cp $WORKDIR/keyring $KEYRING } + +{ test -r $WORKDIR/addressbook } && { test ! -r $addressbook } && { + act "Updating addressbook location: $addressbook" + cp $WORKDIR/addressbook $addressbook } + addressbook_tmp=$TMPDIR/${USER}.${hostname}.addressbook { test -r "$addressbook" } || { create_addressbook } { test -r "$addressbook_tmp" } && { addressbook="$addressbook_tmp" } -${=mkdir} "$WORKDIR/cache" -${=mkdir} "$WORKDIR/log" -${=mkdir} "$WORKDIR/certs" +${=mkdir} "$MAILDIRS/logs" +# ${=mkdir} "$MAILDIRS/certs" -PROCMAILDIR=$WORKDIR/.procmail -MUTTDIR=$WORKDIR/.mutt +PROCMAILDIR=$MAILDIRS/.procmail +MUTTDIR=$MAILDIRS/.mutt # use gnome-keyring for passwords on GNU systems @@ -228,12 +257,16 @@ cleanexit() { } # first delete dirs - for d in `${=find} $TMPDIR/ -maxdepth 1 -type d`; do - { test "$d" = "$TMPDIR/" } || { ${=rm} -r ${d} } + tmpdirs=`${=find} $TMPDIR/ -maxdepth 1 -type d` + for d in ${(f)tmpdirs}; do + { test "$d" = "$TMPDIR/" } || { + func "deleting dir: $d" + ${=rm} -r "${d}" } done # then locks, with a warning - for l in `${=find} $TMPDIR/ -maxdepth 1 -type f -name '*.lock'`; do + llist=`${=find} $TMPDIR/ -maxdepth 1 -type f -name '*.lock'` + for l in ${(f)llist}; do lname=`basename ${(s:.lock:)l}` func "cleaning lock for $lname" @@ -251,7 +284,9 @@ cleanexit() { rm -f ${TMPDIR}/${lname}.lock # remove the actual file - if [ -r ${TMPDIR}/$lname ]; then ${=rm} ${TMPDIR}/$lname + if [ -r ${TMPDIR}/$lname ]; then + func "deleting temp file: ${TMPDIR}/$lname" + ${=rm} "${TMPDIR}/$lname" else act "empty lock: file was already removed"; fi done diff --git a/src/zlibs/accounts b/src/zlibs/accounts @@ -21,24 +21,25 @@ # Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - switch_identity() { if [ "$name" != "" ]; then act "switch to identity: $name <$login>" - rm -f $MUTTDIR/identity - cat <<EOF > $MUTTDIR/identity + rm -f $MAILDIRS/Identity + cat <<EOF > $MAILDIRS/Identity +# Automatically generated, do not modify +# change or add configs into Accounts instead set hostname = $host set realname = "$name" set from = "$name <$login>" EOF else error "No identity found, left blank." - touch $MUTTDIR/identity + touch $MAILDIRS/Identity fi } list_accounts() { - for a in `${=find} $WORKDIR/Accounts -type f | grep -v README | sed 's/.txt//'`; do + for a in `${=find} $ACCOUNTS -type f | grep -v README | sed 's/.txt//'`; do act -n "`basename $a`\t :: " awk ' /^name/ { for(i=2;i<=NF;i++) printf "%s ", $i } @@ -73,10 +74,14 @@ read_account() { return 1 } { test "$account" = "" } && { account=default } - # find the file + # find the account func "read_account looking for ${type} ${account}" - for a in `${=find} $WORKDIR/Accounts -name "$type.$account*"`; do + accountlist=`${=find} $ACCOUNTS -name "$type.$account*" | grep -v 'lock$' | grep -v 'pid$'` + for a in ${(f)accountlist}; do + # check if it is locked func "found account: $a" + { test -r "${a}.lock" } && { + pidcheck "${a}" } all+=($a) done if [ ${#all} = 0 ]; then @@ -237,21 +242,21 @@ lookup_secret() { _hash=$1 if [ "$2" = "" ]; then key=password else key="$2"; fi - cat <<EOF | ${SQL} -column -batch $WORKDIR/keyring + cat <<EOF | ${SQL} -column -batch $KEYRING SELECT ${key} FROM secrets WHERE hash IS "${_hash}"; EOF } new_password() { - notice "Setting a new password for $name" + notice "Setting a new password for $type account: $name" + act "please enter password for username '$login'" password=`pin_entry $login $host` res=0 case $OS in MAC) if [ "$password" != "" ]; then - act -n "Old " security delete-internet-password \ -c JARO -a $email -s $host \ -p $transport -P $port > /dev/null @@ -268,7 +273,10 @@ new_password() { return 0 else - act -n "Old " + error "No password given, operation aborted" + return 1 + + # we are not deleting passwords anymore security delete-internet-password \ -c JARO -a $email -s $host \ -p $transport -P $port > /dev/null @@ -279,6 +287,8 @@ new_password() { return 1 } act "No new password given, old password erased." return 0 + ######### + fi ;; GNU) @@ -299,12 +309,12 @@ EOF else # save it into local keyring - { test -r $WORKDIR/keyring } || { + { test -r $KEYRING } || { # make sure the local keyring exists - touch $WORKDIR/keyring - chmod 600 $WORKDIR/keyring - chown $_uid:$_gid $WORKDIR/keyring - cat <<EOF | ${SQL} -batch $WORKDIR/keyring + touch $KEYRING + chmod 600 $KEYRING + chown $_uid:$_gid $KEYRING + cat <<EOF | ${SQL} -batch $KEYRING CREATE TABLE secrets ( hash text unique, @@ -319,13 +329,13 @@ EOF notice "Select the password to lock this keyring entry:" _password="`print $password | gpg -c --cipher-algo AES256 --openpgp --no-options | base64`" if [ "$lookup" = "" ]; then # new entry - cat <<EOF | ${SQL} -batch $WORKDIR/keyring + cat <<EOF | ${SQL} -batch $KEYRING INSERT INTO secrets (hash, password) VALUES ("${_hash}", "${_password}"); EOF act "saved new password in local keyring" else # update entry - cat <<EOF | ${SQL} -batch $WORKDIR/keyring + cat <<EOF | ${SQL} -batch $KEYRING UPDATE secrets SET password="${_password}" WHERE hash LIKE "${_hash}"; EOF act "updated local keyring with new password" diff --git a/src/zlibs/email b/src/zlibs/email @@ -139,7 +139,7 @@ fetch() { fmconf+=(" ssl warnings 3600 and wants mda \"procmail -m $PROCMAILDIR/rc\" ") if [ "$cert" = "check" ]; then - fmconf+=(" sslcertck sslcertpath '$WORKDIR/certs' ") + fmconf+=(" sslcertck sslcertpath '$MAILDIRS/certs' ") fi @@ -331,11 +331,10 @@ set imap_pass = "${password}" # set imap_peek = yes EOF unset password - print "source $tmp" >> $MUTTDIR/password + print "source '$tmp'" > $TMPDIR/muttpass (sleep 1; - cp /dev/null $MUTTDIR/password - cp /dev/null $tmp - unlink $tmp + cp /dev/null $TMPDIR/muttpass + unlink $tmp # secure delete in ram ) & ${=mutt} -F $MUTTDIR/rc -f ${iproto}://${ilogin}@${host}${folder} diff --git a/src/zlibs/filters b/src/zlibs/filters @@ -45,23 +45,25 @@ update() { maildirmake $MAILDIRS/unsorted.ml ${=mkdir} $MAILDIRS/outbox + ###### # MUTT ${=mkdir} $MUTTDIR + ${=mkdir} $MUTTDIR/cache rm -f $MUTTDIR/rc cat<<EOF > $MUTTDIR/rc # mutt config generated by Jaro Mail unset use_domain -set folder = $MAILDIRS -set spoolfile = $MAILDIRS/known/ -set record = $MAILDIRS/sent/ -set postponed= $MAILDIRS/postponed/ -set tmpdir = $WORKDIR/cache +set folder = '$MAILDIRS' +set spoolfile = '$MAILDIRS/known/' +set record = '$MAILDIRS/sent/' +set postponed= '$MAILDIRS/postponed/' +set tmpdir = '$MUTTDIR/cache' set sendmail = "$WORKDIR/bin/jaro -q queue" -set header_cache= $WORKDIR/cache +set header_cache= '$MUTTDIR/cache' set maildir_header_cache_verify=no set editor = "$WORKDIR/bin/jaro -q edit" -set mailcap_path = "$WORKDIR/.mutt/mailcap:$WORKDIR/mailcap:$HOME/.mailcap:/etc/mailcap:/etc/mailcap:/usr/etc/mailcap:/usr/local/etc/mailcap" +set mailcap_path = "$MUTTDIR/mailcap:$MAILDIRS/mailcap:$HOME/.mailcap:/etc/mailcap:/etc/mailcap:/usr/etc/mailcap:/usr/local/etc/mailcap" # Little Brother Database set query_command = "$WORKDIR/bin/jaro -q complete '%s'" @@ -70,18 +72,24 @@ macro index,pager A "<pipe-message>$WORKDIR/bin/jaro -l whitelist -q learn all<e macro index,pager z "<pipe-message>$WORKDIR/bin/jaro -l blacklist -q learn sender<enter>" "add sender to blacklist" # mailboxes in order of priority -source $MUTTDIR/mboxes +source '$MUTTDIR/mboxes' # specific configuration files -source $MUTTDIR/gpg -source $MUTTDIR/crypto -source $MUTTDIR/general -source $MUTTDIR/formats -source $MUTTDIR/keybindings -source $MUTTDIR/identity -source $MUTTDIR/password -source $MUTTDIR/colors -source $WORKDIR/Mutt.txt +source '$WORKDIR/.mutt/gpg' +source '$WORKDIR/.mutt/crypto' +source '$WORKDIR/.mutt/general' +source '$WORKDIR/.mutt/formats' +source '$WORKDIR/.mutt/keybindings' +source '$WORKDIR/.mutt/colors' +source '$MAILDIRS/Identity' +source '$TMPDIR/muttpass' +EOF + +# support user made configuration of mutt + { test -r $MAILDIRS/Mutt.txt } && { + print "source '$MAILDIRS/Mutt.txt'" >> $MUTTDIR/rc } + +cat <<EOF >> $MUTTDIR/rc ## end of Jaro Mail generated muttrc #################################### @@ -121,7 +129,7 @@ application/*; a=${WORKDIR}/tmp && f=\`basename %s\` && rm -f \$a/\$f && cp %s \ EOF # this one is empty and sources files in temp when necessary - touch $MUTTDIR/password + # touch $TMPDIR/muttpass # just the header, will be completed later in procmail loop rm -f $MUTTDIR/mboxes @@ -136,7 +144,7 @@ EOF # SIEVE act "generating sieve filters" id=$datestamp.$RANDOM - sieve=$WORKDIR/sieve.filter + sieve=$MAILDIRS/Sieve.txt lock $sieve rm -f $sieve touch $sieve @@ -193,7 +201,7 @@ MAILDIR=$MAILDIRS JARO=$WORKDIR/bin/jaro DEFAULT=unsorted/ VERBOSE=off -LOGFILE=$WORKDIR/log/procmail.log +LOGFILE=\$MAILDIR/logs/procmail.log SHELL = /bin/sh # VERY IMPORTANT UMASK = 007 # James Bond :-) LINEBUF = 8192 # avoid procmail choke diff --git a/src/zlibs/helpers b/src/zlibs/helpers @@ -255,42 +255,42 @@ cert() { # gmail) cc=Equifax_Secure_Certificate_Authority - if ! [ -r $WORKDIR/certs/${cc}.pem ]; then + if ! [ -r $MAILDIRS/certs/${cc}.pem ]; then - curl -o $WORKDIR/certs/${cc}.pem \ + curl -o $MAILDIRS/certs/${cc}.pem \ "https://www.geotrust.com/resources/root_certificates/certificates/${cc}.cer" openssl x509 -in \ - $WORKDIR/certs/${cc}.pem -fingerprint \ + $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 $WORKDIR/certs/${cc}.pem ]; then - curl -o $WORKDIR/certs/${cc}.pem \ + if ! [ -r $MAILDIRS/certs/${cc}.pem ]; then + curl -o $MAILDIRS/certs/${cc}.pem \ "http://ca.autistici.org/ca.pem" openssl x509 -in \ - $WORKDIR/certs/${cc}.pem \ + $MAILDIRS/certs/${cc}.pem \ -fingerprint -subject -issuer -serial -hash -noout fi notice "Aut/Inv CA succesfully installed" # riseup) cc=RiseupCA - if ! [ -r $WORKDIR/certs/${cc}.pem ]; then - curl -o $WORKDIR/certs/${cc}.pem "https://help.riseup.net/assets/43052/RiseupCA.pem" + if ! [ -r $MAILDIRS/certs/${cc}.pem ]; then + curl -o $MAILDIRS/certs/${cc}.pem "https://help.riseup.net/assets/43052/RiseupCA.pem" openssl x509 -in \ - $WORKDIR/certs/${cc}.pem \ + $MAILDIRS/certs/${cc}.pem \ -fingerprint -subject -issuer -serial -hash -noout fi notice "Riseup CA succesfully installed" act "refreshing certificates" - c_rehash $WORKDIR/certs > /dev/null + c_rehash $MAILDIRS/certs > /dev/null if [ $? != 0 ]; then - error "Error refreshing certificates in $WORKDIR/certs" - c_rehash $WORKDIR/certs + error "Error refreshing certificates in $MAILDIRS/certs" + c_rehash $MAILDIRS/certs fi notice "Done importing most common certificates." return 0 diff --git a/src/zlibs/locking b/src/zlibs/locking @@ -63,7 +63,7 @@ pidcheck() { # check if lock belongs to us act "Owner (${lockpid}) still running, waiting release..." sleep 1; continue else - act "Owner (pid ${_pid}) not running, taking over the lock" + act "Owner (${lockpid}) not running, taking over the lock" rm -f ${1}.pid; echo "$$" > ${1}.pid _prun=0 fi @@ -84,8 +84,11 @@ unlock() { pidcheck $1 { test $? = 0 } || { return 1 } - $WORKDIR/bin/dotlock -u ${=@} - { test $? != 0 } && { error "Unable to unlock: $1"; return 1 } + $WORKDIR/bin/dotlock -u "$1" + { test $? = 0 } || { + rm -f "$1.lock" + { test $? = 0 } || { error "Unable to unlock: $1"; return 1 } + } { test -r "${1}.pid" } && { rm -f ${1}.pid } return 0 }