Project

General

Profile

Download (34 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	installer.php (pfSense installer)
4
	part of pfSense (http://www.pfsense.com/)
5
	Copyright (C) 2010 Scott Ullrich <sullrich@gmail.com>
6
	All rights reserved.
7

    
8
	Redistribution and use in source and binary forms, with or without
9
	modification, are permitted provided that the following conditions are met:
10

    
11
	1. Redistributions of source code must retain the above copyright notice,
12
	   this list of conditions and the following disclaimer.
13

    
14
	2. Redistributions in binary form must reproduce the above copyright
15
	   notice, this list of conditions and the following disclaimer in the
16
	   documentation and/or other materials provided with the distribution.
17

    
18
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
19
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
22
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
	POSSIBILITY OF SUCH DAMAGE.
28
*/
29

    
30
$nocsrf = true;
31

    
32
require("globals.inc");
33
require("guiconfig.inc");
34

    
35
define('PC_SYSINSTALL', '/usr/sbin/pc-sysinstall/pc-sysinstall/pc-sysinstall.sh');
36

    
37
if($g['platform'] == "pfSense" or $g['platform'] == "nanobsd") {
38
	Header("Location: /");
39
	exit;
40
}
41

    
42
// Main switch dispatcher
43
switch ($_REQUEST['state']) {
44
	case "update_installer_status":
45
		update_installer_status();
46
		exit;
47
	case "custominstall":
48
		installer_custom();
49
		exit;
50
	case "begin_install":
51
		installing_gui();
52
		begin_install();
53
		exit;
54
	case "verify_before_install":
55
		verify_before_install();
56
		exit;
57
	default:
58
		installer_main();	
59
}
60

    
61
function write_out_pc_sysinstaller_config($disks, $bootmanager = "bsd") {
62
	$diskareas = "";
63
	$fd = fopen("/usr/sbin/pc-sysinstall/examples/pfSense-install.cfg", "w");
64
	if(!$fd) {
65
		return true;
66
	}
67
	if($bootmanager == "") 
68
	 	$bootmanager = "none";
69
	$numdisks = -1;
70
	$lastdisk = "";
71
	$diskdefs = "";
72
	// Run through the disks and create the conf areas for pc-sysinstaller
73
	foreach($disks as $disksa) {
74
		$fstype = $disksa['fstype'];
75
		$size = $disksa['size'];
76
		$mountpoint = $disksa['mountpoint'];
77
		$disk = $disksa['disk'];
78
		if($disk <> $lastdisk) {
79
			$lastdisk = $disk;
80
			$numdisks++;
81
			$diskdefs .= "disk{$numdisks}={$disk}\n";
82
		}
83
		$diskareas .= "disk{$numdisks}-part={$fstype} {$size} {$mountpoint} \n";
84
		if($encpass)
85
			$diskareas .= "encpass={$encpass}\n";
86
	}
87
	
88
	$config = <<<EOF
89
# Sample configuration file for an installation using pc-sysinstall
90
# This file was automatically generated by installer.php
91
 
92
installMode=fresh
93
installInteractive=yes
94
installType=FreeBSD
95
installMedium=LiveCD
96

    
97
# Set the disk parameters
98
{$diskdefs}
99
partition=all
100
bootManager={$bootmanager}
101
commitDiskPart
102

    
103
# Setup the disk label
104
# All sizes are expressed in MB
105
# Avail FS Types, UFS, UFS+S, UFS+J, ZFS, SWAP
106
# Size 0 means use the rest of the slice size
107
# Alternatively, you can append .eli to any of
108
# the above filesystem types to encrypt that disk.
109
# If you with to use a passphrase with this 
110
# encrypted partition, on the next line 
111
# the flag "encpass=" should be entered:
112
# encpass=mypass
113
# disk0-part=UFS 500 /boot
114
# disk0-part=UFS.eli 500 /
115
# disk0-part=UFS.eli 500 /usr
116
{$diskareas}
117

    
118
# Do it now!
119
commitDiskLabel
120

    
121
# Set if we are installing via optical, USB, or FTP
122
installType=FreeBSD
123

    
124
packageType=cpdup
125

    
126
# Optional Components
127
cpdupPaths=boot,COPYRIGHT,bin,conf,conf.default,dev,etc,home,kernels,libexec,lib,root,sbin,usr,var
128

    
129
# runExtCommand=chmod a+rx /usr/local/bin/after_installation_routines.sh ; cd / ; /usr/local/bin/after_installation_routines.sh
130
EOF;
131
	fwrite($fd, $config);
132
	fclose($fd);
133
	return;
134
}
135

    
136
function start_installation() {
137
	global $g, $fstype, $savemsg;
138
	if(file_exists("/tmp/install_complete"))
139
		return;
140
	$ps_running = exec("/bin/ps awwwux | /usr/bin/grep -v grep | /usr/bin/grep 'sh /tmp/installer.sh'");
141
	if($ps_running)	
142
		return;
143
	$fd = fopen("/tmp/installer.sh", "w");
144
	if(!$fd) {
145
		die(gettext("Could not open /tmp/installer.sh for writing"));
146
		exit;
147
	}
148
	fwrite($fd, "/bin/rm /tmp/.pc-sysinstall/pc-sysinstall.log 2>/dev/null\n");
149
	fwrite($fd, "/usr/sbin/pc-sysinstall/pc-sysinstall/pc-sysinstall.sh -c /usr/sbin/pc-sysinstall/examples/pfSense-install.cfg \n");
150
	fwrite($fd, "/bin/chmod a+rx /usr/local/bin/after_installation_routines.sh\n");
151
	fwrite($fd, "cd / && /usr/local/bin/after_installation_routines.sh\n");
152
	fwrite($fd, "/bin/mkdir /mnt/tmp\n");
153
	fwrite($fd, "/usr/bin/touch /tmp/install_complete\n");
154
	fclose($fd);
155
	exec("/bin/chmod a+rx /tmp/installer.sh");
156
	mwexec_bg("/bin/sh /tmp/installer.sh");
157
}
158

    
159
function installer_find_first_disk() {
160
	global $g, $fstype, $savemsg;
161
	$disk = `/usr/sbin/pc-sysinstall/pc-sysinstall/pc-sysinstall.sh disk-list | head -n1 | cut -d':' -f1`;
162
	return trim($disk);
163
}
164

    
165
function pcsysinstall_get_disk_info($diskname) {
166
	global $g, $fstype, $savemsg;
167
	$disk = split("\n", `/usr/sbin/pc-sysinstall/pc-sysinstall/pc-sysinstall.sh disk-list`);
168
	$disks_array = array();
169
	foreach($disk as $d) {
170
		$disks_info = split(":", $d);
171
		$tmp_array = array();
172
		if($disks_info[0] == $diskname) {
173
			$disk_info = split("\n", `/usr/sbin/pc-sysinstall/pc-sysinstall/pc-sysinstall.sh disk-info {$disks_info[0]}`);
174
			$disk_info_split = split("=", $disk_info);
175
			foreach($disk_info as $di) { 
176
				$di_s = split("=", $di);
177
				if($di_s[0])
178
					$tmp_array[$di_s[0]] = $di_s[1];
179
			}
180
			$tmp_array['disk'] = trim($disks_info[0]);
181
			$tmp_array['desc'] = trim(htmlentities($disks_info[1]));
182
			return $tmp_array;
183
		}
184
	}
185
}
186

    
187
// Return an array with all disks information.
188
function installer_find_all_disks() {
189
	global $g, $fstype, $savemsg;
190
	$disk = split("\n", `/usr/sbin/pc-sysinstall/pc-sysinstall/pc-sysinstall.sh disk-list`);
191
	$disks_array = array();
192
	foreach($disk as $d) {
193
		if(!$d) 
194
			continue;
195
		$disks_info = split(":", $d);
196
		$tmp_array = array();
197
		$disk_info = split("\n", `/usr/sbin/pc-sysinstall/pc-sysinstall/pc-sysinstall.sh disk-info {$disks_info[0]}`);
198
		foreach($disk_info as $di) { 
199
			$di_s = split("=", $di);
200
			if($di_s[0])
201
				$tmp_array[$di_s[0]] = $di_s[1];
202
		}
203
		$tmp_array['disk'] = trim($disks_info[0]);
204
		$tmp_array['desc'] = trim(htmlentities($disks_info[1]));
205
		$disks_array[] = $tmp_array;
206
	}
207
	return $disks_array;
208
}
209

    
210
function update_installer_status() {
211
	global $g, $fstype, $savemsg;
212
	// Ensure status files exist
213
	if(!file_exists("/tmp/installer_installer_running"))
214
		touch("/tmp/installer_installer_running");
215
	$status = `cat /tmp/.pc-sysinstall/pc-sysinstall.log`;
216
	$status = str_replace("\n", "\\n", $status);
217
	$status = str_replace("\n", "\\r", $status);
218
	echo "this.document.forms[0].installeroutput.value='$status';\n";
219
	echo "this.document.forms[0].installeroutput.scrollTop = this.document.forms[0].installeroutput.scrollHeight;\n";	
220
	// Find out installer progress
221
	$progress = "5";
222
	if(strstr($status, "Running: dd")) 
223
		$progress = "6";
224
	if(strstr($status, "Running: gpart create -s GPT")) 
225
		$progress = "7";
226
	if(strstr($status, "Running: gpart bootcode")) 
227
		$progress = "7";
228
	if(strstr($status, "Running: newfs -U")) 
229
		$progress = "8";
230
	if(strstr($status, "Running: sync")) 
231
		$progress = "9";
232
	if(strstr($status, "/boot /mnt/boot")) 
233
		$progress = "10";
234
	if(strstr($status, "/COPYRIGHT /mnt/COPYRIGHT"))
235
		$progress = "11";
236
	if(strstr($status, "/bin /mnt/bin"))
237
		$progress = "12";
238
	if(strstr($status, "/conf /mnt/conf"))
239
		$progress = "15";
240
	if(strstr($status, "/conf.default /mnt/conf.default"))
241
		$progress = "20";
242
	if(strstr($status, "/dev /mnt/dev"))
243
		$progress = "25";
244
	if(strstr($status, "/etc /mnt/etc"))
245
		$progress = "30";
246
	if(strstr($status, "/home /mnt/home"))
247
		$progress = "35";
248
	if(strstr($status, "/kernels /mnt/kernels"))
249
		$progress = "40";
250
	if(strstr($status, "/libexec /mnt/libexec"))
251
		$progress = "50";
252
	if(strstr($status, "/lib /mnt/lib"))
253
		$progress = "60";
254
	if(strstr($status, "/root /mnt/root"))
255
		$progress = "70";
256
	if(strstr($status, "/sbin /mnt/sbin"))
257
		$progress = "75";
258
	if(strstr($status, "/sys /mnt/sys"))
259
		$progress = "80";
260
	if(strstr($status, "/usr /mnt/usr"))
261
		$progress = "95";
262
	if(strstr($status, "/usr /mnt/usr"))
263
		$progress = "90";
264
	if(strstr($status, "/var /mnt/var"))
265
		$progress = "95";
266
	if(strstr($status, "cap_mkdb /etc/login.conf"))
267
		$progress = "96";
268
	if(strstr($status, "Setting hostname"))
269
		$progress = "97";
270
	if(strstr($status, "umount -f /mnt"))
271
		$progress = "98";
272
	if(strstr($status, "umount -f /mnt"))
273
		$progress = "99";
274
	if(strstr($status, "Installation finished"))
275
		$progress = "100";
276
	// Check for error and bail if we see one.
277
	if(stristr($status, "error")) {
278
		$error = true;
279
		echo "\$('installerrunning').innerHTML='<img class=\"infoboxnpimg\" src=\"/themes/{$g['theme']}/images/icons/icon_exclam.gif\"> <font size=\"2\"><b>An error occurred.  Aborting installation.  <a href=\"/installer\">Back</a> to webInstaller'; ";
280
		echo "\$('progressbar').style.width='100%';\n";
281
		unlink_if_exists("/tmp/install_complete");
282
		return;
283
	}
284
	$running_old = trim(file_get_contents("/tmp/installer_installer_running"));
285
	if($installer_running <> "running") {
286
		$ps_running = exec("/bin/ps awwwux | /usr/bin/grep -v grep | /usr/bin/grep 'sh /tmp/installer.sh'");
287
		if($ps_running)	{
288
			$running = "\$('installerrunning').innerHTML='<table><tr><td valign=\"middle\"><img src=\"/themes/{$g['theme']}/images/misc/loader.gif\"></td><td valign=\"middle\">&nbsp;<font size=\"2\"><b>Installer running ({$progress}% completed)...</td></tr></table>'; ";
289
			if($running_old <> $running) {
290
				echo $running;
291
				file_put_contents("/tmp/installer_installer_running", "$running");			
292
			}
293
		}
294
	}
295
	if($progress) 
296
		echo "\$('progressbar').style.width='{$progress}%';\n";
297
	if(file_exists("/tmp/install_complete")) {
298
		echo "\$('installerrunning').innerHTML='<img class=\"infoboxnpimg\" src=\"/themes/{$g['theme']}/images/icons/icon_exclam.gif\"> <font size=\"+1\">Installation completed.  Please <a href=\"/reboot.php\">reboot</a> to continue';\n";
299
		echo "\$('pbdiv').Fade();\n";
300
		unlink_if_exists("/tmp/installer.sh");
301
		file_put_contents("/tmp/installer_installer_running", "finished");
302
	}
303
}
304

    
305
function update_installer_status_win($status) {
306
	global $g, $fstype, $savemsg;
307
	echo "<script type=\"text/javascript\">\n";
308
	echo "	\$('installeroutput').value = '" . str_replace(htmlentities($status), "\n", "") . "';\n";
309
	echo "</script>";
310
}
311

    
312
function begin_install() {
313
	global $g, $savemsg;
314
	if(file_exists("/tmp/install_complete"))
315
		return;
316
	unlink_if_exists("/tmp/install_complete");
317
	update_installer_status_win(sprintf(gettext("Beginning installation on disk %s."),$disk));
318
	start_installation();
319
}
320

    
321
function head_html() {
322
	global $g, $fstype, $savemsg;
323
	echo <<<EOF
324
<html>
325
	<head>
326
		<style type='text/css'>
327
			hr {
328
				border: 0;
329
				color: #000000;
330
				background-color: #000000;
331
				height: 1px;
332
				width: 100%;
333
				text-align: left;
334
			}
335
			a:link { 
336
				color: #000000;
337
				text-decoration:underline;
338
				font-size:14;
339
			}
340
			a:visited { 
341
				color: #000000;
342
				text-decoration:underline;
343
				font-size:14;
344
			}
345
			a:hover { 
346
				color: #FFFF00;
347
				text-decoration: none;
348
				font-size:14;
349
			}
350
			a:active { 
351
				color: #FFFF00;
352
				text-decoration:underline;
353
				font-size:14;
354
			}
355
		</style>
356
	</head>
357
EOF;
358

    
359
}
360

    
361
function body_html() {
362
	global $g, $fstype, $savemsg;
363
	$pfSversion = str_replace("\n", "", file_get_contents("/etc/version"));
364
	if(strstr($pfSversion, "1.2")) 
365
		$one_two = true;
366
	$pgtitle = array("{$g['product_name']}", gettext("Installer"));
367
	include("head.inc");
368
	echo <<<EOF
369
	<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
370
	<script src="/javascript/scriptaculous/prototype.js" type="text/javascript"></script>
371
	<script type="text/javascript">
372
		function getinstallerprogress() {
373
			url = '/installer/installer.php';
374
			pars = 'state=update_installer_status';
375
			callajax(url, pars, installcallback);
376
		}
377
		function callajax(url, pars, activitycallback) {
378
			var myAjax = new Ajax.Request(
379
				url,
380
				{
381
					method: 'post',
382
					parameters: pars,
383
					onComplete: activitycallback
384
				});
385
		}
386
		function installcallback(transport) {
387
			setTimeout('getinstallerprogress()', 2000);
388
			eval(transport.responseText);
389
		}
390
	</script>
391
EOF;
392

    
393
	if($one_two)
394
		echo "<p class=\"pgtitle\">{$pgtitle}</font></p>";
395

    
396
	if ($savemsg) print_info_box($savemsg); 
397
}
398

    
399
function end_html() {
400
	global $g, $fstype, $savemsg;
401
	echo "</form>";
402
	echo "</body>";
403
	echo "</html>";
404
}
405

    
406
function template() {
407
	global $g, $fstype, $savemsg;
408
	head_html();
409
	body_html();
410
	echo <<<EOF
411
	<div id="mainlevel">
412
		<table width="100%" border="0" cellpadding="0" cellspacing="0">
413
	 		<tr>
414
	    		<td>
415
					<div id="mainarea">
416
						<table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">
417
							<tr>
418
	     						<td class="tabcont" >
419
	      							<form action="installer.php" method="post">
420
									<div id="pfsensetemplate">
421

    
422

    
423
									</div>
424
	     						</td>
425
							</tr>
426
						</table>
427
					</div>
428
				</td>
429
			</tr>
430
		</table>
431
	</div>
432
EOF;
433
	end_html();
434
}
435

    
436
function verify_before_install() {
437
	global $g, $fstype, $savemsg;
438
	$encrypted_root = false;
439
	$non_encrypted_boot = false;
440
	$non_encrypted_notice = false;
441
	head_html();
442
	body_html();
443
	page_table_start($g['product_name'] . " installer - Verify final installation settings");
444
	// If we are visiting this step from anything but the row editor / custom install
445
	// then load the on disk layout contents if they are available.
446
	if(!$_REQUEST['fstype0'] && file_exists("/tmp/webInstaller_disk_layout.txt")) {
447
		$disks = unserialize(file_get_contents("/tmp/webInstaller_disk_layout.txt"));
448
		$bootmanager = unserialize(file_get_contents("/tmp/webInstaller_disk_bootmanager.txt"));
449
		$restored_layout_from_file = true;
450
		$restored_layout_txt = "The previous disk layout was restored from disk";
451
	}
452
	if(!$bootmanager) 
453
		$bootmanager = $_REQUEST['bootmanager'];
454
	echo "\n<!--" . print_r($_REQUEST, true) . " -->\n";
455
	$disk = pcsysinstall_get_disk_info(htmlspecialchars($_REQUEST['disk']));
456
	$disksize = format_bytes($disk['size'] * 1048576);
457
	$disks = array();
458
	// Loop through posted items and create an array
459
	for($x=0; $x<99; $x++) { // XXX: Make this more optimal
460
		if(!$_REQUEST['fstype' . $x])
461
			continue;
462
		$tmparray = array();
463
		if($_REQUEST['fstype' . $x] <> "SWAP") {
464
			$tmparray['mountpoint'] = $_REQUEST['mountpoint' . $x];
465
			// Check for encrypted slice /
466
			if(stristr($_REQUEST['fstype' . $x], ".eli")) {
467
				if($tmparray['mountpoint'] == "/") 
468
					$encrypted_root = true;
469
			}
470
			// Check if we have a non-encrypted /boot
471
			if($tmparray['mountpoint'] == "/boot") 	{
472
				if(!stristr($_REQUEST['fstype' . $x], ".eli"))
473
					$non_encrypted_boot = true;
474
			}
475
			if($tmparray['mountpoint'] == "/conf") {	
476
				$tmparray['mountpoint'] = "/conf{$x}";
477
				$error_txt[] = "/conf is not an allowed mount point and has been renamed to /conf{$x}.";
478
			}
479
		} else  {
480
			$tmparray['mountpoint'] = "none";
481
		}
482
		// If we have an encrypted /root and lack a non encrypted /boot, throw an error/warning
483
		if($encrypted_root && !$non_encrypted_boot && !$non_encrypted_notice) {
484
			$error_txt[] = "A non-encrypted /boot slice is required when encrypting the / slice";
485
			$non_encrypted_notice = true;
486
		}
487
		$tmparray['disk'] = $_REQUEST['disk' . $x];
488
		$tmparray['fstype'] = $_REQUEST['fstype' . $x];
489
		$tmparray['size'] = $_REQUEST['size' . $x];
490
		$tmparray['encpass'] = $_REQUEST['encpass' . $x];
491
		$disks[] = $tmparray;
492
	}
493
	echo "\n<!-- " . print_r($disks, true) . " --> \n";
494
	$bootmanagerupper = strtoupper($bootmanager);
495
	echo <<<EOFAMBAC
496
	<form method="post" action="installer.php">
497
	<input type="hidden" name="fstype" value="{$fstype_echo}">
498
	<input type="hidden" name="disk" value="{$disk_echo}">
499
	<input type="hidden" name="state" value="begin_install">
500
	<input type="hidden" name="swapsize" value="{$swapsize}">
501
	<input type="hidden" name="encpass" value="{$encpass}">
502
	<input type="hidden" name="bootmanager" value="{$bootmanager}">
503
	<div id="mainlevel">
504
		<table width="800" border="0" cellpadding="0" cellspacing="0">
505
	 		<tr>
506
	    		<td>
507
					<div id="mainarea">
508
						<table width="100%" border="0" cellpadding="0" cellspacing="0">
509
							<tr>
510
	     						<td >
511
									<div>
512
										<center>
513
											<div id="pfsensetemplate">
514
												<table width='100%'>
515
EOFAMBAC;
516
												// If errors are found, throw the big red box.
517
												if ($error_txt) {
518
													echo "<tr><td colspan=\"5\">&nbsp;</td>";
519
													echo "<tr><td colspan=\"5\">";
520
													print_input_errors($error_txt);
521
													echo "</td></tr>";
522
												} else 
523
													echo "<tr><td>&nbsp;</td></tr>";
524

    
525
	echo <<<EOFAMBACBAF
526

    
527
												<tr><td colspan='5' align="center"><b>Boot manager: {$bootmanagerupper}</td></tr>
528
												<tr><td>&nbsp;</td></tr>
529
												<tr>
530
													<td align='left'>
531
														<b>Mount point</b>
532
													</td>
533
													<td align='left'>
534
														<b>Filesysytem type</b>
535
													</td>
536
													<td align='left'>
537
														<b>Disk</b>
538
													</td>
539
													<td align='left'>
540
														<b>Size</b>
541
													</td>
542
													<td align='left'>
543
														<b>Encryption password</b>
544
													</td>
545
												</tr>
546
												<tr><td colspan='5'><hr></td></tr>
547

    
548
EOFAMBACBAF;
549

    
550
													foreach($disks as $disk) {
551
														$desc = pcsysinstall_get_disk_info($disk['disk']);
552
														echo "<tr>";
553
														echo "<td>&nbsp;&nbsp;&nbsp;{$disk['mountpoint']}</td>";
554
														echo "<td>{$disk['fstype']}</td>";
555
														echo "<td>{$disk['disk']} {$desc['desc']}</td>";
556
														echo "<td>{$disk['size']}</td>";
557
														echo "<td>{$disk['encpass']}</td>";
558
														echo "</tr>";
559
													}
560

    
561
echo <<<EOFAMB
562
												<tr><td colspan="5"><hr></td></tr>
563
												</table>
564
											</div>
565
										</center>
566
									</div>
567
	     						</td>
568
							</tr>
569
						</table>
570
					</div>
571
					<center>
572
						<p/>
573
						<input type="button" value="Cancel" onClick="javascript:document.location='installer.php?state=custominstall';"> &nbsp;&nbsp;
574
EOFAMB;
575
						if(!$error_txt) 
576
						echo "<input type=\"submit\" value=\"Begin installation\"> <br/>&nbsp;";
577
echo <<<EOFAMBASDF
578

    
579
					</center>
580
				</td>
581
			</tr>
582
		</table>
583
	</div>
584
EOFAMBASDF;
585

    
586

    
587
	page_table_end();
588
	end_html();
589
	write_out_pc_sysinstaller_config($disks, $bootmanager);
590
	file_put_contents("/tmp/webInstaller_disk_layout.txt", serialize($disks));
591
	file_put_contents("/tmp/webInstaller_disk_bootmanager.txt", serialize($bootmanager));
592
}
593

    
594
function installing_gui() {
595
	global $g, $fstype, $savemsg;
596
	head_html();
597
	body_html();
598
	echo "<form action=\"installer.php\" method=\"post\" state=\"step1_post\">";
599
	page_table_start();
600
	echo <<<EOF
601
	<center>
602
		<table width="100%">
603
		<tr><td>
604
			<div id="mainlevel">
605
				<table width="100%" border="0" cellpadding="0" cellspacing="0">
606
			 		<tr>
607
			    		<td>
608
							<div id="mainarea">
609
								<table width="100%" border="0" cellpadding="0" cellspacing="0">
610
									<tr>
611
			     						<td>
612
											<div id="pfsenseinstaller" width="100%">
613
												<div id='installerrunning' width='100%' style="padding:8px; border:1px dashed #000000">
614
													<table>
615
														<tr>
616
															<td valign="middle">
617
																<img src="/themes/{$g['theme']}/images/misc/loader.gif">
618
															</td>
619
															<td valign="middle">
620
																&nbsp;<font size="2"><b>Starting Installer...  Please wait...
621
															</td>
622
														</tr>
623
													</table>
624
												</div>
625
												<div id='pbdiv'>
626
													<br/>
627
													<center>
628
													<table id='pbtable' height='15' width='640' border='0' colspacing='0' cellpadding='0' cellspacing='0'>
629
														<tr>
630
															<td background="/themes/the_wall/images/misc/bar_left.gif" height='15' width='5'>
631
															</td>
632
															<td>
633
																<table id="progholder" name="progholder" height='15' width='630' border='0' colspacing='0' cellpadding='0' cellspacing='0'>
634
																	<td background="/themes/the_wall/images/misc/bar_gray.gif" valign="top" align="left">
635
																		<img src='/themes/the_wall/images/misc/bar_blue.gif' width='0' height='15' name='progressbar' id='progressbar'>
636
																	</td>
637
																</table>
638
															</td>
639
															<td background="/themes/the_wall/images/misc/bar_right.gif" height='15' width='5'>
640
															</td>
641
														</tr>
642
													</table>
643
													<br/>
644
												</div>
645
												<textarea name='installeroutput' id='installeroutput' rows="31" cols="90">
646
												</textarea>
647
											</div>
648
			     						</td>
649
									</tr>
650
								</table>
651
							</div>
652
						</td>
653
					</tr>
654
				</table>
655
			</div>
656
		</td></tr>
657
		</table>
658
	</center>
659
	<script type="text/javascript">setTimeout('getinstallerprogress()', 250);</script>
660

    
661
EOF;
662
	page_table_end();
663
	end_html();
664
}
665

    
666
function page_table_start($pgtitle = "") {
667
	global $g, $fstype, $savemsg;
668
	if($pgtitle == "") 
669
		$pgtitle = "{$g['product_name']} installer";
670
	echo <<<EOF
671
	<center>
672
		<img border="0" src="/themes/{$g['theme']}/images/logo.gif"></a><br/>
673
		<table cellpadding="6" cellspacing="0" width="550" style="border:1px solid #000000">
674
		<tr height="10" bgcolor="#990000">
675
			<td style="border-bottom:1px solid #000000">
676
				<font color='white'>
677
					<b>
678
						{$pgtitle}
679
					</b>
680
				</font>
681
			</td>
682
		</tr>
683
		<tr>
684
			<td>
685

    
686
EOF;
687

    
688
}
689

    
690
function page_table_end() {
691
	global $g, $fstype, $savemsg;
692
	echo <<<EOF
693
			</td>
694
		</tr>
695
		</table>
696
	</center>
697

    
698
EOF;
699
	
700
}
701

    
702
function installer_custom() {
703
	global $g, $fstype, $savemsg;
704
	global $select_txt, $custom_disks;
705
	if(file_exists("/tmp/.pc-sysinstall/pc-sysinstall.log")) 
706
		unlink("/tmp/.pc-sysinstall/pc-sysinstall.log");
707
	head_html();
708
	body_html();
709
	page_table_start($g['product_name'] . " installer - Customize disk(s) layout");
710
	echo <<<EOF
711
		<script type="text/javascript">
712
			function row_helper_dynamic_custom(tr) {
713
				var totalsize = 0;
714
				for(var x = 0; x<99; x++) { //optimize me better
715
					if(\$('size' + x)) {
716
						if(parseInt($('size' + x).value) > 0)
717
							totalsize += parseInt($('size' + x).value);
718
					}
719
				}
720
				\$('totalsize').value = totalsize;
721
			}
722
		</script>
723
		<script type="text/javascript" src="/javascript/row_helper_dynamic.js"></script>
724
		<script type="text/javascript">
725
			// Setup rowhelper data types
726
			rowname[0] = "mountpoint";
727
			rowtype[0] = "textbox";
728
			rowsize[0] = "8";
729
			rowname[1] = "fstype";
730
			rowtype[1] = "select";
731
			rowsize[1] = "1";
732
			rowname[2] = "disk";
733
			rowtype[2] = "select";
734
			rowsize[2] = "1";
735
			rowname[3] = "size";
736
			rowtype[3] = "textbox";
737
			rowsize[3] = "8";
738
			rowname[4] = "encpass";
739
			rowtype[4] = "textbox";
740
			rowsize[4] = "8";
741
			field_counter_js = 5;
742
			rows = 1;
743
			totalrows = 1;
744
			loaded = 1;
745
		</script>
746
		<form action="installer.php" method="post">
747
			<input type="hidden" name="state" value="verify_before_install">
748
			<div id="mainlevel">
749
				<center>
750
				<table width="100%" border="0" cellpadding="5" cellspacing="0">
751
			 		<tr>
752
			    		<td>
753
							<center>
754
							<div id="mainarea">
755
								<center>
756
								<table width="100%" border="0" cellpadding="5" cellspacing="5">
757
									<tr>
758
			     						<td>
759
											<div id="pfsenseinstaller">
760
												<center>
761
												<div id='loadingdiv'>
762
													<table>
763
														<tr>
764
															<td valign="center">
765
																<img src="/themes/{$g['theme']}/images/misc/loader.gif">
766
															</td>
767
															<td valign="center">
768
														 		&nbsp;Probing disks, please wait...
769
															</td>
770
														</tr>
771
													</table>
772
												</div>
773
EOF;
774
	ob_flush();
775
	$disks = installer_find_all_disks();
776
	if(file_exists("/tmp/webInstaller_disk_bootmanager.txt"))
777
		$bootmanager = unserialize(file_get_contents("/tmp/webInstaller_disk_bootmanager.txt"));
778
	if($bootmanager == "none") 
779
		$noneselected = " SELECTED";
780
	if($bootmanager == "bsd") 
781
		$bsdeselected = " SELECTED";
782

    
783
	if(!$disks)  {
784
		$custom_txt = gettext("ERROR: Could not find any suitable disks for installation.");
785
	} else {
786
		// Prepare disk selection dropdown
787
		$custom_txt = <<<EOF
788
												<center>
789
												<table>
790
												<tr>
791
													<td align='right'>
792
														Boot manager:
793
													</td>
794
													<td>
795
														<select name='bootmanager'>
796
															<option value='none' $noneselected>
797
																None
798
															</option>
799
															<option value='bsd' $bsdeselected>
800
																BSD
801
															</option>
802
														</select>
803
													</td>
804
												</tr>
805
												</table>
806
												<hr>
807
												<table id='maintable'><tbody>
808
												<tr>
809
													<td align="middle">
810
														<b>Mount</b>
811
													</td>
812
													<td align='middle'>
813
														<b>Filesysytem</b>
814
													</td>
815
													<td align="middle">
816
														<b>Disk</b>
817
													</td>
818
													<td align="middle">
819
														<b>Size</b>
820
													</td>
821
													<td align="middle">
822
														<b>Encryption password</b>
823
													</td>
824
													<td>
825
														&nbsp;
826
													</td>
827
												</tr>
828
												<tr>
829

    
830
EOF;
831

    
832
		// Calculate swap disk sizes
833
		$memory = get_memory();
834
		$swap_size = $memory[0] * 2;
835
		$first_disk = trim(installer_find_first_disk());
836
		$disk_info = pcsysinstall_get_disk_info($first_disk);
837
		$size = $disk_info['size'];
838
		$first_disk_size = $size - $swap_size;
839
		// Decreate by 1 megabyte as some disks will fail
840
		$first_disk_size--;
841

    
842
		// Debugging
843
		echo "\n\n<!-- $first_disk - " . print_r($disk_info, true) . " - $size  - $first_disk_size -->\n\n";
844

    
845
		// Check to see if a on disk layout exists
846
		if(file_exists("/tmp/webInstaller_disk_layout.txt")) {
847
			$disks_restored = unserialize(file_get_contents("/tmp/webInstaller_disk_layout.txt"));
848
			$restored_layout_from_file = true;
849
			$restored_layout_txt = "<br/>* The previous disk layout was restored from disk";
850
		}
851

    
852
		// If we restored disk layout(s) from a file then build the rows
853
		if($restored_layout_from_file == true) {
854
			$diskcounter = 0;
855
			foreach($disks_restored as $dr) {
856
				$custom_txt .= return_rowhelper_row("$diskcounter", $dr['mountpoint'], $dr['fstype'], $dr['disk'], $dr['size'], $dr['encpass']);
857
				$diskcounter++;
858
			}
859
		} else {		
860
			// Construct the default rows that outline the disks configuration.
861
			$custom_txt .= return_rowhelper_row("0", "/", "UFS", $first_disk, "{$first_disk_size}", "");
862
			$custom_txt .= return_rowhelper_row("1", "none", "SWAP", $first_disk, "$swap_size", "");
863
		}
864

    
865
		// tfoot and tbody are used by rowhelper
866
		$custom_txt .= "</tr>";
867
		$custom_txt .= "<tfoot></tfoot></tbody>";
868
		$custom_txt .= "<tr><td></td><td></td><td align='right'>Total allocated:</td><td><input size=\"8\" id='totalsize' name='totalsize'></td></tr>";
869
		$custom_txt .= "</table>";
870
		$custom_txt .= "<script type=\"text/javascript\">row_helper_dynamic_custom();</script>";
871
	}
872
	echo <<<EOF
873

    
874
												<tr>
875
													<td colspan='4'>
876
													<script type="text/javascript">
877
														\$('loadingdiv').style.visibility='hidden';
878
													</script>
879
													<div id='contentdiv' style="display:none;">
880
														<p/>
881
														{$custom_txt}<p/>
882
														<hr><p/>
883
														<input type="button" value="Cancel" onClick="javascript:document.location='/installer/installer.php';"> &nbsp;&nbsp
884
														<input type="submit" value="Next">
885
													</div>
886
													<script type="text/javascript">
887
														var encryption_warning_shown = false;
888
														\$('contentdiv').appear();
889
														function onfstypeChange() {
890
															for(var x = 0; x<99; x++) { //optimize me better
891
																if(\$('fstype' + x)) {
892
																	var fstype = \$F('fstype' + x);
893
																	if(fstype.substring(fstype.length - 4) == ".eli") {
894
																		\$('encpass' + x).disabled = 0;
895
																		if(!encryption_warning_shown) {
896
																			alert('NOTE: If you define a disk encryption password you will need to enter it on *EVERY* bootup!');
897
																			encryption_warning_shown = true;
898
																		}
899
																	} else { 
900
																		\$('encpass' + x).disabled = 1;
901
																	}
902
																}
903
															}
904
														}
905
														onfstypeChange();
906
													</script>
907
												</center>
908
												</td></tr>
909
												</table>
910
											</div>
911
			     						</td>
912
									</tr>
913
								</table>
914
								</center>
915
								<span class="vexpl">
916
									<span class="red">
917
										<strong>
918
											NOTES:
919
										</strong>
920
									</span>
921
									<br/>* Sizes are in megabytes.
922
									<br/>* Encryption password field should only be used if a encrypted filesystem (.eli) was chosen
923
									<br/>* Mount points named /conf are not allowed.  Use /cf if you want to make a configuration slice/mount.
924
									{$restored_layout_txt}
925
								</span>
926
								</strong>
927
							</div>
928
						</td>
929
					</tr>
930
				</table>
931
			</div>
932
			</center>
933
			<script type="text/javascript">
934
			<!--
935
				newrow[1] = "{$select_txt}";
936
				newrow[2] = "{$custom_disks}";
937
			-->
938
			</script>
939
			
940

    
941
EOF;
942
	page_table_end();
943
	end_html();
944
}
945

    
946
function installer_main() {
947
	global $g, $fstype, $savemsg;
948
	if(file_exists("/tmp/.pc-sysinstall/pc-sysinstall.log")) 
949
		unlink("/tmp/.pc-sysinstall/pc-sysinstall.log");
950
	head_html();
951
	body_html();
952
	$disk = installer_find_first_disk();
953
	// Only enable ZFS if this exists.  The install will fail otherwise.
954
	//	if(file_exists("/boot/gptzfsboot")) 
955
	//		$zfs_enabled = "<tr bgcolor=\"#9A9A9A\"><td align=\"center\"><a href=\"installer.php?state=verify_before_install&fstype0=ZFS&size=200M\">Easy installation of {$g['product_name']} using the ZFS filesystem on disk {$disk}</a></td></tr>";
956
	page_table_start();
957
	echo <<<EOF
958
		<form action="installer.php" method="post" state="step1_post">
959
			<div id="mainlevel">
960
				<center>
961
				<b><font face="arial" size="+2">Welcome to the {$g['product_name']} webInstaller!</b></font><p/>
962
				<font face="arial" size="+1">This utility will install {$g['product_name']} to a hard disk, flash drive, etc.</font>
963
				<table width="100%" border="0" cellpadding="5" cellspacing="0">
964
			 		<tr>
965
			    		<td>
966
							<center>
967
							<div id="mainarea">
968
								<br/>
969
								<center>
970
								Please select an installer option to begin:
971
								<p/>
972
								<table width="100%" border="0" cellpadding="5" cellspacing="5">
973
									<tr>
974
			     						<td>
975
											<div id="pfsenseinstaller">
976
												<center>
977
EOF;
978
	if(!$disk) {
979
		echo gettext("ERROR: Could not find any suitable disks for installation.");
980
		echo "</div></td></tr></table></div></table></div>";
981
		end_html();
982
		exit;
983
	}
984
	echo <<<EOF
985

    
986
													<table cellspacing="5" cellpadding="5" style="border: 1px dashed;">
987
														<tr bgcolor="#CECECE"><td align="center">
988
<!--
989
															<a href="installer.php?state=verify_before_install&disk={$disk}&fstype=UFS&swapsize=200M">Easy installation of {$g['product_name']} using the UFS filesystem on disk {$disk}</a>
990
-->
991
														</td></tr>
992
													 	{$zfs_enabled}
993
														<tr bgcolor="#AAAAAA"><td align="center">
994
															<a href="installer.php?state=custominstall">Custom installation of {$g['product_name']}</a>
995
														</td></tr>
996
														<tr bgcolor="#CECECE"><td align="center">
997
															<a href='/'>Cancel and return to Dashboard</a>
998
														</td></tr>
999
													</table>
1000
												</center>
1001
											</div>
1002
			     						</td>
1003
									</tr>
1004
								</table>
1005
							</div>
1006
						</td>
1007
					</tr>
1008
				</table>
1009
			</div>
1010
EOF;
1011
	page_table_end();
1012
	end_html();
1013
}
1014

    
1015
function return_rowhelper_row($rownum, $mountpoint, $fstype, $disk, $size, $encpass) {
1016
		global $g, $select_txt, $custom_disks, $savemsg;
1017
		$release = php_uname("r");
1018
		$release = trim($release[0]);
1019

    
1020
		// Mount point
1021
		$disks = installer_find_all_disks();
1022
		$custom_txt .= "<tr>";
1023
		$custom_txt .=  "<td><input size='8' id='mountpoint{$rownum}' name='mountpoint{$rownum}' value='{$mountpoint}'></td>";
1024

    
1025
		// Filesystem type array
1026
		$types = array(
1027
			'UFS' => 'UFS',
1028
			'UFS+S' => 'UFS + Softupdates',
1029
			'UFS.eli' => 'Encrypted UFS',
1030
			'UFS+S.eli' => 'Encrypted UFS + Softupdates',
1031
			'SWAP' => 'SWAP'
1032
		);
1033

    
1034
		// UFS + Journaling was introduced in 9.0
1035
		if($release == "9") {
1036
			$types['UFS+J'] = "UFS + Journaling";
1037
			$types['UFS+J.eli'] = "Encrypted UFS + Journaling";
1038
		}
1039
		
1040
		// Add ZFS Boot loader if it exists
1041
		if(file_exists("/boot/gptzfsboot")) {
1042
			$types['ZFS'] = "Zetabyte Filesystem";
1043
			$types['ZFS.eli'] = "Encrypted Zetabyte Filesystem";
1044
		}
1045

    
1046
		// fstype form field
1047
		$custom_txt .=  "<td><select onChange='javascript:onfstypeChange()' id='fstype{$rownum}' name='fstype{$rownum}'>";
1048
		$select_txt = "";
1049
		foreach($types as $type => $desc) {
1050
			if($type == $fstype)
1051
				$SELECTED="SELECTED";
1052
			else 
1053
				$SELECTED="";
1054
			$select_txt .= "<option value='$type' $SELECTED>$desc</option>";
1055
		}
1056
		$custom_txt .= "{$select_txt}</select>\n";
1057
		$custom_txt .= "</td>";
1058
		
1059
		// Disk selection form field
1060
		$custom_txt .= "<td><select id='disk{$rownum}' name='disk{$rownum}'>\n";
1061
		$custom_disks = "";
1062
		foreach($disks as $dsk) {
1063
			$disksize_bytes = format_bytes($dsk['size'] * 1048576);
1064
			$disksize = $dsk['size'];
1065
			if($disk == $dsk['disk'])
1066
				$SELECTED="SELECTED";
1067
			else 
1068
				$SELECTED="";
1069
			$custom_disks .= "<option value='{$dsk['disk']}' $SELECTED>{$dsk['disk']} - {$dsk['desc']} - {$disksize}MB ({$disksize_bytes})</option>";
1070
		}
1071
		$custom_txt .= "{$custom_disks}</select></td>\n";
1072

    
1073
		// Slice size
1074
		$custom_txt .= "<td><input onChange='javascript:row_helper_dynamic_custom();' name='size{$rownum}' id='size{$rownum}' size='8' type='text' value='{$size}'></td>";
1075

    
1076
		// Encryption password
1077
		$custom_txt .= "<td>";
1078
		$custom_txt .= "<input id='encpass{$rownum}' name='encpass{$rownum}' size='8' value='{$encpass}'>";
1079
		$custom_txt .= "</td>";
1080
	
1081
		// Add Rowhelper + button
1082
		if($rownum == 1) {
1083
			$custom_txt .= "<td>";
1084
			$custom_txt .= "<div id=\"addrowbutton\">";
1085
			$custom_txt .= "<a onclick=\"javascript:addRowTo('maintable', 'formfldalias'); return false;\" href=\"#\">";
1086
			$custom_txt .= "<img border=\"0\" src=\"/themes/{$g['theme']}/images/icons/icon_plus.gif\" alt=\"\" title=\"add another entry\" /></a>";
1087
			$custom_txt .= "</div>";
1088
			$custom_txt .= "</td>";	
1089
		}
1090

    
1091
		$custom_txt .= "</tr>";	
1092
		return $custom_txt;
1093
}
1094

    
1095
?>
(2-2/2)