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 92292c69d059846e5e25c682525bc2663defb6be
parent 3ed8455dcf61b7b52233db669bd0de5fb981310d
Author: Jaromil <jaromil@dyne.org>
Date:   Wed,  6 Jun 2012 14:46:12 +0200

tighter file locking and cleanup

Diffstat:
Mdoc/jaromail-manual.org | 1-
Msrc/jaro | 89+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
2 files changed, 55 insertions(+), 35 deletions(-)

diff --git a/doc/jaromail-manual.org b/doc/jaromail-manual.org @@ -85,7 +85,6 @@ and actions involved in managing one's email communication: | MTA | Mail Transport Agent | [[http://www.fetchmail.info][Fetchmail]] | | | Filtering Agent | [[http://www.procmail.org][Procmail]] | | SMTP | Mail Delivery Agent | [[http://msmtp.sourceforge.net][MSmtp]] | - | | Addressbook | [[http://www.spinnaker.de/lbdb][Lbdb]] | #+LATEX: \pagebreak diff --git a/src/jaro b/src/jaro @@ -20,8 +20,8 @@ # this source code; if not, write to: # Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -VERSION=0.1 -DATE=May/2012 +VERSION=0.9 +DATE=Jun/2012 JAROMAILEXEC=$0 typeset -a OLDARGS for arg in ${argv}; do OLDARGS+=($arg); done @@ -165,9 +165,13 @@ ps ax | grep '[g]nome-keyring-daemon' > /dev/null cleanexit() { func "Clean exit procedures" - for f in `ls $TMPDIR/ | grep -v '.lock$'`; do - { test -r $TMPDIR/$f } && { unlink $TMPDIR/$f } - done + # while ( ps ax | grep '[s]rm' > /dev/null + # test $? = 0 ); do sleep 1; done + + # for f in `ls $TMPDIR/ | grep -v '.lock$'`; do + # { test ! -r $TMPDIR/$f.lock } && { unlink $TMPDIR/$f } + # done + # { test $TMPRAM = 1 } && { rmdir $TMPDIR } unset typeset -h name login host protocol port password auth folders accountopt } @@ -183,17 +187,18 @@ TRAPINT() { } lock() { - func "lock: $@" - $WORKDIR/.lbdb/dotlock ${=@} + func "lock: $1" + $WORKDIR/.lbdb/dotlock ${1} case $? in - 1) error "Cannot lock non existing file: $@" + 1) error "Cannot lock non existing file: $1" return 1 ;; - 3) error "Locked file in use: $@" + 3) error "Locked file in use: $1" return 3 ;; - 5) error "Impossible to lock: $@" + 5) error "Impossible to lock: $1" return 5 ;; # success - 0) return 0 ;; + 0) echo "$$" > ${1}.pid + return 0 ;; esac } newlock() { # create locked @@ -201,26 +206,41 @@ newlock() { # create locked touch $1 chmod 600 $1 lock $1 + echo "$$" > ${1}.pid } unlock() { - func "unlock: $@" + func "unlock: $1" + lockpid="`cat ${1}.pid`" + { test "$$" != "$lockpid" } && { + error "Unlock attempt by different PID: $1" + error "Created by $lockpid now $$ is trying to unlock" + return 1 + } $WORKDIR/.lbdb/dotlock -u ${=@} if [ $? != 0 ]; then - error "Unable to unlock: $@" + error "Unable to unlock: $1" return 1 fi + rm -f ${1}.pid return 0 } -locked_unlink() { # delete a file that we are locking - # use with care! this can permanently erase currently locked files - ${=rm} ${1} - touch ${1} - $WORKDIR/.lbdb/dotlock -d -f ${1} -} -unlink() { # lock and delete +unlink() { # delete a file that we are locking func "unlink: $1" - lock ${1} - locked_unlink ${1} & + # use with care! this can permanently erase currently locked files + # only the locking PID should use it on its own locks + lockpid="`cat ${1}.pid`" + { test "$$" != "$lockpid" } && { + error "Unlock attempt by different PID: $1" + error "Created by $lockpid now $$ is trying to unlock" + return 1 + } + ( + ${=rm} ${1} + touch ${1} + $WORKDIR/.lbdb/dotlock -d -f ${1} + rm -f ${1}.pid + ) &! + return 0 } @@ -750,17 +770,17 @@ EOF case $? in 1) notice "No mails for $name" - unlock $tmp + unlink $tmp return 1 ;; 2) error "Invalid or unknown certificate for $host" - unlock $tmp + unlink $tmp return 1 ;; 3) error "Invalid password for user $login at $host" - unlock $tmp + unlink $tmp return 1 ;; *) ;; @@ -776,11 +796,11 @@ EOF fi act "please wait while downloading mails..." - cat $tmp | fetchmail -f - + cat $tmp | fetchmail -f $tmp # TODO: substitute this with cat conf | fetchmail -f - # to avoid writing the password in clear on filesystem - unlock $tmp + 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` @@ -861,10 +881,10 @@ EOF # whitelist those to whom we send mails cat ${mail} | $WORKDIR/bin/jaro -l whitelist -q learn to: ${=rm} ${mail} & - locked_unlink ${smtp} & + unlink ${smtp} & fi done - unlock $tmp + unlink $tmp return 0 } @@ -901,18 +921,18 @@ peek() { error "Error retrieving password for $login on $host" unset password all; return 1 } - tmp=$TMPDIR/muttpasswd.$RANDOM + tmp=$TMPDIR/$host.peek.$RANDOM newlock $tmp cat <<EOF >> $tmp set imap_pass = "${password}" # set imap_peek = yes EOF unset password - echo "source $TMPDIR/muttpasswd" >> $MUTTDIR/password + echo "source $tmp" >> $MUTTDIR/password (sleep 1; cp /dev/null $MUTTDIR/password cp /dev/null $tmp - unlock $tmp + unlink $tmp ) & mutt -F $MUTTDIR/rc -f ${iproto}://${ilogin}@${host}${folder} return $? @@ -1345,11 +1365,12 @@ rmdupes() { notice "Removing duplicates in $folder" c=0 for i in `find ${folder} -type f`; do - formail -D 100000 $tmp <$i \ + # 5MB should be enough ehre? + formail -D 5000000 $tmp <$i \ && rm $i && c=`expr $c + 1` done done - unlock $tmp + unlink $tmp notice "$c duplicates found and deleted" }