Piping for msmtp
msmtp
is a simple programme that can pretend to be sendmail
on your system.
Once configured it will take an input file (or stdin) and use the configured
smtp server to send an email to the appropriate recipient.
Configuring msmtp
This is repeated in many, many places but for completeness here we go... this file is either /etc/msmtprc
or ~/.msmtprc
:
account bengreeneu
host localhost
from benjamin@example.com
port 25
auth on
user benjamin@example.com
password mypasswordissecret
logfile ~/.msmtp.log
tls on
tls_starttls on
tls_certcheck off
Adjust to taste ;-).
Spawn the msmtp
process and pipe to it
To make this nice and easy, I have created a
github repository
that contains the example project and a Makefile
.
The basic steps in this programme are:
- Create two pipes, one for
STDIN
and one forSTDOUT
they are named from the perspective of the parent process (wpipefd
is write from parent to child andrpipefd
is read from child to parent). - Re-assign the file descriptors in the forked process so that
STDIN_FILENO
andSTDOUT_FILENO
are connected to the pipe. - Replace the current executable image in the forked process with the
execv
system call. The new process will have the normal 3 file descriptors:- stdin (
STDIN_FILENO
/ 0) connected towpipefd
- stdout (
STDOUT_FILENO
/ 1) connected torpipefd
- stderr (
STDERR_FILENO
/ 2) this is untouched so will be the same as the parent process... good for debugging!
- stdin (
- Write the email to the pipe, the Linux kernel will buffer the bytes written unless you have some funny kernel configuration.
- Read the output from
rpipefd
until the process closes the other side of therpipefd
(ie. the child process closes stdout or the process terminates).
Further Work
It might be cool to use the techniques learnt here to extend the little shell described here so it can pipe stuff like a more fully featured shell.
Many programmes act differently if stdin is connected to a pipe rather than a tty or pty. Fortunately there are several places that this is covered, please see Using pseudo-terminals (pty) to control interactive programmes. Although the tty and pty stuff is really quite old there are many modern uses, one of which is containers, see Implementing Container Runtime Shim for much more detail than perhaps you would like!