docker-images/images/imap-download/run.sh

114 lines
3.1 KiB
Bash
Raw Normal View History

2021-05-25 21:19:37 +00:00
#!/usr/bin/env bash
2021-05-26 12:44:47 +00:00
if [[ -z "${TARGET_UID}" ]]; then
echo "Error: The TARGET_UID environment variable was not specified.";
exit 1;
fi
if [[ -z "${TARGET_GID}" ]]; then
echo "Error: The TARGET_GID environment variable was not specified.";
exit 1;
fi
if [[ "${EUID}" -ne 0 ]]; then
echo "Error: This Docker container must run as root because fetchmail is a pain, and to allow customisation of the target UID/GID (although all possible actions are run as non-root users)";
exit 1;
fi
dir_newmail="/tmp/maildir/Mail/new";
target_dir="/mnt/output";
fetchmail_uid="$(id -u "fetchmail")";
fetchmail_gid="$(id -g "fetchmail")";
2021-05-25 21:19:37 +00:00
temp_dir="$(mktemp --tmpdir -d "imap-download-XXXXXXX")";
on_exit() {
rm -rf "${temp_dir}";
}
trap on_exit EXIT;
2021-05-26 12:44:47 +00:00
run_as_user() {
run_as_uid="${1}"; shift;
run_as_gid="${1}"; shift;
if [[ -z "${run_as_uid}" ]]; then
echo "run_as_user: No target UID specified.";
return 1;
fi
if [[ -z "${run_as_gid}" ]]; then
echo "run_as_user: No target GID specified.";
return 2;
fi
# Ref https://github.com/SinusBot/docker/pull/40
# WORKAROUND for `setpriv: libcap-ng is too old for "all" caps`, previously "-all" was used here
# create a list to drop all capabilities supported by current kernel
cap_prefix="-cap_";
caps="$cap_prefix$(seq -s ",$cap_prefix" 0 "$(cat /proc/sys/kernel/cap_last_cap)")";
setpriv --inh-caps="${caps}" --reuid "${run_as_uid}" --clear-groups --regid "${run_as_gid}" "$@";
return "$?";
}
2021-05-25 21:19:37 +00:00
do_fetchmail() {
log_msg "Starting fetchmail";
while :; do
2021-05-26 12:44:47 +00:00
run_as_user "${fetchmail_uid}" "${fetchmail_gid}" fetchmail --mda "/usr/bin/procmail -m /srv/procmail.conf";
exit_code="$?";
if [[ "$exit_code" -eq 127 ]]; then
log_msg "setpriv failed, exiting with code 127";
exit 127;
fi
log_msg "Fetchmail exited with code ${exit_code}, sleeping 60 seconds";
sleep 60
done
2021-05-25 21:19:37 +00:00
}
log_msg() {
echo "$(date -u +"%Y-%m-%d %H:%M:%S") imap-download: $*";
}
mkdir -p "${dir_newmail}";
2021-05-25 21:19:37 +00:00
2021-05-26 12:44:47 +00:00
# Moves an attachment to the output directory as the target uid/gid.
# chowns the file before moving.
# $1 The path to the file to move.
move_attachment() {
local filename="${1}";
chown "${TARGET_UID}:${TARGET_GID}" "${filename}";
run_as_user "${TARGET_UID}" "${TARGET_GID}" mv "${filename}" "${target_dir}";
}
2021-05-25 21:19:37 +00:00
do_attachments() {
while :; do # : = infinite loop
# Wait for an update
# inotifywait's non-0 exit code forces an exit for some reason :-/
inotifywait -qr --event create --format '%:e %f' "${dir_newmail}";
while read -r filename; do
log_msg "Processing email ${filename}";
# Move the email to a temporary directory for processing
mv "${filename}" "${temp_dir}";
# Unpack the attachments
munpack -C "${temp_dir}" "${filename}";
# Delete the original email file and any description files
rm "${filename}";
find "${temp_dir}" -iname '*.desc' -delete;
# Move the attachment files to the output directory
while read -r attachment; do
log_msg "Extracted attachment ${attachment}";
chmod 0775 "${temp_dir}/${attachment}";
2021-05-26 12:44:47 +00:00
move_attachment "${attachment}";
2021-05-25 21:19:37 +00:00
done < <(find "${temp_dir}" -type f);
done < <(find "${dir_newmail}" -type f);
done
}
do_fetchmail &
do_attachments