Project

General

Profile

Download (33.8 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
EOFAMBAC;
515
												// If errors are found, throw the big red box.
516
												if ($error_txt) 
517
													print_input_errors($error_txt);
518
	echo <<<EOFAMBACBAF
519

    
520
												<table width='100%'>
521
												<tr><td>&nbsp;</td></tr>
522
												<tr><td colspan='5' align="center"><b>Boot manager: {$bootmanagerupper}</td></tr>
523
												<tr><td>&nbsp;</td></tr>
524
												<tr>
525
													<td align='left'>
526
														<b>Mount point</b>
527
													</td>
528
													<td align='left'>
529
														<b>Filesysytem type</b>
530
													</td>
531
													<td align='left'>
532
														<b>Disk</b>
533
													</td>
534
													<td align='left'>
535
														<b>Size</b>
536
													</td>
537
													<td align='left'>
538
														<b>Encryption password</b>
539
													</td>
540
												</tr>
541
												<tr><td colspan='5'><hr></td></tr>
542

    
543
EOFAMBACBAF;
544

    
545
													foreach($disks as $disk) {
546
														$desc = pcsysinstall_get_disk_info($disk['disk']);
547
														echo "<tr>";
548
														echo "<td>&nbsp;&nbsp;&nbsp;{$disk['mountpoint']}</td>";
549
														echo "<td>{$disk['fstype']}</td>";
550
														echo "<td>{$disk['disk']} {$desc['desc']}</td>";
551
														echo "<td>{$disk['size']}</td>";
552
														echo "<td>{$disk['encpass']}</td>";
553
														echo "</tr>";
554
													}
555

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

    
574
					</center>
575
				</td>
576
			</tr>
577
		</table>
578
	</div>
579
EOFAMBASDF;
580

    
581

    
582
	page_table_end();
583
	end_html();
584
	write_out_pc_sysinstaller_config($disks, $bootmanager);
585
	file_put_contents("/tmp/webInstaller_disk_layout.txt", serialize($disks));
586
	file_put_contents("/tmp/webInstaller_disk_bootmanager.txt", serialize($bootmanager));
587
}
588

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

    
656
EOF;
657
	page_table_end();
658
	end_html();
659
}
660

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

    
681
EOF;
682

    
683
}
684

    
685
function page_table_end() {
686
	global $g, $fstype, $savemsg;
687
	echo <<<EOF
688
			</td>
689
		</tr>
690
		</table>
691
	</center>
692

    
693
EOF;
694
	
695
}
696

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

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

    
825
EOF;
826

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

    
837
		// Debugging
838
		echo "\n\n<!-- $first_disk - " . print_r($disk_info, true) . " - $size  - $first_disk_size -->\n\n";
839

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

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

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

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

    
936
EOF;
937
	page_table_end();
938
	end_html();
939
}
940

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

    
981
													<table cellspacing="5" cellpadding="5" style="border: 1px dashed;">
982
														<tr bgcolor="#CECECE"><td align="center">
983
<!--
984
															<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>
985
-->
986
														</td></tr>
987
													 	{$zfs_enabled}
988
														<tr bgcolor="#AAAAAA"><td align="center">
989
															<a href="installer.php?state=custominstall">Custom installation of {$g['product_name']}</a>
990
														</td></tr>
991
														<tr bgcolor="#CECECE"><td align="center">
992
															<a href='/'>Cancel and return to Dashboard</a>
993
														</td></tr>
994
													</table>
995
												</center>
996
											</div>
997
			     						</td>
998
									</tr>
999
								</table>
1000
							</div>
1001
						</td>
1002
					</tr>
1003
				</table>
1004
			</div>
1005
EOF;
1006
	page_table_end();
1007
	end_html();
1008
}
1009

    
1010
function return_rowhelper_row($rownum, $mountpoint, $fstype, $disk, $size, $encpass) {
1011
		global $g, $select_txt, $custom_disks, $savemsg;
1012
		$release = php_uname("r");
1013
		$release = trim($release[0]);
1014

    
1015
		// Mount point
1016
		$disks = installer_find_all_disks();
1017
		$custom_txt .= "<tr>";
1018
		$custom_txt .=  "<td><input size='8' id='mountpoint{$rownum}' name='mountpoint{$rownum}' value='{$mountpoint}'></td>";
1019

    
1020
		// Filesystem type array
1021
		$types = array(
1022
			'UFS' => 'UFS',
1023
			'UFS+S' => 'UFS + Softupdates',
1024
			'UFS.eli' => 'Encrypted UFS',
1025
			'UFS+S.eli' => 'Encrypted UFS + Softupdates',
1026
			'SWAP' => 'SWAP'
1027
		);
1028

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

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

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

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

    
1086
		$custom_txt .= "</tr>";	
1087
		return $custom_txt;
1088
}
1089

    
1090
?>
(2-2/2)