Added support for base64 encodings
[clearscm.git] / maps / bin / display.cgi
1 #!/usr/bin/perl
2 ################################################################################
3 #
4 # File:         $RCSfile: display.cgi,v $
5 # Revision:     $Revision: 1.1 $
6 # Description:  Displays an email message
7 # Author:       Andrew@DeFaria.com
8 # Created:      Fri Nov 29 14:17:21  2002
9 # Modified:     $Date: 2013/06/12 14:05:47 $
10 # Language:     perl
11 #
12 # (c) Copyright 2000-2006, Andrew@DeFaria.com, all rights reserved.
13 #
14 ################################################################################
15 use strict;
16 use warnings;
17
18 use FindBin;
19 $0 = $FindBin::Script;
20
21 use lib $FindBin::Bin;
22
23 use MAPS;
24 use MAPSWeb;
25
26 use CGI qw/:standard *table/;
27 use CGI::Carp "fatalsToBrowser";
28
29 use MIME::Parser;
30 use MIME::Base64;
31 use MIME::Words qw(:all);
32
33 my $userid      = cookie('MAPSUser');
34 my $sender      = param('sender');
35 my $msg_nbr     = param('msg_nbr');
36 my $table_name  = 'message';
37
38 sub ParseEmail (@) {
39   my (@header) = @_;
40
41   my %header;
42
43   # First output the header information. Note we'll skip uninteresting stuff
44   foreach (@header) {
45     last if ($_ eq '' || $_ eq "\cM");
46
47     # Escape "<" and ">"
48     s/\</\&lt\;/;
49     s/\>/\&gt\;/;
50
51     if (/^from:\s*(.*)/i) {
52       $header{From} = $1;
53     } elsif (/^subject:\s*(.*)/i) {
54       $header{Subject} = $1;
55     } elsif (/^date:\s*(.*)/i) {
56       $header{date} = $1;
57     } elsif (/^To:\s*(.*)/i) {
58       $header{to} = $1;
59     } elsif (/^Content-Transfer-Encoding: base64/) {
60       $header{base64} = 1;
61     } # if
62   } # while
63
64   return %header;
65 } # ParseEmail
66
67 sub Body ($) {
68   my ($count) = @_;
69
70   $count ||= 1;
71
72   my $handle = FindEmail $sender;
73
74   my ($userid, $sender, $subject, $timestamp, $message);
75
76   # Need to handle multiple messages
77   for (my $i = 0; $i < $count; $i++) {
78     ($userid, $sender, $subject, $timestamp, $message) = GetEmail $handle;
79   } # for
80
81   my $parser = new MIME::Parser;
82
83   $parser->output_to_core (1);
84
85   my $entity = $parser->parse_data ($message);
86
87   my %header = ParseEmail @{($entity->header)[0]};
88
89   print p . "\n";
90     print start_table ({-align        => "center",
91                         -id           => $table_name,
92                         -border       => 0,
93                         -cellspacing  => 0,
94                         -cellpadding  => 0,
95                         -width        => "100%"});
96     print start_table ({-align        => "center",
97                         -bgcolor      => "#d4d0c8",
98                         -border       => 0,
99                         -cellspacing  => 2,
100                         -cellpadding  => 2,
101                         -width        => "100%"}) . "\n";
102     print "<tbody><tr><td>\n";
103     print start_table ({-align        => "center",
104                         -border       => 0,
105                         -cellspacing  => 0,
106                         -cellpadding  => 2,
107                         -bgcolor      => "#ece9d8",
108                         -width        => "100%"}) . "\n";
109
110     foreach (keys (%header)) {
111       next if /base64/;
112
113       my $str = decode_mimewords ($header{$_});
114
115       print Tr ([
116         th ({-align    => "right",
117              -bgcolor  => "#ece9d8",
118              -width    => "8%"}, "$_:") . "\n" .
119         td ({-bgcolor  => "white"}, $str)
120       ]);
121     } # if
122
123     print end_table;
124     print "</td></tr>";
125     print end_table;
126
127   print start_table ({-align        => "center",
128                       -bgcolor      => "black",
129                       -border       => 0,
130                       -cellspacing  => 0,
131                       -cellpadding  => 2,
132                       -width        => "100%"}) . "\n";
133   print "<tbody><tr><td>\n";
134   print start_table ({-align        => "center",
135                       -border       => 0,
136                       -cellspacing  => 0,
137                       -cellpadding  => 2,
138                       -bgcolor      => "white",
139                       -width        => "100%"}) . "\n";
140   print "<tbody><tr><td>\n";
141
142   my @parts = $entity->parts;
143
144   if (scalar @parts == 0) {
145     print '<pre>';
146     $entity->print_body;
147     print '</pre>';
148   } else {
149     foreach my $part ($entity->parts) {
150       # We assume here that if this part is multipart/alternative then
151       # there exists at least one part that is text/html and we favor
152       # that (since we're outputing to a web page anyway...
153       if ($part->mime_type eq 'multipart/alternative') {
154         foreach my $subpart ($part->parts) {
155           if ($subpart->mime_type eq 'text/html') {
156             # There should be an easier way to get this but I couldn't find one.
157             my $encoding = ${$subpart->{mail_inet_head}{mail_hdr_hash}{'Content-Transfer-Encoding'}[0]};
158             if ($encoding =~ /base64/) {
159               $subpart->bodyhandle->print();
160             } else {
161               $subpart->print_body;
162             } # if
163             last;
164           } elsif ($subpart->mime_type eq 'multipart/related') {
165             # This is stupid - multipart/related? When it's really just HTML?!?
166             $subpart->print_body;
167             last;
168           } # if
169         } # foreach
170       } else {
171         if ($part->mime_type =~ /text/) {
172           print '<pre>';
173           $part->print_body;
174           print '</pre>';
175         } # if
176       } # if
177     } # foreach
178   } # if
179
180   print "</td></tr>\n";
181   print end_table;
182   print "</td></tr>\n";
183   print end_table;
184   print end_table;
185 } # Body
186
187 $userid = Heading (
188   'getcookie',
189   '',
190   "Email message from $sender",
191   "Email message from $sender",
192   '',
193   $table_name,
194 );
195
196 SetContext $userid;
197 NavigationBar $userid;
198
199 Body $msg_nbr;
200
201 Footing $table_name;