Project

General

Profile

Download (34.8 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	services.inc
5
	part of m0n0wall (http://m0n0.ch/wall)
6

    
7
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
8
	All rights reserved.
9

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

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

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

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

    
32
/* include all configuration functions */
33
require_once("functions.inc");
34

    
35
function load_balancer_use_sticky() {
36
	global $config, $g;
37
	if (isset ($config['system']['lb_use_sticky']))
38
		touch("/var/etc/use_pf_pool__stickyaddr");
39
	else
40
		unlink_if_exists("/var/etc/use_pf_pool__stickyaddr");
41
}
42

    
43
function services_dhcpd_configure() {
44
	global $config, $g;
45
	if(isset($config['system']['developerspew'])) {
46
		$mt = microtime();
47
		echo "services_dhcpd_configure($if) being called $mt\n";
48
	}
49

    
50
	/* if OLSRD is enabled, allow WAN to house DHCP. */
51
	if($config['installedpackages']['olsrd'])
52
		foreach($config['installedpackages']['olsrd']['config'] as $olsrd)
53
				if($olsrd['enable'])
54
					$is_olsr_enabled = true;
55

    
56
	/* configure DHCPD chroot */
57
	$fd = fopen("/tmp/dhcpd.sh","w");
58
	$status = `mount | grep "{$g['dhcpd_chroot_path']}/dev"`;
59
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}\n");
60
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/dev\n");
61
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/etc\n");
62
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/usr/local/sbin\n");
63
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/var/db\n");
64
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/usr\n");
65
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/lib\n");
66
	fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}/run\n");
67
	fwrite($fd, "chown -R dhcpd:_dhcp {$g['dhcpd_chroot_path']}/*\n");
68
	fwrite($fd, "cp /lib/libc.so.* {$g['dhcpd_chroot_path']}/lib/\n");
69
	fwrite($fd, "cp /usr/local/sbin/dhcpd {$g['dhcpd_chroot_path']}/usr/local/sbin/\n");
70
	fwrite($fd, "chmod a+rx {$g['dhcpd_chroot_path']}/usr/local/sbin/dhcpd\n");
71
	if(!trim($status))
72
		fwrite($fd, "mount -t devfs devfs {$g['dhcpd_chroot_path']}/dev\n");
73
	fclose($fd);
74
	mwexec("/bin/sh /tmp/dhcpd.sh");
75

    
76
	/* kill any running dhcpd */
77
	if(is_process_running("dhcpd"))
78
		mwexec("killall dhcpd");
79

    
80
	$syscfg = $config['system'];
81
	$dhcpdcfg = $config['dhcpd'];
82

    
83
	/* DHCP enabled on any interfaces? */
84
	$dhcpdenable = false;
85
	if(is_array($dhcpdcfg))
86
		foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
87
			if($dhcpif == "lan") 
88
				if(!$config['interfaces']['lan']) 	
89
					continue;
90
			if (isset($dhcpifconf['enable']) &&
91
				(($dhcpif == "lan") ||
92
				(isset($config['interfaces'][$dhcpif]['enable']) &&
93
				$config['interfaces'][$dhcpif]['if'] && (!$config['interfaces'][$dhcpif]['bridge']))))
94
				$dhcpdenable = true;
95
			if (isset($dhcpifconf['enable']) &&
96
				(($dhcpif == "wan") || (isset($config['interfaces'][$dhcpif]['enable']) &&
97
				$config['interfaces'][$dhcpif]['if'] && (!$config['interfaces'][$dhcpif]['bridge']))))
98
				$dhcpdenable = true;
99
		}
100

    
101
	if (!$dhcpdenable)
102
		return 0;
103

    
104
	if ($g['booting'])
105
		echo "Starting DHCP service...";
106
	else
107
		sleep(1);
108

    
109
	/* write dhcpd.conf */
110
	$fd = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpd.conf", "w");
111
	if (!$fd) {
112
		printf("Error: cannot open dhcpd.conf in services_dhcpd_configure().\n");
113
		return 1;
114
	}
115

    
116

    
117

    
118
	$dhcpdconf = <<<EOD
119
	
120
option domain-name "{$syscfg['domain']}";
121
option ldap-server code 95 = text;
122
option domain-search-list code 119 = text;
123
default-lease-time 7200;
124
max-lease-time 86400;
125
log-facility local7;
126
ddns-update-style none;
127
one-lease-per-client true;
128
deny duplicates;
129
ping-check true;
130

    
131
EOD;
132

    
133
	$dhcpdifs = array();
134

    
135
	/*    loop through and deterimine if we need to setup
136
	 *    failover peer "bleh" entries
137
	 */
138
	$dhcpnum = 0;
139
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
140

    
141
		if(!isset($dhcpifconf['disableauthoritative']))
142
			$dhcpdconf .= "authoritative;\n";
143

    
144
		if($dhcpifconf['failover_peerip'] <> "") {
145
			/*
146
			 *    yep, failover peer is defined.
147
			 *    does it match up to a defined vip?
148
			 */
149
			$skew = 110;
150
			$a_vip = &$config['virtualip']['vip'];
151
			if(is_array($a_vip)) {
152
				foreach ($a_vip as $vipent) {
153
					$int = guess_interface_from_ip($dhcpifconf['failover_peerip']);
154
					$intip = find_interface_ip($int);
155
					$real_dhcpif = convert_friendly_interface_to_real_interface_name($dhcpif);
156
					if($int == $real_dhcpif) {
157
						/* this is the interface! */
158
						if($vipent['advskew'] < "20")
159
							$skew = 0;
160
					}
161
				}
162
			} else {
163
				log_error("Warning!  DHCP Failover setup and no CARP virtual IP's defined!");
164
			}
165
			if($skew > 10) {
166
				$type = "secondary";
167
				$dhcpdconf_pri  = "mclt 600;\n";
168
				$my_port = "520";
169
				$peer_port = "519";
170
			} else {
171
				$my_port = "519";
172
				$peer_port = "520";
173
				$type = "primary";
174
				$dhcpdconf_pri  = "split 128;\n";
175
				$dhcpdconf_pri .= "  mclt 600;\n";
176
			}
177
			$dhcpdconf .= <<<EOPP
178
failover peer "dhcp{$dhcpnum}" {
179
  {$type};
180
  address {$intip};
181
  port {$my_port};
182
  peer address {$dhcpifconf['failover_peerip']};
183
  peer port {$peer_port};
184
  max-response-delay 10;
185
  max-unacked-updates 10;
186
  {$dhcpdconf_pri}
187
  load balance max seconds 3;
188
}
189

    
190
EOPP;
191
		$dhcpnum++;
192
		}
193
	}
194

    
195
	$dhcpnum = 0;
196

    
197
	foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
198

    
199
		$ifcfg = $config['interfaces'][$dhcpif];
200

    
201
		if (!isset($dhcpifconf['enable']) ||
202
			($ifcfg['ipaddr'] == "dhcp") ||
203
			(($dhcpif != "lan") &&
204
			(!isset($ifcfg['enable']) || !$ifcfg['if'] || $ifcfg['bridge'])))
205
			continue;
206

    
207
		if($dhcpif == "lan" && $ifcfg['bridge'])
208
			log_error("NOTE: DHCP Server on LAN is enabled.");
209

    
210
		$subnet = gen_subnet($ifcfg['ipaddr'], $ifcfg['subnet']);
211
		$subnetmask = gen_subnet_mask($ifcfg['subnet']);
212

    
213
		if($is_olsr_enabled == true)
214
			if($dhcpifconf['netmask'])
215
				$subnetmask = gen_subnet_mask($dhcpifconf['netmask']);
216

    
217
		$dnscfg = "";
218

    
219
		if ($dhcpifconf['domain']) {
220
			$dnscfg .= "	option domain-name \"{$dhcpifconf['domain']}\";\n";
221
		}
222
		
223
    if($dhcpifconf['domainsearchlist'] <> "") {
224
			$dnscfg .= "	option domain-search-list \"{$dhcpifconf['domainsearchlist']}\";\n";
225
    }
226

    
227
		if (isset($dhcpifconf['ddnsupdate'])) {
228
			if($dhcpifconf['ddnsdomain'] <> "") {
229
				$dnscfg .= "	ddns-domainname \"{$dhcpifconf['ddnsdomain']}\";\n";
230
			}
231
			$dnscfg .= "	ddns-update-style interim;\n";
232
		}
233

    
234
		if (is_array($dhcpifconf['dnsserver']) && ($dhcpifconf['dnsserver'][0])) {
235
			$dnscfg .= "	option domain-name-servers " . join(",", $dhcpifconf['dnsserver']) . ";";
236
		} else if (isset($config['dnsmasq']['enable'])) {
237
			$dnscfg .= "	option domain-name-servers " . $ifcfg['ipaddr'] . ";";
238
		} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
239
			$dnscfg .= "	option domain-name-servers " . join(",", $syscfg['dnsserver']) . ";";
240
		}
241

    
242
		$dhcpdconf .= "subnet $subnet netmask $subnetmask {\n";
243
		$dhcpdconf .= "	pool {\n";
244

    
245
		/* is failover dns setup? */
246
		if (is_array($dhcpifconf['dnsserver']) && $dhcpifconf['dnsserver'][0] <> "") {
247
			$dhcpdconf .= "		option domain-name-servers {$dhcpifconf['dnsserver'][0]}";
248
			if($dhcpifconf['dnsserver'][1] <> "")
249
				$dhcpdconf .= ",{$dhcpifconf['dnsserver'][1]}";
250
			$dhcpdconf .= ";\n";
251
		}
252

    
253
		if($dhcpifconf['failover_peerip'] <> "")
254
			$dhcpdconf .= "		deny dynamic bootp clients;\n";
255

    
256
		if (isset($dhcpifconf['denyunknown']))
257
		   $dhcpdconf .= "		deny unknown clients;\n";
258

    
259
		if ($dhcpifconf['gateway'])
260
			$routers = $dhcpifconf['gateway'];
261
		else
262
			$routers = $ifcfg['ipaddr'];
263

    
264
		if($dhcpifconf['failover_peerip'] <> "") {
265
			$dhcpdconf .= "		failover peer \"dhcp{$dhcpnum}\";\n";
266
			$dhcpnum++;
267
		}
268

    
269
		$dhcpdconf .= <<<EOD
270
		range {$dhcpifconf['range']['from']} {$dhcpifconf['range']['to']};
271
	}
272
	option routers {$routers};
273
$dnscfg
274

    
275
EOD;
276
    
277
    if ($dhcpifconf['defaultleasetime'])
278
			$dhcpdconf .= "	default-lease-time {$dhcpifconf['defaultleasetime']};\n";
279
		if ($dhcpifconf['maxleasetime'])
280
			$dhcpdconf .= "	max-lease-time {$dhcpifconf['maxleasetime']};\n";
281

    
282
		if (is_array($dhcpifconf['winsserver']) && $dhcpifconf['winsserver'][0]) {
283
			$dhcpdconf .= "	option netbios-name-servers " . join(",", $dhcpifconf['winsserver']) . ";\n";
284
			$dhcpdconf .= "	option netbios-node-type 8;\n";
285
		}
286

    
287
		if (is_array($dhcpifconf['ntpserver']) && $dhcpifconf['ntpserver'][0])
288
			$dhcpdconf .= "	option ntp-servers " . join(",", $dhcpifconf['ntpserver']) . ";\n";
289

    
290
		if ($dhcpifconf['tftp'] <> "")
291
			$dhcpdconf .= "	option tftp-server-name \"{$dhcpifconf['tftp']}\";\n";
292

    
293
    if ($dhcpifconf['ldap'] <> "")
294
			$dhcpdconf .= "	option ldap-server \"{$dhcpifconf['ldap']}\";\n";
295

    
296
		if(isset($dhcpifconf['netboot'])) {
297
			if (($dhcpifconf['next-server'] <> "") && ($dhcpifconf['filename'] <> "")) {
298
				$dhcpdconf .= "	next-server {$dhcpifconf['next-server']};\n";
299
				$dhcpdconf .= "	filename \"{$dhcpifconf['filename']}\";\n";
300
			}
301
			if ($dhcpifconf['rootpath'] <> "") {
302
				$dhcpdconf .= "	option root-path \"{$dhcpifconf['rootpath']}\";\n";
303
      }
304
		}
305
		
306
		$dhcpdconf .= <<<EOD
307
}
308

    
309
EOD;
310

    
311
		/* add static mappings */
312
		if (is_array($dhcpifconf['staticmap'])) {
313

    
314
			$i = 0;
315
			foreach ($dhcpifconf['staticmap'] as $sm) {
316
				$dhcpdconf .= <<<EOD
317
host s_{$dhcpif}_{$i} {
318
	hardware ethernet {$sm['mac']};
319

    
320
EOD;
321
				if ($sm['ipaddr'])
322
					$dhcpdconf .= "	fixed-address {$sm['ipaddr']};\n";
323

    
324
				if ($sm['hostname'])
325
					$dhcpdconf .= "	option host-name {$sm['hostname']};\n";
326

    
327
				$dhcpdconf .= "}\n";
328
				$i++;
329
			}
330
		}
331

    
332
		$dhcpdifs[] = $ifcfg['if'];
333
	}
334

    
335
	fwrite($fd, $dhcpdconf);
336
	fclose($fd);
337

    
338
	/* create an empty leases database */
339
	touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
340

    
341
	/* fire up dhcpd in a chroot */
342
	mwexec("/usr/local/sbin/dhcpd -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf {$g['dhcpd_chroot_path']}/etc/dhcpd.conf " .
343
		join(" ", $dhcpdifs));
344

    
345
	if ($g['booting']) {
346
		print "done.\n";
347
	}
348

    
349
	return 0;
350
}
351

    
352
function interfaces_staticarp_configure($if) {
353
	global $config, $g;
354
	if(isset($config['system']['developerspew'])) {
355
		$mt = microtime();
356
		echo "interfaces_staticarp_configure($if) being called $mt\n";
357
	}
358

    
359
        $ifcfg = $config['interfaces'][$if];
360

    
361
        /* Enable staticarp, if enabled */
362
        if(isset($config['dhcpd'][$if]['staticarp'])) {
363
                mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " staticarp " );
364
                mwexec("/usr/sbin/arp -ad > /dev/null 2>&1 ");
365
                if (is_array($config['dhcpd'][$if]['staticmap'])) {
366

    
367
                        foreach ($config['dhcpd'][$if]['staticmap'] as $arpent) {
368
                                mwexec("/usr/sbin/arp -s " . escapeshellarg($arpent['ipaddr']) . " " . escapeshellarg($arpent['mac']));
369

    
370
                        }
371

    
372
                }
373
        } else {
374
                mwexec("/sbin/ifconfig " . escapeshellarg($ifcfg['if']) . " -staticarp " );
375
                mwexec("/usr/sbin/arp -da > /dev/null 2>&1 ");
376
        }
377

    
378
        return 0;
379
}
380

    
381
function services_dhcrelay_configure() {
382
	global $config, $g;
383
	if(isset($config['system']['developerspew'])) {
384
		$mt = microtime();
385
		echo "services_dhcrelay_configure() being called $mt\n";
386
	}
387

    
388
	/* kill any running dhcrelay */
389
	killbypid("{$g['varrun_path']}/dhcrelay.pid");
390

    
391
	$dhcrelaycfg = $config['dhcrelay'];
392

    
393
	/* DHCPRelay enabled on any interfaces? */
394
	$dhcrelayenable = false;
395
	if(is_array($dhcrelaycfg)) {
396
		foreach ($dhcrelaycfg as $dhcrelayif => $dhcrelayifconf) {
397
			if (isset($dhcrelayifconf['enable']) &&
398
				(($dhcrelayif == "lan") ||
399
				(isset($config['interfaces'][$dhcrelayif]['enable']) &&
400
				$config['interfaces'][$dhcrelayif]['if'] && (!$config['interfaces'][$dhcrelayif]['bridge']))))
401
				$dhcrelayenable = true;
402
		}
403
	}
404

    
405
	if (!$dhcrelayenable)
406
		return 0;
407

    
408
	if ($g['booting'])
409
		echo "Starting DHCP relay service...";
410
	else
411
		sleep(1);
412

    
413
	$dhcrelayifs = array();
414
	foreach ($dhcrelaycfg as $dhcrelayif => $dhcrelayifconf) {
415

    
416
		$ifcfg = $config['interfaces'][$dhcrelayif];
417

    
418
		if (!isset($dhcrelayifconf['enable']) ||
419
			(($dhcrelayif != "lan") &&
420
			(!isset($ifcfg['enable']) || !$ifcfg['if'] || $ifcfg['bridge'])))
421
			continue;
422

    
423
		$dhcrelayifs[] = $ifcfg['if'];
424
	}
425

    
426
	/* In order for the relay to work, it needs to be active on the
427
	   interface in which the destination server sits */
428
	foreach ($config['interfaces'] as $ifname) {
429
		$subnet = $ifname['ipaddr'] . "/" . $ifname['subnet'];
430
		if (ip_in_subnet($dhcrelaycfg['server'],$subnet))
431
			$destif = $ifname['if'];
432
	}
433

    
434
	if (!isset($destif))
435
		$destif = $config['interfaces']['wan']['if'];
436

    
437
	$dhcrelayifs[] = $destif;
438
	$dhcrelayifs = array_unique($dhcrelayifs);
439

    
440
	/* fire up dhcrelay */
441
	$cmd = "/usr/local/sbin/dhcrelay -i " .  join(" -i ", $dhcrelayifs);
442

    
443
	if (isset($dhcrelaycfg['agentoption']))
444
		$cmd .=  " -a -m replace";
445

    
446
	$cmd .= " {$dhcrelaycfg['server']}";
447
	mwexec($cmd);
448

    
449
	if (!$g['booting']) {
450
		/* set the reload filter dity flag */
451
		touch("{$g['tmp_path']}/filter_dirty");
452
	}
453

    
454
	return 0;
455
}
456

    
457
function services_dyndns_reset() {
458
	global $config, $g;
459
	if(isset($config['system']['developerspew'])) {
460
		$mt = microtime();
461
		echo "services_dyndns_reset() being called $mt\n";
462
	}
463

    
464
	if (file_exists("{$g['vardb_path']}/ez-ipupdate*.cache")) {
465
		conf_mount_rw();
466
		unlink("{$g['vardb_path']}/ez-ipupdate*.cache");
467
		conf_mount_ro();
468
	}
469

    
470
	mwexec("rm {$g['varetc_path']}/ez-ipupdate*.cache");
471
	mwexec("rm {$g['varetc_path']}/dyndns*.cache");
472

    
473
	return 0;
474
}
475

    
476
function services_dyndns_configure() {
477
	global $config, $g;
478
	if(isset($config['system']['developerspew'])) {
479
		$mt = microtime();
480
		echo "services_dyndns_configure() being called $mt\n";
481
	}
482

    
483
	$dyndnscfg = $config['dyndnses']['dyndns'];
484

    
485
	if (is_array($dyndnscfg)) {
486
		foreach ($dyndnscfg as $dyndns) {
487
			if (!isset($dyndns['enable']))
488
				continue;
489
			/* determine interface name */
490
			$if = get_real_wan_interface($dyndns['interface']);
491

    
492
			if ($g['booting']) {
493
				echo "Starting DynDNS clients...";
494
				if (isset($config['system']['use_old_dyndns'])) {
495
					echo " [Using ez-ipupdate] ";
496
					services_dyndns_configure_old($if);
497
					continue;
498
				}
499
			} else {
500
				sleep(1);
501
				if (isset($config['system']['use_old_dyndns'])) {
502
					services_dyndns_configure_old($if);
503
					continue;
504
				}
505
			}
506

    
507
			/* load up the dyndns.class */
508
			require_once("dyndns.class");
509

    
510
			log_error("DynDns: Running updatedns()");
511

    
512
			
513
			/* get ip */
514
			$ip = find_interface_ip($if);
515

    
516
			$dns = new updatedns($dnsService = $dyndns['type'],
517
							 $dnsHost = $dyndns['host'],
518
							 $dnsUser = $dyndns['username'],
519
							 $dnsPass = $dyndns['password'],
520
							 $dnsWilcard = $dyndns['wildcard'],
521
							 $dnsMX = $dyndns['mx'], $dnsIf = "{$if}");
522

    
523
		}
524

    
525
		if ($g['booting'])
526
			echo "done.\n";
527
	}
528

    
529
	return 0;
530
}
531

    
532
function services_dyndns_configure_old($if) {
533
	global $config, $g;
534
	if(isset($config['system']['developerspew'])) {
535
		$mt = microtime();
536
		echo "services_dyndns_configure_old() being called $mt\n";
537
	}
538

    
539
        /* kill any running ez-ipupdate */
540
        /* ez-ipupdate needs SIGQUIT instead of SIGTERM */
541
        sigkillbypid("{$g['varrun_path']}/ez-ipupdate_{$if}.pid", "QUIT");
542

    
543
        $dyndnscfg = $config['dyndnses']['dyndns'];
544
        $wancfg = $config['interfaces'][$if];
545

    
546
                sleep(1);
547

    
548
                /* write ez-ipupdate.conf */
549
                $fd = fopen("{$g['varetc_path']}/ez-ipupdate_{$if}.conf", "w");
550
                if (!$fd) {
551
                        printf("Error: cannot open ez-ipupdate_{$if}.conf in services_dyndns_configure().\n");
552
                        return 1;
553
                }
554

    
555
                $ezipupdateconf = <<<EOD
556
service-type={$dyndns['type']}
557
user={$dyndns['username']}:{$dyndns['password']}
558
host={$dyndns['host']}
559
interface={$if}
560
max-interval=2073600
561
pid-file={$g['varrun_path']}/ez-ipupdate_{$if}.pid
562
cache-file={$g['vardb_path']}/ez-ipupdate_{$if}.cache
563
daemon
564

    
565
EOD;
566

    
567
                /* enable server[:port]? */
568
                if ($dyndns['server']) {
569
                        if ($dyndns['port'])
570
                                $ezipupdateconf .= "server={$dyndns['server']}:{$dyndns['port']}\n";
571
                        else
572
                                $ezipupdateconf .= "server={$dyndns['server']}\n";
573
                }
574

    
575
                /* enable MX? */
576
                if ($dyndns['mx']) {
577
                        $ezipupdateconf .= "mx={$dyndns['mx']}\n";
578
                }
579

    
580
                /* enable wildcards? */
581
                if (isset($dyndns['wildcard'])) {
582
                        $ezipupdateconf .= "wildcard\n";
583
                }
584

    
585
                fwrite($fd, $ezipupdateconf);
586
                fclose($fd);
587

    
588
                /* run ez-ipupdate */
589
                mwexec("/usr/local/bin/ez-ipupdate -c {$g['varetc_path']}/ez-ipupdate_{$if}.conf");
590

    
591
                if ($g['booting'])
592
                        echo "done\n";
593

    
594
        return 0;
595
}
596

    
597
function services_dnsmasq_configure() {
598
	global $config, $g;
599
	$return = 0;
600
	
601
	if(isset($config['system']['developerspew'])) {
602
		$mt = microtime();
603
		echo "services_dnsmasq_configure() being called $mt\n";
604
	}
605

    
606
	/* kill any running dnsmasq */
607
	sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM");
608

    
609
	if (isset($config['dnsmasq']['enable'])) {
610

    
611
		if ($g['booting'])
612
			echo "Starting DNS forwarder...";
613
		else
614
			sleep(1);
615

    
616
		/* generate hosts file */
617
		if(system_hosts_generate()!=0)
618
			$return = 1;
619

    
620
		$args = "";
621

    
622
		if (isset($config['dnsmasq']['regdhcp'])) {
623

    
624
			$args .= " -l {$g['dhcpd_chroot_path']}/var/db/dhcpd.leases" .
625
				" -s {$config['system']['domain']}";
626
		}
627

    
628
                if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
629
                        foreach($config['dnsmasq']['domainoverrides'] as $override) {
630
                                $args .= ' --server=/' . $override['domain'] . '/' . $override['ip'];
631
                        }
632
                }
633

    
634
		/* suppose that dnsmasq handles our domain and don't send
635
		requests for our local domain to upstream servers */
636
		//if (!empty($config['system']['domain'])) {
637
		//	$args .= sprintf(' --local=/%s/', $config['system']['domain']);
638
		//}
639

    
640
		/* run dnsmasq */
641
		mwexec("/usr/local/sbin/dnsmasq --cache-size=5000 {$args}");
642

    
643
		if ($g['booting'])
644
			echo "done.\n";
645
	}
646

    
647
	if (!$g['booting']) {
648
		if(services_dhcpd_configure()!=0)
649
			$return = 1;
650
	}
651

    
652
	return $return;
653
}
654

    
655
function services_snmpd_configure() {
656
	global $config, $g;
657
	if(isset($config['system']['developerspew'])) {
658
		$mt = microtime();
659
		echo "services_snmpd_configure() being called $mt\n";
660
	}
661

    
662
	/* kill any running snmpd */
663
	sigkillbypid("{$g['varrun_path']}/snmpd.pid", "TERM");
664
	if(is_process_running("bsnmpd")) 
665
		exec("/usr/bin/killall bsnmpd");
666

    
667
	if (isset($config['snmpd']['enable'])) {
668

    
669
		if ($g['booting'])
670
			echo "Starting SNMP daemon... ";
671

    
672
		/* generate snmpd.conf */
673
		$fd = fopen("{$g['varetc_path']}/snmpd.conf", "w");
674
		if (!$fd) {
675
			printf("Error: cannot open snmpd.conf in services_snmpd_configure().\n");
676
			return 1;
677
		}
678

    
679

    
680
		$snmpdconf = <<<EOD
681
location := "{$config['snmpd']['syslocation']}"
682
contact := "{$config['snmpd']['syscontact']}"
683
read := "{$config['snmpd']['rocommunity']}"
684

    
685
EOD;
686

    
687
/* No docs on what write strings do there for disable for now.
688
		if(isset($config['snmpd']['rwenable']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
689
		    $snmpdconf .= <<<EOD
690
# write string
691
write := "{$config['snmpd']['rwcommunity']}"
692

    
693
EOD;
694
		}
695
*/
696

    
697

    
698
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
699
		    $snmpdconf .= <<<EOD
700
# SNMP Trap support.
701
traphost := {$config['snmpd']['trapserver']}
702
trapport := {$config['snmpd']['trapserverport']}
703
trap := "{$config['snmpd']['trapstring']}"
704

    
705

    
706
EOD;
707
		}
708

    
709

    
710
		$snmpdconf .= <<<EOD
711
system := 1     # pfSense
712
%snmpd
713
begemotSnmpdDebugDumpPdus       = 2
714
begemotSnmpdDebugSyslogPri      = 7
715
begemotSnmpdCommunityString.0.1 = $(read)
716

    
717
EOD;
718

    
719
/* No docs on what write strings do there for disable for now.
720
		if(isset($config['snmpd']['rwcommunity']) && preg_match('/^\S+$/', $config['snmpd']['rwcommunity'])){
721
		    $snmpdconf .= <<<EOD
722
begemotSnmpdCommunityString.0.2 = $(write)
723

    
724
EOD;
725
		}
726
*/
727

    
728

    
729
		if(isset($config['snmpd']['trapenable']) && preg_match('/^\S+$/', $config['snmpd']['trapserver'])){
730
		    $snmpdconf .= <<<EOD
731
begemotTrapSinkStatus.[$(traphost)].$(trapport) = 4
732
begemotTrapSinkVersion.[$(traphost)].$(trapport) = 2
733
begemotTrapSinkComm.[$(traphost)].$(trapport) = $(trap)
734

    
735
EOD;
736
		}
737

    
738

    
739
		$snmpdconf .= <<<EOD
740
begemotSnmpdCommunityDisable    = 1
741

    
742
EOD;
743

    
744
		if(isset($config['snmpd']['bindlan'])) {
745
			$bind_to_ip = $config['interfaces']['lan']['ipaddr'];
746
		} else {
747
			$bind_to_ip = "0.0.0.0";
748
		}
749

    
750
		if(is_port( $config['snmpd']['pollport'] )) {
751
		    $snmpdconf .= <<<EOD
752
begemotSnmpdPortStatus.{$bind_to_ip}.{$config['snmpd']['pollport']} = 1
753

    
754
EOD;
755

    
756
		}
757

    
758
		$snmpdconf .= <<<EOD
759
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
760
begemotSnmpdLocalPortType."/var/run/snmpd.sock" = 4
761

    
762
# These are bsnmp macros not php vars.
763
sysContact      = $(contact)
764
sysLocation     = $(location)
765
sysObjectId     = 1.3.6.1.4.1.12325.1.1.2.1.$(system)
766

    
767
snmpEnableAuthenTraps = 2
768

    
769
EOD;
770

    
771
		if (is_array( $config['snmpd']['modules'] )) {
772
		    if(isset($config['snmpd']['modules']['mibii'])) {
773
			$snmpdconf .= <<<EOD
774
begemotSnmpdModulePath."mibII"  = "/usr/lib/snmp_mibII.so"
775

    
776
EOD;
777
		    }
778

    
779
		    if(isset($config['snmpd']['modules']['netgraph'])) {
780
			$snmpdconf .= <<<EOD
781
begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"
782
%netgraph
783
begemotNgControlNodeName = "snmpd"
784

    
785
EOD;
786
		    }
787

    
788
		    if(isset($config['snmpd']['modules']['pf'])) {
789
			$snmpdconf .= <<<EOD
790
begemotSnmpdModulePath."pf"     = "/usr/lib/snmp_pf.so"
791

    
792
EOD;
793
		    }
794

    
795
		    if(isset($config['snmpd']['modules']['hostres'])) {
796
			$snmpdconf .= <<<EOD
797
begemotSnmpdModulePath."hostres"     = "/usr/lib/snmp_hostres.so"
798

    
799
EOD;
800
		    }
801
		    if(isset($config['snmpd']['modules']['bridge'])) {
802
			$snmpdconf .= <<<EOD
803
begemotSnmpdModulePath."bridge"     = "/usr/lib/snmp_bridge.so"
804
# config must end with blank line
805

    
806

    
807
EOD;
808
		    }
809
		}
810

    
811
		fwrite($fd, $snmpdconf);
812
		fclose($fd);
813

    
814
		if (isset($config['snmpd']['bindlan'])) {
815
			$bindlan = "";
816
		}
817

    
818
		/* run bsnmpd */
819
		mwexec("/usr/sbin/bsnmpd -c {$g['varetc_path']}/snmpd.conf" .
820
			"{$bindlan} -p {$g['varrun_path']}/snmpd.pid");
821

    
822
		if ($g['booting'])
823
			echo "done.\n";
824
	}
825

    
826
	return 0;
827
}
828

    
829
function services_proxyarp_configure() {
830
	global $config, $g;
831
	if(isset($config['system']['developerspew'])) {
832
		$mt = microtime();
833
		echo "services_proxyarp_configure() being called $mt\n";
834
	}
835

    
836
	/* kill any running choparp */
837
	killbyname("choparp");
838

    
839
	if (isset($config['virtualip']) && is_array($config['virtualip']['vip'])) {
840
		$paa = array();
841

    
842
		/* group by interface */
843
		foreach ($config['virtualip']['vip'] as $vipent) {
844
			if ($vipent['mode'] === "proxyarp") {
845
				if ($vipent['interface'])
846
					$if = $vipent['interface'];
847
				else
848
					$if = "wan";
849

    
850
				if (!is_array($paa[$if]))
851
					$paa[$if] = array();
852

    
853
				$paa[$if][] = $vipent;
854
			}
855
		}
856

    
857
		if (count($paa))
858
		foreach ($paa as $paif => $paents) {
859
			if ($paif == "wan" && !(is_ipaddr($config['interfaces']['wan']['ipaddr']) ||
860
                                       ($config['interfaces']['wan']['ipaddr'] == "dhcp") ||
861
                                       ($config['interfaces']['wan']['ipaddr'] == "bigpond")))
862
                               continue;
863

    
864
			$args = $config['interfaces'][$paif]['if'] . " auto";
865

    
866
			foreach ($paents as $paent) {
867

    
868
				if (isset($paent['subnet']))
869
					$args .= " " . escapeshellarg("{$paent['subnet']}/{$paent['subnet_bits']}");
870
				else if (isset($paent['range']))
871
					$args .= " " . escapeshellarg($paent['range']['from'] . "-" .
872
						$paent['range']['to']);
873
			}
874

    
875
			mwexec_bg("/usr/local/sbin/choparp " . $args);
876
		}
877
	}
878
}
879

    
880
function services_dnsupdate_process() {
881
	global $config, $g;
882
	if(isset($config['system']['developerspew'])) {
883
		$mt = microtime();
884
		echo "services_dnsupdate_process() being called $mt\n";
885
	}
886

    
887
	/* Dynamic DNS updating active? */
888
	if (is_array($config['dnsupdates']['dnsupdate'])) {
889
		foreach ($config['dnsupdates']['dnsupdate'] as $i => $dnsupdate) {
890
		if (!isset($dyndns['enable']))
891
				continue;
892
			/* determine interface name */
893
			if ($dyndns['interface'] == "wan")
894
				$if = get_real_wan_interface();
895
			else
896
				$if = convert_friendly_interface_to_real_interface_name($dyndns['interface']);
897

    
898
			$wanip = get_current_wan_address($if);
899
			if ($wanip) {
900

    
901
				$keyname = $dnsupdate['keyname'];
902
				/* trailing dot */
903
				if (substr($keyname, -1) != ".")
904
					$keyname .= ".";
905

    
906
				$hostname = $dnsupdate['host'];
907
				/* trailing dot */
908
				if (substr($hostname, -1) != ".")
909
					$hostname .= ".";
910

    
911
				/* write private key file
912
				   this is dumb - public and private keys are the same for HMAC-MD5,
913
				   but nsupdate insists on having both */
914
				$fd = fopen("{$g['varetc_path']}/K{$i}{$keyname}+157+00000.private", "w");
915
				$privkey .= <<<EOD
916
Private-key-format: v1.2
917
Algorithm: 157 (HMAC)
918
Key: {$dnsupdate['keydata']}
919

    
920
EOD;
921
				fwrite($fd, $privkey);
922
				fclose($fd);
923

    
924
				/* write public key file */
925
				if ($dnsupdate['keytype'] == "zone") {
926
					$flags = 257;
927
					$proto = 3;
928
				} else if ($dnsupdate['keytype'] == "host") {
929
					$flags = 513;
930
					$proto = 3;
931
				} else if ($dnsupdate['keytype'] == "user") {
932
					$flags = 0;
933
					$proto = 2;
934
				}
935

    
936
				$fd = fopen("{$g['varetc_path']}/K{$keyname}+157+00000.key", "w");
937
				fwrite($fd, "{$keyname} IN KEY {$flags} {$proto} 157 {$dnsupdate['keydata']}\n");
938
				fclose($fd);
939

    
940
				/* generate update instructions */
941
				$upinst = "";
942
				if (!empty($dnsupdate['server']))
943
					$upinst .= "server {$dnsupdate['server']}\n";
944
				$upinst .= "update delete {$dnsupdate['host']} A\n";
945
				$upinst .= "update add {$dnsupdate['host']} {$dnsupdate['ttl']} A {$wanip}\n";
946
				$upinst .= "\n";	/* mind that trailing newline! */
947

    
948
				$fd = fopen("{$g['varetc_path']}/nsupdatecmds{$i}", "w");
949
				fwrite($fd, $upinst);
950
				fclose($fd);
951

    
952
				/* invoke nsupdate */
953
				$cmd = "/usr/sbin/nsupdate -k {$g['varetc_path']}/K{$i}{$keyname}+157+00000.key";
954
				if (isset($dnsupdate['usetcp']))
955
					$cmd .= " -v";
956
				$cmd .= " {$g['varetc_path']}/nsupdatecmds{$i}";
957
	
958
				mwexec_bg($cmd);
959
			}
960
		}
961
	}
962

    
963
	return 0;
964
}
965

    
966
function setup_wireless_olsr() {
967
	global $config, $g;
968
	if(!$config['installedpackages']['olsrd'] || !$config['installedpackages'])
969
		return;
970
	if(isset($config['system']['developerspew'])) {
971
		$mt = microtime();
972
		echo "setup_wireless_olsr($interface) being called $mt\n";
973
	}
974
	conf_mount_rw();
975
	foreach($config['installedpackages']['olsrd']['config'] as $olsrd) {
976
		$olsr_enable = $olsrd['enable'];
977
		if($olsr_enable <> "on")
978
			return;
979
		$fd = fopen("{$g['varetc_path']}/olsr.conf", "w");
980

    
981
		if($olsrd['announcedynamicroute'] or $olsrd['enableannounce'] == "on") {
982
			$enableannounce .= "\nHna4\n";
983
			$enableannounce .= "{\n";
984
		if($olsrd['announcedynamicroute'])
985
			$enableannounce .= "\t{$olsrd['announcedynamicroute']}\n";
986
		if($olsrd['enableannounce'] == "on")
987
			$enableannounce .= "0.0.0.0 0.0.0.0";
988
			$enableannounce .= "\n}\n";
989
		} else {
990
			$enableannounce = "";
991
		}
992

    
993
		$olsr .= <<<EODA
994
#
995
# olsr.org OLSR daemon config file
996
#
997
# Lines starting with a # are discarded
998
#
999
# This file was generated by setup_wireless_olsr() in services.inc
1000
#
1001

    
1002
# This file is an example of a typical
1003
# configuration for a mostly static
1004
# network(regarding mobility) using
1005
# the LQ extention
1006

    
1007
# Debug level(0-9)
1008
# If set to 0 the daemon runs in the background
1009

    
1010
DebugLevel	2
1011

    
1012
# IP version to use (4 or 6)
1013

    
1014
IpVersion	4
1015

    
1016
# Clear the screen each time the internal state changes
1017

    
1018
ClearScreen     yes
1019

    
1020
{$enableannounce}
1021

    
1022
# Should olsrd keep on running even if there are
1023
# no interfaces available? This is a good idea
1024
# for a PCMCIA/USB hotswap environment.
1025
# "yes" OR "no"
1026

    
1027
AllowNoInt	yes
1028

    
1029
# TOS(type of service) value for
1030
# the IP header of control traffic.
1031
# If not set it will default to 16
1032

    
1033
#TosValue	16
1034

    
1035
# The fixed willingness to use(0-7)
1036
# If not set willingness will be calculated
1037
# dynamically based on battery/power status
1038
# if such information is available
1039

    
1040
#Willingness    	4
1041

    
1042
# Allow processes like the GUI front-end
1043
# to connect to the daemon.
1044

    
1045
IpcConnect
1046
{
1047
     # Determines how many simultaneously
1048
     # IPC connections that will be allowed
1049
     # Setting this to 0 disables IPC
1050

    
1051
     MaxConnections  0
1052

    
1053
     # By default only 127.0.0.1 is allowed
1054
     # to connect. Here allowed hosts can
1055
     # be added
1056

    
1057
     Host            127.0.0.1
1058
     #Host            10.0.0.5
1059

    
1060
     # You can also specify entire net-ranges
1061
     # that are allowed to connect. Multiple
1062
     # entries are allowed
1063

    
1064
     #Net             192.168.1.0 255.255.255.0
1065
}
1066

    
1067
# Wether to use hysteresis or not
1068
# Hysteresis adds more robustness to the
1069
# link sensing but delays neighbor registration.
1070
# Used by default. 'yes' or 'no'
1071

    
1072
UseHysteresis	no
1073

    
1074
# Hysteresis parameters
1075
# Do not alter these unless you know
1076
# what you are doing!
1077
# Set to auto by default. Allowed
1078
# values are floating point values
1079
# in the interval 0,1
1080
# THR_LOW must always be lower than
1081
# THR_HIGH.
1082

    
1083
#HystScaling	0.50
1084
#HystThrHigh	0.80
1085
#HystThrLow	0.30
1086

    
1087

    
1088
# Link quality level
1089
# 0 = do not use link quality
1090
# 1 = use link quality for MPR selection
1091
# 2 = use link quality for MPR selection and routing
1092
# Defaults to 0
1093

    
1094
LinkQualityLevel	{$olsrd['enablelqe']}
1095

    
1096
# Link quality window size
1097
# Defaults to 10
1098

    
1099
LinkQualityWinSize	10
1100

    
1101
# Polling rate in seconds(float).
1102
# Default value 0.05 sec
1103

    
1104
Pollrate	0.05
1105

    
1106

    
1107
# TC redundancy
1108
# Specifies how much neighbor info should
1109
# be sent in TC messages
1110
# Possible values are:
1111
# 0 - only send MPR selectors
1112
# 1 - send MPR selectors and MPRs
1113
# 2 - send all neighbors
1114
#
1115
# defaults to 0
1116

    
1117
TcRedundancy	2
1118

    
1119
#
1120
# MPR coverage
1121
# Specifies how many MPRs a node should
1122
# try select to reach every 2 hop neighbor
1123
#
1124
# Can be set to any integer >0
1125
#
1126
# defaults to 1
1127

    
1128
MprCoverage	3
1129

    
1130
# Example plugin entry with parameters:
1131

    
1132
EODA;
1133

    
1134
if($olsrd['enablehttpinfo'] == "on") {
1135
	$olsr .= <<<EODB
1136

    
1137
LoadPlugin "/usr/local/lib/olsrd_httpinfo.so.0.1"
1138
{
1139
    PlParam     "port"   "{$olsrd['port']}"
1140
    PlParam     "Net"    "{$olsrd['allowedhttpinfohost']} {$olsrd['allowedhttpinfosubnet']}"
1141
}
1142

    
1143
EODB;
1144

    
1145
}
1146

    
1147
if($olsrd['enabledsecure'] == "on") {
1148
	$olsr .= <<<EODC
1149

    
1150
LoadPlugin "/usr/local/lib/olsrd_secure.so.0.5"
1151
{
1152
    PlParam     "Keyfile"   "/usr/local/etc/olsrkey.txt"
1153
}
1154

    
1155
EODC;
1156

    
1157
}
1158

    
1159
if($olsrd['enabledyngw'] == "on") {
1160

    
1161
	/* unset default route, olsr auto negotiates */
1162
	mwexec("/sbin/route delete default");
1163

    
1164
	$olsr .= <<<EODE
1165

    
1166
LoadPlugin "/usr/local/lib/olsrd_dyn_gw.so.0.4"
1167
{
1168
    # how often to look for a inet gw, in seconds
1169
    # defaults to 5 secs, if commented out
1170
    PlParam     "Interval"   "{$olsrd['polling']}"
1171

    
1172
    # if one or more IPv4 addresses are given, do a ping on these in
1173
    # descending order to validate that there is not only an entry in
1174
    # routing table, but also a real internet connection. If any of
1175
    # these addresses could be pinged successfully, the test was
1176
    # succesful, i.e. if the ping on the 1st address was successful,the
1177
    # 2nd won't be pinged
1178
    PlParam     "Ping"       "{$olsrd['ping']}"
1179
    #PlParam     "HNA"   "192.168.81.0 255.255.255.0"
1180
}
1181

    
1182
EODE;
1183

    
1184
}
1185

    
1186
foreach($config['installedpackages']['olsrd']['config'] as $conf) {
1187
	$interfaces = explode(',', $conf['iface_array']);
1188
	foreach($interfaces as $interface) {
1189
		$realinterface = convert_friendly_interface_to_real_interface_name($interface);
1190
$olsr .= <<<EODAD
1191
Interface "{$realinterface}"
1192
{
1193

    
1194
    # Hello interval in seconds(float)
1195
    HelloInterval    2.0
1196

    
1197
    # HELLO validity time
1198
    HelloValidityTime	20.0
1199

    
1200
    # TC interval in seconds(float)
1201
    TcInterval        5.0
1202

    
1203
    # TC validity time
1204
    TcValidityTime	30.0
1205

    
1206
    # MID interval in seconds(float)
1207
    MidInterval	5.0
1208

    
1209
    # MID validity time
1210
    MidValidityTime	30.0
1211

    
1212
    # HNA interval in seconds(float)
1213
    HnaInterval	5.0
1214

    
1215
    # HNA validity time
1216
    HnaValidityTime 	30.0
1217

    
1218
    # When multiple links exist between hosts
1219
    # the weight of interface is used to determine
1220
    # the link to use. Normally the weight is
1221
    # automatically calculated by olsrd based
1222
    # on the characteristics of the interface,
1223
    # but here you can specify a fixed value.
1224
    # Olsrd will choose links with the lowest value.
1225

    
1226
    # Weight 0
1227

    
1228

    
1229
}
1230

    
1231
EODAD;
1232

    
1233
	}
1234
	break;
1235
}
1236
		fwrite($fd, $olsr);
1237
		fclose($fd);
1238
	}
1239

    
1240
	if(is_process_running("olsrd"))
1241
		mwexec("/usr/bin/killall olsrd");
1242

    
1243
	sleep(2);
1244

    
1245
	mwexec_bg("/usr/local/sbin/olsrd -f {$g['varetc_path']}/olsr.conf");
1246

    
1247
	conf_mount_ro();
1248
}
1249

    
1250
/* configure cron service */
1251
function configure_cron() {
1252
	global $g, $config;
1253
	conf_mount_rw();
1254
	/* preserve existing crontab entries */
1255
	$crontab_contents = file_get_contents("/etc/crontab");
1256
	$crontab_contents_a = split("\n", $crontab_contents);
1257
	
1258
	for ($i = 0; $i < count($crontab_contents_a); $i++) {
1259
		$item =& $crontab_contents_a[$i];
1260
		if (strpos($item, "# pfSense specific crontab entries") !== false) {
1261
			array_splice($crontab_contents_a, $i - 1);
1262
			break;
1263
		}
1264
	}
1265
	$crontab_contents = implode("\n", $crontab_contents_a) . "\n";
1266
	
1267
	
1268
	if (is_array($config['cron']['item'])) {
1269
		$crontab_contents .= "#\n";
1270
		$crontab_contents .= "# pfSense specific crontab entries\n";
1271
		$crontab_contents .= "# Created: " . date("F j, Y, g:i a") . "\n";
1272
		$crontab_contents .= "#\n";
1273

    
1274
		foreach ($config['cron']['item'] as $item) {
1275
			$crontab_contents .= "\n{$item['minute']}\t";
1276
			$crontab_contents .= "{$item['hour']}\t";
1277
			$crontab_contents .= "{$item['mday']}\t";
1278
			$crontab_contents .= "{$item['month']}\t";
1279
			$crontab_contents .= "{$item['wday']}\t";
1280
			$crontab_contents .= "{$item['who']}\t";
1281
			$crontab_contents .= "{$item['command']}";
1282
		}
1283
    
1284
		$crontab_contents .= "\n#\n";
1285
		$crontab_contents .= "# If possible do not add items to this file manually.\n";
1286
		$crontab_contents .= "# If you do so, this file must be terminated with a blank line (e.g. new line)\n";
1287
		$crontab_contents .= "#\n\n";
1288
	}
1289
	
1290
	/* please maintain the newline at the end of file */
1291
	file_put_contents("/etc/crontab", $crontab_contents);
1292
	
1293
	if (!$g['booting'])
1294
		conf_mount_ro();
1295
}
1296

    
1297
function upnp_action ($action) {
1298
	switch($action) {
1299
		case "start":
1300
			if(file_exists('/var/etc/miniupnpd.conf'))
1301
				mwexec_bg('/usr/local/sbin/miniupnpd -f /var/etc/miniupnpd.conf');
1302
			break;
1303
		case "stop":
1304
			while((int)exec("pgrep miniupnpd | wc -l") > 0)
1305
				mwexec('killall miniupnpd 2>/dev/null');
1306
			mwexec('/sbin/pfctl -aminiupnpd -Fr 2>&1 >/dev/null');
1307
			mwexec('/sbin/pfctl -aminiupnpd -Fn 2>&1 >/dev/null');
1308
			break;
1309
		case "restart":
1310
			upnp_action('stop');
1311
			upnp_action('start');
1312
			break;
1313
	}
1314
}
1315

    
1316
function upnp_start() {
1317
	global $config, $g;
1318
	if($config['installedpackages']['miniupnpd']['config'][0]['enable']) {
1319
		if($g['booting']) {
1320
			echo "Starting UPnP service... ";
1321
			include('/usr/local/pkg/miniupnpd.inc');
1322
			sync_package_miniupnpd();
1323
			echo "done.\n";
1324
		}
1325
		else {
1326
			upnp_action('start');
1327
		}
1328
	}
1329
}
1330

    
1331
?>
(21-21/31)