Project

General

Profile

Download (36 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 src="/javascript/scriptaculous/scriptaculous.js" type="text/javascript"></script>
372
	<script type="text/javascript">
373
		function getinstallerprogress() {
374
			url = '/installer/installer.php';
375
			pars = 'state=update_installer_status';
376
			callajax(url, pars, installcallback);
377
		}
378
		function callajax(url, pars, activitycallback) {
379
			var myAjax = new Ajax.Request(
380
				url,
381
				{
382
					method: 'post',
383
					parameters: pars,
384
					onComplete: activitycallback
385
				});
386
		}
387
		function installcallback(transport) {
388
			setTimeout('getinstallerprogress()', 2000);
389
			eval(transport.responseText);
390
		}
391
	</script>
392
EOF;
393

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

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

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

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

    
423

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

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

    
526
	echo <<<EOFAMBACBAF
527

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

    
549
EOFAMBACBAF;
550

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

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

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

    
587

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

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

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

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

    
687
EOF;
688

    
689
}
690

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

    
699
EOF;
700
	
701
}
702

    
703
function installer_custom() {
704
	global $g, $fstype, $savemsg;
705
	global $select_txt, $custom_disks;
706
	if(file_exists("/tmp/.pc-sysinstall/pc-sysinstall.log")) 
707
		unlink("/tmp/.pc-sysinstall/pc-sysinstall.log");
708
	$disks = installer_find_all_disks();
709
	// Pass size of disks down to javascript.
710
	$disk_sizes_js_txt = "var disk_sizes = new Array();\n";
711
	foreach($disks as $disk) 
712
		$disk_sizes_js_txt .= "disk_sizes['{$disk['disk']}'] = '{$disk['size']}';\n";
713
	head_html();
714
	body_html();
715
	page_table_start($g['product_name'] . " installer - Customize disk(s) layout");
716
	echo <<<EOF
717
		<script type="text/javascript">
718
			Array.prototype.in_array = function(p_val) {
719
				for(var i = 0, l = this.length; i < l; i++) {
720
					if(this[i] == p_val) {
721
						return true;
722
					}
723
				}
724
				return false;
725
			}
726
			function row_helper_dynamic_custom() {
727
				var totalsize = 0;
728
				{$disk_sizes_js_txt}
729
				// Run through all rows and process data
730
				for(var x = 0; x<99; x++) { //optimize me better
731
					if(\$('fstype' + x)) {
732
						var fstype = \$F('fstype' + x);
733
						if(fstype.substring(fstype.length - 4) == ".eli") {
734
							\$('encpass' + x).disabled = 0;
735
							if(!encryption_warning_shown) {
736
								alert('NOTE: If you define a disk encryption password you will need to enter it on *EVERY* bootup!');
737
								encryption_warning_shown = true;
738
							}
739
						} else { 
740
							\$('encpass' + x).disabled = 1;
741
						}
742
					}
743
					// Calculate size allocations
744
					if(\$('size' + x)) {
745
						if(parseInt($('size' + x).value) > 0)
746
							totalsize += parseInt($('size' + x).value);
747
					}
748
				}
749
				// If the totalsize element exists, set it and disable
750
				if(\$('totalsize')) {
751
					if(\$('totalsize').value != totalsize) {
752
						// When size allocation changes, draw attention.
753
 						new Effect.Highlight('totalsize');
754
						\$('totalsize').value = totalsize;
755
					}
756
					\$('totalsize').disabled = 1;
757
				}
758
				if(\$('disktotals')) {
759
					var disks_seen = new Array();
760
					var tmp_sizedisks = 0;
761
					var disksseen = 0;
762
					for(var xx = 0; xx<99; xx++) {
763
						if(\$('disk' + xx)) {
764
							if(!disks_seen.in_array(\$('disk' + xx).value)) {
765
								tmp_sizedisks += parseInt(disk_sizes[\$('disk' + xx).value]);
766
								disks_seen[disksseen] = \$('disk' + xx).value;
767
								disksseen++;
768
							}
769
						}
770
					\$('disktotals').value = tmp_sizedisks;
771
					\$('disktotals').disabled = 1;
772
					\$('disktotals').setStyle({color:'#000000'});
773
					var remaining = parseInt(\$('disktotals').value) - parseInt(\$('totalsize').value);
774
						if(remaining == 1) {
775
							if(\$('totalsize'))
776
								\$('totalsize').setStyle({
777
									background:'#00FF00',
778
									color:'#000000'
779
								});
780
						} else {
781
							if(\$('totalsize'))
782
								\$('totalsize').setStyle({
783
									background:'#FFFFFF',
784
									color:'#000000'
785
								});
786
						}
787
					}
788
				}
789
			}
790
		</script>
791
		<script type="text/javascript" src="/javascript/row_helper_dynamic.js"></script>
792
		<script type="text/javascript">
793
			// Setup rowhelper data types
794
			rowname[0] = "mountpoint";
795
			rowtype[0] = "textbox";
796
			rowsize[0] = "8";
797
			rowname[1] = "fstype";
798
			rowtype[1] = "select";
799
			rowsize[1] = "1";
800
			rowname[2] = "disk";
801
			rowtype[2] = "select";
802
			rowsize[2] = "1";
803
			rowname[3] = "size";
804
			rowtype[3] = "textbox";
805
			rowsize[3] = "8";
806
			rowname[4] = "encpass";
807
			rowtype[4] = "textbox";
808
			rowsize[4] = "8";
809
			field_counter_js = 5;
810
			rows = 1;
811
			totalrows = 1;
812
			loaded = 1;
813
			rowhelper_onChange = " onChange='javascript:row_helper_dynamic_custom()' ";
814
			rowhelper_onAdd = 'row_helper_dynamic_custom();';
815
		</script>
816
		<form action="installer.php" method="post">
817
			<input type="hidden" name="state" value="verify_before_install">
818
			<div id="mainlevel">
819
				<center>
820
				<table width="100%" border="0" cellpadding="5" cellspacing="0">
821
			 		<tr>
822
			    		<td>
823
							<center>
824
							<div id="mainarea">
825
								<center>
826
								<table width="100%" border="0" cellpadding="5" cellspacing="5">
827
									<tr>
828
			     						<td>
829
											<div id="pfsenseinstaller">
830
												<center>
831
												<div id='loadingdiv'>
832
													<table>
833
														<tr>
834
															<td valign="center">
835
																<img src="/themes/{$g['theme']}/images/misc/loader.gif">
836
															</td>
837
															<td valign="center">
838
														 		&nbsp;Probing disks, please wait...
839
															</td>
840
														</tr>
841
													</table>
842
												</div>
843
EOF;
844
	ob_flush();
845
	if(file_exists("/tmp/webInstaller_disk_bootmanager.txt"))
846
		$bootmanager = unserialize(file_get_contents("/tmp/webInstaller_disk_bootmanager.txt"));
847
	if($bootmanager == "none") 
848
		$noneselected = " SELECTED";
849
	if($bootmanager == "bsd") 
850
		$bsdeselected = " SELECTED";
851

    
852
	if(!$disks)  {
853
		$custom_txt = gettext("ERROR: Could not find any suitable disks for installation.");
854
	} else {
855
		// Prepare disk selection dropdown
856
		$custom_txt = <<<EOF
857
												<center>
858
												<table>
859
												<tr>
860
													<td align='right'>
861
														Boot manager:
862
													</td>
863
													<td>
864
														<select name='bootmanager'>
865
															<option value='none' $noneselected>
866
																None
867
															</option>
868
															<option value='bsd' $bsdeselected>
869
																BSD
870
															</option>
871
														</select>
872
													</td>
873
												</tr>
874
												</table>
875
												<hr>
876
												<table id='maintable'><tbody>
877
												<tr>
878
													<td align="middle">
879
														<b>Mount</b>
880
													</td>
881
													<td align='middle'>
882
														<b>Filesysytem</b>
883
													</td>
884
													<td align="middle">
885
														<b>Disk</b>
886
													</td>
887
													<td align="middle">
888
														<b>Size</b>
889
													</td>
890
													<td align="middle">
891
														<b>Encryption password</b>
892
													</td>
893
													<td>
894
														&nbsp;
895
													</td>
896
												</tr>
897
												<tr>
898

    
899
EOF;
900

    
901
		// Calculate swap disk sizes
902
		$memory = get_memory();
903
		$swap_size = $memory[0] * 2;
904
		$first_disk = trim(installer_find_first_disk());
905
		$disk_info = pcsysinstall_get_disk_info($first_disk);
906
		$size = $disk_info['size'];
907
		$first_disk_size = $size - $swap_size;
908
		// Decreate by 1 megabyte as some disks will fail
909
		$first_disk_size--;
910

    
911
		// Debugging
912
		echo "\n\n<!-- $first_disk - " . print_r($disk_info, true) . " - $size  - $first_disk_size -->\n\n";
913

    
914
		// Check to see if a on disk layout exists
915
		if(file_exists("/tmp/webInstaller_disk_layout.txt")) {
916
			$disks_restored = unserialize(file_get_contents("/tmp/webInstaller_disk_layout.txt"));
917
			$restored_layout_from_file = true;
918
			$restored_layout_txt = "<br/>* The previous disk layout was restored from a previous session";
919
		}
920

    
921
		// If we restored disk layout(s) from a file then build the rows
922
		if($restored_layout_from_file == true) {
923
			$diskcounter = 0;
924
			foreach($disks_restored as $dr) {
925
				$custom_txt .= return_rowhelper_row("$diskcounter", $dr['mountpoint'], $dr['fstype'], $dr['disk'], $dr['size'], $dr['encpass']);
926
				$diskcounter++;
927
			}
928
		} else {		
929
			// Construct the default rows that outline the disks configuration.
930
			$custom_txt .= return_rowhelper_row("0", "/", "UFS", $first_disk, "{$first_disk_size}", "");
931
			$custom_txt .= return_rowhelper_row("1", "none", "SWAP", $first_disk, "$swap_size", "");
932
		}
933

    
934
		// tfoot and tbody are used by rowhelper
935
		$custom_txt .= "</tr>";
936
		$custom_txt .= "<tfoot></tfoot></tbody>";
937
		$custom_txt .= "<tr><td></td><td></td><td align='right'>Total allocated:</td><td><input style='border:0px; background-color: #FFFFFF;' size='8' id='totalsize' name='totalsize'></td></tr>";
938
		$custom_txt .= "<tr><td></td><td></td><td align='right'>Disk capacity total:</td><td><input style='border:0px; background-color: #FFFFFF;' size='8' id='disktotals' name='disktotals'></td></tr>";
939
		$custom_txt .= "</table>";
940
		$custom_txt .= "<script type=\"text/javascript\">row_helper_dynamic_custom();</script>";
941
	}
942
	echo <<<EOF
943

    
944
												<tr>
945
													<td colspan='4'>
946
													<script type="text/javascript">
947
														\$('loadingdiv').style.visibility='hidden';
948
													</script>
949
													<div id='contentdiv' style="display:none;">
950
														<p/>
951
														{$custom_txt}<p/>
952
														<hr><p/>
953
														<input type="button" value="Cancel" onClick="javascript:document.location='/installer/installer.php';"> &nbsp;&nbsp
954
														<input type="submit" value="Next">
955
													</div>
956
													<script type="text/javascript">
957
														var encryption_warning_shown = false;
958
														\$('contentdiv').appear();
959
														row_helper_dynamic_custom();
960
													</script>
961
												</center>
962
												</td></tr>
963
												</table>
964
											</div>
965
			     						</td>
966
									</tr>
967
								</table>
968
								</center>
969
								<span class="vexpl">
970
									<span class="red">
971
										<strong>
972
											NOTES:
973
										</strong>
974
									</span>
975
									<br/>* Sizes are in megabytes.
976
									<br/>* Encryption password field should only be used if a encrypted filesystem (.eli) was chosen
977
									<br/>* Mount points named /conf are not allowed.  Use /cf if you want to make a configuration slice/mount.
978
									<br/>* Leave at least one megabyte unallocated to avoid errors
979
									{$restored_layout_txt}
980
								</span>
981
								</strong>
982
							</div>
983
						</td>
984
					</tr>
985
				</table>
986
			</div>
987
			</center>
988
			<script type="text/javascript">
989
			<!--
990
				newrow[1] = "{$select_txt}";
991
				newrow[2] = "{$custom_disks}";
992
			-->
993
			</script>
994
			
995

    
996
EOF;
997
	page_table_end();
998
	end_html();
999
}
1000

    
1001
function installer_main() {
1002
	global $g, $fstype, $savemsg;
1003
	if(file_exists("/tmp/.pc-sysinstall/pc-sysinstall.log")) 
1004
		unlink("/tmp/.pc-sysinstall/pc-sysinstall.log");
1005
	head_html();
1006
	body_html();
1007
	$disk = installer_find_first_disk();
1008
	// Only enable ZFS if this exists.  The install will fail otherwise.
1009
	//	if(file_exists("/boot/gptzfsboot")) 
1010
	//		$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>";
1011
	page_table_start();
1012
	echo <<<EOF
1013
		<form action="installer.php" method="post" state="step1_post">
1014
			<div id="mainlevel">
1015
				<center>
1016
				<b><font face="arial" size="+2">Welcome to the {$g['product_name']} webInstaller!</b></font><p/>
1017
				<font face="arial" size="+1">This utility will install {$g['product_name']} to a hard disk, flash drive, etc.</font>
1018
				<table width="100%" border="0" cellpadding="5" cellspacing="0">
1019
			 		<tr>
1020
			    		<td>
1021
							<center>
1022
							<div id="mainarea">
1023
								<br/>
1024
								<center>
1025
								Please select an installer option to begin:
1026
								<p/>
1027
								<table width="100%" border="0" cellpadding="5" cellspacing="5">
1028
									<tr>
1029
			     						<td>
1030
											<div id="pfsenseinstaller">
1031
												<center>
1032
EOF;
1033
	if(!$disk) {
1034
		echo gettext("ERROR: Could not find any suitable disks for installation.");
1035
		echo "</div></td></tr></table></div></table></div>";
1036
		end_html();
1037
		exit;
1038
	}
1039
	echo <<<EOF
1040

    
1041
													<table cellspacing="5" cellpadding="5" style="border: 1px dashed;">
1042
														<tr bgcolor="#CECECE"><td align="center">
1043
<!--
1044
															<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>
1045
-->
1046
														</td></tr>
1047
													 	{$zfs_enabled}
1048
														<tr bgcolor="#AAAAAA"><td align="center">
1049
															<a href="installer.php?state=custominstall">Custom installation of {$g['product_name']}</a>
1050
														</td></tr>
1051
														<tr bgcolor="#CECECE"><td align="center">
1052
															<a href='/'>Cancel and return to Dashboard</a>
1053
														</td></tr>
1054
													</table>
1055
												</center>
1056
											</div>
1057
			     						</td>
1058
									</tr>
1059
								</table>
1060
							</div>
1061
						</td>
1062
					</tr>
1063
				</table>
1064
			</div>
1065
EOF;
1066
	page_table_end();
1067
	end_html();
1068
}
1069

    
1070
function return_rowhelper_row($rownum, $mountpoint, $fstype, $disk, $size, $encpass) {
1071
		global $g, $select_txt, $custom_disks, $savemsg;
1072
		$release = php_uname("r");
1073
		$release = trim($release[0]);
1074

    
1075
		// Mount point
1076
		$disks = installer_find_all_disks();
1077
		$custom_txt .= "<tr>";
1078
		$custom_txt .=  "<td><input size='8' id='mountpoint{$rownum}' name='mountpoint{$rownum}' value='{$mountpoint}'></td>";
1079

    
1080
		// Filesystem type array
1081
		$types = array(
1082
			'UFS' => 'UFS',
1083
			'UFS+S' => 'UFS + Softupdates',
1084
			'UFS.eli' => 'Encrypted UFS',
1085
			'UFS+S.eli' => 'Encrypted UFS + Softupdates',
1086
			'SWAP' => 'SWAP'
1087
		);
1088

    
1089
		// UFS + Journaling was introduced in 9.0
1090
		if($release == "9") {
1091
			$types['UFS+J'] = "UFS + Journaling";
1092
			$types['UFS+J.eli'] = "Encrypted UFS + Journaling";
1093
		}
1094
		
1095
		// Add ZFS Boot loader if it exists
1096
		if(file_exists("/boot/gptzfsboot")) {
1097
			$types['ZFS'] = "Zetabyte Filesystem";
1098
			$types['ZFS.eli'] = "Encrypted Zetabyte Filesystem";
1099
		}
1100

    
1101
		// fstype form field
1102
		$custom_txt .=  "<td><select onChange='javascript:row_helper_dynamic_custom()' id='fstype{$rownum}' name='fstype{$rownum}'>";
1103
		$select_txt = "";
1104
		foreach($types as $type => $desc) {
1105
			if($type == $fstype)
1106
				$SELECTED="SELECTED";
1107
			else 
1108
				$SELECTED="";
1109
			$select_txt .= "<option value='$type' $SELECTED>$desc</option>";
1110
		}
1111
		$custom_txt .= "{$select_txt}</select>\n";
1112
		$custom_txt .= "</td>";
1113
		
1114
		// Disk selection form field
1115
		$custom_txt .= "<td><select id='disk{$rownum}' name='disk{$rownum}'>\n";
1116
		$custom_disks = "";
1117
		foreach($disks as $dsk) {
1118
			$disksize_bytes = format_bytes($dsk['size'] * 1048576);
1119
			$disksize = $dsk['size'];
1120
			if($disk == $dsk['disk'])
1121
				$SELECTED="SELECTED";
1122
			else 
1123
				$SELECTED="";
1124
			$custom_disks .= "<option value='{$dsk['disk']}' $SELECTED>{$dsk['disk']} - {$dsk['desc']} - {$disksize}MB ({$disksize_bytes})</option>";
1125
		}
1126
		$custom_txt .= "{$custom_disks}</select></td>\n";
1127

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

    
1131
		// Encryption password
1132
		$custom_txt .= "<td>";
1133
		$custom_txt .= "<input id='encpass{$rownum}' name='encpass{$rownum}' size='8' value='{$encpass}'>";
1134
		$custom_txt .= "</td>";
1135
	
1136
		// Add Rowhelper + button
1137
		if($rownum == 1) {
1138
			$custom_txt .= "<td>";
1139
			$custom_txt .= "<div id=\"addrowbutton\">";
1140
			$custom_txt .= "<a onclick=\"javascript:addRowTo('maintable', 'formfldalias'); return false;\" href=\"#\">";
1141
			$custom_txt .= "<img border=\"0\" src=\"/themes/{$g['theme']}/images/icons/icon_plus.gif\" alt=\"\" title=\"add another entry\" /></a>";
1142
			$custom_txt .= "</div>";
1143
			$custom_txt .= "</td>";	
1144
		}
1145

    
1146
		$custom_txt .= "</tr>";	
1147
		return $custom_txt;
1148
}
1149

    
1150
?>
(2-2/2)