Project

General

Profile

Download (38.9 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	installer.php (pfSense webInstaller)
4
	part of pfSense (https://www.pfsense.org/)
5
	Copyright (C) 2013-2015 Electric Sheep Fencing, LP
6
	Copyright (C) 2010 Scott Ullrich <sullrich@gmail.com>
7
	All rights reserved.
8

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

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

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

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

    
31
$nocsrf = true;
32

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

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

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

    
43
// Main switch dispatcher
44
switch ($_REQUEST['state']) {
45
	case "update_installer_status":
46
		update_installer_status();
47
		exit;
48
	case "custominstall":
49
		installer_custom();
50
		exit;
51
	case "begin_install":
52
		installing_gui();
53
		begin_install();
54
		exit;
55
	case "verify_before_install":
56
		verify_before_install();
57
		exit;
58
	case "easy_install_ufs":
59
		easy_install("UFS+S");
60
		exit;
61
	case "easy_install_ufs":
62
		easy_install("ZFS");
63
		exit;
64

    
65
	default:
66
		installer_main();
67
}
68

    
69
function easy_install($fstype = "UFS+S") {
70
	// Calculate swap and disk sizes
71
	$disks = installer_find_all_disks();
72
	$memory = get_memory();
73
	$swap_size = $memory[0] * 2;
74
	$first_disk = trim(installer_find_first_disk());
75
	$disk_info = pcsysinstall_get_disk_info($first_disk);
76
	$size = $disk_info['size'];
77
	$first_disk_size = $size - $swap_size;
78
	$disk_setup = array();
79
	$tmp_array = array();
80
	// Build the disk layout for /
81
	$tmp_array['disk'] = $first_disk;
82
	$tmp_array['size'] = $first_disk_size;
83
	$tmp_array['mountpoint'] = "/";
84
	$tmp_array['fstype'] = $fstype;
85
	$disk_setup[] = $tmp_array;
86
	unset($tmp_array);
87
	$tmp_array = array();
88
	// Build the disk layout for SWAP
89
	$tmp_array['disk'] = $first_disk;
90
	$tmp_array['size'] = $swap_size;
91
	$tmp_array['mountpoint'] = "none";
92
	$tmp_array['fstype'] = "SWAP";
93
	$disk_setup[] = $tmp_array;
94
	unset($tmp_array);
95
	$bootmanager = "bsd";
96
	file_put_contents("/tmp/webInstaller_disk_layout.txt", serialize($disk_setup));
97
	file_put_contents("/tmp/webInstaller_disk_bootmanager.txt", serialize($bootmanager));
98
	header("Location: installer.php?state=verify_before_install");
99
	exit;
100
}
101

    
102
function write_out_pc_sysinstaller_config($disks, $bootmanager = "bsd") {
103
	$diskareas = "";
104
	$fd = fopen("/usr/sbin/pc-sysinstall/examples/pfSense-install.cfg", "w");
105
	if (!$fd) {
106
		return true;
107
	}
108
	if ($bootmanager == "") {
109
		$bootmanager = "none";
110
	}
111
	// Yes, -1.  We ++ early in loop.
112
	$numdisks = -1;
113
	$lastdisk = "";
114
	$diskdefs = "";
115
	// Run through the disks and create the conf areas for pc-sysinstaller
116
	foreach ($disks as $disksa) {
117
		$fstype = $disksa['fstype'];
118
		$size = $disksa['size'];
119
		$mountpoint = $disksa['mountpoint'];
120
		$disk = $disksa['disk'];
121
		if ($disk <> $lastdisk) {
122
			$lastdisk = $disk;
123
			$numdisks++;
124
			$diskdefs .= "# disk {$disk}\n";
125
			$diskdefs .= "disk{$numdisks}={$disk}\n";
126
			$diskdefs .= "partition=all\n";
127
			$diskdefs .= "bootManager={$bootmanager}\n";
128
			$diskdefs .= "commitDiskPart\n\n";
129
		}
130
		$diskareas .= "disk{$numdisks}-part={$fstype} {$size} {$mountpoint} \n";
131
		if ($encpass) {
132
			$diskareas .= "encpass={$encpass}\n";
133
		}
134
	}
135

    
136
	$config = <<<EOF
137
# Sample configuration file for an installation using pc-sysinstall
138
# This file was automatically generated by installer.php
139

    
140
installMode=fresh
141
installInteractive=yes
142
installType=FreeBSD
143
installMedium=LiveCD
144

    
145
# Set the disk parameters
146
{$diskdefs}
147

    
148
# Setup the disk label
149
# All sizes are expressed in MB
150
# Avail FS Types, UFS, UFS+S, UFS+J, ZFS, SWAP
151
# Size 0 means use the rest of the slice size
152
# Alternatively, you can append .eli to any of
153
# the above filesystem types to encrypt that disk.
154
# If you with to use a passphrase with this
155
# encrypted partition, on the next line
156
# the flag "encpass=" should be entered:
157
# encpass=mypass
158
# disk0-part=UFS 500 /boot
159
# disk0-part=UFS.eli 500 /
160
# disk0-part=UFS.eli 500 /usr
161
{$diskareas}
162

    
163
# Do it now!
164
commitDiskLabel
165

    
166
# Set if we are installing via optical, USB, or FTP
167
installType=FreeBSD
168

    
169
packageType=cpdup
170

    
171
# Optional Components
172
cpdupPaths=boot,COPYRIGHT,bin,conf,conf.default,dev,etc,home,kernels,libexec,lib,root,sbin,usr,var
173

    
174
# runExtCommand=chmod a+rx /usr/local/bin/after_installation_routines.sh ; cd / ; /usr/local/bin/after_installation_routines.sh
175
EOF;
176
	fwrite($fd, $config);
177
	fclose($fd);
178
	return;
179
}
180

    
181
function start_installation() {
182
	global $g, $fstype, $savemsg;
183
	if (file_exists("/tmp/install_complete")) {
184
		return;
185
	}
186
	$ps_running = exec("/bin/ps awwwux | /usr/bin/grep -v grep | /usr/bin/grep 'sh /tmp/installer.sh'");
187
	if ($ps_running) {
188
		return;
189
	}
190
	$fd = fopen("/tmp/installer.sh", "w");
191
	if (!$fd) {
192
		die(gettext("Could not open /tmp/installer.sh for writing"));
193
		exit;
194
	}
195
	fwrite($fd, "/bin/rm /tmp/.pc-sysinstall/pc-sysinstall.log 2>/dev/null\n");
196
	fwrite($fd, "/usr/sbin/pc-sysinstall/pc-sysinstall/pc-sysinstall.sh -c /usr/sbin/pc-sysinstall/examples/pfSense-install.cfg \n");
197
	fwrite($fd, "/bin/chmod a+rx /usr/local/bin/after_installation_routines.sh\n");
198
	fwrite($fd, "cd / && /usr/local/bin/after_installation_routines.sh\n");
199
	fwrite($fd, "/bin/mkdir /mnt/tmp\n");
200
	fwrite($fd, "/usr/bin/touch /tmp/install_complete\n");
201
	fclose($fd);
202
	exec("/bin/chmod a+rx /tmp/installer.sh");
203
	mwexec_bg("/bin/sh /tmp/installer.sh");
204
}
205

    
206
function installer_find_first_disk() {
207
	global $g, $fstype, $savemsg;
208
	$disk = `/usr/sbin/pc-sysinstall/pc-sysinstall/pc-sysinstall.sh disk-list | head -n1 | cut -d':' -f1`;
209
	return trim($disk);
210
}
211

    
212
function pcsysinstall_get_disk_info($diskname) {
213
	global $g, $fstype, $savemsg;
214
	$disk = explode("\n", `/usr/sbin/pc-sysinstall/pc-sysinstall/pc-sysinstall.sh disk-list`);
215
	$disks_array = array();
216
	foreach ($disk as $d) {
217
		$disks_info = explode(":", $d);
218
		$tmp_array = array();
219
		if ($disks_info[0] == $diskname) {
220
			$disk_info = explode("\n", `/usr/sbin/pc-sysinstall/pc-sysinstall/pc-sysinstall.sh disk-info {$disks_info[0]}`);
221
			$disk_info_split = explode("=", $disk_info);
222
			foreach ($disk_info as $di) {
223
				$di_s = explode("=", $di);
224
				if ($di_s[0]) {
225
					$tmp_array[$di_s[0]] = $di_s[1];
226
				}
227
			}
228
			$tmp_array['size']--;
229
			$tmp_array['disk'] = trim($disks_info[0]);
230
			$tmp_array['desc'] = trim(htmlentities($disks_info[1]));
231
			return $tmp_array;
232
		}
233
	}
234
}
235

    
236
// Return an array with all disks information.
237
function installer_find_all_disks() {
238
	global $g, $fstype, $savemsg;
239
	$disk = explode("\n", `/usr/sbin/pc-sysinstall/pc-sysinstall/pc-sysinstall.sh disk-list`);
240
	$disks_array = array();
241
	foreach ($disk as $d) {
242
		if (!$d) {
243
			continue;
244
		}
245
		$disks_info = explode(":", $d);
246
		$tmp_array = array();
247
		$disk_info = explode("\n", `/usr/sbin/pc-sysinstall/pc-sysinstall/pc-sysinstall.sh disk-info {$disks_info[0]}`);
248
		foreach ($disk_info as $di) {
249
			$di_s = explode("=", $di);
250
			if ($di_s[0]) {
251
				$tmp_array[$di_s[0]] = $di_s[1];
252
			}
253
		}
254
		$tmp_array['size']--;
255
		$tmp_array['disk'] = trim($disks_info[0]);
256
		$tmp_array['desc'] = trim(htmlentities($disks_info[1]));
257
		$disks_array[] = $tmp_array;
258
	}
259
	return $disks_array;
260
}
261

    
262
function update_installer_status() {
263
	global $g, $fstype, $savemsg;
264
	// Ensure status files exist
265
	if (!file_exists("/tmp/installer_installer_running")) {
266
		touch("/tmp/installer_installer_running");
267
	}
268
	$status = `cat /tmp/.pc-sysinstall/pc-sysinstall.log`;
269
	$status = str_replace("\n", "\\n", $status);
270
	$status = str_replace("\n", "\\r", $status);
271
	$status = str_replace("'", "\\'", $status);
272
	echo "document.forms[0].installeroutput.value='$status';\n";
273
	echo "document.forms[0].installeroutput.scrollTop = document.forms[0].installeroutput.scrollHeight;\n";
274
	// Find out installer progress
275
	$progress = "5";
276
	if (strstr($status, "Running: dd")) {
277
		$progress = "6";
278
	}
279
	if (strstr($status, "Running: gpart create -s GPT")) {
280
		$progress = "7";
281
	}
282
	if (strstr($status, "Running: gpart bootcode")) {
283
		$progress = "7";
284
	}
285
	if (strstr($status, "Running: newfs -U")) {
286
		$progress = "8";
287
	}
288
	if (strstr($status, "Running: sync")) {
289
		$progress = "9";
290
	}
291
	if (strstr($status, "/boot /mnt/boot")) {
292
		$progress = "10";
293
	}
294
	if (strstr($status, "/COPYRIGHT /mnt/COPYRIGHT")) {
295
		$progress = "11";
296
	}
297
	if (strstr($status, "/bin /mnt/bin")) {
298
		$progress = "12";
299
	}
300
	if (strstr($status, "/conf /mnt/conf")) {
301
		$progress = "15";
302
	}
303
	if (strstr($status, "/conf.default /mnt/conf.default")) {
304
		$progress = "20";
305
	}
306
	if (strstr($status, "/dev /mnt/dev")) {
307
		$progress = "25";
308
	}
309
	if (strstr($status, "/etc /mnt/etc")) {
310
		$progress = "30";
311
	}
312
	if (strstr($status, "/home /mnt/home")) {
313
		$progress = "35";
314
	}
315
	if (strstr($status, "/kernels /mnt/kernels")) {
316
		$progress = "40";
317
	}
318
	if (strstr($status, "/libexec /mnt/libexec")) {
319
		$progress = "50";
320
	}
321
	if (strstr($status, "/lib /mnt/lib")) {
322
		$progress = "60";
323
	}
324
	if (strstr($status, "/root /mnt/root")) {
325
		$progress = "70";
326
	}
327
	if (strstr($status, "/sbin /mnt/sbin")) {
328
		$progress = "75";
329
	}
330
	if (strstr($status, "/sys /mnt/sys")) {
331
		$progress = "80";
332
	}
333
	if (strstr($status, "/usr /mnt/usr")) {
334
		$progress = "95";
335
	}
336
	if (strstr($status, "/usr /mnt/usr")) {
337
		$progress = "90";
338
	}
339
	if (strstr($status, "/var /mnt/var")) {
340
		$progress = "95";
341
	}
342
	if (strstr($status, "cap_mkdb /etc/login.conf")) {
343
		$progress = "96";
344
	}
345
	if (strstr($status, "Setting hostname")) {
346
		$progress = "97";
347
	}
348
	if (strstr($status, "umount -f /mnt")) {
349
		$progress = "98";
350
	}
351
	if (strstr($status, "umount -f /mnt")) {
352
		$progress = "99";
353
	}
354
	if (strstr($status, "Installation finished")) {
355
		$progress = "100";
356
	}
357
	// Check for error and bail if we see one.
358
	if (stristr($status, "error")) {
359
		$error = true;
360
		echo "\$('#installerrunning').html('<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'); ";
361
		echo "\$('#progressbar').css('width','100%');\n";
362
		unlink_if_exists("/tmp/install_complete");
363
		return;
364
	}
365
	$running_old = trim(file_get_contents("/tmp/installer_installer_running"));
366
	if ($installer_running <> "running") {
367
		$ps_running = exec("/bin/ps awwwux | /usr/bin/grep -v grep | /usr/bin/grep 'sh /tmp/installer.sh'");
368
		if ($ps_running)	{
369
			$running = "\$('#installerrunning').html('<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>'); ";
370
			if ($running_old <> $running) {
371
				echo $running;
372
				file_put_contents("/tmp/installer_installer_running", "$running");
373
			}
374
		}
375
	}
376
	if ($progress) {
377
		echo "\$('#progressbar').css('width','{$progress}%');\n";
378
	}
379
	if (file_exists("/tmp/install_complete")) {
380
		echo "\$('#installerrunning').html('<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";
381
		echo "\$('#pbdiv').fadeOut();\n";
382
		unlink_if_exists("/tmp/installer.sh");
383
		file_put_contents("/tmp/installer_installer_running", "finished");
384
	}
385
}
386

    
387
function update_installer_status_win($status) {
388
	global $g, $fstype, $savemsg;
389
	echo "<script type=\"text/javascript\">\n";
390
	echo "	\$('#installeroutput').val('" . str_replace(htmlentities($status), "\n", "") . "');\n";
391
	echo "</script>\n";
392
}
393

    
394
function begin_install() {
395
	global $g, $savemsg;
396
	if (file_exists("/tmp/install_complete")) {
397
		return;
398
	}
399
	unlink_if_exists("/tmp/install_complete");
400
	update_installer_status_win(sprintf(gettext("Beginning installation on disk %s."),$disk));
401
	start_installation();
402
}
403

    
404
function head_html() {
405
	global $g, $fstype, $savemsg;
406
	echo <<<EOF
407
<html>
408
	<head>
409
		<style type='text/css'>
410
			hr {
411
				border: 0;
412
				color: #000000;
413
				background-color: #000000;
414
				height: 1px;
415
				width: 100%;
416
				text-align: left;
417
			}
418
			a:link {
419
				color: #000000;
420
				text-decoration:underline;
421
				font-size:14;
422
			}
423
			a:visited {
424
				color: #000000;
425
				text-decoration:underline;
426
				font-size:14;
427
			}
428
			a:hover {
429
				color: #FFFF00;
430
				text-decoration: none;
431
				font-size:14;
432
			}
433
			a:active {
434
				color: #FFFF00;
435
				text-decoration:underline;
436
				font-size:14;
437
			}
438
		</style>
439
	</head>
440
EOF;
441

    
442
}
443

    
444
function body_html() {
445
	global $g, $fstype, $savemsg;
446
	$pgtitle = array("{$g['product_name']}", gettext("Installer"));
447
	include("head.inc");
448
	echo <<<EOF
449
	<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
450
	<script type="text/javascript" src="/javascript/jquery-1.11.1.min.js"></script>
451
	<script type="text/javascript" src="/javascript/jquery-migrate-1.2.1.min.js"></script>
452
	<script type="text/javascript" src="/javascript/jquery/jquery-ui-1.11.1.min.js"></script>
453
	<script type="text/javascript">
454
		function getinstallerprogress() {
455
			url = '/installer/installer.php';
456
			pars = 'state=update_installer_status';
457
			callajax(url, pars, installcallback);
458
		}
459
		function callajax(url, pars, activitycallback) {
460
			jQuery.ajax(
461
				url,
462
				{
463
					type: 'post',
464
					data: pars,
465
					complete: activitycallback
466
				});
467
		}
468
		function installcallback(transport) {
469
			setTimeout('getinstallerprogress()', 2000);
470
			eval(transport.responseText);
471
		}
472
	</script>
473
EOF;
474

    
475
	if ($one_two) {
476
		echo "<p class=\"pgtitle\">{$pgtitle}</font></p>";
477
	}
478

    
479
	if ($savemsg) {
480
		print_info_box($savemsg);
481
	}
482
}
483

    
484
function end_html() {
485
	global $g, $fstype, $savemsg;
486
	echo "</form>";
487
	echo "</body>";
488
	echo "</html>";
489
}
490

    
491
function template() {
492
	global $g, $fstype, $savemsg;
493
	head_html();
494
	body_html();
495
	echo <<<EOF
496
	<div id="mainlevel">
497
		<table width="100%" border="0" cellpadding="0" cellspacing="0">
498
			<tr>
499
				<td>
500
					<div id="mainarea">
501
						<table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">
502
							<tr>
503
								<td class="tabcont" >
504
									<form action="installer.php" method="post">
505
									<div id="pfsensetemplate">
506

    
507

    
508
									</div>
509
								</td>
510
							</tr>
511
						</table>
512
					</div>
513
				</td>
514
			</tr>
515
		</table>
516
	</div>
517
EOF;
518
	end_html();
519
}
520

    
521
function verify_before_install() {
522
	global $g, $fstype, $savemsg;
523
	$encrypted_root = false;
524
	$non_encrypted_boot = false;
525
	$non_encrypted_notice = false;
526
	head_html();
527
	body_html();
528
	page_table_start($g['product_name'] . " installer - Verify final installation settings");
529
	// If we are visiting this step from anything but the row editor / custom install
530
	// then load the on disk layout contents if they are available.
531
	if (!$_REQUEST['fstype0'] && file_exists("/tmp/webInstaller_disk_layout.txt")) {
532
		$disks = unserialize(file_get_contents("/tmp/webInstaller_disk_layout.txt"));
533
		$bootmanager = unserialize(file_get_contents("/tmp/webInstaller_disk_bootmanager.txt"));
534
		$restored_layout_from_file = true;
535
		$restored_layout_txt = "The previous disk layout was restored from disk";
536
	} else {
537
		$disks = array();
538
	}
539
	if (!$bootmanager) {
540
		$bootmanager = $_REQUEST['bootmanager'];
541
	}
542
	// echo "\n<!--" . print_r($_REQUEST, true) . " -->\n";
543
	$disk = pcsysinstall_get_disk_info(htmlspecialchars($_REQUEST['disk']));
544
	$disksize = format_bytes($disk['size'] * 1048576);
545
	// Loop through posted items and create an array
546
	for ($x=0; $x<99; $x++) { // XXX: Make this more optimal
547
		if (!$_REQUEST['fstype' . $x]) {
548
			continue;
549
		}
550
		$tmparray = array();
551
		if ($_REQUEST['fstype' . $x] <> "SWAP") {
552
			$tmparray['mountpoint'] = $_REQUEST['mountpoint' . $x];
553
			// Check for encrypted slice /
554
			if (stristr($_REQUEST['fstype' . $x], ".eli")) {
555
				if ($tmparray['mountpoint'] == "/") {
556
					$encrypted_root = true;
557
				}
558
			}
559
			// Check if we have a non-encrypted /boot
560
			if ($tmparray['mountpoint'] == "/boot") {
561
				if (!stristr($_REQUEST['fstype' . $x], ".eli")) {
562
					$non_encrypted_boot = true;
563
				}
564
			}
565
			if ($tmparray['mountpoint'] == "/conf") {
566
				$tmparray['mountpoint'] = "/conf{$x}";
567
				$error_txt[] = "/conf is not an allowed mount point and has been renamed to /conf{$x}.";
568
			}
569
		} else  {
570
			$tmparray['mountpoint'] = "none";
571
		}
572
		// If we have an encrypted /root and lack a non encrypted /boot, throw an error/warning
573
		if ($encrypted_root && !$non_encrypted_boot && !$non_encrypted_notice) {
574
			$error_txt[] = "A non-encrypted /boot slice is required when encrypting the / slice";
575
			$non_encrypted_notice = true;
576
		}
577
		$tmparray['disk'] = $_REQUEST['disk' . $x];
578
		$tmparray['fstype'] = $_REQUEST['fstype' . $x];
579
		$tmparray['size'] = $_REQUEST['size' . $x];
580
		$tmparray['encpass'] = $_REQUEST['encpass' . $x];
581
		$disks[] = $tmparray;
582
	}
583
	// echo "\n<!-- " . print_r($disks, true) . " --> \n";
584
	$bootmanagerupper = strtoupper($bootmanager);
585
	echo <<<EOFAMBAC
586
	<form method="post" action="installer.php">
587
	<input type="hidden" name="fstype" value="{$fstype_echo}">
588
	<input type="hidden" name="disk" value="{$disk_echo}">
589
	<input type="hidden" name="state" value="begin_install">
590
	<input type="hidden" name="swapsize" value="{$swapsize}">
591
	<input type="hidden" name="encpass" value="{$encpass}">
592
	<input type="hidden" name="bootmanager" value="{$bootmanager}">
593
	<div id="mainlevel">
594
		<table width="800" border="0" cellpadding="0" cellspacing="0">
595
			<tr>
596
				<td>
597
					<div id="mainarea">
598
						<table width="100%" border="0" cellpadding="0" cellspacing="0">
599
							<tr>
600
								<td >
601
									<div>
602
										<center>
603
											<div id="pfsensetemplate">
604
												<table width='100%'>
605
EOFAMBAC;
606
												// If errors are found, throw the big red box.
607
												if ($error_txt) {
608
													echo "<tr><td colspan=\"5\">&nbsp;</td>";
609
													echo "<tr><td colspan=\"5\">";
610
													print_input_errors($error_txt);
611
													echo "</td></tr>";
612
												} else {
613
													echo "<tr><td>&nbsp;</td></tr>";
614
												}
615

    
616
	echo <<<EOFAMBACBAF
617

    
618
												<tr><td colspan='5' align="center"><b>Boot manager: {$bootmanagerupper}</td></tr>
619
												<tr><td>&nbsp;</td></tr>
620
												<tr>
621
													<td align='left'>
622
														<b>Mount point</b>
623
													</td>
624
													<td align='left'>
625
														<b>Filesysytem type</b>
626
													</td>
627
													<td align='left'>
628
														<b>Disk</b>
629
													</td>
630
													<td align='left'>
631
														<b>Size</b>
632
													</td>
633
													<td align='left'>
634
														<b>Encryption password</b>
635
													</td>
636
												</tr>
637
												<tr><td colspan='5'><hr></td></tr>
638

    
639
EOFAMBACBAF;
640

    
641
													foreach ($disks as $disk) {
642
														$desc = pcsysinstall_get_disk_info($disk['disk']);
643
														echo "<tr>";
644
														echo "<td>&nbsp;&nbsp;&nbsp;" . htmlspecialchars($disk['mountpoint']) . "</td>";
645
														echo "<td>" . htmlspecialchars($disk['fstype']) . "</td>";
646
														echo "<td>" . htmlspecialchars($disk['disk']) . " " . htmlspecialchars($desc['desc']) . "</td>";
647
														echo "<td>" . htmlspecialchars($disk['size']) . "</td>";
648
														echo "<td>" . htmlspecialchars($disk['encpass']) . "</td>";
649
														echo "</tr>";
650
													}
651

    
652
echo <<<EOFAMB
653
												<tr><td colspan="5"><hr></td></tr>
654
												</table>
655
											</div>
656
										</center>
657
									</div>
658
								</td>
659
							</tr>
660
						</table>
661
					</div>
662
					<center>
663
						<p/>
664
						<input type="button" value="Cancel" onClick="javascript:document.location='installer.php?state=custominstall';"> &nbsp;&nbsp;
665
EOFAMB;
666
						if (!$error_txt) {
667
							echo "<input type=\"submit\" value=\"Begin installation\"> <br />&nbsp;";
668
						}
669
echo <<<EOFAMBASDF
670

    
671
					</center>
672
				</td>
673
			</tr>
674
		</table>
675
	</div>
676
EOFAMBASDF;
677

    
678

    
679
	page_table_end();
680
	end_html();
681
	write_out_pc_sysinstaller_config($disks, $bootmanager);
682
	// Serialize layout to disk so it can be read in later.
683
	file_put_contents("/tmp/webInstaller_disk_layout.txt", serialize($disks));
684
	file_put_contents("/tmp/webInstaller_disk_bootmanager.txt", serialize($bootmanager));
685
}
686

    
687
function installing_gui() {
688
	global $g, $fstype, $savemsg;
689
	head_html();
690
	body_html();
691
	echo "<form action=\"installer.php\" method=\"post\" state=\"step1_post\">";
692
	page_table_start();
693
	echo <<<EOF
694
	<center>
695
		<table width="100%">
696
		<tr><td>
697
			<div id="mainlevel">
698
				<table width="100%" border="0" cellpadding="0" cellspacing="0">
699
					<tr>
700
						<td>
701
							<div id="mainarea">
702
								<table width="100%" border="0" cellpadding="0" cellspacing="0">
703
									<tr>
704
										<td>
705
											<div id="pfsenseinstaller" width="100%">
706
												<div id='installerrunning' width='100%' style="padding:8px; border:1px dashed #000000">
707
													<table>
708
														<tr>
709
															<td valign="middle">
710
																<img src="/themes/{$g['theme']}/images/misc/loader.gif">
711
															</td>
712
															<td valign="middle">
713
																&nbsp;<font size="2"><b>Starting Installer...  Please wait...
714
															</td>
715
														</tr>
716
													</table>
717
												</div>
718
												<div id='pbdiv'>
719
													<br />
720
													<center>
721
													<table id='pbtable' height='15' width='640' border='0' colspacing='0' cellpadding='0' cellspacing='0'>
722
														<tr>
723
															<td background="/themes/{$g['theme']}/images/misc/bar_left.gif" height='15' width='5'>
724
															</td>
725
															<td>
726
																<table id="progholder" name="progholder" height='15' width='630' border='0' colspacing='0' cellpadding='0' cellspacing='0'>
727
																	<td background="/themes/{$g['theme']}/images/misc/bar_gray.gif" valign="top" align="left">
728
																		<img src='/themes/{$g['theme']}/images/misc/bar_blue.gif' width='0' height='15' name='progressbar' id='progressbar'>
729
																	</td>
730
																</table>
731
															</td>
732
															<td background="/themes/{$g['theme']}/images/misc/bar_right.gif" height='15' width='5'>
733
															</td>
734
														</tr>
735
													</table>
736
													<br />
737
												</div>
738
												<textarea name='installeroutput' id='installeroutput' rows="31" cols="90">
739
												</textarea>
740
											</div>
741
										</td>
742
									</tr>
743
								</table>
744
							</div>
745
						</td>
746
					</tr>
747
				</table>
748
			</div>
749
		</td></tr>
750
		</table>
751
	</center>
752
	<script type="text/javascript">setTimeout('getinstallerprogress()', 250);</script>
753

    
754
EOF;
755
	page_table_end();
756
	end_html();
757
}
758

    
759
function page_table_start($pgtitle = "") {
760
	global $g, $fstype, $savemsg;
761
	if ($pgtitle == "") {
762
		$pgtitle = "{$g['product_name']} installer";
763
	}
764
	echo <<<EOF
765
	<center>
766
		<img border="0" src="/themes/{$g['theme']}/images/logo.gif"></a><br />
767
		<table cellpadding="6" cellspacing="0" width="550" style="border:1px solid #000000">
768
		<tr height="10" bgcolor="#990000">
769
			<td style="border-bottom:1px solid #000000">
770
				<font color='white'>
771
					<b>
772
						{$pgtitle}
773
					</b>
774
				</font>
775
			</td>
776
		</tr>
777
		<tr>
778
			<td>
779

    
780
EOF;
781

    
782
}
783

    
784
function page_table_end() {
785
	global $g, $fstype, $savemsg;
786
	echo <<<EOF
787
			</td>
788
		</tr>
789
		</table>
790
	</center>
791

    
792
EOF;
793

    
794
}
795

    
796
function installer_custom() {
797
	global $g, $fstype, $savemsg;
798
	global $select_txt, $custom_disks;
799
	if (file_exists("/tmp/.pc-sysinstall/pc-sysinstall.log")) {
800
		unlink("/tmp/.pc-sysinstall/pc-sysinstall.log");
801
	}
802
	$disks = installer_find_all_disks();
803
	// Pass size of disks down to javascript.
804
	$disk_sizes_js_txt = "var disk_sizes = new Array();\n";
805
	foreach ($disks as $disk) {
806
		$disk_sizes_js_txt .= "disk_sizes['{$disk['disk']}'] = '{$disk['size']}';\n";
807
	}
808
	head_html();
809
	body_html();
810
	page_table_start($g['product_name'] . " installer - Customize disk(s) layout");
811
	echo <<<EOF
812
		<script type="text/javascript">
813
			Array.prototype.in_array = function(p_val) {
814
				for (var i = 0, l = this.length; i < l; i++) {
815
					if (this[i] == p_val) {
816
						return true;
817
					}
818
				}
819
				return false;
820
			}
821
			function row_helper_dynamic_custom() {
822
				var totalsize = 0;
823
				{$disk_sizes_js_txt}
824
				// Run through all rows and process data
825
				for (var x = 0; x<99; x++) { //optimize me better
826
					if (\$('#fstype' + x).length) {
827
						if (\$('#size' + x).val() == '') {
828
							\$('#size' + x).val(disk_sizes[\$('disk' + x).value]);
829
						}
830
						var fstype = \$('#fstype' + x).val();
831
						if (fstype.substring(fstype.length - 4) == ".eli") {
832
							\$('#encpass' + x).prop('disabled',false);
833
							if (!encryption_warning_shown) {
834
								alert('NOTE: If you define a disk encryption password you will need to enter it on *EVERY* bootup!');
835
								encryption_warning_shown = true;
836
							}
837
						} else {
838
							\$('#encpass' + x).prop('disabled',true);
839
						}
840
					}
841
					// Calculate size allocations
842
					if (\$('#size' + x).length) {
843
						if (parseInt($('#size' + x).val()) > 0) {
844
							totalsize += parseInt($('#size' + x).val());
845
						}
846
					}
847
				}
848
				// If the totalsize element exists, set it and disable
849
				if (\$('#totalsize').length) {
850
					if (\$('#totalsize').val() != totalsize) {
851
						// When size allocation changes, draw attention.
852
						jQuery('#totalsize').effect('highlight');
853
						\$('#totalsize').val(totalsize);
854
					}
855
					\$('#totalsize').prop('disabled',true);
856
				}
857
				if (\$('#disktotals').length) {
858
					var disks_seen = new Array();
859
					var tmp_sizedisks = 0;
860
					var disksseen = 0;
861
					for (var xx = 0; xx<99; xx++) {
862
						if (\$('#disk' + xx).length) {
863
							if (!disks_seen.in_array(\$('#disk' + xx).val())) {
864
								tmp_sizedisks += parseInt(disk_sizes[\$('#disk' + xx).val()]);
865
								disks_seen[disksseen] = \$('#disk' + xx).val();
866
								disksseen++;
867
							}
868
						}
869
					\$('#disktotals').val(tmp_sizedisks);
870
					\$('#disktotals').prop('disabled',true);
871
					\$('#disktotals').css('color','#000000');
872
					var remaining = parseInt(\$('#disktotals').val()) - parseInt(\$('#totalsize').val());
873
						if (remaining == 0) {
874
							if (\$('#totalsize').length)
875
								\$('#totalsize').css({
876
									'background':'#00FF00',
877
									'color':'#000000'
878
								});
879
						} else {
880
							if (\$('#totalsize').length)
881
								\$('#totalsize').css({
882
									'background':'#FFFFFF',
883
									'color':'#000000'
884
								});
885
						}
886
						if (parseInt(\$('#totalsize').val()) > parseInt(\$('#disktotals').val())) {
887
							if (\$('#totalsize'))
888
								\$('#totalsize').css({
889
									'background':'#FF0000',
890
									'color':'#000000'
891
								});
892
						}
893
						if (\$('#availalloc').length) {
894
							\$('#availalloc').prop('disabled',true);
895
							\$('#availalloc').val(remaining);
896
							\$('#availalloc').css({
897
								'background':'#FFFFFF',
898
								'color':'#000000'
899
							});
900
						}
901
					}
902
				}
903
			}
904
		</script>
905
		<script type="text/javascript" src="/javascript/row_helper_dynamic.js"></script>
906
		<script type="text/javascript">
907
			// Setup rowhelper data types
908
			rowname[0] = "mountpoint";
909
			rowtype[0] = "textbox";
910
			rowsize[0] = "8";
911
			rowname[1] = "fstype";
912
			rowtype[1] = "select";
913
			rowsize[1] = "1";
914
			rowname[2] = "disk";
915
			rowtype[2] = "select";
916
			rowsize[2] = "1";
917
			rowname[3] = "size";
918
			rowtype[3] = "textbox";
919
			rowsize[3] = "8";
920
			rowname[4] = "encpass";
921
			rowtype[4] = "textbox";
922
			rowsize[4] = "8";
923
			field_counter_js = 5;
924
			rows = 1;
925
			totalrows = 1;
926
			loaded = 1;
927
			rowhelper_onChange = 	" onChange='javascript:row_helper_dynamic_custom()' ";
928
			rowhelper_onDelete = 	"row_helper_dynamic_custom(); ";
929
			rowhelper_onAdd = 		"row_helper_dynamic_custom();";
930
		</script>
931
		<form action="installer.php" method="post">
932
			<input type="hidden" name="state" value="verify_before_install">
933
			<div id="mainlevel">
934
				<center>
935
				<table width="100%" border="0" cellpadding="5" cellspacing="0">
936
					<tr>
937
						<td>
938
							<center>
939
							<div id="mainarea">
940
								<center>
941
								<table width="100%" border="0" cellpadding="5" cellspacing="5">
942
									<tr>
943
										<td>
944
											<div id="pfsenseinstaller">
945
												<center>
946
												<div id='loadingdiv'>
947
													<table>
948
														<tr>
949
															<td valign="center">
950
																<img src="/themes/{$g['theme']}/images/misc/loader.gif">
951
															</td>
952
															<td valign="center">
953
																&nbsp;Probing disks, please wait...
954
															</td>
955
														</tr>
956
													</table>
957
												</div>
958
EOF;
959
	ob_flush();
960
	// Read bootmanager setting from disk if found
961
	if (file_exists("/tmp/webInstaller_disk_bootmanager.txt")) {
962
		$bootmanager = unserialize(file_get_contents("/tmp/webInstaller_disk_bootmanager.txt"));
963
	}
964
	if ($bootmanager == "none") {
965
		$noneselected = " SELECTED";
966
	}
967
	if ($bootmanager == "bsd") {
968
		$bsdeselected = " SELECTED";
969
	}
970
	if (!$disks)  {
971
		$custom_txt = gettext("ERROR: Could not find any suitable disks for installation.");
972
	} else {
973
		// Prepare disk selection dropdown
974
		$custom_txt = <<<EOF
975
												<center>
976
												<table>
977
												<tr>
978
													<td align='right'>
979
														Boot manager:
980
													</td>
981
													<td>
982
														<select name='bootmanager'>
983
															<option value='none' $noneselected>
984
																None
985
															</option>
986
															<option value='bsd' $bsdeselected>
987
																BSD
988
															</option>
989
														</select>
990
													</td>
991
												</tr>
992
												</table>
993
												<hr>
994
												<table id='maintable'><tbody>
995
												<tr>
996
													<td align="middle">
997
														<b>Mount</b>
998
													</td>
999
													<td align='middle'>
1000
														<b>Filesysytem</b>
1001
													</td>
1002
													<td align="middle">
1003
														<b>Disk</b>
1004
													</td>
1005
													<td align="middle">
1006
														<b>Size</b>
1007
													</td>
1008
													<td align="middle">
1009
														<b>Encryption password</b>
1010
													</td>
1011
													<td>
1012
														&nbsp;
1013
													</td>
1014
												</tr>
1015
												<tr>
1016

    
1017
EOF;
1018

    
1019
		// Calculate swap disk sizes
1020
		$memory = get_memory();
1021
		$swap_size = $memory[0] * 2;
1022
		$first_disk = trim(installer_find_first_disk());
1023
		$disk_info = pcsysinstall_get_disk_info($first_disk);
1024
		$size = $disk_info['size'];
1025
		$first_disk_size = $size - $swap_size;
1026

    
1027
		// Debugging
1028
		// echo "\n\n<!-- $first_disk - " . print_r($disk_info, true) . " - $size  - $first_disk_size -->\n\n";
1029

    
1030
		// Check to see if a on disk layout exists
1031
		if (file_exists("/tmp/webInstaller_disk_layout.txt")) {
1032
			$disks_restored = unserialize(file_get_contents("/tmp/webInstaller_disk_layout.txt"));
1033
			$restored_layout_from_file = true;
1034
			$restored_layout_txt = "<br />* The previous disk layout was restored from a previous session";
1035
		}
1036

    
1037
		// If we restored disk layout(s) from a file then build the rows
1038
		if ($restored_layout_from_file == true) {
1039
			$diskcounter = 0;
1040
			foreach ($disks_restored as $dr) {
1041
				$custom_txt .= return_rowhelper_row("$diskcounter", $dr['mountpoint'], $dr['fstype'], $dr['disk'], $dr['size'], $dr['encpass']);
1042
				$diskcounter++;
1043
			}
1044
		} else {
1045
			// Construct the default rows that outline the disks configuration.
1046
			$custom_txt .= return_rowhelper_row("0", "/", "UFS+S", $first_disk, "{$first_disk_size}", "");
1047
			$custom_txt .= return_rowhelper_row("1", "none", "SWAP", $first_disk, "$swap_size", "");
1048
		}
1049

    
1050
		// tfoot and tbody are used by rowhelper
1051
		$custom_txt .= "</tr>";
1052
		$custom_txt .= "<tfoot></tfoot></tbody>";
1053
		// Total allocation box
1054
		$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>";
1055
		// Add row button
1056
		$custom_txt .= "</td><td>&nbsp;</td><td>";
1057
		$custom_txt .= "<div id=\"addrowbutton\">";
1058
		$custom_txt .= "<a onclick=\"javascript:addRowTo('maintable', 'formfldalias'); return false;\" href=\"#\">";
1059
		$custom_txt .= "<img border=\"0\" src=\"/themes/{$g['theme']}/images/icons/icon_plus.gif\" alt=\"\" title=\"add another entry\" /></a>";
1060
		$custom_txt .= "</div>";
1061
		$custom_txt .= "</td></tr>";
1062
		// Disk capacity box
1063
		$custom_txt .= "<tr><td></td><td></td><td align='right'>Disk(s) capacity total:</td><td><input style='border:0px; background-color: #FFFFFF;' size='8' id='disktotals' name='disktotals'></td></tr>";
1064
		// Remaining allocation box
1065
		$custom_txt .= "<tr><td></td><td></td><td align='right'>Available space for allocation:</td><td><input style='border:0px; background-color: #FFFFFF;' size='8' id='availalloc' name='availalloc'></td></tr>";
1066
		$custom_txt .= "</table>";
1067
		$custom_txt .= "<script type=\"text/javascript\">row_helper_dynamic_custom();</script>";
1068
	}
1069
	echo <<<EOF
1070

    
1071
												<tr>
1072
													<td colspan='4'>
1073
													<script type="text/javascript">
1074
														\$('#loadingdiv').css('visibility','hidden');
1075
													</script>
1076
													<div id='contentdiv' style="display:none;">
1077
														<p/>
1078
														{$custom_txt}<p/>
1079
														<hr><p/>
1080
														<input type="button" value="Cancel" onClick="javascript:document.location='/installer/installer.php';"> &nbsp;&nbsp
1081
														<input type="submit" value="Next">
1082
													</div>
1083
													<script type="text/javascript">
1084
														var encryption_warning_shown = false;
1085
														\$('#contentdiv').fadeIn();
1086
														row_helper_dynamic_custom();
1087
													</script>
1088
												</center>
1089
												</td></tr>
1090
												</table>
1091
											</div>
1092
										</td>
1093
									</tr>
1094
								</table>
1095
								</center>
1096
								<span class="vexpl">
1097
									<span class="red">
1098
										<strong>
1099
											NOTES:
1100
										</strong>
1101
									</span>
1102
									<br />* Sizes are in megabytes.
1103
									<br />* Mount points named /conf are not allowed.  Use /cf if you want to make a configuration slice/mount.
1104
									{$restored_layout_txt}
1105
								</span>
1106
								</strong>
1107
							</div>
1108
						</td>
1109
					</tr>
1110
				</table>
1111
			</div>
1112
			</center>
1113
			<script type="text/javascript">
1114
			<!--
1115
				newrow[1] = "{$select_txt}";
1116
				newrow[2] = "{$custom_disks}";
1117
			-->
1118
			</script>
1119

    
1120

    
1121
EOF;
1122
	page_table_end();
1123
	end_html();
1124
}
1125

    
1126
function installer_main() {
1127
	global $g, $fstype, $savemsg;
1128
	if (file_exists("/tmp/.pc-sysinstall/pc-sysinstall.log")) {
1129
		unlink("/tmp/.pc-sysinstall/pc-sysinstall.log");
1130
	}
1131
	head_html();
1132
	body_html();
1133
	$disk = installer_find_first_disk();
1134
	// Only enable ZFS if this exists.  The install will fail otherwise.
1135
	if (file_exists("/boot/gptzfsboot")) {
1136
		$zfs_enabled = "<tr bgcolor=\"#9A9A9A\"><td align=\"center\"><a href=\"installer.php?state=easy_install_zfs\">Easy installation of {$g['product_name']} using the ZFS filesystem on disk {$disk}</a></td></tr>";
1137
	}
1138
	page_table_start();
1139
	echo <<<EOF
1140
		<form action="installer.php" method="post" state="step1_post">
1141
			<div id="mainlevel">
1142
				<center>
1143
				<b><font face="arial" size="+2">Welcome to the {$g['product_name']} webInstaller!</b></font><p/>
1144
				<font face="arial" size="+1">This utility will install {$g['product_name']} to a hard disk, flash drive, etc.</font>
1145
				<table width="100%" border="0" cellpadding="5" cellspacing="0">
1146
					<tr>
1147
						<td>
1148
							<center>
1149
							<div id="mainarea">
1150
								<br />
1151
								<center>
1152
								Please select an installer option to begin:
1153
								<p/>
1154
								<table width="100%" border="0" cellpadding="5" cellspacing="5">
1155
									<tr>
1156
										<td>
1157
											<div id="pfsenseinstaller">
1158
												<center>
1159
EOF;
1160
	if (!$disk) {
1161
		echo gettext("ERROR: Could not find any suitable disks for installation.");
1162
		echo "</div></td></tr></table></div></table></div>";
1163
		end_html();
1164
		exit;
1165
	}
1166
	echo <<<EOF
1167

    
1168
													<table cellspacing="5" cellpadding="5" style="border: 1px dashed;">
1169
														<tr bgcolor="#CECECE"><td align="center">
1170
															<a href="installer.php?state=easy_install_ufs">Easy installation of {$g['product_name']} using the UFS filesystem on disk {$disk}</a>
1171
														</td></tr>
1172
														{$zfs_enabled}
1173
														<tr bgcolor="#AAAAAA"><td align="center">
1174
															<a href="installer.php?state=custominstall">Custom installation of {$g['product_name']}</a>
1175
														</td></tr>
1176
														<tr bgcolor="#CECECE"><td align="center">
1177
															<a href='/'>Cancel and return to Dashboard</a>
1178
														</td></tr>
1179
													</table>
1180
												</center>
1181
											</div>
1182
										</td>
1183
									</tr>
1184
								</table>
1185
							</div>
1186
						</td>
1187
					</tr>
1188
				</table>
1189
			</div>
1190
EOF;
1191
	page_table_end();
1192
	end_html();
1193
}
1194

    
1195
function return_rowhelper_row($rownum, $mountpoint, $fstype, $disk, $size, $encpass) {
1196
	global $g, $select_txt, $custom_disks, $savemsg;
1197
	$release = php_uname("r");
1198
	// Get release number like 8.3 or 10.1
1199
	$relnum = strtok($release, "-");
1200

    
1201
	// Mount point
1202
	$disks = installer_find_all_disks();
1203
	$custom_txt .= "<tr>";
1204
	$custom_txt .=  "<td><input size='8' id='mountpoint{$rownum}' name='mountpoint{$rownum}' value='{$mountpoint}'></td>";
1205

    
1206
	// Filesystem type array
1207
	$types = array(
1208
		'UFS' => 'UFS',
1209
		'UFS+S' => 'UFS + Softupdates',
1210
		'UFS.eli' => 'Encrypted UFS',
1211
		'UFS+S.eli' => 'Encrypted UFS + Softupdates',
1212
		'SWAP' => 'SWAP'
1213
	);
1214

    
1215
	// UFS + Journaling was introduced in 9.0
1216
	if ($relnum >= 9) {
1217
		$types['UFS+J'] = "UFS + Journaling";
1218
		$types['UFS+J.eli'] = "Encrypted UFS + Journaling";
1219
	}
1220

    
1221
	// Add ZFS Boot loader if it exists
1222
	if (file_exists("/boot/gptzfsboot")) {
1223
		$types['ZFS'] = "Zetabyte Filesystem";
1224
		$types['ZFS.eli'] = "Encrypted Zetabyte Filesystem";
1225
	}
1226

    
1227
	// fstype form field
1228
	$custom_txt .=  "<td><select onChange='javascript:row_helper_dynamic_custom()' id='fstype{$rownum}' name='fstype{$rownum}'>";
1229
	$select_txt = "";
1230
	foreach ($types as $type => $desc) {
1231
		if ($type == $fstype) {
1232
			$SELECTED="SELECTED";
1233
		} else {
1234
			$SELECTED="";
1235
		}
1236
		$select_txt .= "<option value='$type' $SELECTED>$desc</option>";
1237
	}
1238
	$custom_txt .= "{$select_txt}</select>\n";
1239
	$custom_txt .= "</td>";
1240

    
1241
	// Disk selection form field
1242
	$custom_txt .= "<td><select id='disk{$rownum}' name='disk{$rownum}'>\n";
1243
	$custom_disks = "";
1244
	foreach ($disks as $dsk) {
1245
		$disksize_bytes = format_bytes($dsk['size'] * 1048576);
1246
		$disksize = $dsk['size'];
1247
		if ($disk == $dsk['disk']) {
1248
			$SELECTED="SELECTED";
1249
		} else {
1250
			$SELECTED="";
1251
		}
1252
		$custom_disks .= "<option value='{$dsk['disk']}' $SELECTED>{$dsk['disk']} - {$dsk['desc']} - {$disksize}MB ({$disksize_bytes})</option>";
1253
	}
1254
	$custom_txt .= "{$custom_disks}</select></td>\n";
1255

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

    
1259
	// Encryption password
1260
	$custom_txt .= "<td>";
1261
	$custom_txt .= "<input id='encpass{$rownum}' name='encpass{$rownum}' size='8' value='{$encpass}'>";
1262
	$custom_txt .= "</td>";
1263

    
1264
	// Add Rowhelper + button
1265
	if ($rownum > 0) {
1266
		$custom_txt .= "<td><a onclick=\"removeRow(this); return false;\" href=\"#\"><img border=\"0\" src=\"/themes/{$g['theme']}/images/icons/icon_x.gif\" alt=\"\" title=\"remove this entry\"/></a></td>";
1267
	}
1268

    
1269
	$custom_txt .= "</tr>";
1270
	return $custom_txt;
1271
}
1272

    
1273
?>
(2-2/2)