From 64f7a9614568e3d42bcddc4f523dfc691f360ca8 Mon Sep 17 00:00:00 2001 From: Peter Ludikovsky Date: Tue, 2 Aug 2016 16:04:55 +0200 Subject: Verbesserter Prozess plus Service-File & Installer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- Makefile | 9 +++++ junker.sh | 115 +++++++++++++++++++++++++++++++++++++++++++++----------- junker@.service | 11 ++++++ 3 files changed, 113 insertions(+), 22 deletions(-) create mode 100644 Makefile create mode 100644 junker@.service 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 -- cgit v1.2.3