1
<?php
2
/**
3
 * StatusNet - the distributed open-source microblogging tool
4
 * Copyright (C) 2009, StatusNet, Inc.
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU Affero General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU Affero General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Affero General Public License
17
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19
20
define('INSTALLDIR', dirname(__FILE__));
21
22
$external_libraries=array(
23
    array(
24
        'name'=>'gettext',
25
        'url'=>'http://us.php.net/manual/en/book.gettext.php',
26
        'check_function'=>'gettext'
27
    ),
28
    array(
29
        'name'=>'PEAR',
30
        'url'=>'http://pear.php.net/',
31
        'deb'=>'php-pear',
32
        'include'=>'PEAR.php',
33
        'check_class'=>'PEAR'
34
    ),
35
    array(
36
        'name'=>'DB',
37
        'pear'=>'DB',
38
        'url'=>'http://pear.php.net/package/DB',
39
        'deb'=>'php-db',
40
        'include'=>'DB/common.php',
41
        'check_class'=>'DB_common'
42
    ),
43
    array(
44
        'name'=>'DB_DataObject',
45
        'pear'=>'DB_DataObject',
46
        'url'=>'http://pear.php.net/package/DB_DataObject',
47
        'include'=>'DB/DataObject.php',
48
        'check_class'=>'DB_DataObject'
49
    ),
50
    array(
51
        'name'=>'Console_Getopt',
52
        'pear'=>'Console_Getopt',
53
        'url'=>'http://pear.php.net/package/Console_Getopt',
54
        'include'=>'Console/Getopt.php',
55
        'check_class'=>'Console_Getopt'
56
    ),
57
    array(
58
        'name'=>'Facebook API',
59
        'url'=>'http://developers.facebook.com/',
60
        'include'=>'facebook/facebook.php',
61
        'check_class'=>'Facebook'
62
    ),
63
    array(
64
        'name'=>'htmLawed',
65
        'url'=>'http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed',
66
        'include'=>'htmLawed/htmLawed.php',
67
        'check_function'=>'htmLawed'
68
    ),
69
    array(
70
        'name'=>'HTTP_Request',
71
        'pear'=>'HTTP_Request',
72
        'url'=>'http://pear.php.net/package/HTTP_Request',
73
        'deb'=>'php-http-request',
74
        'include'=>'HTTP/Request.php',
75
        'check_class'=>'HTTP_Request'
76
    ),
77
    array(
78
        'name'=>'Mail',
79
        'pear'=>'Mail',
80
        'url'=>'http://pear.php.net/package/Mail',
81
        'deb'=>'php-mail',
82
        'include'=>'Mail.php',
83
        'check_class'=>'Mail'
84
    ),
85
    array(
86
        'name'=>'Mail_mimeDecode',
87
        'pear'=>'Mail_mimeDecode',
88
        'url'=>'http://pear.php.net/package/Mail_mimeDecode',
89
        'deb'=>'php-mail-mimedecode',
90
        'include'=>'Mail/mimeDecode.php',
91
        'check_class'=>'Mail_mimeDecode'
92
    ),
93
    array(
94
        'name'=>'Mime_Type',
95
        'pear'=>'Mime_Type',
96
        'url'=>'http://pear.php.net/package/Mime_Type',
97
        'include'=>'MIME/Type.php',
98
        'check_class'=>'Mime_Type'
99
    ),
100
    array(
101
        'name'=>'Net_URL_Mapper',
102
        'pear'=>'Net_URL_Mapper',
103
        'url'=>'http://pear.php.net/package/Net_URL_Mapper',
104
        'include'=>'Net/URL/Mapper.php',
105
        'check_class'=>'Net_URL_Mapper'
106
    ),
107
    array(
108
        'name'=>'Net_Socket',
109
        'pear'=>'Net_Socket',
110
        'url'=>'http://pear.php.net/package/Net_Socket',
111
        'deb'=>'php-net-socket',
112
        'include'=>'Net/Socket.php',
113
        'check_class'=>'Net_Socket'
114
    ),
115
    array(
116
        'name'=>'Net_SMTP',
117
        'pear'=>'Net_SMTP',
118
        'url'=>'http://pear.php.net/package/Net_SMTP',
119
        'deb'=>'php-net-smtp',
120
        'include'=>'Net/SMTP.php',
121
        'check_class'=>'Net_SMTP'
122
    ),
123
    array(
124
        'name'=>'Net_URL',
125
        'pear'=>'Net_URL',
126
        'url'=>'http://pear.php.net/package/Net_URL',
127
        'deb'=>'php-net-url',
128
        'include'=>'Net/URL.php',
129
        'check_class'=>'Net_URL'
130
    ),
131
    array(
132
        'name'=>'Net_URL2',
133
        'pear'=>'Net_URL2',
134
        'url'=>'http://pear.php.net/package/Net_URL2',
135
        'include'=>'Net/URL2.php',
136
        'check_class'=>'Net_URL2'
137
    ),
138
    array(
139
        'name'=>'Services_oEmbed',
140
        'pear'=>'Services_oEmbed',
141
        'url'=>'http://pear.php.net/package/Services_oEmbed',
142
        'include'=>'Services/oEmbed.php',
143
        'check_class'=>'Services_oEmbed'
144
    ),
145
    array(
146
        'name'=>'Stomp',
147
        'url'=>'http://stomp.codehaus.org/PHP',
148
        'include'=>'Stomp.php',
149
        'check_class'=>'Stomp'
150
    ),
151
    array(
152
        'name'=>'System_Command',
153
        'pear'=>'System_Command',
154
        'url'=>'http://pear.php.net/package/System_Command',
155
        'include'=>'System/Command.php',
156
        'check_class'=>'System_Command'
157
    ),
158
    array(
159
        'name'=>'XMPPHP',
160
        'url'=>'http://code.google.com/p/xmpphp',
161
        'include'=>'XMPPHP/XMPP.php',
162
        'check_class'=>'XMPPHP_XMPP'
163
    ),
164
    array(
165
        'name'=>'PHP Markdown',
166
        'url'=>'http://www.michelf.com/projects/php-markdown/',
167
        'include'=>'markdown.php',
168
        'check_class'=>'Markdown_Parser'
169
    ),
170
    array(
171
        'name'=>'OAuth',
172
        'url'=>'http://code.google.com/p/oauth-php',
173
        'include'=>'OAuth.php',
174
        'check_class'=>'OAuthRequest'
175
    ),
176
    array(
177
        'name'=>'Validate',
178
        'pear'=>'Validate',
179
        'url'=>'http://pear.php.net/package/Validate',
180
        'include'=>'Validate.php',
181
        'check_class'=>'Validate'
182
    )
183
);
184
185
function main()
186
{
187
    if (!checkPrereqs())
188
    {
189
        return;
190
    }
191
    
192
    if( $_GET['checklibs'] ){
193
        showLibs();
194
    }else{
195
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
196
            handlePost();
197
        } else {
198
            showForm();
199
        }
200
    }
201
}
202
203
function haveExternalLibrary($external_library)
204
{
205
    if(isset($external_library['include']) && ! include_once($external_library['include'])){
206
        return false;
207
    }
208
    if(isset($external_library['check_function']) && ! function_exists($external_library['check_function'])){
209
        return false;
210
    }
211
    if(isset($external_library['check_class']) && ! class_exists($external_library['check_class'])){
212
        return false;
213
    }
214
    return true;
215
}
216
217
function checkPrereqs()
218
{
219
	$pass = true;
220
221
    if (file_exists(INSTALLDIR.'/config.php')) {
222
         ?><p class="error">Config file &quot;config.php&quot; already exists.</p>
223
         <?php
224
        $pass = false;
225
    }
226
227
    if (version_compare(PHP_VERSION, '5.2.3', '<')) {
228
            ?><p class="error">Require PHP version 5.2.3 or greater.</p><?php
229
		    $pass = false;
230
    }
231
232
    $reqs = array('gd', 'curl',
233
                  'xmlwriter', 'mbstring');
234
235
    foreach ($reqs as $req) {
236
        if (!checkExtension($req)) {
237
            ?><p class="error">Cannot load required extension: <code><?php echo $req; ?></code></p><?php
238
		    $pass = false;
239
        }
240
    }
241
    if (!checkExtension('pgsql') && !checkExtension('mysql')) {
242
      ?><p class="error">Cannot find mysql or pgsql extension. You need one or the other: <code><?php echo $req; ?></code></p><?php
243
                    $pass = false;
244
    }
245
246
	if (!is_writable(INSTALLDIR)) {
247
         ?><p class="error">Cannot write config file to: <code><?php echo INSTALLDIR; ?></code></p>
248
	       <p>On your server, try this command: <code>chmod a+w <?php echo INSTALLDIR; ?></code>
249
         <?php
250
	     $pass = false;
251
	}
252
253
	// Check the subdirs used for file uploads
254
	$fileSubdirs = array('avatar', 'background', 'file');
255
	foreach ($fileSubdirs as $fileSubdir) {
256
		$fileFullPath = INSTALLDIR."/$fileSubdir/";
257
		if (!is_writable($fileFullPath)) {
258
    	     ?><p class="error">Cannot write <?php echo $fileSubdir; ?> directory: <code><?php echo $fileFullPath; ?></code></p>
259
		       <p>On your server, try this command: <code>chmod a+w <?php echo $fileFullPath; ?></code></p>
260
	     <?php
261
		     $pass = false;
262
		}
263
	}
264
265
	return $pass;
266
}
267
268
function checkExtension($name)
269
{
270
    if (!extension_loaded($name)) {
271
        if (!@dl($name.'.so')) {
272
            return false;
273
        }
274
    }
275
    return true;
276
}
277
278
function showLibs()
279
{
280
    global $external_libraries;
281
    $present_libraries=array();
282
    $absent_libraries=array();
283
    foreach($external_libraries as $external_library){
284
        if(haveExternalLibrary($external_library)){
285
            $present_libraries[]=$external_library;
286
        }else{
287
            $absent_libraries[]=$external_library;
288
        }
289
    }
290
    echo<<<E_O_T
291
    <div class="instructions">
292
        <p>Laconica comes bundled with a number of libraries required for the application to work. However, it is best that you use PEAR or you distribution to manage
293
        libraries instead, as they tend to provide security updates faster, and may offer improved performance.</p>
294
        <p>On Debian based distributions, such as Ubuntu, use a package manager (such as &quot;aptitude&quot;, &quot;apt-get&quot;, and &quot;synaptic&quot;) to install the package listed.</p>
295
        <p>On RPM based distributions, such as Red Hat, Fedora, CentOS, Scientific Linux, Yellow Dog Linux and Oracle Enterprise Linux, use a package manager (such as &quot;yum&quot;, &quot;apt-rpm&quot;, and &quot;up2date&quot;) to install the package listed.</p>
296
        <p>On servers without a package manager (such as Windows), or if the library is not packaged for your distribution, you can use PHP's PEAR to install the library. Simply run &quot;pear install &lt;name&gt;&quot;.</p>
297
    </div>
298
    <h2>Absent Libraries</h2>
299
    <ul id="absent_libraries">
300
E_O_T;
301
    foreach($absent_libraries as $library)
302
    {
303
        echo '<li>';
304
        if($library['url']){
305
            echo '<a href=">'.$library['url'].'">'.htmlentities($library['name']).'</a>';
306
        }else{
307
            echo htmlentities($library['name']);
308
        }
309
        echo '<ul>';
310
        if($library['deb']){
311
            echo '<li class="deb package">deb: <a href="apt:' . urlencode($library['deb']) . '">' . htmlentities($library['deb']) . '</a></li>';
312
        }
313
        if($library['rpm']){
314
            echo '<li class="rpm package">rpm: ' . htmlentities($library['rpm']) . '</li>';
315
        }
316
        if($library['pear']){
317
            echo '<li class="pear package">pear: ' . htmlentities($library['pear']) . '</li>';
318
        }
319
        echo '</ul>';
320
    }
321
    echo<<<E_O_T
322
    </ul>
323
    <h2>Installed Libraries</h2>
324
    <ul id="present_libraries">
325
E_O_T;
326
    foreach($present_libraries as $library)
327
    {
328
        echo '<li>';
329
        if($library['url']){
330
            echo '<a href=">'.$library['url'].'">'.htmlentities($library['name']).'</a>';
331
        }else{
332
            echo htmlentities($library['name']);
333
        }
334
        echo '</li>';
335
    }
336
    echo<<<E_O_T
337
    </ul>
338
E_O_T;
339
}
340
341
function showForm()
342
{
343
    echo<<<E_O_T
344
        </ul>
345
    </dd>
346
</dl>
347
<dl id="page_notice" class="system_notice">
348
    <dt>Page notice</dt>
349
    <dd>
350
        <div class="instructions">
351
            <p>Enter your database connection information below to initialize the database.</p>
352
            <p>Laconica bundles a number of libraries for ease of installation. <a href="?checklibs=true">You can see what bundled libraries you are using, versus what libraries are installed on your server.</a>
353
        </div>
354
    </dd>
355
</dl>
356
<form method="post" action="install.php" class="form_settings" id="form_install">
357
    <fieldset>
358
        <legend>Connection settings</legend>
359
        <ul class="form_data">
360
            <li>
361
                <label for="sitename">Site name</label>
362
                <input type="text" id="sitename" name="sitename" />
363
                <p class="form_guide">The name of your site</p>
364
            </li>
365
            <li>
366
                <label for="fancy-enable">Fancy URLs</label>
367
                <input type="radio" name="fancy" id="fancy-enable" value="enable" checked='checked' /> enable<br />
368
                <input type="radio" name="fancy" id="fancy-disable" value="" /> disable<br />
369
                <p class="form_guide" id='fancy-form_guide'>Enable fancy (pretty) URLs. Auto-detection failed, it depends on Javascript.</p>
370
            </li>
371
            <li>
372
                <label for="host">Hostname</label>
373
                <input type="text" id="host" name="host" />
374
                <p class="form_guide">Database hostname</p>
375
            </li>
376
            <li>
377
378
                <label for="dbtype">Type</label>
379
                <input type="radio" name="dbtype" id="fancy-mysql" value="mysql" checked='checked' /> MySQL<br />
380
                <input type="radio" name="dbtype" id="dbtype-pgsql" value="pgsql" /> PostgreSQL<br />
381
                <p class="form_guide">Database type</p>
382
            </li>
383
384
            <li>
385
                <label for="database">Name</label>
386
                <input type="text" id="database" name="database" />
387
                <p class="form_guide">Database name</p>
388
            </li>
389
            <li>
390
                <label for="username">Username</label>
391
                <input type="text" id="username" name="username" />
392
                <p class="form_guide">Database username</p>
393
            </li>
394
            <li>
395
                <label for="password">Password</label>
396
                <input type="password" id="password" name="password" />
397
                <p class="form_guide">Database password (optional)</p>
398
            </li>
399
        </ul>
400
        <input type="submit" name="submit" class="submit" value="Submit" />
401
    </fieldset>
402
</form>
403
404
E_O_T;
405
}
406
407
function updateStatus($status, $error=false)
408
{
409
?>
410
                <li <?php echo ($error) ? 'class="error"': ''; ?>><?php echo $status;?></li>
411
412
<?php
413
}
414
415
function handlePost()
416
{
417
?>
418
419
<?php
420
    $host     = $_POST['host'];
421
    $dbtype   = $_POST['dbtype'];
422
    $database = $_POST['database'];
423
    $username = $_POST['username'];
424
    $password = $_POST['password'];
425
    $sitename = $_POST['sitename'];
426
    $fancy    = !empty($_POST['fancy']);
427
    $server = $_SERVER['HTTP_HOST'];
428
    $path = substr(dirname($_SERVER['PHP_SELF']), 1);
429
430
?>
431
    <dl class="system_notice">
432
        <dt>Page notice</dt>
433
        <dd>
434
            <ul>
435
<?php
436
	$fail = false;
437
438
    if (empty($host)) {
439
        updateStatus("No hostname specified.", true);
440
		$fail = true;
441
    }
442
443
    if (empty($database)) {
444
        updateStatus("No database specified.", true);
445
		$fail = true;
446
    }
447
448
    if (empty($username)) {
449
        updateStatus("No username specified.", true);
450
		$fail = true;
451
    }
452
453
//     if (empty($password)) {
454
//         updateStatus("No password specified.", true);
455
// 		$fail = true;
456
//     }
457
458
    if (empty($sitename)) {
459
        updateStatus("No sitename specified.", true);
460
		$fail = true;
461
    }
462
463
    if($fail){
464
            showForm();
465
        return;
466
    }
467
468
    // FIXME: use PEAR::DB or PDO instead of our own switch
469
470
    switch($dbtype) {
471
        case 'mysql':
472
            $db = mysql_db_installer($host, $database, $username, $password);
473
            break;
474
        case 'pgsql':
475
            $db = pgsql_db_installer($host, $database, $username, $password);
476
            break;
477
        default:
478
    }
479
480
    if (!$db) {
481
        // database connection failed, do not move on to create config file.
482
        return false;
483
    }
484
485
    updateStatus("Writing config file...");
486
    $res = writeConf($sitename, $server, $path, $fancy, $db);
487
488
    if (!$res) {
489
        updateStatus("Can't write config file.", true);
490
        showForm();
491
        return;
492
    }
493
494
    /*
495
        TODO https needs to be considered
496
    */
497
    $link = "http://".$server.'/'.$path;
498
499
    updateStatus("StatusNet has been installed at $link");
500
    updateStatus("You can visit your <a href='$link'>new StatusNet site</a>.");
501
?>
502
503
<?php
504
}
505
506
function pgsql_db_installer($host, $database, $username, $password) {
507
  $connstring = "dbname=$database host=$host user=$username";
508
509
  //No password would mean trust authentication used.
510
  if (!empty($password)) {
511
    $connstring .= " password=$password";
512
  }
513
  updateStatus("Starting installation...");
514
  updateStatus("Checking database...");
515
  $conn = pg_connect($connstring);
516
517
  if ($conn ===false) {
518
    updateStatus("Failed to connect to database: $connstring");
519
    showForm();
520
    return false;
521
  }
522
523
  //ensure database encoding is UTF8
524
  $record = pg_fetch_object(pg_query($conn, 'SHOW server_encoding'));
525
  if ($record->server_encoding != 'UTF8') {
526
    updateStatus("StatusNet requires UTF8 character encoding. Your database is ". htmlentities($record->server_encoding));
527
    showForm();
528
    return false;
529
  }
530
531
  updateStatus("Running database script...");
532
  //wrap in transaction;
533
  pg_query($conn, 'BEGIN');
534
  $res = runDbScript(INSTALLDIR.'/db/statusnet_pg.sql', $conn, 'pgsql');
535
536
  if ($res === false) {
537
      updateStatus("Can't run database script.", true);
538
      showForm();
539
      return false;
540
  }
541
  foreach (array('sms_carrier' => 'SMS carrier',
542
                'notice_source' => 'notice source',
543
                'foreign_services' => 'foreign service')
544
          as $scr => $name) {
545
      updateStatus(sprintf("Adding %s data to database...", $name));
546
      $res = runDbScript(INSTALLDIR.'/db/'.$scr.'.sql', $conn, 'pgsql');
547
      if ($res === false) {
548
          updateStatus(sprintf("Can't run %d script.", $name), true);
549
          showForm();
550
          return false;
551
      }
552
  }
553
  pg_query($conn, 'COMMIT');
554
555
  if (empty($password)) {
556
    $sqlUrl = "pgsql://$username@$host/$database";
557
  }
558
  else {
559
    $sqlUrl = "pgsql://$username:$password@$host/$database";
560
  }
561
562
  $db = array('type' => 'pgsql', 'database' => $sqlUrl);
563
564
  return $db;
565
}
566
567
function mysql_db_installer($host, $database, $username, $password) {
568
  updateStatus("Starting installation...");
569
  updateStatus("Checking database...");
570
571
  $conn = mysql_connect($host, $username, $password);
572
  if (!$conn) {
573
      updateStatus("Can't connect to server '$host' as '$username'.", true);
574
      showForm();
575
      return false;
576
  }
577
  updateStatus("Changing to database...");
578
  $res = mysql_select_db($database, $conn);
579
  if (!$res) {
580
      updateStatus("Can't change to database.", true);
581
      showForm();
582
      return false;
583
  }
584
  updateStatus("Running database script...");
585
  $res = runDbScript(INSTALLDIR.'/db/statusnet.sql', $conn);
586
  if ($res === false) {
587
      updateStatus("Can't run database script.", true);
588
      showForm();
589
      return false;
590
  }
591
  foreach (array('sms_carrier' => 'SMS carrier',
592
                'notice_source' => 'notice source',
593
                'foreign_services' => 'foreign service')
594
          as $scr => $name) {
595
      updateStatus(sprintf("Adding %s data to database...", $name));
596
      $res = runDbScript(INSTALLDIR.'/db/'.$scr.'.sql', $conn);
597
      if ($res === false) {
598
          updateStatus(sprintf("Can't run %d script.", $name), true);
599
          showForm();
600
          return false;
601
      }
602
  }
603
604
      $sqlUrl = "mysqli://$username:$password@$host/$database";
605
      $db = array('type' => 'mysql', 'database' => $sqlUrl);
606
      return $db;
607
}
608
609
function writeConf($sitename, $server, $path, $fancy, $db)
610
{
611
    // assemble configuration file in a string
612
    $cfg =  "<?php\n".
613
            "if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }\n\n".
614
615
            // site name
616
            "\$config['site']['name'] = '$sitename';\n\n".
617
618
            // site location
619
            "\$config['site']['server'] = '$server';\n".
620
            "\$config['site']['path'] = '$path'; \n\n".
621
622
            // checks if fancy URLs are enabled
623
            ($fancy ? "\$config['site']['fancy'] = true;\n\n":'').
624
625
            // database
626
            "\$config['db']['database'] = '{$db['database']}';\n\n".
627
            ($db['type'] == 'pgsql' ? "\$config['db']['quote_identifiers'] = true;\n\n":'').
628
            "\$config['db']['type'] = '{$db['type']}';\n\n".
629
630
            "?>";
631
    // write configuration file out to install directory
632
    $res = file_put_contents(INSTALLDIR.'/config.php', $cfg);
633
634
    return $res;
635
}
636
637
function runDbScript($filename, $conn, $type = 'mysql')
638
{
639
    $sql = trim(file_get_contents($filename));
640
    $stmts = explode(';', $sql);
641
    foreach ($stmts as $stmt) {
642
        $stmt = trim($stmt);
643
        if (!mb_strlen($stmt)) {
644
            continue;
645
        }
646
        // FIXME: use PEAR::DB or PDO instead of our own switch
647
        switch ($type) {
648
        case 'mysql':
649
            $res = mysql_query($stmt, $conn);
650
            if ($res === false) {
651
                $error = mysql_error();
652
            }
653
            break;
654
        case 'pgsql':
655
            $res = pg_query($conn, $stmt);
656
            if ($res === false) {
657
                $error = pg_last_error();
658
            }
659
            break;
660
        default:
661
            updateStatus("runDbScript() error: unknown database type ". $type ." provided.");
662
        }
663
        if ($res === false) {
664
            updateStatus("ERROR ($error) for SQL '$stmt'");
665
            return $res;
666
        }
667
    }
668
    return true;
669
}
670
671
?>
672
<?php echo"<?"; ?> xml version="1.0" encoding="UTF-8" <?php echo "?>"; ?>
673
<!DOCTYPE html>
674
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en_US" lang="en_US">
675
    <head>
676
        <title>Install StatusNet</title>
677
	<link rel="shortcut icon" href="favicon.ico"/>
678
        <link rel="stylesheet" type="text/css" href="theme/default/css/display.css?version=0.8" media="screen, projection, tv"/>
679
        <!--[if IE]><link rel="stylesheet" type="text/css" href="theme/base/css/ie.css?version=0.8" /><![endif]-->
680
        <!--[if lte IE 6]><link rel="stylesheet" type="text/css" theme/base/css/ie6.css?version=0.8" /><![endif]-->
681
        <!--[if IE]><link rel="stylesheet" type="text/css" href="theme/default/css/ie.css?version=0.8" /><![endif]-->
682
        <script src="js/jquery.min.js"></script>
683
        <script src="js/install.js"></script>
684
    </head>
685
    <body id="install">
686
        <div id="wrap">
687
            <div id="header">
688
                <address id="site_contact" class="vcard">
689
                    <a class="url home bookmark" href=".">
690
                        <img class="logo photo" src="theme/default/logo.png" alt="StatusNet"/>
691
                        <span class="fn org">StatusNet</span>
692
                    </a>
693
                </address>
694
            </div>
695
            <div id="core">
696
                <div id="content">
697
                    <h1>Install StatusNet</h1>
698
<?php main(); ?>
699
                </div>
700
            </div>
701
        </div>
702
    </body>
703
</html>