Project

General

Profile

Download (33 KB) Statistics
| Branch: | Tag: | Revision:
1 7597c8e8 Colin Smith
<?php
2 1262d7e7 Renato Botelho
/*
3
 * pkg-utils.inc
4 a2febf9a Stephen Beaver
 *
5 ac24dc24 Renato Botelho
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2005-2006 Colin Smith (ethethlay@gmail.com)
7 81299b5c Renato Botelho
 * Copyright (c) 2004-2016 Rubicon Communications, LLC (Netgate)
8 ac24dc24 Renato Botelho
 * All rights reserved.
9 a2febf9a Stephen Beaver
 *
10 b12ea3fb Renato Botelho
 * Licensed under the Apache License, Version 2.0 (the "License");
11
 * you may not use this file except in compliance with the License.
12
 * You may obtain a copy of the License at
13 a2febf9a Stephen Beaver
 *
14 b12ea3fb Renato Botelho
 * http://www.apache.org/licenses/LICENSE-2.0
15 a2febf9a Stephen Beaver
 *
16 b12ea3fb Renato Botelho
 * Unless required by applicable law or agreed to in writing, software
17
 * distributed under the License is distributed on an "AS IS" BASIS,
18
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19
 * See the License for the specific language governing permissions and
20
 * limitations under the License.
21 8c6516d1 Colin Smith
 */
22 523855b0 Scott Ullrich
23 01a6e665 Ermal
require_once("globals.inc");
24 7eea4407 Ermal
require_once("service-utils.inc");
25 1e8644ca Renato Botelho
26 49aec489 Phil Davis
if (file_exists("/cf/conf/use_xmlreader")) {
27 093bcebc Scott Ullrich
	require_once("xmlreader.inc");
28 49aec489 Phil Davis
} else {
29 093bcebc Scott Ullrich
	require_once("xmlparse.inc");
30 49aec489 Phil Davis
}
31 33b7cc0d Colin Smith
32 1e8644ca Renato Botelho
require_once("pfsense-utils.inc");
33 b47833cc Scott Ullrich
34 eab543ed Ermal
if (!function_exists("pkg_debug")) {
35
	/* set up logging if needed */
36
	function pkg_debug($msg) {
37
		global $g, $debug, $fd_log;
38
39 49aec489 Phil Davis
		if (!$debug) {
40 eab543ed Ermal
			return;
41 49aec489 Phil Davis
		}
42 eab543ed Ermal
43
		if (!$fd_log) {
44 b27ac786 Renato Botelho
			if (!$fd_log = fopen("{$g['tmp_path']}/pkg_mgr_debug.log", "w")) {
45 e791dee8 Renato Botelho
				update_status(gettext("Warning, could not open log for writing.") . "\n");
46 49aec489 Phil Davis
			}
47 eab543ed Ermal
		}
48
		@fwrite($fd_log, $msg);
49
	}
50
}
51
52 c078dd89 Renato Botelho
/* Validate if pkg name is valid */
53
function pkg_valid_name($pkgname) {
54
	global $g;
55
56
	$pattern = "/^{$g['pkg_prefix']}[a-zA-Z0-9\.\-_]+$/";
57
	return preg_match($pattern, $pkgname);
58
}
59
60 c2eb2508 Renato Botelho
/* Remove pkg_prefix from package name if it's present */
61
function pkg_remove_prefix(&$pkg_name) {
62
	global $g;
63
64
	if (substr($pkg_name, 0, strlen($g['pkg_prefix'])) == $g['pkg_prefix']) {
65
		$pkg_name = substr($pkg_name, strlen($g['pkg_prefix']));
66
	}
67 e7405fbf Scott Ullrich
}
68 33b7cc0d Colin Smith
69 d3ff1e59 Renato Botelho
/* Execute pkg update when it's necessary */
70
function pkg_update($force = false) {
71
	global $g;
72
73 6cf87aec Renato Botelho
	return pkg_call("update" . ($force ? " -f" : ""));
74 d3ff1e59 Renato Botelho
}
75
76 75bb92c4 Renato Botelho
/* return an array with necessary environment vars for pkg */
77 a948633c Renato Botelho
function pkg_env($extra_env = array()) {
78 75bb92c4 Renato Botelho
	global $config, $g;
79
80
	$pkg_env_vars = array(
81 e21ac870 Renato Botelho
		"LANG" => "C",
82 75bb92c4 Renato Botelho
		"HTTP_USER_AGENT" => $user_agent,
83 a120c849 Renato Botelho
		"ASSUME_ALWAYS_YES" => "true",
84
		"FETCH_TIMEOUT" => 5,
85
		"FETCH_RETRY" => 2
86 75bb92c4 Renato Botelho
	);
87
88 a7fcbc1e jim-p
	if (!empty($config['system']['proxyurl'])) {
89
		$http_proxy = $config['system']['proxyurl'];
90
		if (!empty($config['system']['proxyport'])) {
91
			$http_proxy .= ':' . $config['system']['proxyport'];
92
		}
93
		$pkg_env_vars['HTTP_PROXY'] = $http_proxy;
94 1060378f jim-p
95
		if (!empty($config['system']['proxyuser']) && !empty($config['system']['proxypass'])) {
96
			$pkg_env_vars['HTTP_PROXY_AUTH'] = "basic:*:{$config['system']['proxyuser']}:{$config['system']['proxypass']}";
97
		}
98 a7fcbc1e jim-p
	}
99
100 dc61252a Renato Botelho
	if (isset($config['system']['use_mfs_tmpvar'])) {
101 75bb92c4 Renato Botelho
		$pkg_env_vars['PKG_DBDIR'] = '/root/var/db/pkg';
102
		$pkg_env_vars['PKG_CACHEDIR'] = '/root/var/cache/pkg';
103
	}
104
105 a948633c Renato Botelho
	foreach ($extra_env as $key => $value) {
106
		$pkg_env_vars[$key] = $value;
107
	}
108
109 75bb92c4 Renato Botelho
	return $pkg_env_vars;
110
}
111
112 c2eb2508 Renato Botelho
/* Execute a pkg call */
113 a948633c Renato Botelho
function pkg_call($params, $mute = false, $extra_env = array()) {
114 e791dee8 Renato Botelho
	global $g, $config;
115 6fd37d04 Renato Botelho
116 c2eb2508 Renato Botelho
	if (empty($params)) {
117
		return false;
118
	}
119
120 96bf5038 Renato Botelho
	$user_agent = $g['product_name'] . '/' . $g['product_version'];
121 3138b2e3 Renato Botelho
	if (!isset($config['system']['do_not_send_host_uuid'])) {
122 21dfcd61 Renato Botelho
		$user_agent .= ' : ' . get_single_sysctl('kern.hostuuid');
123 96bf5038 Renato Botelho
	}
124
125 6fd37d04 Renato Botelho
	$descriptorspec = array(
126
		1 => array("pipe", "w"), /* stdout */
127 a2febf9a Stephen Beaver
		2 => array("pipe", "w")	 /* stderr */
128 6fd37d04 Renato Botelho
	);
129
130 4b834523 Renato Botelho
131 6fd37d04 Renato Botelho
	pkg_debug("pkg_call(): {$params}\n");
132 75bb92c4 Renato Botelho
	$process = proc_open("/usr/sbin/pkg {$params}", $descriptorspec, $pipes,
133 a948633c Renato Botelho
	    '/', pkg_env($extra_env));
134 6fd37d04 Renato Botelho
135
	if (!is_resource($process)) {
136
		return false;
137
	}
138
139
	stream_set_blocking($pipes[1], 0);
140
	stream_set_blocking($pipes[2], 0);
141
142
	/* XXX: should be a tunnable? */
143
	$timeout = 300; // seconds
144
	$error_log = '';
145
146
	do {
147
		$write = array();
148
		$read = array($pipes[1], $pipes[2]);
149
		$except = array();
150
151
		$stream = stream_select($read, $write, $except, null, $timeout);
152
		if ($stream !== FALSE && $stream > 0) {
153
			foreach ($read as $pipe) {
154
				$content = stream_get_contents($pipe);
155
				if ($content == '') {
156
					continue;
157
				}
158
				if ($pipe === $pipes[1]) {
159
					if (!$mute) {
160 e791dee8 Renato Botelho
						update_status($content);
161 6fd37d04 Renato Botelho
					}
162
					flush();
163
				} else if ($pipe === $pipes[2]) {
164
					$error_log .= $content;
165
				}
166
			}
167 49aec489 Phil Davis
		}
168 a2febf9a Stephen Beaver
169 6fd37d04 Renato Botelho
		$status = proc_get_status($process);
170
	} while ($status['running']);
171 a2febf9a Stephen Beaver
172 6fd37d04 Renato Botelho
	fclose($pipes[1]);
173
	fclose($pipes[2]);
174
	proc_close($process);
175
176 4b834523 Renato Botelho
177 1c981897 Renato Botelho
	$rc = $status['exitcode'];
178 6fd37d04 Renato Botelho
179
	pkg_debug("pkg_call(): rc = {$rc}\n");
180
	if ($rc == 0) {
181
		return true;
182
	}
183
184
	pkg_debug("pkg_call(): error_log\n{$error_log}\n");
185
	if (!$mute) {
186 e791dee8 Renato Botelho
		update_status("\n\n" .  sprintf(gettext(
187
		    "ERROR!!! An error occurred on pkg execution (rc = %d) with parameters '%s':"),
188
		    $rc, $params) . "\n" . $error_log . "\n");
189 49aec489 Phil Davis
	}
190 a2febf9a Stephen Beaver
191 6fd37d04 Renato Botelho
	return false;
192 31e7e1bc Scott Ullrich
}
193
194 6fd37d04 Renato Botelho
/* Execute pkg with $params, fill stdout and stderr and return pkg rc */
195 a948633c Renato Botelho
function pkg_exec($params, &$stdout, &$stderr, $extra_env = array()) {
196 96bf5038 Renato Botelho
	global $g, $config;
197 6fd37d04 Renato Botelho
198
	if (empty($params)) {
199
		return -1;
200
	}
201
202 96bf5038 Renato Botelho
	$user_agent = $g['product_name'] . '/' . $g['product_version'];
203 3138b2e3 Renato Botelho
	if (!isset($config['system']['do_not_send_host_uuid'])) {
204 21dfcd61 Renato Botelho
		$user_agent .= ' : ' . get_single_sysctl('kern.hostuuid');
205 96bf5038 Renato Botelho
	}
206
207 6fd37d04 Renato Botelho
	$descriptorspec = array(
208
		1 => array("pipe", "w"), /* stdout */
209 a2febf9a Stephen Beaver
		2 => array("pipe", "w")	 /* stderr */
210 6fd37d04 Renato Botelho
	);
211
212 4b834523 Renato Botelho
213 6fd37d04 Renato Botelho
	pkg_debug("pkg_exec(): {$params}\n");
214 75bb92c4 Renato Botelho
	$process = proc_open("/usr/sbin/pkg {$params}", $descriptorspec, $pipes,
215 a948633c Renato Botelho
	    '/', pkg_env($extra_env));
216 6fd37d04 Renato Botelho
217
	if (!is_resource($process)) {
218
		return -1;
219
	}
220
221
	$stdout = '';
222
	while (($l = fgets($pipes[1])) !== FALSE) {
223
		$stdout .= $l;
224
	}
225
	fclose($pipes[1]);
226
227
	$stderr = '';
228
	while (($l = fgets($pipes[2])) !== FALSE) {
229
		$stderr .= $l;
230
	}
231
	fclose($pipes[2]);
232 c2eb2508 Renato Botelho
233 4b834523 Renato Botelho
234 6fd37d04 Renato Botelho
	return proc_close($process);
235 c2eb2508 Renato Botelho
}
236
237 8df1877b Renato Botelho
/* Compare 2 pkg versions and return:
238
 * '=' - versions are the same
239
 * '>' - $v1 > $v2
240
 * '<' - $v1 < $v2
241
 * '?' - Error
242
 */
243
function pkg_version_compare($v1, $v2) {
244
	if (empty($v1) || empty($v2)) {
245
		return '?';
246
	}
247
248 500dfdb8 Renato Botelho
	$rc = pkg_exec("version -t '{$v1}' '{$v2}'", $stdout, $stderr);
249 8df1877b Renato Botelho
250
	if ($rc != 0) {
251
		return '?';
252
	}
253
254
	return str_replace("\n", "", $stdout);
255
}
256
257 c2eb2508 Renato Botelho
/* Check if package is installed */
258
function is_pkg_installed($pkg_name) {
259
	global $g;
260
261 f5b1c660 Renato Botelho
	if (empty($pkg_name)) {
262
		return false;
263
	}
264 c2eb2508 Renato Botelho
265 500dfdb8 Renato Botelho
	return pkg_call("info -e " . $pkg_name, true);
266 c2eb2508 Renato Botelho
}
267
268 7379d80f Renato Botelho
/* Install package, $pkg_name should not contain prefix */
269 46903fb9 Renato Botelho
function pkg_install($pkg_name, $force = false) {
270 7379d80f Renato Botelho
	global $g;
271 e7553e1b Renato Botelho
	$result = false;
272 7379d80f Renato Botelho
273 f5b1c660 Renato Botelho
	$shortname = $pkg_name;
274
	pkg_remove_prefix($shortname);
275 7379d80f Renato Botelho
276 46903fb9 Renato Botelho
	$pkg_force = "";
277
	if ($force) {
278
		$pkg_force = "-f ";
279
	}
280
281 f5b1c660 Renato Botelho
	pkg_debug("Installing package {$shortname}\n");
282 46903fb9 Renato Botelho
	if ($force || !is_pkg_installed($pkg_name)) {
283 f5b1c660 Renato Botelho
		$result = pkg_call("install -y " . $pkg_force . $pkg_name);
284 e7553e1b Renato Botelho
		/* Cleanup cacke to free disk space */
285
		pkg_call("clean -y");
286 7379d80f Renato Botelho
	}
287
288 e7553e1b Renato Botelho
	return $result;
289 7379d80f Renato Botelho
}
290
291 c2eb2508 Renato Botelho
/* Delete package from FreeBSD, $pkg_name should not contain prefix */
292
function pkg_delete($pkg_name) {
293
	global $g;
294
295 f5b1c660 Renato Botelho
	$shortname = $pkg_name;
296
	pkg_remove_prefix($shortname);
297 c2eb2508 Renato Botelho
298 f5b1c660 Renato Botelho
	pkg_debug("Removing package {$shortname}\n");
299 c2eb2508 Renato Botelho
	if (is_pkg_installed($pkg_name)) {
300 f5b1c660 Renato Botelho
		pkg_call("delete -y " . $pkg_name);
301 c2eb2508 Renato Botelho
		/* Cleanup unecessary dependencies */
302 e1382589 Renato Botelho
		pkg_call("autoremove -y");
303 49aec489 Phil Davis
	}
304 8c6516d1 Colin Smith
}
305 43db85f8 Scott Ullrich
306 af5d93f6 Renato Botelho
/* Check if package is present in config.xml */
307
function is_package_installed($package_name) {
308
	return (get_package_id($package_name) != -1);
309 8c6516d1 Colin Smith
}
310 43db85f8 Scott Ullrich
311 af5d93f6 Renato Botelho
/* Find package array index */
312
function get_package_id($package_name) {
313 e65a287f Scott Ullrich
	global $config;
314
315 af5d93f6 Renato Botelho
	if (!is_array($config['installedpackages']['package'])) {
316
		return -1;
317
	}
318
319
	foreach ($config['installedpackages']['package'] as $idx => $pkg) {
320 a50534b6 Renato Botelho
		if ($pkg['name'] == $package_name ||
321 4e322e2c Phil Davis
		    get_package_internal_name($pkg) == $package_name) {
322 af5d93f6 Renato Botelho
			return $idx;
323 e65a287f Scott Ullrich
		}
324
	}
325 af5d93f6 Renato Botelho
326 e65a287f Scott Ullrich
	return -1;
327 8c6516d1 Colin Smith
}
328
329 af5d93f6 Renato Botelho
/* Return internal_name when it's defined, otherwise, returns name */
330
function get_package_internal_name($package_data) {
331
	if (isset($package_data['internal_name']) && ($package_data['internal_name'] != "")) {
332 75a01a7c Phil Davis
		/* e.g. name is Ipguard-dev, internal name is ipguard */
333 af5d93f6 Renato Botelho
		return $package_data['internal_name'];
334 75a01a7c Phil Davis
	} else {
335 af5d93f6 Renato Botelho
		return $package_data['name'];
336 75a01a7c Phil Davis
	}
337
}
338
339 a2febf9a Stephen Beaver
// Get information about packages.
340 1e85a9ed Renato Botelho
function get_pkg_info($pkgs = 'all', $only_local = false) {
341 e791dee8 Renato Botelho
	global $g, $input_errors;
342 b2a66231 Ermal
343 65c94077 Renato Botelho
	$out = '';
344
	$err = '';
345 e65a287f Scott Ullrich
346 d65fc2ff Renato Botelho
	unset($pkg_filter);
347
	if (is_array($pkgs)) {
348
		$pkg_filter = $pkgs;
349
		$pkgs = 'all';
350
	}
351
352 65c94077 Renato Botelho
	if ($pkgs == 'all') {
353 1e85a9ed Renato Botelho
		$pkgs = $g['pkg_prefix'];
354 65c94077 Renato Botelho
	}
355 b2a66231 Ermal
356 9b7cfb3f Renato Botelho
	if (!function_exists('is_subsystem_dirty')) {
357
		require_once("util.inc");
358
	}
359
360
	/* Do not run remote operations if pkg has a lock */
361
	if (is_subsystem_dirty('pkg')) {
362 1e85a9ed Renato Botelho
		$only_local = true;
363 9b7cfb3f Renato Botelho
		$lock = false;
364
	} else {
365
		$lock = true;
366
	}
367
368 c86db913 Renato Botelho
	$extra_param = "";
369 1e85a9ed Renato Botelho
	if ($only_local) {
370 c86db913 Renato Botelho
		$extra_param = "-U ";
371
	}
372
373 9b7cfb3f Renato Botelho
	if ($lock) {
374
		mark_subsystem_dirty('pkg');
375
	}
376 1e85a9ed Renato Botelho
	$rc = pkg_exec("search {$extra_param}-R --raw-format json-compact " . $pkgs, $out, $err);
377 9b7cfb3f Renato Botelho
	if ($lock) {
378
		clear_subsystem_dirty('pkg');
379
	}
380 b2a66231 Ermal
381 65c94077 Renato Botelho
	if ($rc != 0) {
382 e791dee8 Renato Botelho
		update_status("\n" . gettext(
383
		    "ERROR: Error trying to get packages list. Aborting...")
384
		    . "\n");
385
		update_status($err);
386 5c22f8ef Stephen Beaver
		$input_errors[] =  gettext("ERROR: Error trying to get packages list. Aborting...") . "\n";
387
		$input_errors[] =  $err;
388 65c94077 Renato Botelho
		return array();
389
	}
390
391
	$result = array();
392
	$pkgs_info = explode("\n", $out);
393
	foreach ($pkgs_info as $pkg_info_json) {
394
		$pkg_info = json_decode($pkg_info_json, true);
395
		if (!isset($pkg_info['name'])) {
396
			continue;
397
		}
398
399 d65fc2ff Renato Botelho
		if (isset($pkg_filter) && !in_array($pkg_info['name'], $pkg_filter)) {
400
			continue;
401
		}
402
403 b9e2048a Renato Botelho
		$pkg_info['shortname'] = $pkg_info['name'];
404
		pkg_remove_prefix($pkg_info['shortname']);
405
406
		/* XXX: Add it to globals.inc? */
407
		$pkg_info['changeloglink'] =
408
		    "https://github.com/pfsense/FreeBSD-ports/commits/devel/" .
409
		    $pkg_info['categories'][0] . '/' . $pkg_info['name'];
410
411 77340246 Renato Botelho
		if (is_pkg_installed($pkg_info['name'])) {
412
			$pkg_info['installed'] = true;
413 54f236f7 Renato Botelho
414 500dfdb8 Renato Botelho
			$rc = pkg_exec("query %v {$pkg_info['name']}", $out, $err);
415 54f236f7 Renato Botelho
416
			if ($rc != 0) {
417 e791dee8 Renato Botelho
				update_status("\n" . gettext(
418
				    "ERROR: Error trying to get package version. Aborting...")
419
				    . "\n");
420
				update_status($err);
421 54f236f7 Renato Botelho
				$input_errors[] =  gettext("ERROR: Error trying to get package version. Aborting...") . "\n";
422
				$input_errors[] =  $err;
423
				return array();
424
			}
425
426
			$pkg_info['installed_version'] = str_replace("\n", "", $out);
427 82692fe1 Renato Botelho
		} else if (is_package_installed($pkg_info['shortname'])) {
428
			$pkg_info['broken'] = true;
429 77340246 Renato Botelho
		}
430
431 c8cae8e5 Renato Botelho
		$pkg_info['desc'] = preg_replace('/\n+WWW:.*$/', '', $pkg_info['desc']);
432
433 65c94077 Renato Botelho
		$result[] = $pkg_info;
434
		unset($pkg_info);
435 34da63c3 Colin Smith
	}
436 b2a66231 Ermal
437 c5ecf722 Renato Botelho
	/* Sort result alphabetically */
438
	usort($result, function($a, $b) {
439
		return(strcasecmp ($a['name'], $b['name']));
440
	});
441
442 65c94077 Renato Botelho
	return $result;
443 8c6516d1 Colin Smith
}
444
445 bed6c19b Renato Botelho
/*
446
 * If binary pkg is installed but post-install tasks were not
447 0d0f419e Phil Davis
 * executed yet, do it now.
448 bed6c19b Renato Botelho
 * This scenario can happen when a pkg is pre-installed during
449
 * build phase, and at this point, cannot find a running system
450
 * to register itself in config.xml and also execute custom
451
 * install functions
452
 */
453
function register_all_installed_packages() {
454
	global $g, $config, $pkg_interface;
455
456 1e85a9ed Renato Botelho
	$pkg_info = get_pkg_info('all', true);
457 bed6c19b Renato Botelho
458
	foreach ($pkg_info as $pkg) {
459
		if (!isset($pkg['installed'])) {
460
			continue;
461
		}
462
463
		pkg_remove_prefix($pkg['name']);
464
465
		if (is_package_installed($pkg['name'])) {
466
			continue;
467
		}
468
469
		update_status(sprintf(gettext(
470
		    "Running last steps of %s installation.") . "\n",
471
		    $pkg['name']));
472
		install_package_xml($pkg['name']);
473
	}
474
}
475
476 8c6516d1 Colin Smith
/*
477
 * resync_all_package_configs() Force packages to setup their configuration and rc.d files.
478
 * This function may also print output to the terminal indicating progress.
479
 */
480
function resync_all_package_configs($show_message = false) {
481 b1224cdc jim-p
	global $config, $pkg_interface, $g;
482 b2a66231 Ermal
483 6acdf659 Carlos Eduardo Ramos
	log_error(gettext("Resyncing configuration for all packages."));
484 06e57df8 Scott Ullrich
485 49aec489 Phil Davis
	if (!is_array($config['installedpackages']['package'])) {
486 3a9eb3c9 Ermal
		return;
487 49aec489 Phil Davis
	}
488 06e57df8 Scott Ullrich
489 49aec489 Phil Davis
	if ($show_message == true) {
490 3a9eb3c9 Ermal
		echo "Syncing packages:";
491 49aec489 Phil Davis
	}
492 b2a66231 Ermal
493 06e57df8 Scott Ullrich
494 49aec489 Phil Davis
	foreach ($config['installedpackages']['package'] as $idx => $package) {
495
		if (empty($package['name'])) {
496 2addd5b2 Ermal
			continue;
497 49aec489 Phil Davis
		}
498
		if ($show_message == true) {
499 2addd5b2 Ermal
			echo " " . $package['name'];
500 49aec489 Phil Davis
		}
501
		if (platform_booting() != true) {
502 af5d93f6 Renato Botelho
			stop_service(get_package_internal_name($package));
503 49aec489 Phil Davis
		}
504 a0d4336f Renato Botelho
		sync_package($package['name']);
505 e791dee8 Renato Botelho
		update_status(gettext("Syncing packages...") . "\n");
506 e65a287f Scott Ullrich
	}
507 06e57df8 Scott Ullrich
508 49aec489 Phil Davis
	if ($show_message == true) {
509 08452bff Warren Baker
		echo " done.\n";
510 49aec489 Phil Davis
	}
511 06e57df8 Scott Ullrich
512 3a9eb3c9 Ermal
	@unlink("/conf/needs_package_sync");
513 8c6516d1 Colin Smith
}
514
515 d1a8f050 Renato Botelho
function uninstall_package($package_name) {
516 e791dee8 Renato Botelho
	global $config;
517 b2a66231 Ermal
518 0d579b59 Renato Botelho
	$internal_name = $package_name;
519 d1a8f050 Renato Botelho
	$id = get_package_id($package_name);
520 df5da531 Ermal
	if ($id >= 0) {
521 d1a8f050 Renato Botelho
		$internal_name = get_package_internal_name($config['installedpackages']['package'][$id]);
522
		stop_service($internal_name);
523 0d579b59 Renato Botelho
	}
524 f5b1c660 Renato Botelho
	$pkg_name = $g['pkg_prefix'] . $internal_name;
525 0d579b59 Renato Botelho
526 f5b1c660 Renato Botelho
	if (is_pkg_installed($pkg_name)) {
527 e791dee8 Renato Botelho
		update_status(gettext("Removing package...") . "\n");
528 f5b1c660 Renato Botelho
		pkg_delete($pkg_name);
529 0d579b59 Renato Botelho
	} else {
530
		delete_package_xml($package_name);
531 1570d27a Ermal Lu?i
	}
532 4c6a49d7 Scott Ullrich
533 e791dee8 Renato Botelho
	update_status(gettext("done.") . "\n");
534 f898cf33 Scott Ullrich
}
535
536 a0d4336f Renato Botelho
/* Run <custom_php_resync_config_command> */
537
function sync_package($package_name) {
538
	global $config, $builder_package_install;
539 2d26ee5e Sjon Hortensius
540
	// If this code is being called by pfspkg_installer
541 09e11b69 Scott Ullrich
	// which the builder system uses then return (ignore).
542 49aec489 Phil Davis
	if ($builder_package_install) {
543 f0695975 Scott Ullrich
		return;
544 49aec489 Phil Davis
	}
545 2d26ee5e Sjon Hortensius
546 49aec489 Phil Davis
	if (empty($config['installedpackages']['package'])) {
547 b2a66231 Ermal
		return;
548 49aec489 Phil Davis
	}
549 a0d4336f Renato Botelho
550
	if (($pkg_id = get_package_id($package_name)) == -1) {
551
		return; // This package doesn't really exist - exit the function.
552 49aec489 Phil Davis
	}
553 3e643dba Ermal LUÇI
554 49aec489 Phil Davis
	if (!is_array($config['installedpackages']['package'][$pkg_id])) {
555 a2febf9a Stephen Beaver
		return;	 // No package belongs to the pkg_id passed to this function.
556 49aec489 Phil Davis
	}
557 3e643dba Ermal LUÇI
558
	$package =& $config['installedpackages']['package'][$pkg_id];
559 49aec489 Phil Davis
	if (!file_exists("/usr/local/pkg/" . $package['configurationfile'])) {
560 6acdf659 Carlos Eduardo Ramos
		log_error(sprintf(gettext("The %s package is missing its configuration file and must be reinstalled."), $package['name']));
561 106574d1 Renato Botelho
		delete_package_xml($package['name']);
562 a0d4336f Renato Botelho
		return;
563 2c794549 Ermal
	}
564 a0d4336f Renato Botelho
565 2c794549 Ermal
	$pkg_config = parse_xml_config_pkg("/usr/local/pkg/" . $package['configurationfile'], "packagegui");
566 49aec489 Phil Davis
	if (isset($pkg_config['nosync'])) {
567 2addd5b2 Ermal
		return;
568 49aec489 Phil Davis
	}
569 a0d4336f Renato Botelho
570 2c794549 Ermal
	/* Bring in package include files */
571
	if (!empty($pkg_config['include_file'])) {
572
		$include_file = $pkg_config['include_file'];
573 49aec489 Phil Davis
		if (file_exists($include_file)) {
574 2c794549 Ermal
			require_once($include_file);
575 49aec489 Phil Davis
		} else {
576 e8c516a0 Phil Davis
			log_error(sprintf(gettext('Reinstalling package %1$s because its include file(%2$s) is missing!'), $package['name'], $include_file));
577 2c794549 Ermal
			uninstall_package($package['name']);
578 fad3ad59 Renato Botelho
			if (install_package($package['name']) != 0) {
579 e8c516a0 Phil Davis
				log_error(sprintf(gettext("Reinstalling package %s failed. Take appropriate measures!!!"), $package['name']));
580 a0d4336f Renato Botelho
				return;
581
			}
582
			if (file_exists($include_file)) {
583
				require_once($include_file);
584
			} else {
585
				return;
586 83cfae8d Ermal Lu?i
			}
587 30e4c34a Scott Ullrich
		}
588 2c794549 Ermal
	}
589 30e4c34a Scott Ullrich
590 49aec489 Phil Davis
	if (!empty($pkg_config['custom_php_global_functions'])) {
591 2c794549 Ermal
		eval($pkg_config['custom_php_global_functions']);
592 49aec489 Phil Davis
	}
593
	if (!empty($pkg_config['custom_php_resync_config_command'])) {
594 2c794549 Ermal
		eval($pkg_config['custom_php_resync_config_command']);
595 49aec489 Phil Davis
	}
596 8c6516d1 Colin Smith
}
597
598 801fcf24 Renato Botelho
/* Read info.xml installed by package and return an array */
599
function read_package_config($package_name) {
600
	global $g;
601 e5b5e29c Renato Botelho
602 801fcf24 Renato Botelho
	$pkg_info_xml = '/usr/local/share/' . $g['pkg_prefix'] . $package_name . '/info.xml';
603 7860191a Renato Botelho
604 801fcf24 Renato Botelho
	if (!file_exists($pkg_info_xml)) {
605
		return false;
606
	}
607 7860191a Renato Botelho
608 801fcf24 Renato Botelho
	$pkg_info = parse_xml_config_pkg($pkg_info_xml, 'pfsensepkgs');
609 7860191a Renato Botelho
610 801fcf24 Renato Botelho
	if (empty($pkg_info)) {
611
		return false;
612 43dad535 Vinicius Coque
	}
613 801fcf24 Renato Botelho
614
	/* it always returns an array with 1 item */
615
	return $pkg_info['package'][0];
616 8c6516d1 Colin Smith
}
617
618 a2b0d909 Renato Botelho
/* Read package configurationfile and return an array */
619
function read_package_configurationfile($package_name) {
620
	global $config, $g;
621
622
	$pkg_config = array();
623
	$id = get_package_id($package_name);
624
625
	if ($id < 0 || !isset($config['installedpackages']['package'][$id]['configurationfile'])) {
626
		return $pkg_config;
627
	}
628
629
	$pkg_configurationfile = $config['installedpackages']['package'][$id]['configurationfile'];
630
631
	if (empty($pkg_configurationfile) || !file_exists('/usr/local/pkg/' . $pkg_configurationfile)) {
632
		return $pkg_config;
633
	}
634
635
	$pkg_config = parse_xml_config_pkg('/usr/local/pkg/' . $pkg_configurationfile, "packagegui");
636
637
	return $pkg_config;
638
}
639
640 801fcf24 Renato Botelho
function get_after_install_info($package_name) {
641 666c49ce Renato Botelho
	$pkg_config = read_package_config($package_name);
642 384e2647 Renato Botelho
643 801fcf24 Renato Botelho
	if (isset($pkg_config['after_install_info'])) {
644
		return $pkg_config['after_install_info'];
645 49aec489 Phil Davis
	}
646 384e2647 Renato Botelho
647 801fcf24 Renato Botelho
	return '';
648
}
649 384e2647 Renato Botelho
650 801fcf24 Renato Botelho
function eval_once($toeval) {
651
	global $evaled;
652
	if (!$evaled) {
653
		$evaled = array();
654 49aec489 Phil Davis
	}
655 801fcf24 Renato Botelho
	$evalmd5 = md5($toeval);
656
	if (!in_array($evalmd5, $evaled)) {
657
		@eval($toeval);
658
		$evaled[] = $evalmd5;
659 384e2647 Renato Botelho
	}
660 801fcf24 Renato Botelho
	return;
661 384e2647 Renato Botelho
}
662
663 801fcf24 Renato Botelho
function install_package_xml($package_name) {
664 e791dee8 Renato Botelho
	global $g, $config, $pkg_interface;
665 bfe9c9e7 jim-p
666 801fcf24 Renato Botelho
	if (($pkg_info = read_package_config($package_name)) == false) {
667
		return false;
668 49aec489 Phil Davis
	}
669 cfde64b8 Scott Ullrich
670 801fcf24 Renato Botelho
	/* safe side. Write config below will send to ro again. */
671
672 c92ccac7 Vinicius Coque
	pkg_debug(gettext("Beginning package installation.") . "\n");
673
	log_error(sprintf(gettext('Beginning package installation for %s .'), $pkg_info['name']));
674 2a0e6517 Colin Smith
675 7597c8e8 Colin Smith
	/* add package information to config.xml */
676 af5d93f6 Renato Botelho
	$pkgid = get_package_id($pkg_info['name']);
677 e791dee8 Renato Botelho
	update_status(gettext("Saving updated package information...") . "\n");
678 49aec489 Phil Davis
	if ($pkgid == -1) {
679 7597c8e8 Colin Smith
		$config['installedpackages']['package'][] = $pkg_info;
680 086cf944 Phil Davis
		$changedesc = sprintf(gettext("Installed %s package."), $pkg_info['name']);
681 6acdf659 Carlos Eduardo Ramos
		$to_output = gettext("done.") . "\n";
682 7597c8e8 Colin Smith
	} else {
683
		$config['installedpackages']['package'][$pkgid] = $pkg_info;
684 6acdf659 Carlos Eduardo Ramos
		$changedesc = sprintf(gettext("Overwrote previous installation of %s."), $pkg_info['name']);
685
		$to_output = gettext("overwrite!") . "\n";
686 7597c8e8 Colin Smith
	}
687 801fcf24 Renato Botelho
	unlink_if_exists('/conf/needs_package_sync');
688 e8c516a0 Phil Davis
	write_config(sprintf(gettext("Intermediate config write during package install for %s."), $pkg_info['name']));
689 e791dee8 Renato Botelho
	update_status($to_output);
690 b2a66231 Ermal
691 801fcf24 Renato Botelho
	if (($pkgid = get_package_id($package_name)) == -1) {
692 e791dee8 Renato Botelho
		update_status(sprintf(gettext("The %s package is not installed.%sInstallation aborted."), $package_name, "\n\n"));
693 b2a66231 Ermal
694 801fcf24 Renato Botelho
		uninstall_package($package_name);
695
		write_config($changedesc);
696
		log_error(sprintf(gettext("Failed to install package: %s."), $pkg_info['name']));
697 e791dee8 Renato Botelho
		update_status(gettext("Failed to install package.") . "\n");
698 2c794549 Ermal
		return false;
699 e65a287f Scott Ullrich
	}
700 bfe9c9e7 jim-p
701 5a5cbf01 jim-p
	if (file_exists("/usr/local/pkg/" . $pkg_info['configurationfile'])) {
702 e791dee8 Renato Botelho
		update_status(gettext("Loading package configuration... "));
703 5a5cbf01 jim-p
		$pkg_config = parse_xml_config_pkg("/usr/local/pkg/" . $pkg_info['configurationfile'], "packagegui");
704 e791dee8 Renato Botelho
		update_status(gettext("done.") . "\n");
705
		update_status(gettext("Configuring package components...") . "\n");
706 49aec489 Phil Davis
		if (!empty($pkg_config['filter_rules_needed'])) {
707 bc771948 Ermal Lu?i
			$config['installedpackages']['package'][$pkgid]['filter_rule_function'] = $pkg_config['filter_rules_needed'];
708 49aec489 Phil Davis
		}
709 7597c8e8 Colin Smith
		/* modify system files */
710 b2a66231 Ermal
711 a2febf9a Stephen Beaver
		/* if a require exists, include it.  this will
712
		 * show us where an error exists in a package
713
		 * instead of making us blindly guess
714 2df5cb99 Scott Ullrich
		 */
715 fcf92dae Ermal
		$missing_include = false;
716 49aec489 Phil Davis
		if ($pkg_config['include_file'] <> "") {
717 e791dee8 Renato Botelho
			update_status(gettext("Loading package instructions...") . "\n");
718 49aec489 Phil Davis
			if (file_exists($pkg_config['include_file'])) {
719 9b1aa8d9 Renato Botelho
				pkg_debug("require_once('{$pkg_config['include_file']}')\n");
720 43ad432c Ermal Lu?i
				require_once($pkg_config['include_file']);
721 49aec489 Phil Davis
			} else {
722 9b1aa8d9 Renato Botelho
				pkg_debug("Missing include {$pkg_config['include_file']}\n");
723 fcf92dae Ermal
				$missing_include = true;
724 e8c516a0 Phil Davis
				update_status(sprintf(gettext("Include %s is missing!"), basename($pkg_config['include_file'])) . "\n");
725 801fcf24 Renato Botelho
726
				uninstall_package($package_name);
727
				write_config($changedesc);
728
				log_error(sprintf(gettext("Failed to install package: %s."), $pkg_info['name']));
729 e791dee8 Renato Botelho
				update_status(gettext("Failed to install package.") . "\n");
730 fcf92dae Ermal
				return false;
731
			}
732 43db85f8 Scott Ullrich
		}
733 57811192 Ermal
734
		/* custom commands */
735 e791dee8 Renato Botelho
		update_status(gettext("Custom commands...") . "\n");
736 57811192 Ermal
		if ($missing_include == false) {
737 49aec489 Phil Davis
			if ($pkg_config['custom_php_global_functions'] <> "") {
738 e791dee8 Renato Botelho
				update_status(gettext("Executing custom_php_global_functions()..."));
739 57811192 Ermal
				eval_once($pkg_config['custom_php_global_functions']);
740 e791dee8 Renato Botelho
				update_status(gettext("done.") . "\n");
741 57811192 Ermal
			}
742 49aec489 Phil Davis
			if ($pkg_config['custom_php_install_command']) {
743 e791dee8 Renato Botelho
				update_status(gettext("Executing custom_php_install_command()..."));
744 57811192 Ermal
				eval_once($pkg_config['custom_php_install_command']);
745 e791dee8 Renato Botelho
				update_status(gettext("done.") . "\n");
746 57811192 Ermal
			}
747 49aec489 Phil Davis
			if ($pkg_config['custom_php_resync_config_command'] <> "") {
748 e791dee8 Renato Botelho
				update_status(gettext("Executing custom_php_resync_config_command()..."));
749 57811192 Ermal
				eval_once($pkg_config['custom_php_resync_config_command']);
750 e791dee8 Renato Botelho
				update_status(gettext("done.") . "\n");
751 57811192 Ermal
			}
752
		}
753 7597c8e8 Colin Smith
		/* sidebar items */
754 49aec489 Phil Davis
		if (is_array($pkg_config['menu'])) {
755 e791dee8 Renato Botelho
			update_status(gettext("Menu items... "));
756 49aec489 Phil Davis
			foreach ($pkg_config['menu'] as $menu) {
757
				if (is_array($config['installedpackages']['menu'])) {
758
					foreach ($config['installedpackages']['menu'] as $amenu) {
759
						if ($amenu['name'] == $menu['name']) {
760 1570d27a Ermal Lu?i
							continue 2;
761 49aec489 Phil Davis
						}
762
					}
763
				} else {
764 27018d3c Ermal
					$config['installedpackages']['menu'] = array();
765 49aec489 Phil Davis
				}
766 1570d27a Ermal Lu?i
				$config['installedpackages']['menu'][] = $menu;
767 7597c8e8 Colin Smith
			}
768 e791dee8 Renato Botelho
			update_status(gettext("done.") . "\n");
769 7597c8e8 Colin Smith
		}
770 2dc264a4 Colin Smith
		/* services */
771 49aec489 Phil Davis
		if (is_array($pkg_config['service'])) {
772 e791dee8 Renato Botelho
			update_status(gettext("Services... "));
773 49aec489 Phil Davis
			foreach ($pkg_config['service'] as $service) {
774
				if (is_array($config['installedpackages']['service'])) {
775
					foreach ($config['installedpackages']['service'] as $aservice) {
776
						if ($aservice['name'] == $service['name']) {
777 d282095a Renato Botelho
							continue 2;
778 49aec489 Phil Davis
						}
779
					}
780
				} else {
781 27018d3c Ermal
					$config['installedpackages']['service'] = array();
782 49aec489 Phil Davis
				}
783 2dc264a4 Colin Smith
				$config['installedpackages']['service'][] = $service;
784
			}
785 e791dee8 Renato Botelho
			update_status(gettext("done.") . "\n");
786 2dc264a4 Colin Smith
		}
787 7597c8e8 Colin Smith
	} else {
788 9b1aa8d9 Renato Botelho
		pkg_debug("Unable to find config file\n");
789 e791dee8 Renato Botelho
		update_status(gettext("Loading package configuration... failed!") . "\n\n" . gettext("Installation aborted."));
790 c92ccac7 Vinicius Coque
		pkg_debug(gettext("Unable to load package configuration. Installation aborted.") ."\n");
791 801fcf24 Renato Botelho
792
		uninstall_package($package_name);
793
		write_config($changedesc);
794
		log_error(sprintf(gettext("Failed to install package: %s."), $pkg_info['name']));
795 e791dee8 Renato Botelho
		update_status(gettext("Failed to install package.") . "\n");
796 2c794549 Ermal
		return false;
797 7597c8e8 Colin Smith
	}
798 2c794549 Ermal
799
	/* set up package logging streams */
800 49aec489 Phil Davis
	if ($pkg_info['logging']) {
801 2c794549 Ermal
		system_syslogd_start();
802
	}
803
804 e791dee8 Renato Botelho
	update_status(gettext("Writing configuration... "));
805 801fcf24 Renato Botelho
	write_config($changedesc);
806
	log_error(sprintf(gettext("Successfully installed package: %s."), $pkg_info['name']));
807 e791dee8 Renato Botelho
	update_status(gettext("done.") . "\n");
808 801fcf24 Renato Botelho
	if ($pkg_info['after_install_info']) {
809 e791dee8 Renato Botelho
		update_status($pkg_info['after_install_info']);
810 2d26ee5e Sjon Hortensius
	}
811 801fcf24 Renato Botelho
812 2c794549 Ermal
	return true;
813 64974db7 Scott Ullrich
}
814
815 3bb7e3e8 Renato Botelho
function delete_package_xml($package_name, $when = "post-deinstall") {
816 e791dee8 Renato Botelho
	global $g, $config, $pkg_interface;
817 b2a66231 Ermal
818 6955830f Ermal Lu?i
819 3bb7e3e8 Renato Botelho
	$pkgid = get_package_id($package_name);
820 b2a66231 Ermal
	if ($pkgid == -1) {
821 e791dee8 Renato Botelho
		update_status(sprintf(gettext("The %s package is not installed.%sDeletion aborted."), $package_name, "\n\n"));
822 e65a287f Scott Ullrich
		ob_flush();
823
		sleep(1);
824
		return;
825
	}
826 086cf944 Phil Davis
	pkg_debug(sprintf(gettext("Removing %s package... "), $package_name));
827 e791dee8 Renato Botelho
	update_status(sprintf(gettext("Removing %s components..."), $package_name) . "\n");
828 407bf67a Colin Smith
	/* parse package configuration */
829
	$packages = &$config['installedpackages']['package'];
830 b63f2e8b Matthew Grooms
	$menus =& $config['installedpackages']['menu'];
831 3c41c4ab Colin Smith
	$services = &$config['installedpackages']['service'];
832 2addd5b2 Ermal
	$pkg_info =& $packages[$pkgid];
833 49aec489 Phil Davis
	if (file_exists("/usr/local/pkg/" . $pkg_info['configurationfile'])) {
834 19a11678 Colin Smith
		$pkg_config = parse_xml_config_pkg("/usr/local/pkg/" . $packages[$pkgid]['configurationfile'], "packagegui");
835 3f01fe47 Colin Smith
		/* remove menu items */
836 49aec489 Phil Davis
		if (is_array($pkg_config['menu'])) {
837 e791dee8 Renato Botelho
			update_status(gettext("Menu items... "));
838 8604523b Ermal Lu?i
			if (is_array($pkg_config['menu']) && is_array($menus)) {
839 49aec489 Phil Davis
				foreach ($pkg_config['menu'] as $menu) {
840
					foreach ($menus as $key => $instmenu) {
841
						if ($instmenu['name'] == $menu['name']) {
842 8604523b Ermal Lu?i
							unset($menus[$key]);
843 b2a66231 Ermal
							break;
844
						}
845
					}
846 8604523b Ermal Lu?i
				}
847
			}
848 e791dee8 Renato Botelho
			update_status(gettext("done.") . "\n");
849 407bf67a Colin Smith
		}
850 3c41c4ab Colin Smith
		/* remove services */
851 49aec489 Phil Davis
		if (is_array($pkg_config['service'])) {
852 e791dee8 Renato Botelho
			update_status(gettext("Services... "));
853 8604523b Ermal Lu?i
			if (is_array($pkg_config['service']) && is_array($services)) {
854 49aec489 Phil Davis
				foreach ($pkg_config['service'] as $service) {
855
					foreach ($services as $key => $instservice) {
856
						if ($instservice['name'] == $service['name']) {
857
							if (platform_booting() != true) {
858 06e57df8 Scott Ullrich
								stop_service($service['name']);
859 49aec489 Phil Davis
							}
860
							if ($service['rcfile']) {
861 c5966711 phildd
								$prefix = RCFILEPREFIX;
862 49aec489 Phil Davis
								if (!empty($service['prefix'])) {
863 941baf1e Ermal
									$prefix = $service['prefix'];
864 49aec489 Phil Davis
								}
865
								if (file_exists("{$prefix}{$service['rcfile']}")) {
866 941baf1e Ermal
									@unlink("{$prefix}{$service['rcfile']}");
867 49aec489 Phil Davis
								}
868 941baf1e Ermal
							}
869 8604523b Ermal Lu?i
							unset($services[$key]);
870
						}
871 0cab7cad Colin Smith
					}
872 3c41c4ab Colin Smith
				}
873
			}
874 e791dee8 Renato Botelho
			update_status(gettext("done.") . "\n");
875 3c41c4ab Colin Smith
		}
876 b2a66231 Ermal
		/*
877
		 * XXX: Otherwise inclusion of config.inc again invalidates actions taken.
878 a2febf9a Stephen Beaver
		 *	Same is done during installation.
879 b2a66231 Ermal
		 */
880 e8c516a0 Phil Davis
		write_config(sprintf(gettext("Intermediate config write during package removal for %s."), $package_name));
881 b2a66231 Ermal
882
		/*
883 a2febf9a Stephen Beaver
		 * If a require exists, include it.	 this will
884 b2a66231 Ermal
		 * show us where an error exists in a package
885
		 * instead of making us blindly guess
886 892aef15 Scott Ullrich
		 */
887 fcf92dae Ermal
		$missing_include = false;
888 49aec489 Phil Davis
		if ($pkg_config['include_file'] <> "") {
889 e791dee8 Renato Botelho
			update_status(gettext("Loading package instructions...") . "\n");
890 49aec489 Phil Davis
			if (file_exists($pkg_config['include_file'])) {
891 9b1aa8d9 Renato Botelho
				pkg_debug("require_once(\"{$pkg_config['include_file']}\")\n");
892 1570d27a Ermal Lu?i
				require_once($pkg_config['include_file']);
893 49aec489 Phil Davis
			} else {
894 9b1aa8d9 Renato Botelho
				pkg_debug("Missing include {$pkg_config['include_file']}\n");
895 fcf92dae Ermal
				$missing_include = true;
896 e8c516a0 Phil Davis
				update_status(sprintf(gettext("Include file %s could not be found for inclusion."), basename($pkg_config['include_file'])) . "\n");
897 fcf92dae Ermal
			}
898
		}
899
		/* ermal
900
		 * NOTE: It is not possible to handle parse errors on eval.
901
		 * So we prevent it from being run at all to not interrupt all the other code.
902
		 */
903 3bb7e3e8 Renato Botelho
		if ($when == "deinstall" && $missing_include == false) {
904 49aec489 Phil Davis
			/* evaluate this package's global functions and pre deinstall commands */
905
			if ($pkg_config['custom_php_global_functions'] <> "") {
906 fcf92dae Ermal
				eval_once($pkg_config['custom_php_global_functions']);
907 49aec489 Phil Davis
			}
908
			if ($pkg_config['custom_php_pre_deinstall_command'] <> "") {
909 fcf92dae Ermal
				eval_once($pkg_config['custom_php_pre_deinstall_command']);
910 49aec489 Phil Davis
			}
911 43db85f8 Scott Ullrich
		}
912 644d2d59 Colin Smith
		/* deinstall commands */
913 3bb7e3e8 Renato Botelho
		if ($when == "post-deinstall" && $pkg_config['custom_php_deinstall_command'] <> "") {
914 e791dee8 Renato Botelho
			update_status(gettext("Deinstall commands... "));
915 fcf92dae Ermal
			if ($missing_include == false) {
916
				eval_once($pkg_config['custom_php_deinstall_command']);
917 e791dee8 Renato Botelho
				update_status(gettext("done.") . "\n");
918 49aec489 Phil Davis
			} else {
919 e8c516a0 Phil Davis
				update_status("\n". gettext("Not executing custom deinstall hook because an include is missing.") . "\n");
920 49aec489 Phil Davis
			}
921 644d2d59 Colin Smith
		}
922 407bf67a Colin Smith
	}
923 2addd5b2 Ermal
	/* syslog */
924 ce7edfff doktornotor
	$need_syslog_restart = false;
925 8a82c222 doktornotor
	if (is_array($pkg_info['logging']) && $pkg_info['logging']['logfilename'] <> "") {
926 e8c516a0 Phil Davis
		update_status(gettext("Syslog entries... "));
927 2addd5b2 Ermal
		@unlink("{$g['varlog_path']}/{$pkg_info['logging']['logfilename']}");
928 e791dee8 Renato Botelho
		update_status("done.\n");
929 ce7edfff doktornotor
		$need_syslog_restart = true;
930 2addd5b2 Ermal
	}
931 2d26ee5e Sjon Hortensius
932 6b861ecd Renato Botelho
	if ($when == "post-deinstall") {
933
		/* remove config.xml entries */
934
		update_status(gettext("Configuration... "));
935
		unset($config['installedpackages']['package'][$pkgid]);
936
		update_status(gettext("done.") . "\n");
937 e8c516a0 Phil Davis
		write_config(sprintf(gettext("Removed %s package."), $package_name));
938 6b861ecd Renato Botelho
	}
939 ce7edfff doktornotor
940
	/* remove package entry from /etc/syslog.conf if needed */
941 f164ace4 doktornotor
	/* this must be done after removing the entries from config.xml */
942 ce7edfff doktornotor
	if ($need_syslog_restart) {
943
		system_syslogd_start();
944
	}
945
946 f0a550fd Colin Smith
}
947 5025a56c Scott Ullrich
948 46903fb9 Renato Botelho
/*
949
 * Used during upgrade process or retore backup process, verify all
950
 * packages installed in config.xml and install pkg accordingly
951
 */
952
function package_reinstall_all() {
953 e791dee8 Renato Botelho
	global $g, $config, $pkg_interface;
954 c53eb903 Ermal
955 7b31a030 Chris Buechler
	$upgrade = (file_exists('/conf/needs_package_sync') && platform_booting());
956
957
	if ((!isset($config['installedpackages']['package']) ||
958
	    !is_array($config['installedpackages']['package'])) && !$upgrade) {
959 46903fb9 Renato Botelho
		return true;
960
	}
961
962
	/* During boot after upgrade, wait for internet connection */
963
	if ($upgrade) {
964 7b31a030 Chris Buechler
		update_status(gettext("Waiting for Internet connection to update pkg metadata and finish package reinstallation"));
965 3610a08e Renato Botelho
		$ntries = 3;
966
		while ($ntries > 0) {
967 46903fb9 Renato Botelho
			if (pkg_update(true)) {
968
				break;
969
			}
970 e791dee8 Renato Botelho
			update_status('.');
971 46903fb9 Renato Botelho
			sleep(1);
972 3610a08e Renato Botelho
			$ntries--;
973 46903fb9 Renato Botelho
		}
974 e791dee8 Renato Botelho
		update_status("\n");
975 3610a08e Renato Botelho
976
		if ($ntries == 0) {
977
			file_notice(gettext("Package reinstall"),
978
			    gettext("Package reinstall process was ABORTED due to lack of internet connectivity"));
979
			return false;
980
		}
981 46903fb9 Renato Botelho
	}
982
983
	$pkg_info = get_pkg_info();
984
985 c0cb3c73 Renato Botelho
	if ($upgrade &&
986
	    file_exists("{$g['cf_conf_path']}/packages_to_reinstall_after_upgrade.txt")) {
987
		$package_list = file("{$g['cf_conf_path']}/packages_to_reinstall_after_upgrade.txt",
988
		    FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
989
		unlink_if_exists("{$g['cf_conf_path']}/packages_to_reinstall_after_upgrade.txt");
990
	} else {
991 5eda5816 NewEraCracker
		if (!isset($config['installedpackages']['package']) || !is_array($config['installedpackages']['package'])) {
992
			return true;
993
		}
994 c0cb3c73 Renato Botelho
		$package_list = array();
995
		foreach ($config['installedpackages']['package'] as $package) {
996
			$package_list[] = get_package_internal_name($package);
997
		}
998
	}
999
1000
	foreach ($package_list as $package) {
1001 46903fb9 Renato Botelho
		$found = false;
1002
		foreach ($pkg_info as $pkg) {
1003
			pkg_remove_prefix($pkg['name']);
1004 c0cb3c73 Renato Botelho
			if ($pkg['name'] == $package) {
1005
				pkg_install($g['pkg_prefix'] . $package, true);
1006 46903fb9 Renato Botelho
				$found = true;
1007
				break;
1008
			}
1009
		}
1010
1011
		if (!$found) {
1012
			if (!function_exists("file_notice")) {
1013
				require_once("notices.inc");
1014
			}
1015
1016
			file_notice(gettext("Package reinstall"),
1017 c0cb3c73 Renato Botelho
			    sprintf(gettext("Package %s does not exist in current %s version and it has been removed."),
1018
			    $package, $g['product_name']));
1019
			uninstall_package($package);
1020 46903fb9 Renato Botelho
		}
1021
	}
1022
1023
	return true;
1024 9b193619 Scott Ullrich
}
1025
1026 60dd7649 jim-p
function stop_packages() {
1027
	require_once("config.inc");
1028
	require_once("functions.inc");
1029
	require_once("filter.inc");
1030
	require_once("shaper.inc");
1031
	require_once("captiveportal.inc");
1032
	require_once("pkg-utils.inc");
1033
	require_once("pfsense-utils.inc");
1034
	require_once("service-utils.inc");
1035
1036 c5966711 phildd
	global $config, $g;
1037 60dd7649 jim-p
1038 e8c516a0 Phil Davis
	log_error(gettext("Stopping all packages."));
1039 60dd7649 jim-p
1040 c5966711 phildd
	$rcfiles = glob(RCFILEPREFIX . "*.sh");
1041 49aec489 Phil Davis
	if (!$rcfiles) {
1042 60dd7649 jim-p
		$rcfiles = array();
1043 49aec489 Phil Davis
	} else {
1044 60dd7649 jim-p
		$rcfiles = array_flip($rcfiles);
1045 49aec489 Phil Davis
		if (!$rcfiles) {
1046 60dd7649 jim-p
			$rcfiles = array();
1047 49aec489 Phil Davis
		}
1048 60dd7649 jim-p
	}
1049
1050
	if (is_array($config['installedpackages']['package'])) {
1051 49aec489 Phil Davis
		foreach ($config['installedpackages']['package'] as $package) {
1052 60dd7649 jim-p
			echo " Stopping package {$package['name']}...";
1053 af5d93f6 Renato Botelho
			$internal_name = get_package_internal_name($package);
1054 75a01a7c Phil Davis
			stop_service($internal_name);
1055
			unset($rcfiles[RCFILEPREFIX . strtolower($internal_name) . ".sh"]);
1056 60dd7649 jim-p
			echo "done.\n";
1057
		}
1058
	}
1059
1060 6186cdc4 jim-p
	foreach ($rcfiles as $rcfile => $number) {
1061
		$shell = @popen("/bin/sh", "w");
1062
		if ($shell) {
1063 60dd7649 jim-p
			echo " Stopping {$rcfile}...";
1064 61ef1385 Ermal
			if (!@fwrite($shell, "{$rcfile} stop >>/tmp/bootup_messages 2>&1")) {
1065 49aec489 Phil Davis
				if ($shell) {
1066 61ef1385 Ermal
					pclose($shell);
1067 49aec489 Phil Davis
				}
1068 61ef1385 Ermal
				$shell = @popen("/bin/sh", "w");
1069
			}
1070 60dd7649 jim-p
			echo "done.\n";
1071 6186cdc4 jim-p
			pclose($shell);
1072 60dd7649 jim-p
		}
1073
	}
1074
}
1075
1076 d5f0597b Renato Botelho
/* Identify which meta package is installed */
1077
function get_meta_pkg_name() {
1078
	global $g;
1079
1080
	/* XXX: Use pkg annotation */
1081
	if (is_pkg_installed($g['product_name'])) {
1082
		return $g['product_name'];
1083
	} else if (is_pkg_installed($g['product_name'] . '-vmware')) {
1084
		return $g['product_name'] . '-vmware';
1085
	}
1086
	return false;
1087
}
1088
1089
/* Identify which base package is installed */
1090
function get_base_pkg_name() {
1091
	global $g;
1092
1093
	/* XXX: Use pkg annotation */
1094
	if (is_pkg_installed($g['product_name'] . '-base-' . $g['platform'])) {
1095
		return $g['product_name'] . '-base-' . $g['platform'];
1096
	} else if (is_pkg_installed($g['product_name'] . '-base')) {
1097
		return $g['product_name'] . '-base';
1098
	}
1099
	return false;
1100
}
1101
1102
/* Verify if system needs upgrade (meta package or base) */
1103 d1c57eb8 Stephen Beaver
function get_system_pkg_version($baseonly = false) {
1104 d5f0597b Renato Botelho
	global $g;
1105
1106
	$base_pkg = get_base_pkg_name();
1107
	$meta_pkg = get_meta_pkg_name();
1108
1109
	if (!$base_pkg || !$meta_pkg) {
1110
		return false;
1111
	}
1112
1113
	$info = get_pkg_info($base_pkg);
1114
	$pkg_name = $base_pkg;
1115
1116
	$pkg_info = array();
1117
	foreach ($info as $item) {
1118
		if ($item['name'] == $base_pkg) {
1119
			$pkg_info = $item;
1120
		}
1121
	}
1122
1123 d1c57eb8 Stephen Beaver
	if (empty($pkg_info) || (!$baseonly && ($pkg_info['version'] == $pkg_info['installed_version']))) {
1124 d5f0597b Renato Botelho
		$info = get_pkg_info($meta_pkg);
1125
		$pkg_name = $meta_pkg;
1126
1127
		foreach ($info as $item) {
1128 59d256a1 Renato Botelho
			if ($item['name'] == $meta_pkg) {
1129 d5f0597b Renato Botelho
				$pkg_info = $item;
1130
			}
1131
		}
1132
	}
1133
1134
	if (empty($pkg_info)) {
1135
		return false;
1136
	}
1137
1138
	return array(
1139
	    'pkg_name'          => $pkg_name,
1140
	    'version'           => $pkg_info['version'],
1141
	    'installed_version' => $pkg_info['installed_version']
1142
	);
1143
}
1144
1145 db8621d8 Renato Botelho
/* List available repos */
1146
function pkg_list_repos() {
1147 ad3c9763 Renato Botelho
	global $g;
1148
1149 db8621d8 Renato Botelho
	$path = "/usr/local/share/{$g['product_name']}/pkg/repos";
1150 ad3c9763 Renato Botelho
1151 db8621d8 Renato Botelho
	$default_descr = @file_get_contents($path . "/{$g['product_name']}-repo.descr");
1152 ad3c9763 Renato Botelho
1153 db8621d8 Renato Botelho
	$default = array(
1154
	    'name' => 'Default',
1155
	    'path' => $path . "/{$g['product_name']}-repo.conf",
1156
	    'descr' => $default_descr
1157
	);
1158
1159
	$result = array($default);
1160
1161
	$conf_files = glob("{$path}/{$g['product_name']}-repo-*.conf");
1162
	foreach ($conf_files as $conf_file) {
1163
		$descr_file = preg_replace('/.conf$/', '.descr', $conf_file);
1164
		if (file_exists($descr_file)) {
1165
			$descr_content = file($descr_file);
1166
			$descr = chop($descr_content[0]);
1167
		} else {
1168
			$descr = 'Unknown';
1169
		}
1170
		if (!preg_match('/-repo-(.*).conf/', $conf_file, $matches)) {
1171
			continue;
1172
		}
1173
		$entry = array(
1174
		    'name' => ucfirst(strtolower($matches[1])),
1175
		    'path' => $conf_file,
1176
		    'descr' => $descr
1177
		);
1178
		$result[] = $entry;
1179 ad3c9763 Renato Botelho
	}
1180
1181 db8621d8 Renato Botelho
	return $result;
1182
}
1183
1184
/* Switch between stable and devel repos */
1185
function pkg_switch_repo($path) {
1186
	global $g;
1187
1188
	safe_mkdir("/usr/local/etc/pkg/repos");
1189
	@unlink("/usr/local/etc/pkg/repos/{$g['product_name']}.conf");
1190
	@symlink($path, "/usr/local/etc/pkg/repos/{$g['product_name']}.conf");
1191
1192 ce6e6519 Renato Botelho
	$abi_file = str_replace('.conf', '.abi', $path);
1193
	$altabi_file = str_replace('.conf', '.altabi', $path);
1194
1195
	if (file_exists($abi_file) && file_exists($altabi_file)) {
1196
		$abi = file_get_contents($abi_file);
1197
		$altabi = file_get_contents($altabi_file);
1198
1199
		$pkg_conf = array(
1200
			"ABI={$abi}",
1201
			"ALTABI={$altabi}"
1202
		);
1203
1204
		file_put_contents("/usr/local/etc/pkg.conf", $pkg_conf);
1205
	}
1206
1207 db8621d8 Renato Botelho
	return pkg_update(true);
1208 ad3c9763 Renato Botelho
}
1209
1210 61ef1385 Ermal
?>