ea0fa9a012eddd040c1f00bb09ba0a80c547c7d7
4 * sqspell_functions.php
6 * All SquirrelSpell-wide functions are in this file.
8 * @author Konstantin Riabitsev <icon at duke.edu>
9 * @copyright © 1999-2005 The SquirrelMail Project Team
10 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
13 * @subpackage squirrelspell
17 if (! defined('SM_PATH')) define('SM_PATH','../../');
19 /** globalize configuration vars **/
20 global $SQSPELL_APP, $SQSPELL_APP_DEFAULT, $SQSPELL_WORDS_FILE, $SQSPELL_CRYPTO;
23 * load plugin configuration
24 * @todo allow storing configuration file in config/ directory
26 include_once(SM_PATH
. 'plugins/squirrelspell/sqspell_config.php');
28 /** Hooked functions **/
31 * Register option page block (internal function)
32 * @since 1.5.1 (sqspell 0.5)
35 function squirrelspell_optpage_block_function() {
36 global $optpage_blocks;
39 * Dependency on JavaScript is checked by SquirrelMail scripts
40 * Register Squirrelspell with the $optpage_blocks array.
44 'name' => _("SpellChecker Options"),
45 'url' => '../plugins/squirrelspell/sqspell_options.php',
46 '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."),
51 * This function adds a "Check Spelling" link to the "Compose" row
52 * during message composition (internal function).
53 * @since 1.5.1 (sqspell 0.5)
56 function squirrelspell_setup_function() {
58 * Check if this browser is capable of displaying SquirrelSpell
61 if (checkForJavascript()) {
63 * Some people may choose to disable javascript even though their
64 * browser is capable of using it. So these freaks don't complain,
65 * use document.write() so the "Check Spelling" button is not
66 * displayed if js is off in the browser.
68 echo "<script type=\"text/javascript\">\n".
70 'document.write("<input type=\"button\" value=\"'.
72 '\" name=\"check_spelling\" onclick=\"window.open(\'../plugins/squirrelspell/sqspell_'.
73 'interface.php\', \'sqspell\', \'status=yes,width=550,height=370,'.
74 'resizable=yes\')\" />");' . "\n".
81 * Upgrade dictionaries (internal function)
83 * Transparently upgrades user's dictionaries when message listing is loaded
84 * @since 1.5.1 (sqspell 0.5)
86 function squirrelspell_upgrade_function() {
87 global $data_dir, $username;
89 if (! sqspell_check_version(0,5)) {
90 $langs=sqspell_getSettings_old(null);
91 $words=sqspell_getWords_old();
92 sqspell_saveSettings($langs);
93 foreach ($langs as $lang) {
94 $lang_words=sqspell_getLang_old($words,$lang);
95 $aLang_words=explode("\n",$lang_words);
97 foreach($aLang_words as $word) {
98 if (! preg_match("/^#/",$word) && trim($word)!='') {
102 sqspell_writeWords($new_words,$lang);
104 // bump up version number
105 setPref($data_dir,$username,'sqspell_version','0.5');
109 /** Internal functions **/
112 * This function is the GUI wrapper for the options page. SquirrelSpell
113 * uses it for creating all Options pages.
115 * @param string $title The title of the page to display
116 * @param string $scriptsrc This is used to link a file.js into the
117 * <script src="file.js"></script> format. This
118 * allows to separate javascript from the rest of the
119 * plugin and place it into the js/ directory.
120 * @param string $body The body of the message to display.
123 function sqspell_makePage($title, $scriptsrc, $body){
124 global $color, $SQSPELL_VERSION;
126 if (! sqgetGlobalVar('MOD', $MOD, SQ_GET
) ) {
127 $MOD = 'options_main';
130 displayPageHeader($color, 'None');
131 echo " <br />\n";
133 * Check if we need to link in a script.
136 echo "<script type=\"text/javascript\" src=\"js/$scriptsrc\"></script>\n";
138 echo html_tag( 'table', '', 'center', '', 'width="95%" border="0" cellpadding="2" cellspacing="0"' ) . "\n"
139 . html_tag( 'tr', "\n" .
140 html_tag( 'td', '<strong>' . $title .'</strong>', 'center', $color[9] )
142 . html_tag( 'tr', "\n" .
143 html_tag( 'td', '<hr />', 'left' )
145 . html_tag( 'tr', "\n" .
146 html_tag( 'td', $body, 'left' )
149 * Generate a nice "Return to Options" link, unless this is the
152 if ($MOD != "options_main"){
153 echo html_tag( 'tr', "\n" .
154 html_tag( 'td', '<hr />', 'left' )
156 . html_tag( 'tr', "\n" .
157 html_tag( 'td', '<a href="sqspell_options.php">'
158 . _("Back to "SpellChecker Options" page")
164 * Close the table and display the version.
166 echo html_tag( 'tr', "\n" .
167 html_tag( 'td', '<hr />', 'left' )
170 html_tag( 'td', 'SquirrelSpell ' . squirrelspell_version(), 'center', $color[9] )
172 echo '</body></html>';
176 * Function similar to the one above. This one is a general wrapper
177 * for the Squirrelspell pop-up window. It's called form nearly
178 * everywhere, except the check_me module, since that one is highly
181 * @param string $onload Used to indicate and pass the name of a js function
182 * to call in a <body onload="function()" for automatic
183 * onload script execution.
184 * @param string $title Title of the page.
185 * @param string $scriptsrc If defined, link this javascript source page into
186 * the document using <script src="file.js"> format.
187 * @param string $body The content to include.
190 function sqspell_makeWindow($onload, $title, $scriptsrc, $body){
191 global $color, $SQSPELL_VERSION;
193 displayHtmlHeader($title,
194 ($scriptsrc ?
"\n<script type=\"text/javascript\" src=\"js/$scriptsrc\"></script>\n" : ''));
196 echo "<body text=\"$color[8]\" bgcolor=\"$color[4]\" link=\"$color[7]\" "
197 . "vlink=\"$color[7]\" alink=\"$color[7]\"";
199 * Provide an onload="jsfunction()" if asked to.
202 echo " onload=\"$onload\"";
205 * Draw the rest of the page.
208 . html_tag( 'table', "\n" .
209 html_tag( 'tr', "\n" .
210 html_tag( 'td', '<strong>' . $title . '</strong>', 'center', $color[9] )
212 html_tag( 'tr', "\n" .
213 html_tag( 'td', '<hr />', 'left' )
215 html_tag( 'tr', "\n" .
216 html_tag( 'td', $body, 'left' )
218 html_tag( 'tr', "\n" .
219 html_tag( 'td', '<hr />', 'left' )
221 html_tag( 'tr', "\n" .
222 html_tag( 'td', 'SquirrelSpell ' . squirrelspell_version(), 'center', $color[9] )
224 '', '', 'width="100%" border="0" cellpadding="2"' )
225 . "</body>\n</html>\n";
229 * Encryption function used by plugin (old format)
231 * This function does the encryption and decryption of the user
232 * dictionary. It is only available when PHP is compiled with
233 * mcrypt support (--with-mcrypt). See doc/CRYPTO for more
236 * @param $mode A string with either of the two recognized values:
237 * "encrypt" or "decrypt".
238 * @param $ckey The key to use for processing (the user's password
240 * @param $input Content to decrypt or encrypt, according to $mode.
241 * @return encrypted/decrypted content, or "PANIC" if the
243 * @since 1.5.1 (sqspell 0.5)
246 function sqspell_crypto_old($mode, $ckey, $input){
248 * Double-check if we have the mcrypt_generic function. Bail out if
251 if (!function_exists('mcrypt_generic')) {
255 * Setup mcrypt routines.
257 $td = mcrypt_module_open(MCRYPT_Blowfish
, "", MCRYPT_MODE_ECB
, "");
258 $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size ($td), MCRYPT_RAND
);
259 mcrypt_generic_init($td, $ckey, $iv);
261 * See what we have to do depending on $mode.
262 * 'encrypt' -- Encrypt the content.
263 * 'decrypt' -- Decrypt the content.
267 $crypto = mcrypt_generic($td, $input);
270 $crypto = mdecrypt_generic($td, $input);
272 * See if it decrypted successfully. If so, it should contain
273 * the string "# SquirrelSpell". If not, then bail out.
275 if (!strstr($crypto, "# SquirrelSpell")){
281 * Finish up the mcrypt routines and return the processed content.
283 if (function_exists('mcrypt_generic_deinit')) {
285 mcrypt_generic_deinit ($td);
286 mcrypt_module_close ($td);
288 // older deprecated function
289 mcrypt_generic_end ($td);
295 * Encryption function used by plugin
297 * This function does the encryption and decryption of the user
298 * dictionary. It is only available when PHP is compiled with
299 * mcrypt support (--with-mcrypt). See doc/CRYPTO for more
302 * @param $mode A string with either of the two recognized values:
303 * "encrypt" or "decrypt".
304 * @param $ckey The key to use for processing (the user's password
306 * @param $input Content to decrypt or encrypt, according to $mode.
307 * @return encrypted/decrypted content, or "PANIC" if the
310 function sqspell_crypto($mode, $ckey, $input){
312 * Double-check if we have the mcrypt_generic function. Bail out if
315 if (!function_exists('mcrypt_generic')) {
319 * Setup mcrypt routines.
321 $td = mcrypt_module_open(MCRYPT_Blowfish
, "", MCRYPT_MODE_ECB
, "");
322 $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size ($td), MCRYPT_RAND
);
323 mcrypt_generic_init($td, $ckey, $iv);
325 * See what we have to do depending on $mode.
326 * 'encrypt' -- Encrypt the content.
327 * 'decrypt' -- Decrypt the content.
331 $crypto = mcrypt_generic($td, '{sqspell}'.$input);
334 $crypto = mdecrypt_generic($td, $input);
335 if (preg_match("/^\{sqspell\}(.*)/",$crypto,$match)){
336 $crypto = trim($match[1]);
343 * Finish up the mcrypt routines and return the processed content.
345 if (function_exists('mcrypt_generic_deinit')) {
347 mcrypt_generic_deinit ($td);
348 mcrypt_module_close ($td);
350 // older deprecated function
351 mcrypt_generic_end ($td);
357 * This function transparently upgrades the 0.2 dictionary format to the
358 * 0.3 format, since user-defined languages have been added in 0.3 and
359 * the new format keeps user dictionaries selection in the file.
361 * This function will be retired soon, as it's been a while since anyone
362 * has been using SquirrelSpell-0.2.
364 * @param $words_string Contents of the 0.2-style user dictionary.
365 * @return Contents of the 0.3-style user dictionary.
368 function sqspell_upgradeWordsFile($words_string){
369 global $SQSPELL_APP_DEFAULT, $SQSPELL_VERSION;
371 * Define just one dictionary for this user -- the default.
372 * If the user wants more, s/he can set them up in personal
373 * preferences. See doc/UPGRADING for more info.
376 substr_replace($words_string,
377 "# SquirrelSpell User Dictionary $SQSPELL_VERSION\n# "
378 . "Last Revision: " . date("Y-m-d")
379 . "\n# LANG: $SQSPELL_APP_DEFAULT\n# $SQSPELL_APP_DEFAULT",
380 0, strpos($words_string, "\n")) . "# End\n";
381 sqspell_writeWords($new_words_string);
382 return $new_words_string;
386 * gets list of available dictionaries from user's prefs.
387 * Function was modified in 1.5.1 (sqspell 0.5).
388 * Older function is suffixed with '_old'
389 * @return array list of dictionaries used by end user.
391 function sqspell_getSettings(){
392 global $data_dir, $username, $SQSPELL_APP_DEFAULT, $SQSPELL_APP;
396 $sLangs=getPref($data_dir,$username,'sqspell_langs','');
398 $ret[0]=$SQSPELL_APP_DEFAULT;
400 $aLangs = explode(',',$sLangs);
401 foreach ($aLangs as $lang) {
402 if (array_key_exists($lang,$SQSPELL_APP)) {
411 * Saves user's language preferences
412 * @param array $langs languages array (first key is default language)
413 * @since 1.5.1 (sqspell 0.5)
415 function sqspell_saveSettings($langs) {
416 global $data_dir, $username;
417 setPref($data_dir,$username,'sqspell_langs',implode(',',$langs));
421 * Get list of enabled languages.
423 * Right now it just returns an array with the dictionaries
424 * available to the user for spell-checking. It will probably
425 * do more in the future, as features are added.
427 * @param string $words The contents of the user's ".words" file.
428 * @return array a strings array with dictionaries available
429 * to this user, e.g. {"English", "Spanish"}, etc.
430 * @since 1.5.1 (sqspell 0.5)
433 function sqspell_getSettings_old($words){
434 global $SQSPELL_APP, $SQSPELL_APP_DEFAULT;
436 * Check if there is more than one dictionary configured in the
439 if (sizeof($SQSPELL_APP) > 1){
441 * Now load the user prefs. Check if $words was empty -- a bit of
442 * a dirty fall-back. TODO: make it so this is not required.
445 $words=sqspell_getWords_old();
449 * This user has a ".words" file.
450 * Find which dictionaries s/he wants to use and load them into
453 preg_match("/# LANG: (.*)/i", $words, $matches);
454 $langs=explode(", ", $matches[1]);
457 * User doesn't have a personal dictionary. Grab the default
460 $langs[0]=$SQSPELL_APP_DEFAULT;
464 * There is no need to read the ".words" file as there is only one
465 * dictionary defined system-wide.
467 $langs[0]=$SQSPELL_APP_DEFAULT;
473 * Get user dictionary for selected language
474 * Function was modified in 1.5.1 (sqspell 0.5).
475 * Older function is suffixed with '_old'
476 * @param string $lang language
477 * @param array words stored in selected language dictionary
479 function sqspell_getLang($lang) {
480 global $data_dir, $username,$SQSPELL_CRYPTO;
481 $sWords=getPref($data_dir,$username,'sqspell_dict_' . $lang,'');
482 if (preg_match("/^\{crypt\}(.*)/i",$sWords,$match)) {
484 * Dictionary is encrypted or mangled. Try to decrypt it.
485 * If fails, complain loudly.
487 * $old_key would be a value submitted by one of the modules with
488 * the user's old mailbox password. I admin, this is rather dirty,
491 if (sqgetGlobalVar('old_key', $old_key, SQ_POST
)) {
494 sqgetGlobalVar('key', $key, SQ_COOKIE
);
495 sqgetGlobalVar('onetimepad', $onetimepad, SQ_SESSION
);
497 * Get user's password (the key).
499 $clear_key = OneTimePadDecrypt($key, $onetimepad);
502 * Invoke the decryption routines.
504 $sWords=sqspell_crypto("decrypt", $clear_key, $match[1]);
506 * See if decryption failed.
508 if ($sWords=="PANIC"){
509 sqspell_handle_crypt_panic($lang);
510 // script execution stops here
513 * OK! Phew. Set the encryption flag to true so we can later on
514 * encrypt it again before saving to HDD.
516 $SQSPELL_CRYPTO=true;
520 * No encryption is/was used. Set $SQSPELL_CRYPTO to false,
521 * in case we have to save the dictionary later.
523 $SQSPELL_CRYPTO=false;
525 // rebuild word list and remove empty entries
527 foreach (explode(',',$sWords) as $word) {
528 if (trim($word) !='') {
529 $aWords[]=trim($word);
536 * Get user's dictionary (old format)
538 * This function returns only user-defined dictionary words that correspond
539 * to the requested language.
541 * @param $words The contents of the user's ".words" file.
542 * @param $lang Which language words to return, e.g. requesting
543 * "English" will return ONLY the words from user's
544 * English dictionary, disregarding any others.
545 * @return The list of words corresponding to the language
547 * @since 1.5.1 (sqspell 0.5)
550 function sqspell_getLang_old($words, $lang){
551 $start=strpos($words, "# $lang\n");
553 * strpos() will return -1 if no # $lang\n string was found.
554 * Use this to return a zero-length value and indicate that no
555 * words are present in the requested dictionary.
557 if (!$start) return '';
559 * The words list will end with a new directive, which will start
560 * with "#". Locate the next "#" and thus find out where the
563 $end=strpos($words, "#", $start+
1);
564 $lang_words = substr($words, $start, $end-$start);
569 * Saves user's dictionary (old format)
571 * This function operates the user dictionary. If the format is
572 * clear-text, then it just reads the file and returns it. However, if
573 * the file is encrypted (well, "garbled"), then it tries to decrypt
574 * it, checks whether the decryption was successful, troubleshoots if
575 * not, then returns the clear-text dictionary to the app.
577 * @return the contents of the user's ".words" file, decrypted if
579 * @since 1.5.1 (sqspell 0.5)
582 function sqspell_getWords_old(){
583 global $SQSPELL_WORDS_FILE, $SQSPELL_CRYPTO;
585 if (file_exists($SQSPELL_WORDS_FILE)){
589 $fp=fopen($SQSPELL_WORDS_FILE, 'r');
590 $words=fread($fp, filesize($SQSPELL_WORDS_FILE));
594 * Check if this is an encrypted file by looking for
595 * the string "# SquirrelSpell" in it (the crypto
596 * function does that).
598 if ($words && !strstr($words, "# SquirrelSpell")){
600 * This file is encrypted or mangled. Try to decrypt it.
601 * If fails, complain loudly.
603 * $old_key would be a value submitted by one of the modules with
604 * the user's old mailbox password. I admin, this is rather dirty,
607 sqgetGlobalVar('key', $key, SQ_COOKIE
);
608 sqgetGlobalVar('onetimepad', $onetimepad, SQ_SESSION
);
610 sqgetGlobalVar('old_key', $old_key, SQ_POST
);
612 if ($old_key != '') {
616 * Get user's password (the key).
618 $clear_key = OneTimePadDecrypt($key, $onetimepad);
621 * Invoke the decryption routines.
623 $words=sqspell_crypto_old("decrypt", $clear_key, $words);
625 * See if decryption failed.
627 if ($words=="PANIC"){
628 sqspell_handle_crypt_panic();
629 // script execution stops here.
632 * OK! Phew. Set the encryption flag to true so we can later on
633 * encrypt it again before saving to HDD.
635 $SQSPELL_CRYPTO=true;
639 * No encryption is/was used. Set $SQSPELL_CRYPTO to false,
640 * in case we have to save the dictionary later.
642 $SQSPELL_CRYPTO=false;
645 * Check if we need to upgrade the dictionary from version 0.2.x
646 * This is going away soon.
648 if (strstr($words, "Dictionary v0.2")){
649 $words=sqspell_upgradeWordsFile($words);
655 * Saves user's dictionary
656 * Function was replaced in 1.5.1 (sqspell 0.5).
657 * Older function is suffixed with '_old'
658 * @param array $words words that should be stored in dictionary
659 * @param string $lang language
661 function sqspell_writeWords($words,$lang){
662 global $SQSPELL_CRYPTO,$username,$data_dir;
664 $sWords = implode(',',$words);
665 if ($SQSPELL_CRYPTO){
667 * User wants to encrypt the file. So be it.
668 * Get the user's password to use as a key.
670 sqgetGlobalVar('key', $key, SQ_COOKIE
);
671 sqgetGlobalVar('onetimepad', $onetimepad, SQ_SESSION
);
673 $clear_key=OneTimePadDecrypt($key, $onetimepad);
675 * Try encrypting it. If fails, scream bloody hell.
677 $save_words = sqspell_crypto("encrypt", $clear_key, $sWords);
678 if ($save_words == 'PANIC'){
679 // FIXME: handle errors here
682 $save_words='{crypt}'.$save_words;
686 setPref($data_dir,$username,'sqspell_dict_'.$lang,$save_words);
690 * Writes user dictionary into the $username.words file, then changes mask
691 * to 0600. If encryption is needed -- does that, too.
693 * @param $words The contents of the ".words" file to write.
695 * @since 1.5.1 (sqspell 0.5)
698 function sqspell_writeWords_old($words){
699 global $SQSPELL_WORDS_FILE, $SQSPELL_CRYPTO;
701 * if $words is empty, create a template entry by calling the
702 * sqspell_makeDummy() function.
705 $words=sqspell_makeDummy();
707 if ($SQSPELL_CRYPTO){
709 * User wants to encrypt the file. So be it.
710 * Get the user's password to use as a key.
712 sqgetGlobalVar('key', $key, SQ_COOKIE
);
713 sqgetGlobalVar('onetimepad', $onetimepad, SQ_SESSION
);
715 $clear_key=OneTimePadDecrypt($key, $onetimepad);
717 * Try encrypting it. If fails, scream bloody hell.
719 $save_words = sqspell_crypto("encrypt", $clear_key, $words);
720 if ($save_words == 'PANIC'){
722 * AAAAAAAAH! I'm not handling this yet, since obviously
723 * the admin of the site forgot to compile the MCRYPT support in
724 * when upgrading an existing PHP installation.
725 * I will add a handler for this case later, when I can come up
726 * with some work-around... Right now, do nothing. Let the Admin's
729 /** save some hairs on admin's head and store error message in logs */
730 error_log('SquirrelSpell: php does not have mcrypt support');
733 $save_words = $words;
736 * Do the actual writing.
738 $fp=fopen($SQSPELL_WORDS_FILE, "w");
739 fwrite($fp, $save_words);
741 chmod($SQSPELL_WORDS_FILE, 0600);
745 * Deletes user's dictionary
746 * Function was modified in 1.5.1 (sqspell 0.5). Older function is suffixed
748 * @param string $lang dictionary
750 function sqspell_deleteWords($lang) {
751 global $data_dir, $username;
752 removePref($data_dir,$username,'sqspell_dict_'.$lang);
756 * Deletes user's dictionary when it is corrupted.
757 * @since 1.5.1 (sqspell 0.5)
760 function sqspell_deleteWords_old(){
762 * So I open the door to my enemies,
763 * and I ask can we wipe the slate clean,
764 * but they tell me to please go...
765 * uhm... Well, this just erases the user dictionary file.
767 global $SQSPELL_WORDS_FILE;
768 if (file_exists($SQSPELL_WORDS_FILE)){
769 unlink($SQSPELL_WORDS_FILE);
773 * Creates an empty user dictionary for the sake of saving prefs or
776 * @return The template to use when storing the user dictionary.
779 function sqspell_makeDummy(){
780 global $SQSPELL_VERSION, $SQSPELL_APP_DEFAULT;
781 $words = "# SquirrelSpell User Dictionary $SQSPELL_VERSION\n"
782 . "# Last Revision: " . date('Y-m-d')
783 . "\n# LANG: $SQSPELL_APP_DEFAULT\n# End\n";
788 * This function checks for security attacks. A $MOD variable is
789 * provided in the QUERY_STRING and includes one of the files from the
790 * modules directory ($MOD.mod). See if someone is trying to get out
791 * of the modules directory by providing dots, unicode strings, or
794 * @param string $rMOD the name of the module requested to include.
795 * @return void, since it bails out with an access error if needed.
797 function sqspell_ckMOD($rMOD){
798 if (strstr($rMOD, '.')
799 ||
strstr($rMOD, '/')
800 ||
strstr($rMOD, '%')
801 ||
strstr($rMOD, "\\")){
808 * Used to check internal version of SquirrelSpell dictionary
809 * @param integer $major main version number
810 * @param integer $minor second version number
811 * @return boolean true if stored dictionary version is $major.$minor or newer
812 * @since 1.5.1 (sqspell 0.5)
814 function sqspell_check_version($major,$minor) {
815 global $data_dir, $username;
816 // 0.4 version is internal version number that is used to indicate upgrade from
817 // separate files to generic SquirrelMail prefs storage.
818 $sqspell_version=getPref($data_dir,$username,'sqspell_version','0.4');
820 $aVersion=explode('.',$sqspell_version);
822 if ($aVersion[0] < $major ||
823 ( $aVersion[0] == $major && $aVersion[1] < $minor)) {
830 * Displays form that allows to enter different password for dictionary decryption.
831 * If language is not set, function provides form to handle older dictionary files.
832 * @param string $lang language
833 * @since 1.5.1 (sqspell 0.5)
835 function sqspell_handle_crypt_panic($lang=false) {
836 if (! sqgetGlobalVar('SCRIPT_NAME',$SCRIPT_NAME,SQ_SERVER
))
840 * AAAAAAAAAAAH!!!!! OK, ok, breathe!
841 * Let's hope the decryption failed because the user changed his
842 * password. Bring up the option to key in the old password
843 * or wipe the file and start over if everything else fails.
845 * The _("SquirrelSpell...) line has to be on one line, otherwise
846 * gettext will bork. ;(
848 $msg = html_tag( 'p', "\n" .
849 '<strong>' . _("ATTENTION:") . '</strong><br />'
850 . _("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.") ,
852 . (($lang) ?
html_tag('p',sprintf(_("Your %s dictionary is encrypted with password that differs from your current password."),
853 htmlspecialchars($lang)),'left') : '')
854 . '<blockquote>' . "\n"
855 . '<form method="post" onsubmit="return AYS()">' . "\n"
856 . '<input type="hidden" name="MOD" value="crypto_badkey" />' . "\n"
858 '<input type="hidden" name="dict_lang" value="'.htmlspecialchars($lang).'" />' :
859 '<input type="hidden" name="old_setup" value="yes" />')
860 . html_tag( 'p', "\n" .
861 '<input type="checkbox" name="delete_words" value="ON" />'
862 . _("Delete my dictionary and start a new one") . '<br />'
863 . _("Decrypt my dictionary with my old password:")
864 . '<input name="old_key" size="10" />' ,
866 . '</blockquote>' . "\n"
867 . html_tag( 'p', "\n"
868 . '<input type="submit" value="'
869 . _("Proceed") . ' >>" />' ,
873 * Add some string vars so they can be i18n'd.
875 $msg .= "<script type='text/javascript'><!--\n"
876 . "var ui_choice = \"" . _("You must make a choice") ."\";\n"
877 . "var ui_candel = \"" . _("You can either delete your dictionary or type in the old password. Not both.") . "\";\n"
878 . "var ui_willdel = \"" . _("This will delete your personal dictionary file. Proceed?") . "\";\n"
879 . "//--></script>\n";
881 * See if this happened in the pop-up window or when accessing
882 * the SpellChecker options page.
883 * This is a dirty solution, I agree.
884 * TODO: make this prettier.
886 if (strstr($SCRIPT_NAME, "sqspell_options")){
887 sqspell_makePage(_("Error Decrypting Dictionary"),
888 "decrypt_error.js", $msg);
890 sqspell_makeWindow(null, _("Error Decrypting Dictionary"),
891 "decrypt_error.js", $msg);
897 * SquirrelSpell version. Don't modify, since it identifies the format
898 * of the user dictionary files and messing with this can do ugly
900 * @global string $SQSPELL_VERSION
903 $SQSPELL_VERSION="v0.3.8";