xref: /dokuwiki/install.php (revision 5cfb88156f790ba8677badc88863a85569149942)
1*5cfb8815Schris<?php
2*5cfb8815Schris/**
3*5cfb8815Schris *  Dokuwiki installation assistance
4*5cfb8815Schris *
5*5cfb8815Schris *  @author      Chris Smith <chris@jalakai.co.uk>
6*5cfb8815Schris */
7*5cfb8815Schris
8*5cfb8815Schrisif(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__)).'/');
9*5cfb8815Schrisif(!defined('DOKU_CONF')) define('DOKU_CONF',DOKU_INC.'conf/');
10*5cfb8815Schrisif(!defined('DOKU_LOCAL')) define('DOKU_LOCAL',DOKU_INC.'conf/');
11*5cfb8815Schris
12*5cfb8815Schrisif(!defined('DEBUG')) define('DEBUG', false);
13*5cfb8815Schris
14*5cfb8815Schris// ------------------------------------------------------------------------------------
15*5cfb8815Schris// important settings ...
16*5cfb8815Schris// installation dependent local config file list
17*5cfb8815Schris$config_files = array(
18*5cfb8815Schris  'local' => DOKU_LOCAL.'local.php',
19*5cfb8815Schris  'users' => DOKU_LOCAL.'users.auth.php',
20*5cfb8815Schris  'auth'  => DOKU_LOCAL.'acl.auth.php'
21*5cfb8815Schris);
22*5cfb8815Schris
23*5cfb8815Schris// other installation dir/file permission requirements
24*5cfb8815Schris$install_permissions = array(
25*5cfb8815Schris  'data'      => 'data',
26*5cfb8815Schris  'pages'     => 'data/pages',
27*5cfb8815Schris  'attic'     => 'data/attic',
28*5cfb8815Schris  'media'     => 'data/media',
29*5cfb8815Schris  'meta'      => 'data/meta',
30*5cfb8815Schris  'cache'     => 'data/cache',
31*5cfb8815Schris  'locks'     => 'data/locks',
32*5cfb8815Schris  'changelog' => 'data/changes.log'
33*5cfb8815Schris);
34*5cfb8815Schris
35*5cfb8815Schris// array use to verify unchanged dokuwiki.php files, 'version' => 'md5 hash'
36*5cfb8815Schris$dokuwiki_php = DOKU_CONF.'dokuwiki.php';
37*5cfb8815Schris$dokuwiki_hash = array(
38*5cfb8815Schris  '2005-09-22' => 'e33223e957b0b0a130d0520db08f8fb7',
39*5cfb8815Schris  '2006-03-05' => '51295727f79ab9af309a2fd9e0b61acc',
40*5cfb8815Schris  '2006-03-09' => '51295727f79ab9af309a2fd9e0b61acc',
41*5cfb8815Schris);
42*5cfb8815Schris
43*5cfb8815Schris// language strings
44*5cfb8815Schris
45*5cfb8815Schris// ------------------------------------------------------------------------------------
46*5cfb8815Schris// initialise variables ...
47*5cfb8815Schris
48*5cfb8815Schris$msg = array();
49*5cfb8815Schris$error = array();
50*5cfb8815Schris$debug = array();
51*5cfb8815Schris$process_form = false;
52*5cfb8815Schris
53*5cfb8815Schris// form variables with default values
54*5cfb8815Schris$title       = "";
55*5cfb8815Schris$location    = true;
56*5cfb8815Schris$data        = "./data";
57*5cfb8815Schris$changeslog  = true;
58*5cfb8815Schris$acl         = true;
59*5cfb8815Schris$superuser   = "";
60*5cfb8815Schris$fullname    = "";
61*5cfb8815Schris$email       = "";
62*5cfb8815Schris
63*5cfb8815Schris// check for dokuwiki
64*5cfb8815Schris// (for now assume included with Dokuwiki install & resident in dokuwiki root folder)
65*5cfb8815Schris
66*5cfb8815Schris// ------------------------------------------------------------------------------------
67*5cfb8815Schris// check for virgin dokuwiki installation
68*5cfb8815Schris$virgin_install = true;
69*5cfb8815Schris
70*5cfb8815Schris  // $config_files mustn't exist
71*5cfb8815Schris  foreach ($config_files as $file) {
72*5cfb8815Schris    if (@file_exists($file)) {
73*5cfb8815Schris      $virgin_install = false;
74*5cfb8815Schris      $file = str_replace($_SERVER['DOCUMENT_ROOT'],'{DOCUMENT_ROOT}', $file);
75*5cfb8815Schris      $msg[] = "<span class=\"file\">$file</span> exists"; }
76*5cfb8815Schris  }
77*5cfb8815Schris
78*5cfb8815Schris  // main dokuwiki config file (conf/dokuwiki.php) must not have been modified
79*5cfb8815Schris  $installation_hash = md5(@file_get_contents($dokuwiki_php));
80*5cfb8815Schris  if (!in_array($installation_hash, $dokuwiki_hash)) {
81*5cfb8815Schris    $virgin_install = false;
82*5cfb8815Schris    $msg[] = "unrecognised or modified dokuwiki.php -- hash=$installation_hash";
83*5cfb8815Schris  }
84*5cfb8815Schris// ------------------------------------------------------------------------------------
85*5cfb8815Schris// check for other basic installation & configuration details (to be nice)
86*5cfb8815Schris
87*5cfb8815Schris$changeslog_exists = @file_exists(DOKU_INC.'data/changes.log');
88*5cfb8815Schris
89*5cfb8815Schrisif (!is_writable(DOKU_CONF)) {
90*5cfb8815Schris  $file = str_replace($_SERVER['DOCUMENT_ROOT'],'{DOCUMENT_ROOT}', DOKU_CONF);
91*5cfb8815Schris  $error[] = "<span class=\"file\">$file</span> must be writable by the web server.";
92*5cfb8815Schris}
93*5cfb8815Schris
94*5cfb8815Schris//-------------------------------------------------------------------------------------
95*5cfb8815Schris// utility functions
96*5cfb8815Schris
97*5cfb8815Schris/**
98*5cfb8815Schris * remove magic quotes recursivly
99*5cfb8815Schris *
100*5cfb8815Schris * @author Andreas Gohr <andi@splitbrain.org>
101*5cfb8815Schris */
102*5cfb8815Schrisfunction remove_magic_quotes(&$array) {
103*5cfb8815Schris  foreach (array_keys($array) as $key) {
104*5cfb8815Schris    if (is_array($array[$key])) {
105*5cfb8815Schris      remove_magic_quotes($array[$key]);
106*5cfb8815Schris    }else {
107*5cfb8815Schris      $array[$key] = stripslashes($array[$key]);
108*5cfb8815Schris    }
109*5cfb8815Schris  }
110*5cfb8815Schris}
111*5cfb8815Schris
112*5cfb8815Schrisfunction cleanText($var, $default, $regex, $msg) {
113*5cfb8815Schris  global $error;
114*5cfb8815Schris
115*5cfb8815Schris  $value = isset($_REQUEST[$var]) ? $_REQUEST[$var] : $default;
116*5cfb8815Schris
117*5cfb8815Schris  if ($regex) {
118*5cfb8815Schris    if (!preg_match($regex, $value)) {
119*5cfb8815Schris      $error[] = "$var - illegal/unrecognised value";
120*5cfb8815Schris    }
121*5cfb8815Schris  }
122*5cfb8815Schris  return $value;
123*5cfb8815Schris}
124*5cfb8815Schris
125*5cfb8815Schrisfunction fileWrite($name, $filename, $data) {
126*5cfb8815Schris  global $error;
127*5cfb8815Schris
128*5cfb8815Schris  if (($fp = @fopen($filename, 'wb')) === false) {
129*5cfb8815Schris    $filename = str_replace($_SERVER['DOCUMENT_ROOT'],'{DOCUMENT_ROOT}', $filename);
130*5cfb8815Schris    $error[] = "Unable to create $name (<span class=\"file\">$filename</span>).  You will need to check directory/file permissions and create the file manually.";
131*5cfb8815Schris    return false;
132*5cfb8815Schris  }
133*5cfb8815Schris
134*5cfb8815Schris  if (!empty($data)) { fwrite($fp, $data);  }
135*5cfb8815Schris  fclose($fp);
136*5cfb8815Schris  return true;
137*5cfb8815Schris}
138*5cfb8815Schris
139*5cfb8815Schris// ------------------------------------------------------------------------------------
140*5cfb8815Schris// form processing ...
141*5cfb8815Schrisif (isset($_REQUEST['submit'])) {
142*5cfb8815Schris  if (!$virgin_install) {
143*5cfb8815Schris    $msg[] = "unable to apply updates, installation already modified";
144*5cfb8815Schris
145*5cfb8815Schris  } else {
146*5cfb8815Schris    // apply updates per form instructions
147*5cfb8815Schris    $process_form = true;
148*5cfb8815Schris
149*5cfb8815Schris    if (get_magic_quotes_gpc()) {
150*5cfb8815Schris      if (!empty($_REQUEST)) remove_magic_quotes($_REQUEST);
151*5cfb8815Schris    }
152*5cfb8815Schris
153*5cfb8815Schris    $title = cleanText('title', '', '');
154*5cfb8815Schris    $location = isset($_REQUEST['location']);
155*5cfb8815Schris    $data = cleanText('data', '', '');
156*5cfb8815Schris    $changeslog = isset($_REQUEST['changeslog']);
157*5cfb8815Schris    $acl = isset($_REQUEST['acl']);
158*5cfb8815Schris    $superuser = cleanText('superuser','','/\S+/', );
159*5cfb8815Schris    $password = cleanText('password','','/\S+/');
160*5cfb8815Schris    $confirm = cleanText('confirm','','/^'.preg_quote($password,'/').'$/');
161*5cfb8815Schris    $fullname = cleanText('fullname','','');
162*5cfb8815Schris    $email = cleanText('email','','');
163*5cfb8815Schris
164*5cfb8815Schris    $debug = compact('title','location','data','changeslog','acl','superuser','password','confirm');
165*5cfb8815Schris
166*5cfb8815Schris    if (empty($error)) {
167*5cfb8815Schris      // all incoming data is ok ... lets do ...
168*5cfb8815Schris      // create changes.log
169*5cfb8815Schris      if (!$changeslog_exists) {
170*5cfb8815Schris        $filename = realpath((empty($data) || ($data{0} != "/")) ? DOKU_INC.$data : $data).'/changes.log';
171*5cfb8815Schris        fileWrite('changeslog',$filename, '');
172*5cfb8815Schris      }
173*5cfb8815Schris
174*5cfb8815Schris      // create local.php
175*5cfb8815Schris      $output = "";
176*5cfb8815Schris      if (!empty($title)) $output .= '$conf[\'title\'] = \''.addslashes($title)."';\n";
177*5cfb8815Schris      if (!empty($data)) $output .= '$conf[\'data\'] = \''.$data."';\n";
178*5cfb8815Schris      if ($acl) $output .= '$conf[\'useacl\'] = 1'.";\n";
179*5cfb8815Schris      if (!empty($superuser)) $output .= '$conf[\'superuser\'] = \''.$superuser."';\n";
180*5cfb8815Schris
181*5cfb8815Schris      if (!empty($output)) {
182*5cfb8815Schris        $output = '<'.'?php
183*5cfb8815Schris/*
184*5cfb8815Schris * Dokuwiki\'s Main Configuration File - Local Settings
185*5cfb8815Schris * Auto-generated by install script
186*5cfb8815Schris * Date: '.date('r').'
187*5cfb8815Schris */'."\n".$output;
188*5cfb8815Schris           fileWrite('local configuration settings file',DOKU_LOCAL.'local.php',$output);
189*5cfb8815Schris       }
190*5cfb8815Schris
191*5cfb8815Schris      if ($acl) {
192*5cfb8815Schris        // create users.auth.php
193*5cfb8815Schris        // --- user:MD5password:Real Name:email:groups,comma,seperated
194*5cfb8815Schris        $output = (!empty($superuser)) ? join(":",array($superuser, md5($password), $fullname, $email, 'users')) : "";
195*5cfb8815Schris        $output = @file_get_contents(DOKU_CONF.'users.auth.php.dist')."\n$output\n";
196*5cfb8815Schris
197*5cfb8815Schris        fileWrite('acl user file', DOKU_LOCAL.'users.auth.php', $output);
198*5cfb8815Schris
199*5cfb8815Schris        // create acl.auth.php
200*5cfb8815Schris        $output = @file_get_contents(DOKU_CONF.'acl.auth.php.dist');
201*5cfb8815Schris        fileWrite('acl authorisations file', DOKU_LOCAL.'acl.auth.php', $output);
202*5cfb8815Schris      }
203*5cfb8815Schris    }
204*5cfb8815Schris  }
205*5cfb8815Schris}
206*5cfb8815Schris//-------------------------------------------------------------------------------------
207*5cfb8815Schris
208*5cfb8815Schris$show_form = !$process_form && $virgin_install && empty($error);
209*5cfb8815Schris
210*5cfb8815Schris?>
211*5cfb8815Schris<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
212*5cfb8815Schris<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
213*5cfb8815Schris<head>
214*5cfb8815Schris<meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8" />
215*5cfb8815Schris<title>Dokuwiki Installer</title>
216*5cfb8815Schris<style type="text/css">
217*5cfb8815Schris<!--/*--><![CDATA[/*><!--*/
218*5cfb8815Schris
219*5cfb8815Schrishtml {margin: 0; padding: 0;}
220*5cfb8815Schrisbody {
221*5cfb8815Schris  width: 90%;
222*5cfb8815Schris  margin: 0 auto;
223*5cfb8815Schris  font: 84% Verdana, Helvetica, Arial, sans-serif;
224*5cfb8815Schris}
225*5cfb8815Schris
226*5cfb8815Schrisa {
227*5cfb8815Schris  white-space: nowrap;
228*5cfb8815Schris}
229*5cfb8815Schris
230*5cfb8815Schrisimg {
231*5cfb8815Schris  border: none;
232*5cfb8815Schris}
233*5cfb8815Schris
234*5cfb8815Schris.abbr {
235*5cfb8815Schris  border-bottom: 2px dotted #444;
236*5cfb8815Schris}
237*5cfb8815Schris
238*5cfb8815Schris.alert .file {
239*5cfb8815Schris  color: #a03333;
240*5cfb8815Schris}
241*5cfb8815Schris
242*5cfb8815Schris.error .file {
243*5cfb8815Schris  color: #c33;
244*5cfb8815Schris}
245*5cfb8815Schris
246*5cfb8815Schrish1 img {
247*5cfb8815Schris  vertical-align: middle;
248*5cfb8815Schris}
249*5cfb8815Schris
250*5cfb8815Schrisform, fieldset {
251*5cfb8815Schris  margin: 1em 0;
252*5cfb8815Schris  padding: 0;
253*5cfb8815Schris  border: none;
254*5cfb8815Schris  width: 100%;
255*5cfb8815Schris}
256*5cfb8815Schris
257*5cfb8815Schrisul {
258*5cfb8815Schris  font-size: 80%;
259*5cfb8815Schris}
260*5cfb8815Schris
261*5cfb8815Schrisform .field {
262*5cfb8815Schris  margin: 0.5em 0;
263*5cfb8815Schris}
264*5cfb8815Schris
265*5cfb8815Schrislabel {
266*5cfb8815Schris  display: block;
267*5cfb8815Schris}
268*5cfb8815Schris
269*5cfb8815Schrislabel span {
270*5cfb8815Schris  display: block;
271*5cfb8815Schris}
272*5cfb8815Schris
273*5cfb8815Schrislabel input.text {
274*5cfb8815Schris  width: 95%;
275*5cfb8815Schris}
276*5cfb8815Schris
277*5cfb8815Schris#instructions {
278*5cfb8815Schris  float: right;
279*5cfb8815Schris  width: 34%;
280*5cfb8815Schris}
281*5cfb8815Schris
282*5cfb8815Schris#details {
283*5cfb8815Schris  float: left;
284*5cfb8815Schris  width: 58%;
285*5cfb8815Schris}
286*5cfb8815Schris
287*5cfb8815Schris#process {
288*5cfb8815Schris  margin: 1.5em 0;
289*5cfb8815Schris}
290*5cfb8815Schris
291*5cfb8815Schris#debug, #footer {
292*5cfb8815Schris  clear: both;
293*5cfb8815Schris}
294*5cfb8815Schris
295*5cfb8815Schris#acl, #files {
296*5cfb8815Schris  border: 1px solid #ccc;
297*5cfb8815Schris  padding: 0.5em 0 1em 0;
298*5cfb8815Schris}
299*5cfb8815Schris
300*5cfb8815Schrisfieldset.dependent {
301*5cfb8815Schris  margin-left: 2em;
302*5cfb8815Schris}
303*5cfb8815Schris
304*5cfb8815Schris
305*5cfb8815Schris/*]]>*/-->
306*5cfb8815Schris</style>
307*5cfb8815Schris<script type="text/javascript">
308*5cfb8815Schris<!--//--><![CDATA[//><!--
309*5cfb8815Schris
310*5cfb8815Schris
311*5cfb8815Schris//--><!]]>
312*5cfb8815Schris</script>
313*5cfb8815Schris</head>
314*5cfb8815Schris<body>
315*5cfb8815Schris<h1><img src="http://wiki.splitbrain.org/_media/wiki:dokuwiki-64.png" alt="" />Dokuwiki Installer</h1>
316*5cfb8815Schris<div id="instructions">
317*5cfb8815Schris  <p>This page assists in the installation and configuration of <a href="http://wiki.splitbrain.org">Dokuwiki</a>.</p>
318*5cfb8815Schris  <p>Dokuwiki uses ordinary files for the storage of wiki pages and other information associated with those pages
319*5cfb8815Schris  (e.g. images, search indexes, old revisions, etc).  In order to operate successfully Dokuwiki <strong>must</strong>
320*5cfb8815Schris  have write access to the directories that hold those files.  This installer is not capable of setting up directory
321*5cfb8815Schris  permissions, that normally needs to be done directly or if you are using hosting, through your hosting
322*5cfb8815Schris  control panel (e.g. cPanel).</p>
323*5cfb8815Schris  <p>This installer will setup your Dokuwiki configuration for <span class="abbr" title="access control list">ACL</span>,
324*5cfb8815Schris  which in turn allows administrator login and access to Dokuwiki's admin menu for installing plugins, managing
325*5cfb8815Schris  users, managing access to wiki pages and alteration of configuration settings.  It isn't required for Dokuwiki to
326*5cfb8815Schris  operate, however it will make Dokuwiki easier to administer.</p>
327*5cfb8815Schris  <p>Use these links for details concerning <a href="http://wiki.splitbrain.org/wiki:installation">installation instructions</a>
328*5cfb8815Schris  and <a href="http://wiki.splitbrain.org/wiki:configuration">configuration settings</a>.</p>
329*5cfb8815Schris</div>
330*5cfb8815Schris<div id="details">
331*5cfb8815Schris<?php if (!$virgin_install) { ?>
332*5cfb8815Schris  <p>Modified installation detected.</p>
333*5cfb8815Schris  <ul class="alert">
334*5cfb8815Schris<?php   foreach ($msg as $text) { ?>
335*5cfb8815Schris    <li><?php echo $text?></li>
336*5cfb8815Schris<?php   } ?>
337*5cfb8815Schris  </ul>
338*5cfb8815Schris  <p>For security reasons this script will only work with a new &amp; unmodified Dokuwiki installation.
339*5cfb8815Schris  You should either re-extract the files from the downloaded package or consult the complete
340*5cfb8815Schris  <a href="http://wiki.splitbrain.org/wiki:install">Dokuwiki installation instructions</a></p>
341*5cfb8815Schris<?php } /* end if (!virgin_install) */ ?>
342*5cfb8815Schris<?php if (!$process_form && !empty($error)) { ?>
343*5cfb8815Schris  <p>One or more incorrect directory/file permissions were found.</p>
344*5cfb8815Schris  <ul class="error">
345*5cfb8815Schris<?php   foreach ($error as $text) { ?>
346*5cfb8815Schris    <li><?php echo $text ?></li>
347*5cfb8815Schris<?php   } ?>
348*5cfb8815Schris  </ul>
349*5cfb8815Schris  <p>In order to complete this installation the above directories and files need to have their
350*5cfb8815Schris    permissions altered as indicated. Please correct the above problems before trying again.</p>
351*5cfb8815Schris<?php } /* end if (!$process_form && !empty($error)) */ ?>
352*5cfb8815Schris<?php if ($process_form) { ?>
353*5cfb8815Schris<?php   if (empty($error)) { ?>
354*5cfb8815Schris  <p>Configuration updated successfully.</p>
355*5cfb8815Schris  <p>Now that your initial dokuwiki configuration has been set you should delete this file to prevent its further use
356*5cfb8815Schris  which may damage your dokuwiki installation and/or configuration.</p>
357*5cfb8815Schris  <p>Use this link to visit your new <a href="doku.php" title="my new dokuWiki">wiki</a></p>
358*5cfb8815Schris<?php   } else { ?>
359*5cfb8815Schris  <p>The following errors were encountered ... </p>
360*5cfb8815Schris  <ul class="error">
361*5cfb8815Schris<?php     foreach ($error as $text) { ?>
362*5cfb8815Schris    <li><?php echo $text?></li>
363*5cfb8815Schris<?php     } ?>
364*5cfb8815Schris  </ul>
365*5cfb8815Schris  <p>return to <a href="install.php">installation form</a></p>
366*5cfb8815Schris<?php   } ?>
367*5cfb8815Schris<?php } ?>
368*5cfb8815Schris<?php if ($show_form) { ?>
369*5cfb8815Schris  <form action="" method="post">
370*5cfb8815Schris    <fieldset id="wiki">
371*5cfb8815Schris      <div class="field"><label><span> Wiki Name </span><input class="text" type="text" name="title" value="<?php echo $title ?>" /></label></div>
372*5cfb8815Schris      <fieldset id="acl">
373*5cfb8815Schris      <div class="field"><label><input class="checkbox" type="checkbox" name="acl" <?php echo(($acl ? 'checked="checked"' : ''));?> /> Enable ACL </label></div>
374*5cfb8815Schris        <fieldset class="dependent">
375*5cfb8815Schris          <div class="field"><label><span> Superuser </span><input class="text" type="text" name="superuser" value="<?php echo $superuser ?>" /></label></div>
376*5cfb8815Schris          <div class="field"><label><span> Full name </span><input class="text" type="text" name="fullname" value="<?php echo $fullname ?>" /></label></div>
377*5cfb8815Schris          <div class="field"><label><span> Email Address </span><input class="text" type="text" name="email" value="<?php echo $email ?>" /></label></div>
378*5cfb8815Schris          <div class="field"><label><span> Superuser password </span><input class="text" type="password" name="password" /></label></div>
379*5cfb8815Schris          <div class="field"><label><span> Confirm password </span><input class="text" type="password" name="confirm" /></label></div>
380*5cfb8815Schris        </fieldset>
381*5cfb8815Schris      </fieldset>
382*5cfb8815Schris      <fieldset id="files">
383*5cfb8815Schris        <div class="field"><label><input class="checkbox" type="checkbox" name="location" <?php echo(($location ? 'checked="checked"' : ''));?> />Use default wiki location</label></div>
384*5cfb8815Schris        <fieldset class="dependent">
385*5cfb8815Schris          <div class="field"><label><span> Wiki Location </span><input class="text" type="text" name="data" value="<?php echo $data ?>" /></label></div>
386*5cfb8815Schris        </fieldset>
387*5cfb8815Schris      </fieldset>
388*5cfb8815Schris<?php if (!$changeslog_exists) { ?>
389*5cfb8815Schris      <div class="field"><label><input class="checkbox" type="checkbox" name="changeslog" <?php echo(($changeslog ? 'checked="checked"' : ''));?> />Create changes.log file</label></div>
390*5cfb8815Schris<?php } ?>
391*5cfb8815Schris    </fieldset>
392*5cfb8815Schris    <fieldset id="process">
393*5cfb8815Schris      <input class="button" type="submit" name="submit" value="Process Configuration Changes" />
394*5cfb8815Schris    </fieldset>
395*5cfb8815Schris  </form>
396*5cfb8815Schris<?php } ?>
397*5cfb8815Schris</div><!-- #details -->
398*5cfb8815Schris<?php if (DEBUG) { ?>
399*5cfb8815Schris<div id="debug">
400*5cfb8815Schris  <pre>
401*5cfb8815Schris  <?php print_r($_REQUEST); print_r($debug); print_r($error); ?>
402*5cfb8815Schris  </pre>
403*5cfb8815Schris</div>
404*5cfb8815Schris<?php } ?>
405*5cfb8815Schris<div id="footer">
406*5cfb8815Schris  <a href="http://wiki.splitbrain.org"><img src="lib/tpl/default/images/button-dw.png" alt="powered by dokuwiki" /></a>
407*5cfb8815Schris  <a href="http://www.php.net"><img src="lib/tpl/default/images/button-php.gif" alt="powered by php" /></a>
408*5cfb8815Schris</div>
409*5cfb8815Schris</body>
410*5cfb8815Schris</html>