confused original code with php5 fix
[squirrelmail.git] / plugins / squirrelspell / sqspell_functions.php
CommitLineData
849bdf42 1<?php
15e6162e 2/**
91e0dccc 3 * sqspell_functions.php
d112ed5a 4 * ----------------------
5 * All SquirrelSpell-wide functions are in this file.
15e6162e 6 *
9eb3fcb3 7 * Copyright (c) 1999-2005 The SquirrelMail Project Team
15e6162e 8 * Licensed under the GNU GPL. For full terms see the file COPYING.
9 *
7996c920 10 * @author Konstantin Riabitsev <icon@duke.edu>
11 * @version $Id$
ea5f4b8e 12 * @package plugins
13 * @subpackage squirrelspell
15e6162e 14 */
d112ed5a 15
16/**
17 * This function is the GUI wrapper for the options page. SquirrelSpell
18 * uses it for creating all Options pages.
19 *
7996c920 20 * @param string $title The title of the page to display
21 * @param string $scriptsrc This is used to link a file.js into the
d112ed5a 22 * <script src="file.js"></script> format. This
23 * allows to separate javascript from the rest of the
24 * plugin and place it into the js/ directory.
7996c920 25 * @param string $body The body of the message to display.
d112ed5a 26 * @return void
27 */
28function sqspell_makePage($title, $scriptsrc, $body){
8a9f9d09 29 global $color, $SQSPELL_VERSION;
30
b587ac51 31 if (! sqgetGlobalVar('MOD', $MOD, SQ_GET) ) {
8a9f9d09 32 $MOD = 'options_main';
33 }
34
91e0dccc 35 displayPageHeader($color, 'None');
2ad4cea9 36 echo "&nbsp;<br />\n";
d112ed5a 37 /**
38 * Check if we need to link in a script.
39 */
91e0dccc 40 if($scriptsrc) {
d112ed5a 41 echo "<script type=\"text/javascript\" src=\"js/$scriptsrc\"></script>\n";
42 }
484ed7c9 43 echo html_tag( 'table', '', 'center', '', 'width="95%" border="0" cellpadding="2" cellspacing="0"' ) . "\n"
44 . html_tag( 'tr', "\n" .
45 html_tag( 'td', '<strong>' . $title .'</strong>', 'center', $color[9] )
46 ) . "\n"
47 . html_tag( 'tr', "\n" .
04fa3c41 48 html_tag( 'td', '<hr />', 'left' )
484ed7c9 49 ) . "\n"
50 . html_tag( 'tr', "\n" .
51 html_tag( 'td', $body, 'left' )
52 ) . "\n";
d112ed5a 53 /**
54 * Generate a nice "Return to Options" link, unless this is the
55 * starting page.
56 */
91e0dccc 57 if ($MOD != "options_main"){
484ed7c9 58 echo html_tag( 'tr', "\n" .
04fa3c41 59 html_tag( 'td', '<hr />', 'left' )
484ed7c9 60 ) . "\n"
61 . html_tag( 'tr', "\n" .
62 html_tag( 'td', '<a href="sqspell_options.php">'
63 . _("Back to &quot;SpellChecker Options&quot; page")
64 . '</a>',
65 'center' )
66 ) . "\n";
d112ed5a 67 }
68 /**
69 * Close the table and display the version.
70 */
484ed7c9 71 echo html_tag( 'tr', "\n" .
04fa3c41 72 html_tag( 'td', '<hr />', 'left' )
484ed7c9 73 ) . "\n"
74 . html_tag( 'tr',
7996c920 75 html_tag( 'td', 'SquirrelSpell ' . squirrelspell_version(), 'center', $color[9] )
f6536dcf 76 ) . "\n</table>\n";
dcc1cc82 77 echo '</body></html>';
d112ed5a 78}
79
80/**
81 * Function similar to the one above. This one is a general wrapper
82 * for the Squirrelspell pop-up window. It's called form nearly
83 * everywhere, except the check_me module, since that one is highly
84 * customized.
85 *
7996c920 86 * @param string $onload Used to indicate and pass the name of a js function
d112ed5a 87 * to call in a <body onload="function()" for automatic
88 * onload script execution.
7996c920 89 * @param string $title Title of the page.
90 * @param string $scriptsrc If defined, link this javascript source page into
d112ed5a 91 * the document using <script src="file.js"> format.
7996c920 92 * @param string $body The content to include.
d112ed5a 93 * @return void
94 */
95function sqspell_makeWindow($onload, $title, $scriptsrc, $body){
fff30237 96 global $color, $SQSPELL_VERSION;
97
98 displayHtmlHeader($title,
99 ($scriptsrc ? "\n<script type=\"text/javascript\" src=\"js/$scriptsrc\"></script>\n" : ''));
100
101 echo "<body text=\"$color[8]\" bgcolor=\"$color[4]\" link=\"$color[7]\" "
102 . "vlink=\"$color[7]\" alink=\"$color[7]\"";
d112ed5a 103 /**
104 * Provide an onload="jsfunction()" if asked to.
105 */
106 if ($onload) {
fff30237 107 echo " onload=\"$onload\"";
d112ed5a 108 }
109 /**
110 * Draw the rest of the page.
111 */
fff30237 112 echo ">\n"
484ed7c9 113 . html_tag( 'table', "\n" .
114 html_tag( 'tr', "\n" .
115 html_tag( 'td', '<strong>' . $title . '</strong>', 'center', $color[9] )
116 ) . "\n" .
117 html_tag( 'tr', "\n" .
04fa3c41 118 html_tag( 'td', '<hr />', 'left' )
484ed7c9 119 ) . "\n" .
120 html_tag( 'tr', "\n" .
121 html_tag( 'td', $body, 'left' )
122 ) . "\n" .
123 html_tag( 'tr', "\n" .
04fa3c41 124 html_tag( 'td', '<hr />', 'left' )
484ed7c9 125 ) . "\n" .
126 html_tag( 'tr', "\n" .
7996c920 127 html_tag( 'td', 'SquirrelSpell ' . squirrelspell_version(), 'center', $color[9] )
484ed7c9 128 ) ,
129 '', '', 'width="100%" border="0" cellpadding="2"' )
d112ed5a 130 . "</body>\n</html>\n";
131}
132
133/**
7996c920 134 * Encryption function used by plugin (old format)
135 *
d112ed5a 136 * This function does the encryption and decryption of the user
91e0dccc 137 * dictionary. It is only available when PHP is compiled with
d112ed5a 138 * mcrypt support (--with-mcrypt). See doc/CRYPTO for more
139 * information.
140 *
141 * @param $mode A string with either of the two recognized values:
142 * "encrypt" or "decrypt".
143 * @param $ckey The key to use for processing (the user's password
144 * in our case.
145 * @param $input Content to decrypt or encrypt, according to $mode.
146 * @return encrypted/decrypted content, or "PANIC" if the
147 * process bails out.
7996c920 148 * @since 1.5.1 (sqspell 0.5)
149 * @deprecated
d112ed5a 150 */
7996c920 151function sqspell_crypto_old($mode, $ckey, $input){
d112ed5a 152 /**
153 * Double-check if we have the mcrypt_generic function. Bail out if
154 * not so.
155 */
1c2a03c3 156 if (!function_exists('mcrypt_generic')) {
d112ed5a 157 return 'PANIC';
158 }
159 /**
160 * Setup mcrypt routines.
161 */
162 $td = mcrypt_module_open(MCRYPT_Blowfish, "", MCRYPT_MODE_ECB, "");
163 $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size ($td), MCRYPT_RAND);
164 mcrypt_generic_init($td, $ckey, $iv);
165 /**
166 * See what we have to do depending on $mode.
167 * 'encrypt' -- Encrypt the content.
168 * 'decrypt' -- Decrypt the content.
169 */
170 switch ($mode){
171 case 'encrypt':
172 $crypto = mcrypt_generic($td, $input);
173 break;
174 case 'decrypt':
175 $crypto = mdecrypt_generic($td, $input);
91e0dccc 176 /**
d112ed5a 177 * See if it decrypted successfully. If so, it should contain
178 * the string "# SquirrelSpell". If not, then bail out.
179 */
180 if (!strstr($crypto, "# SquirrelSpell")){
181 $crypto='PANIC';
9804bcde 182 }
d112ed5a 183 break;
184 }
185 /**
186 * Finish up the mcrypt routines and return the processed content.
187 */
1c2a03c3 188 if (function_exists('mcrypt_generic_deinit')) {
189 // php 4.1.1+ syntax
190 mcrypt_generic_deinit ($td);
191 mcrypt_module_close ($td);
192 } else {
b765c366 193 // older deprecated function
1c2a03c3 194 mcrypt_generic_end ($td);
195 }
d112ed5a 196 return $crypto;
197}
198
7996c920 199/**
200 * Encryption function used by plugin
201 *
202 * This function does the encryption and decryption of the user
203 * dictionary. It is only available when PHP is compiled with
204 * mcrypt support (--with-mcrypt). See doc/CRYPTO for more
205 * information.
206 *
207 * @param $mode A string with either of the two recognized values:
208 * "encrypt" or "decrypt".
209 * @param $ckey The key to use for processing (the user's password
210 * in our case.
211 * @param $input Content to decrypt or encrypt, according to $mode.
212 * @return encrypted/decrypted content, or "PANIC" if the
213 * process bails out.
214 */
215function sqspell_crypto($mode, $ckey, $input){
216 /**
217 * Double-check if we have the mcrypt_generic function. Bail out if
218 * not so.
219 */
220 if (!function_exists('mcrypt_generic')) {
221 return 'PANIC';
222 }
223 /**
224 * Setup mcrypt routines.
225 */
226 $td = mcrypt_module_open(MCRYPT_Blowfish, "", MCRYPT_MODE_ECB, "");
227 $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size ($td), MCRYPT_RAND);
228 mcrypt_generic_init($td, $ckey, $iv);
229 /**
230 * See what we have to do depending on $mode.
231 * 'encrypt' -- Encrypt the content.
232 * 'decrypt' -- Decrypt the content.
233 */
234 switch ($mode){
235 case 'encrypt':
236 $crypto = mcrypt_generic($td, '{sqspell}'.$input);
237 break;
238 case 'decrypt':
239 $crypto = mdecrypt_generic($td, $input);
240 if (preg_match("/^\{sqspell\}(.*)/",$crypto,$match)){
241 $crypto = trim($match[1]);
242 } else {
243 $crypto='PANIC';
244 }
245 break;
246 }
247 /**
248 * Finish up the mcrypt routines and return the processed content.
249 */
250 if (function_exists('mcrypt_generic_deinit')) {
251 // php 4.1.1+ syntax
252 mcrypt_generic_deinit ($td);
253 mcrypt_module_close ($td);
254 } else {
255 // older deprecated function
256 mcrypt_generic_end ($td);
257 }
258 return $crypto;
259}
260
d112ed5a 261/**
262 * This function transparently upgrades the 0.2 dictionary format to the
263 * 0.3 format, since user-defined languages have been added in 0.3 and
264 * the new format keeps user dictionaries selection in the file.
265 *
266 * This function will be retired soon, as it's been a while since anyone
267 * has been using SquirrelSpell-0.2.
268 *
269 * @param $words_string Contents of the 0.2-style user dictionary.
270 * @return Contents of the 0.3-style user dictionary.
7996c920 271 * @deprecated
91e0dccc 272 */
d112ed5a 273function sqspell_upgradeWordsFile($words_string){
274 global $SQSPELL_APP_DEFAULT, $SQSPELL_VERSION;
275 /**
276 * Define just one dictionary for this user -- the default.
277 * If the user wants more, s/he can set them up in personal
278 * preferences. See doc/UPGRADING for more info.
279 */
91e0dccc 280 $new_words_string =
281 substr_replace($words_string,
282 "# SquirrelSpell User Dictionary $SQSPELL_VERSION\n# "
283 . "Last Revision: " . date("Y-m-d")
284 . "\n# LANG: $SQSPELL_APP_DEFAULT\n# $SQSPELL_APP_DEFAULT",
285 0, strpos($words_string, "\n")) . "# End\n";
d112ed5a 286 sqspell_writeWords($new_words_string);
287 return $new_words_string;
288}
289
290/**
7996c920 291 * gets list of available dictionaries from user's prefs.
292 * Function was modified in 1.5.1 (sqspell 0.5).
293 * Older function is suffixed with '_old'
294 * @return array list of dictionaries used by end user.
295 */
296function sqspell_getSettings(){
297 global $data_dir, $username, $SQSPELL_APP_DEFAULT, $SQSPELL_APP;
298
299 $ret=array();
300
301 $sLangs=getPref($data_dir,$username,'sqspell_langs','');
302 if ($sLangs=='') {
303 $ret[0]=$SQSPELL_APP_DEFAULT;
304 } else {
305 $aLangs = explode(',',$sLangs);
306 foreach ($aLangs as $lang) {
307 if (array_key_exists($lang,$SQSPELL_APP)) {
308 $ret[].=$lang;
309 }
310 }
311 }
312 return $ret;
313}
314
315/**
316 * Saves user's language preferences
317 * @param array $langs languages array (first key is default language)
318 * @since 1.5.1 (sqspell 0.5)
319 */
320function sqspell_saveSettings($langs) {
321 global $data_dir, $username;
322 setPref($data_dir,$username,'sqspell_langs',implode(',',$langs));
323}
324
325/**
326 * Get list of enabled languages.
327 *
91e0dccc 328 * Right now it just returns an array with the dictionaries
d112ed5a 329 * available to the user for spell-checking. It will probably
330 * do more in the future, as features are added.
331 *
7996c920 332 * @param string $words The contents of the user's ".words" file.
333 * @return array a strings array with dictionaries available
d112ed5a 334 * to this user, e.g. {"English", "Spanish"}, etc.
7996c920 335 * @since 1.5.1 (sqspell 0.5)
336 * @deprecated
d112ed5a 337 */
7996c920 338function sqspell_getSettings_old($words){
d112ed5a 339 global $SQSPELL_APP, $SQSPELL_APP_DEFAULT;
340 /**
341 * Check if there is more than one dictionary configured in the
342 * system config.
343 */
344 if (sizeof($SQSPELL_APP) > 1){
345 /**
346 * Now load the user prefs. Check if $words was empty -- a bit of
347 * a dirty fall-back. TODO: make it so this is not required.
348 */
349 if(!$words){
7996c920 350 $words=sqspell_getWords_old();
9804bcde 351 }
d112ed5a 352 if ($words){
353 /**
354 * This user has a ".words" file.
355 * Find which dictionaries s/he wants to use and load them into
356 * the $langs array.
357 */
358 preg_match("/# LANG: (.*)/i", $words, $matches);
359 $langs=explode(", ", $matches[1]);
7996c920 360
361 // make sure that langs are contains values that are present in
362 /*
363 $rebuild_langs=array();
364 foreach ($langs as $lang) {
365 if (array_key_exists($lang,$SQSPELL_APP)) {
366 $rebuild_langs[].=$lang;
367 }
368 }
369 $langs=$rebuild_langs;
370 */
d112ed5a 371 } else {
372 /**
373 * User doesn't have a personal dictionary. Grab the default
374 * system setting.
375 */
376 $langs[0]=$SQSPELL_APP_DEFAULT;
9804bcde 377 }
d112ed5a 378 } else {
379 /**
380 * There is no need to read the ".words" file as there is only one
381 * dictionary defined system-wide.
382 */
383 $langs[0]=$SQSPELL_APP_DEFAULT;
384 }
385 return $langs;
386}
387
388/**
7996c920 389 * Get user dictionary for selected language
390 * Function was modified in 1.5.1 (sqspell 0.5).
391 * Older function is suffixed with '_old'
392 * @param string $lang language
393 * @param array words stored in selected language dictionary
394 */
395function sqspell_getLang($lang) {
396 global $data_dir, $username,$SQSPELL_CRYPTO;
397 $sWords=getPref($data_dir,$username,'sqspell_dict_' . $lang,'');
398 if (preg_match("/^\{crypt\}(.*)/i",$sWords,$match)) {
399 /**
400 * Dictionary is encrypted or mangled. Try to decrypt it.
401 * If fails, complain loudly.
402 *
403 * $old_key would be a value submitted by one of the modules with
404 * the user's old mailbox password. I admin, this is rather dirty,
405 * but efficient. ;)
406 */
407 if (sqgetGlobalVar('old_key', $old_key, SQ_POST)) {
408 $clear_key=$old_key;
409 } else {
410 sqgetGlobalVar('key', $key, SQ_COOKIE);
411 sqgetGlobalVar('onetimepad', $onetimepad, SQ_SESSION);
412 /**
413 * Get user's password (the key).
414 */
415 $clear_key = OneTimePadDecrypt($key, $onetimepad);
416 }
417 /**
418 * Invoke the decryption routines.
419 */
420 $sWords=sqspell_crypto("decrypt", $clear_key, $match[1]);
421 /**
422 * See if decryption failed.
423 */
424 if ($sWords=="PANIC"){
425 sqspell_handle_crypt_panic($lang);
426 // script execution stops here
427 } else {
428 /**
429 * OK! Phew. Set the encryption flag to true so we can later on
430 * encrypt it again before saving to HDD.
431 */
432 $SQSPELL_CRYPTO=true;
433 }
434 } else {
435 /**
436 * No encryption is/was used. Set $SQSPELL_CRYPTO to false,
437 * in case we have to save the dictionary later.
438 */
439 $SQSPELL_CRYPTO=false;
440 }
441 // rebuild word list and remove empty entries
442 $aWords=array();
443 foreach (explode(',',$sWords) as $word) {
444 if (trim($word) !='') {
445 $aWords[].=trim($word);
446 }
447 }
448 return $aWords;
449}
450
451/**
452 * Get user's dictionary (old format)
453 *
d112ed5a 454 * This function returns only user-defined dictionary words that correspond
455 * to the requested language.
456 *
457 * @param $words The contents of the user's ".words" file.
91e0dccc 458 * @param $lang Which language words to return, e.g. requesting
d112ed5a 459 * "English" will return ONLY the words from user's
460 * English dictionary, disregarding any others.
461 * @return The list of words corresponding to the language
462 * requested.
7996c920 463 * @since 1.5.1 (sqspell 0.5)
464 * @deprecated
91e0dccc 465 */
7996c920 466function sqspell_getLang_old($words, $lang){
d112ed5a 467 $start=strpos($words, "# $lang\n");
468 /**
469 * strpos() will return -1 if no # $lang\n string was found.
470 * Use this to return a zero-length value and indicate that no
471 * words are present in the requested dictionary.
472 */
473 if (!$start) return '';
474 /**
475 * The words list will end with a new directive, which will start
476 * with "#". Locate the next "#" and thus find out where the
477 * words end.
478 */
479 $end=strpos($words, "#", $start+1);
480 $lang_words = substr($words, $start, $end-$start);
481 return $lang_words;
482}
483
484/**
7996c920 485 * Saves user's dictionary (old format)
486 *
d112ed5a 487 * This function operates the user dictionary. If the format is
488 * clear-text, then it just reads the file and returns it. However, if
489 * the file is encrypted (well, "garbled"), then it tries to decrypt
490 * it, checks whether the decryption was successful, troubleshoots if
491 * not, then returns the clear-text dictionary to the app.
91e0dccc 492 *
493 * @return the contents of the user's ".words" file, decrypted if
d112ed5a 494 * necessary.
7996c920 495 * @since 1.5.1 (sqspell 0.5)
496 * @deprecated
d112ed5a 497 */
7996c920 498function sqspell_getWords_old(){
d112ed5a 499 global $SQSPELL_WORDS_FILE, $SQSPELL_CRYPTO;
500 $words="";
501 if (file_exists($SQSPELL_WORDS_FILE)){
502 /**
503 * Gobble it up.
504 */
505 $fp=fopen($SQSPELL_WORDS_FILE, 'r');
506 $words=fread($fp, filesize($SQSPELL_WORDS_FILE));
507 fclose($fp);
508 }
509 /**
510 * Check if this is an encrypted file by looking for
511 * the string "# SquirrelSpell" in it (the crypto
512 * function does that).
513 */
514 if ($words && !strstr($words, "# SquirrelSpell")){
515 /**
516 * This file is encrypted or mangled. Try to decrypt it.
517 * If fails, complain loudly.
518 *
519 * $old_key would be a value submitted by one of the modules with
520 * the user's old mailbox password. I admin, this is rather dirty,
521 * but efficient. ;)
522 */
b587ac51 523 sqgetGlobalVar('key', $key, SQ_COOKIE);
524 sqgetGlobalVar('onetimepad', $onetimepad, SQ_SESSION);
525
526 sqgetGlobalVar('old_key', $old_key, SQ_POST);
8a9f9d09 527
528 if ($old_key != '') {
529 $clear_key=$old_key;
d112ed5a 530 } else {
531 /**
532 * Get user's password (the key).
533 */
534 $clear_key = OneTimePadDecrypt($key, $onetimepad);
9804bcde 535 }
d112ed5a 536 /**
537 * Invoke the decryption routines.
538 */
7996c920 539 $words=sqspell_crypto_old("decrypt", $clear_key, $words);
d112ed5a 540 /**
541 * See if decryption failed.
542 */
543 if ($words=="PANIC"){
7996c920 544 sqspell_handle_crypt_panic();
545 // script execution stops here.
d112ed5a 546 } else {
547 /**
91e0dccc 548 * OK! Phew. Set the encryption flag to true so we can later on
d112ed5a 549 * encrypt it again before saving to HDD.
550 */
551 $SQSPELL_CRYPTO=true;
9804bcde 552 }
d112ed5a 553 } else {
554 /**
91e0dccc 555 * No encryption is/was used. Set $SQSPELL_CRYPTO to false,
d112ed5a 556 * in case we have to save the dictionary later.
557 */
558 $SQSPELL_CRYPTO=false;
559 }
560 /**
561 * Check if we need to upgrade the dictionary from version 0.2.x
562 * This is going away soon.
563 */
564 if (strstr($words, "Dictionary v0.2")){
565 $words=sqspell_upgradeWordsFile($words);
566 }
567 return $words;
568}
91e0dccc 569
7996c920 570/**
571 * Saves user's dictionary
572 * Function was replaced in 1.5.1 (sqspell 0.5).
573 * Older function is suffixed with '_old'
574 * @param array $words words that should be stored in dictionary
575 * @param string $lang language
576 */
577function sqspell_writeWords($words,$lang){
578 global $SQSPELL_CRYPTO,$username,$data_dir;
579
580 $sWords = implode(',',$words);
581 if ($SQSPELL_CRYPTO){
582 /**
583 * User wants to encrypt the file. So be it.
584 * Get the user's password to use as a key.
585 */
586 sqgetGlobalVar('key', $key, SQ_COOKIE);
587 sqgetGlobalVar('onetimepad', $onetimepad, SQ_SESSION);
588
589 $clear_key=OneTimePadDecrypt($key, $onetimepad);
590 /**
591 * Try encrypting it. If fails, scream bloody hell.
592 */
593 $save_words = sqspell_crypto("encrypt", $clear_key, $sWords);
594 if ($save_words == 'PANIC'){
595 // FIXME: handle errors here
596
597 }
598 $save_words='{crypt}'.$save_words;
599 } else {
600 $save_words=$sWords;
601 }
602 setPref($data_dir,$username,'sqspell_dict_'.$lang,$save_words);
603}
604
d112ed5a 605/**
606 * Writes user dictionary into the $username.words file, then changes mask
607 * to 0600. If encryption is needed -- does that, too.
608 *
609 * @param $words The contents of the ".words" file to write.
610 * @return void
7996c920 611 * @since 1.5.1 (sqspell 0.5)
612 * @deprecated
d112ed5a 613 */
7996c920 614function sqspell_writeWords_old($words){
d112ed5a 615 global $SQSPELL_WORDS_FILE, $SQSPELL_CRYPTO;
616 /**
617 * if $words is empty, create a template entry by calling the
618 * sqspell_makeDummy() function.
619 */
620 if (!$words){
621 $words=sqspell_makeDummy();
622 }
623 if ($SQSPELL_CRYPTO){
624 /**
625 * User wants to encrypt the file. So be it.
626 * Get the user's password to use as a key.
627 */
b587ac51 628 sqgetGlobalVar('key', $key, SQ_COOKIE);
629 sqgetGlobalVar('onetimepad', $onetimepad, SQ_SESSION);
8a9f9d09 630
d112ed5a 631 $clear_key=OneTimePadDecrypt($key, $onetimepad);
632 /**
633 * Try encrypting it. If fails, scream bloody hell.
634 */
635 $save_words = sqspell_crypto("encrypt", $clear_key, $words);
636 if ($save_words == 'PANIC'){
637 /**
638 * AAAAAAAAH! I'm not handling this yet, since obviously
639 * the admin of the site forgot to compile the MCRYPT support in
640 * when upgrading an existing PHP installation.
641 * I will add a handler for this case later, when I can come up
642 * with some work-around... Right now, do nothing. Let the Admin's
643 * head hurt.. ;)))
644 */
7996c920 645 /** save some hairs on admin's head and store error message in logs */
646 error_log('SquirrelSpell: php does not have mcrypt support');
9804bcde 647 }
d112ed5a 648 } else {
649 $save_words = $words;
650 }
651 /**
652 * Do the actual writing.
653 */
654 $fp=fopen($SQSPELL_WORDS_FILE, "w");
655 fwrite($fp, $save_words);
656 fclose($fp);
657 chmod($SQSPELL_WORDS_FILE, 0600);
658}
91e0dccc 659
7996c920 660/**
661 * Deletes user's dictionary
662 * Function was modified in 1.5.1 (sqspell 0.5). Older function is suffixed
663 * with '_old'
664 * @param string $lang dictionary
665 */
666function sqspell_deleteWords($lang) {
667 global $data_dir, $username;
668 removePref($data_dir,$username,'sqspell_dict_'.$lang);
669}
670
671/**
672 * Deletes user's dictionary when it is corrupted.
673 * @since 1.5.1 (sqspell 0.5)
674 * @deprecated
675 */
676function sqspell_deleteWords_old(){
d112ed5a 677 /**
678 * So I open the door to my enemies,
679 * and I ask can we wipe the slate clean,
680 * but they tell me to please go...
681 * uhm... Well, this just erases the user dictionary file.
682 */
683 global $SQSPELL_WORDS_FILE;
684 if (file_exists($SQSPELL_WORDS_FILE)){
685 unlink($SQSPELL_WORDS_FILE);
686 }
687}
688/**
689 * Creates an empty user dictionary for the sake of saving prefs or
690 * whatever.
691 *
692 * @return The template to use when storing the user dictionary.
7996c920 693 * @deprecated
91e0dccc 694 */
d112ed5a 695function sqspell_makeDummy(){
696 global $SQSPELL_VERSION, $SQSPELL_APP_DEFAULT;
697 $words = "# SquirrelSpell User Dictionary $SQSPELL_VERSION\n"
91e0dccc 698 . "# Last Revision: " . date('Y-m-d')
699 . "\n# LANG: $SQSPELL_APP_DEFAULT\n# End\n";
d112ed5a 700 return $words;
701}
702
703/**
704 * This function checks for security attacks. A $MOD variable is
705 * provided in the QUERY_STRING and includes one of the files from the
706 * modules directory ($MOD.mod). See if someone is trying to get out
707 * of the modules directory by providing dots, unicode strings, or
708 * slashes.
709 *
7996c920 710 * @param string $rMOD the name of the module requested to include.
711 * @return void, since it bails out with an access error if needed.
d112ed5a 712 */
713function sqspell_ckMOD($rMOD){
91e0dccc 714 if (strstr($rMOD, '.')
715 || strstr($rMOD, '/')
d112ed5a 716 || strstr($rMOD, '%')
91e0dccc 717 || strstr($rMOD, "\\")){
d112ed5a 718 echo _("Cute.");
719 exit;
720 }
721}
722
7996c920 723/**
724 * Used to check internal version of SquirrelSpell dictionary
725 * @param integer $major main version number
726 * @param integer $minor second version number
727 * @return boolean true if stored dictionary version is $major.$minor or newer
728 * @since 1.5.1 (sqspell 0.5)
729 */
730function sqspell_check_version($major,$minor) {
731 global $data_dir, $username;
732 // 0.4 version is internal version number that is used to indicate upgrade from
733 // separate files to generic SquirrelMail prefs storage.
734 $sqspell_version=getPref($data_dir,$username,'sqspell_version','0.4');
735
736 $aVersion=explode('.',$sqspell_version);
737
738 if ($aVersion[0] < $major ||
739 ( $aVersion[0] == $major && $aVersion[1] < $minor)) {
740 return false;
741 }
742 return true;
743}
744
745/**
746 * Displays form that allows to enter different password for dictionary decryption.
747 * If language is not set, function provides form to handle older dictionary files.
748 * @param string $lang language
749 * @since 1.5.1 (sqspell 0.5)
750 */
751function sqspell_handle_crypt_panic($lang=false) {
752 if (! sqgetGlobalVar('SCRIPT_NAME',$SCRIPT_NAME,SQ_SERVER))
753 $SCRIPT_NAME='';
754
755 /**
756 * AAAAAAAAAAAH!!!!! OK, ok, breathe!
757 * Let's hope the decryption failed because the user changed his
758 * password. Bring up the option to key in the old password
759 * or wipe the file and start over if everything else fails.
760 *
761 * The _("SquirrelSpell...) line has to be on one line, otherwise
762 * gettext will bork. ;(
763 */
764 $msg = html_tag( 'p', "\n" .
765 '<strong>' . _("ATTENTION:") . '</strong><br />'
766 . _("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.") ,
767 'left' ) . "\n"
768 . (($lang) ? html_tag('p',sprintf(_("Your %s dictionary is encrypted with password that differs from your current password."),
769 htmlspecialchars($lang)),'left') : '')
770 . '<blockquote>' . "\n"
771 . '<form method="post" onsubmit="return AYS()">' . "\n"
772 . '<input type="hidden" name="MOD" value="crypto_badkey" />' . "\n"
773 . (($lang) ?
774 '<input type="hidden" name="dict_lang" value="'.htmlspecialchars($lang).'" />' :
775 '<input type="hidden" name="old_setup" value="yes" />')
776 . html_tag( 'p', "\n" .
777 '<input type="checkbox" name="delete_words" value="ON" />'
778 . _("Delete my dictionary and start a new one") . '<br />'
779 . _("Decrypt my dictionary with my old password:")
780 . '<input name="old_key" size="10" />' ,
781 'left' ) . "\n"
782 . '</blockquote>' . "\n"
783 . html_tag( 'p', "\n"
784 . '<input type="submit" value="'
785 . _("Proceed") . ' &gt;&gt;" />' ,
786 'center' ) . "\n"
787 . '</form>' . "\n";
788 /**
789 * Add some string vars so they can be i18n'd.
790 */
791 $msg .= "<script type='text/javascript'><!--\n"
792 . "var ui_choice = \"" . _("You must make a choice") ."\";\n"
793 . "var ui_candel = \"" . _("You can either delete your dictionary or type in the old password. Not both.") . "\";\n"
794 . "var ui_willdel = \"" . _("This will delete your personal dictionary file. Proceed?") . "\";\n"
795 . "//--></script>\n";
796 /**
797 * See if this happened in the pop-up window or when accessing
798 * the SpellChecker options page.
799 * This is a dirty solution, I agree.
800 * TODO: make this prettier.
801 */
802 if (strstr($SCRIPT_NAME, "sqspell_options")){
803 sqspell_makePage(_("Error Decrypting Dictionary"),
804 "decrypt_error.js", $msg);
805 } else {
806 sqspell_makeWindow(null, _("Error Decrypting Dictionary"),
807 "decrypt_error.js", $msg);
808 }
809 exit;
810}
811
d112ed5a 812/**
813 * SquirrelSpell version. Don't modify, since it identifies the format
91e0dccc 814 * of the user dictionary files and messing with this can do ugly
d112ed5a 815 * stuff. :)
7996c920 816 * @global string $SQSPELL_VERSION
817 * @deprecated
d112ed5a 818 */
d88c744e 819$SQSPELL_VERSION="v0.3.8";
04fa3c41 820?>