Project

General

Profile

Download (26.8 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * service-utils.inc
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2005-2013 BSD Perimeter
7
 * Copyright (c) 2013-2016 Electric Sheep Fencing
8
 * Copyright (c) 2014-2023 Rubicon Communications, LLC (Netgate)
9
 * Copyright (c) 2005-2006 Colin Smith (ethethlay@gmail.com)
10
 * All rights reserved.
11
 *
12
 * Licensed under the Apache License, Version 2.0 (the "License");
13
 * you may not use this file except in compliance with the License.
14
 * You may obtain a copy of the License at
15
 *
16
 * http://www.apache.org/licenses/LICENSE-2.0
17
 *
18
 * Unless required by applicable law or agreed to in writing, software
19
 * distributed under the License is distributed on an "AS IS" BASIS,
20
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
 * See the License for the specific language governing permissions and
22
 * limitations under the License.
23
 */
24

    
25
require_once("captiveportal.inc");
26
require_once("globals.inc");
27
require_once("gwlb.inc");
28
require_once("ipsec.inc");
29
require_once("openvpn.inc");
30
require_once("system.inc");
31
require_once("util.inc");
32
require_once("vpn.inc");
33

    
34
define("RCFILEPREFIX", "/usr/local/etc/rc.d/");
35
function write_rcfile($params) {
36
	global $g;
37

    
38
	safe_mkdir(RCFILEPREFIX);
39
	$rcfile_fullname = RCFILEPREFIX . $params['file'];
40
	if (!file_exists($rcfile_fullname) && !is_link($rcfile_fullname) && !touch($rcfile_fullname)) {
41
		return false;
42
	}
43

    
44
	if (!is_writable($rcfile_fullname) || empty($params['start'])) {
45
		return false;
46
	}
47

    
48
	$towrite = "#!/bin/sh\n";
49
	$towrite .= "# This file was automatically generated\n# by the {$g['product_label']} service handler.\n\n";
50

    
51
	/* write our rc functions */
52
	$towrite .= "rc_start() {\n";
53
	$towrite .= "\t{$params['start']}\n";
54
	$towrite .= "}\n\n";
55
	if (!empty($params['stop'])) {
56
		$tokill = &$params['stop'];
57
	} else if (!empty($params['executable'])) {
58
		/* just nuke the executable */
59
		$tokill = "/usr/bin/killall " . escapeshellarg($params['executable']);
60
	} else {
61
		/* make an educated guess (bad) */
62
		$tokill = array_pop(explode('/', array_shift(explode(' ', $params['start']))));
63
	}
64
	$towrite .= "rc_stop() {\n";
65
	$towrite .= "\t{$tokill}\n";
66
	$towrite .= "}\n\n";
67
	if (!empty($params['restart'])) {
68
		$torestart = &$params['restart'];
69
	} else {
70
		$torestart = "\trc_stop\n";
71
		$torestart .= "\trc_start\n";
72
	}
73
	$towrite .= "rc_restart() {\n";
74
	$towrite .= "{$torestart}\n";
75
	$towrite .= "}\n\n";
76

    
77
	/* begin rcfile logic */
78
	$towrite .= "case \$1 in\n\tstart)\n\t\trc_start\n\t\t;;\n\tstop)\n\t\trc_stop\n\t\t;;\n\trestart)\n\t\trc_restart\n\t\t;;\nesac\n\n";
79

    
80
	@file_put_contents($rcfile_fullname, $towrite);
81
	unset($towrite);
82
	@chmod("{$rcfile_fullname}", 0755);
83

    
84
	return;
85
}
86

    
87
function start_service($name, $after_sync = false) {
88
	if (empty($name)) {
89
		return;
90
	}
91

    
92
	foreach (config_get_path('installedpackages/service', []) as $service) {
93
		if (empty($service)) {
94
			continue;
95
		}
96
		if (isset($service['name']) && (strtolower($service['name']) == strtolower($name))) {
97
			/* Avoid starting twice if this is called just after a
98
			 * package sync which starts the service itself. */
99
			if ($after_sync && isset($service['starts_on_sync'])) {
100
				break;
101
			}
102
			if ($service['rcfile']) {
103
				$prefix = RCFILEPREFIX;
104
				if (!empty($service['prefix'])) {
105
					$prefix = &$service['prefix'];
106
				}
107
				if (file_exists("{$prefix}{$service['rcfile']}") || is_link("{$prefix}{$service['rcfile']}")) {
108
					mwexec_bg("{$prefix}{$service['rcfile']} start");
109
				}
110
			}
111
			if (!empty($service['startcmd'])) {
112
				eval($service['startcmd']);
113
			}
114
			break;
115
		}
116
	}
117
}
118

    
119
function stop_service($name) {
120
	if (empty($name)) {
121
		return;
122
	}
123

    
124
	foreach (config_get_path('installedpackages/service', []) as $service) {
125
		if (empty($service)) {
126
			continue;
127
		}
128
		if (strtolower($service['name']) == strtolower($name)) {
129
			if ($service['rcfile']) {
130
				$prefix = RCFILEPREFIX;
131
				if (!empty($service['prefix'])) {
132
					$prefix = &$service['prefix'];
133
				}
134
				if (file_exists("{$prefix}{$service['rcfile']}") || is_link("{$prefix}{$service['rcfile']}")) {
135
					mwexec("{$prefix}{$service['rcfile']} stop");
136
				}
137
				return;
138
			}
139
			if (!empty($service['stopcmd'])) {
140
				eval($service['stopcmd']);
141
			} elseif (!empty($service['executable'])) {
142
				mwexec("/usr/bin/killall " . escapeshellarg($service['executable']));
143
			}
144

    
145
			break;
146
		}
147
	}
148
}
149

    
150
function restart_service($name) {
151
	if (empty($name)) {
152
		return;
153
	}
154

    
155
	if (is_service_running($name)) {
156
		stop_service($name);
157
	}
158
	start_service($name);
159

    
160
	foreach (config_get_path('installedpackages/service', []) as $service) {
161
		if (empty($service)) {
162
			continue;
163
		}
164
		if (strtolower($service['name']) == strtolower($name)) {
165
			if ($service['restartcmd']) {
166
				eval($service['restartcmd']);
167
			}
168
			break;
169
		}
170
	}
171
}
172

    
173
function is_pid_running($pidfile) {
174
	if (!file_exists($pidfile)) {
175
		return false;
176
	}
177

    
178
	return (isvalidpid($pidfile));
179
}
180

    
181
function is_dhcp_running($interface) {
182
	$status = find_dhclient_process($interface);
183
	if ($status != 0) {
184
		return true;
185
	}
186
	return false;
187
}
188

    
189
function restart_service_if_running($service) {
190
	if (is_service_running($service)) {
191
		restart_service($service);
192
	}
193
	return;
194
}
195

    
196
function is_service_enabled($service_name) {
197
	switch ($service_name) {
198
		case 'bsnmpd':
199
			return config_path_enabled('snmpd');
200
			break;
201
		case 'dhcrelay':
202
			return config_path_enabled('dhcrelay');
203
			break;
204
		case 'dhcrelay6':
205
			return config_path_enabled('dhcrelay6');
206
			break;
207
		case 'dhcpd':
208
			return (dhcp_is_backend('isc') && is_dhcp_server_enabled());
209
			break;
210
		case 'kea-dhcp4':
211
			return (dhcp_is_backend('kea') && is_dhcp_server_enabled());
212
			break;
213
		case 'kea-dhcp6':
214
			return (dhcp_is_backend('kea') && is_dhcpv6_server_enabled());
215
			break;
216
		case 'dnsmasq':
217
			return config_path_enabled('dnsmasq');
218
			break;
219
		case 'dpinger':
220
			/* TODO: Should loop through gateways and check to make
221
			 *       sure they don't all have monitoring disabled. */
222
			$gateways_arr = return_gateways_array();
223
			return is_array($gateways_arr) && !empty($gateways_arr);
224
			break;
225
		case 'igmpproxy':
226
			return (config_path_enabled('igmpproxy') && !empty(config_get_path('igmpproxy/igmpentry', [])));
227
			break;
228
		case 'ipsec':
229
			return ipsec_enabled();
230
			break;
231
		case 'miniupnpd':
232
			return (config_get_path('installedpackages/miniupnpd/config/0/enable') == 'on');
233
			break;
234
		case 'ntpd':
235
			return (config_get_path('ntpd/enable') != 'disabled');
236
			break;
237
		case 'pcscd':
238
			return config_path_enabled('ipsec', 'pkcs11support');
239
			break;
240
		case 'radvd':
241
			return is_radvd_enabled();
242
			break;
243
		case 'sshd':
244
			return config_path_enabled('system/ssh');
245
			break;
246
		case 'syslogd':
247
			$local_enabled = !config_path_enabled('syslog', 'disablelocallogging');
248
			$remote_enabled = !empty(system_syslogd_get_remote_servers(config_get_path('syslog', [])));
249
			return ($local_enabled || $remote_enabled);
250
			break;
251
		case 'unbound':
252
			return config_path_enabled('unbound');
253
			break;
254
		default:
255
			/* Do nothing since we can't determine for certain. */
256
	}
257
	/* TODO: The service name isn't likely to match the config tag,
258
	 *       needs better logic or pkg plugin to probe */
259
	$pkg_enabled = config_get_path("installedpackages/{$service_name}/config/0/enable", null);
260
	if (($pkg_enabled !== null) &&
261
	    (empty($pkg_enabled) || ($pkg_enabled === 'off'))) {
262
		/* Only return false for cases where the config area exists and
263
		 * appears to be disabled. */
264
		return false;
265
	}
266

    
267
	/* Unknown service, for compatibility reasons, return true. */
268
	return true;
269
}
270

    
271
function is_service_running($service, $ps = "") {
272
	foreach (config_get_path('installedpackages/service', []) as $aservice) {
273
		if (empty($aservice)) {
274
			continue;
275
		}
276
		if (isset($aservice['name']) && (strtolower($service) == strtolower($aservice['name']))) {
277
			if ($aservice['custom_php_service_status_command'] <> "") {
278
				eval("\$rc={$aservice['custom_php_service_status_command']};");
279
				return $rc;
280
			}
281
			if (empty($aservice['executable'])) {
282
				return false;
283
			}
284
			if (is_process_running($aservice['executable'])) {
285
				return true;
286
			}
287
			return false;
288
		}
289
	}
290
	if (is_process_running($service)) {
291
		return true;
292
	}
293
	return false;
294
}
295

    
296
function get_services() {
297
	$services = config_get_path('installedpackages/service', []);
298

    
299
	/* Clean up any empty services */
300
	foreach ($services as $k => &$s) {
301
		if (empty($s)) {
302
			config_del_path('installedpackages/services/' . $k);
303
			unset($s);
304
		}
305
	}
306

    
307
	/*
308
	 * Add services that are in the base.
309
	 */
310
	if (is_radvd_enabled()) {
311
		$pconfig = array();
312
		$pconfig['name'] = "radvd";
313
		$pconfig['description'] = gettext("Router Advertisement Daemon");
314
		$pconfig['enabled'] = true;
315
		$pconfig['status'] = get_service_status($pconfig);
316
		$services[] = $pconfig;
317
	}
318

    
319
	if (config_path_enabled('dnsmasq')) {
320
		$pconfig = array();
321
		$pconfig['name'] = "dnsmasq";
322
		$pconfig['description'] = gettext("DNS Forwarder");
323
		$pconfig['enabled'] = true;
324
		$pconfig['status'] = get_service_status($pconfig);
325
		$services[] = $pconfig;
326
	}
327

    
328
	if (config_path_enabled('unbound')) {
329
		$pconfig = array();
330
		$pconfig['name'] = "unbound";
331
		$pconfig['description'] = gettext("DNS Resolver");
332
		$pconfig['enabled'] = true;
333
		$pconfig['status'] = get_service_status($pconfig);
334
		$services[] = $pconfig;
335
	}
336

    
337
	if (config_path_enabled('ipsec', 'pkcs11support')) {
338
		$pconfig = array();
339
		$pconfig['name'] = "pcscd";
340
		$pconfig['description'] = gettext("PC/SC Smart Card Daemon");
341
		$pconfig['enabled'] = true;
342
		$pconfig['status'] = get_service_status($pconfig);
343
		$services[] = $pconfig;
344
	}
345

    
346
	if (config_get_path('ntpd/enable') != 'disabled') {
347
		$pconfig = array();
348
		$pconfig['name'] = "ntpd";
349
		$pconfig['description'] = gettext("NTP clock sync");
350
		$pconfig['enabled'] = true;
351
		$pconfig['status'] = get_service_status($pconfig);
352
		$services[] = $pconfig;
353
	}
354

    
355
	$pconfig = array();
356
	$pconfig['name'] = "syslogd";
357
	$pconfig['description'] = gettext("System Logger Daemon");
358
	$pconfig['enabled'] = is_service_enabled("syslogd");
359
	$pconfig['status'] = get_service_status($pconfig);
360
	$services[] = $pconfig;
361

    
362
	foreach (config_get_path('captiveportal', []) as $zone => $setting) {
363
		if (empty($setting)) {
364
			continue;
365
		}
366
		if (isset($setting['enable'])) {
367
			$pconfig = array();
368
			$pconfig['name'] = "captiveportal";
369
			$pconfig['zone'] = $zone;
370
			$pconfig['enabled'] = true;
371
			$pconfig['description'] = gettext("Captive Portal") . ": " . htmlspecialchars($setting['zone']);
372
			$services[] = $pconfig;
373
		}
374
	}
375

    
376
	$iflist = array();
377
	$ifdescrs = get_configured_interface_list();
378
	foreach ($ifdescrs as $if) {
379
		if (config_get_path("interfaces/{$if}/if") &&
380
		    !link_interface_to_bridge($if)) {
381
			$iflist[$if] = $if;
382
		}
383
	}
384

    
385
	if (config_path_enabled('dhcrelay')) {
386
		$pconfig = array();
387
		$pconfig['name'] = "dhcrelay";
388
		$pconfig['description'] = gettext('ISC DHCP Relay');
389
		$pconfig['enabled'] = true;
390
		$pconfig['status'] = get_service_status($pconfig);
391
		$services[] = $pconfig;
392
	}
393

    
394
	if (config_path_enabled('dhcrelay6')) {
395
		$pconfig = array();
396
		$pconfig['name'] = "dhcrelay6";
397
		$pconfig['description'] = gettext('ISC DHCPv6 Relay');
398
		$pconfig['enabled'] = true;
399
		$pconfig['status'] = get_service_status($pconfig);
400
		$services[] = $pconfig;
401
	}
402

    
403
	if (dhcp_is_backend('isc') && is_dhcp_server_enabled()) {
404
		$pconfig = array();
405
		$pconfig['name'] = "dhcpd";
406
		$pconfig['description'] = gettext('ISC DHCP Server');
407
		$pconfig['enabled'] = true;
408
		$pconfig['status'] = get_service_status($pconfig);
409
		$services[] = $pconfig;
410
	}
411

    
412
	if (dhcp_is_backend('kea') && is_dhcp_server_enabled()) {
413
		$pconfig = array();
414
		$pconfig['name'] = 'kea-dhcp4';
415
		$pconfig['description'] = gettext('Kea DHCP Server');
416
		$pconfig['enabled'] = true;
417
		$pconfig['status'] = get_service_status($pconfig);
418
		$services[] = $pconfig;
419
	}
420

    
421
	if (dhcp_is_backend('kea') && is_dhcpv6_server_enabled()) {
422
		$pconfig = array();
423
		$pconfig['name'] = 'kea-dhcp6';
424
		$pconfig['description'] = gettext('Kea DHCPv6 Server');
425
		$pconfig['enabled'] = true;
426
		$pconfig['status'] = get_service_status($pconfig);
427
		$services[] = $pconfig;
428
	}
429

    
430
	$gateways_arr = return_gateways_array();
431
	if (is_array($gateways_arr) && !empty($gateways_arr)) {
432
		$pconfig = array();
433
		$pconfig['name'] = "dpinger";
434
		$pconfig['description'] = gettext("Gateway Monitoring Daemon");
435
		$pconfig['enabled'] = is_service_enabled("dpinger");
436
		$pconfig['status'] = get_service_status($pconfig);
437
		$services[] = $pconfig;
438
	}
439

    
440
	if (config_path_enabled('snmpd')) {
441
		$pconfig = array();
442
		$pconfig['name'] = "bsnmpd";
443
		$pconfig['description'] = gettext("SNMP Service");
444
		$pconfig['enabled'] = true;
445
		$pconfig['status'] = get_service_status($pconfig);
446
		$services[] = $pconfig;
447
	}
448

    
449
	if (!empty(config_get_path('igmpproxy/igmpentry', []))) {
450
		$pconfig = array();
451
		$pconfig['name'] = "igmpproxy";
452
		$pconfig['description'] = gettext("IGMP proxy");
453
		$pconfig['enabled'] = is_service_enabled("igmpproxy");
454
		$pconfig['status'] = get_service_status($pconfig);
455
		$services[] = $pconfig;
456
	}
457

    
458
	if (config_get_path('installedpackages/miniupnpd/config/0/enable') == 'on') {
459
		$pconfig = array();
460
		$pconfig['name'] = "miniupnpd";
461
		$pconfig['description'] = gettext("UPnP Service");
462
		$pconfig['enabled'] = true;
463
		$pconfig['status'] = get_service_status($pconfig);
464
		$services[] = $pconfig;
465
	}
466

    
467
	if (ipsec_enabled()) {
468
		$pconfig = array();
469
		$pconfig['name'] = "ipsec";
470
		$pconfig['description'] = gettext("IPsec VPN");
471
		$pconfig['enabled'] = true;
472
		$pconfig['status'] = get_service_status($pconfig);
473
		$services[] = $pconfig;
474
	}
475

    
476
	if (config_path_enabled('system/ssh')) {
477
		$pconfig = array();
478
		$pconfig['name'] = "sshd";
479
		$pconfig['description'] = gettext("Secure Shell Daemon");
480
		$pconfig['enabled'] = true;
481
		$pconfig['status'] = get_service_status($pconfig);
482
		$services[] = $pconfig;
483
	}
484

    
485
	foreach (array('server', 'client') as $mode) {
486
		foreach (config_get_path("openvpn/openvpn-{$mode}", []) as $id => $setting) {
487
			if (!isset($setting['disable'])) {
488
				$pconfig = array();
489
				$pconfig['name'] = "openvpn";
490
				$pconfig['mode'] = $mode;
491
				$pconfig['id'] = $id;
492
				$pconfig['vpnid'] = $setting['vpnid'];
493
				$pconfig['description'] = gettext("OpenVPN") . " " . $mode . ": " . htmlspecialchars($setting['description']);
494
				$pconfig['enabled'] = true;
495
				$pconfig['status'] = get_service_status($pconfig);
496
				$services[] = $pconfig;
497
			}
498
		}
499
	}
500

    
501
	return $services;
502
}
503

    
504
function find_service_by_name($name) {
505
	$services = get_services();
506
	foreach ($services as $service) {
507
		if (isset($service["name"]) && ($service["name"] == $name)) {
508
			return $service;
509
		}
510
	}
511
	return array();
512
}
513

    
514
function find_service_by_openvpn_vpnid($vpnid) {
515
	$services = get_services();
516
	foreach ($services as $service) {
517
		if (isset($service["name"]) && ($service["name"] == "openvpn") && isset($service["vpnid"]) && ($service["vpnid"] == $vpnid)) {
518
			return $service;
519
		}
520
	}
521
	return array();
522
}
523

    
524
function find_service_by_cp_zone($zone) {
525
	$services = get_services();
526
	foreach ($services as $service) {
527
		if (isset($service["name"]) && ($service["name"] == "captiveportal") && isset($service["zone"]) && ($service["zone"] == $zone)) {
528
			return $service;
529
		}
530
	}
531
	return array();
532
}
533

    
534
function service_description_compare($a, $b) {
535
	if (strtolower($a['description']) == strtolower($b['description'])) {
536
		return 0;
537
	}
538
	return (strtolower($a['description']) < strtolower($b['description'])) ? -1 : 1;
539
}
540

    
541
function service_name_compare($a, $b) {
542
	if (!isset($a['name']) || !isset($b['name'])) {
543
		return -1;
544
	}
545
	/* If the names are equal, fall back to sorting by description */
546
	if (strtolower($a['name']) == strtolower($b['name'])) {
547
		return service_description_compare($a, $b);
548
	}
549
	return (strtolower($a['name']) < strtolower($b['name'])) ? -1 : 1;
550
}
551

    
552
function service_dispname_compare($a, $b) {
553
	/* If two items have an instance suffix, perform an integer comparison to avoid awkward sorting */
554
	if ((strpos($a['dispname'], '_') > 0) && (strpos($b['dispname'], '_') > 0)) {
555
		list($adn1, $adn2) = explode('_', $a['dispname'], 2);
556
		list($bdn1, $bdn2) = explode('_', $b['dispname'], 2);
557
		if (($adn1 == $bdn1) && is_numeric($adn2) && is_numeric($bdn2)) {
558
			if ($adn2 == $bdn2) {
559
				return 0;
560
			}
561
			return ((int)$adn2 < (int)$bdn2) ? -1 : 1;
562
		}
563
	}
564
	/* If the display names are equal, compare the internal name */
565
	if (strtolower($a['dispname']) == strtolower($b['dispname'])) {
566
		return service_name_compare($a, $b);
567
	}
568
	return (strtolower($a['dispname']) < strtolower($b['dispname'])) ? -1 : 1;
569
}
570

    
571
function get_pkg_descr($package_name) {
572
	foreach (config_get_path('installedpackages/package', []) as $pkg) {
573
		if ($pkg['name'] == $package_name) {
574
			return $pkg['descr'];
575
		}
576
	}
577
	return gettext("Not available.");
578
}
579

    
580
function get_service_status($service) {
581
	global $g;
582
	switch ($service['name']) {
583
		case "openvpn":
584
			$running = is_pid_running("{$g['varrun_path']}/openvpn_{$service['mode']}{$service['vpnid']}.pid");
585
			break;
586
		case "captiveportal":
587
			$running = is_pid_running("{$g['varrun_path']}/nginx-{$service['zone']}-CaptivePortal.pid");
588
			if (config_path_enabled("captiveportal/{$service['zone']}", 'httpslogin')) {
589
				$running = $running && is_pid_running("{$g['varrun_path']}/nginx-{$service['zone']}-CaptivePortal-SSL.pid");
590
			}
591
			break;
592
		case "vhosts-http":
593
			$running = is_pid_running("{$g['varrun_path']}/vhosts-http.pid");
594
			break;
595
		case "dhcrelay6":
596
			$running = is_pid_running("{$g['varrun_path']}/dhcrelay6.pid");
597
			break;
598
		case 'ipsec':
599
			$running = (is_pid_running("{$g['varrun_path']}/charon.pid") || is_process_running('charon'));
600
			break;
601
		case 'kea-dhcp4':
602
			$running = is_pid_running('/var/run/kea/kea-dhcp4.kea-dhcp4.pid');
603
			break;
604
		case 'kea-dhcp6':
605
			$running = is_pid_running('/var/run/kea/kea-dhcp6.kea-dhcp6.pid');
606
			break;
607
		default:
608
			$running = is_service_running($service['name']);
609
	}
610
	return $running;
611
}
612

    
613
function get_service_status_icon($service, $withtext = true, $smallicon = false, $withthumbs = false, $title = "service_state") {
614
	$output = "";
615

    
616
	if (get_service_status($service)) {
617
		$statustext = gettext("Running");
618
		$text_class = "text-success";
619
		$fa_class = "fa fa-check-circle";
620
		$fa_class_thumbs = "fa fa-thumbs-o-up";
621
		$Thumbs_UpDown = "Thumbs up";
622
	} else {
623
		if (is_service_enabled($service['name'])) {
624
			$statustext = gettext("Stopped");
625
			$text_class = "text-danger";
626
			$fa_class = "fa fa-times-circle";
627
		} else {
628
			$statustext = gettext("Disabled");
629
			$text_class = "text-warning";
630
			$fa_class = "fa fa-ban";
631
		}
632
		$fa_class_thumbs = "fa fa-thumbs-o-down";
633
		$Thumbs_UpDown = "Thumbs down";
634
	}
635
	$fa_size = ($smallicon) ? "fa-1x" : "fa-lg";
636

    
637
	if ($title == "state") {
638
		$title = $statustext;
639
	} elseif ($title == "service_state") {
640
		$title = sprintf(gettext('%1$s Service is %2$s'), $service["name"], $statustext);
641
	} elseif ($title == "description_state") {
642
		$title = sprintf(gettext('%1$s Service is %2$s'), $service["description"], $statustext);
643
	} elseif ($title == "description_service_state") {
644
		$title = sprintf(gettext('%1$s, %2$s Service is %3$s'), $service["description"], $service["name"], $statustext);
645
	}
646

    
647
	$spacer = ($withthumbs || $withtext) ? " " : "";
648

    
649
	$output = "<i class=\"{$text_class} {$fa_class} {$fa_size}\" title=\"{$title}\"><span style=\"display: none\">{$statustext}</span></i>{$spacer}";
650

    
651
	$spacer = ($withtext) ? " " : "";
652
	if ($withthumbs) {
653
		$output .= "<i class=\"{$text_class} {$fa_class_thumbs} {$fa_size}\" title=\"{$Thumbs_UpDown}\"></i>{$spacer}";
654
	}
655

    
656
	if ($withtext) {
657
		$output .= "<span class=\"" . $text_class . "\">" . $statustext . "</span>";
658
	}
659

    
660
	return $output;
661
}
662

    
663
function get_service_control_links($service, $addname = false) {
664
	global $g;
665
	$output = "";
666
	$stitle = ($addname) ? $service['name'] . " " : "";
667

    
668
	switch ($service['name']) {
669
		case "openvpn":
670
			$link = '<a title="%s" href="#" id="openvpn-%s-' . $service['mode'] . '-' . $service['vpnid'] . '" >';
671
		break;
672
		case "captiveportal":
673
			$link = '<a title="%s" href="#" id="captiveportal-%s-' . $service['zone'] . '">';
674
		break;
675
		default:
676
			$link = '<a title="%s" href="#" id="%s-' . $service['name'] . '">';
677
	}
678

    
679
	if (get_service_status($service)) {
680
		switch ($service['name']) {
681
			case "openvpn":
682
				$output .= '<a href="#" id="openvpn-restartservice-' . $service['mode'] . '-' . $service['vpnid'] . '" >';
683
				break;
684
			case "captiveportal":
685
				$output .= '<a href="#" id="captiveportal-restartservice-' . $service['zone'] . '">';
686
				break;
687
			default:
688
				$output .= '<a href="#" id="restartservice-' . $service['name'] . '" >';
689
		}
690

    
691
		$output .= "<i class=\"fa fa-repeat\" title=\"" . sprintf(gettext("Restart %sService"), $stitle) . "\"></i></a>\n";
692

    
693
		switch ($service['name']) {
694
			case "openvpn":
695
				$output .= '<a href="#" id="openvpn-stopservice-' . $service['mode'] . '-' . $service['vpnid'] . '" >';
696
				break;
697
			case "captiveportal":
698
				$output .= '<a href="#" id="captiveportal-stopservice-' . $service['zone'] . '">';
699
				break;
700
			default:
701
				$output .= '<a href="#" id="stopservice-' . $service['name'] . '">';
702
		}
703

    
704
		$output .= "<i class=\"fa fa-stop-circle-o\" title=\"" . sprintf(gettext("Stop %sService"), $stitle) . "\"></i></a>";
705

    
706
	} else {
707
		$service_enabled = is_service_enabled($service['name']);
708

    
709
		if ($service['name'] == 'openvpn' || $service['name'] == 'captiveportal' || $service_enabled) {
710
			$output .= sprintf($link, sprintf(gettext("Start %sService"), $stitle), 'startservice');
711
			$output .= '<i class="fa fa-play-circle"></i></a> ';
712
		}
713
	}
714

    
715
	return $output;
716
}
717

    
718
function service_control_start($name, $extras) {
719
	global $g;
720
	switch ($name) {
721
		case 'radvd':
722
			services_radvd_configure();
723
			break;
724
		case 'captiveportal':
725
			$zone = htmlspecialchars($extras['zone']);
726
			captiveportal_init_webgui_zonename($zone);
727
			break;
728
		case 'ntpd':
729
			system_ntp_configure();
730
			break;
731
		case 'dpinger':
732
			setup_gateways_monitor();
733
			break;
734
		case 'bsnmpd':
735
			services_snmpd_configure();
736
			break;
737
		case 'dhcrelay':
738
			services_dhcrelay_configure();
739
			break;
740
		case 'dhcrelay6':
741
			services_dhcrelay6_configure();
742
			break;
743
		case 'dnsmasq':
744
			services_dnsmasq_configure();
745
			break;
746
		case 'unbound':
747
			services_unbound_configure();
748
			break;
749
		case 'kea-dhcp4':
750
		case 'kea-dhcp6':
751
		case 'dhcpd':
752
			services_dhcpd_configure();
753
			break;
754
		case 'igmpproxy':
755
			services_igmpproxy_configure();
756
			break;
757
		case 'miniupnpd':
758
			upnp_action('start');
759
			break;
760
		case 'ipsec':
761
			ipsec_force_reload();
762
			break;
763
		case 'sshd':
764
			send_event("service restart sshd");
765
			break;
766
		case 'pcscd':
767
			ipsec_force_reload();
768
			break;
769
		case 'openvpn':
770
			$vpnmode = isset($extras['vpnmode']) ? htmlspecialchars($extras['vpnmode']) : htmlspecialchars($extras['mode']);
771
			if (($vpnmode == "server") || ($vpnmode == "client")) {
772
				$id = isset($extras['vpnid']) ? htmlspecialchars($extras['vpnid']) : htmlspecialchars($extras['id']);
773
				$configfile = "{$g['openvpn_base']}/{$vpnmode}{$id}/config.ovpn";
774
				if (file_exists($configfile)) {
775
					openvpn_restart_by_vpnid($vpnmode, $id);
776
				}
777
			}
778
			break;
779
		case 'syslogd':
780
			system_syslogd_start();
781
			break;
782
		default:
783
			start_service($name);
784
			break;
785
	}
786
	return sprintf(gettext("%s has been started."), htmlspecialchars($name));
787
}
788
function service_control_stop($name, $extras) {
789
	global $g;
790
	switch ($name) {
791
		case 'radvd':
792
			killbypid("{$g['varrun_path']}/radvd.pid");
793
			break;
794
		case 'captiveportal':
795
			$zone = htmlspecialchars($extras['zone']);
796
			killbypid("{$g['varrun_path']}/nginx-{$zone}-CaptivePortal.pid");
797
			killbypid("{$g['varrun_path']}/nginx-{$zone}-CaptivePortal-SSL.pid");
798
			break;
799
		case 'ntpd':
800
			killbyname("ntpd");
801
			break;
802
		case 'openntpd':
803
			killbyname("openntpd");
804
			break;
805
		case 'dpinger':
806
			stop_dpinger();
807
			break;
808
		case 'bsnmpd':
809
			killbypid("{$g['varrun_path']}/snmpd.pid");
810
			break;
811
		case 'choparp':
812
			killbyname("choparp");
813
			break;
814
		case 'kea-dhcp4':
815
			killbypid('/var/run/kea/kea-dhcp4.kea-dhcp4.pid');
816
			break;
817
		case 'kea-dhcp6':
818
			killbypid('/var/run/kea/kea-dhcp6.kea-dhcp6.pid');
819
			break;
820
		case 'dhcpd':
821
			killbyname("dhcpd");
822
			break;
823
		case 'dhcrelay':
824
			killbypid("{$g['varrun_path']}/dhcrelay.pid");
825
			break;
826
		case 'dhcrelay6':
827
			killbypid("{$g['varrun_path']}/dhcrelay6.pid");
828
			break;
829
		case 'dnsmasq':
830
			killbypid("{$g['varrun_path']}/dnsmasq.pid");
831
			break;
832
		case 'unbound':
833
			killbypid("{$g['varrun_path']}/unbound.pid");
834
			break;
835
		case 'igmpproxy':
836
			killbyname("igmpproxy");
837
			break;
838
		case 'miniupnpd':
839
			upnp_action('stop');
840
			break;
841
		case 'sshd':
842
			killbyname("sshd");
843
			break;
844
		case 'pcscd':
845
		case 'ipsec':
846
			exec("/usr/local/sbin/strongswanrc stop");
847
			if (isvalidproc("pcscd")) {
848
				killbyname("pcscd");
849
			}
850
			break;
851
		case 'openvpn':
852
			$vpnmode = htmlspecialchars($extras['vpnmode']);
853
			if (($vpnmode == "server") or ($vpnmode == "client")) {
854
				$id = htmlspecialchars($extras['id']);
855
				$pidfile = "{$g['varrun_path']}/openvpn_{$vpnmode}{$id}.pid";
856
				killbypid($pidfile);
857
				openvpn_delete_tmp($vpnmode, $id);
858
			}
859
			break;
860
		case 'syslogd':
861
			if (isvalidpid("{$g['varrun_path']}/syslog.pid")) {
862
				sigkillbypid("{$g['varrun_path']}/syslog.pid", "TERM");
863
				usleep(100000);
864
			}
865
			if (isvalidpid("{$g['varrun_path']}/syslog.pid")) {
866
				sigkillbypid("{$g['varrun_path']}/syslog.pid", "KILL");
867
				usleep(100000);
868
			}
869
			/* Make sure sshguard stops as well */
870
			sigkillbyname("sshguard", "TERM");
871
			break;
872
		default:
873
			stop_service($name);
874
			break;
875
	}
876
	return sprintf(gettext("%s has been stopped."), htmlspecialchars($name));
877
}
878

    
879
function service_control_restart($name, $extras) {
880
	global $g;
881
	switch ($name) {
882
		case 'radvd':
883
			services_radvd_configure();
884
			break;
885
		case 'captiveportal':
886
			$zone = htmlspecialchars($extras['zone']);
887
			killbypid("{$g['varrun_path']}/nginx-{$zone}-CaptivePortal.pid");
888
			killbypid("{$g['varrun_path']}/nginx-{$zone}-CaptivePortal-SSL.pid");
889
			/* see https://redmine.pfsense.org/issues/12651 */
890
			sleep(1);
891
			captiveportal_init_webgui_zonename($zone);
892
			break;
893
		case 'ntpd':
894
		case 'openntpd':
895
			system_ntp_configure();
896
			break;
897
		case 'dpinger':
898
			setup_gateways_monitor();
899
			break;
900
		case 'bsnmpd':
901
			services_snmpd_configure();
902
			break;
903
		case 'dhcrelay':
904
			services_dhcrelay_configure();
905
			break;
906
		case 'dhcrelay6':
907
			services_dhcrelay6_configure();
908
			break;
909
		case 'dnsmasq':
910
			services_dnsmasq_configure();
911
			break;
912
		case 'unbound':
913
			services_unbound_configure();
914
			break;
915
		case 'dhcpd':
916
			services_dhcpd_configure();
917
			break;
918
		case 'igmpproxy':
919
			services_igmpproxy_configure();
920
			break;
921
		case 'miniupnpd':
922
			upnp_action('restart');
923
			break;
924
		case 'ipsec':
925
			ipsec_force_reload();
926
			break;
927
		case 'sshd':
928
			send_event("service restart sshd");
929
			break;
930
		case 'pcscd':
931
			exec("/usr/local/sbin/strongswanrc stop");
932
			if (isvalidproc("pcscd")) {
933
				killbyname("pcscd");
934
			}
935
			ipsec_force_reload();
936
			break;
937
		case 'openvpn':
938
			$vpnmode = htmlspecialchars($extras['vpnmode']);
939
			if (($vpnmode == "server") || ($vpnmode == "client")) {
940
				$id = htmlspecialchars($extras['id']);
941
				$configfile = "{$g['openvpn_base']}/{$vpnmode}{$id}/config.ovpn";
942
				if (file_exists($configfile)) {
943
					openvpn_restart_by_vpnid($vpnmode, $id);
944
				}
945
			}
946
			break;
947
		case 'syslogd':
948
			system_syslogd_start();
949
			break;
950
		default:
951
			restart_service($name);
952
			break;
953
	}
954
	return sprintf(gettext("%s has been restarted."), htmlspecialchars($name));
955
}
(46-46/61)