Skip to content

Instantly share code, notes, and snippets.

@mvsantos
Last active June 8, 2017 13:36
Show Gist options
  • Save mvsantos/e00eb8d9ac9c945b5dcc5bc824b7c261 to your computer and use it in GitHub Desktop.
Save mvsantos/e00eb8d9ac9c945b5dcc5bc824b7c261 to your computer and use it in GitHub Desktop.
Start a mock smtp server which can be useful for local dev environment and may also be bundled into a Docker image
#!/usr/bin/env bash
# Authors: Marcos Santos, 2017
# License: MIT
# This script starts a mock smtp server and stores the emails "sent" in a local
# directory (i.e. /tmp/smtp-sink ).
# This comes in handy when running tests on a dev environment.
#
# This script requires the binary smtp-sink which is normally shipped within
# Postfix package. See http://www.postfix.org/smtp-sink.1.html
# Alternatively, the Python onliner below can be used to start a simple mock
# stmp server and write the result to stdout
# sudo python -m smtpd -n -c DebuggingServer 127.0.0.1:25
# Immediately exit this script if ..
# any internal command exits with non-zero status
set -o errexit
# any unbound variables are used
set -o nounset
# any pipe fails
set -o pipefail
set_cmd_full_path() {
# Prefix the command names with the string CMD_
local cmd_name="CMD_${1}"
local bin_name="$2"
for P in /bin /usr/bin /usr/sbin;
do
if [[ -x "$P/$bin_name" ]]; then
export "${cmd_name}"="$P/$bin_name"
break
fi
done
# The exclamation mark preceding the variable name expands the check to the
# variable's value instead of the variable string name itself. And the ":-"
# sets the initiate the variable and avoid triggering 'nonunset' early exit.
if [[ -z "${!cmd_name:-}" ]]; then
/bin/echo "Error: The binary '${bin_name}' was not found in any of the pre-defined paths."
exit 128
fi
}
set_cmd_full_path BIN_WHOAMI whoami
set_cmd_full_path BIN_MKDIR mkdir
set_cmd_full_path BIN_CHOWN chown
set_cmd_full_path BIN_FIND find
set_cmd_full_path BIN_SMTPSINK smtp-sink
if [[ "$($CMD_BIN_WHOAMI)" != "root" ]]; then
/bin/echo "Error: This script must be run by the 'root' user because it requires privilege changes."
exit 128
fi
$CMD_BIN_MKDIR -p /tmp/smtp-sink
$CMD_BIN_CHOWN -R nobody:nobody /tmp/smtp-sink
$CMD_BIN_FIND /tmp/smtp-sink -type d -exec chmod 755 {} \;
$CMD_BIN_FIND /tmp/smtp-sink -type f -exec chmod 644 {} \;
# -u Switch to the specified user privileges after opening the network socket
# and optionally changing the process root directory.
# -R Change the process root directory to the specified location. This option
# requires super-user privileges (-u).
# -d Dump each mail transaction to a single-message file whose name is
# created by expanding the dump-template via strftime(3) and appending a
# pseudo-random hexadecimal number.
# (example: "%Y%m%d%H/%M." expands into "2006081203/05.809a62e3").
$CMD_BIN_SMTPSINK -u nobody -R /tmp/smtp-sink -d "maildir/%Y-%m-%d/mail.%H.%M." 127.0.0.1:25 1024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment