Project

General

Profile

Download (38 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/****h* pfSense/config
3
 * NAME
4
 *   config.inc - Functions to manipulate config.xml
5
 * DESCRIPTION
6
 *   This include contains various config.xml specific functions.
7
 * HISTORY
8
 * $Id$
9
 ******
10

    
11
	config.inc
12
	Copyright (C) 2004 Scott Ullrich
13
	All rights reserved.
14

    
15
	originally part of m0n0wall (http://m0n0.ch/wall)
16
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
17
	All rights reserved.
18

    
19
	Redistribution and use in source and binary forms, with or without
20
	modification, are permitted provided that the following conditions are met:
21

    
22
	1. Redistributions of source code must retain the above copyright notice,
23
	   this list of conditions and the following disclaimer.
24

    
25
	2. Redistributions in binary form must reproduce the above copyright
26
	   notice, this list of conditions and the following disclaimer in the
27
	   documentation and/or other materials provided with the distribution.
28

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

    
41
/* do not load this file twice. */
42
if($config_inc_loaded == true)
43
	return;
44
else
45
	$config_inc_loaded = true;
46

    
47
/* include globals/utility/XML parser files */
48
require_once("globals.inc");
49
require_once("util.inc");
50
require_once("pfsense-utils.inc");
51
require_once("xmlparse.inc");
52

    
53
/* read platform */
54
if (file_exists("{$g['etc_path']}/platform")) {
55
	$g['platform'] = chop(file_get_contents("{$g['etc_path']}/platform"));
56
} else {
57
	$g['platform'] = "unknown";
58
}
59

    
60
/* if /debugging exists, lets set $debugging
61
   so we can output more information */
62
if(file_exists("/debugging")) {
63
	$debugging = true;
64
	$g['debug'] = true;
65
}
66

    
67
$config_contents = file_get_contents("/cf/conf/config.xml");
68
if(stristr($config_contents, "m0n0wall") == true) {
69
	/* user has just upgraded to m0n0wall, replace root xml tags */
70
	echo "Upgrading m0n0wall configuration to pfSense... ";
71
	$config_contents = str_replace("m0n0wall","pfsense");
72
	$fd = fopen("/cf/conf/config.xml", "w");
73
	fwrite($fd, $config_contents);
74
	fclose($fd);
75
	echo "done.";
76
}
77

    
78
/* if our config file exists bail out, we're already set. */
79
if ($g['booting'] and !file_exists($g['cf_conf_path'] . "/config.xml")  ) {
80
	/* find the device where config.xml resides and write out an fstab */
81
	unset($cfgdevice);
82

    
83
	/* check if there's already an fstab (NFS booting?) */
84
	if (!file_exists("{$g['etc_path']}/fstab")) {
85

    
86
		if (strstr($g['platform'], "cdrom")) {
87
			/* config is on floppy disk for CD-ROM version */
88
			$cfgdevice = $cfgpartition = "fd0";
89
			$dmesg = `dmesg -a`;
90
			if(ereg("da0", $dmesg) == true) {
91
				$cfgdevice = $cfgpartition = "da0" ;
92
				if (mwexec("/sbin/mount -r /dev/{$cfgdevice} /cf")) {
93
					/* could not mount, fallback to floppy */
94
					$cfgdevice = $cfgpartition = "fd0";
95
				}
96
			}
97
			$cfgfstype = "msdos";
98
			echo "CDROM build\n";
99
			echo "   CFG: {$cfgpartition}\n";
100
			echo "  TYPE: {$cfgfstype}\n";
101
		} else {
102
			/* probe kernel known disks until we find one with config.xml */
103
			$disks = explode(" ", trim(preg_replace("/kern.disks: /", "", exec("/sbin/sysctl kern.disks"))));
104
			foreach ($disks as $mountdisk) {
105
				/* skip mfs mounted filesystems */
106
				if (strstr($mountdisk, "md"))
107
					continue;
108
				if (mwexec("/sbin/mount -r /dev/{$mountdisk}a {$g['cf_path']}") == 0) {
109
					if (file_exists("{$g['cf_conf_path']}/config.xml")) {
110
						/* found it */
111
						$cfgdevice = $mountdisk;
112
						$cfgpartition = $cfgdevice . "a";
113
						$cfgfstype = "ufs";
114
						echo "Found configuration on $cfgdevice.\n";
115
					}
116

    
117
					mwexec("/sbin/umount -f {$g['cf_path']}");
118

    
119
					if ($cfgdevice)
120
						break;
121
				}
122
				if (mwexec("/sbin/mount -r /dev/{$mountdisk}d {$g['cf_path']}") == 0) {
123
					if (file_exists("{$g['cf_conf_path']}/config.xml")) {
124
						/* found it */
125
						$cfgdevice = $mountdisk;
126
						$cfgpartition = $cfgdevice . "d";
127
						$cfgfstype = "ufs";
128
						echo "Found configuration on $cfgdevice.\n";
129
					}
130

    
131
					mwexec("/sbin/umount -f {$g['cf_path']}");
132

    
133
					if ($cfgdevice)
134
						break;
135
				}
136
			}
137
		}
138

    
139
		if (!$cfgdevice) {
140
			/* no device found, print an error and die */
141
			echo <<<EOD
142

    
143

    
144
*******************************************************************************
145
* FATAL ERROR                                                                 *
146
* The device that contains the configuration file (config.xml) could not be   *
147
* found. pfSense cannot continue booting.                                     *
148
*******************************************************************************
149

    
150

    
151
EOD;
152

    
153
			mwexec("/sbin/halt");
154
			exit;
155
		}
156

    
157
		/* write device name to a file for rc.firmware */
158
		$fd = fopen("{$g['varetc_path']}/cfdevice", "w");
159
		fwrite($fd, $cfgdevice . "\n");
160
		fclose($fd);
161

    
162
		/* write out an fstab */
163
		$fd = fopen("{$g['etc_path']}/fstab", "w");
164

    
165
		$fstab = "/dev/{$cfgpartition} {$g['cf_path']} {$cfgfstype} ro 1 1\n";
166
		$fstab .= "proc /proc procfs rw 0 0\n";
167

    
168
		fwrite($fd, $fstab);
169
		fclose($fd);
170
	}
171

    
172
	/* mount all filesystems */
173
	mwexec("/sbin/mount -a");
174
}
175

    
176
$config = parse_config();
177

    
178
/****f* config/parse_config
179
 * NAME
180
 *   parse_config - Read in config.cache or config.xml if needed and return $config array
181
 * INPUTS
182
 *   $parse       - boolean to force parse_config() to read config.xml and generate config.cache
183
 * RESULT
184
 *   $config      - array containing all configuration variables
185
 ******/
186
function parse_config($parse = false) {
187
	global $g;
188

    
189
	config_lock();
190
	if(!$parse) {
191
		if(file_exists($g['tmp_path'] . '/config.cache')) {
192
			$config = unserialize(file_get_contents($g['tmp_path'] . '/config.cache'));
193
			if(is_null($config)) {
194
				config_unlock();
195
				parse_config(true);
196
			}
197
		} else {
198
			config_unlock();
199
			$config = parse_config(true);
200
		}
201
	} else {
202
		$config = parse_xml_config($g['conf_path'] . '/config.xml', $g['xml_rootobj']);
203
		generate_config_cache($config);
204
	}
205
	
206
	alias_make_table($config);
207
	config_unlock();
208
	return $config;
209
}
210

    
211
/****f* config/generate_config_cache
212
 * NAME
213
 *   generate_config_cache - Write serialized configuration to cache.
214
 * INPUTS
215
 *   $config	- array containing current firewall configuration
216
 * RESULT
217
 *   boolean	- true on completion
218
 ******/
219
function generate_config_cache($config) {
220
	global $g;
221
	conf_mount_rw();
222
	$configcache = fopen($g['tmp_path'] . '/config.cache', "w");
223
	fwrite($configcache, serialize($config));
224
	fclose($configcache);
225
	conf_mount_ro();
226
	return true;
227
}
228

    
229
/****f* config/parse_config_bootup
230
 * NAME
231
 *   parse_config_bootup - Bootup-specific configuration checks.
232
 * RESULT
233
 *   null
234
 ******/
235
function parse_config_bootup() {
236
	global $config, $g;
237
	if (!$noparseconfig) {
238
		if (!file_exists("{$g['conf_path']}/config.xml")) {
239
			config_lock();
240
			if ($g['booting']) {
241
				if (strstr($g['platform'], "cdrom")) {
242
					/* try copying the default config. to the floppy */
243
					echo "Resetting factory defaults...\n";
244
					reset_factory_defaults();
245
	
246
					echo "No XML configuration file found - using factory defaults.\n";
247
					echo "Make sure that the configuration floppy disk with the conf/config.xml\n";
248
					echo "file is inserted. If it isn't, your configuration changes will be lost\n";
249
					echo "on reboot.\n";
250
				} else {
251
					echo "XML configuration file not found.  pfSense cannot continue booting.\n";
252
					mwexec("/sbin/halt");
253
					exit;
254
				}
255
			} else {
256
				config_unlock();
257
				exit(0);
258
			}
259
		}
260
	}
261

    
262
	parse_config(true);
263
	
264
	if ((float)$config['version'] > (float)$g['latest_config']) {
265
		echo <<<EOD
266

    
267

    
268
*******************************************************************************
269
* WARNING!                                                                    *
270
* The current configuration has been created with a newer version of pfSense  *
271
* than this one! This can lead to serious misbehavior and even security       *
272
* holes! You are urged to either upgrade to a newer version of pfSense or     *
273
* revert to the default configuration immediately!                            *
274
*******************************************************************************
275

    
276

    
277
EOD;
278
		}
279

    
280
	/* make alias table (for faster lookups) */
281
	alias_make_table($config);
282
	config_unlock();
283
}
284

    
285
/****f* config/conf_mount_rw
286
 * NAME
287
 *   conf_mount_rw - Mount filesystems read/write.
288
 * RESULT
289
 *   null
290
 ******/
291
/* mount flash card read/write */
292
function conf_mount_rw() {
293
	global $g;
294

    
295
	/* do not mount on cdrom platform */
296
	if($g['platform'] == "cdrom" or $g['platform'] == "pfSense")
297
		return;
298

    
299
	$status = mwexec("/sbin/umount -f {$g['cf_path']}");
300
	$status = mwexec("/sbin/mount -w {$g['cf_path']}");
301
	if($status <> 0) {
302
		mwexec("/sbin/fsck -y {$g['cf_path']}");
303
		$status = mwexec("/sbin/mount -w {$g['cf_path']}");
304
	}
305

    
306
	/*    if the platform is soekris or wrap or pfSense, lets mount the
307
	 *    compact flash cards root.
308
         */
309
	if($g['platform'] == "wrap" or $g['platform'] == "net45xx"
310
	   or $g['platform'] == "embedded") {
311
		$status = mwexec("/sbin/mount -w /");
312
		/* we could not mount this correctly.  kick off fsck */
313
		if($status <> 0) {
314
			log_error("File system is dirty.  Launching FSCK for /");
315
			mwexec("/sbin/fsck -y");
316
			$status = mwexec("/sbin/mount -w /");
317
		}
318
	}
319
}
320

    
321
/****f* config/conf_mount_ro
322
 * NAME         
323
 *   conf_mount_ro - Mount filesystems readonly.
324
 * RESULT
325
 *   null        
326
 ******/
327
function conf_mount_ro() {
328
	global $g;
329

    
330
	if($g['booting'] == true)
331
		return;
332
	
333
	/* do not umount if generating ssh keys */
334
	if(file_exists("/tmp/keys_generating"))
335
		return;
336
	
337
	/* do not umount on cdrom or pfSense platforms */
338
	if($g['platform'] == "cdrom" or $g['platform'] == "pfSense")
339
		return;
340

    
341
	/* sync data, then force a umount the remount of /cf */
342
	mwexec("/bin/sync");
343
	mwexec("/bin/sync");
344
	mwexec("/sbin/umount -f {$g['cf_path']}");
345
	mwexec("/sbin/mount -r {$g['cf_path']}");
346
	mwexec("/bin/sync");
347
	mwexec("/bin/sync");
348
	mwexec("/sbin/mount -r /");
349
}
350

    
351
/****f* config/convert_config
352
 * NAME         
353
 *   convert_config - Attempt to update config.xml.
354
 * DESCRIPTION
355
 *   convert_config() reads the current global configuration
356
 *   and attempts to convert it to conform to the latest
357
 *   config.xml version. This allows major formatting changes
358
 *   to be made with a minimum of breakage.
359
 * RESULT
360
 *   null        
361
 ******/
362
/* convert configuration, if necessary */
363
function convert_config() {
364
	global $config, $g;
365

    
366
	if ($config['version'] == $g['latest_config'])
367
		return;		/* already at latest version */
368

    
369
	// Save off config version
370
	$prev_version = $config['version'];
371

    
372
	/* convert 1.0 -> 1.1 */
373
	if ($config['version'] == "1.0") {
374
		$opti = 1;
375
		$ifmap = array('lan' => 'lan', 'wan' => 'wan', 'pptp' => 'pptp');
376

    
377
		/* convert DMZ to optional, if necessary */
378
		if (isset($config['interfaces']['dmz'])) {
379

    
380
			$dmzcfg = &$config['interfaces']['dmz'];
381

    
382
			if ($dmzcfg['if']) {
383
				$config['interfaces']['opt' . $opti] = array();
384
				$optcfg = &$config['interfaces']['opt' . $opti];
385

    
386
				$optcfg['enable'] = $dmzcfg['enable'];
387
				$optcfg['descr'] = "DMZ";
388
				$optcfg['if'] = $dmzcfg['if'];
389
				$optcfg['ipaddr'] = $dmzcfg['ipaddr'];
390
				$optcfg['subnet'] = $dmzcfg['subnet'];
391

    
392
				$ifmap['dmz'] = "opt" . $opti;
393
				$opti++;
394
			}
395

    
396
			unset($config['interfaces']['dmz']);
397
		}
398

    
399
		/* convert WLAN1/2 to optional, if necessary */
400
		for ($i = 1; isset($config['interfaces']['wlan' . $i]); $i++) {
401

    
402
			if (!$config['interfaces']['wlan' . $i]['if']) {
403
				unset($config['interfaces']['wlan' . $i]);
404
				continue;
405
			}
406

    
407
			$wlancfg = &$config['interfaces']['wlan' . $i];
408
			$config['interfaces']['opt' . $opti] = array();
409
			$optcfg = &$config['interfaces']['opt' . $opti];
410

    
411
			$optcfg['enable'] = $wlancfg['enable'];
412
			$optcfg['descr'] = "WLAN" . $i;
413
			$optcfg['if'] = $wlancfg['if'];
414
			$optcfg['ipaddr'] = $wlancfg['ipaddr'];
415
			$optcfg['subnet'] = $wlancfg['subnet'];
416
			$optcfg['bridge'] = $wlancfg['bridge'];
417

    
418
			$optcfg['wireless'] = array();
419
			$optcfg['wireless']['mode'] = $wlancfg['mode'];
420
			$optcfg['wireless']['ssid'] = $wlancfg['ssid'];
421
			$optcfg['wireless']['channel'] = $wlancfg['channel'];
422
			$optcfg['wireless']['wep'] = $wlancfg['wep'];
423

    
424
			$ifmap['wlan' . $i] = "opt" . $opti;
425

    
426
			unset($config['interfaces']['wlan' . $i]);
427
			$opti++;
428
		}
429

    
430
		/* convert filter rules */
431
		$n = count($config['filter']['rule']);
432
		for ($i = 0; $i < $n; $i++) {
433

    
434
			$fr = &$config['filter']['rule'][$i];
435

    
436
			/* remap interface */
437
			if (array_key_exists($fr['interface'], $ifmap))
438
				$fr['interface'] = $ifmap[$fr['interface']];
439
			else {
440
				/* remove the rule */
441
				echo "\nWarning: filter rule removed " .
442
					"(interface '{$fr['interface']}' does not exist anymore).";
443
				unset($config['filter']['rule'][$i]);
444
				continue;
445
			}
446

    
447
			/* remap source network */
448
			if (isset($fr['source']['network'])) {
449
				if (array_key_exists($fr['source']['network'], $ifmap))
450
					$fr['source']['network'] = $ifmap[$fr['source']['network']];
451
				else {
452
					/* remove the rule */
453
					echo "\nWarning: filter rule removed " .
454
						"(source network '{$fr['source']['network']}' does not exist anymore).";
455
					unset($config['filter']['rule'][$i]);
456
					continue;
457
				}
458
			}
459

    
460
			/* remap destination network */
461
			if (isset($fr['destination']['network'])) {
462
				if (array_key_exists($fr['destination']['network'], $ifmap))
463
					$fr['destination']['network'] = $ifmap[$fr['destination']['network']];
464
				else {
465
					/* remove the rule */
466
					echo "\nWarning: filter rule removed " .
467
						"(destination network '{$fr['destination']['network']}' does not exist anymore).";
468
					unset($config['filter']['rule'][$i]);
469
					continue;
470
				}
471
			}
472
		}
473

    
474
		/* convert shaper rules */
475
		$n = count($config['pfqueueing']['rule']);
476
		if (is_array($config['pfqueueing']['rule']))
477
			for ($i = 0; $i < $n; $i++) {
478

    
479
			$fr = &$config['pfqueueing']['rule'][$i];
480

    
481
			/* remap interface */
482
			if (array_key_exists($fr['interface'], $ifmap))
483
				$fr['interface'] = $ifmap[$fr['interface']];
484
			else {
485
				/* remove the rule */
486
				echo "\nWarning: traffic shaper rule removed " .
487
					"(interface '{$fr['interface']}' does not exist anymore).";
488
				unset($config['pfqueueing']['rule'][$i]);
489
				continue;
490
			}
491

    
492
			/* remap source network */
493
			if (isset($fr['source']['network'])) {
494
				if (array_key_exists($fr['source']['network'], $ifmap))
495
					$fr['source']['network'] = $ifmap[$fr['source']['network']];
496
				else {
497
					/* remove the rule */
498
					echo "\nWarning: traffic shaper rule removed " .
499
						"(source network '{$fr['source']['network']}' does not exist anymore).";
500
					unset($config['pfqueueing']['rule'][$i]);
501
					continue;
502
				}
503
			}
504

    
505
			/* remap destination network */
506
			if (isset($fr['destination']['network'])) {
507
				if (array_key_exists($fr['destination']['network'], $ifmap))
508
					$fr['destination']['network'] = $ifmap[$fr['destination']['network']];
509
				else {
510
					/* remove the rule */
511
					echo "\nWarning: traffic shaper rule removed " .
512
						"(destination network '{$fr['destination']['network']}' does not exist anymore).";
513
					unset($config['pfqueueing']['rule'][$i]);
514
					continue;
515
				}
516
			}
517
		}
518

    
519
		$config['version'] = "1.1";
520
	}
521

    
522
	/* convert 1.1 -> 1.2 */
523
	if ($config['version'] == "1.1") {
524
		/* move LAN DHCP server config */
525
		$tmp = $config['dhcpd'];
526
		$config['dhcpd'] = array();
527
		$config['dhcpd']['lan'] = $tmp;
528

    
529
		/* encrypt password */
530
		$config['system']['password'] = crypt($config['system']['password']);
531

    
532
		$config['version'] = "1.2";
533
	}
534

    
535
	/* convert 1.2 -> 1.3 */
536
	if ($config['version'] == "1.2") {
537
		/* convert advanced outbound NAT config */
538
		for ($i = 0; isset($config['nat']['advancedoutbound']['rule'][$i]); $i++) {
539
			$curent = &$config['nat']['advancedoutbound']['rule'][$i];
540
			$src = $curent['source'];
541
			$curent['source'] = array();
542
			$curent['source']['network'] = $src;
543
			$curent['destination'] = array();
544
			$curent['destination']['any'] = true;
545
		}
546

    
547
		/* add an explicit type="pass" to all filter rules to make things consistent */
548
		for ($i = 0; isset($config['filter']['rule'][$i]); $i++) {
549
			$config['filter']['rule'][$i]['type'] = "pass";
550
		}
551

    
552
		$config['version'] = "1.3";
553
	}
554

    
555
	/* convert 1.3 -> 1.4 */
556
	if ($config['version'] == "1.3") {
557
		/* convert shaper rules (make pipes) */
558
		if (is_array($config['pfqueueing']['rule'])) {
559
			$config['pfqueueing']['pipe'] = array();
560

    
561
			for ($i = 0; isset($config['pfqueueing']['rule'][$i]); $i++) {
562
				$curent = &$config['pfqueueing']['rule'][$i];
563

    
564
				/* make new pipe and associate with this rule */
565
				$newpipe = array();
566
				$newpipe['descr'] = $curent['descr'];
567
				$newpipe['bandwidth'] = $curent['bandwidth'];
568
				$newpipe['delay'] = $curent['delay'];
569
				$newpipe['mask'] = $curent['mask'];
570
				$config['pfqueueing']['pipe'][$i] = $newpipe;
571

    
572
				$curent['targetpipe'] = $i;
573

    
574
				unset($curent['bandwidth']);
575
				unset($curent['delay']);
576
				unset($curent['mask']);
577
			}
578
		}
579

    
580
		$config['version'] = "1.4";
581
	}
582

    
583
	/* Convert 1.4 -> 1.5 */
584
	if ($config['version'] == "1.4") {
585

    
586
		/* Default route moved */
587
		if (isset($config['interfaces']['wan']['gateway']))
588
			if ($config['interfaces']['wan']['gateway'] <> "")
589
				$config['interfaces']['wan']['gateway'] = $config['interfaces']['wan']['gateway'];
590
		unset($config['interfaces']['wan']['gateway']);
591

    
592
                /* Queues are no longer interface specific */
593
                if (isset($config['interfaces']['lan']['schedulertype']))
594
                        unset($config['interfaces']['lan']['schedulertype']);
595
                if (isset($config['interfaces']['wan']['schedulertype']))
596
                        unset($config['interfaces']['wan']['schedulertype']);
597

    
598
                for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
599
                        if(isset($config['interfaces']['opt' . $i]['schedulertype']))
600
                                unset($config['interfaces']['opt' . $i]['schedulertype']);
601
                }
602

    
603
		$config['version'] = "1.5";
604
	}
605

    
606
	/* Convert 1.5 -> 1.6 */
607
	if ($config['version'] == "1.5") {
608
		/* Alternate firmware URL moved */
609
		if (isset($config['system']['firmwareurl']) && isset($config['system']['firmwarename'])) { // Only convert if *both* are defined.
610
			$config['system']['alt_firmware_url'] = array();
611
			$config['system']['alt_firmware_url']['enabled'] = "";
612
			$config['system']['alt_firmware_url']['firmware_base_url'] = $config['system']['firmwareurl'];
613
			$config['system']['alt_firmware_url']['firmware_filename'] = $config['system']['firmwarename'];
614
			unset($config['system']['firmwareurl'], $config['system']['firmwarename']);
615
		} else {
616
			unset($config['system']['firmwareurl'], $config['system']['firmwarename']);
617
		}
618

    
619
		$config['version'] = "1.6";
620
	}
621
	
622
	/* Convert 1.6 -> 1.7 */
623
	if ($config['version'] == "1.6") {
624
		/* wipe previous shaper configuration */
625
		unset($config['shaper']['queue']);
626
		unset($config['shaper']['rule']);
627
		unset($config['interfaces']['wan']['bandwidth']);
628
		unset($config['interfaces']['wan']['bandwidthtype']);
629
		unset($config['interfaces']['lan']['bandwidth']);
630
		unset($config['interfaces']['lan']['bandwidthtype']);		
631
		$config['shaper']['enable'] = FALSE;
632
		$config['version'] = "1.7";	
633
	}
634
	/* Convert 1.7 -> 1.8 */
635
	if ($config['version'] == "1.7") {
636
		if(isset($config['proxyarp']) && is_array($config['proxyarp']['proxyarpnet'])) {
637
			$proxyarp = &$config['proxyarp']['proxyarpnet'];
638
			foreach($proxyarp as $arpent){
639
				$vip = array();
640
				$vip['mode'] = "proxyarp";
641
				$vip['interface'] = $arpent['interface'];
642
				$vip['descr'] = $arpent['descr'];
643
				if (isset($arpent['range'])) {
644
					$vip['range'] = $arpent['range'];
645
					$vip['type'] = "range";
646
				} else {
647
					$subnet = explode('/', $arpent['network']);
648
					$vip['subnet'] = $subnet[0];
649
					if (isset($subnet[1])) {
650
						$vip['subnet_bits'] = $subnet[1];
651
						$vip['type'] = "network";
652
					} else {
653
						$vip['subnet_bits'] = "32";
654
						$vip['type'] = "single";
655
					}
656
				}
657
				$config['virtualip']['vip'][] = $vip;
658
			}
659
			unset($config['proxyarp']);
660
		}
661
		if(isset($config['installedpackages']) && isset($config['installedpackages']['carp']) && is_array($config['installedpackages']['carp']['config'])) {
662
			$carp = &$config['installedpackages']['carp']['config'];
663
			foreach($carp as $carpent){
664
				$vip = array();
665
				$vip['mode'] = "carp";
666
				$vip['interface'] = "AUTO";
667
				$vip['descr'] = "CARP vhid {$carpent['vhid']}";
668
				$vip['type'] = "single";
669
				$vip['vhid'] = $carpent['vhid'];
670
				$vip['advskew'] = $carpent['advskew'];
671
				$vip['password'] = $carpent['password'];
672
				$vip['subnet'] = $carpent['ipaddress'];
673
				$vip['subnet_bits'] = $carpent['netmask'];
674
				$config['virtualip']['vip'][] = $vip;
675
			}
676
			unset($config['installedpackages']['carp']);
677
		}
678
		/* Server NAT is no longer needed */
679
		unset($config['nat']['servernat']);
680
		
681
		/* enable SSH */
682
		if ($config['version'] == "1.8") {
683
			$config['system']['sshenabled'] = true;
684
		}
685
		
686
		$config['version'] = "1.9";
687
	}
688

    
689
	/* Convert 1.8 -> 1.9 */
690
	if ($config['version'] == "1.8") {
691
		$config['theme']="metallic";
692
		$config['version'] = "1.9";
693
	}
694
	/* Convert 1.9 -> 2.0 */
695
	if ($config['version'] == "1.9") {
696
		if(is_array($config['ipsec']['tunnel'])) {
697
			reset($config['ipsec']['tunnel']);
698
			while (list($index, $tunnel) = each($config['ipsec']['tunnel'])) {
699
				/* Sanity check on required variables */
700
				/* This fixes bogus <tunnel> entries - remnant of bug #393 */
701
				if (!isset($tunnel['local-subnet']) && !isset($tunnel['remote-subnet'])) {
702
					unset($config['ipsec']['tunnel'][$tunnel]);
703
				}
704
			}
705
        	}
706
		$config['version'] = "2.0";
707
	}
708
	/* Convert 2.0 -> 2.1 */
709
	if ($config['version'] == "2.0") {
710
		/* shaper scheduler moved */
711
		if(isset($config['system']['schedulertype'])) {
712
			$config['shaper']['schedulertype'] = $config['system']['schedulertype'];
713
			unset($config['system']['schedulertype']);
714
		}
715
		$config['version'] = "2.1";
716
	}
717
	/* Convert 2.1 -> 2.2 */
718
	if ($config['version'] == "2.1") {
719
		/* move gateway to wan interface */
720
		$config['interfaces']['wan']['gateway'] = $config['system']['gateway'];
721
		$config['version'] = "2.2";
722
	}
723

    
724
	if ($prev_version != $config['version'])
725
		write_config("Upgraded config version level from {$prev_version} to {$config['version']}");
726
}
727

    
728
/****f* config/write_config
729
 * NAME
730
 *   write_config - Backup and write the firewall configuration.
731
 * DESCRIPTION
732
 *   write_config() handles backing up the current configuration,
733
 *   applying changes, and regenerating the configuration cache.
734
 * INPUTS
735
 *   $desc	- string containing the a description of configuration changes
736
 *   $backup	- boolean: do not back up current configuration if false.
737
 * RESULT
738
 *   null       
739
 ******/
740
/* save the system configuration */
741
function write_config($desc="Unknown", $backup = true) {
742
	global $config, $g;
743

    
744
	if($g['platform'] <> "wrap") {
745
		if($backup) backup_config();
746
	}
747

    
748
	if (time() > mktime(0, 0, 0, 9, 1, 2004))       /* make sure the clock settings are plausible */
749
                $changetime = time();
750

    
751
	/* Log the running script so it's not entirely unlogged what changed */ 
752
        if ($desc == "Unknown") 
753
        	$desc = "{$_SERVER['SCRIPT_NAME']} made unknown change";  
754

    
755
	$config['revision']['description'] = $desc;
756
	$config['revision']['time'] = $changetime;
757
	
758
	config_lock();
759

    
760
	/* generate configuration XML */
761
	$xmlconfig = dump_xml_config($config, $g['xml_rootobj']);
762

    
763
	conf_mount_rw();
764

    
765
	/* write new configuration */
766
	$fd = fopen("{$g['cf_conf_path']}/config.xml", "w");
767
	if (!$fd)
768
		die("Unable to open {$g['cf_conf_path']}/config.xml for writing in write_config()\n");
769
	fwrite($fd, $xmlconfig);
770
	fclose($fd);
771

    
772
	if($g['booting'] <> true) {
773
		conf_mount_ro();
774
	}
775

    
776
	config_unlock();
777

    
778
	// Always reparse the config after it's written - something is getting lost in serialize().
779
	$config = parse_config(true);
780
	return $config;
781
}
782

    
783
/****f* config/reset_factory_defaults
784
 * NAME
785
 *   reset_factory_defaults - Reset the system to its default configuration.
786
 * RESULT
787
 *   integer	- indicates completion
788
 ******/
789
function reset_factory_defaults() {
790
	global $g;
791

    
792
	config_lock();
793
	conf_mount_rw();
794

    
795
	/* create conf directory, if necessary */
796
	safe_mkdir("{$g['cf_conf_path']}");
797

    
798
	/* clear out /conf */
799
	$dh = opendir($g['conf_path']);
800
	while ($filename = readdir($dh)) {
801
		if (($filename != ".") && ($filename != "..")) {
802
			unlink_if_exists($g['conf_path'] . "/" . $filename);
803
		}
804
	}
805
	closedir($dh);
806

    
807
	/* copy default configuration */
808
	copy("{$g['conf_default_path']}/config.xml", "{$g['conf_path']}/config.xml");
809
	
810
	/* call the wizard */
811
	touch("/conf/trigger_initial_wizard");
812
	
813
	conf_mount_ro();
814
	config_unlock();
815

    
816
	return 0;
817
}
818

    
819
function config_restore($conffile) {
820
	global $config, $g;
821
       
822
        if (!file_exists($conffile))
823
                return 1;
824
        
825
        config_lock();
826
        conf_mount_rw();        
827
        
828
        backup_config();
829
        copy($conffile, "{$g['cf_conf_path']}/config.xml");
830
	$config = parse_config(true);
831
        write_config("Reverted to " . array_pop(explode("/", $conffile)) . ".", false);
832
        
833
        conf_mount_ro();
834
        config_unlock();
835

    
836
        return 0;
837
}
838

    
839

    
840

    
841
function config_install($conffile) {
842
        global $config, $g;
843
        
844
        if (!file_exists($conffile))
845
                return 1;
846

    
847
	if($g['booting'] == true)
848
		echo "Installing configuration...\n";
849
 
850
        config_lock();
851
        conf_mount_rw();
852

    
853
	
854
        copy($conffile, "{$g['conf_path']}/config.xml");
855

    
856
	/* unlink cache file if it exists */
857
	if(file_exists("{$g['tmp_path']}/config.cache"))
858
		unlink("{$g['tmp_path']}/config.cache");
859
  
860
        conf_mount_ro();
861
        config_unlock();
862

    
863
        return 0;
864
}
865

    
866
/* lock configuration file, decide that the lock file is stale after
867
   10 seconds */
868
function config_lock() {
869
	global $g, $process_lock;
870

    
871
	/* No need to continue if we're the ones holding the lock */
872
	if ($process_lock)
873
		return;
874

    
875
	$lockfile = "{$g['varrun_path']}/config.lock";
876

    
877
	$n = 0;
878
	while ($n < 10) {
879
		/* open the lock file in append mode to avoid race condition */
880
		if ($fd = @fopen($lockfile, "x")) {
881
			/* succeeded */
882
			$process_lock = true;
883
			fclose($fd);
884
			return;
885
		} else {
886
			/* file locked, wait and try again */
887
			$process_lock = false;
888
			sleep(1);
889
			$n++;
890
		}
891
	}
892
}
893

    
894
/* unlock configuration file */
895
function config_unlock() {
896
	global $g, $process_lock;
897

    
898
	$lockfile = "{$g['varrun_path']}/config.lock";
899
	$process_lock = false;
900

    
901
	unlink_if_exists($lockfile);
902
}
903

    
904
function set_networking_interfaces_ports() {
905
	global $noreboot;
906
	global $config;
907
	global $g;
908
	global $fp;
909

    
910
	$fp = fopen('php://stdin', 'r');
911

    
912
	$iflist = get_interface_list();
913

    
914
	echo <<<EOD
915

    
916
Valid interfaces are:
917

    
918

    
919
EOD;
920

    
921
	foreach ($iflist as $iface => $ifa) {
922
		echo sprintf("% -8s%s%s\n", $iface, $ifa['mac'],
923
			$ifa['up'] ? "   (up)" : "");
924
	}
925

    
926
	echo <<<EOD
927

    
928
Do you want to set up VLANs first?
929
If you are not going to use VLANs, or only for optional interfaces, you
930
should say no here and use the webGUI to configure VLANs later, if required.
931

    
932
Do you want to set up VLANs now [y|n]?
933
EOD;
934

    
935
	if (strcasecmp(chop(fgets($fp)), "y") == 0)
936
		vlan_setup();
937

    
938
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
939

    
940
		echo "\n\nVLAN interfaces:\n\n";
941
		$i = 0;
942
		foreach ($config['vlans']['vlan'] as $vlan) {
943

    
944
			echo sprintf("% -8s%s\n", "vlan{$i}",
945
				"VLAN tag {$vlan['tag']}, interface {$vlan['if']}");
946

    
947
			$iflist['vlan' . $i] = array();
948
			$i++;
949
		}
950
	}
951

    
952
	echo <<<EOD
953

    
954
*NOTE*  pfSense requires *ATLEAST* 2 assigned interfaces to function.
955
        If you do not have two interfaces turn off the machine until
956
	you do.
957

    
958
If you do not know the names of your interfaces, you may choose to use
959
auto-detection... In that case, disconnect all interfaces now before
960
hitting a.   The system will then prompt you to plug in each nic to
961
autodetect.
962

    
963
EOD;
964

    
965
	do {
966
		echo "\nEnter the LAN interface name or 'a' for auto-detection: ";
967
		$lanif = chop(fgets($fp));
968
		if ($lanif === "") {
969
			exit(0);
970
		}
971

    
972
		if ($lanif === "a")
973
			$lanif = autodetect_interface("LAN", $fp);
974
		else if (!array_key_exists($lanif, $iflist)) {
975
			echo "\nInvalid interface name '{$lanif}'\n";
976
			unset($lanif);
977
			continue;
978
		}
979
	} while (!$lanif);
980

    
981
	do {
982
		echo "\nEnter the WAN interface name or 'a' for auto-detection: ";
983
		$wanif = chop(fgets($fp));
984
		if ($wanif === "") {
985
			exit(0);
986
		}
987
		if ($wanif === "a")
988
			$wanif = autodetect_interface("WAN", $fp);
989
		else if (!array_key_exists($wanif, $iflist)) {
990
			echo "\nInvalid interface name '{$wanif}'\n";
991
			unset($wanif);
992
			continue;
993
		}
994
	} while (!$wanif);
995

    
996
	/* optional interfaces */
997
	$i = 0;
998
	$optif = array();
999

    
1000
	while (1) {
1001
		if ($optif[$i])
1002
			$i++;
1003
		$i1 = $i + 1;
1004
		echo "\nEnter the Optional {$i1} interface name or 'a' for auto-detection\n" .
1005
			"(or nothing if finished): ";
1006
		$optif[$i] = chop(fgets($fp));
1007

    
1008
		if ($optif[$i]) {
1009
			if ($optif[$i] === "a") {
1010
				$ad = autodetect_interface("Optional " . $i1, $fp);
1011
				if ($ad)
1012
					$optif[$i] = $ad;
1013
				else
1014
					unset($optif[$i]);
1015
			} else if (!array_key_exists($optif[$i], $iflist)) {
1016
				echo "\nInvalid interface name '{$optif[$i]}'\n";
1017
				unset($optif[$i]);
1018
				continue;
1019
			}
1020
		} else {
1021
			unset($optif[$i]);
1022
			break;
1023
		}
1024
	}
1025

    
1026
	/* check for double assignments */
1027
	$ifarr = array_merge(array($lanif, $wanif), $optif);
1028

    
1029
	for ($i = 0; $i < (count($ifarr)-1); $i++) {
1030
		for ($j = ($i+1); $j < count($ifarr); $j++) {
1031
			if ($ifarr[$i] == $ifarr[$j]) {
1032
				echo <<<EOD
1033

    
1034
Error: you cannot assign the same interface name twice!
1035

    
1036
EOD;
1037

    
1038
				exit(0);
1039
			}
1040
		}
1041
	}
1042

    
1043
	echo <<<EOD
1044

    
1045
The interfaces will be assigned as follows:
1046

    
1047
LAN  -> {$lanif}
1048
WAN  -> {$wanif}
1049

    
1050
EOD;
1051

    
1052
	for ($i = 0; $i < count($optif); $i++) {
1053
		echo "OPT" . ($i+1) . " -> " . $optif[$i] . "\n";
1054
	}
1055

    
1056
echo <<<EOD
1057

    
1058
Do you want to proceed [y|n]?
1059
EOD;
1060

    
1061
	if (strcasecmp(chop(fgets($fp)), "y") == 0) {
1062

    
1063
		$config['interfaces']['lan']['if'] = $lanif;
1064
		if (preg_match($g['wireless_regex'], $lanif)) {
1065
			if (!is_array($config['interfaces']['lan']['wireless']))
1066
				$config['interfaces']['lan']['wireless'] = array();
1067
		} else {
1068
			unset($config['interfaces']['lan']['wireless']);
1069
		}
1070
		
1071
		$config['interfaces']['wan']['if'] = $wanif;
1072
		if (preg_match($g['wireless_regex'], $wanif)) {
1073
			if (!is_array($config['interfaces']['wan']['wireless']))
1074
				$config['interfaces']['wan']['wireless'] = array();
1075
		} else {
1076
			unset($config['interfaces']['wan']['wireless']);
1077
		}
1078
		
1079
		for ($i = 0; $i < count($optif); $i++) {
1080
			if (!is_array($config['interfaces']['opt' . ($i+1)]))
1081
				$config['interfaces']['opt' . ($i+1)] = array();
1082
			
1083
			$config['interfaces']['opt' . ($i+1)]['if'] = $optif[$i];
1084
			
1085
			/* wireless interface? */
1086
			if (preg_match($g['wireless_regex'], $optif[$i])) {
1087
				if (!is_array($config['interfaces']['opt' . ($i+1)]['wireless']))
1088
					$config['interfaces']['opt' . ($i+1)]['wireless'] = array();
1089
			} else {
1090
				unset($config['interfaces']['opt' . ($i+1)]['wireless']);
1091
			}
1092
			
1093
			unset($config['interfaces']['opt' . ($i+1)]['enable']);
1094
			$config['interfaces']['opt' . ($i+1)]['descr'] = "OPT" . ($i+1);
1095
		}
1096
		
1097
		/* remove all other (old) optional interfaces */
1098
		for (; isset($config['interfaces']['opt' . ($i+1)]); $i++)
1099
			unset($config['interfaces']['opt' . ($i+1)]);
1100
		
1101
		conf_mount_rw();
1102
		
1103
		/* call the wizard */
1104
		touch("/conf/trigger_initial_wizard");
1105
		
1106
		write_config();
1107
		
1108
		echo <<<EOD
1109

    
1110

    
1111

    
1112
EOD;
1113

    
1114
		if($g['booting'])
1115
			return;
1116

    
1117
		echo "One moment while we reload the settings...";
1118

    
1119
		/* resync everything */
1120
		reload_all_sync();
1121
		
1122
		echo " done!";
1123

    
1124
	}
1125
}
1126

    
1127
function autodetect_interface($ifname, $fp) {
1128
	$iflist_prev = get_interface_list("media");
1129
	echo <<<EOD
1130

    
1131
Connect the {$ifname} interface now and make sure that the link is up.
1132
Then press ENTER to continue.
1133

    
1134
EOD;
1135
	fgets($fp);
1136
	$iflist = get_interface_list("media");
1137

    
1138
	foreach ($iflist_prev as $ifn => $ifa) {
1139
		if (!$ifa['up'] && $iflist[$ifn]['up']) {
1140
			echo "Detected link-up on interface {$ifn}.\n";
1141
			return $ifn;
1142
		}
1143
	}
1144

    
1145
	echo "No link-up detected.\n";
1146

    
1147
	return null;
1148
}
1149

    
1150
function vlan_setup() {
1151
	global $iflist, $config, $g, $fp;
1152

    
1153
	$iflist = get_interface_list();
1154

    
1155
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
1156

    
1157
	echo <<<EOD
1158

    
1159
WARNING: all existing VLANs will be cleared if you proceed!
1160

    
1161
Do you want to proceed [y|n]?
1162
EOD;
1163

    
1164
	if (strcasecmp(chop(fgets($fp)), "y") != 0)
1165
		return;
1166
	}
1167

    
1168
	$config['vlans']['vlan'] = array();
1169
	echo "\n";
1170

    
1171
	while (1) {
1172
		$vlan = array();
1173

    
1174
		echo "\nEnter the parent interface name for the new VLAN (or nothing if finished): ";
1175
		$vlan['if'] = chop(fgets($fp));
1176

    
1177
		if ($vlan['if']) {
1178
			if (!array_key_exists($vlan['if'], $iflist) or
1179
			    !is_jumbo_capable($vlan['if'])) {
1180
				echo "\nInvalid interface name '{$vlan['if']}'\n";
1181
				continue;
1182
			}
1183
		} else {
1184
			break;
1185
		}
1186

    
1187
		echo "Enter the VLAN tag (1-4094): ";
1188
		$vlan['tag'] = chop(fgets($fp));
1189

    
1190
		if (!is_numericint($vlan['tag']) || ($vlan['tag'] < 1) || ($vlan['tag'] > 4094)) {
1191
			echo "\nInvalid VLAN tag '{$vlan['tag']}'\n";
1192
			continue;
1193
		}
1194

    
1195
		$config['vlans']['vlan'][] = $vlan;
1196
	}
1197
}
1198

    
1199
function system_start_ftp_helpers() {
1200
	require_once("interfaces.inc");
1201
	global $config, $g;
1202

    
1203
	/* build an array of interfaces to work with */
1204
	$iflist = array("lan" => "LAN");
1205
	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) 
1206
		$iflist['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
1207

    
1208
	/* loop through all interfaces and handle pftpx */
1209
	$interface_counter = 0;
1210
	foreach ($iflist as $ifent => $ifname) {
1211
		/*    if the ftp proxy is disabled for this interface then kill pftpx 
1212
		 *    instance and continue. note that the helpers for port forwards are 
1213
		 *    launched in a  different sequence so we are filtering them out 
1214
                 *    here by not including -c {$port} -g 8021 first.
1215
		 */
1216
		$port = 8021 + $interface_counter;
1217
		if(isset($config['interfaces'][$ifname]['disableftpproxy'])) {
1218
			/*    item is disabled.  lets ++ the interface counter and
1219
			 *    keep processing interfaces. kill pftpx if already
1220
                         *    running for this instance.
1221
                         */
1222
			$helpers = exec("ps awux | grep \"/usr/local/sbin/pftpx -c {$port}\" | grep -v grep | sed \"s/  */ /g\" | cut -f2 -d\" \"");
1223
			if($helpers)
1224
				mwexec("/bin/kill {$helpers}");
1225
			$interface_counter++;
1226
		} else {
1227
			/* grab the current interface IP address */
1228
			$ip = find_interface_ip(convert_friendly_interface_to_real_interface_name($ifname));
1229
			/* if pftpx is already running then do not launch it again */
1230
			$helpers = exec("ps awux | grep \"/usr/local/sbin/pftpx -c {$port}\" | grep -v grep | sed \"s/  */ /g\"");
1231
			if(!$helpers && $ip)
1232
 				mwexec("/usr/local/sbin/pftpx -c {$port} -g 8021 {$ip}");
1233
			$interface_counter++;
1234
		}
1235
	}
1236
}
1237

    
1238
function cleanup_backupcache($revisions = 30) {
1239
	global $g;
1240
	$i = false;
1241
	if(file_exists($g['cf_conf_path'] . '/backup/backup.cache')) {
1242
		conf_mount_rw();
1243
		$backups = get_backups();
1244
		$newbaks = array();
1245
		$bakfiles = glob($g['cf_conf_path'] . "/backup/config-*");
1246
		$baktimes = $backups['versions'];
1247
		$tocache = array();
1248
		unset($backups['versions']);
1249
       		foreach($bakfiles as $backup) { // Check for backups in the directory not represented in the cache.
1250
			$tocheck = array_shift(explode('.', array_pop(explode('-', $backup))));	
1251
                	if(!in_array($tocheck, $baktimes)) {
1252
				$i = true;
1253
				if($bootup) print " " . $tocheck . "a";
1254
				$newxml = parse_xml_config($backup, $g['xml_rootobj']);
1255
				if($newxml['revision']['description'] == "") $newxml['revision']['description'] = "Unknown";
1256
				$tocache[$tocheck] = array('description' => $newxml['revision']['description']);
1257
			}
1258
        	}
1259
		foreach($backups as $checkbak) {
1260
			if(count(preg_grep('/' . $checkbak['time'] . '/i', $bakfiles)) != 0) {
1261
				$newbaks[] = $checkbak;
1262
			} else {
1263
				$i = true;
1264
				if($bootup) print " " . $tocheck . "r";
1265
			}
1266
		}
1267
		foreach($newbaks as $todo) $tocache[$todo['time']] = array('description' => $todo['description']);	
1268
		if(is_int($revisions) and (count($tocache) > $revisions)) {
1269
			$toslice = array_slice(array_keys($tocache), 0, $revisions);
1270
			foreach($toslice as $sliced) $newcache[$sliced] = $tocache[$sliced];
1271
			foreach($tocache as $version => $versioninfo) {
1272
				if(!in_array($version, array_keys($newcache))) {
1273
					unlink_if_exists($g['conf_path'] . '/backup/config-' . $version . '.xml');
1274
					if($bootup) print " " . $tocheck . "d";
1275
				}
1276
			}
1277
			$tocache = $newcache;
1278
		}
1279
		$bakout = fopen($g['cf_conf_path'] . '/backup/backup.cache', "w");
1280
        	fwrite($bakout, serialize($tocache));
1281
  	        fclose($bakout);
1282
		conf_mount_ro();
1283
	}
1284
	if($g['booting']) {
1285
		if($i) {
1286
			print "done.\n";
1287
		}
1288
	}
1289
}
1290
  	 
1291
function get_backups() { 	 
1292
	global $g;
1293

    
1294
        if(file_exists("{$g['cf_conf_path']}/backup/backup.cache")) {
1295
                $confvers = unserialize(file_get_contents("{$g['cf_conf_path']}/backup/backup.cache"));
1296
		$bakvers = array_keys($confvers);
1297
		$toreturn = array();
1298
		sort($bakvers);
1299
		// $bakvers = array_reverse($bakvers);
1300
		foreach(array_reverse($bakvers) as $bakver) $toreturn[] = array('time' => $bakver,
1301
								 'description' => $confvers[$bakver]['description']
1302
								);
1303
        } else { 	 
1304
                return false; 	 
1305
        }
1306
	$toreturn['versions'] = $bakvers;
1307
        return $toreturn;
1308
}
1309

    
1310
function backup_config() {
1311
	global $config, $g;
1312

    
1313
	if($g['platform'] == "cdrom")
1314
		return;
1315

    
1316
	conf_mount_rw();
1317

    
1318
	/* Create backup directory if needed */
1319
	safe_mkdir("{$g['cf_conf_path']}/backup");
1320

    
1321
        if($config['revision']['time'] == "") {
1322
                $baktime = 0;
1323
        } else {
1324
                $baktime = $config['revision']['time'];
1325
        }
1326
        if($config['revision']['description'] == "") {
1327
                $bakdesc = "Unknown";
1328
        } else {
1329
                $bakdesc = $config['revision']['description'];
1330
        }
1331
        copy($g['cf_conf_path'] . '/config.xml', $g['cf_conf_path'] . '/backup/config-' . $baktime . '.xml');
1332
        if(file_exists($g['cf_conf_path'] . '/backup/backup.cache')) {
1333
                $backupcache = unserialize(file_get_contents($g['cf_conf_path'] . '/backup/backup.cache'));
1334
        } else {
1335
                $backupcache = array();
1336
        }
1337
        $backupcache[$baktime] = array('description' => $bakdesc);
1338
        $bakout = fopen($g['cf_conf_path'] . '/backup/backup.cache', "w");
1339
        fwrite($bakout, serialize($backupcache));
1340
        fclose($bakout);
1341
	
1342
	conf_mount_ro();
1343
	
1344
	return true;
1345
}
1346

    
1347
function mute_kernel_msgs() {
1348
	exec("/sbin/conscontrol mute on");
1349
}
1350

    
1351
function unmute_kernel_msgs() {
1352
	exec("/sbin/conscontrol mute off");
1353
}
1354

    
1355
function start_devd() {
1356
	exec("/sbin/devd");
1357
}
1358

    
1359
?>
(4-4/25)