#!/usr/bin/perl -w
use MIME::Parser;
use MIME::Types;
use Convert::TNEF;
use FileHandle;
use PDF::Reuse;
use PDF::API2;
# Define Globals
my $top_entity;
my $mes = '1';
my $mescount = 0;
my $pfad='/tmp';
my $fax_sender = $ARGV[0];
my $fax_rec = $ARGV[1];
my $pageNo = 0;
$fax_rec=substr($fax_rec,0,index($fax_rec,"@"));
#Hier könnte eine Berechtigungsprüfung gegen $fax_sender stattfinden
# Datei mit MIME-Nachricht einlesen und parsen
$top_entity = &parse_MIME_Stream(\*STDIN);
# MIME-Nachricht, ggf. rekursiv, durchlaufen
&walk($top_entity);
# Aufräumen
$top_entity->purge;
if ($mes ne 1 ) { # alles ok, Fax erstellen
open PIPE, "|/usr/bin/sendfax -m -s a4 -n -f $fax_sender -d $fax_rec" or die $!;
prFile("/tmp/fax.$$");
prTouchUp(0);
prCompress(1);
&commit_files(0);
close(PIPE);
} else {
# nothing to do - nichts Faxbares gefunden
}
exit;
###############################################################################
sub parse_MIME_Stream {
# Neues Parser-Objekt
my $parser = MIME::Parser->new();
# Parser einstellen
# Attachments müssen in den Hauptspeicher passen
# output_to_core('ALL') bedeutet, dass nichts auf die
# Festplatte geschrieben wird
$parser->output_to_core('ALL');
$parser->filer->purge; # löscht alle vom Parser angelegten Dateien
my $top_entity = $parser->read($_[0]);
return $top_entity;
}
###############################################################################
sub walk {
my $entity = shift if @_;
return unless defined $entity;
my $head;
my $body;
$head = $entity->head();
# Falls es sich um eine mehrteilige Nachricht handelt
if ($head->mime_type() =~ m/multipart/i) {
my $i;
my $num_alt_parts = $entity->parts();
my $current_entity;
# Für alle Multipart/Alternative-Teile der Nachricht
for ($i = 0; $i < $num_alt_parts; $i++) {
# an entity
$current_entity = $entity->parts($i);
# recurse
&walk($current_entity);
}
# ansonsten ist es eine einteilige Nachricht
} else {
&handle_head($entity,$head);
}
}
###############################################################################
sub handle_head {
my $current_entity = shift if @_;
my $current_head = shift if @_;
return unless defined $current_head;
my $body;
$current_head->unfold;
$body = $current_entity->bodyhandle();
my $actfile = $body->path;
#"######################## application/pdf #############################################
if ($current_head->mime_type() eq "application/pdf") { # pdf-attachement
$mes = $body->as_string;
my $pdf = PDF::API2->new;
$pdf = PDF::API2->openScalar($mes);
$pageNo = $pageNo+$pdf->pages;
$mescount++;
$pdf->saveas("/tmp/fax.$mescount.$$");
$pdf->end;
$mes = "Got";
######################### application/ms-tnef ######################################
} elsif ($current_head->mime_type() eq "application/ms-tnef") { # MS-Outlook - NoOne Knows
my $mimetypes = MIME::Types->new;
my %TnefOpts=('output_to_core' => 'ALL', 'output_dir' => '/tmp');
my $tnef = Convert::TNEF->read_ent($body->as_string, \%TnefOpts);
unless ($tnef) {
warn "TNEF CONVERT DID NOT WORK: " . $Convert::TNEF::errstr . "\n";
return;
}
foreach ($tnef->attachments) {
my ($ext) = ($_->longname =~ /\.([A-Za-z]{2,4})$/);
my $type = $mimetypes->mimeTypeOf($ext) || "application/octet-stream";
if ($type eq "application/pdf") { # pdf-attachement
$mes = $_->data;
my $pdf = PDF::API2->new;
$pdf = PDF::API2->openScalar($mes);
$pageNo = $pageNo+$pdf->pages;
$mescount++;
$pdf->saveas("/tmp/fax.$mescount.$$");
$pdf->end;
$mes = "Got";
} else { # other attachements
#ignore
}
}
$tnef->purge;
} else { #other attachements
if (defined($body->path)) { # data is on disk:
unlink($actfile);
}
}
}
###############################################################################
sub commit_files {
for (my $i=1;$i<=$mescount;$i++) {
if ($i>1) { prPage(); }
elsif (($i eq 1) && ($_[0] eq 1)) { prPage(); }
prDoc("/tmp/fax.$i.$$");
}
prEnd();
open(FFILE,"< /tmp/fax.$$");
binmode(FFILE);
while (<FFILE>) {
print PIPE $_;
}
close(FFILE);
unlink("/tmp/fax.$$");
for (my $i=1;$i<=$mescount;$i++) {
unlink("/tmp/fax.$i.$$");
}
}
###############################################################################
__END__