Project

General

Profile

Download (38.1 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
if(file_exists("/cf/conf/config.xml")) {
68
	$config_contents = file_get_contents("/cf/conf/config.xml");
69
	if(stristr($config_contents, "m0n0wall") == true) {
70
		/* user has just upgraded to m0n0wall, replace root xml tags */
71
		echo "Upgrading m0n0wall configuration to pfSense... ";
72
		$config_contents = str_replace("m0n0wall","pfsense");
73
		$fd = fopen("/cf/conf/config.xml", "w");
74
		fwrite($fd, $config_contents);
75
		fclose($fd);
76
		echo "done.";
77
	}
78
}
79

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

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

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

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

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

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

    
135
					if ($cfgdevice)
136
						break;
137
				}
138
			}
139
		}
140

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

    
145

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

    
152

    
153
EOD;
154

    
155
			mwexec("/sbin/halt");
156
			exit;
157
		}
158

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

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

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

    
170
		fwrite($fd, $fstab);
171
		fclose($fd);
172
	}
173

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

    
178
$config = parse_config();
179

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

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

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

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

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

    
269

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

    
278

    
279
EOD;
280
		}
281

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

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

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

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

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

    
326
/****f* config/conf_mount_ro
327
 * NAME         
328
 *   conf_mount_ro - Mount filesystems readonly.
329
 * RESULT
330
 *   null        
331
 ******/
332
function conf_mount_ro() {
333
	global $g;
334

    
335
	if($g['booting'] == true)
336
		return;
337
	
338
	/* do not umount if generating ssh keys */
339
	if(file_exists("/tmp/keys_generating"))
340
		return;
341
	
342
	/* do not umount on cdrom or pfSense platforms */
343
	if($g['platform'] == "cdrom" or $g['platform'] == "pfSense")
344
		return;
345

    
346
	/* sync data, then force a umount the remount of /cf */
347
	mwexec("/bin/sync");
348
	mwexec("/bin/sync");
349
	mwexec("/sbin/umount -f {$g['cf_path']}");
350
	mwexec("/sbin/mount -r {$g['cf_path']}");
351
	mwexec("/bin/sync");
352
	mwexec("/bin/sync");
353
	mwexec("/sbin/mount -r /");
354
	
355
	usleep(100);
356

    
357
}
358

    
359
/****f* config/convert_config
360
 * NAME         
361
 *   convert_config - Attempt to update config.xml.
362
 * DESCRIPTION
363
 *   convert_config() reads the current global configuration
364
 *   and attempts to convert it to conform to the latest
365
 *   config.xml version. This allows major formatting changes
366
 *   to be made with a minimum of breakage.
367
 * RESULT
368
 *   null        
369
 ******/
370
/* convert configuration, if necessary */
371
function convert_config() {
372
	global $config, $g;
373

    
374
	if ($config['version'] == $g['latest_config'])
375
		return;		/* already at latest version */
376

    
377
	// Save off config version
378
	$prev_version = $config['version'];
379

    
380
	/* convert 1.0 -> 1.1 */
381
	if ($config['version'] == "1.0") {
382
		$opti = 1;
383
		$ifmap = array('lan' => 'lan', 'wan' => 'wan', 'pptp' => 'pptp');
384

    
385
		/* convert DMZ to optional, if necessary */
386
		if (isset($config['interfaces']['dmz'])) {
387

    
388
			$dmzcfg = &$config['interfaces']['dmz'];
389

    
390
			if ($dmzcfg['if']) {
391
				$config['interfaces']['opt' . $opti] = array();
392
				$optcfg = &$config['interfaces']['opt' . $opti];
393

    
394
				$optcfg['enable'] = $dmzcfg['enable'];
395
				$optcfg['descr'] = "DMZ";
396
				$optcfg['if'] = $dmzcfg['if'];
397
				$optcfg['ipaddr'] = $dmzcfg['ipaddr'];
398
				$optcfg['subnet'] = $dmzcfg['subnet'];
399

    
400
				$ifmap['dmz'] = "opt" . $opti;
401
				$opti++;
402
			}
403

    
404
			unset($config['interfaces']['dmz']);
405
		}
406

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

    
410
			if (!$config['interfaces']['wlan' . $i]['if']) {
411
				unset($config['interfaces']['wlan' . $i]);
412
				continue;
413
			}
414

    
415
			$wlancfg = &$config['interfaces']['wlan' . $i];
416
			$config['interfaces']['opt' . $opti] = array();
417
			$optcfg = &$config['interfaces']['opt' . $opti];
418

    
419
			$optcfg['enable'] = $wlancfg['enable'];
420
			$optcfg['descr'] = "WLAN" . $i;
421
			$optcfg['if'] = $wlancfg['if'];
422
			$optcfg['ipaddr'] = $wlancfg['ipaddr'];
423
			$optcfg['subnet'] = $wlancfg['subnet'];
424
			$optcfg['bridge'] = $wlancfg['bridge'];
425

    
426
			$optcfg['wireless'] = array();
427
			$optcfg['wireless']['mode'] = $wlancfg['mode'];
428
			$optcfg['wireless']['ssid'] = $wlancfg['ssid'];
429
			$optcfg['wireless']['channel'] = $wlancfg['channel'];
430
			$optcfg['wireless']['wep'] = $wlancfg['wep'];
431

    
432
			$ifmap['wlan' . $i] = "opt" . $opti;
433

    
434
			unset($config['interfaces']['wlan' . $i]);
435
			$opti++;
436
		}
437

    
438
		/* convert filter rules */
439
		$n = count($config['filter']['rule']);
440
		for ($i = 0; $i < $n; $i++) {
441

    
442
			$fr = &$config['filter']['rule'][$i];
443

    
444
			/* remap interface */
445
			if (array_key_exists($fr['interface'], $ifmap))
446
				$fr['interface'] = $ifmap[$fr['interface']];
447
			else {
448
				/* remove the rule */
449
				echo "\nWarning: filter rule removed " .
450
					"(interface '{$fr['interface']}' does not exist anymore).";
451
				unset($config['filter']['rule'][$i]);
452
				continue;
453
			}
454

    
455
			/* remap source network */
456
			if (isset($fr['source']['network'])) {
457
				if (array_key_exists($fr['source']['network'], $ifmap))
458
					$fr['source']['network'] = $ifmap[$fr['source']['network']];
459
				else {
460
					/* remove the rule */
461
					echo "\nWarning: filter rule removed " .
462
						"(source network '{$fr['source']['network']}' does not exist anymore).";
463
					unset($config['filter']['rule'][$i]);
464
					continue;
465
				}
466
			}
467

    
468
			/* remap destination network */
469
			if (isset($fr['destination']['network'])) {
470
				if (array_key_exists($fr['destination']['network'], $ifmap))
471
					$fr['destination']['network'] = $ifmap[$fr['destination']['network']];
472
				else {
473
					/* remove the rule */
474
					echo "\nWarning: filter rule removed " .
475
						"(destination network '{$fr['destination']['network']}' does not exist anymore).";
476
					unset($config['filter']['rule'][$i]);
477
					continue;
478
				}
479
			}
480
		}
481

    
482
		/* convert shaper rules */
483
		$n = count($config['pfqueueing']['rule']);
484
		if (is_array($config['pfqueueing']['rule']))
485
			for ($i = 0; $i < $n; $i++) {
486

    
487
			$fr = &$config['pfqueueing']['rule'][$i];
488

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

    
500
			/* remap source network */
501
			if (isset($fr['source']['network'])) {
502
				if (array_key_exists($fr['source']['network'], $ifmap))
503
					$fr['source']['network'] = $ifmap[$fr['source']['network']];
504
				else {
505
					/* remove the rule */
506
					echo "\nWarning: traffic shaper rule removed " .
507
						"(source network '{$fr['source']['network']}' does not exist anymore).";
508
					unset($config['pfqueueing']['rule'][$i]);
509
					continue;
510
				}
511
			}
512

    
513
			/* remap destination network */
514
			if (isset($fr['destination']['network'])) {
515
				if (array_key_exists($fr['destination']['network'], $ifmap))
516
					$fr['destination']['network'] = $ifmap[$fr['destination']['network']];
517
				else {
518
					/* remove the rule */
519
					echo "\nWarning: traffic shaper rule removed " .
520
						"(destination network '{$fr['destination']['network']}' does not exist anymore).";
521
					unset($config['pfqueueing']['rule'][$i]);
522
					continue;
523
				}
524
			}
525
		}
526

    
527
		$config['version'] = "1.1";
528
	}
529

    
530
	/* convert 1.1 -> 1.2 */
531
	if ($config['version'] == "1.1") {
532
		/* move LAN DHCP server config */
533
		$tmp = $config['dhcpd'];
534
		$config['dhcpd'] = array();
535
		$config['dhcpd']['lan'] = $tmp;
536

    
537
		/* encrypt password */
538
		$config['system']['password'] = crypt($config['system']['password']);
539

    
540
		$config['version'] = "1.2";
541
	}
542

    
543
	/* convert 1.2 -> 1.3 */
544
	if ($config['version'] == "1.2") {
545
		/* convert advanced outbound NAT config */
546
		for ($i = 0; isset($config['nat']['advancedoutbound']['rule'][$i]); $i++) {
547
			$curent = &$config['nat']['advancedoutbound']['rule'][$i];
548
			$src = $curent['source'];
549
			$curent['source'] = array();
550
			$curent['source']['network'] = $src;
551
			$curent['destination'] = array();
552
			$curent['destination']['any'] = true;
553
		}
554

    
555
		/* add an explicit type="pass" to all filter rules to make things consistent */
556
		for ($i = 0; isset($config['filter']['rule'][$i]); $i++) {
557
			$config['filter']['rule'][$i]['type'] = "pass";
558
		}
559

    
560
		$config['version'] = "1.3";
561
	}
562

    
563
	/* convert 1.3 -> 1.4 */
564
	if ($config['version'] == "1.3") {
565
		/* convert shaper rules (make pipes) */
566
		if (is_array($config['pfqueueing']['rule'])) {
567
			$config['pfqueueing']['pipe'] = array();
568

    
569
			for ($i = 0; isset($config['pfqueueing']['rule'][$i]); $i++) {
570
				$curent = &$config['pfqueueing']['rule'][$i];
571

    
572
				/* make new pipe and associate with this rule */
573
				$newpipe = array();
574
				$newpipe['descr'] = $curent['descr'];
575
				$newpipe['bandwidth'] = $curent['bandwidth'];
576
				$newpipe['delay'] = $curent['delay'];
577
				$newpipe['mask'] = $curent['mask'];
578
				$config['pfqueueing']['pipe'][$i] = $newpipe;
579

    
580
				$curent['targetpipe'] = $i;
581

    
582
				unset($curent['bandwidth']);
583
				unset($curent['delay']);
584
				unset($curent['mask']);
585
			}
586
		}
587

    
588
		$config['version'] = "1.4";
589
	}
590

    
591
	/* Convert 1.4 -> 1.5 */
592
	if ($config['version'] == "1.4") {
593

    
594
		/* Default route moved */
595
		if (isset($config['interfaces']['wan']['gateway']))
596
			if ($config['interfaces']['wan']['gateway'] <> "")
597
				$config['interfaces']['wan']['gateway'] = $config['interfaces']['wan']['gateway'];
598
		unset($config['interfaces']['wan']['gateway']);
599

    
600
                /* Queues are no longer interface specific */
601
                if (isset($config['interfaces']['lan']['schedulertype']))
602
                        unset($config['interfaces']['lan']['schedulertype']);
603
                if (isset($config['interfaces']['wan']['schedulertype']))
604
                        unset($config['interfaces']['wan']['schedulertype']);
605

    
606
                for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
607
                        if(isset($config['interfaces']['opt' . $i]['schedulertype']))
608
                                unset($config['interfaces']['opt' . $i]['schedulertype']);
609
                }
610

    
611
		$config['version'] = "1.5";
612
	}
613

    
614
	/* Convert 1.5 -> 1.6 */
615
	if ($config['version'] == "1.5") {
616
		/* Alternate firmware URL moved */
617
		if (isset($config['system']['firmwareurl']) && isset($config['system']['firmwarename'])) { // Only convert if *both* are defined.
618
			$config['system']['alt_firmware_url'] = array();
619
			$config['system']['alt_firmware_url']['enabled'] = "";
620
			$config['system']['alt_firmware_url']['firmware_base_url'] = $config['system']['firmwareurl'];
621
			$config['system']['alt_firmware_url']['firmware_filename'] = $config['system']['firmwarename'];
622
			unset($config['system']['firmwareurl'], $config['system']['firmwarename']);
623
		} else {
624
			unset($config['system']['firmwareurl'], $config['system']['firmwarename']);
625
		}
626

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

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

    
732
	if ($prev_version != $config['version'])
733
		write_config("Upgraded config version level from {$prev_version} to {$config['version']}");
734
}
735

    
736
/****f* config/write_config
737
 * NAME
738
 *   write_config - Backup and write the firewall configuration.
739
 * DESCRIPTION
740
 *   write_config() handles backing up the current configuration,
741
 *   applying changes, and regenerating the configuration cache.
742
 * INPUTS
743
 *   $desc	- string containing the a description of configuration changes
744
 *   $backup	- boolean: do not back up current configuration if false.
745
 * RESULT
746
 *   null       
747
 ******/
748
/* save the system configuration */
749
function write_config($desc="Unknown", $backup = true) {
750
	global $config, $g;
751

    
752
	if($g['platform'] <> "wrap") {
753
		if($backup) backup_config();
754
	}
755

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

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

    
763
	$config['revision']['description'] = $desc;
764
	$config['revision']['time'] = $changetime;
765
	
766
	config_lock();
767

    
768
	/* generate configuration XML */
769
	$xmlconfig = dump_xml_config($config, $g['xml_rootobj']);
770

    
771
	conf_mount_rw();
772

    
773
	/* write new configuration */
774
	$fd = fopen("{$g['cf_conf_path']}/config.xml", "w");
775
	if (!$fd)
776
		die("Unable to open {$g['cf_conf_path']}/config.xml for writing in write_config()\n");
777
	fwrite($fd, $xmlconfig);
778
	fclose($fd);
779

    
780
	if($g['booting'] <> true) {
781
		conf_mount_ro();
782
	}
783

    
784
	config_unlock();
785

    
786
	// Always reparse the config after it's written - something is getting lost in serialize().
787
	$config = parse_config(true);
788
	return $config;
789
}
790

    
791
/****f* config/reset_factory_defaults
792
 * NAME
793
 *   reset_factory_defaults - Reset the system to its default configuration.
794
 * RESULT
795
 *   integer	- indicates completion
796
 ******/
797
function reset_factory_defaults() {
798
	global $g;
799

    
800
	config_lock();
801
	conf_mount_rw();
802

    
803
	/* create conf directory, if necessary */
804
	safe_mkdir("{$g['cf_conf_path']}");
805

    
806
	/* clear out /conf */
807
	$dh = opendir($g['conf_path']);
808
	while ($filename = readdir($dh)) {
809
		if (($filename != ".") && ($filename != "..")) {
810
			unlink_if_exists($g['conf_path'] . "/" . $filename);
811
		}
812
	}
813
	closedir($dh);
814

    
815
	/* copy default configuration */
816
	copy("{$g['conf_default_path']}/config.xml", "{$g['conf_path']}/config.xml");
817
	
818
	/* call the wizard */
819
	touch("/conf/trigger_initial_wizard");
820
	
821
	conf_mount_ro();
822
	config_unlock();
823

    
824
	return 0;
825
}
826

    
827
function config_restore($conffile) {
828
	global $config, $g;
829
       
830
        if (!file_exists($conffile))
831
                return 1;
832
        
833
        config_lock();
834
        conf_mount_rw();        
835
        
836
        backup_config();
837
        copy($conffile, "{$g['cf_conf_path']}/config.xml");
838
	$config = parse_config(true);
839
        write_config("Reverted to " . array_pop(explode("/", $conffile)) . ".", false);
840
        
841
        conf_mount_ro();
842
        config_unlock();
843

    
844
        return 0;
845
}
846

    
847

    
848

    
849
function config_install($conffile) {
850
        global $config, $g;
851
        
852
        if (!file_exists($conffile))
853
                return 1;
854

    
855
	if($g['booting'] == true)
856
		echo "Installing configuration...\n";
857
 
858
        config_lock();
859
        conf_mount_rw();
860

    
861
	
862
        copy($conffile, "{$g['conf_path']}/config.xml");
863

    
864
	/* unlink cache file if it exists */
865
	if(file_exists("{$g['tmp_path']}/config.cache"))
866
		unlink("{$g['tmp_path']}/config.cache");
867
  
868
        conf_mount_ro();
869
        config_unlock();
870

    
871
        return 0;
872
}
873

    
874
/* lock configuration file, decide that the lock file is stale after
875
   10 seconds */
876
function config_lock() {
877
	global $g, $process_lock;
878

    
879
	/* No need to continue if we're the ones holding the lock */
880
	if ($process_lock)
881
		return;
882

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

    
885
	$n = 0;
886
	while ($n < 10) {
887
		/* open the lock file in append mode to avoid race condition */
888
		if ($fd = @fopen($lockfile, "x")) {
889
			/* succeeded */
890
			$process_lock = true;
891
			fclose($fd);
892
			return;
893
		} else {
894
			/* file locked, wait and try again */
895
			$process_lock = false;
896
			sleep(1);
897
			$n++;
898
		}
899
	}
900
}
901

    
902
/* unlock configuration file */
903
function config_unlock() {
904
	global $g, $process_lock;
905

    
906
	$lockfile = "{$g['varrun_path']}/config.lock";
907
	$process_lock = false;
908

    
909
	unlink_if_exists($lockfile);
910
}
911

    
912
function set_networking_interfaces_ports() {
913
	global $noreboot;
914
	global $config;
915
	global $g;
916
	global $fp;
917

    
918
	$fp = fopen('php://stdin', 'r');
919

    
920
	$iflist = get_interface_list();
921

    
922
	echo <<<EOD
923

    
924
Valid interfaces are:
925

    
926

    
927
EOD;
928

    
929
	foreach ($iflist as $iface => $ifa) {
930
		echo sprintf("% -8s%s%s\n", $iface, $ifa['mac'],
931
			$ifa['up'] ? "   (up)" : "");
932
	}
933

    
934
	echo <<<EOD
935

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

    
940
Do you want to set up VLANs now [y|n]?
941
EOD;
942

    
943
	if (strcasecmp(chop(fgets($fp)), "y") == 0)
944
		vlan_setup();
945

    
946
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
947

    
948
		echo "\n\nVLAN interfaces:\n\n";
949
		$i = 0;
950
		foreach ($config['vlans']['vlan'] as $vlan) {
951

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

    
955
			$iflist['vlan' . $i] = array();
956
			$i++;
957
		}
958
	}
959

    
960
	echo <<<EOD
961

    
962
*NOTE*  pfSense requires *ATLEAST* 2 assigned interfaces to function.
963
        If you do not have two interfaces turn off the machine until
964
	you do.
965

    
966
If you do not know the names of your interfaces, you may choose to use
967
auto-detection... In that case, disconnect all interfaces now before
968
hitting a.   The system will then prompt you to plug in each nic to
969
autodetect.
970

    
971
EOD;
972

    
973
	do {
974
		echo "\nEnter the LAN interface name or 'a' for auto-detection: ";
975
		$lanif = chop(fgets($fp));
976
		if ($lanif === "") {
977
			exit(0);
978
		}
979

    
980
		if ($lanif === "a")
981
			$lanif = autodetect_interface("LAN", $fp);
982
		else if (!array_key_exists($lanif, $iflist)) {
983
			echo "\nInvalid interface name '{$lanif}'\n";
984
			unset($lanif);
985
			continue;
986
		}
987
	} while (!$lanif);
988

    
989
	do {
990
		echo "\nEnter the WAN interface name or 'a' for auto-detection: ";
991
		$wanif = chop(fgets($fp));
992
		if ($wanif === "") {
993
			exit(0);
994
		}
995
		if ($wanif === "a")
996
			$wanif = autodetect_interface("WAN", $fp);
997
		else if (!array_key_exists($wanif, $iflist)) {
998
			echo "\nInvalid interface name '{$wanif}'\n";
999
			unset($wanif);
1000
			continue;
1001
		}
1002
	} while (!$wanif);
1003

    
1004
	/* optional interfaces */
1005
	$i = 0;
1006
	$optif = array();
1007

    
1008
	while (1) {
1009
		if ($optif[$i])
1010
			$i++;
1011
		$i1 = $i + 1;
1012
		echo "\nEnter the Optional {$i1} interface name or 'a' for auto-detection\n" .
1013
			"(or nothing if finished): ";
1014
		$optif[$i] = chop(fgets($fp));
1015

    
1016
		if ($optif[$i]) {
1017
			if ($optif[$i] === "a") {
1018
				$ad = autodetect_interface("Optional " . $i1, $fp);
1019
				if ($ad)
1020
					$optif[$i] = $ad;
1021
				else
1022
					unset($optif[$i]);
1023
			} else if (!array_key_exists($optif[$i], $iflist)) {
1024
				echo "\nInvalid interface name '{$optif[$i]}'\n";
1025
				unset($optif[$i]);
1026
				continue;
1027
			}
1028
		} else {
1029
			unset($optif[$i]);
1030
			break;
1031
		}
1032
	}
1033

    
1034
	/* check for double assignments */
1035
	$ifarr = array_merge(array($lanif, $wanif), $optif);
1036

    
1037
	for ($i = 0; $i < (count($ifarr)-1); $i++) {
1038
		for ($j = ($i+1); $j < count($ifarr); $j++) {
1039
			if ($ifarr[$i] == $ifarr[$j]) {
1040
				echo <<<EOD
1041

    
1042
Error: you cannot assign the same interface name twice!
1043

    
1044
EOD;
1045

    
1046
				exit(0);
1047
			}
1048
		}
1049
	}
1050

    
1051
	echo <<<EOD
1052

    
1053
The interfaces will be assigned as follows:
1054

    
1055
LAN  -> {$lanif}
1056
WAN  -> {$wanif}
1057

    
1058
EOD;
1059

    
1060
	for ($i = 0; $i < count($optif); $i++) {
1061
		echo "OPT" . ($i+1) . " -> " . $optif[$i] . "\n";
1062
	}
1063

    
1064
echo <<<EOD
1065

    
1066
Do you want to proceed [y|n]?
1067
EOD;
1068

    
1069
	if (strcasecmp(chop(fgets($fp)), "y") == 0) {
1070

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

    
1118

    
1119

    
1120
EOD;
1121

    
1122
		if($g['booting'])
1123
			return;
1124

    
1125
		echo "One moment while we reload the settings...";
1126

    
1127
		/* resync everything */
1128
		reload_all_sync();
1129
		
1130
		echo " done!\n";
1131

    
1132
	}
1133
}
1134

    
1135
function autodetect_interface($ifname, $fp) {
1136
	$iflist_prev = get_interface_list("media");
1137
	echo <<<EOD
1138

    
1139
Connect the {$ifname} interface now and make sure that the link is up.
1140
Then press ENTER to continue.
1141

    
1142
EOD;
1143
	fgets($fp);
1144
	$iflist = get_interface_list("media");
1145

    
1146
	foreach ($iflist_prev as $ifn => $ifa) {
1147
		if (!$ifa['up'] && $iflist[$ifn]['up']) {
1148
			echo "Detected link-up on interface {$ifn}.\n";
1149
			return $ifn;
1150
		}
1151
	}
1152

    
1153
	echo "No link-up detected.\n";
1154

    
1155
	return null;
1156
}
1157

    
1158
function vlan_setup() {
1159
	global $iflist, $config, $g, $fp;
1160

    
1161
	$iflist = get_interface_list();
1162

    
1163
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
1164

    
1165
	echo <<<EOD
1166

    
1167
WARNING: all existing VLANs will be cleared if you proceed!
1168

    
1169
Do you want to proceed [y|n]?
1170
EOD;
1171

    
1172
	if (strcasecmp(chop(fgets($fp)), "y") != 0)
1173
		return;
1174
	}
1175

    
1176
	$config['vlans']['vlan'] = array();
1177
	echo "\n";
1178

    
1179
	while (1) {
1180
		$vlan = array();
1181

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

    
1185
		if ($vlan['if']) {
1186
			if (!array_key_exists($vlan['if'], $iflist) or
1187
			    !is_jumbo_capable($vlan['if'])) {
1188
				echo "\nInvalid interface name '{$vlan['if']}'\n";
1189
				continue;
1190
			}
1191
		} else {
1192
			break;
1193
		}
1194

    
1195
		echo "Enter the VLAN tag (1-4094): ";
1196
		$vlan['tag'] = chop(fgets($fp));
1197

    
1198
		if (!is_numericint($vlan['tag']) || ($vlan['tag'] < 1) || ($vlan['tag'] > 4094)) {
1199
			echo "\nInvalid VLAN tag '{$vlan['tag']}'\n";
1200
			continue;
1201
		}
1202

    
1203
		$config['vlans']['vlan'][] = $vlan;
1204
	}
1205
}
1206

    
1207
function system_start_ftp_helpers() {
1208
	require_once("interfaces.inc");
1209
	global $config, $g;
1210

    
1211
	/* build an array of interfaces to work with */
1212
	$iflist = array("lan" => "LAN");
1213
	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) 
1214
		$iflist['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
1215

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

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

    
1302
        if(file_exists("{$g['cf_conf_path']}/backup/backup.cache")) {
1303
                $confvers = unserialize(file_get_contents("{$g['cf_conf_path']}/backup/backup.cache"));
1304
		$bakvers = array_keys($confvers);
1305
		$toreturn = array();
1306
		sort($bakvers);
1307
		// $bakvers = array_reverse($bakvers);
1308
		foreach(array_reverse($bakvers) as $bakver) $toreturn[] = array('time' => $bakver,
1309
								 'description' => $confvers[$bakver]['description']
1310
								);
1311
        } else { 	 
1312
                return false; 	 
1313
        }
1314
	$toreturn['versions'] = $bakvers;
1315
        return $toreturn;
1316
}
1317

    
1318
function backup_config() {
1319
	global $config, $g;
1320

    
1321
	if($g['platform'] == "cdrom")
1322
		return;
1323

    
1324
	conf_mount_rw();
1325

    
1326
	/* Create backup directory if needed */
1327
	safe_mkdir("{$g['cf_conf_path']}/backup");
1328

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

    
1355
function mute_kernel_msgs() {
1356
	exec("/sbin/conscontrol mute on");
1357
}
1358

    
1359
function unmute_kernel_msgs() {
1360
	exec("/sbin/conscontrol mute off");
1361
}
1362

    
1363
function start_devd() {
1364
	exec("/sbin/devd");
1365
}
1366

    
1367
?>
(5-5/26)