#!/usr/bin/perl -w

use strict;
use warnings;
use Time::HiRes qw(gettimeofday);

# =========================
# Based on j.mason source: http://jmason.org/software/scripts/extract-rfc822-attachment.txt
# =========================

=head1 README

split-rfc822-attachment - extract a "mail/rfc822" attachment from a mail.

=head1 SYNOPSIS

	split-rfc822-attachment < msg > newmsg
or
        split-rfc822-attachment < msg /path/to/the/destination/

In the first case (no path), the first attachment , ONLY, is extracted to STDOUT.

In the second case (with path), all rfc822 compliant attachment are extracted to files.
Each file's name is appended by a numbered suffix ".1" ".2" ".3" and so on.
The full name of the first file without suffix ".1" is print out to STDOUT.

=head1 EXIT STATUS

Exit status will be 0 if there was an attachment and the attachment was
extracted successfully, 1 if there was no attachment found.  The remaining
non-zero exit statuses are reserved for other failure modes.

=head1 NOTE

Quoted-printable or base64-encoded attachments are not currently
supported.

=head1 VERSION

Jul 26 2013 tj

=cut

my $templ_filename;
my $templ_index;
my $path_dest = defined($ARGV[0])?$ARGV[0]:undef;

my $hdrs = '';
while (<STDIN>) {
  /^$/ and last;
  $hdrs .= $_;
}
$hdrs =~ s/\n[ \t]+/ /gs;

if ($hdrs !~ /^Content-Type: multipart\/mixed\;\s+boundary=\"(\S+)\"$/m) {
  exit 1;
}
my $tophdrs = $hdrs;
my $bound = $1;

##warn "found MIME boundary $bound\n";

while (<STDIN>) {
  /^\Q--${bound}\E$/ and last;
}

while (1) {
  last if eof(STDIN);

  $hdrs = '';

  while (<STDIN>) {
    /^$/ and last;
    $hdrs .= $_;
  }
  $hdrs =~ s/\n[ \t]+/ /gs;

  my $is_rfc822 = ($hdrs =~ /^Content-Type: message\/rfc822(?:\;|$)/m)?1:0;
  my $msg = '';
  my $bound_end = 0; 

  ##warn "found message/rfc822 part: $hdrs\n";

  while (<STDIN>) {
    if ( /^\Q--${bound}--\E$/ ) {
      $bound_end = 1;
      last;
    }
    /^\Q--${bound}\E$/ and last;

    $msg .= $_;
  }

  if ( $is_rfc822 ) {
    if ( defined( $path_dest ) ) {
      my $filename;

      if ( !defined( $templ_filename ) ) {
        mkdir( $path_dest ) unless -d $path_dest;
        $templ_index = 0;

        my $timestamp = int( gettimeofday * 1000 );
        my $alea = $$;
          
        $templ_filename = sprintf("split-rfc822-%012X%05X",$timestamp,$alea);
      }

      $templ_index ++ ;
      $filename = $path_dest . '/' . $templ_filename . '.' . $templ_index ;

      #print STDOUT "$filename\n";

      if ( open( my $fh , ">", $filename.'~' ) or die "cannot open > $filename" ) {
        print $fh $msg or die "cannot write > $filename" ;
        close( $fh ) or die "cannot close > $filename" ;
        rename( $filename.'~' , $filename ) or die "cannot rename > $filename";
      }

      if ( $bound_end ) {
        print STDOUT $path_dest . '/' . $templ_filename . "\n";
        exit 0;
      }
    }
    else {
      print STDOUT $msg;
      exit 0;
    }
  }
  # ignore non rfc822
}

# Something goes wrong
exit 1;

# ------------------
# EOF
