Project

General

Profile

Download (38.6 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

    
62
	default:
63
		installer_main();	
64
}
65

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

    
99
function write_out_pc_sysinstaller_config($disks, $bootmanager = "bsd") {
100
	$diskareas = "";
101
	$fd = fopen("/usr/sbin/pc-sysinstall/examples/pfSense-install.cfg", "w");
102
	if(!$fd) 
103
		return true;
104
	if($bootmanager == "") 
105
	 	$bootmanager = "none";
106
	// Yes, -1.  We ++ early in loop.
107
	$numdisks = -1;
108
	$lastdisk = "";
109
	$diskdefs = "";
110
	// Run through the disks and create the conf areas for pc-sysinstaller
111
	foreach($disks as $disksa) {
112
		$fstype = $disksa['fstype'];
113
		$size = $disksa['size'];
114
		$mountpoint = $disksa['mountpoint'];
115
		$disk = $disksa['disk'];
116
		if($disk <> $lastdisk) {
117
			$lastdisk = $disk;
118
			$numdisks++;
119
			$diskdefs .= "# disk {$disk}\n";
120
			$diskdefs .= "disk{$numdisks}={$disk}\n";
121
			$diskdefs .= "partition=all\n";
122
			$diskdefs .= "bootManager={$bootmanager}\n";
123
			$diskdefs .= "commitDiskPart\n\n";
124
		}
125
		$diskareas .= "disk{$numdisks}-part={$fstype} {$size} {$mountpoint} \n";
126
		if($encpass)
127
			$diskareas .= "encpass={$encpass}\n";
128
	}
129
	
130
	$config = <<<EOF
131
# Sample configuration file for an installation using pc-sysinstall
132
# This file was automatically generated by installer.php
133
 
134
installMode=fresh
135
installInteractive=yes
136
installType=FreeBSD
137
installMedium=LiveCD
138

    
139
# Set the disk parameters
140
{$diskdefs}
141

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

    
157
# Do it now!
158
commitDiskLabel
159

    
160
# Set if we are installing via optical, USB, or FTP
161
installType=FreeBSD
162

    
163
packageType=cpdup
164

    
165
# Optional Components
166
cpdupPaths=boot,COPYRIGHT,bin,conf,conf.default,dev,etc,home,kernels,libexec,lib,root,sbin,usr,var
167

    
168
# runExtCommand=chmod a+rx /usr/local/bin/after_installation_routines.sh ; cd / ; /usr/local/bin/after_installation_routines.sh
169
EOF;
170
	fwrite($fd, $config);
171
	fclose($fd);
172
	return;
173
}
174

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

    
198
function installer_find_first_disk() {
199
	global $g, $fstype, $savemsg;
200
	$disk = `/usr/sbin/pc-sysinstall/pc-sysinstall/pc-sysinstall.sh disk-list | head -n1 | cut -d':' -f1`;
201
	return trim($disk);
202
}
203

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

    
227
// Return an array with all disks information.
228
function installer_find_all_disks() {
229
	global $g, $fstype, $savemsg;
230
	$disk = explode("\n", `/usr/sbin/pc-sysinstall/pc-sysinstall/pc-sysinstall.sh disk-list`);
231
	$disks_array = array();
232
	foreach($disk as $d) {
233
		if(!$d) 
234
			continue;
235
		$disks_info = explode(":", $d);
236
		$tmp_array = array();
237
		$disk_info = explode("\n", `/usr/sbin/pc-sysinstall/pc-sysinstall/pc-sysinstall.sh disk-info {$disks_info[0]}`);
238
		foreach($disk_info as $di) { 
239
			$di_s = explode("=", $di);
240
			if($di_s[0])
241
				$tmp_array[$di_s[0]] = $di_s[1];
242
		}
243
		$tmp_array['size']--;
244
		$tmp_array['disk'] = trim($disks_info[0]);
245
		$tmp_array['desc'] = trim(htmlentities($disks_info[1]));
246
		$disks_array[] = $tmp_array;
247
	}
248
	return $disks_array;
249
}
250

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

    
347
function update_installer_status_win($status) {
348
	global $g, $fstype, $savemsg;
349
	echo "<script type=\"text/javascript\">\n";
350
	echo "	\$('#installeroutput').val('" . str_replace(htmlentities($status), "\n", "") . "');\n";
351
	echo "</script>\n";
352
}
353

    
354
function begin_install() {
355
	global $g, $savemsg;
356
	if(file_exists("/tmp/install_complete"))
357
		return;
358
	unlink_if_exists("/tmp/install_complete");
359
	update_installer_status_win(sprintf(gettext("Beginning installation on disk %s."),$disk));
360
	start_installation();
361
}
362

    
363
function head_html() {
364
	global $g, $fstype, $savemsg;
365
	echo <<<EOF
366
<html>
367
	<head>
368
		<style type='text/css'>
369
			hr {
370
				border: 0;
371
				color: #000000;
372
				background-color: #000000;
373
				height: 1px;
374
				width: 100%;
375
				text-align: left;
376
			}
377
			a:link { 
378
				color: #000000;
379
				text-decoration:underline;
380
				font-size:14;
381
			}
382
			a:visited { 
383
				color: #000000;
384
				text-decoration:underline;
385
				font-size:14;
386
			}
387
			a:hover { 
388
				color: #FFFF00;
389
				text-decoration: none;
390
				font-size:14;
391
			}
392
			a:active { 
393
				color: #FFFF00;
394
				text-decoration:underline;
395
				font-size:14;
396
			}
397
		</style>
398
	</head>
399
EOF;
400

    
401
}
402

    
403
function body_html() {
404
	global $g, $fstype, $savemsg;
405
	$pgtitle = array("{$g['product_name']}", gettext("Installer"));
406
	include("head.inc");
407
	echo <<<EOF
408
	<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
409
	<script type="text/javascript" src="/javascript/jquery-1.11.1.min.js"></script>
410
	<script type="text/javascript" src="/javascript/jquery-migrate-1.2.1.min.js"></script>
411
	<script type="text/javascript" src="/javascript/jquery/jquery-ui-1.11.1.min.js"></script>
412
	<script type="text/javascript">
413
		function getinstallerprogress() {
414
			url = '/installer/installer.php';
415
			pars = 'state=update_installer_status';
416
			callajax(url, pars, installcallback);
417
		}
418
		function callajax(url, pars, activitycallback) {
419
			jQuery.ajax(
420
				url,
421
				{
422
					type: 'post',
423
					data: pars,
424
					complete: activitycallback
425
				});
426
		}
427
		function installcallback(transport) {
428
			setTimeout('getinstallerprogress()', 2000);
429
			eval(transport.responseText);
430
		}
431
	</script>
432
EOF;
433

    
434
	if($one_two)
435
		echo "<p class=\"pgtitle\">{$pgtitle}</font></p>";
436

    
437
	if ($savemsg) print_info_box($savemsg); 
438
}
439

    
440
function end_html() {
441
	global $g, $fstype, $savemsg;
442
	echo "</form>";
443
	echo "</body>";
444
	echo "</html>";
445
}
446

    
447
function template() {
448
	global $g, $fstype, $savemsg;
449
	head_html();
450
	body_html();
451
	echo <<<EOF
452
	<div id="mainlevel">
453
		<table width="100%" border="0" cellpadding="0" cellspacing="0">
454
	 		<tr>
455
	    		<td>
456
					<div id="mainarea">
457
						<table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">
458
							<tr>
459
	     						<td class="tabcont" >
460
	      							<form action="installer.php" method="post">
461
									<div id="pfsensetemplate">
462

    
463

    
464
									</div>
465
	     						</td>
466
							</tr>
467
						</table>
468
					</div>
469
				</td>
470
			</tr>
471
		</table>
472
	</div>
473
EOF;
474
	end_html();
475
}
476

    
477
function verify_before_install() {
478
	global $g, $fstype, $savemsg;
479
	$encrypted_root = false;
480
	$non_encrypted_boot = false;
481
	$non_encrypted_notice = false;
482
	head_html();
483
	body_html();
484
	page_table_start($g['product_name'] . " installer - Verify final installation settings");
485
	// If we are visiting this step from anything but the row editor / custom install
486
	// then load the on disk layout contents if they are available.
487
	if(!$_REQUEST['fstype0'] && file_exists("/tmp/webInstaller_disk_layout.txt")) {
488
		$disks = unserialize(file_get_contents("/tmp/webInstaller_disk_layout.txt"));
489
		$bootmanager = unserialize(file_get_contents("/tmp/webInstaller_disk_bootmanager.txt"));
490
		$restored_layout_from_file = true;
491
		$restored_layout_txt = "The previous disk layout was restored from disk";
492
	} else {
493
		$disks = array();
494
	}
495
	if(!$bootmanager) 
496
		$bootmanager = $_REQUEST['bootmanager'];
497
	// echo "\n<!--" . print_r($_REQUEST, true) . " -->\n";
498
	$disk = pcsysinstall_get_disk_info(htmlspecialchars($_REQUEST['disk']));
499
	$disksize = format_bytes($disk['size'] * 1048576);
500
	// Loop through posted items and create an array
501
	for($x=0; $x<99; $x++) { // XXX: Make this more optimal
502
		if(!$_REQUEST['fstype' . $x])
503
			continue;
504
		$tmparray = array();
505
		if($_REQUEST['fstype' . $x] <> "SWAP") {
506
			$tmparray['mountpoint'] = $_REQUEST['mountpoint' . $x];
507
			// Check for encrypted slice /
508
			if(stristr($_REQUEST['fstype' . $x], ".eli")) {
509
				if($tmparray['mountpoint'] == "/") 
510
					$encrypted_root = true;
511
			}
512
			// Check if we have a non-encrypted /boot
513
			if($tmparray['mountpoint'] == "/boot") 	{
514
				if(!stristr($_REQUEST['fstype' . $x], ".eli"))
515
					$non_encrypted_boot = true;
516
			}
517
			if($tmparray['mountpoint'] == "/conf") {	
518
				$tmparray['mountpoint'] = "/conf{$x}";
519
				$error_txt[] = "/conf is not an allowed mount point and has been renamed to /conf{$x}.";
520
			}
521
		} else  {
522
			$tmparray['mountpoint'] = "none";
523
		}
524
		// If we have an encrypted /root and lack a non encrypted /boot, throw an error/warning
525
		if($encrypted_root && !$non_encrypted_boot && !$non_encrypted_notice) {
526
			$error_txt[] = "A non-encrypted /boot slice is required when encrypting the / slice";
527
			$non_encrypted_notice = true;
528
		}
529
		$tmparray['disk'] = $_REQUEST['disk' . $x];
530
		$tmparray['fstype'] = $_REQUEST['fstype' . $x];
531
		$tmparray['size'] = $_REQUEST['size' . $x];
532
		$tmparray['encpass'] = $_REQUEST['encpass' . $x];
533
		$disks[] = $tmparray;
534
	}
535
	// echo "\n<!-- " . print_r($disks, true) . " --> \n";
536
	$bootmanagerupper = strtoupper($bootmanager);
537
	echo <<<EOFAMBAC
538
	<form method="post" action="installer.php">
539
	<input type="hidden" name="fstype" value="{$fstype_echo}">
540
	<input type="hidden" name="disk" value="{$disk_echo}">
541
	<input type="hidden" name="state" value="begin_install">
542
	<input type="hidden" name="swapsize" value="{$swapsize}">
543
	<input type="hidden" name="encpass" value="{$encpass}">
544
	<input type="hidden" name="bootmanager" value="{$bootmanager}">
545
	<div id="mainlevel">
546
		<table width="800" border="0" cellpadding="0" cellspacing="0">
547
	 		<tr>
548
	    		<td>
549
					<div id="mainarea">
550
						<table width="100%" border="0" cellpadding="0" cellspacing="0">
551
							<tr>
552
	     						<td >
553
									<div>
554
										<center>
555
											<div id="pfsensetemplate">
556
												<table width='100%'>
557
EOFAMBAC;
558
												// If errors are found, throw the big red box.
559
												if ($error_txt) {
560
													echo "<tr><td colspan=\"5\">&nbsp;</td>";
561
													echo "<tr><td colspan=\"5\">";
562
													print_input_errors($error_txt);
563
													echo "</td></tr>";
564
												} else 
565
													echo "<tr><td>&nbsp;</td></tr>";
566

    
567
	echo <<<EOFAMBACBAF
568

    
569
												<tr><td colspan='5' align="center"><b>Boot manager: {$bootmanagerupper}</td></tr>
570
												<tr><td>&nbsp;</td></tr>
571
												<tr>
572
													<td align='left'>
573
														<b>Mount point</b>
574
													</td>
575
													<td align='left'>
576
														<b>Filesysytem type</b>
577
													</td>
578
													<td align='left'>
579
														<b>Disk</b>
580
													</td>
581
													<td align='left'>
582
														<b>Size</b>
583
													</td>
584
													<td align='left'>
585
														<b>Encryption password</b>
586
													</td>
587
												</tr>
588
												<tr><td colspan='5'><hr></td></tr>
589

    
590
EOFAMBACBAF;
591

    
592
													foreach($disks as $disk) {
593
														$desc = pcsysinstall_get_disk_info($disk['disk']);
594
														echo "<tr>";
595
														echo "<td>&nbsp;&nbsp;&nbsp;" . htmlspecialchars($disk['mountpoint']) . "</td>";
596
														echo "<td>" . htmlspecialchars($disk['fstype']) . "</td>";
597
														echo "<td>" . htmlspecialchars($disk['disk']) . " " . htmlspecialchars($desc['desc']) . "</td>";
598
														echo "<td>" . htmlspecialchars($disk['size']) . "</td>";
599
														echo "<td>" . htmlspecialchars($disk['encpass']) . "</td>";
600
														echo "</tr>";
601
													}
602

    
603
echo <<<EOFAMB
604
												<tr><td colspan="5"><hr></td></tr>
605
												</table>
606
											</div>
607
										</center>
608
									</div>
609
	     						</td>
610
							</tr>
611
						</table>
612
					</div>
613
					<center>
614
						<p/>
615
						<input type="button" value="Cancel" onClick="javascript:document.location='installer.php?state=custominstall';"> &nbsp;&nbsp;
616
EOFAMB;
617
						if(!$error_txt) 
618
						echo "<input type=\"submit\" value=\"Begin installation\"> <br />&nbsp;";
619
echo <<<EOFAMBASDF
620

    
621
					</center>
622
				</td>
623
			</tr>
624
		</table>
625
	</div>
626
EOFAMBASDF;
627

    
628

    
629
	page_table_end();
630
	end_html();
631
	write_out_pc_sysinstaller_config($disks, $bootmanager);
632
	// Serialize layout to disk so it can be read in later.
633
	file_put_contents("/tmp/webInstaller_disk_layout.txt", serialize($disks));
634
	file_put_contents("/tmp/webInstaller_disk_bootmanager.txt", serialize($bootmanager));
635
}
636

    
637
function installing_gui() {
638
	global $g, $fstype, $savemsg;
639
	head_html();
640
	body_html();
641
	echo "<form action=\"installer.php\" method=\"post\" state=\"step1_post\">";
642
	page_table_start();
643
	echo <<<EOF
644
	<center>
645
		<table width="100%">
646
		<tr><td>
647
			<div id="mainlevel">
648
				<table width="100%" border="0" cellpadding="0" cellspacing="0">
649
			 		<tr>
650
			    		<td>
651
							<div id="mainarea">
652
								<table width="100%" border="0" cellpadding="0" cellspacing="0">
653
									<tr>
654
			     						<td>
655
											<div id="pfsenseinstaller" width="100%">
656
												<div id='installerrunning' width='100%' style="padding:8px; border:1px dashed #000000">
657
													<table>
658
														<tr>
659
															<td valign="middle">
660
																<img src="/themes/{$g['theme']}/images/misc/loader.gif">
661
															</td>
662
															<td valign="middle">
663
																&nbsp;<font size="2"><b>Starting Installer...  Please wait...
664
															</td>
665
														</tr>
666
													</table>
667
												</div>
668
												<div id='pbdiv'>
669
													<br />
670
													<center>
671
													<table id='pbtable' height='15' width='640' border='0' colspacing='0' cellpadding='0' cellspacing='0'>
672
														<tr>
673
															<td background="/themes/{$g['theme']}/images/misc/bar_left.gif" height='15' width='5'>
674
															</td>
675
															<td>
676
																<table id="progholder" name="progholder" height='15' width='630' border='0' colspacing='0' cellpadding='0' cellspacing='0'>
677
																	<td background="/themes/{$g['theme']}/images/misc/bar_gray.gif" valign="top" align="left">
678
																		<img src='/themes/{$g['theme']}/images/misc/bar_blue.gif' width='0' height='15' name='progressbar' id='progressbar'>
679
																	</td>
680
																</table>
681
															</td>
682
															<td background="/themes/{$g['theme']}/images/misc/bar_right.gif" height='15' width='5'>
683
															</td>
684
														</tr>
685
													</table>
686
													<br />
687
												</div>
688
												<textarea name='installeroutput' id='installeroutput' rows="31" cols="90">
689
												</textarea>
690
											</div>
691
			     						</td>
692
									</tr>
693
								</table>
694
							</div>
695
						</td>
696
					</tr>
697
				</table>
698
			</div>
699
		</td></tr>
700
		</table>
701
	</center>
702
	<script type="text/javascript">setTimeout('getinstallerprogress()', 250);</script>
703

    
704
EOF;
705
	page_table_end();
706
	end_html();
707
}
708

    
709
function page_table_start($pgtitle = "") {
710
	global $g, $fstype, $savemsg;
711
	if($pgtitle == "") 
712
		$pgtitle = "{$g['product_name']} installer";
713
	echo <<<EOF
714
	<center>
715
		<img border="0" src="/themes/{$g['theme']}/images/logo.gif"></a><br />
716
		<table cellpadding="6" cellspacing="0" width="550" style="border:1px solid #000000">
717
		<tr height="10" bgcolor="#990000">
718
			<td style="border-bottom:1px solid #000000">
719
				<font color='white'>
720
					<b>
721
						{$pgtitle}
722
					</b>
723
				</font>
724
			</td>
725
		</tr>
726
		<tr>
727
			<td>
728

    
729
EOF;
730

    
731
}
732

    
733
function page_table_end() {
734
	global $g, $fstype, $savemsg;
735
	echo <<<EOF
736
			</td>
737
		</tr>
738
		</table>
739
	</center>
740

    
741
EOF;
742
	
743
}
744

    
745
function installer_custom() {
746
	global $g, $fstype, $savemsg;
747
	global $select_txt, $custom_disks;
748
	if(file_exists("/tmp/.pc-sysinstall/pc-sysinstall.log")) 
749
		unlink("/tmp/.pc-sysinstall/pc-sysinstall.log");
750
	$disks = installer_find_all_disks();
751
	// Pass size of disks down to javascript.
752
	$disk_sizes_js_txt = "var disk_sizes = new Array();\n";
753
	foreach($disks as $disk) 
754
		$disk_sizes_js_txt .= "disk_sizes['{$disk['disk']}'] = '{$disk['size']}';\n";
755
	head_html();
756
	body_html();
757
	page_table_start($g['product_name'] . " installer - Customize disk(s) layout");
758
	echo <<<EOF
759
		<script type="text/javascript">
760
			Array.prototype.in_array = function(p_val) {
761
				for(var i = 0, l = this.length; i < l; i++) {
762
					if(this[i] == p_val) {
763
						return true;
764
					}
765
				}
766
				return false;
767
			}
768
			function row_helper_dynamic_custom() {
769
				var totalsize = 0;
770
				{$disk_sizes_js_txt}
771
				// Run through all rows and process data
772
				for(var x = 0; x<99; x++) { //optimize me better
773
					if(\$('#fstype' + x).length) {
774
						if(\$('#size' + x).val() == '')
775
							\$('#size' + x).val(disk_sizes[\$('disk' + x).value]);
776
						var fstype = \$('#fstype' + x).val();
777
						if(fstype.substring(fstype.length - 4) == ".eli") {
778
							\$('#encpass' + x).prop('disabled',false);
779
							if(!encryption_warning_shown) {
780
								alert('NOTE: If you define a disk encryption password you will need to enter it on *EVERY* bootup!');
781
								encryption_warning_shown = true;
782
							}
783
						} else { 
784
							\$('#encpass' + x).prop('disabled',true);
785
						}
786
					}
787
					// Calculate size allocations
788
					if(\$('#size' + x).length) {
789
						if(parseInt($('#size' + x).val()) > 0)
790
							totalsize += parseInt($('#size' + x).val());
791
					}
792
				}
793
				// If the totalsize element exists, set it and disable
794
				if(\$('#totalsize').length) {
795
					if(\$('#totalsize').val() != totalsize) {
796
						// When size allocation changes, draw attention.
797
 						jQuery('#totalsize').effect('highlight');
798
						\$('#totalsize').val(totalsize);
799
					}
800
					\$('#totalsize').prop('disabled',true);
801
				}
802
				if(\$('#disktotals').length) {
803
					var disks_seen = new Array();
804
					var tmp_sizedisks = 0;
805
					var disksseen = 0;
806
					for(var xx = 0; xx<99; xx++) {
807
						if(\$('#disk' + xx).length) {
808
							if(!disks_seen.in_array(\$('#disk' + xx).val())) {
809
								tmp_sizedisks += parseInt(disk_sizes[\$('#disk' + xx).val()]);
810
								disks_seen[disksseen] = \$('#disk' + xx).val();
811
								disksseen++;
812
							}
813
						}
814
					\$('#disktotals').val(tmp_sizedisks);
815
					\$('#disktotals').prop('disabled',true);
816
					\$('#disktotals').css('color','#000000');
817
					var remaining = parseInt(\$('#disktotals').val()) - parseInt(\$('#totalsize').val());
818
						if(remaining == 0) {
819
							if(\$('#totalsize').length)
820
								\$('#totalsize').css({
821
									'background':'#00FF00',
822
									'color':'#000000'
823
								});
824
						} else {
825
							if(\$('#totalsize').length)
826
								\$('#totalsize').css({
827
									'background':'#FFFFFF',
828
									'color':'#000000'
829
								});
830
						}
831
						if(parseInt(\$('#totalsize').val()) > parseInt(\$('#disktotals').val())) {
832
							if(\$('#totalsize'))
833
								\$('#totalsize').css({
834
									'background':'#FF0000',
835
									'color':'#000000'
836
								});							
837
						}
838
						if(\$('#availalloc').length) {
839
							\$('#availalloc').prop('disabled',true);
840
							\$('#availalloc').val(remaining);
841
								\$('#availalloc').css({
842
									'background':'#FFFFFF',
843
									'color':'#000000'
844
								});							
845
						}
846
					}
847
				}
848
			}
849
		</script>
850
		<script type="text/javascript" src="/javascript/row_helper_dynamic.js"></script>
851
		<script type="text/javascript">
852
			// Setup rowhelper data types
853
			rowname[0] = "mountpoint";
854
			rowtype[0] = "textbox";
855
			rowsize[0] = "8";
856
			rowname[1] = "fstype";
857
			rowtype[1] = "select";
858
			rowsize[1] = "1";
859
			rowname[2] = "disk";
860
			rowtype[2] = "select";
861
			rowsize[2] = "1";
862
			rowname[3] = "size";
863
			rowtype[3] = "textbox";
864
			rowsize[3] = "8";
865
			rowname[4] = "encpass";
866
			rowtype[4] = "textbox";
867
			rowsize[4] = "8";
868
			field_counter_js = 5;
869
			rows = 1;
870
			totalrows = 1;
871
			loaded = 1;
872
			rowhelper_onChange = 	" onChange='javascript:row_helper_dynamic_custom()' ";
873
			rowhelper_onDelete = 	"row_helper_dynamic_custom(); ";
874
			rowhelper_onAdd = 		"row_helper_dynamic_custom();";
875
		</script>
876
		<form action="installer.php" method="post">
877
			<input type="hidden" name="state" value="verify_before_install">
878
			<div id="mainlevel">
879
				<center>
880
				<table width="100%" border="0" cellpadding="5" cellspacing="0">
881
			 		<tr>
882
			    		<td>
883
							<center>
884
							<div id="mainarea">
885
								<center>
886
								<table width="100%" border="0" cellpadding="5" cellspacing="5">
887
									<tr>
888
			     						<td>
889
											<div id="pfsenseinstaller">
890
												<center>
891
												<div id='loadingdiv'>
892
													<table>
893
														<tr>
894
															<td valign="center">
895
																<img src="/themes/{$g['theme']}/images/misc/loader.gif">
896
															</td>
897
															<td valign="center">
898
														 		&nbsp;Probing disks, please wait...
899
															</td>
900
														</tr>
901
													</table>
902
												</div>
903
EOF;
904
	ob_flush();
905
	// Read bootmanager setting from disk if found
906
	if(file_exists("/tmp/webInstaller_disk_bootmanager.txt"))
907
		$bootmanager = unserialize(file_get_contents("/tmp/webInstaller_disk_bootmanager.txt"));
908
	if($bootmanager == "none") 
909
		$noneselected = " SELECTED";
910
	if($bootmanager == "bsd") 
911
		$bsdeselected = " SELECTED";
912
	if(!$disks)  {
913
		$custom_txt = gettext("ERROR: Could not find any suitable disks for installation.");
914
	} else {
915
		// Prepare disk selection dropdown
916
		$custom_txt = <<<EOF
917
												<center>
918
												<table>
919
												<tr>
920
													<td align='right'>
921
														Boot manager:
922
													</td>
923
													<td>
924
														<select name='bootmanager'>
925
															<option value='none' $noneselected>
926
																None
927
															</option>
928
															<option value='bsd' $bsdeselected>
929
																BSD
930
															</option>
931
														</select>
932
													</td>
933
												</tr>
934
												</table>
935
												<hr>
936
												<table id='maintable'><tbody>
937
												<tr>
938
													<td align="middle">
939
														<b>Mount</b>
940
													</td>
941
													<td align='middle'>
942
														<b>Filesysytem</b>
943
													</td>
944
													<td align="middle">
945
														<b>Disk</b>
946
													</td>
947
													<td align="middle">
948
														<b>Size</b>
949
													</td>
950
													<td align="middle">
951
														<b>Encryption password</b>
952
													</td>
953
													<td>
954
														&nbsp;
955
													</td>
956
												</tr>
957
												<tr>
958

    
959
EOF;
960

    
961
		// Calculate swap disk sizes
962
		$memory = get_memory();
963
		$swap_size = $memory[0] * 2;
964
		$first_disk = trim(installer_find_first_disk());
965
		$disk_info = pcsysinstall_get_disk_info($first_disk);
966
		$size = $disk_info['size'];
967
		$first_disk_size = $size - $swap_size;
968

    
969
		// Debugging
970
		// echo "\n\n<!-- $first_disk - " . print_r($disk_info, true) . " - $size  - $first_disk_size -->\n\n";
971

    
972
		// Check to see if a on disk layout exists
973
		if(file_exists("/tmp/webInstaller_disk_layout.txt")) {
974
			$disks_restored = unserialize(file_get_contents("/tmp/webInstaller_disk_layout.txt"));
975
			$restored_layout_from_file = true;
976
			$restored_layout_txt = "<br />* The previous disk layout was restored from a previous session";
977
		}
978

    
979
		// If we restored disk layout(s) from a file then build the rows
980
		if($restored_layout_from_file == true) {
981
			$diskcounter = 0;
982
			foreach($disks_restored as $dr) {
983
				$custom_txt .= return_rowhelper_row("$diskcounter", $dr['mountpoint'], $dr['fstype'], $dr['disk'], $dr['size'], $dr['encpass']);
984
				$diskcounter++;
985
			}
986
		} else {		
987
			// Construct the default rows that outline the disks configuration.
988
			$custom_txt .= return_rowhelper_row("0", "/", "UFS+S", $first_disk, "{$first_disk_size}", "");
989
			$custom_txt .= return_rowhelper_row("1", "none", "SWAP", $first_disk, "$swap_size", "");
990
		}
991

    
992
		// tfoot and tbody are used by rowhelper
993
		$custom_txt .= "</tr>";
994
		$custom_txt .= "<tfoot></tfoot></tbody>";
995
		// Total allocation box
996
		$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>";
997
		// Add row button
998
		$custom_txt .= "</td><td>&nbsp;</td><td>";
999
		$custom_txt .= "<div id=\"addrowbutton\">";
1000
		$custom_txt .= "<a onclick=\"javascript:addRowTo('maintable', 'formfldalias'); return false;\" href=\"#\">";
1001
		$custom_txt .= "<img border=\"0\" src=\"/themes/{$g['theme']}/images/icons/icon_plus.gif\" alt=\"\" title=\"add another entry\" /></a>";
1002
		$custom_txt .= "</div>";
1003
		$custom_txt .= "</td></tr>";	
1004
		// Disk capacity box
1005
		$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>";
1006
		// Remaining allocation box
1007
		$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>";
1008
		$custom_txt .= "</table>";
1009
		$custom_txt .= "<script type=\"text/javascript\">row_helper_dynamic_custom();</script>";
1010
	}
1011
	echo <<<EOF
1012

    
1013
												<tr>
1014
													<td colspan='4'>
1015
													<script type="text/javascript">
1016
														\$('#loadingdiv').css('visibility','hidden');
1017
													</script>
1018
													<div id='contentdiv' style="display:none;">
1019
														<p/>
1020
														{$custom_txt}<p/>
1021
														<hr><p/>
1022
														<input type="button" value="Cancel" onClick="javascript:document.location='/installer/installer.php';"> &nbsp;&nbsp
1023
														<input type="submit" value="Next">
1024
													</div>
1025
													<script type="text/javascript">
1026
														var encryption_warning_shown = false;
1027
														\$('#contentdiv').fadeIn();
1028
														row_helper_dynamic_custom();
1029
													</script>
1030
												</center>
1031
												</td></tr>
1032
												</table>
1033
											</div>
1034
			     						</td>
1035
									</tr>
1036
								</table>
1037
								</center>
1038
								<span class="vexpl">
1039
									<span class="red">
1040
										<strong>
1041
											NOTES:
1042
										</strong>
1043
									</span>
1044
									<br />* Sizes are in megabytes.
1045
									<br />* Mount points named /conf are not allowed.  Use /cf if you want to make a configuration slice/mount.
1046
									{$restored_layout_txt}
1047
								</span>
1048
								</strong>
1049
							</div>
1050
						</td>
1051
					</tr>
1052
				</table>
1053
			</div>
1054
			</center>
1055
			<script type="text/javascript">
1056
			<!--
1057
				newrow[1] = "{$select_txt}";
1058
				newrow[2] = "{$custom_disks}";
1059
			-->
1060
			</script>
1061
			
1062

    
1063
EOF;
1064
	page_table_end();
1065
	end_html();
1066
}
1067

    
1068
function installer_main() {
1069
	global $g, $fstype, $savemsg;
1070
	if(file_exists("/tmp/.pc-sysinstall/pc-sysinstall.log")) 
1071
		unlink("/tmp/.pc-sysinstall/pc-sysinstall.log");
1072
	head_html();
1073
	body_html();
1074
	$disk = installer_find_first_disk();
1075
	// Only enable ZFS if this exists.  The install will fail otherwise.
1076
	if(file_exists("/boot/gptzfsboot")) 
1077
		$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>";
1078
	page_table_start();
1079
	echo <<<EOF
1080
		<form action="installer.php" method="post" state="step1_post">
1081
			<div id="mainlevel">
1082
				<center>
1083
				<b><font face="arial" size="+2">Welcome to the {$g['product_name']} webInstaller!</b></font><p/>
1084
				<font face="arial" size="+1">This utility will install {$g['product_name']} to a hard disk, flash drive, etc.</font>
1085
				<table width="100%" border="0" cellpadding="5" cellspacing="0">
1086
			 		<tr>
1087
			    		<td>
1088
							<center>
1089
							<div id="mainarea">
1090
								<br />
1091
								<center>
1092
								Please select an installer option to begin:
1093
								<p/>
1094
								<table width="100%" border="0" cellpadding="5" cellspacing="5">
1095
									<tr>
1096
			     						<td>
1097
											<div id="pfsenseinstaller">
1098
												<center>
1099
EOF;
1100
	if(!$disk) {
1101
		echo gettext("ERROR: Could not find any suitable disks for installation.");
1102
		echo "</div></td></tr></table></div></table></div>";
1103
		end_html();
1104
		exit;
1105
	}
1106
	echo <<<EOF
1107

    
1108
													<table cellspacing="5" cellpadding="5" style="border: 1px dashed;">
1109
														<tr bgcolor="#CECECE"><td align="center">
1110
															<a href="installer.php?state=easy_install_ufs">Easy installation of {$g['product_name']} using the UFS filesystem on disk {$disk}</a>
1111
														</td></tr>
1112
													 	{$zfs_enabled}
1113
														<tr bgcolor="#AAAAAA"><td align="center">
1114
															<a href="installer.php?state=custominstall">Custom installation of {$g['product_name']}</a>
1115
														</td></tr>
1116
														<tr bgcolor="#CECECE"><td align="center">
1117
															<a href='/'>Cancel and return to Dashboard</a>
1118
														</td></tr>
1119
													</table>
1120
												</center>
1121
											</div>
1122
			     						</td>
1123
									</tr>
1124
								</table>
1125
							</div>
1126
						</td>
1127
					</tr>
1128
				</table>
1129
			</div>
1130
EOF;
1131
	page_table_end();
1132
	end_html();
1133
}
1134

    
1135
function return_rowhelper_row($rownum, $mountpoint, $fstype, $disk, $size, $encpass) {
1136
		global $g, $select_txt, $custom_disks, $savemsg;
1137
		$release = php_uname("r");
1138
		// Get release number like 8.3 or 10.1
1139
		$relnum = strtok($release, "-");
1140

    
1141
		// Mount point
1142
		$disks = installer_find_all_disks();
1143
		$custom_txt .= "<tr>";
1144
		$custom_txt .=  "<td><input size='8' id='mountpoint{$rownum}' name='mountpoint{$rownum}' value='{$mountpoint}'></td>";
1145

    
1146
		// Filesystem type array
1147
		$types = array(
1148
			'UFS' => 'UFS',
1149
			'UFS+S' => 'UFS + Softupdates',
1150
			'UFS.eli' => 'Encrypted UFS',
1151
			'UFS+S.eli' => 'Encrypted UFS + Softupdates',
1152
			'SWAP' => 'SWAP'
1153
		);
1154

    
1155
		// UFS + Journaling was introduced in 9.0
1156
		if($relnum >= 9) {
1157
			$types['UFS+J'] = "UFS + Journaling";
1158
			$types['UFS+J.eli'] = "Encrypted UFS + Journaling";
1159
		}
1160
		
1161
		// Add ZFS Boot loader if it exists
1162
		if(file_exists("/boot/gptzfsboot")) {
1163
			$types['ZFS'] = "Zetabyte Filesystem";
1164
			$types['ZFS.eli'] = "Encrypted Zetabyte Filesystem";
1165
		}
1166

    
1167
		// fstype form field
1168
		$custom_txt .=  "<td><select onChange='javascript:row_helper_dynamic_custom()' id='fstype{$rownum}' name='fstype{$rownum}'>";
1169
		$select_txt = "";
1170
		foreach($types as $type => $desc) {
1171
			if($type == $fstype)
1172
				$SELECTED="SELECTED";
1173
			else 
1174
				$SELECTED="";
1175
			$select_txt .= "<option value='$type' $SELECTED>$desc</option>";
1176
		}
1177
		$custom_txt .= "{$select_txt}</select>\n";
1178
		$custom_txt .= "</td>";
1179
		
1180
		// Disk selection form field
1181
		$custom_txt .= "<td><select id='disk{$rownum}' name='disk{$rownum}'>\n";
1182
		$custom_disks = "";
1183
		foreach($disks as $dsk) {
1184
			$disksize_bytes = format_bytes($dsk['size'] * 1048576);
1185
			$disksize = $dsk['size'];
1186
			if($disk == $dsk['disk'])
1187
				$SELECTED="SELECTED";
1188
			else 
1189
				$SELECTED="";
1190
			$custom_disks .= "<option value='{$dsk['disk']}' $SELECTED>{$dsk['disk']} - {$dsk['desc']} - {$disksize}MB ({$disksize_bytes})</option>";
1191
		}
1192
		$custom_txt .= "{$custom_disks}</select></td>\n";
1193

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

    
1197
		// Encryption password
1198
		$custom_txt .= "<td>";
1199
		$custom_txt .= "<input id='encpass{$rownum}' name='encpass{$rownum}' size='8' value='{$encpass}'>";
1200
		$custom_txt .= "</td>";
1201
	
1202
		// Add Rowhelper + button
1203
		if($rownum > 0) 
1204
			$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>";
1205

    
1206
		$custom_txt .= "</tr>";	
1207
		return $custom_txt;
1208
}
1209

    
1210
?>
(2-2/2)