Safely Test Postfix rmail for Legacy UUCP Mail
rmail turns up on hosts where something ancient still delivers mail through UUCP, and this guide shows you how to inspect it safely. It is a compatibility boundary, not a mail client, and checking it takes about fifteen minutes.
The route
Jump straight to the step you need, or tick off Done means at the end.
You need a shell and the Postfix package. Everything here is read-only until the final warning section, and no elevated privileges are needed just to inspect the command or its manual. Do not run a delivery example on a production host unless you have confirmed the recipient, the local mail policy and a way to trace the resulting message.
1. Confirm which rmail is installed
Start with the executable your shell would actually find, so you are not debugging a stray wrapper or an old binary elsewhere on PATH:
$ command -v rmail
/usr/sbin/rmail
$ dpkg-query -W -f='${Package} ${Version}\n' postfix
postfix 3.8.6-1ubuntu0.1
Your path and version can differ; on this box the binary belongs to Postfix. The package version is useful for comparing behaviour across machines, but it is no guarantee every distribution builds the command with the same options.
Checkpoint
The command you are about to examine should belong to the mail transport package you expect. If command -v returns something unexpected, stop and look at that file before sending anything through it.
2. Read the local contract, then spot the version gap
Read the installed manual rather than trusting a remembered sendmail command line:
$ man 8 rmail
It describes rmail user ...: the program handles mail received through UUCP, collapses the From lines that mail.local produces into a single return-path form, then hands the processed message to sendmail. It says outright it is designed for UUCP and sendmail specifically, nothing broader.
The installed binary tells you a bit more than that older manual page does:
$ rmail --help
usage: rmail [-T] [-D domain] user ...
That output belongs to the installed Postfix build, not an invitation to invent a new workflow. It lists -T and -D domain as available options, while the manual stays the primary description of what actually happens to the mail. If you need one of those options, verify its exact behaviour on this same package version in a controlled environment first.
3. Check the failure path without submitting mail
Calling rmail with no recipient is a safe way to probe the interface. It should print usage and return non-zero:
$ rmail </dev/null
usage: rmail [-T] [-D domain] user ...
$ printf 'exit status: %s\n' "$?"
exit status: 64
Exact wording and status can vary by build; what matters is that no recipient means no destination to process. If your install instead hangs waiting for input, press Ctrl-C and check its local documentation before continuing.
Do not swap in a real address just to see what happens. A valid recipient turns this from an interface check into an actual mail submission.
4. Understand the input rmail expects
rmail reads the mail message on standard input and takes one or more recipients as arguments. That input is not a subject line, a filename or a command: it is the historical UUCP message format this wrapper is meant to translate before handing it to the local mail transport.
A conceptual invocation looks like this:
$ rmail [email protected] < uucp-message.txt
That example is deliberately not a delivery test; example.invalid is reserved for documentation and this only illustrates the data flow. Do not build a file of real mail and run this casually: Postfix may accept, queue or forward the message depending on the host's configuration.
When diagnosing an existing UUCP integration, find the process or spool that actually invokes rmail and inspect the hand-off there. Keep the original message while testing; a failed delivery can still leave a queue entry, a bounce or sensitive content sitting in logs.
5. Treat recipient arguments as a security boundary
Recipient arguments normally come from a trusted UUCP transport, not an interactive user. If a script builds the command line from remote data, review its quoting and validation before touching it. Keep every recipient as a separate argument, and never assemble an unquoted shell command from a UUCP path or header.
-D domain is not a harmless display option: it changes domain-related processing inside the program. Use it only when the configured UUCP-to-mail mapping needs it, and record the expected address transformation before testing. -T is similarly implementation-specific on this install; check the local help and watch its effect in a disposable environment rather than dropping it into production by guesswork.
None of this needs sudo. Running a mail wrapper as root only widens the blast radius of malformed input and makes ownership or queue problems harder to trace. Use the account and service context the existing UUCP integration already runs as, and change service configuration only during an approved maintenance window.
6. Verify the hand-off without mailing the outside world
For a real integration test, use a local test recipient or an isolated mail transport agreed with the system owner, and use a message with no sensitive content. Capture the Postfix queue state with the site's existing tools before running it, then check afterwards whether a new entry appeared and whether it was delivered, deferred or rejected. A silent shell prompt only means the next mail component accepted the input, not that a human read it.
Recovery
If a test message got queued, follow the site's normal Postfix queue-management procedure and remove only the message you identified. If the wrapper changed a service unit, cron job or UUCP hook, restore the previous file from the backup made before testing and reload only the affected service. Never delete an entire mail queue as a shortcut.
Common traps
- Expecting a normal mail client. rmail is a UUCP compatibility program; use the site's ordinary submission path for interactive mail.
- Testing with a real address first. Run the no-recipient check, then move to an isolated recipient. A valid address can create a queue entry or send mail outbound.
- Trusting the manual alone. The installed binary reports
-Tand-D domainthat the local manual's shorter synopsis does not mention. Record the package version when comparing hosts. - Running as root to fix a lookup failure. A missing recipient, wrong domain mapping or absent UUCP input is a configuration problem; extra privilege will not make the data valid.
- Deleting evidence. Keep the original input, queue identifier and relevant log lines until you actually understand what happened. They are usually the fastest route to recovery.
Done means
- Identified the resolved executable and installed Postfix version.
- Read the local manual and checked the binary's actual usage output.
- Ran a no-recipient check that failed safely with no message submitted.
- Understand the input model: UUCP mail on standard input, recipients as arguments.
- Any integration test uses an isolated recipient, preserves the input, and has a queue and log recovery plan.
- No service, queue, credential or persistent config was changed during the read-only checks.