Last active
June 30, 2021 13:54
-
-
Save sajith/9ea4287c674e0541579bc50235d348da to your computer and use it in GitHub Desktop.
What's in Mailman's pickles?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env python2.7 | |
""" | |
A script to export pickle-ed (*.pck*) files into a corresponding | |
human-readable form. This was specifically written to read such | |
files created by Mailman 2, so this is all Python 2.7 | |
I was given copies of /var/lib/mailman and /etc/mailman. In order | |
to go through the files under them, I used Docker (we need old | |
Mailman libraries to unpickle some of those files, and that is a | |
little easier with Docker), like so: | |
$ docker pull python:2.7.18-slim-stretch | |
$ docker run -it -v $(pwd)/var/lib/mailman:/var/lib/mailman \ | |
python:2.7.18-slim-stretch /bin/bash | |
(Debian Buster is newer, and Buster's mailman also is a little | |
newer. I wanted consistency with the files that I had, hence | |
Stretch.) | |
Once inside the container, I did this: | |
# apt update && apt install mailman | |
# pip install fs | |
(The python-fs package from Debian didn't work for me.) | |
And then I ran this script, and it created a bunch of `*.unpickled` | |
files under `./unpickled`. | |
""" | |
import os | |
import sys | |
import pickle | |
import pprint | |
from fs import open_fs | |
def write_data(data, outdir, outfile): | |
outpath = os.path.join(outdir, outfile) | |
with open(outpath, 'wb') as outf: | |
try: | |
outf.write(data) | |
except Exception as err: | |
sys.stderr.write("Could not write to {}; error:{} ". | |
format(outpath, err)) | |
else: | |
print("Wrote {}.".format(outpath)) | |
def find_and_unpickle(indir, outdir): | |
total = 0 | |
written = 0 | |
errors = 0 | |
directory = open_fs(indir) | |
try: | |
for path in directory.walk.files(filter=['*.pck', '*.pck.last']): | |
total = total + 1 | |
with directory.open(path, 'rb') as pickle_file: | |
print("\nLoading {}...".format(pickle_file.name)) | |
try: | |
data = pickle.load(pickle_file) | |
except Exception as perr: | |
sys.stderr.write("Error loading {}, error: {}". | |
format(pickle_file.name, perr)) | |
errors = errors + 1 | |
outfile = pickle_file.name.replace('/', '_') + '.unpickled' | |
write_data(pprint.pformat(data), outdir, outfile) | |
written = written + 1 | |
except Exception as fserr: | |
sys.stderr.write("\nError reading {}: {}\n". | |
format(path, fserr)) | |
errors = errors + 1 | |
return total, written, errors | |
if __name__ == '__main__': | |
INDIR = '/var/lib/mailman' | |
OUTDIR = './unpickled' | |
if not os.path.exists(OUTDIR): | |
os.mkdir(OUTDIR) | |
total, written, errors = find_and_unpickle(INDIR, OUTDIR) | |
print("\nFound {} of what looks like pickles.".format(total)) | |
print("Re-wrote {}, errors: {}.\n".format(written, errors)) | |
# Local Variables: | |
# mode: python | |
# End: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment