#!/usr/local/bin/perl -w use strict; my %Mime_table; # See RFC-2045. @Mime_table{'A'..'Z', 'a'..'z', 0..9, '+', '/'} = map{scalar(reverse(unpack('b6', chr($_))));} (0..63); $Mime_table{'='} = '000000'; # padding my $Mime_version; my $Input_line; # do { # $Input_line = <>; # if (eof) { # die "No MIME header found.\n"; # } # } until ($Input_line =~ /^mime-version:/i); my $Boundary; do { $Input_line = <>; $Mime_version = 1 if ($Input_line =~ /^mime-version:/i); if (eof) { die "EOF reached before MIME boundary definition found.\n"; } } until ($Input_line =~ /boundary="([^"]+)"/i); $Boundary = $1; do { $Input_line = <>; $Mime_version = 1 if ($Input_line =~ /^mime-version:/i); if (eof) { die "EOF reached before any MIME boundaries found.\n"; } } until ($Input_line =~ /$Boundary/); die "No MIME version header found before first apparent boundary.\n" unless $Mime_version; my $Output_file = ''; my $b64 = 0; SKIPFILE: while (!eof) { HEADER: while (defined($Input_line = <>)) { if ($Input_line =~ /^--$Boundary/) { $Output_file = ''; $b64 = 0; redo SKIPFILE; } if ($Input_line =~ m/name="([^"]+)"/i) { $Output_file = $1; next HEADER; } if ($Input_line =~ m/^Content\-.*base64/i) { $b64 = 1; next HEADER; } if ($Input_line =~ /^\s*$/) { last HEADER; } } if ($Output_file eq '' or $b64 == 0) { next SKIPFILE; } open(OUT, ">$Output_file") or die "Could not open $Output_file for write, $!"; BODY: while (defined($Input_line = <>)) { if ($Input_line =~ /^--$Boundary/) { close(OUT) or die "Error on file close, $!"; $Output_file = ''; $b64 = 0; redo SKIPFILE; } chomp $Input_line; my $Offset = 0; my $Length = length($Input_line); my $Excess = ''; DECODE: while ($Offset < $Length) { my $Block = substr($Input_line, $Offset, 4); if (length($Block) < 4) { $Excess = $Block; last DECODE; } my $Output = pack("B24", join('', map { $Mime_table{$_}} split('',$Block,4))); if ($Block =~ /(=){1,2}$/) { substr($Output, -1, length($1)) = ''; } print OUT $Output; $Offset += 4; } if ($Excess ne '') { $Input_line = $Excess . <>; redo BODY; } } } continue { while (defined($Input_line = <>)) { last SKIPFILE if eof; last SKIPFILE if ($Input_line =~ /^--${Boundary}--/); last if ($Input_line =~ /^--$Boundary/); } $Output_file = ''; $b64 = 0; }