cceb0b20c73d181e4f8acbba6ca8a9f2c864ae38
[squirrelmail.git] / plugins / administrator / options.php
1 <?php
2
3 /**
4 * Administrator Plugin
5 *
6 * Copyright (c) 1999-2003 The SquirrelMail Project Team
7 * Licensed under the GNU GPL. For full terms see the file COPYING.
8 *
9 * Philippe Mingo
10 *
11 * $Id$
12 */
13
14 function parseConfig( $cfg_file ) {
15
16 global $newcfg;
17
18 $cfg = file( $cfg_file );
19 $mode = '';
20 $l = count( $cfg );
21 $modifier = FALSE;
22
23 for ($i=0;$i<$l;$i++) {
24 $line = trim( $cfg[$i] );
25 $s = strlen( $line );
26 for ($j=0;$j<$s;$j++) {
27 switch ( $mode ) {
28 case '=':
29 if ( $line{$j} == '=' ) {
30 // Ok, we've got a right value, lets detect what type
31 $mode = 'D';
32 } else if ( $line{$j} == ';' ) {
33 // hu! end of command
34 $key = $mode = '';
35 }
36 break;
37 case 'K':
38 // Key detect
39 if( $line{$j} == ' ' ) {
40 $mode = '=';
41 } else {
42 $key .= $line{$j};
43 }
44 break;
45 case ';':
46 // Skip until next ;
47 if ( $line{$j} == ';' ) {
48 $mode = '';
49 }
50 break;
51 case 'S':
52 if ( $line{$j} == '\\' ) {
53 $value .= $line{$j};
54 $modifier = TRUE;
55 } else if ( $line{$j} == $delimiter && $modifier === FALSE ) {
56 // End of string;
57 $newcfg[$key] = $value . $delimiter;
58 $key = $value = '';
59 $mode = ';';
60 } else {
61 $value .= $line{$j};
62 $modifier = FALSE;
63 }
64 break;
65 case 'N':
66 if ( $line{$j} == ';' ) {
67 $newcfg{$key} = $value;
68 $key = $mode = '';
69 } else {
70 $value .= $line{$j};
71 }
72 break;
73 case 'C':
74 // Comments
75 if ( $s > $j + 1 &&
76 $line{$j}.$line{$j+1} == '*/' ) {
77 $mode = '';
78 $j++;
79 }
80 break;
81 case 'D':
82 // Delimiter detect
83 switch ( $line{$j} ) {
84 case '"':
85 case "'":
86 // Double quote string
87 $delimiter = $value = $line{$j};
88 $mode = 'S';
89 break;
90 case ' ':
91 // Nothing yet
92 break;
93 default:
94 if ( strtoupper( substr( $line, $j, 4 ) ) == 'TRUE' ) {
95 // Boolean TRUE
96 $newcfg{$key} = 'TRUE';
97 $key = '';
98 $mode = ';';
99 } else if ( strtoupper( substr( $line, $j, 5 ) ) == 'FALSE' ) {
100 $newcfg{$key} = 'FALSE';
101 $key = '';
102 $mode = ';';
103 } else {
104 // Number or function call
105 $mode = 'N';
106 $value = $line{$j};
107 }
108 }
109 break;
110 default:
111 if ( $line{$j} == '$' ) {
112 // We must detect $key name
113 $mode = 'K';
114 $key = '$';
115 } else if ( $s < $j + 2 ) {
116 } else if ( strtoupper( substr( $line, $j, 7 ) ) == 'GLOBAL ' ) {
117 // Skip untill next ;
118 $mode = ';';
119 $j += 6;
120 } else if ( $line{$j}.$line{$j+1} == '/*' ) {
121 $mode = 'C';
122 $j++;
123 } else if ( $line{$j} == '#' || $line{$j}.$line{$j+1} == '//' ) {
124 // Delete till the end of the line
125 $j = $s;
126 }
127 }
128 }
129 }
130 }
131
132 /* Change paths containing SM_PATH to admin-friendly paths
133 relative to the config dir, i.e.:
134 '' --> <empty string>
135 SM_PATH . 'images/logo.gif' --> ../images/logo.gif
136 '/absolute/path/logo.gif' --> /absolute/path/logo.gif
137 'http://whatever/' --> http://whatever
138 Note removal of quotes in returned value
139 */
140 function change_to_rel_path($old_path) {
141 $new_path = str_replace("SM_PATH . '", "../", $old_path);
142 $new_path = str_replace("../config/","", $new_path);
143 $new_path = str_replace("'","", $new_path);
144 return $new_path;
145 }
146
147 /* Change relative path (relative to config dir) to
148 internal SM_PATH, i.e.:
149 empty_string --> ''
150 ../images/logo.gif --> SM_PATH . 'images/logo.gif'
151 images/logo.gif --> SM_PATH . 'config/images/logo.gif'
152 /absolute/path/logo.gif --> '/absolute/path/logo.gif'
153 http://whatever/ --> 'http://whatever'
154 */
155 function change_to_sm_path($old_path) {
156 if ( $old_path === '' || $old_path == "''" ) {
157 return "''";
158 } elseif ( preg_match("/^(\/|http)/", $old_path) ) {
159 return "'" . $old_path . "'";
160 } elseif ( preg_match("/^(\$|SM_PATH)/", $old_path) ) {
161 return $old_path;
162 }
163
164 $new_path = '';
165 $rel_path = explode("../", $old_path);
166 if ( count($rel_path) > 2 ) {
167 // Since we're relative to the config dir,
168 // more than 1 ../ puts us OUTSIDE the SM tree.
169 // get full path to config.php, then pop the filename
170 $abs_path = explode('/', realpath (SM_PATH . 'config/config.php'));
171 array_pop ($abs_path);
172 foreach ( $rel_path as $subdir ) {
173 if ( $subdir === '' ) {
174 array_pop ($abs_path);
175 } else {
176 array_push($abs_path, $subdir);
177 }
178 }
179 foreach ($abs_path as $subdir) {
180 $new_path .= $subdir . '/';
181 }
182 $new_path = "'$new_path'";
183 } elseif ( count($rel_path) > 1 ) {
184 // we're within the SM tree, prepend SM_PATH
185 $new_path = str_replace('../',"SM_PATH . '", $old_path . "'");
186 } else {
187 // Last, if it's a relative path without a .. prefix,
188 // we're somewhere within the config dir, so prepend
189 // SM_PATH . 'config/
190 $new_path = "SM_PATH . 'config/" . $old_path . "'";
191 }
192 return $new_path;
193 }
194
195
196 /* ---------------------- main -------------------------- */
197
198 define('SM_PATH','../../');
199
200 /* SquirrelMail required files. */
201 require_once(SM_PATH . 'include/validate.php');
202 require_once(SM_PATH . 'functions/page_header.php');
203 require_once(SM_PATH . 'functions/imap.php');
204 require_once(SM_PATH . 'include/load_prefs.php');
205 require_once(SM_PATH . 'plugins/administrator/defines.php');
206 require_once(SM_PATH . 'plugins/administrator/auth.php');
207
208 GLOBAL $data_dir, $username;
209
210 if ( !adm_check_user() ) {
211 header('Location: ' . SM_PATH . 'src/options.php') ;
212 exit;
213 }
214
215 displayPageHeader($color, 'None');
216
217 $newcfg = array( );
218
219 foreach ( $defcfg as $key => $def ) {
220 $newcfg[$key] = '';
221 }
222
223 $cfgfile = SM_PATH . 'config/config.php';
224 parseConfig( SM_PATH . 'config/config_default.php' );
225 parseConfig( $cfgfile );
226
227 $colapse = array( 'Titles' => 'off',
228 'Group1' => getPref($data_dir, $username, 'adm_Group1', 'off' ),
229 'Group2' => getPref($data_dir, $username, 'adm_Group2', 'on' ),
230 'Group3' => getPref($data_dir, $username, 'adm_Group3', 'on' ),
231 'Group4' => getPref($data_dir, $username, 'adm_Group4', 'on' ),
232 'Group5' => getPref($data_dir, $username, 'adm_Group5', 'on' ),
233 'Group6' => getPref($data_dir, $username, 'adm_Group6', 'on' ),
234 'Group7' => getPref($data_dir, $username, 'adm_Group7', 'on' ),
235 'Group8' => getPref($data_dir, $username, 'adm_Group8', 'on' ) );
236
237 /* look in $_GET array for 'switch' */
238 if ( sqgetGlobalVar('switch', $switch, SQ_GET) ) {
239 if ( $colapse[$switch] == 'on' ) {
240 $colapse[$switch] = 'off';
241 } else {
242 $colapse[$switch] = 'on';
243 }
244 setPref($data_dir, $username, "adm_$switch", $colapse[$switch] );
245 }
246
247 echo "<form action=options.php method=post name=options>" .
248 "<center><table width=95% bgcolor=\"$color[5]\"><tr><td>".
249 "<table width=100% cellspacing=0 bgcolor=\"$color[4]\">" ,
250 "<tr bgcolor=\"$color[5]\"><th colspan=2>" . _("Configuration Administrator") . "</th></tr>",
251 "<tr bgcolor=\"$color[5]\"><td colspan=2i align=\"center\">";
252 ?>
253 <small>Note: it is recommended that you configure your system using conf.pl, and not this plugin.
254 conf.pl contains additional information regarding the purpose of variables and
255 appropriate values, as well as additional verification steps.<br />
256 Run or consult conf.pl should you run into difficulty with your configuration.</small>
257 </td></tr>
258 <?php
259
260 $act_grp = 'Titles'; /* Active group */
261
262 foreach ( $newcfg as $k => $v ) {
263 $l = strtolower( $v );
264 $type = SMOPT_TYPE_UNDEFINED;
265 $n = substr( $k, 1 );
266 $n = str_replace( '[', '_', $n );
267 $n = str_replace( ']', '_', $n );
268 $e = 'adm_' . $n;
269 $name = $k;
270 $size = 50;
271 if ( isset( $defcfg[$k] ) ) {
272 $name = $defcfg[$k]['name'];
273 $type = $defcfg[$k]['type'];
274 if ( isset( $defcfg[$k]['size'] ) ) {
275 $size = $defcfg[$k]['size'];
276 } else {
277 $size = 40;
278 }
279 } else if ( $l == 'true' ) {
280 $v = 'TRUE';
281 $type = SMOPT_TYPE_BOOLEAN;
282 } else if ( $l == 'false' ) {
283 $v = 'FALSE';
284 $type = SMOPT_TYPE_BOOLEAN;
285 } else if ( $v{0} == "'" ) {
286 $type = SMOPT_TYPE_STRING;
287 } else if ( $v{0} == '"' ) {
288 $type = SMOPT_TYPE_STRING;
289 }
290
291 if ( substr( $k, 0, 7 ) == '$theme[' ) {
292 $type = SMOPT_TYPE_THEME;
293 } else if ( substr( $k, 0, 9 ) == '$plugins[' ) {
294 $type = SMOPT_TYPE_PLUGINS;
295 } else if ( substr( $k, 0, 13 ) == '$ldap_server[' ) {
296 $type = SMOPT_TYPE_LDAP;
297 }
298
299 if( $type == SMOPT_TYPE_TITLE || $colapse[$act_grp] == 'off' ) {
300
301 switch ( $type ) {
302 case SMOPT_TYPE_LDAP:
303 case SMOPT_TYPE_PLUGINS:
304 case SMOPT_TYPE_THEME:
305 case SMOPT_TYPE_HIDDEN:
306 break;
307 case SMOPT_TYPE_EXTERNAL:
308 echo "<tr><td>$name</td><td><b>" .
309 $defcfg[$k]['value'] .
310 "</b></td></tr>";
311 break;
312 case SMOPT_TYPE_TITLE:
313 if ( $colapse[$k] == 'on' ) {
314 $sw = '(+)';
315 } else {
316 $sw = '(-)';
317 }
318 echo "<tr bgcolor=\"$color[0]\"><th colspan=2>" .
319 "<a href=options.php?switch=$k STYLE=\"text-decoration:none\"><b>$sw</b> </a>" .
320 "$name</th></tr>";
321 $act_grp = $k;
322 break;
323 case SMOPT_TYPE_COMMENT:
324 $v = substr( $v, 1, strlen( $v ) - 2 );
325 echo "<tr><td>$name</td><td>".
326 "<b>$v</b>";
327 $newcfg[$k] = "'$v'";
328 if ( isset( $defcfg[$k]['comment'] ) ) {
329 echo ' &nbsp; ' . $defcfg[$k]['comment'];
330 }
331 echo "</td></tr>\n";
332 break;
333 case SMOPT_TYPE_INTEGER:
334 /* look for variable $e in POST, fill into $v */
335 if ( sqgetGlobalVar($e, $v, SQ_POST) ) {
336 $v = intval( $v );
337 $newcfg[$k] = $v;
338 }
339 echo "<tr><td>$name</td><td>".
340 "<input size=10 name=\"adm_$n\" value=\"$v\">";
341 if ( isset( $defcfg[$k]['comment'] ) ) {
342 echo ' &nbsp; ' . $defcfg[$k]['comment'];
343 }
344 echo "</td></tr>\n";
345 break;
346 case SMOPT_TYPE_NUMLIST:
347 if ( sqgetGlobalVar($e, $v, SQ_POST) ) {
348 $newcfg[$k] = $v;
349 }
350 echo "<tr><td>$name</td><td>";
351 echo "<select name=\"adm_$n\">";
352 foreach ( $defcfg[$k]['posvals'] as $kp => $vp ) {
353 echo "<option value=\"$kp\"";
354 if ( $kp == $v ) {
355 echo ' selected';
356 }
357 echo ">$vp</option>";
358 }
359 echo '</select>';
360 if ( isset( $defcfg[$k]['comment'] ) ) {
361 echo ' &nbsp; ' . $defcfg[$k]['comment'];
362 }
363 echo "</td></tr>\n";
364 break;
365 case SMOPT_TYPE_STRLIST:
366 if ( sqgetGlobalVar($e, $v, SQ_POST) ) {
367 $v = '"' . $v . '"';
368 $newcfg[$k] = $v;
369 }
370 echo "<tr><td>$name</td><td>".
371 "<select name=\"adm_$n\">";
372 foreach ( $defcfg[$k]['posvals'] as $kp => $vp ) {
373 echo "<option value=\"$kp\"";
374 if ( $kp == substr( $v, 1, strlen( $v ) - 2 ) ) {
375 echo ' selected';
376 }
377 echo ">$vp</option>";
378 }
379 echo '</select>';
380 if ( isset( $defcfg[$k]['comment'] ) ) {
381 echo ' &nbsp; ' . $defcfg[$k]['comment'];
382 }
383 echo "</td></tr>\n";
384 break;
385
386 case SMOPT_TYPE_TEXTAREA:
387 if ( sqgetGlobalVar($e, $v, SQ_POST) ) {
388 $v = '"' . $v . '"';
389 $newcfg[$k] = str_replace( "\n", '', $v );
390 }
391 echo "<tr><td valign=top>$name</td><td>".
392 "<textarea cols=\"$size\" name=\"adm_$n\">" . substr( $v, 1, strlen( $v ) - 2 ) . "</textarea>";
393 if ( isset( $defcfg[$k]['comment'] ) ) {
394 echo ' &nbsp; ' . $defcfg[$k]['comment'];
395 }
396 echo "</td></tr>\n";
397 break;
398 case SMOPT_TYPE_STRING:
399 if ( sqgetGlobalVar($e, $v, SQ_POST) ) {
400 $v = '"' . $v . '"';
401 $newcfg[$k] = $v;
402 }
403 if ( $v == '""' && isset( $defcfg[$k]['default'] ) ) {
404 $v = "'" . $defcfg[$k]['default'] . "'";
405 $newcfg[$k] = $v;
406 }
407 echo "<tr><td>$name</td><td>".
408 "<input size=\"$size\" name=\"adm_$n\" value=\"" . substr( $v, 1, strlen( $v ) - 2 ) . "\">";
409 if ( isset( $defcfg[$k]['comment'] ) ) {
410 echo ' &nbsp; ' . $defcfg[$k]['comment'];
411 }
412 echo "</td></tr>\n";
413 break;
414 case SMOPT_TYPE_BOOLEAN:
415 if ( sqgetGlobalVar($e, $v, SQ_POST) ) {
416 $newcfg[$k] = $v;
417 } else {
418 $v = strtoupper( $v );
419 }
420 if ( $v == 'TRUE' ) {
421 $ct = ' checked';
422 $cf = '';
423 } else {
424 $ct = '';
425 $cf = ' checked';
426 }
427 echo "<tr><td>$name</td><td>" .
428 "<INPUT$ct type=radio NAME=\"adm_$n\" value=\"TRUE\">" . _("Yes") .
429 "<INPUT$cf type=radio NAME=\"adm_$n\" value=\"FALSE\">" . _("No");
430 if ( isset( $defcfg[$k]['comment'] ) ) {
431 echo ' &nbsp; ' . $defcfg[$k]['comment'];
432 }
433 echo "</td></tr>\n";
434 break;
435 case SMOPT_TYPE_PATH:
436 if ( sqgetGlobalVar($e, $v, SQ_POST) ) {
437 $v = change_to_sm_path($v);
438 $newcfg[$k] = $v;
439 }
440 if ( $v == "''" && isset( $defcfg[$k]['default'] ) ) {
441 $v = change_to_sm_path($defcfg[$k]['default']);
442 $newcfg[$k] = $v;
443 }
444 echo "<tr><td>$name</td><td>".
445 "<input size=\"$size\" name=\"adm_$n\" value=\"" . change_to_rel_path($v) . "\">";
446 if ( isset( $defcfg[$k]['comment'] ) ) {
447 echo ' &nbsp; ' . $defcfg[$k]['comment'];
448 }
449 echo "</td></tr>\n";
450 break;
451 default:
452 echo "<tr><td>$name</td><td>" .
453 "<b><i>$v</i></b>";
454 if ( isset( $defcfg[$k]['comment'] ) ) {
455 echo ' &nbsp; ' . $defcfg[$k]['comment'];
456 }
457 echo "</td></tr>\n";
458 }
459 }
460 }
461
462 /* Special Themes Block */
463 if ( $colapse['Group7'] == 'off' ) {
464 $i = 0;
465 echo '<tr><th>' . _("Theme Name") .
466 '</th><th>' . _("Theme Path") .
467 '</th></tr>';
468 while ( isset( $newcfg["\$theme[$i]['NAME']"] ) ) {
469 $k1 = "\$theme[$i]['NAME']";
470 $e1 = "theme_name_$i";
471 if ( sqgetGlobalVar($e, $v1, SQ_POST) ) {
472 $v1 = '"' . str_replace( '\"', '"', $v1 ) . '"';
473 $v1 = '"' . str_replace( '"', '\"', $v1 ) . '"';
474 $newcfg[$k1] = $v1;
475 } else {
476 $v1 = $newcfg[$k1];
477 }
478 $k2 = "\$theme[$i]['PATH']";
479 $e2 = "theme_path_$i";
480 if ( sqgetGlobalVar($e, $v2, SQ_POST) ) {
481 $v2 = change_to_sm_path($v2);
482 $newcfg[$k2] = $v2;
483 } else {
484 $v2 = $newcfg[$k2];
485 }
486 $name = substr( $v1, 1, strlen( $v1 ) - 2 );
487 $path = change_to_rel_path($v2);
488 echo '<tr>'.
489 "<td align=right>$i. <input name=\"$e1\" value=\"$name\" size=30></td>".
490 "<td><input name=\"$e2\" value=\"$path\" size=40></td>".
491 "</tr>\n";
492 $i++;
493
494 }
495 }
496
497 /* Special Plugins Block */
498 if ( $colapse['Group8'] == 'on' ) {
499 $sw = '(+)';
500 } else {
501 $sw = '(-)';
502 }
503 echo "<tr bgcolor=\"$color[0]\"><th colspan=2>" .
504 "<a href=options.php?switch=Group8 STYLE=\"text-decoration:none\"><b>$sw</b> </a>" .
505 _("Plugins") . '</th></tr>';
506
507 if( $colapse['Group8'] == 'off' ) {
508
509 $plugpath = SM_PATH . 'plugins/';
510 if ( file_exists($plugpath) ) {
511 $fd = opendir( $plugpath );
512 $op_plugin = array();
513 $p_count = 0;
514 while (false !== ($file = readdir($fd))) {
515 if ($file != '.' && $file != '..' && $file != 'CVS' && is_dir($plugpath . $file) ) {
516 $op_plugin[] = $file;
517 $p_count++;
518 }
519 }
520 closedir($fd);
521 asort( $op_plugin );
522
523 /* Lets get the plugins that are active */
524 $plugins = array();
525 if ( sqgetGlobalVar('plg', $v, SQ_POST) ) {
526 foreach ( $op_plugin as $plg ) {
527 if ( sqgetGlobalVar("plgs_$plg", $v, SQ_POST) && $v == 'on' ) {
528 $plugins[] = $plg;
529 }
530 }
531 $i = 0;
532 foreach ( $plugins as $plg ) {
533 $k = "\$plugins[$i]";
534 $newcfg[$k] = "'$plg'";
535 $i++;
536 }
537 while ( isset( $newcfg["\$plugins[$i]"] ) ) {
538 $k = "\$plugins[$i]";
539 $newcfg[$k] = '';
540 $i++;
541 }
542 } else {
543 $i = 0;
544 while ( isset( $newcfg["\$plugins[$i]"] ) ) {
545 $k = "\$plugins[$i]";
546 $v = $newcfg[$k];
547 $plugins[] = substr( $v, 1, strlen( $v ) - 2 );
548 $i++;
549 }
550 }
551 echo "<tr><td colspan=2><input type=hidden name=plg value=on><center><table><tr><td>";
552 foreach ( $op_plugin as $plg ) {
553 if ( in_array( $plg, $plugins ) ) {
554 $sw = ' checked';
555 } else {
556 $sw = '';
557 }
558 echo '<tr>' .
559 "<td>$plg</td><td><input$sw type=checkbox name=plgs_$plg></td>".
560 "</tr>\n";
561 }
562 echo '</td></tr></table></td></tr>';
563 } else {
564 echo '<tr><td colspan=2 align="center">Plugin directory could not be found: ' . $plugpath . "</td></tr>\n";
565 }
566 }
567 echo "<tr bgcolor=\"$color[5]\"><th colspan=2><input value=\"" .
568 _("Change Settings") . "\" type=submit></th></tr>" ,
569 '</table></td></tr></table></form>';
570
571 /*
572 Write the options to the file.
573 */
574
575 if( $fp = @fopen( $cfgfile, 'w' ) ) {
576 fwrite( $fp, "<?PHP\n".
577 "/**\n".
578 " * SquirrelMail Configuration File\n".
579 " * Created using the Administrator Plugin\n".
580 " */\n" );
581
582 foreach ( $newcfg as $k => $v ) {
583 if ( $k{0} == '$' && $v <> '' ) {
584 if ( substr( $k, 1, 11 ) == 'ldap_server' ) {
585 $v = substr( $v, 0, strlen( $v ) - 1 ) . "\n)";
586 $v = str_replace( 'array(', "array(\n\t", $v );
587 $v = str_replace( "',", "',\n\t", $v );
588 }
589 fwrite( $fp, "$k = $v;\n" );
590 }
591 }
592 fwrite( $fp, '?>' );
593 fclose( $fp );
594 } else {
595 echo '<font size=+1><br>'.
596 _("Config file can't be opened. Please check config.php.").
597 '</font>';
598 }
599 ?>