summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Ludikovsky <peter@ludikovsky.name>2016-08-02 16:04:55 +0200
committerPeter Ludikovsky <peter@ludikovsky.name>2016-08-02 16:04:55 +0200
commit64f7a9614568e3d42bcddc4f523dfc691f360ca8 (patch)
tree2ce95952690378163393dee73e4e4caa50b3c9f2
parent73e35d529ed91ff538a32e5317197a407392404e (diff)
Verbesserter Prozess plus Service-File & Installer
- Statt sa-learn wird nun spamc verwendet - Logik für die Bewegung von Nachrichten optimiert - Benutzer als Parameter - (Fast) alle Optionen parametrisiert & überschreibbar - systemd .service, mit User als Parameter - Installation per make
-rw-r--r--Makefile9
-rwxr-xr-xjunker.sh115
-rw-r--r--junker@.service11
3 files changed, 113 insertions, 22 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..12d6e79
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,9 @@
+all: install
+
+install: install-systemd
+
+install-systemd: install-junker
+ install -o root -g root -m 644 junker@.service $(PREFIX)/usr/lib/systemd/system/junker@.service
+
+install-junker:
+ install -o root -g root junker.sh $(PREFIX)/usr/bin/junker.sh
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} )
diff --git a/junker@.service b/junker@.service
new file mode 100644
index 0000000..fe68add
--- /dev/null
+++ b/junker@.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=inotfy-based spam/ham learner
+
+[Service]
+Type=simple
+ExecStart=/usr/bin/junker.sh %i
+ExecReload=/bin/kill -HUP $MAINPID
+
+[Install]
+WantedBy=multi-user.target
+Requires=spamassassin.service