From 849bdf42ed7bd7cca68909d2b46869742dfd210e Mon Sep 17 00:00:00 2001 From: thomppj Date: Wed, 31 Oct 2001 06:10:21 +0000 Subject: [PATCH] Began rework of options page. Also added 3 plugins (filters, translate, and squirrelspell) into CVS for maintenance with the Squirrelmail core. Please note that these plugins are NOT going to be INTEGRATED with the core, just maintained alongside it here in CVS and packaged as a part of the official Squirrelmail release when we release 1.2. git-svn-id: https://svn.code.sf.net/p/squirrelmail/code/trunk/squirrelmail@1662 7612ce4b-ef26-0410-bec9-ea0150e637f0 --- plugins/filters/CHANGES | 63 ++ plugins/filters/README | 45 ++ plugins/filters/filters.php | 372 +++++++++++ plugins/filters/options.php | 349 +++++++++++ plugins/filters/setup.php | 85 +++ plugins/filters/sqimap_read_data.php | 85 +++ plugins/squirrelspell/INSTALL | 19 + plugins/squirrelspell/doc/CRYPTO | 30 + plugins/squirrelspell/doc/ChangeLog | 72 +++ plugins/squirrelspell/doc/PRIVACY | 14 + plugins/squirrelspell/doc/README | 52 ++ plugins/squirrelspell/doc/UPGRADING | 15 + plugins/squirrelspell/doc/index.php | 3 + plugins/squirrelspell/index.php | 3 + plugins/squirrelspell/js/WHATISTHIS | 3 + plugins/squirrelspell/js/check_me.js | 221 +++++++ plugins/squirrelspell/js/crypto_settings.js | 17 + plugins/squirrelspell/js/decrypt_error.js | 21 + plugins/squirrelspell/js/index.php | 3 + plugins/squirrelspell/js/init.js | 13 + plugins/squirrelspell/modules/WHATISTHIS | 3 + .../squirrelspell/modules/check_me.mod.php | 250 ++++++++ plugins/squirrelspell/modules/crypto.mod.php | 36 ++ .../modules/crypto_badkey.mod.php | 54 ++ .../squirrelspell/modules/edit_dic.mod.php | 57 ++ .../squirrelspell/modules/enc_setup.mod.php | 53 ++ .../squirrelspell/modules/forget_me.mod.php | 44 ++ .../modules/forget_me_not.mod.php | 43 ++ plugins/squirrelspell/modules/index.php | 3 + plugins/squirrelspell/modules/init.mod.php | 44 ++ .../squirrelspell/modules/lang_change.mod.php | 53 ++ .../squirrelspell/modules/lang_setup.mod.php | 30 + .../modules/options_main.mod.php | 27 + plugins/squirrelspell/setup.php | 73 +++ plugins/squirrelspell/sqspell_config.dist | 88 +++ plugins/squirrelspell/sqspell_config.php | 88 +++ plugins/squirrelspell/sqspell_functions.php | 311 ++++++++++ plugins/squirrelspell/sqspell_interface.php | 36 ++ plugins/squirrelspell/sqspell_options.php | 35 ++ plugins/translate/INSTALL | 16 + plugins/translate/README | 73 +++ plugins/translate/options.php | 144 +++++ plugins/translate/setup.php | 416 +++++++++++++ src/options.php | 586 ++++++++++++------ 44 files changed, 3844 insertions(+), 204 deletions(-) create mode 100644 plugins/filters/CHANGES create mode 100644 plugins/filters/README create mode 100644 plugins/filters/filters.php create mode 100644 plugins/filters/options.php create mode 100644 plugins/filters/setup.php create mode 100644 plugins/filters/sqimap_read_data.php create mode 100644 plugins/squirrelspell/INSTALL create mode 100644 plugins/squirrelspell/doc/CRYPTO create mode 100644 plugins/squirrelspell/doc/ChangeLog create mode 100644 plugins/squirrelspell/doc/PRIVACY create mode 100644 plugins/squirrelspell/doc/README create mode 100644 plugins/squirrelspell/doc/UPGRADING create mode 100644 plugins/squirrelspell/doc/index.php create mode 100644 plugins/squirrelspell/index.php create mode 100644 plugins/squirrelspell/js/WHATISTHIS create mode 100644 plugins/squirrelspell/js/check_me.js create mode 100644 plugins/squirrelspell/js/crypto_settings.js create mode 100644 plugins/squirrelspell/js/decrypt_error.js create mode 100644 plugins/squirrelspell/js/index.php create mode 100644 plugins/squirrelspell/js/init.js create mode 100644 plugins/squirrelspell/modules/WHATISTHIS create mode 100644 plugins/squirrelspell/modules/check_me.mod.php create mode 100644 plugins/squirrelspell/modules/crypto.mod.php create mode 100644 plugins/squirrelspell/modules/crypto_badkey.mod.php create mode 100644 plugins/squirrelspell/modules/edit_dic.mod.php create mode 100644 plugins/squirrelspell/modules/enc_setup.mod.php create mode 100644 plugins/squirrelspell/modules/forget_me.mod.php create mode 100644 plugins/squirrelspell/modules/forget_me_not.mod.php create mode 100644 plugins/squirrelspell/modules/index.php create mode 100644 plugins/squirrelspell/modules/init.mod.php create mode 100644 plugins/squirrelspell/modules/lang_change.mod.php create mode 100644 plugins/squirrelspell/modules/lang_setup.mod.php create mode 100644 plugins/squirrelspell/modules/options_main.mod.php create mode 100644 plugins/squirrelspell/setup.php create mode 100644 plugins/squirrelspell/sqspell_config.dist create mode 100644 plugins/squirrelspell/sqspell_config.php create mode 100644 plugins/squirrelspell/sqspell_functions.php create mode 100644 plugins/squirrelspell/sqspell_interface.php create mode 100644 plugins/squirrelspell/sqspell_options.php create mode 100644 plugins/translate/INSTALL create mode 100644 plugins/translate/README create mode 100644 plugins/translate/options.php create mode 100644 plugins/translate/setup.php diff --git a/plugins/filters/CHANGES b/plugins/filters/CHANGES new file mode 100644 index 00000000..e762423d --- /dev/null +++ b/plugins/filters/CHANGES @@ -0,0 +1,63 @@ +Changes since 0.8.3 +------------------- +Just changed include() calls to require_once() calls. + +Changes since 0.8.2 +------------------- +Added many new FREE anti-spam databases to lookup from. +Removed ORBS since they're off the air. + +Changes since 0.8.1 +------------------- +Added a SpamFilters_DNScache[] array that is useful for 2 reasons: + +1. You can put in IPs in the cache that override the SPAMfilter's DNS + checking routines -- either to force 'em to NOT filter email coming from + a specific IP (ie. for those pesky customers who can't figure out how to + make Exchange not be an open relay) or to force 'em to ALWAYS filter email + coming from a specific IP (ie. for those pesky sites you KNOW are SPAM + sources or relays but that aren't added to any of the DNS databases) + +2. Before the SPAMfilters do a DNS query, they check to see if the IP in + question is already in the cache. If not and the query is performed, the + result is put in the DNS cache. This makes the SPAM filters a LOT faster + when you get lots of email from various mailing lists (all coming from a + very small number of IPs). The SPAM filters don't have to do a DNS query + on every message coming from the squirrelmail-plugins mailing list -- only + one the first time through to confirm the list server isn't in any of the + DNS databases! :-) + +Changes since 0.8 +------------------- +Just fixed the Bad or malformed FETCH error that occurred when the INBOX was +empty. The spamfilter plugin did a FETCH query from MsgNum 1 to * and since +there WAS no Msg Num 1 the IMAP server would respond with an error. Now I +check the number of messages before calling spam_filters or user_filters + +Changes since 0.7 +-------------------- +Tyler made TONS of changes to incorporate the fixes I'd done and posted +about, as well as to fix the problem with number of unread messages not +showing up in the folder panel. He also added some code to scan the headers +for specific IPs in order to scan only IPs on the previous hop in the +header. + +This didn't work well for me (the IP of my gateway wasn't reported on the +Received from ... by ... line, and so RSS and DUL still had tons of false +hits. I munged it so instead it uses a single string provided at +setup/install time to find the right line in the header to find the IPs to +look for in the various databases. (see SpamFilters_YourHop in setup.php) +This seems to work pretty well for me -- faster enough to turn on all the +databases and zero (so far) false hits! (grin) + +I also found a bug in sqimap_read_data() in functions/imap_general.php. +After much discussion with Tyler, I rewrote it and posted it to +squirrelmail-devel but it hasn't been accepted/tested/blessed yet +NOTE: THIS NEW VERSION OF sqimap_read_data() IS REQUIRED BY FILTERS 0.8 +so you'll have to edit functions/imap_general.php and replace the function +with the contents of sqimap_read_data.php. + +As soon as either my version of sqimap_read_data is officially part of the +SM 1.1.2 CVS or until a new working version is posted, this is the only way +to guarantee filters 0.8 will work. + diff --git a/plugins/filters/README b/plugins/filters/README new file mode 100644 index 00000000..efb6599d --- /dev/null +++ b/plugins/filters/README @@ -0,0 +1,45 @@ +Filters 0.8.3 + +IMPORTANT: I've noticed at least one version of PHP that has bugs in the +checkdnsrr() function that the SPAM filtering code RELIES ON. In my case, +the PHP server that comes with Mandrake 8.1 has this problem -- checkdnsrr() +NEVER finds the inaddr records, even the ones that really exist. (sigh) + +NOTE!!! As of the time of this writing, there is a bug in sqimap_read_data() +in functions/imap_general.php. I rewrote it (see sqimap_read_data.php) so +if the SPAM filters aren't filtering, make a backup copy of +functions/imap_general.php, remove the sqimap_read_data() function in there +and replace it with the contents of sqimap_read_data.php. Hopefully, either +my replacement will be blessed by squirrelmail-devel or some other version +will come out soon. Now back to your regularly scheduled README... (grin) + +This is a poor alternative to procmail or Elm's filter programs. This is a +pathetic replacement for good RBL mail scanning when you get the mail. This +is more for systems that can't/won't offer that kind of functionality and +you still require it. + +This is slow. Yep. Slow. + + +To configure, you should just take a peek at setup.php and set +$SpamFilters_YourHop to some string if you want to avoid tons of false +hits on the RSS and DUL and ORBS databases. It should also speed up the +scan somewhat. + +If you do not want to enable spam filters for all users, edit setup.php and +set the $AllowSpamFilters to false. Spam filters can take TONS of time, so +if you don't want your users to complain and ask you tons of questions, this +is a quick and easy method. + +If you use UW and if you encounter strange errors while using this plugin on +your system, edit setup.php and set $UseSeparateImapConnection to true. This +may not solve the problem. One problem it might fix is if you run UW 2001 +and if you don't see the number of unread messages in your left-hand folder +pane, or if you see timeouts or IMAP server error messages. Turning on this +feature may slow down the filters a bit more since it has to open a new +connection. + +Lastly, if there are some IPs that you want to refuse email from or some IPs +you want to accept email from REGARDLESS of what the DNS databases say, you +can put in overrides in the SpamFilters_DNScache[] array. See the comments +in setup.php for more info on this. diff --git a/plugins/filters/filters.php b/plugins/filters/filters.php new file mode 100644 index 00000000..7fe9783f --- /dev/null +++ b/plugins/filters/filters.php @@ -0,0 +1,372 @@ + + * Tyler Akins + * Brent Bice + * (c) 2000 (GNU GPL - see ../../COPYING) + * + * This plugin filters your inbox into different folders based upon given + * criteria. It is most useful for people who are subscibed to mailing lists + * to help organize their messages. The argument stands that filtering is + * not the place of the client, which is why this has been made a plugin for + * SquirrelMail. You may be better off using products such as Sieve or + * Procmail to do your filtering so it happens even when SquirrelMail isn't + * running. + * + * If you need help with this, or see improvements that can be made, please + * email me directly at the address above. I definately welcome suggestions + * and comments. This plugin, as is the case with all SquirrelMail plugins, + * is not directly supported by the developers. Please come to me off the + * mailing list if you have trouble with it. + * + * Also view plugins/README.plugins for more information. + * + */ + + function start_filters() { + global $username, $key, $imapServerAddress, $imapPort, $imap, + $imap_general, $filters, $imap_stream, $imapConnection, + $UseSeparateImapConnection, $AllowSpamFilters; + + // Detect if we have already connected to IMAP or not. + // Also check if we are forced to use a separate IMAP connection + if ((!isset($imap_stream) && !isset($imapConnection)) || + $UseSeparateImapConnection) { + $stream = sqimap_login($username, $key, $imapServerAddress, + $imapPort, 10); + $previously_connected = false; + } elseif (isset($imapConnection)) { + $stream = $imapConnection; + $previously_connected = true; + } else { + $previously_connected = true; + $stream = $imap_stream; + } + + if (sqimap_get_num_messages($stream, "INBOX") > 0) { + // Filter spam from inbox before we sort them into folders + if ($AllowSpamFilters) + spam_filters($stream); + + // Sort into folders + user_filters($stream); + } + + if (!$previously_connected) + sqimap_logout($stream); + } + + + function user_filters($imap_stream) { + $filters = load_filters(); + if (! $filters) return; + + sqimap_mailbox_select($imap_stream, 'INBOX'); + + // For every rule + for ($i=0; $i < count($filters); $i++) { + // If it is the "combo" rule + if ($filters[$i]["where"] == "To or Cc") { + /* + * If it's "TO OR CC", we have to do two searches, one for TO + * and the other for CC. + */ + filter_search_and_delete($imap_stream, 'TO', + $filters[$i]['what'], $filters[$i]['folder']); + filter_search_and_delete($imap_stream, 'CC', + $filters[$i]['what'], $filters[$i]['folder']); + } else { + /* + * If it's a normal TO, CC, SUBJECT, or FROM, then handle it + * normally. + */ + filter_search_and_delete($imap_stream, $filters[$i]['where'], + $filters[$i]['what'], $filters[$i]['folder']); + } + } + // Clean out the mailbox whether or not auto_expunge is on + // That way it looks like it was redirected properly + sqimap_mailbox_expunge($imap_stream, 'INBOX'); + } + + function filter_search_and_delete($imap, $where, $what, $where_to) { + fputs ($imap, 'a001 SEARCH ALL ' . $where . ' "' . addslashes($what) . + "\"\r\n"); + $read = sqimap_read_data ($imap, 'a001', true, $response, $message); + + // This may have problems with EIMS due to it being goofy + + for ($r=0; $r < count($read) && + substr($read[$r], 0, 8) != '* SEARCH'; $r++) {} + if ($response == 'OK') { + $ids = explode(' ', $read[$r]); + if (sqimap_mailbox_exists($imap, $where_to)) { + for ($j=2; $j < count($ids); $j++) { + $id = trim($ids[$j]); + sqimap_messages_copy ($imap, $id, $id, $where_to); + sqimap_messages_flag ($imap, $id, $id, 'Deleted'); + } + } + } + } + + // These are the spam filters + function spam_filters($imap_stream) { + global $data_dir, $username; + global $SpamFilters_YourHop; + global $SpamFilters_DNScache; + + $filters_spam_scan = getPref($data_dir, $username, "filters_spam_scan"); + $filters_spam_folder = getPref($data_dir, $username, "filters_spam_folder"); + $filters = load_spam_filters(); + + $run = 0; + + foreach ($filters as $Key=> $Value) { + if ($Value['enabled']) + $run ++; + } + + // short-circuit + if ($run == 0) { + return; + } + + sqimap_mailbox_select($imap_stream, 'INBOX'); + + // Ask for a big list of all "Received" headers in the inbox with + // flags for each message. Kinda big. + fputs($imap_stream, 'A3999 FETCH 1:* (FLAGS BODY.PEEK[HEADER.FIELDS ' . + "(RECEIVED)])\r\n"); + + $read = sqimap_read_data ($imap_stream, 'A3999', true, $response, $message); + + if ($response != 'OK') + return; + + $i = 0; + while ($i < count($read)) { + // EIMS will give funky results + $Chunks = explode(' ', $read[$i]); + if ($Chunks[0] != '*') { + $i ++; + continue; + } + $MsgNum = $Chunks[1]; + + $IPs = array(); + $i ++; + $IsSpam = 0; + $Scan = 1; + + // Check for normal IMAP servers + if ($filters_spam_scan == 'new') { + if (is_int(strpos($Chunks[4], '\Seen'))) { + $Scan = 0; + } + } + + // Look through all of the Received headers for IP addresses + // Stop when I get ")" on a line + // Stop if I get "*" on a line (don't advance) + // and above all, stop if $i is bigger than the total # of lines + while (($i < count($read)) && + ($read[$i][0] != ')' && $read[$i][0] != '*' && + $read[$i][0] != "\n") && (! $IsSpam)) + { + // Check to see if this line is the right "Received from" line + // to check + if (is_int(strpos($read[$i], $SpamFilters_YourHop))) { + + // short-circuit and skip work if we don't scan this one + if ($Scan) { + $read[$i] = ereg_replace('[^0-9\.]', ' ', $read[$i]); + $elements = explode(' ', $read[$i]); + foreach ($elements as $value) { + if ($value != '' && + ereg('[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}', + $value, $regs)) { + $Chunks = explode('.', $value); + if ("$SpamFilters_DNScache[$value]" == "") { + $SpamFilters_DNScache[$value] = + filters_spam_check_site($Chunks[0], $Chunks[1], + $Chunks[2], $Chunks[3], $filters); + } + if ($SpamFilters_DNScache[$value]) { + $IsSpam ++; + break; // no sense in checking more IPs + } + } + } + } + } + $i ++; + } + + // Lookie! It's spam! Yum! + if ($IsSpam) { + if (sqimap_mailbox_exists ($imap_stream, $filters_spam_folder)) { + sqimap_messages_copy ($imap_stream, $MsgNum, $MsgNum, + $filters_spam_folder); + sqimap_messages_flag ($imap_stream, $MsgNum, $MsgNum, + 'Deleted'); + } + } + } + + sqimap_mailbox_expunge($imap_stream, 'INBOX'); + } + + + // Does the loop through each enabled filter for the specified IP address. + // IP format: $a.$b.$c.$d + function filters_spam_check_site($a, $b, $c, $d, &$filters) { + foreach ($filters as $key => $value) { + if ($filters[$key]['enabled']) { + if ($filters[$key]['dns']) { + if (checkdnsrr("$d.$c.$b.$a." . $filters[$key]['dns'], + 'ANY')) { + return 1; + } + } + } + } + return 0; + } + + function load_filters() { + global $data_dir, $username; + $filters = array(); + for ($i=0; $fltr = getPref($data_dir, $username, 'filter' . $i); $i++) { + $ary = explode(',', $fltr); + $filters[$i]['where'] = $ary[0]; + $filters[$i]['what'] = $ary[1]; + $filters[$i]['folder'] = $ary[2]; + } + return $filters; + } + + function load_spam_filters() { + global $data_dir, $username; + + $filters['MAPS RBL']['prefname'] = 'filters_spam_maps_rbl'; + $filters['MAPS RBL']['name'] = 'MAPS Realtime Blackhole List'; + $filters['MAPS RBL']['link'] = 'http://www.mail-abuse.org/rbl/'; + $filters['MAPS RBL']['dns'] = 'blackholes.mail-abuse.org'; + $filters['MAPS RBL']['comment'] = +'COMMERCIAL - This list contains servers that are verified spam senders. +It is a pretty reliable list to scan spam from.'; + + $filters['MAPS RSS']['prefname'] = 'filters_spam_maps_rss'; + $filters['MAPS RSS']['name'] = 'MAPS Relay Spam Stopper'; + $filters['MAPS RSS']['link'] = 'http://www.mail-abuse.org/rss/'; + $filters['MAPS RSS']['dns'] = 'relays.mail-abuse.org'; + $filters['MAPS RSS']['comment'] = +'COMMERCIAL - Servers that are configured (or misconfigured) to allow spam to +be relayed through their system will be banned with this. Another good one to +use.'; + + $filters['MAPS DUL']['prefname'] = 'filters_spam_maps_dul'; + $filters['MAPS DUL']['name'] = 'MAPS Dial-Up List'; + $filters['MAPS DUL']['link'] = 'http://www.mail-abuse.org/dul/'; + $filters['MAPS DUL']['dns'] = 'dialups.mail-abuse.org'; + $filters['MAPS DUL']['comment'] = +'COMMERCIAL - Dial-up users are often filtered out since they should use their +ISP\'s mail servers to send mail. Spammers typically get a dial-up account +and send spam directly from there.'; + + $filters['MAPS RBLplus']['prefname'] = 'filters_spam_maps_rblplus'; + $filters['MAPS RBLplus']['name'] = 'MAPS RBL+ List'; + $filters['MAPS RBLplus']['link'] = 'http://www.mail-abuse.org/'; + $filters['MAPS RBLplus']['dns'] = 'rbl-plus.mail-abuse.org'; + $filters['MAPS RBLplus']['comment'] = +'COMMERCIAL - RBL+ is a combination of RSS, DUL, and RBL.'; + + $filters['Osirusoft']['prefname'] = 'filters_spam_maps_osirusoft'; + $filters['Osirusoft']['name'] = 'Osirusoft List'; + $filters['Osirusoft']['link'] = 'http://relays.osirusoft.com/'; + $filters['Osirusoft']['dns'] = 'relays.osirusoft.com'; + $filters['Osirusoft']['comment'] = +'FREE - Osirusoft - Very thorough, but also rejects replies from many +ISP\'s abuse@domain.name email messages for some reason.'; + + $filters['ORDB']['prefname'] = 'filters_spam_ordb'; + $filters['ORDB']['name'] = 'Open Relay Database List'; + $filters['ORDB']['link'] = 'http://www.ordb.org/'; + $filters['ORDB']['dns'] = 'relays.ordb.org'; + $filters['ORDB']['comment'] = +'FREE - ORDB was born when ORBS went off the air. It seems to have fewer false +positives than ORBS did though.'; + + $filters['ORBZ']['prefname'] = 'filters_spam_orbz'; + $filters['ORBZ']['name'] = 'ORBZ List'; + $filters['ORBZ']['link'] = 'http://www.orbz.org/'; + $filters['ORBZ']['dns'] = 'inputs.orbz.org'; + $filters['ORBZ']['comment'] = +'FREE - Another ORBS replacement (just the INPUTS database used here).'; + + $filters['Five-Ten']['prefname'] = 'filters_spam_fiveten'; + $filters['Five-Ten']['name'] = 'Five-Ten-sg.com Lists'; + $filters['Five-Ten']['link'] = 'http://www.five-ten-sg.com/blackhole.php'; + $filters['Five-Ten']['dns'] = 'blackholes.five-ten-sg.com'; + $filters['Five-Ten']['comment'] = +'FREE - Five-Ten-sg.com has SPAM source, OpenRelay, and and Dialup IPs.'; + + $filters['Dorkslayers']['prefname'] = 'filters_spam_dorks'; + $filters['Dorkslayers']['name'] = 'Dorkslayers Lists'; + $filters['Dorkslayers']['link'] = 'http://www.dorkslayers.com'; + $filters['Dorkslayers']['dns'] = 'orbs.dorkslayers.com'; + $filters['Dorkslayers']['comment'] = +'FREE - Dorkslayers appears to include only really bad open relays outside +the US to avoid being sued. Interestingly enough, their website recommends +you NOT use their service.'; + + $filters['ORBL']['prefname'] = 'filters_spam_orbl'; + $filters['ORBL']['name'] = 'ORBL Lists'; + $filters['ORBL']['link'] = 'http://www.orbl.org'; + $filters['ORBL']['dns'] = 'or.orbl.org'; + $filters['ORBL']['comment'] = +'FREE - ORBL is another ORBS spinoff formed after ORBS shut down. May be +SLOOOOOOW!'; + + $filters['ORBZ-UK']['prefname'] = 'filters_spam_orbzuk'; + $filters['ORBZ-UK']['name'] = 'ORBZ-UK Lists'; + $filters['ORBZ-UK']['link'] = 'http://orbz.gst-group.co.uk'; + $filters['ORBZ-UK']['dns'] = 'orbz.gst-group.co.uk'; + $filters['ORBZ-UK']['comment'] = +'FREE - orbz.gst-group.co.uk lists not only open relays, but also mailservers +that refuse or bounce email addressed to postmaster@.'; + + foreach ($filters as $Key => $Value) { + $filters[$Key]['enabled'] = getPref($data_dir, $username, + $filters[$Key]['prefname']); + } + + return $filters; + } + + function remove_filter ($id) { + global $data_dir, $username; + + while ($nextFilter = getPref($data_dir, $username, 'filter' . + ($id + 1))) { + setPref($data_dir, $username, 'filter' . $id, $nextFilter); + $id ++; + } + + removePref($data_dir, $username, 'filter' . $id); + } + + function filter_swap($id1, $id2) { + global $data_dir, $username; + + $FirstFilter = getPref($data_dir, $username, 'filter' . $id1); + $SecondFilter = getPref($data_dir, $username, 'filter' . $id2); + + if ($FirstFilter && $SecondFilter) { + setPref($data_dir, $username, 'filter' . $id2, $FirstFilter); + setPref($data_dir, $username, 'filter' . $id1, $SecondFilter); + } + } +?> diff --git a/plugins/filters/options.php b/plugins/filters/options.php new file mode 100644 index 00000000..b53ef1a1 --- /dev/null +++ b/plugins/filters/options.php @@ -0,0 +1,349 @@ + + * Tyler Akins + * Brent Bice + * (c) 2000 (GNU GPL - see ../../COPYING) + * + * This plugin filters your inbox into different folders based upon given + * criteria. It is most useful for people who are subscibed to mailing lists + * to help organize their messages. The argument stands that filtering is + * not the place of the client, which is why this has been made a plugin for + * SquirrelMail. You may be better off using products such as Sieve or + * Procmail to do your filtering so it happens even when SquirrelMail isn't + * running. + * + * If you need help with this, or see improvements that can be made, please + * email me directly at the address above. I definately welcome suggestions + * and comments. This plugin, as is the case with all SquirrelMail plugins, + * is not directly supported by the developers. Please come to me off the + * mailing list if you have trouble with it. + * + * Also view plugins/README.plugins for more information. + * + */ + chdir (".."); + require_once('../src/validate.php'); + require_once ("../functions/page_header.php"); + require_once ("../functions/imap.php"); + require_once ("../src/load_prefs.php"); + + global $AllowSpamFilters; + + displayPageHeader($color, "None"); + + if (isset($filter_submit)) { + if (!isset($theid)) $theid = 0; + $filter_what = ereg_replace(",", " ", $filter_what); + $filter_what = str_replace("\\\\", "\\", $filter_what); + $filter_what = str_replace("\\\"", "\"", $filter_what); + $filter_what = str_replace("\"", """, $filter_what); + + setPref($data_dir, $username, "filter".$theid, $filter_where.",".$filter_what.",".$filter_folder); + $filters[$theid]["where"] = $filter_where; + $filters[$theid]["what"] = $filter_what; + $filters[$theid]["folder"] = $filter_folder; + } elseif (isset($spam_submit) && $AllowSpamFilters) { + $spam_filters = load_spam_filters(); + setPref($data_dir, $username, 'filters_spam_folder', $filters_spam_folder_set); + setPref($data_dir, $username, 'filters_spam_scan', $filters_spam_scan_set); + foreach ($spam_filters as $Key => $Value) + { + $input = $spam_filters[$Key]['prefname'] . '_set'; + setPref($data_dir, $username, $spam_filters[$Key]['prefname'], + $$input); + } + } elseif (isset($action) && $action == "delete") { + remove_filter($theid); + } elseif (isset($action) && $action == "move_up") { + filter_swap($theid, $theid - 1); + } elseif (isset($action) && $action == "move_down") { + filter_swap($theid, $theid + 1); + } + + if ($AllowSpamFilters) { + $filters_spam_folder = getPref($data_dir, $username, 'filters_spam_folder'); + $filters_spam_scan = getPref($data_dir, $username, 'filters_spam_scan'); + } + $filters = load_filters(); + + ?> +
+
+
- Message Filtering
+
+
[New] - [Done]

+ + + + +
+[Edit] + +[Delete] + +[Down 0) echo ' | '; +} +if ($i > 0) { +?>Up] +- If contains then move to +
+ + + +
 
+ + + + + +
Spam Filtering
+ +

[Edit]
+ Spam is sent to not set yet]'; + } + ?>
Spam scan is limited to

+ + + $Value) + { + echo '\n"; + } + + ?> +
'; + + if ($spam_filters[$Key]['enabled']) + { + echo 'ON'; + } + else + { + echo 'OFF'; + } + + echo ' - '; + + if ($spam_filters[$Key]['link']) + { + echo ''; + } + + echo $spam_filters[$Key]['name']; + if ($spam_filters[$Key]['link']) + { + echo ''; + } + echo "
+ +
+
+
+ + + + + + + + + + + + +
+   + + +
+ Contains: + + "> +
+ Move to: + + + +
+ + > +
+
+
+
+ + + + + + + + + + + + + + $Value) + { + echo "\n"; + echo '\n"; + } + ?> + +
Move spam to: +
Moving spam directly to the trash may not be a good idea at first, + since messages from friends and mailing lists might accidentally be marked as spam. + Whatever folder you set this to, make sure that it gets cleaned out periodically, + so that you don't have an excessively large mailbox hanging around. +
What to Scan: +
The more messages you scan, the longer it takes. I would suggest + that you scan only new messages. If you make a change to your filters, I + would set it to scan all messages, then go view my INBOX, then come back and + set it to scan only new messages. That way, your new spam filters will be + applied and you'll scan even the spam you read with the new filters.
$Key - '; + if ($spam_filters[$Key]['link']) + { + echo ''; + } + echo $spam_filters[$Key]['name']; + if ($spam_filters[$Key]['link']) + { + echo ''; + } + echo '
'; + echo $spam_filters[$Key]['comment']; + echo "
+
+
+ diff --git a/plugins/filters/setup.php b/plugins/filters/setup.php new file mode 100644 index 00000000..152afe5b --- /dev/null +++ b/plugins/filters/setup.php @@ -0,0 +1,85 @@ + + * Tyler Akins + * Brent Bice + * (c) 2000 (GNU GPL - see ../../COPYING) + * + * This plugin filters your inbox into different folders based upon given + * criteria. It is most useful for people who are subscibed to mailing lists + * to help organize their messages. The argument stands that filtering is + * not the place of the client, which is why this has been made a plugin for + * SquirrelMail. You may be better off using products such as Sieve or + * Procmail to do your filtering so it happens even when SquirrelMail isn't + * running. + * + * If you need help with this, or see improvements that can be made, please + * email me directly at the address above. I definately welcome suggestions + * and comments. This plugin, as is the case with all SquirrelMail plugins, + * is not directly supported by the developers. Please come to me off the + * mailing list if you have trouble with it. + * + * Also view plugins/README.plugins for more information. + * + */ + + // Set this to true if you have problems -- check the README file + // Note: This doesn't work all of the time (No idea why) + // Seems to be related to UW + global $UseSeparateImapConnection; + $UseSeparateImapConnection = false; + + // Set this to false if you do not want the user to be able to enable + // spam filters + global $AllowSpamFilters; + $AllowSpamFilters = true; + + // Set this to a string containing something unique to the line in the + // header you want me to find IPs to scan the databases with. For example, + // All the email coming IN from the internet to my site has a line in + // the header that looks like (all on one line): + // Received: [from usw-sf-list1.sourceforge.net (usw-sf-fw2.sourceforge.net + // [216.136.171.252]) by firewall.persistence.com (SYSADMIN-antispam + // 0.2) with + // Since this line indicates the FIRST hop the email takes into my network, + // I set my SpamFilters_YourHop to 'by firewall.persistence.com' but any + // case-sensitive string will do. You can set it to something found on + // every line in the header (like ' ') if you want to scan all IPs in + // the header (lots of false alarms here tho). + + global $SpamFilters_YourHop; + $SpamFilters_YourHop = 'by firewall.persistence.com'; + + // A cache of IPs we've already checked or are known bad boys or good boys + // ie. $SpamFilters_DNScache["210.54.220.18"] = true; + // would tell filters to not even bother doing the DNS queries for that + // IP and any email coming from it are SPAM - false would mean that any + // email coming from it would NOT be SPAM + global $SpamFilters_DNScache; + + require_once ("../plugins/filters/filters.php"); + + function squirrelmail_plugin_init_filters() { + global $squirrelmail_plugin_hooks; + global $mailbox, $imap_stream, $imapConnection; + + $squirrelmail_plugin_hooks["left_main_before"]["filters"] = "start_filters"; + if ($mailbox == "INBOX") + $squirrelmail_plugin_hooks["right_main_after_header"]["filters"] = "start_filters"; + $squirrelmail_plugin_hooks["options_register"]["filters"] = "squirrelmail_plugin_register"; + } + + function squirrelmail_plugin_register() { + global $optionpages; + + $optionpages[] = array( + 'name' => 'Message Filters', + 'url' => '../plugins/filters/options.php', + 'desc' => 'Filtering enables messages with different criteria to + be automatically filtered into different folders for + easier organization.', + 'js' => false + ); + } +?> diff --git a/plugins/filters/sqimap_read_data.php b/plugins/filters/sqimap_read_data.php new file mode 100644 index 00000000..840a4bf0 --- /dev/null +++ b/plugins/filters/sqimap_read_data.php @@ -0,0 +1,85 @@ + /****************************************************************************** + ** Reads the output from the IMAP stream. If handle_errors is set to true, + ** this will also handle all errors that are received. If it is not set, + ** the errors will be sent back through $response and $message + ******************************************************************************/ + function sqimap_read_data ($imap_stream, $pre, $handle_errors, &$response, &$message) { + global $color, $squirrelmail_language, $imap_general_debug; + + $data = array(); + $size = 0; + + do { + $read = fgets($imap_stream, 9096); + if (ereg("^$pre (OK|BAD|NO)(.*)$", $read, $regs)) { + break; // found end of reply + } + + // Continue if needed for this single line + while (strpos($read, "\n") === false) { + $read .= fgets($imap_stream, 9096); + } + + $data[] = $read; + + if (ereg("^\\* [0-9]+ FETCH.*\\{([0-9]+)\\}", $read, $regs)) { + $size = $regs[1]; + if ($imap_general_debug) { + echo "Size is $size
\n"; + } + + $total_size = 0; + do { + $read = fgets($imap_stream, 9096); + if ($imap_general_debug) { + echo "$read
\n"; + flush(); + } + $data[] = $read; + $total_size += strlen($read); + } while ($total_size < $size); + + $size = 0; + } + // For debugging purposes + if ($imap_general_debug) { + echo "$read
\n"; + flush(); + } + } while (true); + + $response = $regs[1]; + $message = trim($regs[2]); + + if ($imap_general_debug) echo '--
'; + + if ($handle_errors == false) + return $data; + + if ($response == 'NO') { + // ignore this error from m$ exchange, it is not fatal (aka bug) + if (strstr($message, 'command resulted in') === false) { + set_up_language($squirrelmail_language); + echo "
\n"; + echo _("ERROR : Could not complete request."); + echo "
\n"; + echo _("Reason Given: "); + echo $message . "

\n"; + exit; + } + } else if ($response == 'BAD') { + set_up_language($squirrelmail_language); + echo "
\n"; + echo _("ERROR : Bad or malformed request."); + echo "
\n"; + echo _("Server responded: "); + echo $message . "

\n"; + exit; + } + + return $data; + } + + + + diff --git a/plugins/squirrelspell/INSTALL b/plugins/squirrelspell/INSTALL new file mode 100644 index 00000000..01c2c384 --- /dev/null +++ b/plugins/squirrelspell/INSTALL @@ -0,0 +1,19 @@ +SquirrelSpell-v0.3.1 +--------------------- + +Untar SquirrelSpell into your squirrelmail/plugins directory. Move +sqspell_config.dist to sqspell_config.php if this is a fresh install. If +upgrading, just untar over your old installation. + +Modify the sqspell_config.php file making sure you have ispell or aspell +available on your system and located in PHP's path. The squirrelspell +doesn't check for that and if it is not available, you're just going to +get a "No errors found" message every time. :) Quite pleasing, but not +very useful. + +Read files in "doc" directory -- they explain some features. + +Enable the plugin either by hand or by running the configure script from +your squirrelmail install directory. + +Enjoy and report bugs. ;) diff --git a/plugins/squirrelspell/doc/CRYPTO b/plugins/squirrelspell/doc/CRYPTO new file mode 100644 index 00000000..1ae82ed4 --- /dev/null +++ b/plugins/squirrelspell/doc/CRYPTO @@ -0,0 +1,30 @@ +CRYPTOGRAPHY SUPPORT IN SQUIRRELSPELL +-------------------------------------- + +Starting with version v0.3 SquirrelSpell is capable of working with encrypted +user dictionaries. However, this option is only available when PHP +is compiled with support for MCRYPT. This is relatively easy -- to enable +MCRYPT support, follow instructions at: + +http://www.php.net/manual/en/ref.mcrypt.php + +NOTE: You will need libmcrypt version 2.4.x or above for SquirrelSpell +to work. + +HOW IT'S DONE +-------------- +SquirrelSpell encrypts the dictionary with the user's mailbox password, +thus making the encryption/decryption process transparent to the user. +The algorythm used for encryption is Blowfish, but you may manually override +it in the code if you so wish. + +The only shortcoming this approach has -- when mailbox password is changed, +SquirrelSpell asks the user to enter the old password in order to re-encrypt +the file with the new key. If the user doesn't remember the password, then +the file is lost, unless you want to brute-force it open. + +The encryption is off by default and users are warned about remembering +their passwords before they enable encryption of their personal dictionary. + +I haven't tested the overhead. If anyone has any benchmarks -- you are +welcome to share them. diff --git a/plugins/squirrelspell/doc/ChangeLog b/plugins/squirrelspell/doc/ChangeLog new file mode 100644 index 00000000..040ebc93 --- /dev/null +++ b/plugins/squirrelspell/doc/ChangeLog @@ -0,0 +1,72 @@ +SQUIRRELSPELL + +v0.3.5 +------- +- Making it work with 1.1.1 broke it under 1.0.6. Decided not to support + developmental versions after this release. + +v0.3.4 +------- +- Changes to unbreak it in 1.1.1. :) + +v0.3.3 +------- +- Apparently, magic quotes wasn't a bug, but something introduced in 1.0.6, + so I took out all magic-quotes escaping routines, since it's done + automatically now by validate.php. + +v0.3.2 +------- +- Rolled back changes in v0.3.1 +- Workaround for an odd bug with PHP's magic_quotes_gpc +- Changed trim to chop so the newline-trimming function doesn't trim + leading spaces. +- Changed SOUP_NAZI to only deny Opera-4 versions +- Moved SQSPELL_VERSION to sqspell_functions.php for easier + upgrades. + +v0.3.1 +------- +Changes to make it work with 1.0.5. + +v0.3 +----- +Added vlink and alink settings, plus fixed some colors. + +v0.3b +------ +- Major code re-organization. +- Moved modules into separate directory. +- Moved most JavaScript out of the main code into separate .js files +- Created generic GUI-wrappers for most interface screens. +- Added support for multiple international dictionaries. +- Added MCRYPT support for encrypting the user dictionaries. +- No longer checks lines starting with ">" (reply). +- No longer checks anything past the "--" on a single line (signature). +- SquirrelSpell options are now on the main OPTIONS page, not on the + personal options page. + +v0.2.1 +------ +Added a SoupNazi function. :)) Checks for bad browsers which are known not to +work with SquirrelSpell due to their odd JavaScript. + +v0.2pl1 +------- +Fixed the Magic Quotes problems. + +v0.2 +----- +Added user dictionaries. + +v0.1.1 +------- +Added support for aspell + +v0.1pl1 +-------- +Fixed Magic Quotes errors. + +version v0.1 +------------- +Initial release. diff --git a/plugins/squirrelspell/doc/PRIVACY b/plugins/squirrelspell/doc/PRIVACY new file mode 100644 index 00000000..a88e1929 --- /dev/null +++ b/plugins/squirrelspell/doc/PRIVACY @@ -0,0 +1,14 @@ +PRIVACY CONCERNS WHEN USING SQUIRRELSPELL: +------------------------------------------- + +Beginning with version v0.2 SquirrelSpell saves personal dictionary on the +server. This has a potential of a serious privacy issue, therefore you +should configure your system to disallow web access to the directory where +your user dictionaries are stored. By default they are stored in your +$data_dir which you provided in your Squirrelmail config. This is the best +option, but you should read the SquirrelMail FAQ's and Readme's on how to +secure that directory. + +Also, see the CRYPTO file for instructions on how to enable encryption +of user dictionaries. This is done in order to further enhance the +privacy of your users. diff --git a/plugins/squirrelspell/doc/README b/plugins/squirrelspell/doc/README new file mode 100644 index 00000000..297331e5 --- /dev/null +++ b/plugins/squirrelspell/doc/README @@ -0,0 +1,52 @@ +SquirrelSpell +-------------- + +SquirrelSpell is a JavaScript-powered spellchecker written to work with +SquirrelMail versions 0.5 and higher. + +LICENSE: +--------- +This is free software released under GNU GPL license and comes with no +warranty of any kind. You may modify, borrow, or redistribute code as long +as it doesn't violate the GNU GPL license. You can read more about this +license at http://www.gnu.org/ + +FEATURES: +---------- +SquirrelSpell works with UN*X's ISPELL or ASPELL libraries and +SquirrelMail version 0.5 and higher. No PHP recompilation required, +unless you wish to enable MCRYPT support. + +* SpellChecker: +ISPELL or ASPELL. It all depends on them. Read configuration parameters in +sqspell_config.php. Starting with version v0.3 supports multiple international +dictionaries. + +* User Dictionary: +SquirrelSpell adds words to the user dictionary. You may edit your +dictionary under options->personal options->Edit my dictionary. + +* Encryption: +Starting with version v0.3 SquirrelSpell is capable of working with +encrypted user dictionaries. See doc/CRYPTO for information on how to +enable this feature. + +* i18n and l10n: +SquirrelSpell supports any international dictionaries provided by ispell +or aspell. However, since there isn't a translation interface available +for SquirrelMail plugins, all messages produced by SquirrelSpell will be +in English. + +AUTHOR: +-------- +Konstantin Riabitsev, http://www.mricon.com/ + +SUPPORT: +--------- +Send suppot questions and bug reports to the plugins mailing list: +squirrelmail-plugins@lists.sourceforge.net. When reporting a bug +don't forget to mention your browser version, SquirrelMail and +SquirrelSpell versions, as well as any other useful info. + +ENJOY. :) +--------- diff --git a/plugins/squirrelspell/doc/UPGRADING b/plugins/squirrelspell/doc/UPGRADING new file mode 100644 index 00000000..1537b676 --- /dev/null +++ b/plugins/squirrelspell/doc/UPGRADING @@ -0,0 +1,15 @@ +From version v0.2 to version v0.3 +---------------------------------- + +The user dictionaries will be converted to v0.3 format. Once they are +converted, you can't downgrade back to v0.2. If this scares you, backup all +*.words files in your $data_dir somewhere safe. + +Files are renamed around. config.php is now sqspell_config.php. + +When you are setting up SQSPELL_DEFAULT_APP in the sqspell_config, keep in +mind that this has to reflect whichever dictionary you used in version 0.2. +Say, if you used "ispell -d german", you will need to specify German as +your SQSPELL_DEFAULT_APP so user dictionaries can be upgraded successfully. +Otherwise wrong words will end up in a wrong dictionary. + diff --git a/plugins/squirrelspell/doc/index.php b/plugins/squirrelspell/doc/index.php new file mode 100644 index 00000000..9b392653 --- /dev/null +++ b/plugins/squirrelspell/doc/index.php @@ -0,0 +1,3 @@ + diff --git a/plugins/squirrelspell/index.php b/plugins/squirrelspell/index.php new file mode 100644 index 00000000..9b392653 --- /dev/null +++ b/plugins/squirrelspell/index.php @@ -0,0 +1,3 @@ + diff --git a/plugins/squirrelspell/js/WHATISTHIS b/plugins/squirrelspell/js/WHATISTHIS new file mode 100644 index 00000000..b26031d1 --- /dev/null +++ b/plugins/squirrelspell/js/WHATISTHIS @@ -0,0 +1,3 @@ +squirrelspell/js + +These are javascript files used by SquirrelSpell. diff --git a/plugins/squirrelspell/js/check_me.js b/plugins/squirrelspell/js/check_me.js new file mode 100644 index 00000000..852ca0e4 --- /dev/null +++ b/plugins/squirrelspell/js/check_me.js @@ -0,0 +1,221 @@ +/** + CHECK_ME.JS + ------------ + This JavaScript app is the driving power of the SquirrelSpell's + main spellchecker window. Hope you have as much pain figuring + it out as it took to write. ;)) + **/ + +var CurrentError=0; +var CurrentLocation=0; + +var CurrentLine; +var CurrentSymbol; +var ChangesMade=false; + +function populateSqspellForm(){ + // this function loads error data into the form. + CurrentWord=Word=misses[CurrentError]; + WordLocations = locations[CurrentError].split(", "); + CurrentLoc = WordLocations[CurrentLocation]; + if(CurrentLocation==WordLocations.length-1) { + CurrentLocation=0; + } else { + CurrentLocation++; + } + + tmp = CurrentLoc.split(":"); + CurrentLine=parseInt(tmp[0]); + CurrentSymbol=parseInt(tmp[1]); + document.forms[0].sqspell_error.value=Word; + LineValue=sqspell_lines[CurrentLine]; + StartWith=0; + NewLineValue=""; + if (CurrentSymbol > 40){ + StartWith=CurrentSymbol-40; + NewLineValue = "..."; + } + EndWith=LineValue.length; + EndLine=""; + if (EndWith > CurrentSymbol + 40){ + EndWith=CurrentSymbol+40; + EndLine="..."; + } + NewLineValue+=LineValue.substring(StartWith, CurrentSymbol) + "*" + Word + "*" + LineValue.substring(CurrentSymbol + Word.length, EndWith) + EndLine; + document.forms[0].sqspell_line_area.value=NewLineValue; + + if (suggestions[CurrentError]){ + WordSuggestions = suggestions[CurrentError].split(", "); + for (i=0; i= 0){ + allLoc = locations[i].split(", "); + for (j=0; j lSymbol){ + tmp[1] = tmp[1] + difference; + allLoc[j] = tmp.join(":"); + } + } + } + locations[i] = allLoc.join(", "); + } + } +} + +function sqspellCommitChanges(){ + // Write the changes back into the compose form + if (navigator.appName.indexOf("Microsoft")==0){ + // MSIE doesn't have array.shift() + newSubject = sqspell_lines[0]; + newBody = ""; + for (i=1; i diff --git a/plugins/squirrelspell/js/init.js b/plugins/squirrelspell/js/init.js new file mode 100644 index 00000000..ca2a368f --- /dev/null +++ b/plugins/squirrelspell/js/init.js @@ -0,0 +1,13 @@ +/** + INIT.JS + ------- + Grabs the text from the SquirrelMail field and submits it to + the squirrelspell. + **/ +function sqspell_init(flag){ + // flag tells the function whether to automatically submit the form, or + // wait for user input. True submits the form, while False doesn't. + textToSpell = opener.document.forms[0].subject.value + "\n" + opener.document.forms[0].body.value; + document.forms[0].sqspell_text.value = textToSpell; + if (flag) document.forms[0].submit(); +} diff --git a/plugins/squirrelspell/modules/WHATISTHIS b/plugins/squirrelspell/modules/WHATISTHIS new file mode 100644 index 00000000..e764b117 --- /dev/null +++ b/plugins/squirrelspell/modules/WHATISTHIS @@ -0,0 +1,3 @@ +squirrelspell/modules + +This is where the loadable modules for SquirrelSpell are. diff --git a/plugins/squirrelspell/modules/check_me.mod.php b/plugins/squirrelspell/modules/check_me.mod.php new file mode 100644 index 00000000..0a650944 --- /dev/null +++ b/plugins/squirrelspell/modules/check_me.mod.php @@ -0,0 +1,250 @@ +" (reply's) + // 2) So we can stop processing when we get to "--" on a single line, + // which means that the signature is starting + // 3) So we can add an extra space at the beginning of each line. This way + // ispell/aspell don't treat these as command characters. + $sqspell_raw_lines = explode("\n", $sqspell_text); + for ($i=0; $i + + + SquirrelSpell Results + + + + ', $color[4], $color[8], $color[7], $color[7], $color[7]); + ?> + + + + +
Found errors

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Line with an error:
+ +
+ Error: + + + + Suggestions: + + +
+ Change to: + + + + Occurs times: + + +

+ + + + + + + + +
+ Change + + Change All + + Ignore + + Ignore All + + Add to Dic +
+

+ + +
+
+
+ + +
"; + sqspell_makeWindow(null, "No errors found", null, $msg); + } +?> diff --git a/plugins/squirrelspell/modules/crypto.mod.php b/plugins/squirrelspell/modules/crypto.mod.php new file mode 100644 index 00000000..dce29801 --- /dev/null +++ b/plugins/squirrelspell/modules/crypto.mod.php @@ -0,0 +1,36 @@ +Your personal dictionary has been encrypted and is now stored in an encrypted format.

"; + break; + + case "decrypt": + // Decrypt the file and save plain text. + $words=sqspell_getWords(); + // flip the flag. + $SQSPELL_CRYPTO=false; + sqspell_writeWords($words); + $msg="

Your personal dictionary has been decrypted and is now stored as clear text.

"; + break; + + case "": + // Wait, this shouldn't happen! :) + $msg = "

No action requested.

"; + break; +} + sqspell_makePage("Personal Dictionary Crypto Settings", null, $msg); +?> diff --git a/plugins/squirrelspell/modules/crypto_badkey.mod.php b/plugins/squirrelspell/modules/crypto_badkey.mod.php new file mode 100644 index 00000000..2fd94091 --- /dev/null +++ b/plugins/squirrelspell/modules/crypto_badkey.mod.php @@ -0,0 +1,54 @@ +Your personal dictionary was erased.

"; + sqspell_makePage("Dictionary Erased", null, $msg); + } else { + $msg = "

Your personal dictionary was erased. Please close this window and + click \"Check Spelling\" button again to start your spellcheck over.

+

+ +

"; + sqspell_makeWindow(null, "Dictionary Erased", null, $msg); + } + exit; + } + + if ($old_key){ + // User provided another key to try and decrypt the dictionary. + // call sqspell_getWords. If this key fails, the function will + // handle it. + $words=sqspell_getWords(); + // It worked! Pinky, you're a genius! + // Write it back this time encrypted with a new key. + sqspell_writeWords($words); + // See where we are and call a necessary GUI-wrapper. + if (strstr($SCRIPT_NAME, "sqspell_options")){ + $msg="

Your personal dictionary was re-encrypted successfully. Now + return to the "SpellChecker options" menu and make your selection + again.

"; + sqspell_makePage("Successful Re-encryption", null, $msg); + } else { + $msg = "

Your personal dictionary was re-encrypted successfully. Please + close this window and click \"Check Spelling\" button again to start your + spellcheck over.

+

"; + sqspell_makeWindow(null, "Dictionary re-encrypted", null, $msg); + } + exit; + } +?> diff --git a/plugins/squirrelspell/modules/edit_dic.mod.php b/plugins/squirrelspell/modules/edit_dic.mod.php new file mode 100644 index 00000000..2bb16ff6 --- /dev/null +++ b/plugins/squirrelspell/modules/edit_dic.mod.php @@ -0,0 +1,57 @@ +No words in your personal dictionary.

"); + } else { + // We're loaded with booty. + $pre_msg = "

Please check any words you wish to delete from your dictionary.

\n"; + $pre_msg .= "\n"; + $langs=sqspell_getSettings($words); + for ($i=0; $i + + \n"; + } + } + // Check if all dictionaries were empty. + if (!$msg) + $msg = "

No words in your dictionary.

"; + else $msg .= "
$langs[$i] dictionary
+
+ + + + + + +
\n"; + $words_ary=explode("\n", $lang_words); + array_pop($words_ary); + array_shift($words_ary); + // Do some fancy stuff to separate the words into three columns. + for ($j=0; $j\n"; + $msg .= " $words_ary[$j]
"; + } + $msg .= "
+
+ +

+
"; + sqspell_makePage("Edit your Personal Dictionary", null, $msg); + } +?> diff --git a/plugins/squirrelspell/modules/enc_setup.mod.php b/plugins/squirrelspell/modules/enc_setup.mod.php new file mode 100644 index 00000000..b70050a3 --- /dev/null +++ b/plugins/squirrelspell/modules/enc_setup.mod.php @@ -0,0 +1,53 @@ +Your personal dictionary is currently encrypted. This + helps protect your privacy in case the web-mail system gets compromized and your + personal dictionary ends up stolen. It is currently encrypted with the password + you use to access your mailbox, making it hard for anyone to see what is stored + in your personal dictionary.

+

ATTENTION: If you forget your password, your personal dictionary + will become unaccessible, since it can no longer be decrypted. + If you change your mailbox password, SquirrelSpell will recognize it and prompt you for + your old password in order to re-encrypt the dictionary with a new key.

+
+ +

Please decrypt my personal + dictionary and store it in a clear-text format.

+

+
+ "; +} else { + // current format is clear text. + $msg = "

Your personal dictionary is currently not encrypted. + You may wish to encrypt your personal dictionary to protect your privacy in case + the webmail system gets compromized and your personal dictionary file gets stolen. + When encrypted, the file's contents look garbled and are hard to decrypt without + knowing the correct key (which is your mailbox password).

+ ATTENTION: If you decide to encrypt your personal dictionary, + you must remember that it gets "hashed" with your mailbox password. If + you forget your mailbox password and the administrator changes it to a new value, + your personal dictionary will become useless and will have to be created anew. + However, if you or your system administrator change your mailbox password but you + still have the old password at hand, you will be able to enter the old key to + re-encrypt the dictionary with the new value.

+
+ +

Please encrypt my personal + dictionary and store it in an encrypted format.

+

+
+ "; +} + sqspell_makePage("Personal Dictionary Crypto Settings", "crypto_settings.js", $msg); +?> diff --git a/plugins/squirrelspell/modules/forget_me.mod.php b/plugins/squirrelspell/modules/forget_me.mod.php new file mode 100644 index 00000000..73444a0b --- /dev/null +++ b/plugins/squirrelspell/modules/forget_me.mod.php @@ -0,0 +1,44 @@ +Deleting the following entries from $sqspell_use_app dictionary:

+
    \n"; + for ($i=0; $iNo changes requested.

    "); + } +?> + diff --git a/plugins/squirrelspell/modules/forget_me_not.mod.php b/plugins/squirrelspell/modules/forget_me_not.mod.php new file mode 100644 index 00000000..0770ba92 --- /dev/null +++ b/plugins/squirrelspell/modules/forget_me_not.mod.php @@ -0,0 +1,43 @@ +
    "; + sqspell_makeWindow($onload, "Personal Dictionary Updated", null, $msg); +?> + diff --git a/plugins/squirrelspell/modules/index.php b/plugins/squirrelspell/modules/index.php new file mode 100644 index 00000000..9b392653 --- /dev/null +++ b/plugins/squirrelspell/modules/index.php @@ -0,0 +1,3 @@ + diff --git a/plugins/squirrelspell/modules/init.mod.php b/plugins/squirrelspell/modules/init.mod.php new file mode 100644 index 00000000..ade9c788 --- /dev/null +++ b/plugins/squirrelspell/modules/init.mod.php @@ -0,0 +1,44 @@ + + + +

    "; + if (sizeof($langs)==1){ + // only one dictionary defined by the users. Submit the form + // automatically. + $onload="sqspell_init(true)"; + $msg .= "Please wait, communicating with the server...

    + + "; + } else { + // more than one dictionary. Let the user choose the dictionary first + // then manually submit the form. + $onload="sqspell_init(false)"; + $msg .= "Please choose which dictionary you would like to use to spellcheck this + message:

    +

    + +

    + "; + $langs = sqspell_getSettings(null); + $add = "

    Make this dictionary my default selection: \n"; + $msg .= "

    "; + sqspell_makePage("Add International Dictionaries", null, $msg); +?> diff --git a/plugins/squirrelspell/modules/options_main.mod.php b/plugins/squirrelspell/modules/options_main.mod.php new file mode 100644 index 00000000..9ad26b04 --- /dev/null +++ b/plugins/squirrelspell/modules/options_main.mod.php @@ -0,0 +1,27 @@ +Please choose which options you wish to set up:

    +
      +
    • Edit your personal dictionary
    • + "; + // See if more than one dictionary is defined system-wide. + // If so, let the user choose his preferred ones. + if (sizeof($SQSPELL_APP)>1) + $msg .= "
    • Set up international dictionaries
    • \n"; + // See if MCRYPT is available. + // If so, let the user choose whether s/he wants to encrypt the + // personal dictionary file. + if (function_exists("mcrypt_generic")) + $msg .= "
    • Encrypt or decrypt your personal dictionary
    • \n"; + else $msg .= "
    • Encrypt or decrypt your personal dictionary (not available)
    • \n"; + $msg .= "
    \n"; + sqspell_makePage("SquirrelSpell Options Menu", null, $msg); + +?> diff --git a/plugins/squirrelspell/setup.php b/plugins/squirrelspell/setup.php new file mode 100644 index 00000000..671b63ad --- /dev/null +++ b/plugins/squirrelspell/setup.php @@ -0,0 +1,73 @@ + 'SpellChecker Options', + 'url' => '../plugins/squirrelspell/sqspell_options.php', + 'desc' => 'Here you may set up how your personal dictionary is stored, + edit it, or choose which languages should be available to + you when spell-checking.', + 'js' => true + ); +} + +function squirrelspell_setup() { + /* Gets added to the COMPOSE buttons row. */ + if (soupNazi()) { + return; + } + +?> + + diff --git a/plugins/squirrelspell/sqspell_config.dist b/plugins/squirrelspell/sqspell_config.dist new file mode 100644 index 00000000..e0405b4b --- /dev/null +++ b/plugins/squirrelspell/sqspell_config.dist @@ -0,0 +1,88 @@ + "ispell -a"); + + or + + $SQSPELL_APP = array("English" => "/usr/local/bin/aspell -a"); + + Sometimes you have to specify full path for PHP to find it. + Aspell is a better spell-checker than Ispell, so you're encouraged + to use it. + + If you want to have more than one dictionary available to users, + configure the array to look something like this: + + $SQSPELL_APP = array( + "English" => "aspell -a", + "Russian" => "ispell -d russian -a", + ... + "Swahili" => "ispell -d swahili -a" + ); + + Watch the commas, making sure there isn't one after your last + dictionary declaration. Also, make sure all these dictionaries + are available on your system before you specify them here. + + Whatever your setting is, don't omit the "-a" flag. + + **/ +$SQSPELL_APP = array("English" => "ispell -a"); + +/** + DEFAULT DICTIONARY + ------------------- + Even if you're only running one dictionary, still specify which one + is the default. Watch the case -- it has to be exactly as in array + you declared in $SQSPELL_APP. + **/ +$SQSPELL_APP_DEFAULT="English"; + +/** + USER DICTIONARY: + ----------------- + $SQSPELL_WORDS_FILE is a location and mask of a user dictionary file. + The default setting should be OK for most everyone. Read PRIVACY and + CRYPTO in the "doc" directory. + **/ +$SQSPELL_WORDS_FILE = "$data_dir/$username.words"; + +/** + CASE SENSITIVITY: + ------------------ + Use $SQSPELL_EREG="ereg" for case-sensitive matching of user + dictionary, or $SQSPELL_EREG="eregi" for case-insensitive + matching. It is advised to use case-sensitive matching. + **/ +$SQSPELL_EREG="ereg"; + +/** + SOUP NAZI (AVOIDING BAD BROWSERS) + ------------------------------------- + Since some browsers choke on JavaScript, here is an option to disable the + browsers with known problems. All you do is add some part of an USER_AGENT + string of an offending browser which you want to disable and users will not + know about this plugin. E.g. browsers with "Mozilla/4.61 (Macintosh, I, PPC)" + USER_AGENT string will get weeded out if you provide "Macintosh" in the + config string. + + Mozilla/2 -- You're kidding, right? + Mozilla/3 -- known not to work + Opera -- known not to work + Macintosh -- Netscape 4.x on Macintosh chokes for some reason. + Adding until resolved. + **/ +$SQSPELL_SOUP_NAZI = "Mozilla/3, Mozilla/2, Opera 4, Opera/4, Macintosh"; + +?> diff --git a/plugins/squirrelspell/sqspell_config.php b/plugins/squirrelspell/sqspell_config.php new file mode 100644 index 00000000..e0405b4b --- /dev/null +++ b/plugins/squirrelspell/sqspell_config.php @@ -0,0 +1,88 @@ + "ispell -a"); + + or + + $SQSPELL_APP = array("English" => "/usr/local/bin/aspell -a"); + + Sometimes you have to specify full path for PHP to find it. + Aspell is a better spell-checker than Ispell, so you're encouraged + to use it. + + If you want to have more than one dictionary available to users, + configure the array to look something like this: + + $SQSPELL_APP = array( + "English" => "aspell -a", + "Russian" => "ispell -d russian -a", + ... + "Swahili" => "ispell -d swahili -a" + ); + + Watch the commas, making sure there isn't one after your last + dictionary declaration. Also, make sure all these dictionaries + are available on your system before you specify them here. + + Whatever your setting is, don't omit the "-a" flag. + + **/ +$SQSPELL_APP = array("English" => "ispell -a"); + +/** + DEFAULT DICTIONARY + ------------------- + Even if you're only running one dictionary, still specify which one + is the default. Watch the case -- it has to be exactly as in array + you declared in $SQSPELL_APP. + **/ +$SQSPELL_APP_DEFAULT="English"; + +/** + USER DICTIONARY: + ----------------- + $SQSPELL_WORDS_FILE is a location and mask of a user dictionary file. + The default setting should be OK for most everyone. Read PRIVACY and + CRYPTO in the "doc" directory. + **/ +$SQSPELL_WORDS_FILE = "$data_dir/$username.words"; + +/** + CASE SENSITIVITY: + ------------------ + Use $SQSPELL_EREG="ereg" for case-sensitive matching of user + dictionary, or $SQSPELL_EREG="eregi" for case-insensitive + matching. It is advised to use case-sensitive matching. + **/ +$SQSPELL_EREG="ereg"; + +/** + SOUP NAZI (AVOIDING BAD BROWSERS) + ------------------------------------- + Since some browsers choke on JavaScript, here is an option to disable the + browsers with known problems. All you do is add some part of an USER_AGENT + string of an offending browser which you want to disable and users will not + know about this plugin. E.g. browsers with "Mozilla/4.61 (Macintosh, I, PPC)" + USER_AGENT string will get weeded out if you provide "Macintosh" in the + config string. + + Mozilla/2 -- You're kidding, right? + Mozilla/3 -- known not to work + Opera -- known not to work + Macintosh -- Netscape 4.x on Macintosh chokes for some reason. + Adding until resolved. + **/ +$SQSPELL_SOUP_NAZI = "Mozilla/3, Mozilla/2, Opera 4, Opera/4, Macintosh"; + +?> diff --git a/plugins/squirrelspell/sqspell_functions.php b/plugins/squirrelspell/sqspell_functions.php new file mode 100644 index 00000000..5eaa4615 --- /dev/null +++ b/plugins/squirrelspell/sqspell_functions.php @@ -0,0 +1,311 @@ + +  
    + + + + + + + + + + + + + + + + + +
    + +

    + +

    Back to "SpellChecker Options" page

    + SquirrelSpell +
    + + + + <?php echo $title ?> + + + + + > + + + + + + + + + + + + + + + + +
    + +

    + +

    + SquirrelSpell +
    + + + 1){ + // OK, so there are more than one dictionary option. + // Now load the user prefs. + if(!$words) $words=sqspell_getWords(); + if ($words){ + // find which dictionaries user wants to use + preg_match("/# LANG: (.*)/i", $words, $matches); + $langs=explode(", ", $matches[1]); + } else { + // User doesn't have a personal dictionary. Set him up with + // a default setting. + $langs[0]=$SQSPELL_APP_DEFAULT; + } + } else { + // There is only one dictionary defined system-wide. + $langs[0]=$SQSPELL_APP_DEFAULT; + } + return $langs; +} + +function sqspell_getLang($words, $lang){ + // + // Returns words of a specific user dictionary. + // + $start=strpos($words, "# $lang\n"); + if (!$start) return ""; + $end=strpos($words, "#", $start+1); + $lang_words = substr($words, $start, $end-$start); + return $lang_words; +} + +function sqspell_getWords(){ + // + // This baby operates the user dictionary. If the format is clear-text, + // then it just reads the file and returns it. However, if the file is + // encrypted, then it decrypts it, checks whether the decryption was + // successful, troubleshoots if not, then returns the clear-text dictionary + // to the app. + // + global $SQSPELL_WORDS_FILE, $SQSPELL_CRYPTO; + $words=""; + if (file_exists($SQSPELL_WORDS_FILE)){ + // Gobble it up. + $fp=fopen($SQSPELL_WORDS_FILE, "r"); + $words=fread($fp, filesize($SQSPELL_WORDS_FILE)); + fclose($fp); + } + // Check if this is an encrypted file by looking for + // the string "# SquirrelSpell" in it. + if ($words && !strstr($words, "# SquirrelSpell")){ + // This file is encrypted or mangled. Try to decrypt it. + // If fails, raise hell. + global $key, $onetimepad, $old_key; + if ($old_key) { + // an override in case user is trying to decrypt a dictionary + // with his old password + $clear_key=$old_key; + } else { + // get user's password (the key). + $clear_key = OneTimePadDecrypt($key, $onetimepad); + } + // decrypt + $words=sqspell_crypto("decrypt", $clear_key, $words); + if ($words=="PANIC"){ + // AAAAAAAAAAAH!!!!! OK, ok, breathe! + // Let's hope the decryption failed because the user changed his + // password. Bring up the option to key in the old password + // or wipe the file and start over if everything else fails. + $msg="

    + ATTENTION:
    + SquirrelSpell was unable to decrypt your personal dictionary. This is most likely + due to the fact that you have changed your mailbox password. In order to proceed, + you will have to supply your old password so that SquirrelSpell can decrypt your + personal dictionary. It will be re-encrypted with your new password after this.
    + If you haven't encrypted your dictionary, then it got mangled and is no longer + valid. You will have to delete it and start anew. This is also true if you don't + remember your old password -- without it, the encrypted data is no longer + accessible.

    +
    +
    + +

    Delete my dictionary and start a new one
    + Decrypt my dictionary with my old password:

    +
    +

    + + "; + // See if this happened in the pop-up window or when accessing + // the SpellChecker options page. + global $SCRIPT_NAME; + if (strstr($SCRIPT_NAME, "sqspell_options")) + sqspell_makePage("Error Decrypting Dictionary", "decrypt_error.js", $msg); + else sqspell_makeWindow(null, "Error Decrypting Dictionary", "decrypt_error.js", $msg); + exit; + } else { + // OK! Phew. Set the encryption flag to true so we can later on + // encrypt it again before saving to HDD. + $SQSPELL_CRYPTO=true; + } + } else { + // No encryption is used. Set $SQSPELL_CRYPTO to false, in case we have to + // save the dictionary later. + $SQSPELL_CRYPTO=false; + } + // Check if we need to upgrade the dictionary from version 0.2.x + if (strstr($words, "Dictionary v0.2")) $words=sqspell_upgradeWordsFile($words); + return $words; +} + +function sqspell_writeWords($words){ + // + // Writes user dictionary into the $username.words file, then changes mask + // to 0600. If encryption is needed -- does that, too. + // + global $SQSPELL_WORDS_FILE, $SQSPELL_CRYPTO; + // if $words is empty, create a template entry. + if (!$words) $words=sqspell_makeDummy(); + if ($SQSPELL_CRYPTO){ + // User wants to encrypt the file. So be it. + // get his password to use as a key. + global $key, $onetimepad; + $clear_key=OneTimePadDecrypt($key, $onetimepad); + // Try encrypting it. If fails, scream bloody hell. + $save_words = sqspell_crypto("encrypt", $clear_key, $words); + if ($save_words=="PANIC"){ + // AAAAAAAAH! I'm not handling this yet, since obviously + // the admin of the site forgot to compile the MCRYPT support in. + // I will add a handler for this case later, when I can come up + // with some work-around... Right now, do nothing. Let the Admin's + // head hurt.. ;))) + } + } else { + $save_words = $words; + } + $fp=fopen($SQSPELL_WORDS_FILE, "w"); + fwrite($fp, $save_words); + fclose($fp); + chmod($SQSPELL_WORDS_FILE, 0600); +} + +function sqspell_deleteWords(){ + // + // so I open the door to my enemies, + // and I ask can we wipe the slate clean, + // but they tell me to please go... + // uhm... Well, this just erases the user dictionary file. + // + global $SQSPELL_WORDS_FILE; + if (file_exists($SQSPELL_WORDS_FILE)) unlink($SQSPELL_WORDS_FILE); +} + +function sqspell_makeDummy(){ + // + // Creates an empty user dictionary for the sake of saving prefs or + // whatever. + // + global $SQSPELL_VERSION, $SQSPELL_APP_DEFAULT; + $words="# SquirrelSpell User Dictionary $SQSPELL_VERSION\n# Last Revision: " . date("Y-m-d") . "\n# LANG: $SQSPELL_APP_DEFAULT\n# End\n"; + return $words; +} + +/** + VERSION: + --------- + SquirrelSpell version. Don't modify, since it identifies the format + of the user dictionary files and messing with this can do ugly + stuff. :) + **/ +$SQSPELL_VERSION="v0.3.5"; + + +?> diff --git a/plugins/squirrelspell/sqspell_interface.php b/plugins/squirrelspell/sqspell_interface.php new file mode 100644 index 00000000..fa81e4f6 --- /dev/null +++ b/plugins/squirrelspell/sqspell_interface.php @@ -0,0 +1,36 @@ + diff --git a/plugins/squirrelspell/sqspell_options.php b/plugins/squirrelspell/sqspell_options.php new file mode 100644 index 00000000..86c75cd3 --- /dev/null +++ b/plugins/squirrelspell/sqspell_options.php @@ -0,0 +1,35 @@ + diff --git a/plugins/translate/INSTALL b/plugins/translate/INSTALL new file mode 100644 index 00000000..945acc9a --- /dev/null +++ b/plugins/translate/INSTALL @@ -0,0 +1,16 @@ +Installing Plugins +================== +Simply untar the file in the plugins directory, and make sure it is +in its own directory, and that the name of the directory is the name +of the plugin. Example below uses "plug_demo" as the name of the +plugin: + + $ cd plugins + $ tar -zxvf /usr/archives/plug_demo.tar.gz + +Then go to your config directory and run conf.pl. Choose option +8 and add the plugin. Save and exit, then that should be all +if the plugin was made correctly. :) + + $ cd ../config + $ ./conf.pl diff --git a/plugins/translate/README b/plugins/translate/README new file mode 100644 index 00000000..b81fd1cc --- /dev/null +++ b/plugins/translate/README @@ -0,0 +1,73 @@ +Message Translation -- Version 1.4 + +If you have ever received a mail message from someone who is not in +your country, you probably noticed that they used a different language +than you. If you don't know their language, a translator might help you +out. + + +Features +======== + +* Multiple translation servers +* Uses your language preference for setting up default translation options +* You pick where you see the translation box +* You decide which translation buttons you see + + +Description +=========== + +This plugin lets you select, on a per-user basis, the translator you want +to use. It defaults to None. It has different servers you can use, and +it lists their strengths and limits with each one. Also, there are +multiple servers just in case one changes their interface or goes down. + +Since SquirrelMail is designed to have multiple translations of the text, +this plugin takes your preference and will use it for selecting what to +translate the text into. + + +Future Work +=========== + +* Grab translation directly from server (need to send POST request directly) +* Translate your outgoing message + + +Servers +======= + +Babelfish = babelfish.altavista.com +Go.com = translator.go.com +Dictionary.com = www.dictionary.com/translate +InterTran = tranexp.com +GPLTrans = www.translator.cx + + +Installation +============ + +As with other plugins, just uncompress the archive in the plugins +directory, go back to the main directory, run configure and add the plugin. + +Questions/comments/flames/etc can be sent to the Squirrelmail Plugins list + + +Changes +======= +1.3 -> 1.4 + * Modified to use new option page hook. + Paul Joseph Thompson + +1.2 -> 1.3 + * Stupid bugfix. :-) + +1.1 -> 1.2 + * HTML changed to look better + +1.0 -> 1.1 + * Added more servers + * Added better language handling + * You have to pick a server, but you can choose not to have the box + * Added better support for direction of translation diff --git a/plugins/translate/options.php b/plugins/translate/options.php new file mode 100644 index 00000000..9a702f2b --- /dev/null +++ b/plugins/translate/options.php @@ -0,0 +1,144 @@ +' . $Desc . "\n"; + } + + +?> +
    +
    +
    - Translator
    +
    + +

    Your server options are as follows:

    + +
      + +
    • Babelfish - + 13 language pairs, + maximum of 1000 characters translated, + powered by Systran + [ Babelfish ]
    • + +
    • Go.com - + 10 language pairs, + maximum of 25 kilobytes translated, + powered by Systran + [ Translator.Go.com ]
    • + +
    • Dictionary.com - + 12 language pairs, + no known limits, + powered by Systran + [ Dictionary.com ]
    • + +
    • InterTran - + 767 language pairs, + no known limits, + powered by Translation Experts's InterTran + [ Translation Experts ]
    • + +
    • GPLTrans - + 8 language pairs, + no known limits, + powered by GPLTrans (free, open source) + [ GPLTrans ]
    • + +
    + +

    You also decide if you want the translation box displayed, + and where it will be located.

    + +
    + + + + + + + + +
    Select your translator: +
    When reading:> - Show translation box +
    + > - Translate inside the SquirrelMail frames
    When composing:> - Not yet functional, currently does nothing
    + +
    +
    + diff --git a/plugins/translate/setup.php b/plugins/translate/setup.php new file mode 100644 index 00000000..f33cc197 --- /dev/null +++ b/plugins/translate/setup.php @@ -0,0 +1,416 @@ +Download this as a file
    '); + if (is_int($pos)) { + $new_body = substr($new_body, 0, $pos); + } + + $trans = get_html_translation_table('HTMLENTITIES'); + $trans[' '] = ' '; + $trans = array_flip($trans); + $new_body = strtr($new_body, $trans); + + $new_body = urldecode($new_body); + $new_body = strip_tags($new_body); + + /* I really don't like this next part ... */ + $new_body = str_replace('"', "''", $new_body); + $new_body = strtr($new_body, "\n", ' '); + + $function = 'translate_form_' . $translate_server; + $function($new_body); +} + +function translate_table_end() { + ?> + + + + + + + 'Translation Options', + 'url' => '../plugins/translate/options.php', + 'desc' => 'Which translator should be used when you get messages in a different language?', + 'js' => false + ); +} + +function translate_sav() { + global $username,$data_dir; + global $submit_translate, $translate_translate_server; + global $translate_translate_location; + global $translate_translate_show_read; + global $translate_translate_show_send; + global $translate_translate_same_window; + + if ($submit_translate) { + if (isset($translate_translate_server)) { + setPref($data_dir, $username, 'translate_server', $translate_translate_server); + } else { + setPref($data_dir, $username, 'translate_server', 'babelfish'); + } + + if (isset($translate_translate_location)) { + setPref($data_dir, $username, 'translate_location', $translate_translate_location); + } else { + setPref($data_dir, $username, 'translate_location', 'center'); + } + + if (isset($translate_translate_show_read)) { + setPref($data_dir, $username, 'translate_show_read', '1'); + } else { + setPref($data_dir, $username, 'translate_show_read', ''); + } + + if (isset($translate_translate_show_send)) { + setPref($data_dir, $username, 'translate_show_send', '1'); + } else { + setPref($data_dir, $username, 'translate_show_send', ''); + } + + if (isset($translate_translate_same_window)) { + setPref($data_dir, $username, 'translate_same_window', '1'); + } else { + setPref($data_dir, $username, 'translate_same_window', ''); + } + + echo '
    Translation options saved.
    '; + } +} + + +function translate_pref() { + global $username, $data_dir; + global $translate_server, $translate_location; + global $translate_show_send, $translate_show_read; + global $translate_same_window; + + $translate_server = getPref($data_dir, $username, 'translate_server'); + if ($translate_server == '') { + $translate_server = 'babelfish'; + } + + $translate_location = getPref($data_dir, $username, 'translate_location'); + if ($translate_location == '') { + $translate_location = 'center'; + } + + $translate_show_send = getPref($data_dir, $username, 'translate_show_send'); + $translate_show_read = getPref($data_dir, $username, 'translate_show_read'); + $translate_same_window = getPref($data_dir, $username, 'translate_same_window'); +} + + +/** + * This function could be sped up. + * It basically negates the process if a ! is found in the beginning and + * matches a * at the end with 0 or more characters. + */ +function translate_does_it_match_language($test) { + global $squirrelmail_language; + $true = 1; + $false = 0; + $index = 0; + $smindex = 0; + + if (! $test || ! $squirrelmail_language) { + return $false; + } + + if ($test[$index] == '!') { + $index ++; + $true = 0; + $false = 1; + } + + if (($index == 0) && ($test == $squirrelmail_language)) { + return $true; + } + + while ($test[$index]) { + if ($test[$index] == '*') { + return $true; + } + if ($test[$index] != $squirrelmail_language[$smindex]) { + return $false; + } + $index ++; + $smindex ++; + } + + return $false; +} + + +function translate_lang_opt($from, $to, $value, $text) { + global $translate_dir; + + echo ' \n"; +} + + +function translate_new_form($action) { + global $translate_dir, $translate_new_window, $translate_location; + global $color, $translate_same_window; + + echo '
    \n"; + + ?>> + + +
    + + + - +
    + + + + + + Babelfish: + + + + + Go.com: + + + + + to + InterTran: + + + GPLTrans: + + + + Dictionary.com: + diff --git a/src/options.php b/src/options.php index 01692c2d..1c306714 100644 --- a/src/options.php +++ b/src/options.php @@ -1,248 +1,426 @@
    +
    - -
    +
    +
    '._("Successfully saved personal information!").'
    '; - } else if (isset($submit_display)) { - // Do checking to make sure $chosentheme is in the array - $in_ary = false; - for ($i=0; $i < count($theme); $i++) - { - if ($theme[$i]['PATH'] == $chosentheme) - { - $in_ary = true; - break; - } - } - if (! $in_ary) - $chosentheme = ''; - - # Save display preferences - setPref($data_dir, $username, 'chosen_theme', $chosentheme); - setPref($data_dir, $username, 'language', $language); - setPref($data_dir, $username, 'use_javascript_addr_book', $javascript_abook); - setPref($data_dir, $username, 'show_num', $shownum); - setPref($data_dir, $username, 'wrap_at', $wrapat); - setPref($data_dir, $username, 'editor_size', $editorsize); - setPref($data_dir, $username, 'left_refresh', $leftrefresh); - setPref($data_dir, $username, 'location_of_bar', $folder_new_location); - setPref($data_dir, $username, 'location_of_buttons', $button_new_location); - setPref($data_dir, $username, 'left_size', $leftsize); - - if (isset($altIndexColors) && $altIndexColors == 1) { - setPref($data_dir, $username, 'alt_index_colors', 1); - } else { - setPref($data_dir, $username, 'alt_index_colors', 0); - } - - setPref($data_dir, $username, 'show_html_default', ($showhtmldefault?1:0) ); - - if (isset($includeselfreplyall)) { - setPref($data_dir, $username, 'include_self_reply_all', 1); - } else { - removePref($data_dir, $username, 'include_self_reply_all'); - } - - if (isset($pageselectormax)) { - setPref($data_dir, $username, 'page_selector_max', $pageselectormax); - } else { - removePref($data_dir, $username, 'page_selector_max', 0 ); - } - - if (isset($pageselector)) { - removePref($data_dir, $username, 'page_selector'); - } else { - setPref($data_dir, $username, 'page_selector', 1); - } - - do_hook('options_display_save'); - - echo '
    '._("Successfully saved display preferences!").'
    '; - echo '' . _("Refresh Page") . '
    '; - } else if (isset($submit_folder)) { - # Save folder preferences - if ($trash != 'none') { - setPref($data_dir, $username, 'move_to_trash', true); - setPref($data_dir, $username, 'trash_folder', $trash); - } else { - setPref($data_dir, $username, 'move_to_trash', '0'); - setPref($data_dir, $username, 'trash_folder', 'none'); - } - if ($sent != 'none') { - setPref($data_dir, $username, 'move_to_sent', true); - setPref($data_dir, $username, 'sent_folder', $sent); - } else { - setPref($data_dir, $username, 'move_to_sent', '0'); - setPref($data_dir, $username, 'sent_folder', 'none'); - } - if ($draft != 'none') { - setPref($data_dir, $username, 'save_as_draft', true); - setPref($data_dir, $username, 'draft_folder', $draft); - } else { - setPref($data_dir, $username, 'save_as_draft', '0'); - setPref($data_dir, $username, 'draft_folder', 'none'); - } - if (isset($folderprefix)) { - setPref($data_dir, $username, 'folder_prefix', $folderprefix); - } else { - setPref($data_dir, $username, 'folder_prefix', ''); - } - setPref($data_dir, $username, 'unseen_notify', $unseennotify); - setPref($data_dir, $username, 'unseen_type', $unseentype); - if (isset($collapsefolders)) - setPref($data_dir, $username, 'collapse_folders', $collapsefolders); - else - removePref($data_dir, $username, 'collapse_folders'); - setPref($data_dir, $username, 'date_format', $dateformat); - setPref($data_dir, $username, 'hour_format', $hourformat); - do_hook('options_folders_save'); - echo '
    '._("Successfully saved folder preferences!").'
    '; - echo '' . _("Refresh Folder List") . '
    '; - } else { - do_hook('options_save'); - } + echo '
    '._("Successfully saved personal information!").'
    '; + } else if (isset($submit_display)) { + // Do checking to make sure $chosentheme is in the array + $in_ary = false; + for ($i=0; $i < count($theme); $i++) { + if ($theme[$i]['PATH'] == $chosentheme) { + $in_ary = true; + break; + } + } + if (! $in_ary) { + $chosentheme = ''; + } + /* Save display preferences. */ + setPref($data_dir, $username, 'chosen_theme', $chosentheme); + setPref($data_dir, $username, 'language', $language); + setPref($data_dir, $username, 'use_javascript_addr_book', $javascript_abook); + setPref($data_dir, $username, 'show_num', $shownum); + setPref($data_dir, $username, 'wrap_at', $wrapat); + setPref($data_dir, $username, 'editor_size', $editorsize); + setPref($data_dir, $username, 'left_refresh', $leftrefresh); + setPref($data_dir, $username, 'location_of_bar', $folder_new_location); + setPref($data_dir, $username, 'location_of_buttons', $button_new_location); + setPref($data_dir, $username, 'left_size', $leftsize); + + if (isset($altIndexColors) && $altIndexColors == 1) { + setPref($data_dir, $username, 'alt_index_colors', 1); + } else { + setPref($data_dir, $username, 'alt_index_colors', 0); + } + + setPref($data_dir, $username, 'show_html_default', ($showhtmldefault?1:0) ); + + if (isset($includeselfreplyall)) { + setPref($data_dir, $username, 'include_self_reply_all', 1); + } else { + removePref($data_dir, $username, 'include_self_reply_all'); + } + + if (isset($pageselectormax)) { + setPref($data_dir, $username, 'page_selector_max', $pageselectormax); + } else { + removePref($data_dir, $username, 'page_selector_max', 0 ); + } + + if (isset($pageselector)) { + removePref($data_dir, $username, 'page_selector'); + } else { + setPref($data_dir, $username, 'page_selector', 1); + } + + do_hook('options_display_save'); + + echo '
    '._("Successfully saved display preferences!").'
    '; + echo '' . _("Refresh Page") . '
    '; + } else if (isset($submit_folder)) { + /* Save folder preferences. */ + if ($trash != 'none') { + setPref($data_dir, $username, 'move_to_trash', true); + setPref($data_dir, $username, 'trash_folder', $trash); + } else { + setPref($data_dir, $username, 'move_to_trash', '0'); + setPref($data_dir, $username, 'trash_folder', 'none'); + } + if ($sent != 'none') { + setPref($data_dir, $username, 'move_to_sent', true); + setPref($data_dir, $username, 'sent_folder', $sent); + } else { + setPref($data_dir, $username, 'move_to_sent', '0'); + setPref($data_dir, $username, 'sent_folder', 'none'); + } + if ($draft != 'none') { + setPref($data_dir, $username, 'save_as_draft', true); + setPref($data_dir, $username, 'draft_folder', $draft); + } else { + setPref($data_dir, $username, 'save_as_draft', '0'); + setPref($data_dir, $username, 'draft_folder', 'none'); + } + if (isset($folderprefix)) { + setPref($data_dir, $username, 'folder_prefix', $folderprefix); + } else { + setPref($data_dir, $username, 'folder_prefix', ''); + } + setPref($data_dir, $username, 'unseen_notify', $unseennotify); + setPref($data_dir, $username, 'unseen_type', $unseentype); + if (isset($collapsefolders)) + setPref($data_dir, $username, 'collapse_folders', $collapsefolders); + else + removePref($data_dir, $username, 'collapse_folders'); + setPref($data_dir, $username, 'date_format', $dateformat); + setPref($data_dir, $username, 'hour_format', $hourformat); + do_hook('options_folders_save'); + echo '
    '._("Successfully saved folder preferences!").'
    '; + echo '' . _("Refresh Folder List") . '
    '; + } else { + do_hook('options_save'); + } + + /****************************************/ + /* Now build our array of option pages. */ + /****************************************/ + + /* Build a section for Personal Options. */ + $optionpages[] = array( + 'name' => _("Personal Information"), + 'url' => 'options_personal.php', + 'desc' => _("This contains personal information about yourself such as your name, your email address, etc."), + 'js' => false + ); + + /* Build a section for Display Options. */ + $optionpages[] = array( + 'name' => _("Display Preferences"), + 'url' => 'options_display.php', + 'desc' => _("You can change the way that SquirrelMail looks and displays information to you, such as the colors, the language, and other settings."), + 'js' => false + ); + + /* Build a section for Message Highlighting Options. */ + $optionpages[] = array( + 'name' =>_("Message Highlighting"), + 'url' => 'options_highlight.php', + 'desc' =>_("Based upon given criteria, incoming messages can have different background colors in the message list. This helps to easily distinguish who the messages are from, especially for mailing lists."), + 'js' => false + ); + + /* Build a section for Folder Options. */ + $optionpages[] = array( + 'name' => _("Folder Preferences"), + 'url' => 'options_folder.php', + 'desc' => _("These settings change the way your folders are displayed and manipulated."), + 'js' => false + ); + + /* Build a section for Index Order Options. */ + $optionpages[] = array( + 'name' => _("Index Order"), + 'url' => 'options_order.php', + 'desc' => _("The order of the message index can be rearanged and changed to contain the headers in any order you want."), + 'js' => false + ); + /* Build a section for plugins wanting to register an optionpage. */ + do_hook('options_register'); + + /*****************************************************/ + /* Let's sort Javascript Option Pages to the bottom. */ + /*****************************************************/ + foreach ($optionpages as $optpage) { + if ($optpage['js']) { + $js_optionpages[] = $optpage; + } else { + $nojs_optionpages[] = $optpage; + } + } + $optionpages = array_merge($nojs_optionpages, $js_optionpages); + + /********************************************/ + /* Now, print out each option page section. */ + /********************************************/ + $first_optpage = false; + foreach ($optionpages as $next_optpage) { + if ($first_optpage == false) { + $first_optpage = $next_optpage; + } else { + print_optionpages_row($first_optpage, $next_optpage); + $first_optpage = false; + } + } + + if ($first_optpage != false) { + print_optionpages_row($first_optpage); + } + + do_hook('options_link_and_description'); + ?> +
    + +
    + + + +" width="100%" cellpadding="5" cellspacing="0" border="0"> -
    + /** + * This function prints out an option page row: in which the left + * Left: options for functionality that do not require javascript + * Right: options for functionality that do not require javascript + */ + function print_optionpages_row_nojs($leftopt, $rightopt = false) { + global $color; +?> + +
    - + + + + + + - - -
    - + + +   +  
    - + +

    - - - + + + + + - - - -
    - +   +  
    - -

    +
    +
    + + + -
    - + + + + + + - - -
    - + + +   +  
    - + +

    -
    - - - + + + + + - - - -
    - +   +  
    - -

    +
    +
    + + + - -
    - + + + + + + - - -
    - + +   + +  
    - + +

    -
    - - - - - - - - +   + + + + + +   + + + + + +?> -- 2.25.1