1 <?php printf("<?xml version=\"1.0\" encoding=\"%s\"?>\n", 'iso-8859-1'); ?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4 <html xmlns="http://www.w3.org/1999/xhtml">
6 <!-- $Id: configurator.php,v 1.2 2002-02-25 18:14:11 carstenklapp Exp $ -->
8 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
12 <h1>Configuration tool for PhpWiki 1.3.x</h1>
14 <p>This tool is provided for testing purposes only. It's not finished so don't try to use it to configure your server yet.</p>
18 * The Configurator is a php script to aid in the configuration of PhpWiki.
19 * Parts of this file are based on PHPWeather's configurator.php file.
20 * http://sourceforge.net/projects/phpweather/
22 * TO CHANGE THE CONFIGURATION OF YOUR PHPWIKI, DO *NOT* MODIFY THIS FILE!
23 * more instructions go here
25 * An index.php will be generated for you which you can also modify later if you wish.
29 //////////////////////////////
30 // begin configuration options
35 Copyright 1999, 2000, 2001, 2002 $ThePhpWikiProgrammingTeam = array(
36 "Steve Wainstead", "Clifford A. Adams", "Lawrence Akka",
37 "Scott R. Anderson", "Jon Åslund", "Neil Brown", "Jeff Dairiki",
38 "Stéphane Gourichon", "Jan Hidders", "Arno Hollosi", "John Jorgensen",
39 "Antti Kaihola", "Jeremie Kass", "Carsten Klapp", "Marco Milanesi",
40 "Grant Morgan", "Jan Nieuwenhuizen", "Aredridel Niothke",
41 "Pablo Roca Rozas", "Sandino Araico Sánchez", "Joel Uckelman",
42 "Reini Urban", "Tim Voght");
44 This file is part of PhpWiki.
46 PhpWiki is free software; you can redistribute it and/or modify
47 it under the terms of the GNU General Public License as published by
48 the Free Software Foundation; either version 2 of the License, or
49 (at your option) any later version.
51 PhpWiki is distributed in the hope that it will be useful,
52 but WITHOUT ANY WARRANTY; without even the implied warranty of
53 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
54 GNU General Public License for more details.
56 You should have received a copy of the GNU General Public License
57 along with PhpWiki; if not, write to the Free Software
58 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
64 This is the starting file for PhpWiki. All this file does is set
65 configuration options, and at the end of the file it includes() the
66 file lib/main.php, where the real action begins.
68 This file is divided into six parts: Parts Zero, One, Two, Three,
69 Four and Five. Each one has different configuration settings you can
70 change; in all cases the default should work on your system,
71 however, we recommend you tailor things to your particular setting.
76 $properties['Part Zero'] =
77 new part('part0', false, '
78 Part Zero: If PHP needs help in finding where you installed the
79 rest of the PhpWiki code, you can set the include_path here.');
83 $properties['PHP include_path'] =
84 new iniset('include_path', "\$include_path", "
85 NOTE: phpwiki uses the PEAR library of php code for SQL database
86 access. Your PHP is probably already configured to set
87 include_path so that PHP can find the pear code. If not (or if you
88 change include_path here) make sure you include the path to the
89 PEAR code in include_path. (To find the PEAR code on your system,
90 search for a file named 'PEAR.php'. Some common locations are:
98 The above examples are already included by PhpWiki. You shouldn't
99 have to change this unless you see a WikiFatalError:
101 lib/FileFinder.php:82: Fatal[256]: DB.php: file not found
103 Define the include path for this wiki: pear plus the phpwiki path
105 $include_path = '.:/Apache/php/pear:/prog/php/phpwiki';
107 Windows needs ';' as path delimiter. cygwin, mac and unix ':'
109 if (substr(PHP_OS,0,3) == 'WIN') {
110 $include_path = implode(';',explode(':',$include_path));
111 } elseif (substr(PHP_OS,0,6) == 'CYGWIN') {
112 $include_path = '.:/usr/local/lib/php/pear:/usr/src/php/phpwiki';
119 $properties['Part Null'] =
120 new part('partnullheader', "", "
121 Part Null: Don't touch this!");
125 $properties['Part Null Settings'] =
126 new unchangeable_property('partnullsettings', "
127 define ('PHPWIKI_VERSION', '1.3.3-jeffs-hacks');
128 require \"lib/prepend.php\";
129 rcs_id('\$Id: configurator.php,v 1.2 2002-02-25 18:14:11 carstenklapp Exp $');", "");
133 $properties['Part One'] =
134 new part('partone', "///////////////////////////////////////////////////////////////////
138 Authentication and security settings:
143 $properties['Wiki Name'] =
144 new defines('WIKI_NAME', ''/*'PhpWiki'*/, "
145 The name of your wiki.
146 This is used to generate a keywords meta tag in the HTML templates,
147 in bookmark titles for any bookmarks made to pages in your wiki,
148 and during RSS generation for the title of the RSS channel.");
152 $properties['Reverse DNS'] =
153 new defines_boolean('ENABLE_REVERSE_DNS',
154 array('true' => 'perform additional reverse dns lookups',
155 'false' => 'just record the address as given by the httpd server'), "
156 If set, we will perform reverse dns lookups to try to convert the
157 users IP number to a host name, even if the http server didn't do
162 $properties['Admin Username'] =
163 new defines('ADMIN_USER', "", "
164 Username and password of administrator.
165 Set these to your preferences. For heaven's sake
166 pick a good password!");
167 $properties['Admin Password'] =
168 new defines_password('ADMIN_PASSWD', "", "");
172 $properties['ZIPdump Authentication'] =
173 new defines_boolean('ZIPDUMP_AUTH',
174 array('false' => 'everyone may download zip dumps',
175 'true' => 'only admin may download zip dumps'), "
176 If true, only the admin user can make zip dumps, else zip dumps
177 require no authentication.");
181 $properties['Strict Mailable Pagedumps'] =
182 new defines_boolean('STRICT_MAILABLE_PAGEDUMPS',
183 array('false' => 'binary',
184 'true' => 'quoted-printable'), "
185 If you define this to true, (MIME-type) page-dumps (either zip dumps,
186 or \"dumps to directory\" will be encoded using the quoted-printable
187 encoding. If you're actually thinking of mailing the raw page dumps,
188 then this might be useful, since (among other things,) it ensures
189 that all lines in the message body are under 80 characters in length.
191 Also, setting this will cause a few additional mail headers
192 to be generated, so that the resulting dumps are valid
193 RFC 2822 e-mail messages.
195 Probably, you can just leave this set to false, in which case you get
196 raw ('binary' content-encoding) page dumps.");
200 $properties['Maximum Upload Size'] =
201 new defines_numeric('MAX_UPLOAD_SIZE', "16 * 1024 * 1024", "
202 The maximum file upload size.");
206 $properties['Minor Edit Timeout'] =
207 new defines_numeric('MINOR_EDIT_TIMEOUT', "7 * 24 * 3600", "
208 If the last edit is older than MINOR_EDIT_TIMEOUT seconds, the
209 default state for the \"minor edit\" checkbox on the edit page form
214 //fixme: new property subclass
215 $properties['Disabled Actions'] =
216 new property('DisabledActions', "array('dumpserial', 'loadfile')", "
217 Actions listed in this array will not be allowed.");
221 //fixme: commented out by default
222 $properties['Access Log'] =
223 new defines('ACCESS_LOG', "/tmp/wiki_access_log", "
224 PhpWiki can generate an access_log (in \"NCSA combined log\" format)
225 for you. If you want one, define this to the name of the log file.");
229 $properties['Strict Login'] =
230 new defines_boolean('ALLOW_BOGO_LOGIN',
231 array('true' => 'Users may Sign In with any WikiWord',
232 'false' => 'Only admin may Sign In'), "
233 If ALLOW_BOGO_LOGIN is true, users are allowed to login (with
234 any/no password) using any userid which: 1) is not the ADMIN_USER,
235 2) is a valid WikiWord (matches $WikiNameRegexp.)");
239 $properties['Require Sign In Before Editing'] =
240 new defines_boolean('REQUIRE_SIGNIN_BEFORE_EDIT',
241 array('false' => 'Do not require Sign In',
242 'true' => 'Require Sign In'), "
243 If set, then if an anonymous user attempts to edit a page he will
244 be required to sign in. (If ALLOW_BOGO_LOGIN is true, of course,
245 no password is required, but the user must still sign in under
246 some sort of BogoUserId.)");
250 $properties['Path for PHP Session Support'] =
251 new iniset('session.save_path', 'some_other_directory', "
252 The login code now uses PHP's session support. Usually, the default
253 configuration of PHP is to store the session state information in
254 /tmp. That probably will work fine, but fails e.g. on clustered
255 servers where each server has their own distinct /tmp (this is the
256 case on SourceForge's project web server.) You can specify an
257 alternate directory in which to store state information like so
258 (whatever user your httpd runs as must have read/write permission
259 in this directory):");
263 $properties['Disable PHP Transparent Session ID'] =
264 new unchangeable_property('session.use_trans_sid', "@ini_set('session.use_trans_sid', 0);", "
265 If your php was compiled with --enable-trans-sid it tries to
266 add a PHPSESSID query argument to all URL strings when cookie
267 support isn't detected in the client browser. For reasons
268 which aren't entirely clear (PHP bug) this screws up the URLs
269 generated by PhpWiki. Therefore, transparent session ids
270 should be disabled. This next line does that.
272 (At the present time, you will not be able to log-in to PhpWiki,
273 or set any user preferences, unless your browser supports cookies.)");
277 $properties['Part Two'] =
278 new part('parttwo', "///////////////////////////////////////////////////////////////////
287 // MORE CONFIG OPTIONS GO IN HERE
291 $properties['Page Revisions'] =
292 new part('parttworevisions', "
295 The next section controls how many old revisions of each page are
296 kept in the database.
298 There are two basic classes of revisions: major and minor. Which
299 class a revision belongs in is determined by whether the author
300 checked the \"this is a minor revision\" checkbox when they saved the
303 There is, additionally, a third class of revisions: author
304 revisions. The most recent non-mergable revision from each distinct
305 author is and author revision.
307 The expiry parameters for each of those three classes of revisions
308 can be adjusted seperately. For each class there are five
309 parameters (usually, only two or three of the five are actually
310 set) which control how long those revisions are kept in the
313 max_keep: If set, this specifies an absolute maximum for the
314 number of archived revisions of that class. This is
315 meant to be used as a safety cap when a non-zero
316 min_age is specified. It should be set relatively high,
317 and it's purpose is to prevent malicious or accidental
318 database overflow due to someone causing an
319 unreasonable number of edits in a short period of time.
321 min_age: Revisions younger than this (based upon the supplanted
322 date) will be kept unless max_keep is exceeded. The age
323 should be specified in days. It should be a
324 non-negative, real number,
326 min_keep: At least this many revisions will be kept.
328 keep: No more than this many revisions will be kept.
330 max_age: No revision older than this age will be kept.
332 Supplanted date: Revisions are timestamped at the instant that they
333 cease being the current revision. Revision age is computed using
334 this timestamp, not the edit time of the page.
336 Merging: When a minor revision is deleted, if the preceding
337 revision is by the same author, the minor revision is merged with
338 the preceding revision before it is deleted. Essentially: this
339 replaces the content (and supplanted timestamp) of the previous
340 revision with the content after the merged minor edit, the rest of
341 the page metadata for the preceding version (summary, mtime, ...)
347 // MORE CONFIG OPTIONS GO IN HERE
351 $properties['Part Three'] =
352 new part('partthree', "///////////////////////////////////////////////////////////////////
356 Page appearance and layout
361 $properties['Theme'] =
362 new defines_selection('THEME',
363 array('default' => 'default',
364 'Hawaiian' => 'Hawaiian',
365 'MacOSX' => 'MacOSX',
366 'Portland' => 'Portland',
367 'Sidebar' => 'Sidebar',
368 'SpaceWiki' => 'SpaceWiki'), "
371 Most of the page appearance is controlled by files in the theme
374 There are a number of pre-defined themes shipped with PhpWiki.
375 Or you may create your own (e.g. by copying and then modifying one of
380 define('THEME', 'default');
381 define('THEME', 'Hawaiian');
382 define('THEME', 'MacOSX');
383 define('THEME', 'Portland');
384 define('THEME', 'Sidebar');
385 define('THEME', 'SpaceWiki');</pre>");
390 $properties['Character Set'] =
391 new defines('CHARSET', 'iso-8859-1', "
392 Select a valid charset name to be inserted into the xml/html pages,
393 and to reference links to the stylesheets (css). For more info see:
394 http://www.iana.org/assignments/character-sets. Note that PhpWiki
395 has been extensively tested only with the latin1 (iso-8859-1)
398 If you change the default from iso-8859-1 PhpWiki may not work
399 properly and it will require code modifications. However, character
400 sets similar to iso-8859-1 may work with little or no modification
401 depending on your setup. The database must also support the same
402 charset, and of course the same is true for the web browser. (Some
403 work is in progress hopefully to allow more flexibility in this
404 area in the future).");
408 $properties['Language'] =
409 new selection('LANG',
410 array('C' => 'English',
411 'nl' => 'Nederlands',
416 'it' => 'Italiano'), "
417 Select your language/locale - default language is \"C\" for English.
418 Other languages available:<pre>
419 English \"C\" (English - HomePage)
420 Dutch \"nl\" (Nederlands - ThuisPagina)
421 Spanish \"es\" (Español - PáginaPrincipal)
422 French \"fr\" (Français - Accueil)
423 German \"de\" (Deutsch - StartSeite)
424 Swedish \"sv\" (Svenska - Framsida)
425 Italian \"it\" (Italiano - PaginaPrincipale)
427 If you set \$LANG to the empty string, your systems default language
428 (as determined by the applicable environment variables) will be
431 Note that on some systems, apprently using these short forms for
432 the locale won't work. On my home system 'LANG=de' won't result in
433 german pages. Somehow the system must recognize the locale as a
434 valid locale before gettext() will work, i.e., use 'de_DE', 'nl_NL'.");
438 // MORE CONFIG OPTIONS GO IN HERE
442 $properties['Part Four'] =
443 new part('partfour', "///////////////////////////////////////////////////////////////////
452 //fixme: new property subclass
453 $properties['Allowed Protocols'] =
454 new property('AllowedProtocols', "http|https|mailto|ftp|news|nntp|ssh|gopher", "
455 allowed protocols for links - be careful not to allow \"javascript:\"
456 URL of these types will be automatically linked.
457 within a named link [name|uri] one more protocol is defined: phpwiki");
461 //fixme: new property subclass
462 $properties['Inline Images'] =
463 new property('InlineImages', "png|jpg|gif", "
464 URLs ending with the following extension should be inlined as images");
468 $properties['WikiName Regexp'] =
469 new property('WikiNameRegexp', "(?<![[:alnum:]])(?:[[:upper:]][[:lower:]]+){2,}(?![[:alnum:]])", "
470 Perl regexp for WikiNames (\"bumpy words\")
471 (?<!..) & (?!...) used instead of '\b' because \b matches '_' as well");
475 $properties['InterWiki Map File'] =
476 new defines('INTERWIKI_MAP_FILE', "lib/interwiki.map", "
477 InterWiki linking -- wiki-style links to other wikis on the web
479 The map will be taken from a page name InterWikiMap.
480 If that page is not found (or is not locked), or map
481 data can not be found in it, then the file specified
482 by INTERWIKI_MAP_FILE (if any) will be used.");
486 $properties['Part Five'] =
487 new part('partfive', "///////////////////////////////////////////////////////////////////
491 URL options -- you can probably skip this section.
496 // MORE CONFIG OPTIONS GO IN HERE
502 ////////////////////////////////////////////////////////////////
503 // Okay... fire up the code:
504 ////////////////////////////////////////////////////////////////
506 include "lib/main.php";
508 // (c-file-style: "gnu")
513 // c-hanging-comment-ender-p: nil
514 // indent-tabs-mode: nil
521 // end of configuration options
522 ///////////////////////////////
523 // begin class definitions
528 * Produces a string in the form "$name = value;"
530 * $InlineImages = "png|jpg|gif";
534 var $config_item_name;
538 function property($config_item_name, $default_value, $description) {
539 $this->config_item_name = $config_item_name;
540 $this->description = $description;
541 $this->default_value = $default_value;
544 function get_config_item_name() {
545 return $this->config_item_name;
548 function get_description() {
549 return $this->description;
552 function get_config_line($posted_value) {
553 return "\n\$" . $this->get_config_item_name() . " = \"" . $posted_value . "\";";
555 function get_config($posted_value) {
556 $d = str_replace("<pre>", "", $this->get_description());
557 $d = str_replace("</pre>", "", $d);
558 $d = str_replace("\n", "\n// ", $d) . $this->get_config_line($posted_value) ."\n";
562 function get_instructions($title) {
563 $i = "<p><b><h3>" . $title . "</h3></b></p>\n <p>" . str_replace("\n\n", "</p><p>", $this->get_description()) . "</p>\n";
564 return "<tr>\n<td>\n" . $i . "</td>\n";
567 function get_html() {
568 return "<input type=\"text\" name=\"" . $this->get_config_item_name() . "\" value=\"" . $this->default_value . "\">";
572 class unchangeable_property extends property {
573 function get_html() {
576 function get_config_line($posted_value) {
577 if ($this->description)
579 return "${n}".$this->default_value;
581 function get_instructions($title) {
582 $i = "<p><b><h3>" . $title . "</h3></b></p>\n <p>" . str_replace("\n\n", "</p><p>", $this->get_description()) . "</p>\n";
583 $i = $i ."<em>Not editable.</em><br />\n<pre>" . $this->default_value."</pre>";
584 return "<tr>\n<td colspan=\"2\">\n" .$i ."</td></tr>\n";
589 class selection extends property {
590 function get_html() {
591 $output = '<select name="' . $this->get_config_item_name() . "\">\n";
592 /* The first option is the default */
593 while(list($option, $label) = each($this->default_value)) {
594 $output .= " <option value=\"$option\">$label</option>\n";
596 $output .= " </select>\n </td>\n";
602 class defines extends property {
603 function get_config_line($posted_value) {
604 if ($this->description)
606 if ($posted_value == '')
607 return "${n}//define('".$this->get_config_item_name()."', \"\");";
609 return "${n}define('".$this->get_config_item_name()."', '$posted_value');";
613 class defines_selection extends property {
614 function get_config_line($posted_value) {
615 return defines::get_config_line($posted_value);
617 function get_html() {
618 return selection::get_html();
624 * Seed the random number generator.
626 * better_srand() ensures the randomizer is seeded only once.
628 * How random do you want it? See:
629 * http://www.php.net/manual/en/function.srand.php
630 * http://www.php.net/manual/en/function.mt-srand.php
632 function better_srand($seed = '') {
633 static $wascalled = FALSE;
635 $seed = $seed === '' ? (double) microtime() * 1000000 : $seed;
638 //trigger_error("new random seed", E_USER_NOTICE); //debugging
642 function rand_ascii($length = 1) {
644 //srand((double) microtime() * 1000000);
646 for ($i = 1; $i <= $length; $i++) {
647 $s .= chr(rand(40, 126)); // return only typeable 7 bit ascii
651 class defines_password extends defines {
652 function get_config_line($posted_value) {
653 if ($this->description)
655 if ($posted_value == '')
656 return "${n}//define('".$this->get_config_item_name()."', \"\");";
658 if (function_exists('crypt')) {
659 $salt_length = max(CRYPT_SALT_LENGTH,
663 16 * CRYPT_BLOWFISH);
664 // generate an encrypted password
665 $crypt_pass = crypt($posted_value, rand_ascii($salt_length));
666 $p = "${n}define('".$this->get_config_item_name()."', '$crypt_pass');";
667 $p = $p . "\n// If you used the passencrypt.php utility to encode the password";
668 $p = $p . "\n// then uncomment this line:";
669 return $p . "\ndefine('ENCRYPTED_PASSWD', true);";
671 $p = "${n}define('".$this->get_config_item_name()."', '$posted_value');";
672 $p = $p . "\n// If you used the passencrypt.php utility to encode the password";
673 $p = $p . "\n// then uncomment this line:";
674 $p = $p . "\n//define('ENCRYPTED_PASSWD', true);";
675 $p = $p . "\n// Encrypted passwords cannot be used:";
676 $p = $p . "\n// 'function crypt()' not available in this version of php";
681 function get_html() {
682 return "<input type=\"password\" name=\"" . $this->get_config_item_name() . "\" value=\"" . $this->default_value . "\">";
687 class defines_numeric extends property {
688 function get_config_line($posted_value) {
689 if ($this->description)
691 if ($posted_value == '')
692 return "${n}//define('".$this->get_config_item_name()."', 0);";
694 return "${n}define('".$this->get_config_item_name()."', $posted_value);";
698 class iniset extends property {
699 function get_config_line($posted_value) {
701 return "\nini_set('".$this->get_config_item_name()."', '$posted_value');";
703 return "\n//ini_set('".$this->get_config_item_name()."', '".$this->default_value."');";
707 class defines_boolean extends property {
708 function get_config_line($posted_value) {
709 if ($this->description)
711 return "${n}define('".$this->get_config_item_name()."', $posted_value);";
713 function get_html() {
714 $output = '<select name="' . $this->get_config_item_name() . "\">\n";
715 /* The first option is the default */
716 list($option, $label) = each($this->default_value);
717 $output .= " <option value=\"$option\" selected>$label</option>\n";
718 /* There can only be two options */
719 list($option, $label) = each($this->default_value);
720 $output .= " <option value=\"$option\">$label</option>\n";
721 $output .= "</select>\n </td>\n";
726 class part extends property {
727 function get_config($posted_value) {
728 $d = str_replace("<pre>", "", $this->get_description());
729 $d = str_replace("</pre>", "", $d);
730 $separator = "\n/////////////////////////////////////////////////////////////////////";
731 return $separator . str_replace("\n", "\n// ", $d) ."\n$this->default_value";
733 function get_instructions($title) {
734 $i = "<p><b><h2>" . $title . "</h2></b></p>\n <p>" . str_replace("\n\n", "</p><p>", $this->get_description()) . "</p>\n";
735 return "<tr>\n<td colspan=\"2\" bgcolor=\"#eee\">\n" .$i ."</td></tr>\n";
737 function get_html() {
742 // end of class definitions
743 /////////////////////////////
744 // begin auto generation code
746 if ($action == 'make_config') {
748 $timestamp = date ('dS of F, Y H:i:s');
751 /* This is a local configuration file for PhpWiki.
752 * It was automatically generated by the configurator script
758 /////////////////////////////////////////////////////////////////////
762 $posted = $GLOBALS['HTTP_POST_VARS'];
764 echo "<hr /><pre>\n";
765 print_r($GLOBALS['HTTP_POST_VARS']);
766 echo "</pre><hr />\n";
772 foreach($properties as $option_name => $a) {
773 $posted_value = $posted[$a->config_item_name];
774 $config .= $properties[$option_name]->get_config($posted_value);
777 $diemsg = "The configurator.php is provided for testing purposes only.\nYou can't use this file with your PhpWiki server yet!!";
778 $config .= "\ndie(\"$diemsg\");\n";
781 /* We first check if the config-file exists. */
782 if (file_exists('defaults.php')) {
783 /* We make a backup copy of the file */
784 $new_filename = 'defaults.' . time() . '.php';
785 if (@copy('defaults.php', $new_filename)) {
786 $fp = @fopen('defaults.php', 'w');
789 $fp = @fopen('defaults.php', 'w');
795 echo "<p>The configuration was written to <code><b>defaults.php</b></code>. A backup was made to <code><b>$new_filename</b></code>.</p>\n";
797 echo "<p>A configuration file could <b>not</b> be written. You should copy the above configuration to a file, and manually save it as <code><b>defaults.php</b></code>.</p>\n";
800 echo "<hr />\n<p>Here's the configuration file based on your answers:</p>\n<pre>\n";
801 echo htmlentities($config);
802 echo "</pre>\n<hr />\n";
804 echo "<!--If she can stand it, I can. Play it!-->\n";
805 echo "<p>Would you like to <a href=\"configurator.php\">play again</a>?</p>\n";
808 /* No action has been specified - we make a form. */
811 <form action="configurator.php" method="post">
812 <table border="1" cellpadding="4" cellspacing="0">
813 <input type="hidden" name="action" value="make_config">
816 while(list($property, $obj) = each($properties)) {
817 echo $obj->get_instructions($property);
818 if ($h = $obj->get_html())
819 echo "<td>".$h."</td>\n";
824 <p><input type="submit" value="Make config-file"> <input type="reset" value="Clear"></p>