Skip to content

Instantly share code, notes, and snippets.

@sajith
Last active June 30, 2021 13:54
Show Gist options
  • Save sajith/9ea4287c674e0541579bc50235d348da to your computer and use it in GitHub Desktop.
Save sajith/9ea4287c674e0541579bc50235d348da to your computer and use it in GitHub Desktop.
What's in Mailman's pickles?
#! /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