diff options
Diffstat (limited to 'junker.sh')
-rwxr-xr-x | junker.sh | 115 |
1 files changed, 93 insertions, 22 deletions
@@ -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} ) |