4
* SquirrelMail Spam Buttons Plugin
5
* Copyright (c) 2005-2008 Paul Lesniewski <paul@squirrelmail.org>,
6
* Licensed under the GNU GPL. For full terms see the file COPYING.
9
* @subpackage spam_buttons
16
// ripped from src/compose.php
19
/* This function is used when not sending or adding attachments */
20
function newMail ($mailbox='', $passed_id='', $passed_ent_id='', $action='', $session='') {
21
global $editor_size, $default_use_priority, $body, $idents,
22
$use_signature, $composesession, $data_dir, $username,
23
$username, $key, $imapServerAddress, $imapPort, $compose_messages,
24
$composeMessage, $body_quote;
25
global $languages, $squirrelmail_language, $default_charset;
28
* Set $default_charset to correspond with the user's selection
29
* of language interface. $default_charset global is not correct,
30
* if message is composed in new window.
34
$send_to = $send_to_cc = $send_to_bcc = $subject = $identity = '';
38
$imapConnection = sqimap_login($username, $key, $imapServerAddress,
41
sqimap_mailbox_select($imapConnection, $mailbox);
42
$message = sqimap_get_message($imapConnection, $passed_id, $mailbox);
46
/* redefine the messsage in case of message/rfc822 */
47
$message = $message->getEntity($passed_ent_id);
48
/* message is an entity which contains the envelope and type0=message
49
* and type1=rfc822. The actual entities are childs from
50
* $message->entities[0]. That's where the encoding and is located
53
$entities = $message->entities[0]->findDisplayEntity
54
(array(), $alt_order = array('text/plain'));
55
if (!count($entities)) {
56
$entities = $message->entities[0]->findDisplayEntity
57
(array(), $alt_order = array('text/plain','text/html'));
59
$orig_header = $message->rfc822_header; /* here is the envelope located */
60
/* redefine the message for picking up the attachments */
61
$message = $message->entities[0];
64
$entities = $message->findDisplayEntity (array(), $alt_order = array('text/plain'));
65
if (!count($entities)) {
66
$entities = $message->findDisplayEntity (array(), $alt_order = array('text/plain','text/html'));
68
$orig_header = $message->rfc822_header;
71
$encoding = $message->header->encoding;
72
$type0 = $message->type0;
73
$type1 = $message->type1;
74
foreach ($entities as $ent) {
75
$unencoded_bodypart = mime_fetch_body($imapConnection, $passed_id, $ent);
76
$body_part_entity = $message->getEntity($ent);
77
$bodypart = decodeBody($unencoded_bodypart,
78
$body_part_entity->header->encoding);
79
if ($type1 == 'html') {
80
$bodypart = str_replace("\n", ' ', $bodypart);
81
$bodypart = preg_replace(array('/<p>/i','/<br\s*(\/)*>/i'), "\n", $bodypart);
82
$bodypart = str_replace(array(' ','>','<'),array(' ','>','<'),$bodypart);
83
$bodypart = strip_tags($bodypart);
85
if (isset($languages[$squirrelmail_language]['XTRA_CODE']) &&
86
function_exists($languages[$squirrelmail_language]['XTRA_CODE'])) {
87
if (mb_detect_encoding($bodypart) != 'ASCII') {
88
$bodypart = $languages[$squirrelmail_language]['XTRA_CODE']('decode', $bodypart);
92
// charset encoding in compose form stuff
93
if (isset($body_part_entity->header->parameters['charset'])) {
94
$actual = $body_part_entity->header->parameters['charset'];
99
if ( $actual && is_conversion_safe($actual) && $actual != $default_charset){
100
$bodypart = charset_convert($actual,$bodypart,$default_charset,false);
102
// end of charset encoding in compose
106
if ($default_use_priority) {
107
$mailprio = substr($orig_header->priority,0,1);
116
$from_o = $orig_header->from;
117
if (is_array($from_o)) {
118
if (isset($from_o[0])) {
119
$from_o = $from_o[0];
122
if (is_object($from_o)) {
123
$orig_from = $from_o->getAddress();
128
$identities = array();
129
if (count($idents) > 1) {
130
foreach($idents as $nr=>$data) {
131
$enc_from_name = '"'.$data['full_name'].'" <'. $data['email_address'].'>';
132
if(strtolower($enc_from_name) == strtolower($orig_from)) {
136
$identities[] = $enc_from_name;
139
$identity_match = $orig_header->findAddress($identities);
140
if ($identity_match) {
141
$identity = $identity_match;
147
$use_signature = FALSE;
148
$composeMessage->rfc822_header = $orig_header;
149
$send_to = decodeHeader($orig_header->getAddr_s('to'),false,false,true);
150
$send_to_cc = decodeHeader($orig_header->getAddr_s('cc'),false,false,true);
151
$send_to_bcc = decodeHeader($orig_header->getAddr_s('bcc'),false,false,true);
152
// FIXME: ident support?
153
$subject = decodeHeader($orig_header->subject,false,false,true);
154
/* remember the references and in-reply-to headers in case of an reply */
155
$composeMessage->rfc822_header->more_headers['References'] = $orig_header->references;
156
$composeMessage->rfc822_header->more_headers['In-Reply-To'] = $orig_header->in_reply_to;
157
$body_ary = explode("\n", $body);
158
$cnt = count($body_ary) ;
160
for ($i=0; $i < $cnt; $i++) {
161
if (!ereg("^[>\\s]*$", $body_ary[$i]) || !$body_ary[$i]) {
162
sqWordWrap($body_ary[$i], $editor_size, $default_charset );
163
$body .= $body_ary[$i] . "\n";
165
unset($body_ary[$i]);
168
$composeMessage = getAttachments($message, $composeMessage, $passed_id, $entities, $imapConnection);
170
case ('edit_as_new'):
171
$send_to = decodeHeader($orig_header->getAddr_s('to'),false,false,true);
172
$send_to_cc = decodeHeader($orig_header->getAddr_s('cc'),false,false,true);
173
$send_to_bcc = decodeHeader($orig_header->getAddr_s('bcc'),false,false,true);
174
$subject = decodeHeader($orig_header->subject,false,false,true);
175
$mailprio = $orig_header->priority;
177
$composeMessage = getAttachments($message, $composeMessage, $passed_id, $entities, $imapConnection);
182
$subject = decodeHeader($orig_header->subject,false,false,true);
183
if ((substr(strtolower($subject), 0, 4) != 'fwd:') &&
184
(substr(strtolower($subject), 0, 5) != '[fwd:') &&
185
(substr(strtolower($subject), 0, 6) != '[ fwd:')) {
186
$subject = '[Fwd: ' . $subject . ']';
188
$body = getforwardHeader($orig_header) . $body;
189
$composeMessage = getAttachments($message, $composeMessage, $passed_id, $entities, $imapConnection);
190
$body = "\n" . $body;
192
case ('forward_as_attachment'):
193
$composeMessage = getMessage_RFC822_Attachment($message, $composeMessage, $passed_id, $passed_ent_id, $imapConnection);
195
/// CHANGE FOR SPAM_BUTTONS PLUGIN (added next 6 lines)
196
$subject = decodeHeader($orig_header->subject,false,false,true);
197
if ((substr(strtolower($subject), 0, 4) != 'fwd:') &&
198
(substr(strtolower($subject), 0, 5) != '[fwd:') &&
199
(substr(strtolower($subject), 0, 6) != '[ fwd:')) {
200
$subject = '[Fwd: ' . $subject . ']';
204
if(isset($orig_header->mail_followup_to) && $orig_header->mail_followup_to) {
205
$send_to = $orig_header->getAddr_s('mail_followup_to');
207
$send_to_cc = replyAllString($orig_header);
208
$send_to_cc = decodeHeader($send_to_cc,false,false,true);
212
$send_to = $orig_header->reply_to;
213
if (is_array($send_to) && count($send_to)) {
214
$send_to = $orig_header->getAddr_s('reply_to');
215
} else if (is_object($send_to)) { /* unneccesarry, just for failsafe purpose */
216
$send_to = $orig_header->getAddr_s('reply_to');
218
$send_to = $orig_header->getAddr_s('from');
221
$send_to = decodeHeader($send_to,false,false,true);
222
$subject = decodeHeader($orig_header->subject,false,false,true);
223
$subject = trim($subject);
224
if (substr(strtolower($subject), 0, 3) != 're:') {
225
$subject = 'Re: ' . $subject;
227
/* this corrects some wrapping/quoting problems on replies */
228
$rewrap_body = explode("\n", $body);
229
$from = (is_array($orig_header->from) && !empty($orig_header->from)) ? $orig_header->from[0] : $orig_header->from;
232
$cnt = count($rewrap_body);
233
for ($i=0;$i<$cnt;$i++) {
234
sqWordWrap($rewrap_body[$i], $editor_size, $default_charset);
235
if (preg_match("/^(>+)/", $rewrap_body[$i], $matches)) {
237
$body .= $body_quote . str_replace("\n", "\n" . $body_quote
238
. "$gt ", rtrim($rewrap_body[$i])) ."\n";
240
$body .= $body_quote . (!empty($body_quote) ? ' ' : '') . str_replace("\n", "\n" . $body_quote . (!empty($body_quote) ? ' ' : ''), rtrim($rewrap_body[$i])) . "\n";
242
unset($rewrap_body[$i]);
244
$body = getReplyCitation($from , $orig_header->date) . $body;
245
$composeMessage->reply_rfc822_header = $orig_header;
251
/// CHANGE FOR SPAM_BUTTONS PLUGIN
252
/// $compose_messages[$session] = $composeMessage;
253
/// // Not used any more, but left for posterity
254
/// //sqsession_register($compose_messages, 'compose_messages');
255
/// session_write_close();
256
/// sqimap_logout($imapConnection);
258
$ret = array( 'send_to' => $send_to,
259
'send_to_cc' => $send_to_cc,
260
'send_to_bcc' => $send_to_bcc,
261
'subject' => $subject,
262
'mailprio' => $mailprio,
264
'identity' => $identity );
267
} /* function newMail() */
269
function getforwardHeader($orig_header) {
272
$display = array( _("Subject") => strlen(_("Subject")),
273
_("From") => strlen(_("From")),
274
_("Date") => strlen(_("Date")),
275
_("To") => strlen(_("To")),
276
_("Cc") => strlen(_("Cc")) );
277
$maxsize = max($display);
278
$indent = str_pad('',$maxsize+2);
279
foreach($display as $key => $val) {
280
$display[$key] = $key .': '. str_pad('', $maxsize - $val);
282
$from = decodeHeader($orig_header->getAddr_s('from',"\n$indent"),false,false,true);
283
$from = str_replace(' ',' ',$from);
284
$to = decodeHeader($orig_header->getAddr_s('to',"\n$indent"),false,false,true);
285
$to = str_replace(' ',' ',$to);
286
$subject = decodeHeader($orig_header->subject,false,false,true);
287
$subject = str_replace(' ',' ',$subject);
288
$bodyTop = str_pad(' '._("Original Message").' ',$editor_size -2,'-',STR_PAD_BOTH) .
289
"\n". $display[_("Subject")] . $subject . "\n" .
290
$display[_("From")] . $from . "\n" .
291
$display[_("Date")] . getLongDateString( $orig_header->date, $orig_header->date_unparsed ). "\n" .
292
$display[_("To")] . $to . "\n";
293
if ($orig_header->cc != array() && $orig_header->cc !='') {
294
$cc = decodeHeader($orig_header->getAddr_s('cc',"\n$indent"),false,false,true);
295
$cc = str_replace(' ',' ',$cc);
296
$bodyTop .= $display[_("Cc")] .$cc . "\n";
298
$bodyTop .= str_pad('', $editor_size -2 , '-') .
303
function getMessage_RFC822_Attachment($message, $composeMessage, $passed_id,
304
$passed_ent_id='', $imapConnection) {
305
global $attachment_dir, $username, $data_dir, $uid_support;
306
$hashed_attachment_dir = getHashedDir($username, $attachment_dir);
307
if (!$passed_ent_id) {
308
$body_a = sqimap_run_command($imapConnection,
309
'FETCH '.$passed_id.' RFC822',
310
TRUE, $response, $readmessage,
313
$body_a = sqimap_run_command($imapConnection,
314
'FETCH '.$passed_id.' BODY['.$passed_ent_id.']',
315
TRUE, $response, $readmessage, $uid_support);
316
$message = $message->parent;
318
if ($response == 'OK') {
319
$subject = encodeHeader($message->rfc822_header->subject);
320
array_shift($body_a);
322
$body = implode('', $body_a) . "\r\n";
324
$localfilename = GenerateRandomString(32, 'FILE', 7);
325
$full_localfilename = "$hashed_attachment_dir/$localfilename";
327
$fp = fopen($full_localfilename, 'w');
330
$composeMessage->initAttachment('message/rfc822',$subject.'.msg',
333
return $composeMessage;
337
* temporary function to make use of the deliver class.
338
* In the future the responsible backend should be automaticly loaded
339
* and conf.pl should show a list of available backends.
340
* The message also should be constructed by the message class.
342
function deliverMessage($composeMessage, $draft=false) {
343
global $send_to, $send_to_cc, $send_to_bcc, $mailprio, $subject, $body,
344
$username, $popuser, $usernamedata, $identity, $idents, $data_dir,
345
$request_mdn, $request_dr, $default_charset, $color, $useSendmail,
346
$domain, $action, $default_move_to_sent, $move_to_sent;
347
global $imapServerAddress, $imapPort, $sent_folder, $key;
348
/// CHANGE FOR SPAM_BUTTONS PLUGIN
349
/* --- do we need to do overrides again here? should not need to, but
350
// someone reported problems with the default not being overriden
351
// when using this reporting method ---
352
global $spam_report_email_method, $spam_report_smtpServerAddress,
353
$spam_report_smtpPort, $spam_report_useSendmail,
354
$spam_report_smtp_auth_mech, $spam_report_use_smtp_tls,
355
$smtpServerAddress, $smtpPort, $useSendmail, $smtp_auth_mech,
356
$use_smtp_tls, $sb_debug;
361
// take care of overrides for SMTP server
363
if (!empty($spam_report_smtpServerAddress))
364
$smtpServerAddress = $spam_report_smtpServerAddress;
365
if (!empty($spam_report_smtpPort))
366
$smtpPort = $spam_report_smtpPort;
367
if ($spam_report_useSendmail !== '')
368
$useSendmail = $spam_report_useSendmail;
369
if (!empty($spam_report_smtp_auth_mech))
370
$smtp_auth_mech = $spam_report_smtp_auth_mech;
371
if (!empty($spam_report_use_smtp_tls))
372
$use_smtp_tls = $spam_report_use_smtp_tls;
375
$rfc822_header = $composeMessage->rfc822_header;
377
$abook = addressbook_init(false, true);
378
$rfc822_header->to = $rfc822_header->parseAddress($send_to,true, array(), '', $domain, array(&$abook,'lookup'));
379
$rfc822_header->cc = $rfc822_header->parseAddress($send_to_cc,true,array(), '',$domain, array(&$abook,'lookup'));
380
$rfc822_header->bcc = $rfc822_header->parseAddress($send_to_bcc,true, array(), '',$domain, array(&$abook,'lookup'));
381
$rfc822_header->priority = $mailprio;
382
$rfc822_header->subject = $subject;
384
$special_encoding='';
385
if (strtolower($default_charset) == 'iso-2022-jp') {
386
if (mb_detect_encoding($body) == 'ASCII') {
387
$special_encoding = '8bit';
389
$body = mb_convert_encoding($body, 'JIS');
390
$special_encoding = '7bit';
393
$composeMessage->setBody($body);
395
if (ereg("^([^@%/]+)[@%/](.+)$", $username, $usernamedata)) {
396
$popuser = $usernamedata[1];
397
$domain = $usernamedata[2];
398
unset($usernamedata);
400
$popuser = $username;
403
$from_mail = $idents[$identity]['email_address'];
404
$full_name = $idents[$identity]['full_name'];
405
$reply_to = $idents[$identity]['reply_to'];
407
$from_mail = "$popuser@$domain";
409
$rfc822_header->from = $rfc822_header->parseAddress($from_mail,true);
411
$from = $rfc822_header->from[0];
412
if (!$from->host) $from->host = $domain;
413
$full_name_encoded = encodeHeader($full_name);
414
if ($full_name_encoded != $full_name) {
415
$from_addr = $full_name_encoded .' <'.$from->mailbox.'@'.$from->host.'>';
417
$from_addr = '"'.$full_name .'" <'.$from->mailbox.'@'.$from->host.'>';
419
$rfc822_header->from = $rfc822_header->parseAddress($from_addr,true);
422
$rfc822_header->reply_to = $rfc822_header->parseAddress($reply_to,true);
424
/* Receipt: On Read */
425
if (isset($request_mdn) && $request_mdn) {
426
$rfc822_header->dnt = $rfc822_header->parseAddress($from_mail,true);
429
/* Receipt: On Delivery */
430
if (isset($request_dr) && $request_dr) {
431
$rfc822_header->more_headers['Return-Receipt-To'] = $from_mail;
434
/* multipart messages */
435
if (count($composeMessage->entities)) {
436
$message_body = new Message();
437
$message_body->body_part = $composeMessage->body_part;
438
$composeMessage->body_part = '';
439
$mime_header = new MessageHeader;
440
$mime_header->type0 = 'text';
441
$mime_header->type1 = 'plain';
442
if ($special_encoding) {
443
$mime_header->encoding = $special_encoding;
445
$mime_header->encoding = '8bit';
447
if ($default_charset) {
448
$mime_header->parameters['charset'] = $default_charset;
450
$message_body->mime_header = $mime_header;
451
array_unshift($composeMessage->entities, $message_body);
452
$content_type = new ContentType('multipart/mixed');
454
$content_type = new ContentType('text/plain');
455
if ($special_encoding) {
456
$rfc822_header->encoding = $special_encoding;
458
$rfc822_header->encoding = '8bit';
460
if ($default_charset) {
461
$content_type->properties['charset']=$default_charset;
465
$rfc822_header->content_type = $content_type;
466
$composeMessage->rfc822_header = $rfc822_header;
468
/* Here you can modify the message structure just before we hand
469
it over to deliver */
470
/// CHANGE FOR SPAM_BUTTONS PLUGIN
471
/// $hookReturn = do_hook('compose_send', $composeMessage);
472
/// /* Get any changes made by plugins to $composeMessage. */
473
/// if ( is_object($hookReturn[1]) ) {
474
/// $composeMessage = $hookReturn[1];
477
if (!$useSendmail && !$draft) {
478
require_once(SM_PATH . 'class/deliver/Deliver_SMTP.class.php');
479
$deliver = new Deliver_SMTP();
480
global $smtpServerAddress, $smtpPort, $pop_before_smtp, $smtp_auth_mech;
482
$authPop = (isset($pop_before_smtp) && $pop_before_smtp) ? true : false;
487
get_smtp_user($user, $pass);
489
$stream = $deliver->initStream($composeMessage,$domain,0,
490
$smtpServerAddress, $smtpPort, $user, $pass, $authPop);
492
require_once(SM_PATH . 'class/deliver/Deliver_SendMail.class.php');
493
global $sendmail_path, $sendmail_args;
494
// Check for outdated configuration
495
if (!isset($sendmail_args)) {
496
if ($sendmail_path=='/var/qmail/bin/qmail-inject') {
499
$sendmail_args = '-i -t';
502
$deliver = new Deliver_SendMail(array('sendmail_args'=>$sendmail_args));
503
$stream = $deliver->initStream($composeMessage,$sendmail_path);
505
global $draft_folder;
506
require_once(SM_PATH . 'class/deliver/Deliver_IMAP.class.php');
507
$imap_stream = sqimap_login($username, $key, $imapServerAddress,
509
if (sqimap_mailbox_exists ($imap_stream, $draft_folder)) {
510
require_once(SM_PATH . 'class/deliver/Deliver_IMAP.class.php');
511
$imap_deliver = new Deliver_IMAP();
512
$length = $imap_deliver->mail($composeMessage);
513
sqimap_append ($imap_stream, $draft_folder, $length);
514
$imap_deliver->mail($composeMessage, $imap_stream);
515
sqimap_append_done ($imap_stream, $draft_folder);
516
sqimap_logout($imap_stream);
517
unset ($imap_deliver);
518
$composeMessage->purgeAttachments();
521
$msg = '<br />'.sprintf(_("Error: Draft folder %s does not exist."),
522
htmlspecialchars($draft_folder));
523
plain_error_message($msg, $color);
529
$length = $deliver->mail($composeMessage, $stream);
530
$succes = $deliver->finalizeStream($stream);
533
$msg = _("Message not sent.") .' '. _("Server replied:") .
534
"\n<blockquote>\n" . $deliver->dlv_msg . '<br />' .
535
$deliver->dlv_ret_nr . ' ' .
536
$deliver->dlv_server_msg . "</blockquote>\n\n";
537
plain_error_message($msg, $color);
540
$move_to_sent = getPref($data_dir,$username,'move_to_sent');
541
$imap_stream = sqimap_login($username, $key, $imapServerAddress, $imapPort, 0);
543
/* Move to sent code */
544
if (isset($default_move_to_sent) && ($default_move_to_sent != 0)) {
545
$svr_allow_sent = true;
547
$svr_allow_sent = false;
550
if (isset($sent_folder) && (($sent_folder != '') || ($sent_folder != 'none'))
551
&& sqimap_mailbox_exists( $imap_stream, $sent_folder)) {
557
if ((isset($move_to_sent) && ($move_to_sent != 0)) || (!isset($move_to_sent))) {
558
$lcl_allow_sent = true;
560
$lcl_allow_sent = false;
563
if (($fld_sent && $svr_allow_sent && !$lcl_allow_sent) || ($fld_sent && $lcl_allow_sent)) {
564
sqimap_append ($imap_stream, $sent_folder, $length);
565
require_once(SM_PATH . 'class/deliver/Deliver_IMAP.class.php');
566
$imap_deliver = new Deliver_IMAP();
567
$imap_deliver->mail($composeMessage, $imap_stream);
568
sqimap_append_done ($imap_stream, $sent_folder);
569
unset ($imap_deliver);
571
global $passed_id, $mailbox, $action;
572
$composeMessage->purgeAttachments();
573
if ($action == 'reply' || $action == 'reply_all') {
574
sqimap_mailbox_select ($imap_stream, $mailbox);
575
sqimap_messages_flag ($imap_stream, $passed_id, $passed_id, 'Answered', false);
577
sqimap_logout($imap_stream);
584
if (!function_exists('is_conversion_safe'))
587
* Function informs if it is safe to convert given charset to the one that is used by user.
589
* It is safe to use conversion only if user uses utf-8 encoding and when
590
* converted charset is similar to the one that is used by user.
592
* @param string $input_charset Charset of text that needs to be converted
593
* @return bool is it possible to convert to user's charset
595
function is_conversion_safe($input_charset) {
596
global $languages, $sm_notAlias, $default_charset, $lossy_encoding;
598
if (isset($lossy_encoding) && $lossy_encoding )
601
// convert to lower case
602
$input_charset = strtolower($input_charset);
604
// Is user's locale Unicode based ?
605
if ( $default_charset == "utf-8" ) {
609
// Charsets that are similar
610
switch ($default_charset) {
612
if ( $input_charset == "iso-8859-5" ||
613
$input_charset == "koi8-r" ||
614
$input_charset == "koi8-u" ) {
620
if ( $input_charset == "iso-8859-13" ||
621
$input_charset == "iso-8859-4" ) {
627
if ( $input_charset == "iso-8859-13" ||
628
$input_charset == "windows-1257" ) {
634
if ( $input_charset == "windows-1251" ||
635
$input_charset == "koi8-r" ||
636
$input_charset == "koi8-u" ) {
642
if ( $input_charset == "iso-8859-4" ||
643
$input_charset == "windows-1257" ) {
649
if ( $input_charset == "windows-1251" ||
650
$input_charset == "iso-8859-5" ||
651
$input_charset == "koi8-u" ) {
657
if ( $input_charset == "windows-1251" ||
658
$input_charset == "iso-8859-5" ||
659
$input_charset == "koi8-r" ) {