Update of /cvsroot/php-blog/serendipity
In directory sc8-pr-cvs1:/tmp/cvs-serv25904
Modified Files:
serendipity_admin_installer.inc.php
Log Message:
New installer, please test as much as you can...
This installer has much better handling of errors during the installation.
It has the main steps of the installation split into functions for better overview
Please test it!
Index: serendipity_admin_installer.inc.php
===================================================================
RCS file: /cvsroot/php-blog/serendipity/serendipity_admin_installer.inc.php,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- serendipity_admin_installer.inc.php 22 Jul 2003 00:53:12 -0000 1.19
+++ serendipity_admin_installer.inc.php 22 Jul 2003 16:44:00 -0000 1.20
@@ -5,71 +5,71 @@
function serendipity_query_default($optname, $default)
{
- switch ($optname) {
- case "serendipityPath":
- return dirname(__FILE__) . '/';
+ switch ($optname) {
+ case "serendipityPath":
+ return dirname(__FILE__) . '/';
- case "serendipityHTTPPath":
- return dirname($_SERVER['PHP_SELF']) . '/';
+ case "serendipityHTTPPath":
+ return dirname($_SERVER['PHP_SELF']) . '/';
- case "baseURL":
- $ssl = $_SERVER['HTTPS'] == 'on';
- $port = $_SERVER['SERVER_PORT'];
+ case "baseURL":
+ $ssl = $_SERVER['HTTPS'] == 'on';
+ $port = $_SERVER['SERVER_PORT'];
- return sprintf("http%s://%s%s%s/",
- $ssl ? 's' : '',
- $_SERVER['HTTP_HOST'],
- (($ssl && $port != 443) || (!$ssl && $port != 80)) ? (':' . $port) : '',
- dirname($_SERVER['PHP_SELF'])
- );
-
- case "convert":
- $path = explode(":", $_ENV['PATH']);
- /* add some other possible locations to the path while we are at it,
- * as these are not always included in the apache path */
- $path[] = '/usr/X11R6/bin';
+ return sprintf("http%s://%s%s%s/",
+ $ssl ? 's' : '',
+ $_SERVER['HTTP_HOST'],
+ (($ssl && $port != 443) || (!$ssl && $port != 80)) ? (':' . $port) : '',
+ dirname($_SERVER['PHP_SELF'])
+ );
- foreach ($path as $dir) {
- if (@is_executable($dir . '/convert')) {
- return $dir . '/convert';
- }
- }
- return $default;
-
- default:
- return $default;
- }
+ case "convert":
+ $path = explode(":", $_ENV['PATH']);
+ /* add some other possible locations to the path while we are at it,
+ * as these are not always included in the apache path */
+ $path[] = '/usr/X11R6/bin';
+
+ foreach ($path as $dir) {
+ if (@is_executable($dir . '/convert')) {
+ return $dir . '/convert';
+ }
+ }
+ return $default;
+
+ default:
+ return $default;
+ }
}
function serendipity_parseTemplate($n) {
- global $serendipity;
- $config = array();
+ global $serendipity;
+ $config = array();
$t = file($n);
for ($x=0; $x<count($t); $x++) {
- $l = $t[$x];
+ $l = $t[$x];
$l = trim($l);
switch ($l[0]) {
- // New Configure section
- case "/":
- if ($l[1] == "/") {
+ // New Configure section
+ case "/":
+ if ($l[1] == "/") {
$current = trim(substr($l, 2));
$config[$current] = array();
}
break;
// A configure option
- case "$":
- // Grep out the name, type and default
+ case "$":
+ // Grep out the name, type and default
preg_match('#\{([^|]+\|[^|]+\|([^}]+)?)\}[^/]+/{2}(.+)#msi', $l, $match);
$c = explode("|", $match[1]);
$config[$current][] = array("longname" => $c[0],
- "name" => $c[1],
+ "name" => $c[1],
"type" => $c[2],
"default" => serendipity_query_default($c[1], $c[3]),
- "distdefault" => $c[3],
+ "distdefault" => $c[3],
"desc" => $match[3]);
break;
}
@@ -79,54 +79,52 @@
}
function serendipity_guessInput($type,$name,$value='',$default='') {
-
- switch ($type) {
- case 'bool' :
- echo "<input type='radio' name='".$name."' value='true' ";
- echo (($default==true) ? "CHECKED" : "")."> Yes";
- echo "<input type='radio' name='".$name."' value='false' ";
- echo (($default==true) ? "" : "CHECKED")."> No";
- break;
- case 'protected' :
- echo "<input type='password' size='30' name='".$name."' value=\"";
- echo htmlentities($default)."\">";
-
- break;
- default :
- echo "<input type='text' size='30' name='".$name."' value=\"";
- echo htmlentities($default)."\">";
- break;
- }
+ switch ($type) {
+ case 'bool' :
+ echo "<input type='radio' name='".$name."' value='true' ";
+ echo (($default==true) ? "CHECKED" : "")."> Yes";
+ echo "<input type='radio' name='".$name."' value='false' ";
+ echo (($default==true) ? "" : "CHECKED")."> No";
+ break;
+ case 'protected' :
+ echo "<input type='password' size='30' name='".$name."' value=\"". htmlentities($default) ."\">";
+
+ break;
+
+ default :
+ echo "<input type='text' size='30' name='". $name ."' value=\"". htmlentities($default) ."\">";
+ break;
+ }
}
function serendipity_printConfigTemplate($t, $from = false) {
- global $serendipity;
+ global $serendipity;
echo "<form action='?' method='POST'>";
echo "<input type='hidden' name='serendipity[adminModule]' value='installer'>";
echo "<input type='hidden' name='installAction' value='check'>";
echo "<br>";
foreach ($t as $key => $value) {
- echo "<table width='100%' cellspacing='2'>";
- echo "<tr><td colspan='2'><font size='2'>$key:</font></td></tr>";
- echo "<tr><td><table width='100%' cellspacing='2' cellpadding='3'>";
- for ($x=0; $x<count($value); $x++) {
- if (@is_array($from)) $value[$x]["default"] = $from[$value[$x]["name"]];
- echo "<tr>";
- echo "<td bgcolor='#D8D8D8' valign='top'><font size='2'><strong>".$value[$x]["longname"]."</strong></font><br><font size='1' color='5E7A94'>(". $value[$x]["type"] .") ".$value[$x]["desc"]."</font></td>";
- echo "<td bgcolor='#E0E0E0' valign='top' width='1'><font size='2'>";
-
- echo serendipity_guessInput($value[$x]["type"], $value[$x]["name"], $from[$value[$x]["name"]], $value[$x]["default"]);
-
- echo "</font></td>";
- echo "</tr>";
-
- }
- echo "</table>";
- echo "</td></tr>";
- echo "</table>";
- echo "<p>";
+ echo "<table width='100%' cellspacing='2'>";
+ echo "<tr><td colspan='2'><font size='2'>$key:</font></td></tr>";
+ echo "<tr><td><table width='100%' cellspacing='2' cellpadding='3'>";
+ for ($x=0; $x<count($value); $x++) {
+ if (@is_array($from)) $value[$x]["default"] = $from[$value[$x]["name"]];
+ echo "<tr>";
+ echo "<td bgcolor='#D8D8D8' valign='top'><font size='2'><strong>".$value[$x]["longname"]."</strong></font><br><font size='1' color='5E7A94'>(". $value[$x]["type"] .") ".$value[$x]["desc"]."</font></td>";
+ echo "<td bgcolor='#E0E0E0' valign='top' width='1'><font size='2'>";
+
+ echo serendipity_guessInput($value[$x]["type"], $value[$x]["name"], $from[$value[$x]["name"]], $value[$x]["default"]);
+
+ echo "</font></td>";
+ echo "</tr>";
+
+ }
+ echo "</table>";
+ echo "</td></tr>";
+ echo "</table>";
+ echo "<p>";
}
echo "<input type='submit' value='Check & save'>";
echo "</form>";
@@ -150,10 +148,10 @@
$in_table = 1;
$def = $line;
}
-
- if (preg_match('#^create\s*(\{fulltext\}|unique)\s*index#i', $line)) {
- array_push($queries, $line);
- }
+
+ if (preg_match('#^create\s*(\{fulltext\}|unique)\s*index#i', $line)) {
+ array_push($queries, $line);
+ }
}
}
fclose($fp);
@@ -161,182 +159,216 @@
return $queries;
}
-switch ($_POST["installAction"]) {
- case "check":
- // Check dirs
- if (!is_dir($_POST["serendipityPath"])) {
- $errs[] = $_POST["serendipityPath"]." does not exist, create it.";
- }
- elseif (!is_writable($_POST["serendipityPath"])) {
- $errs[] = "I can't write to ".$_POST["serendipityPath"]." check permissions!";
- }
- elseif (!is_dir($_POST["serendipityPath"].$_POST["uploadPath"])
- && @mkdir($_POST["serendipityPath"].$_POST["uploadPath"], 0770) !== true) {
- $errs[] = $_POST["serendipityPath"].$_POST["uploadPath"]." does not exist and I couldn't create it. You do it.";
- }
+function serendipity_checkInstallation() {
+ global $serendipity;
- // Check paths
- elseif (!is_writable($_POST["serendipityPath"].$_POST["uploadPath"])) {
- $errs[] = "I can't write to ".$_POST["serendipityPath"].$_POST["uploadPath"]."!";
- $errs[] = " -> run <i>chmod g+rwx ".$_POST["serendipityPath"].$_POST["uploadPath"]."</i>";
- }
+ // Check dirs
+ if ( !is_dir($_POST["serendipityPath"]) ) {
+ $errs[] = $_POST["serendipityPath"]." does not exist, create it.";
+ }
+ elseif ( !is_writable($_POST["serendipityPath"]) ) {
+ $errs[] = "I can't write to ".$_POST["serendipityPath"]." check permissions!";
+ }
+ elseif ( !is_dir($_POST["serendipityPath"].$_POST["uploadPath"] ) && @mkdir($_POST["serendipityPath"].$_POST["uploadPath"], 0770) !== true) {
+ $errs[] = $_POST["serendipityPath"].$_POST["uploadPath"]." does not exist and I couldn't create it. You do it.";
+ }
+ elseif ( !is_writable($_POST["serendipityPath"].$_POST["uploadPath"]) ) {
+ $errs[] = "I can't write to ".$_POST["serendipityPath"].$_POST["uploadPath"]."!";
+ $errs[] = " -> run <i>chmod g+rwx ".$_POST["serendipityPath"].$_POST["uploadPath"]."</i>";
+ }
- // Attempt to create the archives directory
- if (!is_dir($_POST["serendipityPath"]."archives") &&
- @mkdir($_POST["serendipityPath"]."archives", 0770) !== true) {
- $errs[] = "Couldn't create the archives directory, you do it:";
- $errs[] = " -> Run <i>mkdir ".$_POST["serendipityPath"]."archives</i>";
- $errs[] = " -> and <i>chmod g+rwx ".$_POST["serendipityPath"]."archives</i>";
- }
+ // Attempt to create the archives directory
+ if ( !is_dir($_POST["serendipityPath"]."archives") && @mkdir($_POST["serendipityPath"]."archives", 0770) !== true ) {
+ $errs[] = "Couldn't create the archives directory, you do it:";
+ $errs[] = " -> Run <i>mkdir ".$_POST["serendipityPath"]."archives</i>";
+ $errs[] = " -> and <i>chmod g+rwx ".$_POST["serendipityPath"]."archives</i>";
+ }
- // Attempt to create the plugins dir
- if (!is_dir($_POST['serendipityPath'] . "plugins") &&
- @mkdir($_POST['serendipityPath'] . "plugins", 0770) !== true) {
- $errs[] = "Couldn't create the plugins directory, you do it:";
- $errs[] = " -> Run <i>mkdir ".$_POST["serendipityPath"]."plugins</i>";
- $errs[] = " -> and <i>chmod g+rwx ".$_POST["serendipityPath"]."plugins</i>";
- }
+ // Attempt to create the plugins dir
+ if ( !is_dir($_POST['serendipityPath'] . "plugins") && @mkdir($_POST['serendipityPath'] . "plugins", 0770) !== true ) {
+ $errs[] = "Couldn't create the plugins directory, you do it:";
+ $errs[] = " -> Run <i>mkdir ".$_POST["serendipityPath"]."plugins</i>";
+ $errs[] = " -> and <i>chmod g+rwx ".$_POST["serendipityPath"]."plugins</i>";
+ }
- $_POST['dbType'] = strtolower(basename($_POST['dbType']));
- foreach ($_POST as $k => $v) {
- if (substr($k, 0, 2) == 'db' || $k == 'serendipityPath') {
- $serendipity[$k] = $v;
- }
- }
- $serendipity['dbType'] = $_POST['dbType'];
- include_once $_POST['serendipityPath'] . '/serendipity_db.inc.php';
-
- // Probe database (do it after the dir stuff, as we need to be able to create the
- // sqlite database)
- serendipity_db_probe($_POST, $errs);
+ // Check imagick
+ if ($_POST["magick"] == "true" && !is_executable($_POST["convert"])) {
+ $errs[] = "Can't execute convert imagemagick binary!";
+ }
- // Check imagick
- if ($_POST["magick"] == "true" && !is_executable($_POST["convert"])) {
- $errs[] = "Can't execute convert binary!";
- }
+ $serendipity['dbType'] = $_POST['dbType'];
+ include_once $_POST['serendipityPath'] . '/serendipity_db.inc.php';
- // Something went wrong
- if (is_array($errs) && count($errs)) {
- echo "<font color='#ff0000'>".implode("<br>", $errs)."</font><p>";
- serendipity_printConfigTemplate(serendipity_parseTemplate("./serendipity_config_local.tpl"), $_POST);
- } else {
- if (IN_serendipity !== true) {
- // Create tables
- echo "Attempting to setup Database...<br>";
- $queries = serendipity_parse_sql_tables('./db.sql');
- $queries = str_replace("{PREFIX}", $_POST['dbPrefix'], $queries);
- foreach ($queries as $query) {
- serendipity_db_schema_import($query);
- }
- if($_POST['want_mail'] == true) {
- $mail_comments = 1;
- } else {
- $mail_comments = 0;
- }
- $enc_pass = md5($_POST['pass']);
- $query = "INSERT INTO $_POST[dbPrefix]authors
- (username, password, email, mail_comments)
- VALUES('$_POST[user]',
- '$enc_pass',
- '$_POST[email]',
- $mail_comments) ";
- serendipity_db_query($query);
- include_once $_POST['serendipityPath'] . '/serendipity_functions_config.inc.php';
- serendipity_set_config_var('template', 'default');
- $text = serendipity_db_escape_string(file_get_contents('./serendipity.css'));
- $query = "INSERT into $_POST[dbPrefix]css (name, data) values ('default', '$text')";
- $res = serendipity_db_query($query);
- if (is_string($res)) {
- echo $res;
- } else {
- echo " Done";
- }
- echo "<br>";
- }
- // Create .htaccess
- $a = file("./htaccess.tpl");
- $fp = @fopen("./.htaccess", "w");
- if (!$fp) {
- echo "<font color='#ff0000'>Error: Could not create <b>.htaccess</b> file, create it yourself\n";
- echo "<br>* Just copy the code below and place it in .htaccess in your serendipity folder:<b><pre>\n";
- echo str_replace("{PREFIX}", $_POST["serendipityHTTPPath"], implode("", $a));
- echo "</pre></b></font>";
- }
- else {
- for($x = 0; $x < count($a); $x++) {
- fwrite($fp, str_replace(array('{PREFIX}','{indexFile}'), array($_POST['serendipityHTTPPath'], $_POST['indexFile']),$a[$x]));
- }
- fclose($fp);
- }
+ // Probe database
+ // (do it after the dir stuff, as we need to be able to create the sqlite database)
+ serendipity_db_probe($_POST, $errs);
- // Save all basic config variables to the database
- $p = serendipity_parseTemplate("./serendipity_config_local.tpl");
- foreach($p as $key=>$value) {
- foreach ($value as $entry) {
- serendipity_set_config_var($entry['name'], $_POST[$entry['name']]);
- }
- }
- // Create a basic configuration file which gives enough information to open
- // the database and get information from the database tables
- $configfp = fopen("./serendipity_config_local.inc.php", "w");
- if (!is_resource($configfp)) {
- echo '<font color="#ff0000">Error! Could not write to ./serendipity_config_local.inc.php</font><br>';
- echo "Try <i>chown -R www:www {$_POST['serendipityPath']}</i><br>";
- echo "followd by <i>chmod 770 {$_POST['serendipityPath']}</i> (change www to the";
- echo "user apache runs as.)</font><br />";
- echo "Once you've done this, hit your browser's \"reload\" button.";
- exit();
- }
+ return $errs;
+}
- fwrite($configfp, "<?php\n");
- fwrite($configfp, "\$serendipity['dbName'] = '{$serendipity['dbName']}';\n");
- fwrite($configfp, "\$serendipity['dbPrefix'] = '{$serendipity['dbPrefix']}';\n");
- fwrite($configfp, "\$serendipity['dbHost'] = '{$serendipity['dbHost']}';\n");
- fwrite($configfp, "\$serendipity['dbUser'] = '{$serendipity['dbUser']}';\n");
- fwrite($configfp, "\$serendipity['dbPass'] = '{$serendipity['dbPass']}';\n");
- fwrite($configfp, "\$serendipity['dbType'] = '{$serendipity['dbType']}';\n");
- fwrite($configfp, "?>\n");
+function serendipity_installDatabase() {
+ global $serendipity;
+ // Create tables
+ $queries = serendipity_parse_sql_tables('./db.sql');
+ $queries = str_replace("{PREFIX}", $_POST['dbPrefix'], $queries);
- fclose($configfp);
+ foreach ($queries as $query) {
+ serendipity_db_schema_import($query);
+ }
- chmod("./serendipity_config_local.inc.php", 0770);
+ if($_POST['want_mail'] == true) {
+ $mail_comments = 1;
+ } else {
+ $mail_comments = 0;
+ }
- if (IN_serendipity !== true) {
- define('IN_serendipity', true);
- /* register default plugins */
- $GLOBALS['serendipity']['dbPrefix'] = $_POST['dbPrefix'];
- $GLOBALS['serendipity']['dbName'] = $_POST['dbName'];
- include_once "serendipity_plugin_api.php";
- serendipity_plugin_api::register_default_plugins();
+ $enc_pass = md5($_POST['pass']);
+ $query = "INSERT INTO $_POST[dbPrefix]authors
+ (username, password, email, mail_comments)
+ VALUES('$_POST[user]',
+ '$enc_pass',
+ '$_POST[email]',
+ $mail_comments) ";
+ serendipity_db_query($query);
- echo "<p>Welcome to serendipity!</b><p>";
- echo "Write down your password: ".$_POST["pass"];
- echo "<br>Your blog is now ready... <a href='".$_POST["serendipityHTTPPath"]."'>Check it out</a>";
- session_destroy();
- } else {
- echo "Configuration variables saved";
- }
- }
- break;
+ include_once $_POST['serendipityPath'] . '/serendipity_functions_config.inc.php';
+ serendipity_set_config_var('template', 'default');
+
+ $text = serendipity_db_escape_string(file_get_contents('./serendipity.css'));
+ $query = "INSERT into $_POST[dbPrefix]css (name, data) values ('default', '$text')";
+ return serendipity_db_query($query);
+}
+
+function serendipity_installFiles() {
+
+ $a = file("./htaccess.tpl");
+ $fp = @fopen("./.htaccess", "w");
+ if ( !$fp ) {
+ $errs[] = "Error: Could not create the <b>.htaccess</b> file, create it yourself\n";
+ $errs[] = "<br>* Just copy the code below and place it in .htaccess in your serendipity folder:<b><pre>\n";
+ $errs[] = str_replace("{PREFIX}", $_POST["serendipityHTTPPath"], implode("", $a));
+ $errs[] = "</pre></b>";
+ return $errs;
+ } else {
+ for($x = 0; $x < count($a); $x++) {
+ fwrite($fp, str_replace(array('{PREFIX}','{indexFile}'), array($_POST['serendipityHTTPPath'], $_POST['indexFile']),$a[$x]));
+ }
+ fclose($fp);
+ return true;
+ }
+
+}
+
+function serendipity_updateConfiguration() {
+ global $serendipity;
+
+ // Save all basic config variables to the database
+ $p = serendipity_parseTemplate("./serendipity_config_local.tpl");
+ foreach($p as $key=>$value) {
+ foreach ($value as $entry) {
+ serendipity_set_config_var($entry['name'], $_POST[$entry['name']]);
+ }
+ }
+
+ // Create a basic configuration file which gives enough information to open
+ // the database and get information from the database tables
+ $configfp = fopen("./serendipity_config_local.inc.php", "w");
+
+ if ( !is_resource($configfp) ) {
+ $errs[] = 'Could not write to ./serendipity_config_local.inc.php';
+ $errs[] = "Try <i>chown -R www:www {$_POST['serendipityPath']}</i>";
+ $errs[] = "Followd by <i>chmod 770 {$_POST['serendipityPath']}</i> (change www to the user apache runs as.)";
+ $errs[] = "Once you've done this, hit your browser's \"reload\" button.";
+ return $errs;
+ }
+
+ fwrite($configfp, "<?php\n");
+ fwrite($configfp, "\t\$serendipity['dbName'] = '{$serendipity['dbName']}';\n");
+ fwrite($configfp, "\t\$serendipity['dbPrefix'] = '{$serendipity['dbPrefix']}';\n");
+ fwrite($configfp, "\t\$serendipity['dbHost'] = '{$serendipity['dbHost']}';\n");
+ fwrite($configfp, "\t\$serendipity['dbUser'] = '{$serendipity['dbUser']}';\n");
+ fwrite($configfp, "\t\$serendipity['dbPass'] = '{$serendipity['dbPass']}';\n");
+ fwrite($configfp, "\t\$serendipity['dbType'] = '{$serendipity['dbType']}';\n");
+ fwrite($configfp, "?>\n");
+
+ fclose($configfp);
+
+ chmod("./serendipity_config_local.inc.php", 0770);
+ return true;
+
+}
+
+switch ( $_POST["installAction"] ) {
+ case "check":
+
+ /* If we already have serendipity installed, all we need to do is write the configuration again */
+ if ( IN_serendipity !== true ) {
+
+ $res = serendipity_checkInstallation();
+ if ( is_array($res) ) {
+ echo "We detected some errors while running some diagnostics on your entered information:<br>";
+ echo "<font color='#ff0000'>- ".implode("<br>", $res)."</font><p>";
+ serendipity_printConfigTemplate(serendipity_parseTemplate("./serendipity_config_local.tpl"), $_POST);
+ die();
+ }
+
+ echo "All entered information appears to be valid.<br>";
+
+ /* We are good to go, lets install databases etc. */
+ echo "Attemping to setup database...";
+ $res = serendipity_installDatabase();
+ if ( !is_string($res) ) {
+ echo " Done<br>";
+ } else {
+ echo $res ."<br>";
+ }
+
+ /* Next are the files, .htaccess */
+ echo "Attemping to write .htaccess file...";
+ $res = serendipity_installFiles();
+ if ( is_array($res) ) {
+ echo "<font color='#ff0000'>- ".implode("<br>", $res)."</font><p>";
+ die();
+ }
+ echo " Done<br>";
+
+ /* We are now installed */
+ define('IN_serendipity', true);
+
+ /* register default plugins */
+ $GLOBALS['serendipity']['dbPrefix'] = $_POST['dbPrefix'];
+ $GLOBALS['serendipity']['dbName'] = $_POST['dbName'];
+
+ include_once "serendipity_plugin_api.php";
+ serendipity_plugin_api::register_default_plugins();
+ echo "<p>Serendipity was successfully installed on your system<br>";
+ echo "Please remember your password: '". $_POST['pass'] ."', your username is '". $_POST['user'] ."'<br>";
+ echo "<br>You can find your new PHP blog here";
+ session_destroy();
+
+ }
+
+ $res = serendipity_updateConfiguration();
+ if ( is_array($res) ) {
+ echo "We detected some errors while trying to update your configuration";
+ echo "<font color='#ff0000'>- ".implode("<br>", $res)."</font><p>";
+ } else {
+ echo "Configuration written & saved";
+ }
+
+ break;
default:
- if (file_exists("./serendipity_config_local.inc.php")) {
- $from = &$serendipity;
- }
- else {
- $from = false;
- }
+ if ( file_exists("./serendipity_config_local.inc.php") ) {
+ $from = &$serendipity;
+ }
+ else {
+ $from = false;
+ }
- serendipity_printConfigTemplate(serendipity_parseTemplate("./serendipity_config_local.tpl"), $from);
+ serendipity_printConfigTemplate(serendipity_parseTemplate("./serendipity_config_local.tpl"), $from);
}
-/*
- * Local Variables:
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: t
- * End:
- */
/* vim: set sts=4 ts=4 expandtab : */
?>
|