Automatic winmail.dat decoding

From CLUG Wiki

Jump to: navigation, search

Debian Logo Warning: This is a Debian-centric page

This page is written by a Debian user with Debian in mind. Thus, he liberally uses apt-get, and assumes that everything will work exactly the same for you.

If you don't run Debian (or something based on it like Ubuntu), it won't, so please find the differences and add them to this page.


newpage icon WARNING: This is a new page.

This is a new page, and might contain technically incorrect information. Please use at your own risk. If you are able to correct any errors or expand this document, please do so.


There are two different sets of instructions, because the ytnef package isn't available in sarge.

Post-Sarge (Etch / Sid)

Install the ytnef decoder:

# apt-get install ytnef libmailtools-perl

Now incorporate this section into your .procmailrc above the final delivery:

####################################################################
# TNEF Attachments
:0
* ^X-MS-TNEF-Correlator
{
  :0 fw B
  * winmail.dat
  |/usr/bin/ytnef-filter
}

Done.

Sarge

Install the tnef decoder:

# apt-get install tnef libmailtools-perl

Install this hacked version of ytnef-filter into /usr/local/bin

#!/usr/bin/perl
use MIME::Parser;
use MIME::Entity;
use Mail::Mailer;
use File::Temp 'tempdir';

my $mail_dir = tempdir ("ytnefXXXX", TMPDIR => 1, CLEANUP => 1);
my $reader = "/usr/bin/tnef";
my $output_dir = "$mail_dir/output";

mkdir($output_dir);

my $parser = new MIME::Parser;
my $filer = new MIME::Parser::FileInto;
$filer->init($mail_dir);

$parser->filer ($filer);
$parser->output_dir($mail_dir);

$entity = $parser->parse ( \*STDIN );

processParts($entity);

$entity->print( \*STDOUT );

$entity->purge;
$parser->filer->purge;

sub processParts {
    my $entity = shift;
    if ($entity->parts) {
        for $part ($entity->parts) {
            processParts($part);
        }
    } else {
        if ( $entity->mime_type =~ /ms-tnef/i ) {
            if ($bh = $entity->bodyhandle) {
                $io = $bh->open("r");
                open(FPTR, ">$output_dir/winmail.dat");
                while (defined($_ = $io->getline)) {
                    print FPTR $_;
                }
                close(FPTR);
                $io->close;

                `$reader -C $output_dir -f $output_dir/winmail.dat`;
                `rm -f $output_dir/winmail.dat`;

                opendir(DIR, $output_dir)
                    or die "Can't open directory $output_dir: $!";
                my @files = map { $output_dir."/".$_ }
                    grep { !/^\./ }
                    readdir DIR;
                closedir DIR;

                for my $file ( @files ) {
                    my $mimetype = "application/binary";
                    my $disposition = "attachment";

                    $mimetype = "text/calendar" if ($file =~ m/\.vcf$/);
                    $mimetype = "text/x-vcard"  if ($file =~ m/\.vcard$/);

                    $disposition = "inline"     if ($file =~ m/\.vcf$/);
                    $disposition = "inline"     if ($file =~ m/\.vcard$/);

                    if ($mimetype eq "application/binary") {
                        $qfile = quotemeta $file;
                        $filetype = `file -bi $qfile`;
                        chomp $filetype;
                        $mimetype = $filetype if ($filetype ne "");
                    }
                    $entity->attach(
                            Path => $file,
                            Type => $mimetype,
                            Disposition => $disposition,
                            Encoding => "-SUGGEST",
                            Top => 0);
                }
            }
        }
    }
}

make it executable

# chmod 755 /usr/local/bin/ytnef-filter

Now incorporate this section into your .procmailrc above the final delivery:

####################################################################
# TNEF Attachments
:0
* ^X-MS-TNEF-Correlator
}
  :0 fw B
  * winmail.dat
  |/usr/local/bin/ytnef-filter
}

Done.