• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2
3"""Unpack a MIME message into a directory of files."""
4
5import os
6import email
7import mimetypes
8
9from email.policy import default
10
11from argparse import ArgumentParser
12
13
14def main():
15    parser = ArgumentParser(description="""\
16Unpack a MIME message into a directory of files.
17""")
18    parser.add_argument('-d', '--directory', required=True,
19                        help="""Unpack the MIME message into the named
20                        directory, which will be created if it doesn't already
21                        exist.""")
22    parser.add_argument('msgfile')
23    args = parser.parse_args()
24
25    with open(args.msgfile, 'rb') as fp:
26        msg = email.message_from_binary_file(fp, policy=default)
27
28    try:
29        os.mkdir(args.directory)
30    except FileExistsError:
31        pass
32
33    counter = 1
34    for part in msg.walk():
35        # multipart/* are just containers
36        if part.get_content_maintype() == 'multipart':
37            continue
38        # Applications should really sanitize the given filename so that an
39        # email message can't be used to overwrite important files
40        filename = part.get_filename()
41        if not filename:
42            ext = mimetypes.guess_extension(part.get_content_type())
43            if not ext:
44                # Use a generic bag-of-bits extension
45                ext = '.bin'
46            filename = f'part-{counter:03d}{ext}'
47        counter += 1
48        with open(os.path.join(args.directory, filename), 'wb') as fp:
49            fp.write(part.get_payload(decode=True))
50
51
52if __name__ == '__main__':
53    main()
54