diff options
author | Peter Ludikovsky <peter@ludikovsky.name> | 2016-08-02 16:04:55 +0200 |
---|---|---|
committer | Peter Ludikovsky <peter@ludikovsky.name> | 2016-08-02 16:04:55 +0200 |
commit | 64f7a9614568e3d42bcddc4f523dfc691f360ca8 (patch) | |
tree | 2ce95952690378163393dee73e4e4caa50b3c9f2 | |
parent | 73e35d529ed91ff538a32e5317197a407392404e (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-- | Makefile | 9 | ||||
-rwxr-xr-x | junker.sh | 115 | ||||
-rw-r--r-- | junker@.service | 11 |
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 @@ -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 |