Handle hostnames with upper-case letters
[webmin.git] / mailboxes / view_mail.cgi
1 #!/usr/local/bin/perl
2 # view_mail.cgi
3 # View a single email message 
4
5 require './mailboxes-lib.pl';
6 &ReadParse();
7 &can_user($in{'user'}) || &error($text{'mail_ecannot'});
8 if (&is_user($in{'user'})) {
9         @uinfo = &get_mail_user($in{'user'});
10         @uinfo || &error($text{'view_eugone'});
11         }
12
13 $uuser = &urlize($in{'user'});
14 @folders = &list_user_folders($in{'user'});
15 $folder = $folders[$in{'folder'}];
16 @mail = &mailbox_list_mails($in{'idx'}, $in{'idx'}, $folder);
17 $mail = $mail[$in{'idx'}];
18 &parse_mail($mail, undef, $in{'raw'});
19 @sub = split(/\0/, $in{'sub'});
20 $subs = join("", map { "&sub=$_" } @sub);
21 foreach $s (@sub) {
22         # We are looking at a mail within a mail ..
23         local $amail = &extract_mail($mail->{'attach'}->[$s]->{'data'});
24         &parse_mail($amail, undef, $in{'raw'});
25         $mail = $amail;
26         }
27
28 dbmopen(%read, "$module_config_directory/$in{'user'}.read", 0600);
29 eval { $read{$mail->{'header'}->{'message-id'}} = 1 }
30         if (!$read{$mail->{'header'}->{'message-id'}});
31
32 if ($in{'raw'}) {
33         # Special mode - viewing whole raw message
34         print "Content-type: text/plain\n\n";
35         if ($mail->{'fromline'}) {
36                 print $mail->{'fromline'},"\n";
37                 }
38         if (defined($mail->{'rawheaders'})) {
39                 #$mail->{'rawheaders'} =~ s/(\S)\t/$1\n\t/g;
40                 print $mail->{'rawheaders'};
41                 }
42         else {
43                 foreach $h (@{$mail->{'headers'}}) {
44                         #$h->[1] =~ s/(\S)\t/$1\n\t/g;
45                         print "$h->[0]: $h->[1]\n";
46                         }
47                 }
48         print "\n";
49         print $mail->{'body'};
50         return;
51         }
52
53 # Find body attachment and type
54 ($textbody, $htmlbody, $body) = &find_body($mail, $config{'view_html'});
55 $body = $htmlbody if ($in{'body'} == 2);
56 $body = $textbody if ($in{'body'} == 1);
57 @attach = @{$mail->{'attach'}};
58
59 # Show pre-body HTML
60 if ($body && $body eq $htmlbody) {
61         $headstuff = &head_html($body->{'data'});
62         }
63
64 # Set the character set for the page to match email
65 $main::force_charset = &get_mail_charset($mail, $body);
66
67 &mail_page_header($text{'view_title'}, $headstuff, undef,
68                   &folder_link($in{'user'}, $folder));
69 print &check_clicks_function();
70 &show_arrows();
71
72 # Start of the form
73 print &ui_form_start("reply_mail.cgi");
74 print &ui_hidden("user", $in{'user'});
75 print &ui_hidden("idx", $in{'idx'});
76 print &ui_hidden("folder", $in{'folder'});
77 print &ui_hidden("mod", &modification_time($folder));
78 foreach $s (@sub) {
79         print &ui_hidden("sub", $s);
80         }
81
82 # Find any delivery status attachment
83 ($dstatus) = grep { $_->{'type'} eq 'message/delivery-status' } @attach;
84
85 # Strip out attachments not to display as icons
86 @attach = grep { $_ ne $body && $_ ne $dstatus } @attach;
87 @attach = grep { !$_->{'attach'} } @attach;
88
89 if ($config{'top_buttons'} == 2 && &editable_mail($mail)) {
90         &show_mail_buttons(1, scalar(@sub));
91         print "<p>\n";
92         }
93
94 # Start of headers section
95 $hbase = "view_mail.cgi?idx=$in{'idx'}&body=$in{'body'}&".
96          "folder=$in{'folder'}&user=$uuser$subs";
97 if ($in{'headers'}) {
98         push(@hmode, "<a href='$hbase&headers=0'>$text{'view_noheaders'}</a>");
99         }
100 else {
101         push(@hmode, "<a href='$hbase&headers=1'>$text{'view_allheaders'}</a>");
102         }
103 push(@hmode, "<a href='$hbase&raw=1'>$text{'view_raw'}</a>");
104 print &ui_table_start($text{'view_headers'},
105                       "width=100%", 2, [ "width=10% nowrap" ],
106                       &ui_links_row(\@hmode));
107
108 if ($in{'headers'}) {
109         # Show all the headers
110         if ($mail->{'fromline'}) {
111                 print &ui_table_row($text{'mail_rfc'},
112                         &eucconv_and_escape($mail->{'fromline'}));
113                 }
114         foreach $h (@{$mail->{'headers'}}) {
115                 print &ui_table_row($h->[0].":",
116                         &eucconv_and_escape(&decode_mimewords($h->[1])));
117                 }
118         }
119 else {
120         # Just show the most useful headers
121         print &ui_table_row($text{'mail_from'},
122                 &address_link($mail->{'header'}->{'from'}));
123         print &ui_table_row($text{'mail_to'},
124                 &address_link($mail->{'header'}->{'to'}));
125         if ($mail->{'header'}->{'cc'}) {
126                 print &ui_table_row($text{'mail_cc'},
127                         &address_link($mail->{'header'}->{'cc'}));
128                 }
129         print &ui_table_row($text{'mail_date'},
130                 &eucconv_and_escape(
131                         &simplify_date($mail->{'header'}->{'date'})));
132         print &ui_table_row($text{'mail_subject'},
133                 &eucconv_and_escape(&decode_mimewords(
134                                         $mail->{'header'}->{'subject'})));
135         }
136 print &ui_table_end();
137
138 # Show body attachment, with properly linked URLs
139 @bodyright = ( );
140 if ($body && $body->{'data'} =~ /\S/) {
141         if ($body eq $textbody) {
142                 # Show plain text
143                 $bodycontents = "<pre>";
144                 foreach $l (&wrap_lines(&eucconv($body->{'data'}),
145                                         $config{'wrap_width'})) {
146                         $bodycontents .= &link_urls_and_escape($l,
147                                                 $config{'link_mode'})."\n";
148                         }
149                 $bodycontents .= "</pre>";
150                 if ($htmlbody) {
151                         push(@bodyright,
152                             "<a href='$hbase&body=2'>$text{'view_ashtml'}</a>");
153                         }
154                 }
155         elsif ($body eq $htmlbody) {
156                 # Attempt to show HTML
157                 $bodycontents = &safe_html($body->{'data'});
158                 $bodycontents = &fix_cids($bodycontents, \@attach,
159                         "detach.cgi?user=$uuser&idx=$in{'idx'}&folder=$in{'folder'}$subs");
160                 if ($textbody) {
161                         push(@bodyright,
162                             "<a href='$hbase&body=1'>$text{'view_ashtml'}</a>");
163                         }
164                 }
165         }
166 if ($bodycontents) {
167         print &ui_table_start($text{'view_body'}, "width=100%", 1,
168                               undef, &ui_links_row(\@bodyright));
169         print &ui_table_row(undef, $bodycontents);
170         print &ui_table_end();
171         }
172
173 # Show delivery status
174 if ($dstatus) {
175         &show_delivery_status($dstatus);
176         }
177
178 # Display other attachments
179 if (@attach) {
180         # Table of attachments
181         $viewurl = "view_mail.cgi?idx=$in{'idx'}&folder=$in{'folder'}&".
182                    "user=$uuser$subs";
183         $detachurl = "detach.cgi?idx=$in{'idx'}&folder=$in{'folder'}&".
184                      "user=$uuser$subs";
185         @detach = &attachments_table(\@attach, $folder, $viewurl, $detachurl,
186                                      undef, undef, undef);
187
188         # Links to download all / slideshow
189         @links = ( );
190         if (@attach > 1) {
191                 push(@links, "<a href='detachall.cgi/attachments.zip?folder=$in{'folder'}&idx=$in{'idx'}&user=$uuser$subs'>$text{'view_aall'}</a>");
192                 }
193         @iattach = grep { $_->{'type'} =~ /^image\// } @attach;
194         if (@iattach > 1) {
195                 push(@links, "<a href='slideshow.cgi?folder=$in{'folder'}&idx=$in{'idx'}&user=$uuser$subs'>$text{'view_aslideshow'}</a>");
196                 }
197         print &ui_links_row(\@links) if (@links);
198
199         # Show form to detact to server, if enabled
200         if ($access{'candetach'} && @detach && defined($uinfo[2])) {
201                 print &ui_table_start($text{'view_dheader'}, "width=100%", 1);
202                 $dtach = &ui_submit($text{'view_detach'}, 'detach');
203                 $dtach .= &ui_hidden("bindex", $body->{'idx'}) if ($body);
204                 $dtach .= &ui_hidden("sindex", $sindex) if (defined($sindex));
205                 $dtach .= &ui_select("attach", undef,
206                                 [ [ '*', $text{'view_dall'} ],
207                                   @detach ]);
208                 $dtach .= "<b>$text{'view_dir'}</b>\n";
209                 $dtach .= &ui_textbox("dir", undef, 60)." ".
210                           &file_chooser_button("dir", 1);
211                 print &ui_table_row(undef, $dtach);
212                 print &ui_table_end();
213                 }
214         }
215
216 &show_mail_buttons(2, scalar(@sub)) if (&editable_mail($mail));
217 if ($config{'arrows'} == 2 && !@sub) {
218         &show_arrows();
219         }
220 print "</form>\n";
221
222 dbmclose(%read);
223
224 # Footer with backlinks
225 local @sr = !@sub ? ( ) :
226     ( "view_mail.cgi?idx=$in{'idx'}", $text{'view_return'} ),
227 $s = int((@mail - $in{'idx'} - 1) / $config{'perpage'}) *
228         $config{'perpage'};
229 &mail_page_footer(
230         @sub ? ("view_mail.cgi?idx=$in{'idx'}&folder=$in{'folder'}&user=$uuser",
231                 $text{'view_return'}) : ( ),
232         "list_mail.cgi?folder=$in{'folder'}&user=$uuser", $text{'mail_return'},
233         "", $text{'index_return'});
234
235 # show_mail_buttons(pos, submode)
236 sub show_mail_buttons
237 {
238 local $spacer = "&nbsp;\n";
239 if (!$_[1]) {
240         print "<input type=submit value=\"$text{'view_delete'}\" name=delete ",
241               "onClick='return check_clicks(form)'>";
242         print $spacer;
243
244         if (!$folder->{'sent'} && !$folder->{'drafts'}) {
245                 $m = $read{$mail->{'header'}->{'message-id'}};
246                 print "<input name=mark$_[0] type=submit value=\"$text{'view_mark'}\">";
247                 print "<select name=mode$_[0]>\n";
248                 foreach $i (0 .. 2) {
249                         printf "<option value=%d %s>%s\n",
250                                 $i, $m == $i ? 'selected' : '', $text{"view_mark$i"};
251                         }
252                 print "</select>";
253                 print $spacer;
254                 }
255         }
256 if (&is_user($in{'user'})) {
257         print "<input type=submit value=\"$text{'view_forward'}\" name=forward>";
258         print $spacer;
259         }
260
261 print "<input type=submit value=\"$text{'view_print'}\" name=print>";
262 print $spacer;
263
264 if (&is_user($in{'user'})) {
265         print "<input type=submit value=\"$text{'view_reply'}\" name=reply>";
266         print "<input type=submit value=\"$text{'view_reply2'}\" name=rall>";
267         print $spacer;
268         }
269
270 print "<input type=submit value=\"$text{'view_strip'}\" name=strip>";
271 print $spacer;
272
273 # Show spam report buttons
274 @modules = &get_available_module_infos(1);
275 ($hasspam) = grep { $_->{'dir'} eq "spam" } @modules;
276 if (&foreign_installed("spam") &&
277     $config{'spam_buttons'} =~ /mail/ &&
278     &spam_report_cmd($in{'user'})) {
279         if ($hasspam) {
280                 print "<input type=submit value=\"$text{'view_black'}\" name=black>";
281                 }
282         if ($config{'spam_del'}) {
283                 print "<input type=submit value=\"$text{'view_razordel'}\" name=razor>\n";
284                 }
285         else {
286                 print "<input type=submit value=\"$text{'view_razor'}\" name=razor>\n";
287                 }
288         }
289 print "<br>\n";
290 }
291
292 sub show_arrows
293 {
294 print "<center>\n";
295 if (!@sub) {
296         if ($in{'idx'}) {
297                 print "<a href='view_mail.cgi?idx=",
298                     $in{'idx'}-1,"&folder=$in{'folder'}&user=$uuser'>",
299                     "<img src=$gconfig{'webprefix'}/images/left.gif border=0 ",
300                     "align=middle></a>\n";
301                 }
302         print "<font size=+1>",&text('view_desc', $in{'idx'}+1,
303                         $folder->{'name'}),"</font>\n";
304         if ($in{'idx'} < @mail-1) {
305                 print "<a href='view_mail.cgi?idx=",
306                     $in{'idx'}+1,"&folder=$in{'folder'}&user=$uuser'>",
307                     "<img src=$gconfig{'webprefix'}/images/right.gif border=0 ",
308                     "align=middle></a>\n";
309                 }
310         }
311 else {
312         print "<font size=+1>$text{'view_sub'}</font>\n";
313         }
314 print "</center><br>\n";
315 }
316
317 # address_link(address)
318 sub address_link
319 {
320 local @addrs = &split_addresses(&decode_mimewords($_[0]));
321 local @rv;
322 foreach $a (@addrs) {
323         push(@rv, &eucconv_and_escape($a->[2]));
324         }
325 return join(" , ", @rv);
326 }
327