#!/usr/local/bin/perl # Display a form for replying to or composing an email require './mailboxes-lib.pl'; &ReadParse(); &can_user($in{'user'}) || &error($text{'mail_ecannot'}); @uinfo = &get_mail_user($in{'user'}); @uinfo || &error($text{'view_eugone'}); @folders = &list_user_folders($in{'user'}); $folder = $folders[$in{'folder'}]; if ($in{'new'}) { # Composing a new email $html_edit = 1 if ($config{'html_edit'} == 2); $sig = &get_signature($in{'user'}); if ($html_edit) { $sig =~ s/\n/
\n/g; $quote = ""; } else { $quote = "\n\n$sig" if ($sig); } $to = $in{'to'}; &mail_page_header($text{'compose_title'}, undef, $html_edit ? "onload='initEditor()'" : "", &folder_link($in{'user'}, $folder)); } else { # Replying or forwarding if ($in{'mailforward'} ne '') { # Replying to multiple @mailforward = sort { $a <=> $b } split(/\0/, $in{'mailforward'}); @mails = &mailbox_list_mails( $mailforward[0], $mailforward[@mailforward-1], $folder); $mail = $mails[$mailforward[0]]; } else { # Replying to one @mails = &mailbox_list_mails($in{'idx'}, $in{'idx'}, $folder); $mail = $mails[$in{'idx'}]; &decode_and_sub(); } &check_modification($folder) if ($in{'delete'}); $mail || &error($text{'mail_eexists'}); if ($in{'delete'}) { # Just delete the email if (!$in{'confirm'} && &need_delete_warn($folder)) { # Need to ask for confirmation before deleting &mail_page_header($text{'confirm_title'}, undef, undef, &folder_link($in{'user'}, $folder)); print &check_clicks_function(); print "
\n"; foreach $i (keys %in) { foreach $v (split(/\0/, $in{$i})) { print "\n"; } } print "
$text{'confirm_warn3'}
\n"; if ($config{'delete_warn'} ne 'y') { print "$text{'confirm_warn2'}

\n" } else { print "$text{'confirm_warn4'}

\n" } print "

\n"; &mail_page_footer("view_mail.cgi?idx=$in{'idx'}&folder=$in{'folder'}&user=$in{'user'}", $text{'view_return'}, "list_mail.cgi?folder=$in{'folder'}&user=$in{'user'}", $text{'mail_return'}, "", $text{'index_return'}); exit; } &lock_folder($folder); &mailbox_delete_mail($folder, $mail); &unlock_folder($folder); &webmin_log("delmail", undef, undef, { 'from' => $folder->{'file'}, 'count' => 1 } ); &redirect("list_mail.cgi?folder=$in{'folder'}&user=$in{'user'}"); exit; } elsif ($in{'print'}) { # Extract the mail body &decode_and_sub(); ($textbody, $htmlbody, $body) = &find_body($mail, $config{'view_html'}); # Output HTML header &PrintHeader(); print "\n"; print "",&html_escape(&decode_mimewords( $mail->{'header'}->{'subject'})),"\n"; print "\n"; # Display the headers print "\n"; print "\n"; print "
$text{'view_headers'}
\n"; print " ", "\n"; print " ", "\n"; print " ", "\n" if ($mail->{'header'}->{'cc'}); print " ", "\n"; print " ", "\n"; print "
$text{'mail_from'}",&eucconv_and_escape($mail->{'header'}->{'from'}),"
$text{'mail_to'}",&eucconv_and_escape($mail->{'header'}->{'to'}),"
$text{'mail_cc'}",&eucconv_and_escape($mail->{'header'}->{'cc'}),"
$text{'mail_date'}",&eucconv_and_escape(&html_escape($mail->{'header'}->{'date'})), "
$text{'mail_subject'}",&eucconv_and_escape(&decode_mimewords( $mail->{'header'}->{'subject'})),"

\n"; # Just display the mail body for printing if ($body eq $textbody) { print "
";
			foreach $l (&wrap_lines($body->{'data'},
						$config{'wrap_width'})) {
				print &eucconv_and_escape($l),"\n";
				}
			print "
\n"; } elsif ($body eq $htmlbody) { print "
\n"; print &safe_html($body->{'data'}); print "
\n"; } print "\n"; exit; } elsif ($in{'mark1'} || $in{'mark2'}) { # Just mark the message dbmopen(%read, "$module_config_directory/$in{'user'}.read", 0600); $mode = $in{'mark1'} ? $in{'mode1'} : $in{'mode2'}; if ($mode) { $read{$mail->{'header'}->{'message-id'}} = $mode; } else { delete($read{$mail->{'header'}->{'message-id'}}); } $perpage = $folder->{'perpage'} || $config{'perpage'}; $s = int((@mails - $in{'idx'} - 1) / $perpage) * $perpage; &redirect("list_mail.cgi?start=$s&folder=$in{'folder'}&user=$in{'user'}"); exit; } elsif ($in{'detach'}) { # Detach some attachment to a directory on the server &error_setup($text{'detach_err'}); $in{'dir'} || &error($text{'detach_edir'}); $in{'dir'} = "$uinfo[7]/$in{'dir'}" if ($in{'dir'} !~ /^\//); &decode_and_sub(); if ($in{'attach'} eq '*') { # Detaching all attachments, under their filenames @dattach = grep { $_->{'idx'} ne $in{'bindex'} } @{$mail->{'attach'}}; } else { # Just one attachment @dattach = ( $mail->{'attach'}->[$in{'attach'}] ); } local @paths; foreach $attach (@dattach) { local $path; if (-d $in{'dir'}) { # Just write to the filename in the directory local $fn; if ($attach->{'filename'}) { $fn = &decode_mimewords( $attach->{'filename'}); } else { $attach->{'type'} =~ /\/(\S+)$/; $fn = "file.$1"; } $path = "$in{'dir'}/$fn"; } else { # Assume a full path was given $path = $in{'dir'}; } push(@paths, $path); } &switch_to_user($in{'user'}); for($i=0; $i<@dattach; $i++) { # Try to write the files &open_tempfile(FILE, ">$paths[$i]", 1, 1) || &error(&text('detach_eopen', "$paths[$i]", $!)); (print FILE $dattach[$i]->{'data'}) || &error(&text('detach_ewrite', "$paths[$i]", $!)); close(FILE) || &error(&text('detach_ewrite', "$paths[$i]", $!)); } &switch_user_back(); # Show a message about the new files &mail_page_header($text{'detach_title'}, undef, undef, &folder_link($in{'user'}, $folder)); for($i=0; $i<@dattach; $i++) { local $sz = (int(length($dattach[$i]->{'data'}) / 1000)+1)." Kb"; print "

",&text('detach_ok', "$paths[$i]", $sz),"

\n"; } &mail_page_footer("view_mail.cgi?idx=$in{'idx'}&folder=$in{'folder'}&user=$in{'user'}", $text{'view_return'}, "list_mail.cgi?folder=$in{'folder'}&user=$in{'user'}", $text{'mail_return'}, "", $text{'index_return'}); exit; } elsif ($in{'black'}) { # Add sender to global SpamAssassin blacklist, and tell user &mail_page_header($text{'black_title'}); &foreign_require("spam", "spam-lib.pl"); local $conf = &spam::get_config(); local @from = map { @{$_->{'words'}} } &spam::find("blacklist_from", $conf); local %already = map { $_, 1 } @from; local ($spamfrom) = &address_parts($mail->{'header'}->{'from'}); if ($already{$spamfrom}) { print "",&text('black_already', "$spamfrom"),"

\n"; } else { push(@from, $spamfrom); &spam::save_directives($conf, 'blacklist_from', \@from, 1); &flush_file_lines(); print "",&text('black_done', "$spamfrom"),"

\n"; } &mail_page_footer("list_mail.cgi?folder=$in{'folder'}&user=$in{'user'}", $text{'mail_return'}, "", $text{'index_return'}); exit; } elsif ($in{'razor'}) { # Report message to Razor and tell user &mail_page_header($text{'razor_title'}); print "$text{'razor_report'}\n"; print "

";
		local $cmd = &spam_report_cmd($in{'user'});
		local $temp = &transname();
		&send_mail($mail, $temp, 0, 1);
		&open_execute_command(OUT, "$cmd <$temp 2>&1", 1);
		local $error;
		while() {
			print &html_escape($_);
			$error++ if (/failed/i);
			}
		close(OUT);
		unlink($temp);
		print "
\n"; if ($? || $error) { print "$text{'razor_err'}

\n"; } else { if ($config{'spam_del'}) { # Delete message too &lock_folder($folder); &mailbox_delete_mail($folder, $mail); &unlock_folder($folder); print "$text{'razor_deleted'}

\n"; } else { print "$text{'razor_done'}

\n"; } } &mail_page_footer("list_mail.cgi?folder=$in{'folder'}&user=$in{'user'}", $text{'mail_return'}, "", $text{'index_return'}); exit; } if (!@mailforward) { &parse_mail($mail); @attach = @{$mail->{'attach'}}; } if ($in{'strip'}) { # Remove all non-body attachments local $newmail = { 'headers' => $mail->{'headers'}, 'header' => $mail->{'header'}, 'fromline' => $mail->{'fromline'} }; foreach $a (@attach) { if ($a->{'type'} eq 'text/plain' || $a->{'type'} eq 'text') { $newmail->{'attach'} = [ $a ]; last; } } &lock_folder($folder); &mailbox_modify_mail($mail, $newmail, $folder); &unlock_folder($folder); &redirect("list_mail.cgi?user=$in{'user'}&folder=$in{'folder'}"); exit; } if ($in{'enew'}) { # Editing an existing message, so keep same fields $to = $mail->{'header'}->{'to'}; $rto = $mail->{'header'}->{'reply-to'}; $from = $mail->{'header'}->{'from'}; $cc = $mail->{'header'}->{'cc'}; $ouser = $1 if ($from =~ /^(\S+)\@/); } else { if (!$in{'forward'} && !@mailforward) { # Replying to a message, so set To: field $to = $mail->{'header'}->{'reply-to'}; $to = $mail->{'header'}->{'from'} if (!$to); } if ($in{'rall'}) { # If replying to all, add any addresses in the original # To: or Cc: to our new Cc: address. # XXX should strip own addresses $cc = $mail->{'header'}->{'to'}; $cc .= ", ".$mail->{'header'}->{'cc'} if ($mail->{'header'}->{'cc'}); } } # Work out new subject, depending on whether we are replying # our forwarding a message (or neither) local $qu = !$in{'enew'} && (!$in{'forward'} || !$config{'fwd_mode'}); $subject = &html_escape(&decode_mimewords( $mail->{'header'}->{'subject'})); $subject = "Re: ".$subject if ($subject !~ /^Re/i && !$in{'forward'} && !@mailforward && !$in{'enew'}); $subject = "Fwd: ".$subject if ($subject !~ /^Fwd/i && ($in{'forward'} || @mailforward)); # Construct the initial mail text $sig = &get_signature($in{'user'}); ($quote, $html_edit, $body) = "ed_message($mail, $qu, $sig); if ($in{'forward'} || $in{'enew'}) { @attach = grep { $_ ne $body } @attach; } else { undef(@attach); } # Show header &mail_page_header( $in{'forward'} || @mailforward ? $text{'forward_title'} : $in{'enew'} ? $text{'enew_title'} : $text{'reply_title'}, undef, $html_edit ? "onload='initEditor()'" : "", &folder_link($in{'user'}, $folder)); } print "

\n"; # Output various hidden fields print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; foreach $s (@sub) { print "\n"; } print "\n"; print "\n"; print "
$text{'reply_headers'}
\n"; # Work out and show the From: address print "\n"; $from ||= &get_user_from_address(\@uinfo); if ($access{'fmode'} == 0) { # Any email addresss print "\n"; } elsif ($access{'fmode'} == 1) { # User's name in selected domains local $u = $from || $ouser || $in{'user'}; $u =~ s/\@.*$//; print "\n"; } elsif ($access{'fmode'} == 2) { # Listed from addresses print "\n"; } elsif ($access{'fmode'} == 3) { # Fixed address in fixed domain print "\n"; } $to = &html_escape($to); print " ", "\n"; $cc = &html_escape($cc); print " ", "\n"; print " ", "\n"; print " ", "\n"; print " ", "\n"; print "
$text{'mail_from'}$ouser\@$access{'from'}$text{'mail_to'}
$text{'mail_cc'}$text{'mail_bcc'}
$text{'mail_subject'}$text{'mail_pri'}\n", "\n", "
\n", "

\n"; # Output message body input print "\n", "", "
$text{'reply_body'}
"; if ($html_edit) { # Output HTML editor textarea print < _editor_url = "$gconfig{'webprefix'}/$module_name/xinha/"; _editor_lang = "en"; EOF print "\n"; } else { # Show text editing area print "\n"; if (&has_command("ispell")) { print "
\n"; print " $text{'reply_spell'}\n"; } } print "

\n"; print "\n"; # Display forwarded attachments if (@attach) { print "\n"; print "\n"; print "
$text{'reply_attach'}
\n"; foreach $a (@attach) { push(@titles, "{'idx'} checked> ".($a->{'filename'} ? $a->{'filename'} : $a->{'type'})); push(@links, "detach.cgi?idx=$in{'idx'}&folder=$in{'folder'}&attach=$a->{'idx'}$subs"); push(@icons, "images/boxes.gif"); } &icons_table(\@links, \@titles, \@icons, 8); print "

\n"; } # Display forwarded mails if (@mailforward) { print "\n"; print "\n"; print "
$text{'reply_mailforward'}
\n"; foreach $f (@mailforward) { push(@titles, &simplify_subject($mails[$f]->{'header'}->{'subject'})); push(@links, "view_mail.cgi?idx=$f&folder=$in{'folder'}&user=$in{'user'}"); push(@icons, "images/boxes.gif"); print "\n"; } &icons_table(\@links, \@titles, \@icons, 8); print "

\n"; } # Add form for more attachments print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; if ($access{'canattach'}) { print "\n"; print "\n"; print "\n"; } print "
$text{'reply_attach2'}
", &file_chooser_button("file0")," ", &file_chooser_button("file1")," ", &file_chooser_button("file2"),"

\n"; print "\n"; print "

\n"; &mail_page_footer("list_mail.cgi?folder=$in{'folder'}&user=$in{'user'}", $text{'mail_return'}, "", $text{'index_return'}); sub decode_and_sub { return if (!$mail); &parse_mail($mail); @sub = split(/\0/, $in{'sub'}); $subs = join("", map { "&sub=$_" } @sub); foreach $s (@sub) { # We are looking at a mail within a mail .. local $amail = &extract_mail( $mail->{'attach'}->[$s]->{'data'}); &parse_mail($amail); $mail = $amail; } }