Project

General

Profile

Download (28.9 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	config.inc
5
	Copyright (C) 2004 Scott Ullrich
6
	All rights reserved.
7

    
8
	originally part of m0n0wall (http://m0n0.ch/wall)
9
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
10
	All rights reserved.
11

    
12
	Redistribution and use in source and binary forms, with or without
13
	modification, are permitted provided that the following conditions are met:
14

    
15
	1. Redistributions of source code must retain the above copyright notice,
16
	   this list of conditions and the following disclaimer.
17

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

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

    
34
/* include globals/utility/XML parser files */
35
require_once("globals.inc");
36
require_once("util.inc");
37
require_once("pfsense-utils.inc");
38
require_once("xmlparse.inc");
39

    
40
/* read platform */
41
if (file_exists("{$g['etc_path']}/platform")) {
42
	$g['platform'] = chop(file_get_contents("{$g['etc_path']}/platform"));
43
} else {
44
	$g['platform'] = "unknown";
45
}
46

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

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

    
55
		if (strstr($g['platform'], "cdrom")) {
56
			/* config is on floppy disk for CD-ROM version */
57
			$cfgdevice = $cfgpartition = "fd0";
58
			$dmesg = `dmesg -a`;
59
			if(ereg("da0", $desg) == true) {
60
				$cfgdevice = $cfgpartition = "da0" ;
61
				if (mwexec("/sbin/mount -r da0 /cf") <> 0) {
62
					/* could not mount, fallback to floppy */
63
					$cfgdevice = $cfgpartition = "fd0";
64
				}
65
			}
66
			$cfgfstype = "msdos";
67
		} else {
68
			/* probe kernel known disks until we find one with config.xml */
69
			$disks = explode(" ", trim(preg_replace("/kern.disks: /", "", exec("/sbin/sysctl kern.disks"))));
70
			foreach ($disks as $mountdisk) {
71
				/* skip mfs mounted filesystems */
72
				if (strstr($mountdisk, "md"))
73
					continue;
74
				if (mwexec("/sbin/mount -r /dev/{$mountdisk}a {$g['cf_path']}") == 0) {
75
					if (file_exists("{$g['cf_conf_path']}/config.xml")) {
76
						/* found it */
77
						$cfgdevice = $mountdisk;
78
						$cfgpartition = $cfgdevice . "a";
79
						$cfgfstype = "ufs";
80
						echo "Found configuration on $cfgdevice.\n";
81
					}
82

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

    
85
					if ($cfgdevice)
86
						break;
87
				}
88
				if (mwexec("/sbin/mount -r /dev/{$mountdisk}d {$g['cf_path']}") == 0) {
89
					if (file_exists("{$g['cf_conf_path']}/config.xml")) {
90
						/* found it */
91
						$cfgdevice = $mountdisk;
92
						$cfgpartition = $cfgdevice . "d";
93
						$cfgfstype = "ufs";
94
						echo "Found configuration on $cfgdevice.\n";
95
					}
96

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

    
99
					if ($cfgdevice)
100
						break;
101
				}
102
			}
103
		}
104

    
105
		if (!$cfgdevice) {
106
			/* no device found, print an error and die */
107
			echo <<<EOD
108

    
109

    
110
*******************************************************************************
111
* FATAL ERROR                                                                 *
112
* The device that contains the configuration file (config.xml) could not be   *
113
* found. pfSense cannot continue booting.                                     *
114
*******************************************************************************
115

    
116

    
117
EOD;
118

    
119
			mwexec("/sbin/halt");
120
			exit;
121
		}
122

    
123
		/* write device name to a file for rc.firmware */
124
		$fd = fopen("{$g['varetc_path']}/cfdevice", "w");
125
		fwrite($fd, $cfgdevice . "\n");
126
		fclose($fd);
127

    
128
		/* write out an fstab */
129
		$fd = fopen("{$g['etc_path']}/fstab", "w");
130

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

    
134
		fwrite($fd, $fstab);
135
		fclose($fd);
136
	}
137

    
138
	/* mount all filesystems */
139
	mwexec("/sbin/mount -a");
140
}
141

    
142
if(!$g['booting']) {
143
	$config = parse_config();
144
}
145

    
146
function parse_config($parse = false) {
147
	global $g;
148

    
149
	config_lock();
150
	if(!$parse) {
151
		if(file_exists($g['tmp_path'] . '/config.cache')) {
152
			$config = unserialize(file_get_contents($g['tmp_path'] . '/config.cache'));
153
			if(is_null($config)) {
154
				config_unlock();
155
				parse_config(true);
156
			}
157
		} else {
158
			config_unlock();
159
			$config = parse_config(true);
160
		}
161
	} else {
162
		$config = parse_xml_config($g['conf_path'] . '/config.xml', $g['xml_rootobj']);
163
		generate_config_cache($config);
164
	}
165
	config_unlock();
166
	return $config;
167
}
168

    
169
function generate_config_cache($config) {
170
	global $g;
171
	$configcache = fopen($g['tmp_path'] . '/config.cache', "w");
172
	fwrite($configcache, serialize($config));
173
	fclose($configcache);
174
	return true;
175
}
176

    
177
function parse_config_bootup() {
178
	global $config, $g;
179
	if (!$noparseconfig) {
180
		if (!file_exists("{$g['conf_path']}/config.xml")) {
181
			config_lock();
182
			if ($g['booting']) {
183
				if (strstr($g['platform'], "cdrom")) {
184
					/* try copying the default config. to the floppy */
185
					reset_factory_defaults();
186
	
187
					echo "No XML configuration file found - using factory defaults.\n";
188
					echo "Make sure that the configuration floppy disk with the conf/config.xml\n";
189
					echo "file is inserted. If it isn't, your configuration changes will be lost\n";
190
					echo "on reboot.\n";
191
				} else {
192
					echo "XML configuration file not found.  pfSense cannot continue booting.\n";
193
					mwexec("/sbin/halt");
194
					exit;
195
				}
196
			} else {
197
				config_unlock();
198
				exit(0);
199
			}
200
		}
201
	}
202

    
203
	parse_config(true);
204
	
205
	if ((float)$config['version'] > (float)$g['latest_config']) {
206
		echo <<<EOD
207

    
208

    
209
*******************************************************************************
210
* WARNING!                                                                    *
211
* The current configuration has been created with a newer version of pfSense  *
212
* than this one! This can lead to serious misbehavior and even security       *
213
* holes! You are urged to either upgrade to a newer version of pfSense or     *
214
* revert to the default configuration immediately!                            *
215
*******************************************************************************
216

    
217

    
218
EOD;
219
		}
220

    
221
	/* make alias table (for faster lookups) */
222
	alias_make_table();
223
	config_unlock();
224
}
225

    
226
/* mount flash card read/write */
227
function conf_mount_rw() {
228
	global $g;
229

    
230
	/* don't use mount -u anymore
231
	   (doesn't sync the files properly and /bin/sync won't help either) */
232
	mwexec("/sbin/umount -f {$g['cf_path']}");
233
	$status = mwexec("/sbin/mount -w -o noatime {$g['cf_path']}");
234
	while($status == -1) {
235
		mwexec("fsck -y");
236
		$status = mwexec("/sbin/mount -w -o noatime {$g['cf_path']}");
237
	}
238
	/* if the platform is soekris or wrap, lets mount the
239
	   compact flash card. */
240
	if($g['platform'] == "wrap" or $g['platform'] == "net45xx") {
241
		mwexec("/sbin/umount -f {$g['embeddedbootupslice']}");
242
		mwexec("/sbin/mount -w {$g['embeddedbootupslice']}");
243
	}
244
}
245

    
246
/* mount flash card read only */
247
function conf_mount_ro() {
248
	global $g;
249

    
250
	mwexec("/sbin/umount -f {$g['cf_path']}");
251
	mwexec("/sbin/mount -r {$g['cf_path']}");
252
	/* if the platform is soekris or wrap, lets unmount the
253
	   compact flash card. */
254
	if($g['platform'] == "wrap" or $g['platform'] == "net45xx") {
255
		mwexec("/sbin/umount -f {$g['embeddedbootupslice']}");
256
		mwexec("/sbin/mount -r {$g['embeddedbootupslice']}");
257
	}
258
}
259

    
260
/* convert configuration, if necessary */
261
function convert_config() {
262
	global $config, $pkg_config, $g;
263

    
264
	if ($config['version'] == $g['latest_config'])
265
		return;		/* already at latest version */
266

    
267
	// Save off config version
268
	$prev_version = $config['version'];
269

    
270
	/* convert 1.0 -> 1.1 */
271
	if ($config['version'] == "1.0") {
272
		$opti = 1;
273
		$ifmap = array('lan' => 'lan', 'wan' => 'wan', 'pptp' => 'pptp');
274

    
275
		/* convert DMZ to optional, if necessary */
276
		if (isset($config['interfaces']['dmz'])) {
277

    
278
			$dmzcfg = &$config['interfaces']['dmz'];
279

    
280
			if ($dmzcfg['if']) {
281
				$config['interfaces']['opt' . $opti] = array();
282
				$optcfg = &$config['interfaces']['opt' . $opti];
283

    
284
				$optcfg['enable'] = $dmzcfg['enable'];
285
				$optcfg['descr'] = "DMZ";
286
				$optcfg['if'] = $dmzcfg['if'];
287
				$optcfg['ipaddr'] = $dmzcfg['ipaddr'];
288
				$optcfg['subnet'] = $dmzcfg['subnet'];
289

    
290
				$ifmap['dmz'] = "opt" . $opti;
291
				$opti++;
292
			}
293

    
294
			unset($config['interfaces']['dmz']);
295
		}
296

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

    
300
			if (!$config['interfaces']['wlan' . $i]['if']) {
301
				unset($config['interfaces']['wlan' . $i]);
302
				continue;
303
			}
304

    
305
			$wlancfg = &$config['interfaces']['wlan' . $i];
306
			$config['interfaces']['opt' . $opti] = array();
307
			$optcfg = &$config['interfaces']['opt' . $opti];
308

    
309
			$optcfg['enable'] = $wlancfg['enable'];
310
			$optcfg['descr'] = "WLAN" . $i;
311
			$optcfg['if'] = $wlancfg['if'];
312
			$optcfg['ipaddr'] = $wlancfg['ipaddr'];
313
			$optcfg['subnet'] = $wlancfg['subnet'];
314
			$optcfg['bridge'] = $wlancfg['bridge'];
315

    
316
			$optcfg['wireless'] = array();
317
			$optcfg['wireless']['mode'] = $wlancfg['mode'];
318
			$optcfg['wireless']['ssid'] = $wlancfg['ssid'];
319
			$optcfg['wireless']['channel'] = $wlancfg['channel'];
320
			$optcfg['wireless']['wep'] = $wlancfg['wep'];
321

    
322
			$ifmap['wlan' . $i] = "opt" . $opti;
323

    
324
			unset($config['interfaces']['wlan' . $i]);
325
			$opti++;
326
		}
327

    
328
		/* convert filter rules */
329
		$n = count($config['filter']['rule']);
330
		for ($i = 0; $i < $n; $i++) {
331

    
332
			$fr = &$config['filter']['rule'][$i];
333

    
334
			/* remap interface */
335
			if (array_key_exists($fr['interface'], $ifmap))
336
				$fr['interface'] = $ifmap[$fr['interface']];
337
			else {
338
				/* remove the rule */
339
				echo "\nWarning: filter rule removed " .
340
					"(interface '{$fr['interface']}' does not exist anymore).";
341
				unset($config['filter']['rule'][$i]);
342
				continue;
343
			}
344

    
345
			/* remap source network */
346
			if (isset($fr['source']['network'])) {
347
				if (array_key_exists($fr['source']['network'], $ifmap))
348
					$fr['source']['network'] = $ifmap[$fr['source']['network']];
349
				else {
350
					/* remove the rule */
351
					echo "\nWarning: filter rule removed " .
352
						"(source network '{$fr['source']['network']}' does not exist anymore).";
353
					unset($config['filter']['rule'][$i]);
354
					continue;
355
				}
356
			}
357

    
358
			/* remap destination network */
359
			if (isset($fr['destination']['network'])) {
360
				if (array_key_exists($fr['destination']['network'], $ifmap))
361
					$fr['destination']['network'] = $ifmap[$fr['destination']['network']];
362
				else {
363
					/* remove the rule */
364
					echo "\nWarning: filter rule removed " .
365
						"(destination network '{$fr['destination']['network']}' does not exist anymore).";
366
					unset($config['filter']['rule'][$i]);
367
					continue;
368
				}
369
			}
370
		}
371

    
372
		/* convert shaper rules */
373
		$n = count($config['pfqueueing']['rule']);
374
		if (is_array($config['pfqueueing']['rule']))
375
			for ($i = 0; $i < $n; $i++) {
376

    
377
			$fr = &$config['pfqueueing']['rule'][$i];
378

    
379
			/* remap interface */
380
			if (array_key_exists($fr['interface'], $ifmap))
381
				$fr['interface'] = $ifmap[$fr['interface']];
382
			else {
383
				/* remove the rule */
384
				echo "\nWarning: traffic shaper rule removed " .
385
					"(interface '{$fr['interface']}' does not exist anymore).";
386
				unset($config['pfqueueing']['rule'][$i]);
387
				continue;
388
			}
389

    
390
			/* remap source network */
391
			if (isset($fr['source']['network'])) {
392
				if (array_key_exists($fr['source']['network'], $ifmap))
393
					$fr['source']['network'] = $ifmap[$fr['source']['network']];
394
				else {
395
					/* remove the rule */
396
					echo "\nWarning: traffic shaper rule removed " .
397
						"(source network '{$fr['source']['network']}' does not exist anymore).";
398
					unset($config['pfqueueing']['rule'][$i]);
399
					continue;
400
				}
401
			}
402

    
403
			/* remap destination network */
404
			if (isset($fr['destination']['network'])) {
405
				if (array_key_exists($fr['destination']['network'], $ifmap))
406
					$fr['destination']['network'] = $ifmap[$fr['destination']['network']];
407
				else {
408
					/* remove the rule */
409
					echo "\nWarning: traffic shaper rule removed " .
410
						"(destination network '{$fr['destination']['network']}' does not exist anymore).";
411
					unset($config['pfqueueing']['rule'][$i]);
412
					continue;
413
				}
414
			}
415
		}
416

    
417
		$config['version'] = "1.1";
418
	}
419

    
420
	/* convert 1.1 -> 1.2 */
421
	if ($config['version'] == "1.1") {
422
		/* move LAN DHCP server config */
423
		$tmp = $config['dhcpd'];
424
		$config['dhcpd'] = array();
425
		$config['dhcpd']['lan'] = $tmp;
426

    
427
		/* encrypt password */
428
		$config['system']['password'] = crypt($config['system']['password']);
429

    
430
		$config['version'] = "1.2";
431
	}
432

    
433
	/* convert 1.2 -> 1.3 */
434
	if ($config['version'] == "1.2") {
435
		/* convert advanced outbound NAT config */
436
		for ($i = 0; isset($config['nat']['advancedoutbound']['rule'][$i]); $i++) {
437
			$curent = &$config['nat']['advancedoutbound']['rule'][$i];
438
			$src = $curent['source'];
439
			$curent['source'] = array();
440
			$curent['source']['network'] = $src;
441
			$curent['destination'] = array();
442
			$curent['destination']['any'] = true;
443
		}
444

    
445
		/* add an explicit type="pass" to all filter rules to make things consistent */
446
		for ($i = 0; isset($config['filter']['rule'][$i]); $i++) {
447
			$config['filter']['rule'][$i]['type'] = "pass";
448
		}
449

    
450
		$config['version'] = "1.3";
451
	}
452

    
453
	/* convert 1.3 -> 1.4 */
454
	if ($config['version'] == "1.3") {
455
		/* convert shaper rules (make pipes) */
456
		if (is_array($config['pfqueueing']['rule'])) {
457
			$config['pfqueueing']['pipe'] = array();
458

    
459
			for ($i = 0; isset($config['pfqueueing']['rule'][$i]); $i++) {
460
				$curent = &$config['pfqueueing']['rule'][$i];
461

    
462
				/* make new pipe and associate with this rule */
463
				$newpipe = array();
464
				$newpipe['descr'] = $curent['descr'];
465
				$newpipe['bandwidth'] = $curent['bandwidth'];
466
				$newpipe['delay'] = $curent['delay'];
467
				$newpipe['mask'] = $curent['mask'];
468
				$config['pfqueueing']['pipe'][$i] = $newpipe;
469

    
470
				$curent['targetpipe'] = $i;
471

    
472
				unset($curent['bandwidth']);
473
				unset($curent['delay']);
474
				unset($curent['mask']);
475
			}
476
		}
477

    
478
		$config['version'] = "1.4";
479
	}
480

    
481
	/* Convert 1.4 -> 1.5 */
482
	if ($config['version'] == "1.4") {
483

    
484
		/* Default route moved */
485
		if (isset($config['interfaces']['wan']['gateway']))
486
			if ($config['interfaces']['wan']['gateway'] <> "")
487
				$config['system']['gateway'] = $config['interfaces']['wan']['gateway'];
488
		unset($config['interfaces']['wan']['gateway']);
489

    
490
                /* Queues are no longer interface specific */
491
                if (isset($config['interfaces']['lan']['schedulertype']))
492
                        unset($config['interfaces']['lan']['schedulertype']);
493
                if (isset($config['interfaces']['wan']['schedulertype']))
494
                        unset($config['interfaces']['wan']['schedulertype']);
495

    
496
                for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
497
                        if(isset($config['interfaces']['opt' . $i]['schedulertype']))
498
                                unset($config['interfaces']['opt' . $i]['schedulertype']);
499
                }
500

    
501
		$config['version'] = "1.5";
502
	}
503

    
504
	/* Convert 1.5 -> 1.6 */
505
	if ($config['version'] == "1.5") {
506
		/* Alternate firmware URL moved */
507
		if (isset($config['system']['firmwareurl']) && isset($config['system']['firmwarename'])) { // Only convert if *both* are defined.
508
			$config['system']['alt_firmware_url'] = array();
509
			$config['system']['alt_firmware_url']['enabled'] = "";
510
			$config['system']['alt_firmware_url']['firmware_base_url'] = $config['system']['firmwareurl'];
511
			$config['system']['alt_firmware_url']['firmware_filename'] = $config['system']['firmwarename'];
512
			unset($config['system']['firmwareurl'], $config['system']['firmwarename']);
513
		} else {
514
			unset($config['system']['firmwareurl'], $config['system']['firmwarename']);
515
		}
516

    
517
		$config['version'] = "1.6";
518
	}
519

    
520
	if ($prev_version != $config['version'])
521
		write_config("Upgraded config version level from {$prev_version} to {$config['version']}");
522
}
523

    
524
/* save the system configuration */
525
function write_config($desc="Unknown", $backup = true) {
526
	global $config, $g;
527

    
528
	if($backup) backup_config();
529

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

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

    
537
	$config['revision']['description'] = $desc;
538
	$config['revision']['time'] = $changetime;
539
	
540
	config_lock();
541
	conf_mount_rw();
542

    
543
	/* generate configuration XML */
544
	$xmlconfig = dump_xml_config($config, $g['xml_rootobj']);
545

    
546
	/* write new configuration */
547
	$fd = fopen("{$g['cf_conf_path']}/config.xml", "w");
548
	if (!$fd)
549
		die("Unable to open {$g['cf_conf_path']}/config.xml for writing in write_config()\n");
550
	fwrite($fd, $xmlconfig);
551
	fclose($fd);
552

    
553
	conf_mount_ro();
554
	config_unlock();
555

    
556
	generate_config_cache($config);
557
	//cleanup_backupcache();
558
}
559

    
560
function reset_factory_defaults() {
561

    
562
	global $g;
563

    
564
	config_lock();
565

    
566
	conf_mount_rw();
567

    
568
	/* create conf directory, if necessary */
569
	if (!file_exists("{$g['cf_conf_path']}"))
570
		@mkdir("{$g['cf_conf_path']}");
571

    
572
	/* clear out /conf */
573
	$dh = opendir($g['conf_path']);
574
	while ($filename = readdir($dh)) {
575
		if (($filename != ".") && ($filename != "..")) {
576
			unlink($g['conf_path'] . "/" . $filename);
577
		}
578
	}
579
	closedir($dh);
580

    
581
	/* copy default configuration */
582
	@copy("{$g['conf_default_path']}/config.xml", "{$g['conf_path']}/config.xml");
583

    
584
	conf_mount_ro();
585

    
586
	config_unlock();
587

    
588
	return 0;
589
}
590

    
591
function config_restore($conffile) {
592
	global $config, $g;
593
        
594
        if (!file_exists($conffile))
595
                return 1;
596
        
597
        config_lock();
598
        conf_mount_rw();        
599
        
600
        backup_config();
601
        copy($conffile, "{$g['conf_path']}/config.xml");
602
        write_config("Reverted to " . array_pop(explode("/", $conffile)) . ".", false);
603
        $config = parse_config(true);
604
        
605
        conf_mount_ro();
606
        config_unlock();
607

    
608
        return 0;
609
}
610

    
611

    
612

    
613
function config_install($conffile) {
614
        global $config, $g;
615
        
616
        if (!file_exists($conffile))
617
                return 1;
618
 
619
        config_lock();
620
        conf_mount_rw();
621
        
622
        copy($conffile, "{$g['conf_path']}/config.xml");
623
                
624
        conf_mount_ro();
625
        config_unlock();
626

    
627
        return 0;
628
}
629

    
630
/* lock configuration file, decide that the lock file is stale after
631
   10 seconds */
632
function config_lock() {
633

    
634
	global $g;
635

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

    
638
	$n = 0;
639
	while ($n < 10) {
640
		/* open the lock file in append mode to avoid race condition */
641
		if ($fd = @fopen($lockfile, "x")) {
642
			/* succeeded */
643
			fclose($fd);
644
			return;
645
		} else {
646
			/* file locked, wait and try again */
647
			sleep(1);
648
			$n++;
649
		}
650
	}
651
}
652

    
653
/* unlock configuration file */
654
function config_unlock() {
655

    
656
	global $g;
657

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

    
660
	if (file_exists($lockfile))
661
		unlink($lockfile);
662
}
663

    
664
function set_networking_interfaces_ports() {
665
	global $noreboot;
666
	global $config;
667
	global $g;
668
	global $fp;
669

    
670
	$fp = fopen('php://stdin', 'r');
671

    
672
	$iflist = get_interface_list();
673

    
674
	echo <<<EOD
675

    
676
Valid interfaces are:
677

    
678

    
679
EOD;
680

    
681
	foreach ($iflist as $iface => $ifa) {
682
		echo sprintf("% -8s%s%s\n", $iface, $ifa['mac'],
683
			$ifa['up'] ? "   (up)" : "");
684
	}
685

    
686
	echo <<<EOD
687

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

    
692
Do you want to set up VLANs now [y|n]?
693
EOD;
694

    
695
	if (strcasecmp(chop(fgets($fp)), "y") == 0)
696
		vlan_setup();
697

    
698
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
699

    
700
		echo "\n\nVLAN interfaces:\n\n";
701
		$i = 0;
702
		foreach ($config['vlans']['vlan'] as $vlan) {
703

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

    
707
			$iflist['vlan' . $i] = array();
708
			$i++;
709
		}
710
	}
711

    
712
	echo <<<EOD
713

    
714
If you do not know the names of your interfaces, you may choose to use
715
auto-detection. In that case, disconnect all interfaces before you begin,
716
and reconnect each one when prompted to do so.
717

    
718
EOD;
719

    
720
	do {
721
		echo "\nEnter the LAN interface name or 'a' for auto-detection: ";
722
		$lanif = chop(fgets($fp));
723
		if ($lanif === "") {
724
			exit(0);
725
		}
726

    
727
		if ($lanif === "a")
728
			$lanif = autodetect_interface("LAN", $fp);
729
		else if (!array_key_exists($lanif, $iflist)) {
730
			echo "\nInvalid interface name '{$lanif}'\n";
731
			unset($lanif);
732
			continue;
733
		}
734
	} while (!$lanif);
735

    
736
	do {
737
		echo "\nEnter the WAN interface name or 'a' for auto-detection: ";
738
		$wanif = chop(fgets($fp));
739
		if ($wanif === "") {
740
			exit(0);
741
		}
742
		if ($wanif === "a")
743
			$wanif = autodetect_interface("WAN", $fp);
744
		else if (!array_key_exists($wanif, $iflist)) {
745
			echo "\nInvalid interface name '{$wanif}'\n";
746
			unset($wanif);
747
			continue;
748
		}
749
	} while (!$wanif);
750

    
751
	/* optional interfaces */
752
	$i = 0;
753
	$optif = array();
754

    
755
	while (1) {
756
		if ($optif[$i])
757
			$i++;
758
		$i1 = $i + 1;
759
		echo "\nEnter the Optional {$i1} interface name or 'a' for auto-detection\n" .
760
			"(or nothing if finished): ";
761
		$optif[$i] = chop(fgets($fp));
762

    
763
		if ($optif[$i]) {
764
			if ($optif[$i] === "a") {
765
				$ad = autodetect_interface("Optional " . $i1, $fp);
766
				if ($ad)
767
					$optif[$i] = $ad;
768
				else
769
					unset($optif[$i]);
770
			} else if (!array_key_exists($optif[$i], $iflist)) {
771
				echo "\nInvalid interface name '{$optif[$i]}'\n";
772
				unset($optif[$i]);
773
				continue;
774
			}
775
		} else {
776
			unset($optif[$i]);
777
			break;
778
		}
779
	}
780

    
781
	/* check for double assignments */
782
	$ifarr = array_merge(array($lanif, $wanif), $optif);
783

    
784
	for ($i = 0; $i < (count($ifarr)-1); $i++) {
785
		for ($j = ($i+1); $j < count($ifarr); $j++) {
786
			if ($ifarr[$i] == $ifarr[$j]) {
787
				echo <<<EOD
788

    
789
Error: you cannot assign the same interface name twice!
790

    
791
EOD;
792

    
793
				exit(0);
794
			}
795
		}
796
	}
797

    
798
	echo <<<EOD
799

    
800
The interfaces will be assigned as follows:
801

    
802
LAN  -> {$lanif}
803
WAN  -> {$wanif}
804

    
805
EOD;
806

    
807
	for ($i = 0; $i < count($optif); $i++) {
808
		echo "OPT" . ($i+1) . " -> " . $optif[$i] . "\n";
809
	}
810

    
811
	if(!$noreboot) echo "\npfSense will reboot after saving the changes.\n";
812

    
813
echo <<<EOD
814

    
815
Do you want to proceed [y|n]?
816
EOD;
817

    
818
	if (strcasecmp(chop(fgets($fp)), "y") == 0) {
819

    
820
		$config['interfaces']['lan']['if'] = $lanif;
821
		if (preg_match($g['wireless_regex'], $lanif)) {
822
			if (!is_array($config['interfaces']['lan']['wireless']))
823
				$config['interfaces']['lan']['wireless'] = array();
824
		} else {
825
			unset($config['interfaces']['lan']['wireless']);
826
		}
827
		
828
		$config['interfaces']['wan']['if'] = $wanif;
829
		if (preg_match($g['wireless_regex'], $wanif)) {
830
			if (!is_array($config['interfaces']['wan']['wireless']))
831
				$config['interfaces']['wan']['wireless'] = array();
832
		} else {
833
			unset($config['interfaces']['wan']['wireless']);
834
		}
835
		
836
		for ($i = 0; $i < count($optif); $i++) {
837
			if (!is_array($config['interfaces']['opt' . ($i+1)]))
838
				$config['interfaces']['opt' . ($i+1)] = array();
839
			
840
			$config['interfaces']['opt' . ($i+1)]['if'] = $optif[$i];
841
			
842
			/* wireless interface? */
843
			if (preg_match($g['wireless_regex'], $optif[$i])) {
844
				if (!is_array($config['interfaces']['opt' . ($i+1)]['wireless']))
845
					$config['interfaces']['opt' . ($i+1)]['wireless'] = array();
846
			} else {
847
				unset($config['interfaces']['opt' . ($i+1)]['wireless']);
848
			}
849
			
850
			unset($config['interfaces']['opt' . ($i+1)]['enable']);
851
			$config['interfaces']['opt' . ($i+1)]['descr'] = "OPT" . ($i+1);
852
		}
853
		
854
		/* remove all other (old) optional interfaces */
855
		for (; isset($config['interfaces']['opt' . ($i+1)]); $i++)
856
			unset($config['interfaces']['opt' . ($i+1)]);
857
		
858
		write_config();
859
		
860
		echo <<<EOD
861

    
862

    
863

    
864
EOD;
865

    
866
		if($noreboot <> true)
867
			system_reboot_sync();
868
	}
869
}
870

    
871
function autodetect_interface($ifname, $fp) {
872
	$iflist_prev = get_interface_list();
873
	echo <<<EOD
874

    
875
Connect the {$ifname} interface now and make sure that the link is up.
876
Then press ENTER to continue.
877

    
878
EOD;
879
	fgets($fp);
880
	$iflist = get_interface_list();
881

    
882
	foreach ($iflist_prev as $ifn => $ifa) {
883
		if (!$ifa['up'] && $iflist[$ifn]['up']) {
884
			echo "Detected link-up on interface {$ifn}.\n";
885
			return $ifn;
886
		}
887
	}
888

    
889
	echo "No link-up detected.\n";
890

    
891
	return null;
892
}
893

    
894
function vlan_setup() {
895
	global $iflist, $config, $g, $fp;
896

    
897
	$iflist = get_interface_list();
898

    
899
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
900

    
901
	echo <<<EOD
902

    
903
WARNING: all existing VLANs will be cleared if you proceed!
904

    
905
Do you want to proceed [y|n]?
906
EOD;
907

    
908
	if (strcasecmp(chop(fgets($fp)), "y") != 0)
909
		return;
910
	}
911

    
912
	$config['vlans']['vlan'] = array();
913
	echo "\n";
914

    
915
	while (1) {
916
		$vlan = array();
917

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

    
921
		if ($vlan['if']) {
922
			if (!array_key_exists($vlan['if'], $iflist)) {
923
				echo "\nInvalid interface name '{$vlan['if']}'\n";
924
				continue;
925
			}
926
		} else {
927
			break;
928
		}
929

    
930
		echo "Enter the VLAN tag (1-4094): ";
931
		$vlan['tag'] = chop(fgets($fp));
932

    
933
		if (!is_numericint($vlan['tag']) || ($vlan['tag'] < 1) || ($vlan['tag'] > 4094)) {
934
			echo "\nInvalid VLAN tag '{$vlan['tag']}'\n";
935
			continue;
936
		}
937

    
938
		$config['vlans']['vlan'][] = $vlan;
939
	}
940
}
941

    
942
function system_start_ftp_helpers() {
943
	global $config, $g;
944
	if($config['system']['disableftpproxy'] <> "") return;
945
	$wanif = get_real_wan_interface();
946
	mwexec("/usr/sbin/inetd -wW -C 60");
947
	mwexec("/usr/bin/killall ftpsesame 2>/dev/null");
948
	mwexec("/usr/local/sbin/ftpsesame -i {$wanif} -q ftpproxy");
949
}
950

    
951
function cleanup_backupcache($revisions = "all") {
952
	global $g;
953
	$i = false;
954
	if(file_exists($g['cf_conf_path'] . '/backup/backup.cache')) {
955
		$backups = get_backups();
956
		$newbaks = array();
957
		$bakfiles = glob("/conf/backup/*");
958
		$baktimes = $backups['versions'];
959
		$tocache = array();
960
		unset($backups['versions']);
961
       		foreach($bakfiles as $backup) { // Check for backups in the directory not represented in the cache.
962
			if(stristr($backup, 'backup.cache')) continue;
963
			$tocheck = array_shift(explode('.', array_pop(explode('-', $backup))));	
964
                	if(!in_array($tocheck, $baktimes)) {
965
				$i = true;
966
				if($bootup) print " " . $tocheck . "a";
967
				$newxml = parse_xml_config($backup, $g['xml_rootobj']);
968
				if($newxml['revision']['description'] == "") $newxml['revision']['description'] = "Unknown";
969
				$tocache[$tocheck] = array('description' => $newxml['revision']['description']);
970
			}
971
        	}
972
		foreach($backups as $checkbak) {
973
			if(count(preg_grep('/' . $checkbak['time'] . '/i', $bakfiles)) != 0) {
974
				$newbaks[] = $checkbak;
975
			} else {
976
				$i = true;
977
				if($bootup) print " " . $tocheck . "r";
978
			}
979
		}
980
		foreach($newbaks as $todo) $tocache[$todo['time']] = array('description' => $todo['description']);	
981
		if(is_integer($revisions)) {
982
			$toslice = array_slice(array_keys($tocache), 0, $revisions);
983
			foreach($toslice as $sliced) $newcache[$sliced] = $tocache[$sliced];
984
			foreach($tocache as $version => $versioninfo) {
985
				if(!in_array($version, array_keys($newcache))) {
986
					unlink_if_exists($g['conf_path'] . '/backup/config-' . $version . '.xml');
987
					if($bootup) print " " . $tocheck . "d";
988
				}
989
			}
990
			$tocache = $newcache;
991
		}
992
		$bakout = fopen($g['cf_conf_path'] . '/backup/backup.cache', "w");
993
        	fwrite($bakout, serialize($tocache));
994
  	        fclose($bakout);
995
	}
996
	if($g['booting']) {
997
		if($i) {
998
			print ".\n";
999
		} else {
1000
			print " done.\n";
1001
		}
1002
	}
1003
}
1004
  	 
1005
function get_backups() { 	 
1006
        if(file_exists("/conf/backup/backup.cache")) {
1007
                $confvers = unserialize(file_get_contents("/conf/backup/backup.cache"));
1008
		$bakvers = array_keys($confvers);
1009
		$toreturn = array();
1010
		sort($bakvers);
1011
		// $bakvers = array_reverse($bakvers);
1012
		foreach(array_reverse($bakvers) as $bakver) $toreturn[] = array('time' => $bakver,
1013
								 'description' => $confvers[$bakver]['description']
1014
								);
1015
        } else { 	 
1016
                return false; 	 
1017
        }
1018
	$toreturn['versions'] = $bakvers;
1019
        return $toreturn;
1020
}
1021

    
1022
function backup_config() {
1023
	global $config, $g;
1024
        if(!is_dir($g['cf_conf_path'] . '/backup')) mkdir($g['cf_conf_path'] . '/backup');
1025
        if($config['revision']['time'] == "") {
1026
                $baktime = 0;
1027
        } else {
1028
                $baktime = $config['revision']['time'];
1029
        }
1030
        if($config['revision']['description'] == "") {
1031
                $bakdesc = "Unknown";
1032
        } else {
1033
                $bakdesc = $config['revision']['description'];
1034
        }
1035
        copy($g['cf_conf_path'] . '/config.xml', $g['cf_conf_path'] . '/backup/config-' . $baktime . '.xml');
1036
        if(file_exists($g['cf_conf_path'] . '/backup/backup.cache')) {
1037
                $backupcache = unserialize(file_get_contents($g['cf_conf_path'] . '/backup/backup.cache'));
1038
        } else {
1039
                $backupcache = array();
1040
        }
1041
        $backupcache[$baktime] = array('description' => $bakdesc);
1042
        $bakout = fopen($g['cf_conf_path'] . '/backup/backup.cache', "w");
1043
        fwrite($bakout, serialize($backupcache));
1044
        fclose($bakout);
1045
	return true;
1046
}
1047
?>
(3-3/18)