From 69693dcd497a2fae7f6eb7bdeb0545120b2cb0a6 Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Tue, 12 Apr 2022 13:03:53 -0700 Subject: [PATCH] new script to reinject message via sendmail --- sendmail-reinject | 70 +++++++++++++++++++++++++++++++++++++++++ sendmail-reinject.1.pod | 41 ++++++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100755 sendmail-reinject create mode 100644 sendmail-reinject.1.pod diff --git a/sendmail-reinject b/sendmail-reinject new file mode 100755 index 0000000..dfc18d5 --- /dev/null +++ b/sendmail-reinject @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 + +import sys +import argparse +import subprocess + +import email +from email.policy import default +from email.utils import parseaddr, getaddresses + + +def sendmail(recipients, message, sender): + """send message via sendmail""" + cmd = [ + 'sendmail', + '-f', sender, + ] + recipients + print(' '.join(cmd), file=sys.stderr) + subprocess.run( + cmd, + input=message.as_bytes(), + check=True, + ) + + +def main(): + parser = argparse.ArgumentParser( + description="Reinject an email message via sendmail.", + ) + pgroup = parser.add_mutually_exclusive_group(required=True) + pgroup.add_argument( + 'message', nargs='?', type=argparse.FileType('rb'), + help="email message path or '-' for stdin", + ) + pgroup.add_argument( + '-i', '--id', + help="message ID for notmuch extraction", + ) + + args = parser.parse_args() + + if args.id: + import notmuch2 as notmuch + db = notmuch.Database() + query = f'id:{args.id}' + assert db.count_messages(query) == 1, "Message ID does not match exactly one message??" + for msg in db.messages(query): + path = msg.path + break + f = open(path, 'rb') + else: + f = args.message + + # parse the email message + msg = email.message_from_binary_file(f, policy=default) + + sender = parseaddr(msg['from'])[1] + + # extract all recipients + tos = msg.get_all('to', []) + ccs = msg.get_all('cc', []) + resent_tos = msg.get_all('resent-to', []) + resent_ccs = msg.get_all('resent-cc', []) + recipients = [r[1] for r in getaddresses(tos + ccs + resent_tos + resent_ccs)] + + sendmail(recipients, msg, sender) + + +if __name__ == '__main__': + main() diff --git a/sendmail-reinject.1.pod b/sendmail-reinject.1.pod new file mode 100644 index 0000000..ed2ac22 --- /dev/null +++ b/sendmail-reinject.1.pod @@ -0,0 +1,41 @@ +=encoding utf8 + +=head1 NAME + +sendmail-reinject - reinject an e-mail via sendmail + +=head1 SYNOPSIS + +B B + +B B<-> + +B B<--id> B + +=head1 DESCRIPTION + +B reinjects a message to your MTA via sendmail. +The message is read in (via path, stdin, or from notmuch via message +ID), the sender and recipients are extracted, and the appropriate +senmdail command is contructed to resent the message. + + +=head1 OPTIONS + +=over 4 + +=item B<--id>,B<-i> B + +Message ID of message to reinject as know to a local notmuch database. +Assumes the python3-notmuch package is available. + +=item B<--help>, B<-h> + +Show usage instructions. + +=back + + +=head1 AUTHOR + +B and this manpage were written by Jameson Graef Rollins. -- 2.35.1