Project

General

Profile

Download (40.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", $config_contents);
73
		if (!config_validate($config_contents))
74
			log_error("ERROR!  Could not convert m0n0wall -> pfsense in config.xml");	
75
		$fd = fopen("/cf/conf/config.xml", "w");
76
		fwrite($fd, $config_contents);
77
		fclose($fd);
78
		echo "done.";
79
	}
80
}
81

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

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

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

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

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

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

    
137
					if ($cfgdevice)
138
						break;
139
				}
140
			}
141
		}
142

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

    
147

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

    
154

    
155
EOD;
156

    
157
			mwexec("/sbin/halt");
158
			exit;
159
		}
160

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

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

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

    
172
		fwrite($fd, $fstab);
173
		fclose($fd);
174
	}
175

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

    
180
$config = parse_config();
181

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

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

    
213
	/*    override some global configuration parms if they exist
214
	 *    instead of hard coding these checks into the codebase
215
         */	
216
	if($config['pptp']['n_pptp_units'])
217
		$g['n_pptp_units'] = $config['pptp']['n_pptp_units'];
218
	if($config['pptp']['pptp_subnet'])
219
		$g['pptp_subnet'] = $config['pptp']['pptp_subnet'];
220
    
221
	if($config['pppoe']['n_pppoe_units'])
222
		$g['n_pppoe_units'] = $config['pppoe']['n_pppoe_units'];
223
	if($config['pppoe']['pppoe_subnet'])
224
		$g['pppoe_subnet'] = $config['pppoe']['pppoe_subnet'];
225

    
226
	return $config;
227
}
228

    
229
/****f* config/generate_config_cache
230
 * NAME
231
 *   generate_config_cache - Write serialized configuration to cache.
232
 * INPUTS
233
 *   $config	- array containing current firewall configuration
234
 * RESULT
235
 *   boolean	- true on completion
236
 ******/
237
function generate_config_cache($config) {
238
	global $g;
239
	conf_mount_rw();
240
	$configcache = fopen($g['tmp_path'] . '/config.cache', "w");
241
	fwrite($configcache, serialize($config));
242
	fclose($configcache);
243
	conf_mount_ro();
244
	return true;
245
}
246

    
247
/****f* config/parse_config_bootup
248
 * NAME
249
 *   parse_config_bootup - Bootup-specific configuration checks.
250
 * RESULT
251
 *   null
252
 ******/
253
function parse_config_bootup() {
254
	global $config, $g, $noparseconfig;
255
	if (!$noparseconfig) {
256
		if (!file_exists("{$g['conf_path']}/config.xml")) {
257
			config_lock();
258
			if ($g['booting']) {
259
				if (strstr($g['platform'], "cdrom")) {
260
					/* try copying the default config. to the floppy */
261
					echo "Resetting factory defaults...\n";
262
					reset_factory_defaults();
263
	
264
					echo "No XML configuration file found - using factory defaults.\n";
265
					echo "Make sure that the configuration floppy disk with the conf/config.xml\n";
266
					echo "file is inserted. If it isn't, your configuration changes will be lost\n";
267
					echo "on reboot.\n";
268
				} else {
269
					echo "XML configuration file not found.  pfSense cannot continue booting.\n";
270
					mwexec("/sbin/halt");
271
					exit;
272
				}
273
			} else {
274
				config_unlock();
275
				exit(0);
276
			}
277
		}
278
	}
279

    
280
	parse_config(true);
281
	
282
	if ((float)$config['version'] > (float)$g['latest_config']) {
283
		echo <<<EOD
284

    
285

    
286
*******************************************************************************
287
* WARNING!                                                                    *
288
* The current configuration has been created with a newer version of pfSense  *
289
* than this one! This can lead to serious misbehavior and even security       *
290
* holes! You are urged to either upgrade to a newer version of pfSense or     *
291
* revert to the default configuration immediately!                            *
292
*******************************************************************************
293

    
294

    
295
EOD;
296
		}
297

    
298
	/* make alias table (for faster lookups) */
299
	alias_make_table($config);
300
	config_unlock();
301
}
302

    
303
/****f* config/conf_mount_rw
304
 * NAME
305
 *   conf_mount_rw - Mount filesystems read/write.
306
 * RESULT
307
 *   null
308
 ******/
309
/* mount flash card read/write */
310
function conf_mount_rw() {
311
	global $g;
312

    
313
	/* do not mount on cdrom platform */
314
	if($g['platform'] == "cdrom" or $g['platform'] == "pfSense")
315
		return;
316

    
317
	$status = mwexec("/sbin/umount -f {$g['cf_path']}");
318
	$status = mwexec("/sbin/mount -w {$g['cf_path']}");
319
	if($status <> 0) {
320
		mwexec("/sbin/fsck -y {$g['cf_path']}");
321
		$status = mwexec("/sbin/mount -w {$g['cf_path']}");
322
	}
323

    
324
	/*    if the platform is soekris or wrap or pfSense, lets mount the
325
	 *    compact flash cards root.
326
         */
327
	if($g['platform'] == "wrap" or $g['platform'] == "net45xx"
328
	   or $g['platform'] == "embedded") {
329
		$status = mwexec("/sbin/mount -w /");
330
		/* we could not mount this correctly.  kick off fsck */
331
		if($status <> 0) {
332
			log_error("File system is dirty.  Launching FSCK for /");
333
			mwexec("/sbin/fsck -y");
334
			$status = mwexec("/sbin/mount -w /");
335
		}
336
	}
337
	
338
	usleep(100);
339
	
340
}
341

    
342
/****f* config/conf_mount_ro
343
 * NAME         
344
 *   conf_mount_ro - Mount filesystems readonly.
345
 * RESULT
346
 *   null        
347
 ******/
348
function conf_mount_ro() {
349
	global $g;
350

    
351
	if($g['booting'] == true)
352
		return;
353
	
354
	/* do not umount if generating ssh keys */
355
	if(file_exists("/tmp/keys_generating"))
356
		return;
357
	
358
	/* do not umount on cdrom or pfSense platforms */
359
	if($g['platform'] == "cdrom" or $g['platform'] == "pfSense")
360
		return;
361

    
362
	/* sync data, then force a umount the remount of /cf */
363
	mwexec("/bin/sync");
364
	mwexec("/bin/sync");
365
	mwexec("/sbin/umount -f {$g['cf_path']}");
366
	mwexec("/sbin/mount -r {$g['cf_path']}");
367
	mwexec("/bin/sync");
368
	mwexec("/bin/sync");
369
	mwexec("/sbin/mount -r /");
370
	
371
	usleep(100);
372

    
373
}
374

    
375
/****f* config/convert_config
376
 * NAME         
377
 *   convert_config - Attempt to update config.xml.
378
 * DESCRIPTION
379
 *   convert_config() reads the current global configuration
380
 *   and attempts to convert it to conform to the latest
381
 *   config.xml version. This allows major formatting changes
382
 *   to be made with a minimum of breakage.
383
 * RESULT
384
 *   null        
385
 ******/
386
/* convert configuration, if necessary */
387
function convert_config() {
388
	global $config, $g;
389

    
390
	if ($config['version'] == $g['latest_config'])
391
		return;		/* already at latest version */
392

    
393
	// Save off config version
394
	$prev_version = $config['version'];
395

    
396
	/* convert 1.0 -> 1.1 */
397
	if ($config['version'] == "1.0") {
398
		$opti = 1;
399
		$ifmap = array('lan' => 'lan', 'wan' => 'wan', 'pptp' => 'pptp');
400

    
401
		/* convert DMZ to optional, if necessary */
402
		if (isset($config['interfaces']['dmz'])) {
403

    
404
			$dmzcfg = &$config['interfaces']['dmz'];
405

    
406
			if ($dmzcfg['if']) {
407
				$config['interfaces']['opt' . $opti] = array();
408
				$optcfg = &$config['interfaces']['opt' . $opti];
409

    
410
				$optcfg['enable'] = $dmzcfg['enable'];
411
				$optcfg['descr'] = "DMZ";
412
				$optcfg['if'] = $dmzcfg['if'];
413
				$optcfg['ipaddr'] = $dmzcfg['ipaddr'];
414
				$optcfg['subnet'] = $dmzcfg['subnet'];
415

    
416
				$ifmap['dmz'] = "opt" . $opti;
417
				$opti++;
418
			}
419

    
420
			unset($config['interfaces']['dmz']);
421
		}
422

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

    
426
			if (!$config['interfaces']['wlan' . $i]['if']) {
427
				unset($config['interfaces']['wlan' . $i]);
428
				continue;
429
			}
430

    
431
			$wlancfg = &$config['interfaces']['wlan' . $i];
432
			$config['interfaces']['opt' . $opti] = array();
433
			$optcfg = &$config['interfaces']['opt' . $opti];
434

    
435
			$optcfg['enable'] = $wlancfg['enable'];
436
			$optcfg['descr'] = "WLAN" . $i;
437
			$optcfg['if'] = $wlancfg['if'];
438
			$optcfg['ipaddr'] = $wlancfg['ipaddr'];
439
			$optcfg['subnet'] = $wlancfg['subnet'];
440
			$optcfg['bridge'] = $wlancfg['bridge'];
441

    
442
			$optcfg['wireless'] = array();
443
			$optcfg['wireless']['mode'] = $wlancfg['mode'];
444
			$optcfg['wireless']['ssid'] = $wlancfg['ssid'];
445
			$optcfg['wireless']['channel'] = $wlancfg['channel'];
446
			$optcfg['wireless']['wep'] = $wlancfg['wep'];
447

    
448
			$ifmap['wlan' . $i] = "opt" . $opti;
449

    
450
			unset($config['interfaces']['wlan' . $i]);
451
			$opti++;
452
		}
453

    
454
		/* convert filter rules */
455
		$n = count($config['filter']['rule']);
456
		for ($i = 0; $i < $n; $i++) {
457

    
458
			$fr = &$config['filter']['rule'][$i];
459

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

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

    
484
			/* remap destination network */
485
			if (isset($fr['destination']['network'])) {
486
				if (array_key_exists($fr['destination']['network'], $ifmap))
487
					$fr['destination']['network'] = $ifmap[$fr['destination']['network']];
488
				else {
489
					/* remove the rule */
490
					echo "\nWarning: filter rule removed " .
491
						"(destination network '{$fr['destination']['network']}' does not exist anymore).";
492
					unset($config['filter']['rule'][$i]);
493
					continue;
494
				}
495
			}
496
		}
497

    
498
		/* convert shaper rules */
499
		$n = count($config['pfqueueing']['rule']);
500
		if (is_array($config['pfqueueing']['rule']))
501
			for ($i = 0; $i < $n; $i++) {
502

    
503
			$fr = &$config['pfqueueing']['rule'][$i];
504

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

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

    
529
			/* remap destination network */
530
			if (isset($fr['destination']['network'])) {
531
				if (array_key_exists($fr['destination']['network'], $ifmap))
532
					$fr['destination']['network'] = $ifmap[$fr['destination']['network']];
533
				else {
534
					/* remove the rule */
535
					echo "\nWarning: traffic shaper rule removed " .
536
						"(destination network '{$fr['destination']['network']}' does not exist anymore).";
537
					unset($config['pfqueueing']['rule'][$i]);
538
					continue;
539
				}
540
			}
541
		}
542

    
543
		$config['version'] = "1.1";
544
	}
545

    
546
	/* convert 1.1 -> 1.2 */
547
	if ($config['version'] == "1.1") {
548
		/* move LAN DHCP server config */
549
		$tmp = $config['dhcpd'];
550
		$config['dhcpd'] = array();
551
		$config['dhcpd']['lan'] = $tmp;
552

    
553
		/* encrypt password */
554
		$config['system']['password'] = crypt($config['system']['password']);
555

    
556
		$config['version'] = "1.2";
557
	}
558

    
559
	/* convert 1.2 -> 1.3 */
560
	if ($config['version'] == "1.2") {
561
		/* convert advanced outbound NAT config */
562
		for ($i = 0; isset($config['nat']['advancedoutbound']['rule'][$i]); $i++) {
563
			$curent = &$config['nat']['advancedoutbound']['rule'][$i];
564
			$src = $curent['source'];
565
			$curent['source'] = array();
566
			$curent['source']['network'] = $src;
567
			$curent['destination'] = array();
568
			$curent['destination']['any'] = true;
569
		}
570

    
571
		/* add an explicit type="pass" to all filter rules to make things consistent */
572
		for ($i = 0; isset($config['filter']['rule'][$i]); $i++) {
573
			$config['filter']['rule'][$i]['type'] = "pass";
574
		}
575

    
576
		$config['version'] = "1.3";
577
	}
578

    
579
	/* convert 1.3 -> 1.4 */
580
	if ($config['version'] == "1.3") {
581
		/* convert shaper rules (make pipes) */
582
		if (is_array($config['pfqueueing']['rule'])) {
583
			$config['pfqueueing']['pipe'] = array();
584

    
585
			for ($i = 0; isset($config['pfqueueing']['rule'][$i]); $i++) {
586
				$curent = &$config['pfqueueing']['rule'][$i];
587

    
588
				/* make new pipe and associate with this rule */
589
				$newpipe = array();
590
				$newpipe['descr'] = $curent['descr'];
591
				$newpipe['bandwidth'] = $curent['bandwidth'];
592
				$newpipe['delay'] = $curent['delay'];
593
				$newpipe['mask'] = $curent['mask'];
594
				$config['pfqueueing']['pipe'][$i] = $newpipe;
595

    
596
				$curent['targetpipe'] = $i;
597

    
598
				unset($curent['bandwidth']);
599
				unset($curent['delay']);
600
				unset($curent['mask']);
601
			}
602
		}
603

    
604
		$config['version'] = "1.4";
605
	}
606

    
607
	/* Convert 1.4 -> 1.5 */
608
	if ($config['version'] == "1.4") {
609

    
610
		/* Default route moved */
611
		if (isset($config['interfaces']['wan']['gateway']))
612
			if ($config['interfaces']['wan']['gateway'] <> "")
613
				$config['interfaces']['wan']['gateway'] = $config['interfaces']['wan']['gateway'];
614
		unset($config['interfaces']['wan']['gateway']);
615

    
616
                /* Queues are no longer interface specific */
617
                if (isset($config['interfaces']['lan']['schedulertype']))
618
                        unset($config['interfaces']['lan']['schedulertype']);
619
                if (isset($config['interfaces']['wan']['schedulertype']))
620
                        unset($config['interfaces']['wan']['schedulertype']);
621

    
622
                for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
623
                        if(isset($config['interfaces']['opt' . $i]['schedulertype']))
624
                                unset($config['interfaces']['opt' . $i]['schedulertype']);
625
                }
626

    
627
		$config['version'] = "1.5";
628
	}
629

    
630
	/* Convert 1.5 -> 1.6 */
631
	if ($config['version'] == "1.5") {
632
		/* Alternate firmware URL moved */
633
		if (isset($config['system']['firmwareurl']) && isset($config['system']['firmwarename'])) { // Only convert if *both* are defined.
634
			$config['system']['alt_firmware_url'] = array();
635
			$config['system']['alt_firmware_url']['enabled'] = "";
636
			$config['system']['alt_firmware_url']['firmware_base_url'] = $config['system']['firmwareurl'];
637
			$config['system']['alt_firmware_url']['firmware_filename'] = $config['system']['firmwarename'];
638
			unset($config['system']['firmwareurl'], $config['system']['firmwarename']);
639
		} else {
640
			unset($config['system']['firmwareurl'], $config['system']['firmwarename']);
641
		}
642

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

    
713
	/* Convert 1.8 -> 1.9 */
714
	if ($config['version'] == "1.8") {
715
		$config['theme']="metallic";
716
		$config['version'] = "1.9";
717
	}
718
	/* Convert 1.9 -> 2.0 */
719
	if ($config['version'] == "1.9") {
720
		if(is_array($config['ipsec']['tunnel'])) {
721
			reset($config['ipsec']['tunnel']);
722
			while (list($index, $tunnel) = each($config['ipsec']['tunnel'])) {
723
				/* Sanity check on required variables */
724
				/* This fixes bogus <tunnel> entries - remnant of bug #393 */
725
				if (!isset($tunnel['local-subnet']) && !isset($tunnel['remote-subnet'])) {
726
					unset($config['ipsec']['tunnel'][$tunnel]);
727
				}
728
			}
729
        	}
730
		$config['version'] = "2.0";
731
	}
732
	/* Convert 2.0 -> 2.1 */
733
	if ($config['version'] == "2.0") {
734
		/* shaper scheduler moved */
735
		if(isset($config['system']['schedulertype'])) {
736
			$config['shaper']['schedulertype'] = $config['system']['schedulertype'];
737
			unset($config['system']['schedulertype']);
738
		}
739
		$config['version'] = "2.1";
740
	}
741
	/* Convert 2.1 -> 2.2 */
742
	if ($config['version'] == "2.1") {
743
		/* move gateway to wan interface */
744
		$config['interfaces']['wan']['gateway'] = $config['system']['gateway'];
745
		$config['version'] = "2.2";
746
	}
747
	/* Convert 2.2 -> 2.3 */
748
	if ($config['version'] == "2.2") {
749
		if(isset($config['shaper'])) {
750
			/* wipe previous shaper configuration */
751
			unset($config['shaper']);
752
		}
753
		$config['version'] = "2.3";
754
	}
755

    
756
	if ($prev_version != $config['version'])
757
		write_config("Upgraded config version level from {$prev_version} to {$config['version']}");
758
}
759

    
760
/****f* config/write_config
761
 * NAME
762
 *   write_config - Backup and write the firewall configuration.
763
 * DESCRIPTION
764
 *   write_config() handles backing up the current configuration,
765
 *   applying changes, and regenerating the configuration cache.
766
 * INPUTS
767
 *   $desc	- string containing the a description of configuration changes
768
 *   $backup	- boolean: do not back up current configuration if false.
769
 * RESULT
770
 *   null       
771
 ******/
772
/* save the system configuration */
773
function write_config($desc="Unknown", $backup = true) {
774
	global $config, $g;
775

    
776
	if($g['platform'] <> "embedded" and $g['platform'] <> "wrap") 
777
		if($backup) backup_config();
778

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

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

    
786
	$config['revision']['description'] = $desc;
787
	$config['revision']['time'] = $changetime;
788
	
789
	config_lock();
790

    
791
	/* generate configuration XML */
792
	$xmlconfig = dump_xml_config($config, $g['xml_rootobj']);
793

    
794
	conf_mount_rw();
795

    
796
	/* write new configuration */
797
	$fd = fopen("{$g['cf_conf_path']}/config.xml", "w");
798
	if (!$fd)
799
		die("Unable to open {$g['cf_conf_path']}/config.xml for writing in write_config()\n");
800
	fwrite($fd, $xmlconfig);
801
	fclose($fd);
802

    
803
	if($g['booting'] <> true) {
804
		conf_mount_ro();
805
	}
806

    
807
	config_unlock();
808

    
809
	// Always reparse the config after it's written - something is getting lost in serialize().
810
	$config = parse_config(true);
811
	return $config;
812
}
813

    
814
/****f* config/reset_factory_defaults
815
 * NAME
816
 *   reset_factory_defaults - Reset the system to its default configuration.
817
 * RESULT
818
 *   integer	- indicates completion
819
 ******/
820
function reset_factory_defaults() {
821
	global $g;
822

    
823
	config_lock();
824
	conf_mount_rw();
825

    
826
	/* create conf directory, if necessary */
827
	safe_mkdir("{$g['cf_conf_path']}");
828

    
829
	/* clear out /conf */
830
	$dh = opendir($g['conf_path']);
831
	while ($filename = readdir($dh)) {
832
		if (($filename != ".") && ($filename != "..")) {
833
			unlink_if_exists($g['conf_path'] . "/" . $filename);
834
		}
835
	}
836
	closedir($dh);
837

    
838
	/* copy default configuration */
839
	copy("{$g['conf_default_path']}/config.xml", "{$g['conf_path']}/config.xml");
840
	
841
	/* call the wizard */
842
	touch("/conf/trigger_initial_wizard");
843
	
844
	conf_mount_ro();
845
	config_unlock();
846

    
847
	return 0;
848
}
849

    
850
function config_restore($conffile) {
851
	global $config, $g;
852
       
853
        if (!file_exists($conffile))
854
                return 1;
855
        
856
        config_lock();
857
        conf_mount_rw();        
858
        
859
        backup_config();
860
        copy($conffile, "{$g['cf_conf_path']}/config.xml");
861
	$config = parse_config(true);
862
        write_config("Reverted to " . array_pop(explode("/", $conffile)) . ".", false);
863
        
864
        conf_mount_ro();
865
        config_unlock();
866

    
867
        return 0;
868
}
869

    
870

    
871

    
872
function config_install($conffile) {
873
        global $config, $g;
874
        
875
        if (!file_exists($conffile))
876
                return 1;
877

    
878
	if (!config_validate($conffile))
879
		return 1;
880

    
881
	if($g['booting'] == true)
882
		echo "Installing configuration...\n";
883
 
884
        config_lock();
885
        conf_mount_rw();
886

    
887
	
888
        copy($conffile, "{$g['conf_path']}/config.xml");
889

    
890
	/* unlink cache file if it exists */
891
	if(file_exists("{$g['tmp_path']}/config.cache"))
892
		unlink("{$g['tmp_path']}/config.cache");
893
  
894
        conf_mount_ro();
895
        config_unlock();
896

    
897
        return 0;
898
}
899

    
900
function config_validate($conffile) {
901

    
902
	global $g, $xmlerr;
903

    
904
	$xml_parser = xml_parser_create();
905
	
906
	if (!($fp = fopen($conffile, "r"))) {
907
		$xmlerr = "XML error: unable to open file";
908
		return false;
909
	}
910
	
911
	while ($data = fread($fp, 4096)) {
912
		if (!xml_parse($xml_parser, $data, feof($fp))) {
913
			$xmlerr = sprintf("%s at line %d",
914
						xml_error_string(xml_get_error_code($xml_parser)),
915
						xml_get_current_line_number($xml_parser));
916
			return false;
917
		}
918
	}
919
	xml_parser_free($xml_parser);
920
	
921
	fclose($fp);
922
	
923
	return true;
924
}
925

    
926
/* lock configuration file, decide that the lock file is stale after
927
   10 seconds */
928
function config_lock() {
929
	global $g, $process_lock;
930

    
931
	/* No need to continue if we're the ones holding the lock */
932
	if ($process_lock)
933
		return;
934

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

    
937
	$n = 0;
938
	while ($n < 10) {
939
		/* open the lock file in append mode to avoid race condition */
940
		if ($fd = @fopen($lockfile, "x")) {
941
			/* succeeded */
942
			$process_lock = true;
943
			fclose($fd);
944
			return;
945
		} else {
946
			/* file locked, wait and try again */
947
			$process_lock = false;
948
			sleep(1);
949
			$n++;
950
		}
951
	}
952
}
953

    
954
/* unlock configuration file */
955
function config_unlock() {
956
	global $g, $process_lock;
957

    
958
	$lockfile = "{$g['varrun_path']}/config.lock";
959
	$process_lock = false;
960

    
961
	unlink_if_exists($lockfile);
962
}
963

    
964
function set_networking_interfaces_ports() {
965
	global $noreboot;
966
	global $config;
967
	global $g;
968
	global $fp;
969

    
970
	$fp = fopen('php://stdin', 'r');
971

    
972
	$iflist = get_interface_list();
973

    
974
	echo <<<EOD
975

    
976
Valid interfaces are:
977

    
978

    
979
EOD;
980

    
981
	if(!is_array($iflist)) {
982
		echo "No interfaces found!\n";
983
	} else {
984
		foreach ($iflist as $iface => $ifa) {
985
			echo sprintf("% -8s%s%s\n", $iface, $ifa['mac'],
986
				$ifa['up'] ? "   (up)" : "");
987
		}
988
	}
989

    
990
	echo <<<EOD
991

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

    
996
Do you want to set up VLANs now [y|n]?
997
EOD;
998

    
999
	if (strcasecmp(chop(fgets($fp)), "y") == 0)
1000
		vlan_setup();
1001

    
1002
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
1003

    
1004
		echo "\n\nVLAN interfaces:\n\n";
1005
		$i = 0;
1006
		foreach ($config['vlans']['vlan'] as $vlan) {
1007

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

    
1011
			$iflist['vlan' . $i] = array();
1012
			$i++;
1013
		}
1014
	}
1015

    
1016
	echo <<<EOD
1017

    
1018
*NOTE*  pfSense requires *ATLEAST* 2 assigned interfaces to function.
1019
        If you do not have two interfaces turn off the machine until
1020
	you do.
1021

    
1022
If you do not know the names of your interfaces, you may choose to use
1023
auto-detection... In that case, disconnect all interfaces now before
1024
hitting a.   The system will then prompt you to plug in each nic to
1025
autodetect.
1026

    
1027
EOD;
1028

    
1029
	do {
1030
		echo "\nEnter the LAN interface name or 'a' for auto-detection: ";
1031
		$lanif = chop(fgets($fp));
1032
		if ($lanif === "") {
1033
			return;
1034
		}
1035

    
1036
		if ($lanif === "a")
1037
			$lanif = autodetect_interface("LAN", $fp);
1038
		else if (!array_key_exists($lanif, $iflist)) {
1039
			echo "\nInvalid interface name '{$lanif}'\n";
1040
			unset($lanif);
1041
			continue;
1042
		}
1043
	} while (!$lanif);
1044

    
1045
	do {
1046
		echo "\nEnter the WAN interface name or 'a' for auto-detection: ";
1047
		$wanif = chop(fgets($fp));
1048
		if ($wanif === "") {
1049
			return;
1050
		}
1051
		if ($wanif === "a")
1052
			$wanif = autodetect_interface("WAN", $fp);
1053
		else if (!array_key_exists($wanif, $iflist)) {
1054
			echo "\nInvalid interface name '{$wanif}'\n";
1055
			unset($wanif);
1056
			continue;
1057
		}
1058
	} while (!$wanif);
1059

    
1060
	/* optional interfaces */
1061
	$i = 0;
1062
	$optif = array();
1063

    
1064
	while (1) {
1065
		if ($optif[$i])
1066
			$i++;
1067
		$i1 = $i + 1;
1068
		echo "\nEnter the Optional {$i1} interface name or 'a' for auto-detection\n" .
1069
			"(or nothing if finished): ";
1070
		$optif[$i] = chop(fgets($fp));
1071

    
1072
		if ($optif[$i]) {
1073
			if ($optif[$i] === "a") {
1074
				$ad = autodetect_interface("Optional " . $i1, $fp);
1075
				if ($ad)
1076
					$optif[$i] = $ad;
1077
				else
1078
					unset($optif[$i]);
1079
			} else if (!array_key_exists($optif[$i], $iflist)) {
1080
				echo "\nInvalid interface name '{$optif[$i]}'\n";
1081
				unset($optif[$i]);
1082
				continue;
1083
			}
1084
		} else {
1085
			unset($optif[$i]);
1086
			break;
1087
		}
1088
	}
1089

    
1090
	/* check for double assignments */
1091
	$ifarr = array_merge(array($lanif, $wanif), $optif);
1092

    
1093
	for ($i = 0; $i < (count($ifarr)-1); $i++) {
1094
		for ($j = ($i+1); $j < count($ifarr); $j++) {
1095
			if ($ifarr[$i] == $ifarr[$j]) {
1096
				echo <<<EOD
1097

    
1098
Error: you cannot assign the same interface name twice!
1099

    
1100
EOD;
1101

    
1102
				return;
1103
			}
1104
		}
1105
	}
1106

    
1107
	echo <<<EOD
1108

    
1109
The interfaces will be assigned as follows:
1110

    
1111
LAN  -> {$lanif}
1112
WAN  -> {$wanif}
1113

    
1114
EOD;
1115

    
1116
	for ($i = 0; $i < count($optif); $i++) {
1117
		echo "OPT" . ($i+1) . " -> " . $optif[$i] . "\n";
1118
	}
1119

    
1120
echo <<<EOD
1121

    
1122
Do you want to proceed [y|n]?
1123
EOD;
1124

    
1125
	if (strcasecmp(chop(fgets($fp)), "y") == 0) {
1126

    
1127
		$config['interfaces']['lan']['if'] = $lanif;
1128
		if (preg_match($g['wireless_regex'], $lanif)) {
1129
			if (!is_array($config['interfaces']['lan']['wireless']))
1130
				$config['interfaces']['lan']['wireless'] = array();
1131
		} else {
1132
			unset($config['interfaces']['lan']['wireless']);
1133
		}
1134
		
1135
		$config['interfaces']['wan']['if'] = $wanif;
1136
		if (preg_match($g['wireless_regex'], $wanif)) {
1137
			if (!is_array($config['interfaces']['wan']['wireless']))
1138
				$config['interfaces']['wan']['wireless'] = array();
1139
		} else {
1140
			unset($config['interfaces']['wan']['wireless']);
1141
		}
1142
		
1143
		for ($i = 0; $i < count($optif); $i++) {
1144
			if (!is_array($config['interfaces']['opt' . ($i+1)]))
1145
				$config['interfaces']['opt' . ($i+1)] = array();
1146
			
1147
			$config['interfaces']['opt' . ($i+1)]['if'] = $optif[$i];
1148
			
1149
			/* wireless interface? */
1150
			if (preg_match($g['wireless_regex'], $optif[$i])) {
1151
				if (!is_array($config['interfaces']['opt' . ($i+1)]['wireless']))
1152
					$config['interfaces']['opt' . ($i+1)]['wireless'] = array();
1153
			} else {
1154
				unset($config['interfaces']['opt' . ($i+1)]['wireless']);
1155
			}
1156
			
1157
			unset($config['interfaces']['opt' . ($i+1)]['enable']);
1158
			$config['interfaces']['opt' . ($i+1)]['descr'] = "OPT" . ($i+1);
1159
		}
1160
		
1161
		/* remove all other (old) optional interfaces */
1162
		for (; isset($config['interfaces']['opt' . ($i+1)]); $i++)
1163
			unset($config['interfaces']['opt' . ($i+1)]);
1164
		
1165
		write_config();
1166
		
1167
		echo <<<EOD
1168

    
1169

    
1170

    
1171
EOD;
1172

    
1173
		if($g['booting'])
1174
			return;
1175

    
1176
		echo "One moment while we reload the settings...";
1177

    
1178
		/* resync everything */
1179
		reload_all_sync();
1180
		
1181
		echo " done!\n";
1182
		
1183
		touch("{$g['tmp_path']}/assign_complete");
1184

    
1185
	}
1186
}
1187

    
1188
function autodetect_interface($ifname, $fp) {
1189
	$iflist_prev = get_interface_list("media");
1190
	echo <<<EOD
1191

    
1192
Connect the {$ifname} interface now and make sure that the link is up.
1193
Then press ENTER to continue.
1194

    
1195
EOD;
1196
	fgets($fp);
1197
	$iflist = get_interface_list("media");
1198

    
1199
	foreach ($iflist_prev as $ifn => $ifa) {
1200
		if (!$ifa['up'] && $iflist[$ifn]['up']) {
1201
			echo "Detected link-up on interface {$ifn}.\n";
1202
			return $ifn;
1203
		}
1204
	}
1205

    
1206
	echo "No link-up detected.\n";
1207

    
1208
	return null;
1209
}
1210

    
1211
function vlan_setup() {
1212
	global $iflist, $config, $g, $fp;
1213

    
1214
	$iflist = get_interface_list();
1215

    
1216
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
1217

    
1218
	echo <<<EOD
1219

    
1220
WARNING: all existing VLANs will be cleared if you proceed!
1221

    
1222
Do you want to proceed [y|n]?
1223
EOD;
1224

    
1225
	if (strcasecmp(chop(fgets($fp)), "y") != 0)
1226
		return;
1227
	}
1228

    
1229
	$config['vlans']['vlan'] = array();
1230
	echo "\n";
1231

    
1232
	while (1) {
1233
		$vlan = array();
1234

    
1235
		echo "\n\nVLAN Capable interfaces:\n\n";
1236
		if(!is_array($iflist)) {
1237
			echo "No interfaces found!\n";
1238
		} else {
1239
			$vlan_capable=0;
1240
			foreach ($iflist as $iface => $ifa) {
1241
				if (is_jumbo_capable($iface)) {
1242
					echo sprintf("% -8s%s%s\n", $iface, $ifa['mac'],
1243
						$ifa['up'] ? "   (up)" : "");
1244
					$vlan_capable++;
1245
				}
1246
			}
1247
		}
1248

    
1249
		if($vlan_capable == 0) {
1250
			echo "No VLAN capable interfaces detected.\n";
1251
			return;
1252
		}
1253

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

    
1257
		if ($vlan['if']) {
1258
			if (!array_key_exists($vlan['if'], $iflist) or
1259
			    !is_jumbo_capable($vlan['if'])) {
1260
				echo "\nInvalid interface name '{$vlan['if']}'\n";
1261
				continue;
1262
			}
1263
		} else {
1264
			break;
1265
		}
1266

    
1267
		echo "Enter the VLAN tag (1-4094): ";
1268
		$vlan['tag'] = chop(fgets($fp));
1269

    
1270
		if (!is_numericint($vlan['tag']) || ($vlan['tag'] < 1) || ($vlan['tag'] > 4094)) {
1271
			echo "\nInvalid VLAN tag '{$vlan['tag']}'\n";
1272
			continue;
1273
		}
1274

    
1275
		$config['vlans']['vlan'][] = $vlan;
1276
	}
1277
}
1278

    
1279
function system_start_ftp_helpers() {
1280
	require_once("interfaces.inc");
1281
	global $config, $g;
1282

    
1283
	/* build an array of interfaces to work with */
1284
	$iflist = array("lan" => "LAN");
1285
	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) 
1286
		$iflist['opt' . $i] = "opt{$i}";
1287

    
1288
	/* loop through all interfaces and handle pftpx */
1289
	$interface_counter = 0;
1290
	foreach ($iflist as $ifent => $ifname) {
1291
		/*    if the ftp proxy is disabled for this interface then kill pftpx 
1292
		 *    instance and continue. note that the helpers for port forwards are 
1293
		 *    launched in a  different sequence so we are filtering them out 
1294
                 *    here by not including -c {$port} -g 8021 first.
1295
		 */
1296
		$port = 8021 + $interface_counter;
1297
		if(isset($config['interfaces'][$ifname]['disableftpproxy'])) {
1298
			/*    item is disabled.  lets ++ the interface counter and
1299
			 *    keep processing interfaces. kill pftpx if already
1300
                         *    running for this instance.
1301
                         */
1302
			$helpers = exec("/bin/ps awux | grep \"/usr/local/sbin/pftpx -c {$port}\" | grep -v grep | sed \"s/  */ /g\" | cut -f2 -d\" \"");
1303
			if($helpers)
1304
				mwexec("/bin/kill {$helpers}");
1305
			$interface_counter++;
1306
		} else {
1307
			/* grab the current interface IP address */
1308
			$int = convert_friendly_interface_to_real_interface_name($ifname);
1309
			$ip = find_interface_ip($int);
1310
			/* if pftpx is already running then do not launch it again */
1311
			$helpers = exec("/bin/ps awux | grep \"/usr/local/sbin/pftpx -c {$port}\" | grep -v grep | sed \"s/  */ /g\"");
1312
			if(!$helpers && $ip)
1313
 				mwexec("/usr/local/sbin/pftpx -c {$port} -g 8021 {$ip}");
1314
			$interface_counter++;
1315
		}
1316
	}
1317
}
1318

    
1319
function cleanup_backupcache($revisions = 30) {
1320
	global $g;
1321
	$i = false;
1322
	if(file_exists($g['cf_conf_path'] . '/backup/backup.cache')) {
1323
		conf_mount_rw();
1324
		$backups = get_backups();
1325
		$newbaks = array();
1326
		$bakfiles = glob($g['cf_conf_path'] . "/backup/config-*");
1327
		$baktimes = $backups['versions'];
1328
		$tocache = array();
1329
		unset($backups['versions']);
1330
       		foreach($bakfiles as $backup) { // Check for backups in the directory not represented in the cache.
1331
			$tocheck = array_shift(explode('.', array_pop(explode('-', $backup))));	
1332
                	if(!in_array($tocheck, $baktimes)) {
1333
				$i = true;
1334
				if($g['booting']) print " " . $tocheck . "a";
1335
				$newxml = parse_xml_config($backup, $g['xml_rootobj']);
1336
				if($newxml['revision']['description'] == "") $newxml['revision']['description'] = "Unknown";
1337
				$tocache[$tocheck] = array('description' => $newxml['revision']['description']);
1338
			}
1339
        	}
1340
		foreach($backups as $checkbak) {
1341
			if(count(preg_grep('/' . $checkbak['time'] . '/i', $bakfiles)) != 0) {
1342
				$newbaks[] = $checkbak;
1343
			} else {
1344
				$i = true;
1345
				if($g['booting']) print " " . $tocheck . "r";
1346
			}
1347
		}
1348
		foreach($newbaks as $todo) $tocache[$todo['time']] = array('description' => $todo['description']);	
1349
		if(is_int($revisions) and (count($tocache) > $revisions)) {
1350
			$toslice = array_slice(array_keys($tocache), 0, $revisions);
1351
			foreach($toslice as $sliced) $newcache[$sliced] = $tocache[$sliced];
1352
			foreach($tocache as $version => $versioninfo) {
1353
				if(!in_array($version, array_keys($newcache))) {
1354
					unlink_if_exists($g['conf_path'] . '/backup/config-' . $version . '.xml');
1355
					if($g['booting']) print " " . $tocheck . "d";
1356
				}
1357
			}
1358
			$tocache = $newcache;
1359
		}
1360
		$bakout = fopen($g['cf_conf_path'] . '/backup/backup.cache', "w");
1361
        	fwrite($bakout, serialize($tocache));
1362
  	        fclose($bakout);
1363
		conf_mount_ro();
1364
	}
1365
	if($g['booting']) {
1366
		if($i) {
1367
			print "done.\n";
1368
		}
1369
	}
1370
}
1371
  	 
1372
function get_backups() { 	 
1373
	global $g;
1374

    
1375
        if(file_exists("{$g['cf_conf_path']}/backup/backup.cache")) {
1376
                $confvers = unserialize(file_get_contents("{$g['cf_conf_path']}/backup/backup.cache"));
1377
		$bakvers = array_keys($confvers);
1378
		$toreturn = array();
1379
		sort($bakvers);
1380
		// $bakvers = array_reverse($bakvers);
1381
		foreach(array_reverse($bakvers) as $bakver) $toreturn[] = array('time' => $bakver,
1382
								 'description' => $confvers[$bakver]['description']
1383
								);
1384
        } else { 	 
1385
                return false; 	 
1386
        }
1387
	$toreturn['versions'] = $bakvers;
1388
        return $toreturn;
1389
}
1390

    
1391
function backup_config() {
1392
	global $config, $g;
1393

    
1394
	if($g['platform'] == "cdrom")
1395
		return;
1396

    
1397
	conf_mount_rw();
1398

    
1399
	/* Create backup directory if needed */
1400
	safe_mkdir("{$g['cf_conf_path']}/backup");
1401

    
1402
        if($config['revision']['time'] == "") {
1403
                $baktime = 0;
1404
        } else {
1405
                $baktime = $config['revision']['time'];
1406
        }
1407
        if($config['revision']['description'] == "") {
1408
                $bakdesc = "Unknown";
1409
        } else {
1410
                $bakdesc = $config['revision']['description'];
1411
        }
1412
        copy($g['cf_conf_path'] . '/config.xml', $g['cf_conf_path'] . '/backup/config-' . $baktime . '.xml');
1413
        if(file_exists($g['cf_conf_path'] . '/backup/backup.cache')) {
1414
                $backupcache = unserialize(file_get_contents($g['cf_conf_path'] . '/backup/backup.cache'));
1415
        } else {
1416
                $backupcache = array();
1417
        }
1418
        $backupcache[$baktime] = array('description' => $bakdesc);
1419
        $bakout = fopen($g['cf_conf_path'] . '/backup/backup.cache', "w");
1420
        fwrite($bakout, serialize($backupcache));
1421
        fclose($bakout);
1422
	
1423
	conf_mount_ro();
1424
	
1425
	return true;
1426
}
1427

    
1428
function mute_kernel_msgs() {
1429
	exec("/sbin/conscontrol mute on");
1430
}
1431

    
1432
function unmute_kernel_msgs() {
1433
	exec("/sbin/conscontrol mute off");
1434
}
1435

    
1436
function start_devd() {
1437
	exec("/sbin/devd");
1438
	sleep(1);
1439
	if(file_exists("/tmp/rc.linkup"))
1440
		unlink("/tmp/rc.linkup");	
1441
}
1442

    
1443
?>
(5-5/27)