summaryrefslogtreecommitdiff
path: root/junker.sh
diff options
context:
space:
mode:
Diffstat (limited to 'junker.sh')
-rwxr-xr-xjunker.sh115
1 files changed, 93 insertions, 22 deletions
diff --git a/junker.sh b/junker.sh
index 28fdf1a..964f406 100755
--- a/junker.sh
+++ b/junker.sh
@@ -2,34 +2,63 @@
[ ! -z "${DEBUG}" ] && set -x
-BASE=$1
+USER=${1:-$( id -un )}
+HOME="$( getent passwd $USER | cut -d ':' -f 6 )"
+BASE="${HOME}"/Maildir
INOTIFY='/usr/bin/inotifywait'
-INOTIFY_EVENTS='close_write,moved_to'
+INOTIFY_EVENTS='moved_to,moved_from'
INOTIFY_OPTIONS='--monitor --recursive --event'" ${INOTIFY_EVENTS}"
-SALEARN=/usr/bin/sa-learn
-SAOPTS=--no-sync
-LOGS=$2
+LOG=/var/log/junker/${USER}.log
+SPAMC='/usr/bin/spamc'
+
+JUNK="${BASE}/Junk"
+NONJUNK="${BASE}/Junk"
+TRASH="${BASE}/Trash"
+SENT="${BASE}/Sent"
+DRAFTS="${BASE}/Drafts"
+
+if [[ -f "${HOME}/.junkerrc" && -r "${HOME}/.junkerrc" ]]
+then
+ . "${HOME}/.junkerrc"
+fi
function OpenLog {
- exec 3>>"${LOGS}/junker.log"
+ exec 3>>"${LOG}"
exec 1>&3
exec 2>&3
- echo -e "$( date +'%Y%m%d %H:%M:%S' )\tLog opened"
+ Log "Log opened"
}
function CloseLog {
- echo -e "$( date +'%Y%m%d %H:%M:%S' )\tLog closed"
+ Log "Log closed"
exec 3>&-
}
+function Log {
+ echo -e "$( date +'%Y%m%d %H:%M:%S' )\t$@"
+}
function Cleanup {
- RunAndLog echo ${SALEARN} --sync
CloseLog
exit 0
}
-function RunAndLog {
- echo -e "$( date +'%Y%m%d %H:%M:%S' )\t$@"
- $@
+function Learn {
+ [[ "$1" != "ham" && "$1" != "spam" ]] && return 3
+ [[ ! -f "$2" || ! -r "$2" ]] && return 4
+ Log "Learning $2 as $1"
+ exec 9<"$2"
+ ${SPAMC} --learntype $1 <&9
+ ret=$?
+ case $ret in
+ 0) Log "Done"
+ ;;
+ 5) Log "Learned"
+ ;;
+ 6) Log "Already known"
+ ;;
+ *) Log "Error occured, code $ret"
+ ;;
+ esac
+ exec 9<&-
}
function Reload {
@@ -37,6 +66,34 @@ function Reload {
OpenLog
}
+if [ ! -d "${BASE}" ]
+then
+ echo "Error: Mail directory not found at ${BASE}, exiting" >&2
+ exit 1
+fi
+if [ ! -d "$( dirname ${LOG} )" ]
+then
+ echo "Error: Log directory not found at ${LOG}, exiting" >&2
+ exit 1
+fi
+if [ ! -x ${INOTIFY} ]
+then
+ echo "Error: inotifywait not found, check path" >&2
+ exit 1
+fi
+if [ ! -x ${SPAMC} ]
+then
+ echo "Error: spamc not found, check path" >&2
+ exit 1
+fi
+checkfile=$( mktemp )
+${SPAMC} --learntype forget <$checkfile
+if [ $? -eq 74 ]
+then
+ echo "Error: spamd doesn't allow connections, needs --allow-tell" >&2
+ exit 1
+fi
+
OpenLog
trap "Cleanup" EXIT SIGINT SIGTERM
@@ -44,18 +101,32 @@ trap "Reload" SIGHUP
while IFS=' ' read -r dir event file
do
- if [[ "${event}" == *MOVED_TO* && "${dir}" == */Junk/ ]]
+ if [[ "${dir}" != */cur/ && "${dir}" != */new/ ]]
+ then
+ continue
+ fi
+ case "${dir}" in
+ ${TRASH}/*)
+ ;&
+ ${SENT}/*)
+ ;&
+ ${DRAFTS}/*)
+ continue
+ esac
+ if [[ "${event}" == *MOVED_TO* && "${dir}" == "${JUNK}"/cur/ ]]
+ then
+ Learn "spam" "${dir}/${file}"
+ elif [[ "${event}" == *MOVED_TO* && "${dir}" == "${JUNK}"/new/ ]]
+ then
+ Learn "spam" "${dir}/${file}"
+ elif [[ "${event}" == *MOVED_TO* && "${dir}" == "${NONJUNK}"/cur/ ]]
then
- RunAndLog echo ${SALEARN} ${SAOPTS} --forget "${dir}/${file}"
- RunAndLog echo ${SALEARN} ${SAOPTS} --spam "${dir}/${file}"
- elif [[ "${event}" == *MOVED_TO* && "${dir}" == */!Junk/ ]]
+ Learn "ham" "${dir}/${file}"
+ elif [[ "${event}" == *MOVED_FROM* && "${dir}" == "${JUNK}"/cur/ ]]
then
- RunAndLog echo ${SALEARN} ${SAOPTS} --forget "${dir}/${file}"
- RunAndLog echo ${SALEARN} ${SAOPTS} --ham "${dir}/${file}"
- elif [[ "${event}" == *CLOSE_WRITE* && "${dir}" == */Junk/ ]]
+ Learn "ham" "${dir}/${file}"
+ elif [[ "${event}" == *MOVED_TO* && "${dir}" == ${BASE}/*/new/ ]]
then
- RunAndLog echo ${SALEARN} ${SAOPTS} --spam "${dir}/${file}"
- else
- RunAndLog echo ${SALEARN} ${SAOPTS} --ham "${dir}/${file}"
+ Learn "ham" "${dir}/${file}"
fi
done < <( ${INOTIFY} ${INOTIFY_OPTIONS} --format '%w %e %f' ${BASE} )