commit a4c584412c9dc16732c2201b3b2aeca88225c05f
parent 68834784349efbe0e38388d9415f2765283698e1
Author: Jaromil <jaromil@dyne.org>
Date: Tue, 18 Sep 2012 21:58:32 +0200
tighter locking
Diffstat:
5 files changed, 74 insertions(+), 31 deletions(-)
diff --git a/src/jaro b/src/jaro
@@ -211,25 +211,54 @@ GNOMEKEY=0
cleanexit() {
func "Clean exit procedures"
- # 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
+ unset name login host protocol port password auth folders accountopt
+
+ # security check
+ { test "$TMPDIR" = "" } && {
+ error "Temporary directory not defined"
+ act "skipping cleanup, this might leave private traces."
+ return 1
+ }
+
+ # first delete dirs
+ for d in `find -O3 $TMPDIR/ -maxdepth 1 -type d`; do
+ { test "$d" = "$TMPDIR/" } || { ${=rm} -r ${d} }
+ done
+
+ # then locks, with a warning
+ for l in `find -O3 $TMPDIR/ -maxdepth 1 -type f -name '*.lock'`; do
+ lname=`basename ${(s:.lock:)l}`
+
+ # skip if in course of unlink - parallel operation, see unlink()
+ { test -r ${TMPDIR}/${lname}.unlink } && { continue }
+
+ pid="$lname.pid"
+ if [ -r ${pid} ]; then
+ error "forced removal of lock created by pid $pid: $lname"
+ rm -f ${TMPDIR}/${pid}
+ else
+ error "forced removal of lock created by unknown pid: $lname"
+ fi
+ rm -f ${TMPDIR}/${lock}
+
+ # remove the actual file
+ if [ -r ${TMPDIR}/$lname ]; then ${=rm} ${TMPDIR}/$lname
+ else error "stale lock: locked file not found"; fi
+
+ done
+
# { test $TMPRAM = 1 } && { rmdir $TMPDIR }
- unset typeset -h name login host protocol port password auth folders accountopt
}
# make sure tmp is wiped from sensitive data in case of sigINT
TRAPINT() {
error "Caught signal, aborting operations."
- { test $CLEANEXIT = 1 } && { cleanexit }
- error "Forced removal of locks"
- { test $TMPDIR } && {
- for l in `find $TMPDIR/`; do
- ${=rm} $l; done
- }
+
+ { test $CLEANEXIT = 1 } && {
+ error "Forced removal of locks"
+ cleanexit }
+
if [ "$DEBUG" = "1" ]; then return 1
else exit 1; fi
}
@@ -294,7 +323,7 @@ option_value() {
usage() {
- cat <<EOF
+ cat <<EOF | more
Jaro Mail $VERSION - your humble and faithful electronic postman
Copyright (C) 2010-2012 by Jaromil @ Dyne.org, License GNU GPL v3+
@@ -317,7 +346,7 @@ Options:
-h print this help
-v version information for this tool
- -q run quietly without printing informations
+ -q run quietly without printing information
-n dry run, show operations without executing them
-D print debugging information at runtime
@@ -355,7 +384,7 @@ Please report bugs on <http://bugs.dyne.org>.
EOF
}
-# TODO: For more informations on Jaro Mail read the manual: man jaro
+# TODO: For more information on Jaro Mail read the manual: man jaro
typeset -A subcommands_opts
main()
@@ -380,6 +409,8 @@ main()
subcommands_opts[peek]="R -readonly=R"
subcommands_opts[open]="R -readonly=R"
+ subcommands_opts[help]=""
+
subcommands_opts[update]=""
subcommands_opts[stat]=""
@@ -508,6 +539,8 @@ main()
update) update ;;
+ help) CLEANEXIT=0; usage ;;
+
search) CLEANEXIT=0; search ${PARAM} ;;
stat) CLEANEXIT=0; stats ${PARAM} ;;
diff --git a/src/zlibs/email b/src/zlibs/email
@@ -82,6 +82,7 @@ fetchall() {
done
return $res
}
+
fetch() {
{ test "$account" = "" } && {
fetchall; return $? }
@@ -267,8 +268,8 @@ EOF
act "Mail sent succesfully"
# whitelist those to whom we send mails
cat ${mail} | $WORKDIR/bin/jaro -q learn recipient
- ${=rm} ${mail} &
- unlink ${smtp} &
+ ${=rm} ${mail}
+ unlink ${smtp}
fi
done
unlink $tmp
diff --git a/src/zlibs/filters b/src/zlibs/filters
@@ -116,8 +116,9 @@ EOF
#######
# SIEVE
act "generating sieve filters"
- id=$RANDOM
+ id=$datestamp.$RANDOM
sieve=$WORKDIR/sieve.filter
+ lock $sieve
rm -f $sieve
touch $sieve
chmod 600 $sieve
@@ -319,6 +320,7 @@ if header :is "X-Spam-Flag" "YES" {
EOF
+unlock $sieve
#### PROCMAIL
diff --git a/src/zlibs/locking b/src/zlibs/locking
@@ -35,21 +35,31 @@ lock() {
return 0 ;;
esac
}
+
newlock() { # create locked
func "creating locked file: $1"
touch $1
chmod 600 $1
lock $1
}
-unlock() {
- func "unlock: $1"
+
+pidcheck() { # check if lock belongs to us
lockpid="`cat ${1}.pid`"
{ test -r "${1}.pid" } && {
{ test "$$" != "$lockpid" } && {
- error "Unlock attempt by different PID: $1"
- error "Created by $lockpid now $$ is trying to unlock"
+ error "Unlock attempt by different PID on `basename $1`"
+ act "created by $lockpid now we ($$) try to unlock"
+ act "skipped removal: $1"
return 1 }
}
+ return 0
+}
+
+unlock() {
+ func "unlock: $1"
+
+ pidcheck $1
+ { test $? = 0 } || { return 1 }
$WORKDIR/bin/dotlock -u ${=@}
{ test $? != 0 } && { error "Unable to unlock: $1"; return 1 }
@@ -59,22 +69,19 @@ unlock() {
unlink() { # delete a file that we are locking
func "unlink: $1"
# use with care! this can permanently erase currently locked files
- # only the locking PID should use it on its own locks
- { test -r "${1}.pid" } && {
- lockpid="`cat ${1}.pid`"
- { test "$$" != "$lockpid" } && {
- error "Unlock attempt by different PID: $1"
- error "Created by $lockpid now $$ is trying to unlock"
- return 1 }
- }
+ pidcheck $1
+ { test $? = 0 } || { return 1 }
+ # signal that is unlinking (for parallel operation)
+ touch ${1}.unlink
(
${=rm} ${1}
touch ${1}
$WORKDIR/bin/dotlock -d -f ${1}
{ test $? != 0 } && { error "Unable to unlink: $1"; return 1 }
{ test -r "${1}.pid" } && { rm -f ${1}.pid }
+ rm -f ${1}.unlink
) &!
return 0
}
diff --git a/src/zlibs/search b/src/zlibs/search
@@ -123,7 +123,7 @@ EOF
} # DRYRUN
${=rm} $TMPDIR/search.db.$id
${=rm} $TMPDIR/search.conf.$id
- ${=rm} $TMPDIR/search.result.$id
+ ${=rm} -r $TMPDIR/search.result.$id
return $exitcode
}