#!/usr/bin/perl # # ----------- MIME-encoded email file viewer ------------------------- # # Version 1.0. # # Suitable for reading *.eml files generated by Mozilla Thunderbird. # # author: Dr. Michael J. Chudobiak, mjc@avtechpulse.com # # Feel free to modify this in any way you like. # # This program assumes that email files are stored in a directory that # is both accessible through the filesystem (at $input_dir) and the # web server (at $input_url). The filename is supplied from the CGI query # string. If the filename has an ".eml" or ".uue" file extension, # (or other extensions listed in $valid_extensions) this script parses # the mime structure and returns a web page. If it does not, the browser # is simply redirected to the non-.eml file. # # To accommodate old messages archived by MS Outlook (stored in *.msg # format) this script will redirect requests for foo.msg to foo.eml # if foo.eml exists. To convert your archive of *.msg into *.eml messages, # use Matijs van Zuijlen's excellent msgconvert.pl Perl script, available # at: http://www.xs4all.nl/~mvz/software/msgconv.html use MIME::Explode; use strict; use CGI qw/escape unescape/; # ----------------- Start of Configuration ------------------------------ # Top of web server directories (do not end with a slash). my $base_dir = "/var/www/html"; # Directory containing files to parse (full path, end with slash). my $input_dir = "/fileserver/officefiles/quotes/"; # The URL corresponding to the above filesystem directory (end with slash). my $input_url = "/intranet/quotes/"; # A working sub-directory (under base_dir) for temporary files. # The directory must exist, and be it must writeable by web server. # (End with slash). my $working_subdir = "/cgi-perl/mime-explode-temp/"; # Where to put the generated files (under base_dir) - adding the # time function makes the directory name unique for each parsed file. # You should add a cron job to delete these temp* directories nightly. my $output_subdir = "/cgi-perl/mime-explode-temp/temp".time; # List of valid file extensions denoting mime-encoded files. # End the list with a space. Separate the extensions with spaces. my $valid_extensions = ".eml .uue "; # For HTML portions of the message, you can apply a default font style # here. I prefer a monospaced font for messages. This may be over-ridden by # the HTML content, of course. my $html_font_style = qq{style="font-family: Courier New, Courier; font-size: small"}; # For plain text portions of the message, you can apply a default font style # here. I prefer a monospaced font for messages. my $text_font_style = qq{style="font-family: Courier New, Courier; font-size: small"}; # ----------------- End of Configuration ------------------------------- # get the input file name from the CGI query string my $input_file = substr($ENV{'QUERY_STRING'},0,100); # unescape escaped characters $input_file = unescape($input_file); # remove non-alphanumerics $input_file =~ s/[^a-zA-Z0-9\-\(\)\. ]//g; # remove form field names, if present $input_file =~ s/SUBMIT//ig; my $input_file_extension = $input_file; $input_file_extension =~ s/(.*)(\.)(.*)$/$2$3/; my $before_extension = $input_file; $before_extension =~ s/(.*)(\.)(.*)$/$1/; # ------------ Use the *.eml version of a *.msg file, if it exists ---------------- # *.msg = binary proprietary MS format # *.eml = multi-part mime-encoded file if (($input_file_extension eq ".msg") and (-e "$input_dir$before_extension.eml")) { $input_file_extension = ".eml"; $input_file = $before_extension . $input_file_extension; } # --------------------------------------------------------------------------------- # If the input file is not mime-encoded file, redirect the browser # to that file directly, instead of decoding it. if ($valid_extensions !~ /$input_file_extension /i) { # Redirect the browser print "Location: $input_url$input_file\n\n"; } else { # generate a web page from the mime parts print "Content-type: text/html\n\n"; print "\n"; my $explode = MIME::Explode->new( output_dir => $base_dir.$output_subdir, mkdir => 0775, decode_subject => 1, check_content_type => 1, ); open(MAIL, "<".$input_dir.$input_file) or die("Couldn't open file for reading: $!\n"); open(OUTPUT, ">".$base_dir.$working_subdir."file.tmp") or die("Couldn't open file.tmp for writing: $!\n"); my $headers = $explode->parse(\*MAIL, \*OUTPUT); close(OUTPUT); close(MAIL); opendir(DIR,$base_dir.$output_subdir); my @entries = readdir(DIR); closedir(DIR); my @textfiles=(); my @htmlfiles=(); my @attachments=(); foreach my $entry (@entries) { next if ($entry eq '.' or $entry eq '..'); if ($entry =~ /\.txt/i) { push(@textfiles,$entry); } elsif ($entry =~ /\.htm/i) { push(@htmlfiles,$entry); } else { push(@attachments,$entry); } } # If there is no HTML file, present the text file as the main body. # Otherwise, use the HTML as the main body, and list the text file as an attachment. foreach my $file (@htmlfiles) { open(HTMLFILE, "<".$base_dir.$output_subdir."/".$file); # format the email text with the specified font print qq{
\n}; # read in the HTML file my $output_html = ""; while () { $output_html .= $_; } # strip out non-body portions of the HTML $output_html =~ s/.*(.*)<\/body>.*/$1/is; print $output_html . "\n
\n"; close(HTMLFILE); } foreach my $file (@textfiles) { if (@htmlfiles) { print qq{
\nAttachment: $file\n}; } else { open(TEXTFILE, "<".$base_dir.$output_subdir."/".$file); # format the email text with the specified font print qq{
\n}; # read in the text file my $output_html = ""; while () { $output_html .= $_; } close(TEXTFILE); # convert newlines to HTML breaks $output_html =~ s/\n/
\n/sg; # convert spaces to HTML spaces $output_html =~ s/ / /sg; print $output_html . "\n
\n"; } } foreach my $file (@attachments) { print qq{
\nAttachment: $file\n}; } print "\n"; }