Project

General

Profile

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