Project

General

Profile

Download (40.1 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 38809d47 Renato Botelho do Couto
 * Copyright (c) 2004-2013 BSD Perimeter
8
 * Copyright (c) 2013-2016 Electric Sheep Fencing
9 402c98a2 Reid Linnemann
 * Copyright (c) 2014-2023 Rubicon Communications, LLC (Netgate)
10 ac24dc24 Renato Botelho
 * All rights reserved.
11 a2febf9a Stephen Beaver
 *
12 b12ea3fb Renato Botelho
 * Licensed under the Apache License, Version 2.0 (the "License");
13
 * you may not use this file except in compliance with the License.
14
 * You may obtain a copy of the License at
15 a2febf9a Stephen Beaver
 *
16 b12ea3fb Renato Botelho
 * http://www.apache.org/licenses/LICENSE-2.0
17 a2febf9a Stephen Beaver
 *
18 b12ea3fb Renato Botelho
 * Unless required by applicable law or agreed to in writing, software
19
 * distributed under the License is distributed on an "AS IS" BASIS,
20
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
 * See the License for the specific language governing permissions and
22
 * limitations under the License.
23 8c6516d1 Colin Smith
 */
24 523855b0 Scott Ullrich
25 01a6e665 Ermal
require_once("globals.inc");
26 7eea4407 Ermal
require_once("service-utils.inc");
27 e56f7a19 Steve Beaver
require_once("/usr/local/www/includes/functions.inc.php");
28 a4105aad Christian McDonald
require_once("xmlparse.inc");
29 1e8644ca Renato Botelho
require_once("pfsense-utils.inc");
30 b47833cc Scott Ullrich
31 eab543ed Ermal
if (!function_exists("pkg_debug")) {
32
	/* set up logging if needed */
33
	function pkg_debug($msg) {
34
		global $g, $debug, $fd_log;
35
36 49aec489 Phil Davis
		if (!$debug) {
37 eab543ed Ermal
			return;
38 49aec489 Phil Davis
		}
39 eab543ed Ermal
40
		if (!$fd_log) {
41 0c9d489e Renato Botelho do Couto
			$fd_log = fopen("{$g['tmp_path']}/pkg_mgr_debug.log",
42
			    "w");
43
		}
44
45
		if (!$fd_log) {
46
			update_status(gettext("Warning, could not open log " .
47
			    "for writing.") . "\n");
48 7489746e Renato Botelho do Couto
			return;
49 eab543ed Ermal
		}
50
		@fwrite($fd_log, $msg);
51
	}
52
}
53
54 c078dd89 Renato Botelho
/* Validate if pkg name is valid */
55
function pkg_valid_name($pkgname) {
56
	global $g;
57
58
	$pattern = "/^{$g['pkg_prefix']}[a-zA-Z0-9\.\-_]+$/";
59
	return preg_match($pattern, $pkgname);
60
}
61
62 c2eb2508 Renato Botelho
/* Remove pkg_prefix from package name if it's present */
63
function pkg_remove_prefix(&$pkg_name) {
64
	global $g;
65
66 2568e151 Christian McDonald
	if (substr($pkg_name, 0, strlen(g_get('pkg_prefix'))) ==
67
	    g_get('pkg_prefix')) {
68
		$pkg_name = substr($pkg_name, strlen(g_get('pkg_prefix')));
69 c2eb2508 Renato Botelho
	}
70 e7405fbf Scott Ullrich
}
71 33b7cc0d Colin Smith
72 d3ff1e59 Renato Botelho
/* Execute pkg update when it's necessary */
73
function pkg_update($force = false) {
74
	global $g;
75
76 6cf87aec Renato Botelho
	return pkg_call("update" . ($force ? " -f" : ""));
77 d3ff1e59 Renato Botelho
}
78
79 75bb92c4 Renato Botelho
/* return an array with necessary environment vars for pkg */
80 a948633c Renato Botelho
function pkg_env($extra_env = array()) {
81 c93b3fcd Reid Linnemann
	global $g;
82 75bb92c4 Renato Botelho
83 2568e151 Christian McDonald
	$user_agent = g_get('product_label') . '/' . g_get('product_version');
84 c93b3fcd Reid Linnemann
	if (!config_path_enabled('system','do_not_send_uniqueid')) {
85 6cc74faa Renato Botelho
		$user_agent .= ':' . system_get_uniqueid();
86 d49ad309 Renato Botelho
	}
87
88 75bb92c4 Renato Botelho
	$pkg_env_vars = array(
89 e21ac870 Renato Botelho
		"LANG" => "C",
90 75bb92c4 Renato Botelho
		"HTTP_USER_AGENT" => $user_agent,
91 a120c849 Renato Botelho
		"ASSUME_ALWAYS_YES" => "true",
92
		"FETCH_TIMEOUT" => 5,
93
		"FETCH_RETRY" => 2
94 75bb92c4 Renato Botelho
	);
95
96 c93b3fcd Reid Linnemann
	$http_proxy = config_get_path('system/proxyurl');
97
	$http_proxyport = config_get_path('system/proxyport');
98
	if (!empty($http_proxy)) {
99
		if (!empty($http_proxyport)) {
100
			$http_proxy .= ':' . $http_proxyport;
101 a7fcbc1e jim-p
		}
102
		$pkg_env_vars['HTTP_PROXY'] = $http_proxy;
103 1060378f jim-p
104 c93b3fcd Reid Linnemann
		$proxyuser = config_get_path('system/proxyuser');
105
		$proxypass = config_get_path('system/proxypass');
106
		if (!empty($proxyuser) && !empty($proxypass)) {
107 0c9d489e Renato Botelho do Couto
			$pkg_env_vars['HTTP_PROXY_AUTH'] = "basic:*:" .
108 c93b3fcd Reid Linnemann
			    $proxyuser . ":" . $proxypass;
109 1060378f jim-p
		}
110 a7fcbc1e jim-p
	}
111
112 c93b3fcd Reid Linnemann
#	if (config_path_enabled('system','use_mfs_tmpvar') &&
113 ff72903f Christian McDonald
#	    !file_exists("/conf/ram_disks_failed")) {
114
#		$pkg_env_vars['PKG_DBDIR'] = '/root/var/db/pkg';
115
#		$pkg_env_vars['PKG_CACHEDIR'] = '/root/var/cache/pkg';
116
#	}
117 75bb92c4 Renato Botelho
118 a948633c Renato Botelho
	foreach ($extra_env as $key => $value) {
119
		$pkg_env_vars[$key] = $value;
120
	}
121
122 75bb92c4 Renato Botelho
	return $pkg_env_vars;
123
}
124
125 c2eb2508 Renato Botelho
/* Execute a pkg call */
126 a948633c Renato Botelho
function pkg_call($params, $mute = false, $extra_env = array()) {
127 c2eb2508 Renato Botelho
	if (empty($params)) {
128
		return false;
129
	}
130
131 6fd37d04 Renato Botelho
	$descriptorspec = array(
132
		1 => array("pipe", "w"), /* stdout */
133 a2febf9a Stephen Beaver
		2 => array("pipe", "w")	 /* stderr */
134 6fd37d04 Renato Botelho
	);
135
136
	pkg_debug("pkg_call(): {$params}\n");
137 58e60eb9 Renato Botelho
	$process = proc_open("/usr/local/sbin/pkg-static {$params}",
138
	    $descriptorspec, $pipes, '/', pkg_env($extra_env));
139 6fd37d04 Renato Botelho
140
	if (!is_resource($process)) {
141
		return false;
142
	}
143
144
	stream_set_blocking($pipes[1], 0);
145
	stream_set_blocking($pipes[2], 0);
146
147 f3f98e97 Phil Davis
	/* XXX: should be a tunable? */
148 9c91c7bd doktornotor
	$timeout = 60; // seconds
149 6fd37d04 Renato Botelho
	$error_log = '';
150
151
	do {
152
		$write = array();
153
		$read = array($pipes[1], $pipes[2]);
154
		$except = array();
155
156 e1a6074d Renato Botelho
		$stream = @stream_select($read, $write, $except, $timeout);
157 6fd37d04 Renato Botelho
		if ($stream !== FALSE && $stream > 0) {
158
			foreach ($read as $pipe) {
159
				$content = stream_get_contents($pipe);
160
				if ($content == '') {
161
					continue;
162
				}
163
				if ($pipe === $pipes[1]) {
164
					if (!$mute) {
165 e791dee8 Renato Botelho
						update_status($content);
166 6fd37d04 Renato Botelho
					}
167
					flush();
168
				} else if ($pipe === $pipes[2]) {
169
					$error_log .= $content;
170
				}
171
			}
172 49aec489 Phil Davis
		}
173 a2febf9a Stephen Beaver
174 6fd37d04 Renato Botelho
		$status = proc_get_status($process);
175
	} while ($status['running']);
176 a2febf9a Stephen Beaver
177 6fd37d04 Renato Botelho
	fclose($pipes[1]);
178
	fclose($pipes[2]);
179
	proc_close($process);
180
181 4b834523 Renato Botelho
182 1c981897 Renato Botelho
	$rc = $status['exitcode'];
183 6fd37d04 Renato Botelho
184
	pkg_debug("pkg_call(): rc = {$rc}\n");
185
	if ($rc == 0) {
186
		return true;
187
	}
188
189
	pkg_debug("pkg_call(): error_log\n{$error_log}\n");
190
	if (!$mute) {
191 0c9d489e Renato Botelho do Couto
		update_status("\n\n" . sprintf(gettext("ERROR!!! An error " .
192
		    "occurred on pkg execution (rc = %d) with parameters " .
193
		    "'%s':"), $rc, $params) . "\n" . $error_log . "\n");
194 49aec489 Phil Davis
	}
195 a2febf9a Stephen Beaver
196 6fd37d04 Renato Botelho
	return false;
197 31e7e1bc Scott Ullrich
}
198
199 6fd37d04 Renato Botelho
/* Execute pkg with $params, fill stdout and stderr and return pkg rc */
200 a948633c Renato Botelho
function pkg_exec($params, &$stdout, &$stderr, $extra_env = array()) {
201 6fd37d04 Renato Botelho
	if (empty($params)) {
202
		return -1;
203
	}
204
205
	$descriptorspec = array(
206
		1 => array("pipe", "w"), /* stdout */
207 a2febf9a Stephen Beaver
		2 => array("pipe", "w")	 /* stderr */
208 6fd37d04 Renato Botelho
	);
209
210 4b834523 Renato Botelho
211 6fd37d04 Renato Botelho
	pkg_debug("pkg_exec(): {$params}\n");
212 58e60eb9 Renato Botelho
	$process = proc_open("/usr/local/sbin/pkg-static {$params}",
213
	    $descriptorspec, $pipes, '/', pkg_env($extra_env));
214 6fd37d04 Renato Botelho
215
	if (!is_resource($process)) {
216
		return -1;
217
	}
218
219
	$stdout = '';
220
	while (($l = fgets($pipes[1])) !== FALSE) {
221
		$stdout .= $l;
222
	}
223
	fclose($pipes[1]);
224
225
	$stderr = '';
226
	while (($l = fgets($pipes[2])) !== FALSE) {
227
		$stderr .= $l;
228
	}
229
	fclose($pipes[2]);
230 c2eb2508 Renato Botelho
231 4b834523 Renato Botelho
232 6fd37d04 Renato Botelho
	return proc_close($process);
233 c2eb2508 Renato Botelho
}
234
235 8df1877b Renato Botelho
/* Compare 2 pkg versions and return:
236
 * '=' - versions are the same
237
 * '>' - $v1 > $v2
238
 * '<' - $v1 < $v2
239
 * '?' - Error
240
 */
241
function pkg_version_compare($v1, $v2) {
242
	if (empty($v1) || empty($v2)) {
243
		return '?';
244
	}
245
246 500dfdb8 Renato Botelho
	$rc = pkg_exec("version -t '{$v1}' '{$v2}'", $stdout, $stderr);
247 8df1877b Renato Botelho
248
	if ($rc != 0) {
249
		return '?';
250
	}
251
252
	return str_replace("\n", "", $stdout);
253
}
254
255 c2eb2508 Renato Botelho
/* Check if package is installed */
256
function is_pkg_installed($pkg_name) {
257
	global $g;
258
259 f5b1c660 Renato Botelho
	if (empty($pkg_name)) {
260
		return false;
261
	}
262 c2eb2508 Renato Botelho
263 500dfdb8 Renato Botelho
	return pkg_call("info -e " . $pkg_name, true);
264 c2eb2508 Renato Botelho
}
265
266 7379d80f Renato Botelho
/* Install package, $pkg_name should not contain prefix */
267 46903fb9 Renato Botelho
function pkg_install($pkg_name, $force = false) {
268 7379d80f Renato Botelho
	global $g;
269 e7553e1b Renato Botelho
	$result = false;
270 7379d80f Renato Botelho
271 f5b1c660 Renato Botelho
	$shortname = $pkg_name;
272
	pkg_remove_prefix($shortname);
273 7379d80f Renato Botelho
274 46903fb9 Renato Botelho
	$pkg_force = "";
275
	if ($force) {
276
		$pkg_force = "-f ";
277
	}
278
279 f5b1c660 Renato Botelho
	pkg_debug("Installing package {$shortname}\n");
280 46903fb9 Renato Botelho
	if ($force || !is_pkg_installed($pkg_name)) {
281 f5b1c660 Renato Botelho
		$result = pkg_call("install -y " . $pkg_force . $pkg_name);
282 f3f98e97 Phil Davis
		/* Cleanup cache to free disk space */
283 e7553e1b Renato Botelho
		pkg_call("clean -y");
284 7379d80f Renato Botelho
	}
285
286 e7553e1b Renato Botelho
	return $result;
287 7379d80f Renato Botelho
}
288
289 c2eb2508 Renato Botelho
/* Delete package from FreeBSD, $pkg_name should not contain prefix */
290
function pkg_delete($pkg_name) {
291
	global $g;
292
293 f5b1c660 Renato Botelho
	$shortname = $pkg_name;
294
	pkg_remove_prefix($shortname);
295 c2eb2508 Renato Botelho
296 f5b1c660 Renato Botelho
	pkg_debug("Removing package {$shortname}\n");
297 c2eb2508 Renato Botelho
	if (is_pkg_installed($pkg_name)) {
298 f5b1c660 Renato Botelho
		pkg_call("delete -y " . $pkg_name);
299 f3f98e97 Phil Davis
		/* Cleanup unnecessary dependencies */
300 e1382589 Renato Botelho
		pkg_call("autoremove -y");
301 49aec489 Phil Davis
	}
302 8c6516d1 Colin Smith
}
303 43db85f8 Scott Ullrich
304 af5d93f6 Renato Botelho
/* Check if package is present in config.xml */
305
function is_package_installed($package_name) {
306
	return (get_package_id($package_name) != -1);
307 8c6516d1 Colin Smith
}
308 43db85f8 Scott Ullrich
309 af5d93f6 Renato Botelho
/* Find package array index */
310
function get_package_id($package_name) {
311 c93b3fcd Reid Linnemann
	foreach (config_get_path('installedpackages/package', []) as $idx => $pkg) {
312 a50534b6 Renato Botelho
		if ($pkg['name'] == $package_name ||
313 4e322e2c Phil Davis
		    get_package_internal_name($pkg) == $package_name) {
314 af5d93f6 Renato Botelho
			return $idx;
315 e65a287f Scott Ullrich
		}
316
	}
317 af5d93f6 Renato Botelho
318 e65a287f Scott Ullrich
	return -1;
319 8c6516d1 Colin Smith
}
320
321 af5d93f6 Renato Botelho
/* Return internal_name when it's defined, otherwise, returns name */
322
function get_package_internal_name($package_data) {
323 0c9d489e Renato Botelho do Couto
	if (isset($package_data['internal_name']) &&
324
	    ($package_data['internal_name'] != "")) {
325 75a01a7c Phil Davis
		/* e.g. name is Ipguard-dev, internal name is ipguard */
326 af5d93f6 Renato Botelho
		return $package_data['internal_name'];
327 75a01a7c Phil Davis
	} else {
328 af5d93f6 Renato Botelho
		return $package_data['name'];
329 75a01a7c Phil Davis
	}
330
}
331
332 a2febf9a Stephen Beaver
// Get information about packages.
333 4333564a Renato Botelho
function get_pkg_info($pkgs = 'all', $remote_repo_usage_disabled = false,
334
    $installed_pkgs_only = false) {
335 e791dee8 Renato Botelho
	global $g, $input_errors;
336 b2a66231 Ermal
337 04daf8b1 stilez
	$out = $err = $extra_param = '';
338 587988f6 stilez
	$rc = 0;
339 e65a287f Scott Ullrich
340 d65fc2ff Renato Botelho
	unset($pkg_filter);
341 04daf8b1 stilez
342 d65fc2ff Renato Botelho
	if (is_array($pkgs)) {
343
		$pkg_filter = $pkgs;
344 2568e151 Christian McDonald
		$pkgs = g_get('pkg_prefix') . '*';
345 e87ea36d Renato Botelho
	} elseif ($pkgs == 'all') {
346 2568e151 Christian McDonald
		$pkgs = g_get('pkg_prefix') . '*';
347 65c94077 Renato Botelho
	}
348 e87ea36d Renato Botelho
349 2568e151 Christian McDonald
	$base_packages = (substr($pkgs, 0, strlen(g_get('pkg_prefix'))) !=
350
	    g_get('pkg_prefix'));
351 07152ca7 Steve Beaver
352 dd6ecfa2 Phil Davis
	if ($installed_pkgs_only && !is_pkg_installed($pkgs)) {
353 a835cdee Renato Botelho
		/*
354
		 * Return early if the caller wants just installed packages
355
		 * and there are none.  Saves doing any calls that might
356
		 * access a remote package repo.
357
		 */
358 dd6ecfa2 Phil Davis
		return array();
359
	}
360
361 9b7cfb3f Renato Botelho
	if (!function_exists('is_subsystem_dirty')) {
362
		require_once("util.inc");
363
	}
364
365
	/* Do not run remote operations if pkg has a lock */
366
	if (is_subsystem_dirty('pkg')) {
367 04daf8b1 stilez
		$remote_repo_usage_disabled = true;
368 9b7cfb3f Renato Botelho
		$lock = false;
369
	} else {
370
		$lock = true;
371
	}
372
373
	if ($lock) {
374
		mark_subsystem_dirty('pkg');
375
	}
376 587988f6 stilez
377 04daf8b1 stilez
	if ($remote_repo_usage_disabled) {
378
		$extra_param = "-U ";
379
	}
380
381 eaed7e74 Renato Botelho
	$did_search = false;
382 a9b0a7a3 Renato Botelho
	$search_rc = 0;
383
	$info_rc = 0;
384
	$search_items = array();
385
	$info_items = array();
386
387 283e8d24 Renato Botelho
	if ($base_packages) {
388
		$repo_param = "";
389
	} else {
390
		$repo_param = "-r {$g['product_name']}";
391
	}
392
393 a9b0a7a3 Renato Botelho
	/*
394
	 * If we want more than just the currently installed packages or
395
	 * we want up-to-date remote repo info then do a full pkg search
396
	 */
397 dd6ecfa2 Phil Davis
	if (!$installed_pkgs_only || !$remote_repo_usage_disabled) {
398 eaed7e74 Renato Botelho
		$did_search = true;
399 654dc4ac Luiz Otavio O Souza
		/* Update the repository access credentials. */
400
		mwexec("/usr/local/sbin/{$g['product_name']}-repo-setup");
401 283e8d24 Renato Botelho
		$search_rc = pkg_exec("search {$repo_param} " .
402 05318264 Renato Botelho
		    "{$extra_param}-R --raw-format json-compact " .
403 a9b0a7a3 Renato Botelho
		    $pkgs, $search_out, $search_err);
404
		if ($search_rc == 0) {
405 c253e352 Renato Botelho
			$search_items = explode("\n", chop($search_out));
406 a9b0a7a3 Renato Botelho
			array_walk($search_items, function(&$v, &$k) {
407
				$v = json_decode($v, true);
408
			});
409
		}
410 4333564a Renato Botelho
	}
411 dd6ecfa2 Phil Davis
412 a9b0a7a3 Renato Botelho
	/*
413
	 * We always should look for local items to detect packages that
414
	 * were removed from remote repo but are already installed locally
415
	 *
416
	 * Take pkg search return code into consideration to fallback to local
417
	 * information when remote repo is not accessible
418
	 */
419
	if (is_pkg_installed($pkgs) || $search_rc != 0) {
420
		$info_rc = pkg_exec("info -R --raw-format json-compact " .
421
		    $pkgs, $info_out, $info_err);
422
		if ($info_rc == 0) {
423 c253e352 Renato Botelho
			$info_items = explode("\n", chop($info_out));
424 a9b0a7a3 Renato Botelho
			array_walk($info_items, function(&$v, &$k) {
425
				$v = json_decode($v, true);
426
			});
427
		}
428 587988f6 stilez
	}
429 04daf8b1 stilez
430 9b7cfb3f Renato Botelho
	if ($lock) {
431
		clear_subsystem_dirty('pkg');
432
	}
433 b2a66231 Ermal
434 a9b0a7a3 Renato Botelho
	if ($search_rc != 0 && $info_rc != 0) {
435 e791dee8 Renato Botelho
		update_status("\n" . gettext(
436
		    "ERROR: Error trying to get packages list. Aborting...")
437
		    . "\n");
438 a9b0a7a3 Renato Botelho
		update_status($search_err . "\n" . $info_err);
439 4333564a Renato Botelho
		$input_errors[] = gettext(
440
		    "ERROR: Error trying to get packages list. Aborting...") .
441
		    "\n";
442 a9b0a7a3 Renato Botelho
		$input_errors[] = $search_err . "\n" . $info_err;
443 65c94077 Renato Botelho
		return array();
444
	}
445
446 a9b0a7a3 Renato Botelho
	/* It was not possible to search, use local information only */
447 eaed7e74 Renato Botelho
	if ($search_rc != 0 || !$did_search) {
448 a9b0a7a3 Renato Botelho
		$search_items = $info_items;
449
	} else {
450
		foreach ($info_items as $pkg_info) {
451
			if (empty($pkg_info['name'])) {
452
				continue;
453
			}
454
455 bc60e070 Renato Botelho
			if (array_search($pkg_info['name'], array_column(
456
			    $search_items, 'name')) === FALSE) {
457 a9b0a7a3 Renato Botelho
				$pkg_info['obsolete'] = true;
458
				$search_items[] = $pkg_info;
459
			}
460
		}
461
	}
462
463 65c94077 Renato Botelho
	$result = array();
464 a9b0a7a3 Renato Botelho
	foreach ($search_items as $pkg_info) {
465
		if (empty($pkg_info['name'])) {
466 65c94077 Renato Botelho
			continue;
467
		}
468
469 4333564a Renato Botelho
		if (isset($pkg_filter) && !in_array($pkg_info['name'],
470
		    $pkg_filter)) {
471 d65fc2ff Renato Botelho
			continue;
472
		}
473
474 b9e2048a Renato Botelho
		$pkg_info['shortname'] = $pkg_info['name'];
475
		pkg_remove_prefix($pkg_info['shortname']);
476
477
		/* XXX: Add it to globals.inc? */
478
		$pkg_info['changeloglink'] =
479
		    "https://github.com/pfsense/FreeBSD-ports/commits/devel/" .
480
		    $pkg_info['categories'][0] . '/' . $pkg_info['name'];
481
482 dd6ecfa2 Phil Davis
		$pkg_is_installed = false;
483
484 77340246 Renato Botelho
		if (is_pkg_installed($pkg_info['name'])) {
485 05318264 Renato Botelho
			$rc = pkg_exec("query %R {$pkg_info['name']}", $out,
486
			    $err);
487 283e8d24 Renato Botelho
			if (!$base_packages &&
488 2568e151 Christian McDonald
			    rtrim($out) != g_get('product_name')) {
489 05318264 Renato Botelho
				continue;
490
			}
491
492 77340246 Renato Botelho
			$pkg_info['installed'] = true;
493 dd6ecfa2 Phil Davis
			$pkg_is_installed = true;
494 54f236f7 Renato Botelho
495 4333564a Renato Botelho
			$rc = pkg_exec("query %v {$pkg_info['name']}", $out,
496
			    $err);
497 54f236f7 Renato Botelho
498
			if ($rc != 0) {
499 a835cdee Renato Botelho
				update_status("\n" . gettext("ERROR: Error " .
500
				    "trying to get package version. " .
501
				    "Aborting...") . "\n");
502 e791dee8 Renato Botelho
				update_status($err);
503 a835cdee Renato Botelho
				$input_errors[] = gettext("ERROR: Error " .
504
				    "trying to get package version. " .
505
				    "Aborting...") . "\n";
506 4333564a Renato Botelho
				$input_errors[] = $err;
507 54f236f7 Renato Botelho
				return array();
508
			}
509
510 a835cdee Renato Botelho
			$pkg_info['installed_version'] = str_replace("\n", "",
511
			    $out);
512 07152ca7 Steve Beaver
513
			/*
514 a835cdee Renato Botelho
			 * We used pkg info to collect pkg data so remote
515
			 * version is not available. Lets try to collect it
516
			 * using rquery if possible
517
			 */
518 eaed7e74 Renato Botelho
			if ($search_rc != 0 || !$did_search) {
519 a835cdee Renato Botelho
				$rc = pkg_exec(
520
				    "rquery -U %v {$pkg_info['name']}", $out,
521
				    $err);
522 07152ca7 Steve Beaver
523
				if ($rc == 0) {
524 a835cdee Renato Botelho
					$pkg_info['version'] =
525
					    str_replace("\n", "", $out);
526 07152ca7 Steve Beaver
				}
527
			}
528
529 82692fe1 Renato Botelho
		} else if (is_package_installed($pkg_info['shortname'])) {
530
			$pkg_info['broken'] = true;
531 dd6ecfa2 Phil Davis
			$pkg_is_installed = true;
532 77340246 Renato Botelho
		}
533
534 4333564a Renato Botelho
		$pkg_info['desc'] = preg_replace('/\n+WWW:.*$/', '',
535
		    $pkg_info['desc']);
536 c8cae8e5 Renato Botelho
537 dd6ecfa2 Phil Davis
		if (!$installed_pkgs_only || $pkg_is_installed) {
538
			$result[] = $pkg_info;
539
		}
540 65c94077 Renato Botelho
		unset($pkg_info);
541 34da63c3 Colin Smith
	}
542 b2a66231 Ermal
543 c5ecf722 Renato Botelho
	/* Sort result alphabetically */
544
	usort($result, function($a, $b) {
545
		return(strcasecmp ($a['name'], $b['name']));
546
	});
547
548 65c94077 Renato Botelho
	return $result;
549 8c6516d1 Colin Smith
}
550
551 bed6c19b Renato Botelho
/*
552
 * If binary pkg is installed but post-install tasks were not
553 0d0f419e Phil Davis
 * executed yet, do it now.
554 bed6c19b Renato Botelho
 * This scenario can happen when a pkg is pre-installed during
555
 * build phase, and at this point, cannot find a running system
556
 * to register itself in config.xml and also execute custom
557
 * install functions
558
 */
559
function register_all_installed_packages() {
560 587988f6 stilez
	$pkg_info = get_pkg_info('all', true, true);
561
562 bed6c19b Renato Botelho
	foreach ($pkg_info as $pkg) {
563
		pkg_remove_prefix($pkg['name']);
564
565
		if (is_package_installed($pkg['name'])) {
566
			continue;
567
		}
568
569
		update_status(sprintf(gettext(
570
		    "Running last steps of %s installation.") . "\n",
571
		    $pkg['name']));
572
		install_package_xml($pkg['name']);
573
	}
574
}
575
576 8c6516d1 Colin Smith
/*
577 0c9d489e Renato Botelho do Couto
 * resync_all_package_configs() Force packages to setup their configuration
578
 * and rc.d files.  This function may also print output to the terminal
579
 * indicating progress.
580 8c6516d1 Colin Smith
 */
581
function resync_all_package_configs($show_message = false) {
582 6acdf659 Carlos Eduardo Ramos
	log_error(gettext("Resyncing configuration for all packages."));
583 06e57df8 Scott Ullrich
584 49aec489 Phil Davis
	if ($show_message == true) {
585 3a9eb3c9 Ermal
		echo "Syncing packages:";
586 49aec489 Phil Davis
	}
587 b2a66231 Ermal
588 c93b3fcd Reid Linnemann
	foreach (config_get_path('installedpackages/package', []) as $idx => $package) {
589 49aec489 Phil Davis
		if (empty($package['name'])) {
590 2addd5b2 Ermal
			continue;
591 49aec489 Phil Davis
		}
592
		if ($show_message == true) {
593 2addd5b2 Ermal
			echo " " . $package['name'];
594 49aec489 Phil Davis
		}
595
		if (platform_booting() != true) {
596 af5d93f6 Renato Botelho
			stop_service(get_package_internal_name($package));
597 49aec489 Phil Davis
		}
598 a0d4336f Renato Botelho
		sync_package($package['name']);
599 e791dee8 Renato Botelho
		update_status(gettext("Syncing packages...") . "\n");
600 e65a287f Scott Ullrich
	}
601 06e57df8 Scott Ullrich
602 49aec489 Phil Davis
	if ($show_message == true) {
603 08452bff Warren Baker
		echo " done.\n";
604 49aec489 Phil Davis
	}
605 8c6516d1 Colin Smith
}
606
607 d1a8f050 Renato Botelho
function uninstall_package($package_name) {
608 c93b3fcd Reid Linnemann
	global $g;
609 b2a66231 Ermal
610 0d579b59 Renato Botelho
	$internal_name = $package_name;
611 d1a8f050 Renato Botelho
	$id = get_package_id($package_name);
612 df5da531 Ermal
	if ($id >= 0) {
613 0c9d489e Renato Botelho do Couto
		$internal_name = get_package_internal_name(
614 c93b3fcd Reid Linnemann
		    config_get_path("installedpackages/package/{$id}"));
615 d1a8f050 Renato Botelho
		stop_service($internal_name);
616 0d579b59 Renato Botelho
	}
617 2568e151 Christian McDonald
	$pkg_name = g_get('pkg_prefix') . $internal_name;
618 0d579b59 Renato Botelho
619 f5b1c660 Renato Botelho
	if (is_pkg_installed($pkg_name)) {
620 e791dee8 Renato Botelho
		update_status(gettext("Removing package...") . "\n");
621 f5b1c660 Renato Botelho
		pkg_delete($pkg_name);
622 0d579b59 Renato Botelho
	} else {
623
		delete_package_xml($package_name);
624 1570d27a Ermal Lu?i
	}
625 4c6a49d7 Scott Ullrich
626 e791dee8 Renato Botelho
	update_status(gettext("done.") . "\n");
627 f898cf33 Scott Ullrich
}
628
629 e5960712 PiBa-NL
function reinstall_package($package_name) {
630 c93b3fcd Reid Linnemann
	global $g;
631 e5960712 PiBa-NL
632
	$internal_name = $package_name;
633
	$id = get_package_id($package_name);
634
	if ($id >= 0) {
635 0c9d489e Renato Botelho do Couto
		$internal_name = get_package_internal_name(
636 c93b3fcd Reid Linnemann
			config_get_path("installedpackages/package/{$id}"));
637 e5960712 PiBa-NL
	}
638 2568e151 Christian McDonald
	$pkg_name = g_get('pkg_prefix') . $internal_name;
639 e5960712 PiBa-NL
	pkg_install($pkg_name);
640
}
641
642 a0d4336f Renato Botelho
/* Run <custom_php_resync_config_command> */
643
function sync_package($package_name) {
644 c93b3fcd Reid Linnemann
	global $builder_package_install;
645 2d26ee5e Sjon Hortensius
646
	// If this code is being called by pfspkg_installer
647 09e11b69 Scott Ullrich
	// which the builder system uses then return (ignore).
648 49aec489 Phil Davis
	if ($builder_package_install) {
649 f0695975 Scott Ullrich
		return;
650 49aec489 Phil Davis
	}
651 2d26ee5e Sjon Hortensius
652 c93b3fcd Reid Linnemann
	if (empty(config_get_path('installedpackages/package', []))) {
653 b2a66231 Ermal
		return;
654 49aec489 Phil Davis
	}
655 a0d4336f Renato Botelho
656
	if (($pkg_id = get_package_id($package_name)) == -1) {
657 0c9d489e Renato Botelho do Couto
		// This package doesn't really exist - exit the function.
658
		return;
659 49aec489 Phil Davis
	}
660 3e643dba Ermal LUÇI
661 c93b3fcd Reid Linnemann
	$package = config_get_path("installedpackages/package/{$pkg_id}");
662
	if (empty($package)) {
663 0c9d489e Renato Botelho do Couto
		// No package belongs to the pkg_id passed to this function.
664
		return;
665 49aec489 Phil Davis
	}
666 3e643dba Ermal LUÇI
667 49aec489 Phil Davis
	if (!file_exists("/usr/local/pkg/" . $package['configurationfile'])) {
668 0c9d489e Renato Botelho do Couto
		log_error(sprintf(gettext("The %s package is missing its " .
669
		    "configuration file and must be reinstalled."),
670
		    $package['name']));
671 106574d1 Renato Botelho
		delete_package_xml($package['name']);
672 a0d4336f Renato Botelho
		return;
673 2c794549 Ermal
	}
674 a0d4336f Renato Botelho
675 0c9d489e Renato Botelho do Couto
	$pkg_config = parse_xml_config_pkg("/usr/local/pkg/" .
676
	    $package['configurationfile'], "packagegui");
677 49aec489 Phil Davis
	if (isset($pkg_config['nosync'])) {
678 2addd5b2 Ermal
		return;
679 49aec489 Phil Davis
	}
680 a0d4336f Renato Botelho
681 2c794549 Ermal
	/* Bring in package include files */
682
	if (!empty($pkg_config['include_file'])) {
683
		$include_file = $pkg_config['include_file'];
684 49aec489 Phil Davis
		if (file_exists($include_file)) {
685 2c794549 Ermal
			require_once($include_file);
686 49aec489 Phil Davis
		} else {
687 0c9d489e Renato Botelho do Couto
			log_error(sprintf(gettext('Reinstalling package %1$s " .
688
			    "because its include file(%2$s) is missing!'),
689
			    $package['name'], $include_file));
690 2c794549 Ermal
			uninstall_package($package['name']);
691 e5960712 PiBa-NL
			if (reinstall_package($package['name']) != 0) {
692 0c9d489e Renato Botelho do Couto
				log_error(sprintf(gettext("Reinstalling " .
693
				    "package %s failed. Take appropriate " .
694
				    "measures!!!"), $package['name']));
695 a0d4336f Renato Botelho
				return;
696
			}
697
			if (file_exists($include_file)) {
698
				require_once($include_file);
699
			} else {
700
				return;
701 83cfae8d Ermal Lu?i
			}
702 30e4c34a Scott Ullrich
		}
703 2c794549 Ermal
	}
704 30e4c34a Scott Ullrich
705 49aec489 Phil Davis
	if (!empty($pkg_config['custom_php_global_functions'])) {
706 2c794549 Ermal
		eval($pkg_config['custom_php_global_functions']);
707 49aec489 Phil Davis
	}
708
	if (!empty($pkg_config['custom_php_resync_config_command'])) {
709 2c794549 Ermal
		eval($pkg_config['custom_php_resync_config_command']);
710 49aec489 Phil Davis
	}
711 8c6516d1 Colin Smith
}
712
713 801fcf24 Renato Botelho
/* Read info.xml installed by package and return an array */
714
function read_package_config($package_name) {
715
	global $g;
716 e5b5e29c Renato Botelho
717 2568e151 Christian McDonald
	$pkg_info_xml = '/usr/local/share/' . g_get('pkg_prefix') . $package_name .
718 0c9d489e Renato Botelho do Couto
	    '/info.xml';
719 7860191a Renato Botelho
720 801fcf24 Renato Botelho
	if (!file_exists($pkg_info_xml)) {
721
		return false;
722
	}
723 7860191a Renato Botelho
724 801fcf24 Renato Botelho
	$pkg_info = parse_xml_config_pkg($pkg_info_xml, 'pfsensepkgs');
725 7860191a Renato Botelho
726 801fcf24 Renato Botelho
	if (empty($pkg_info)) {
727
		return false;
728 43dad535 Vinicius Coque
	}
729 801fcf24 Renato Botelho
730
	/* it always returns an array with 1 item */
731
	return $pkg_info['package'][0];
732 8c6516d1 Colin Smith
}
733
734 a2b0d909 Renato Botelho
/* Read package configurationfile and return an array */
735
function read_package_configurationfile($package_name) {
736
	$pkg_config = array();
737
	$id = get_package_id($package_name);
738 c93b3fcd Reid Linnemann
	$pkg_data = config_get_path("installedpackages/package/{$id}", []);
739
   
740
	if ($id < 0 || empty($pkg_data)) {
741 a2b0d909 Renato Botelho
		return $pkg_config;
742
	}
743
744 71e7de02 Renato Botelho do Couto
	if (empty($pkg_data['configurationfile'])) {
745
		return $pkg_config;
746
	}
747
748
	if (!file_exists('/usr/local/pkg/' . $pkg_data['configurationfile'])) {
749 a2b0d909 Renato Botelho
		return $pkg_config;
750
	}
751
752 0c9d489e Renato Botelho do Couto
	$pkg_config = parse_xml_config_pkg('/usr/local/pkg/' .
753 71e7de02 Renato Botelho do Couto
	    $pkg_data['configurationfile'], "packagegui");
754 a2b0d909 Renato Botelho
755
	return $pkg_config;
756
}
757
758 801fcf24 Renato Botelho
function get_after_install_info($package_name) {
759 666c49ce Renato Botelho
	$pkg_config = read_package_config($package_name);
760 384e2647 Renato Botelho
761 801fcf24 Renato Botelho
	if (isset($pkg_config['after_install_info'])) {
762
		return $pkg_config['after_install_info'];
763 49aec489 Phil Davis
	}
764 384e2647 Renato Botelho
765 801fcf24 Renato Botelho
	return '';
766
}
767 384e2647 Renato Botelho
768 801fcf24 Renato Botelho
function eval_once($toeval) {
769
	global $evaled;
770
	if (!$evaled) {
771
		$evaled = array();
772 49aec489 Phil Davis
	}
773 801fcf24 Renato Botelho
	$evalmd5 = md5($toeval);
774
	if (!in_array($evalmd5, $evaled)) {
775
		@eval($toeval);
776
		$evaled[] = $evalmd5;
777 384e2647 Renato Botelho
	}
778 801fcf24 Renato Botelho
	return;
779 384e2647 Renato Botelho
}
780
781 801fcf24 Renato Botelho
function install_package_xml($package_name) {
782
	if (($pkg_info = read_package_config($package_name)) == false) {
783
		return false;
784 49aec489 Phil Davis
	}
785 cfde64b8 Scott Ullrich
786 c92ccac7 Vinicius Coque
	pkg_debug(gettext("Beginning package installation.") . "\n");
787 0c9d489e Renato Botelho do Couto
	log_error(sprintf(gettext('Beginning package installation for %s .'),
788
	    $pkg_info['name']));
789 2a0e6517 Colin Smith
790 7597c8e8 Colin Smith
	/* add package information to config.xml */
791 af5d93f6 Renato Botelho
	$pkgid = get_package_id($pkg_info['name']);
792 e791dee8 Renato Botelho
	update_status(gettext("Saving updated package information...") . "\n");
793 c93b3fcd Reid Linnemann
	init_config_arr(array('installedpackages', 'package'));
794
	$pkgs = config_get_path('installedpackages/package', []);
795 49aec489 Phil Davis
	if ($pkgid == -1) {
796 c93b3fcd Reid Linnemann
		$pkgs[] = $pkg_info;
797 0c9d489e Renato Botelho do Couto
		$changedesc = sprintf(gettext("Installed %s package."),
798
		    $pkg_info['name']);
799 6acdf659 Carlos Eduardo Ramos
		$to_output = gettext("done.") . "\n";
800 7597c8e8 Colin Smith
	} else {
801 c93b3fcd Reid Linnemann
		$pkgs[$pkgid] = $pkg_info;
802 0c9d489e Renato Botelho do Couto
		$changedesc = sprintf(gettext("Overwrote previous " .
803
		    "installation of %s."), $pkg_info['name']);
804 6acdf659 Carlos Eduardo Ramos
		$to_output = gettext("overwrite!") . "\n";
805 7597c8e8 Colin Smith
	}
806 c93b3fcd Reid Linnemann
	config_set_path('installedpackages/package', $pkgs);
807 0c9d489e Renato Botelho do Couto
	write_config(sprintf(gettext("Intermediate config write during " .
808
	    "package install for %s."), $pkg_info['name']));
809 e791dee8 Renato Botelho
	update_status($to_output);
810 b2a66231 Ermal
811 801fcf24 Renato Botelho
	if (($pkgid = get_package_id($package_name)) == -1) {
812 abcdcfa0 Marcos Mendoza
		update_status(sprintf(gettext('The %1$s package is not ' .
813
		    'installed.%2$sInstallation aborted.'), $package_name,
814 0c9d489e Renato Botelho do Couto
		    "\n\n"));
815 b2a66231 Ermal
816 801fcf24 Renato Botelho
		uninstall_package($package_name);
817
		write_config($changedesc);
818 0c9d489e Renato Botelho do Couto
		log_error(sprintf(gettext("Failed to install package: %s."),
819
		    $pkg_info['name']));
820 e791dee8 Renato Botelho
		update_status(gettext("Failed to install package.") . "\n");
821 2c794549 Ermal
		return false;
822 e65a287f Scott Ullrich
	}
823 bfe9c9e7 jim-p
824 dfc51883 Renato Botelho do Couto
	if (!file_exists("/usr/local/pkg/" . $pkg_info['configurationfile'])) {
825
		pkg_debug("Unable to find config file\n");
826
		update_status(gettext("Loading package configuration... " .
827
		    "failed!") .  "\n\n" . gettext("Installation aborted."));
828
		pkg_debug(gettext("Unable to load package configuration. " .
829
		    "Installation aborted.") ."\n");
830 b2a66231 Ermal
831 dfc51883 Renato Botelho do Couto
		uninstall_package($package_name);
832
		write_config($changedesc);
833
		log_error(sprintf(gettext("Failed to install package: %s."),
834
		    $pkg_info['name']));
835
		update_status(gettext("Failed to install package.") . "\n");
836
		return false;
837
	}
838
839
	update_status(gettext("Loading package configuration... "));
840
	$pkg_config = parse_xml_config_pkg("/usr/local/pkg/" .
841
	    $pkg_info['configurationfile'], "packagegui");
842
	update_status(gettext("done.") . "\n");
843
	update_status(gettext("Configuring package components...") .
844
	    "\n");
845
	if (!empty($pkg_config['filter_rules_needed'])) {
846 c93b3fcd Reid Linnemann
		config_set_path("installedpackages/package/{$pkgid}/filter_rule_function",
847
						$pkg_config['filter_rules_needed']);
848 dfc51883 Renato Botelho do Couto
	}
849
	/* modify system files */
850
851
	/* if a require exists, include it.  this will
852
	 * show us where an error exists in a package
853
	 * instead of making us blindly guess
854
	 */
855
	$missing_include = false;
856
	if ($pkg_config['include_file'] <> "") {
857 6279f1b8 Renato Botelho do Couto
		update_status(gettext("Loading package instructions...") .
858
		    "\n");
859 dfc51883 Renato Botelho do Couto
		if (file_exists($pkg_config['include_file'])) {
860 6279f1b8 Renato Botelho do Couto
			pkg_debug("require_once('" .
861
			    $pkg_config['include_file'] . "')\n");
862 dfc51883 Renato Botelho do Couto
			require_once($pkg_config['include_file']);
863
		} else {
864 6279f1b8 Renato Botelho do Couto
			pkg_debug("Missing include " .
865
			    "{$pkg_config['include_file']}\n");
866 dfc51883 Renato Botelho do Couto
			$missing_include = true;
867
			update_status(sprintf(gettext("Include %s is missing!"),
868
			    basename($pkg_config['include_file'])) . "\n");
869
870
			uninstall_package($package_name);
871
			write_config($changedesc);
872 6279f1b8 Renato Botelho do Couto
			log_error(sprintf(gettext(
873
			    "Failed to install package: %s."),
874
			    $pkg_info['name']));
875
			update_status(gettext("Failed to install package.") .
876
			    "\n");
877 dfc51883 Renato Botelho do Couto
			return false;
878 43db85f8 Scott Ullrich
		}
879 dfc51883 Renato Botelho do Couto
	}
880 57811192 Ermal
881 dfc51883 Renato Botelho do Couto
	/* custom commands */
882
	update_status(gettext("Custom commands...") . "\n");
883
	if ($missing_include == false) {
884
		if ($pkg_config['custom_php_global_functions'] <> "") {
885 6279f1b8 Renato Botelho do Couto
			update_status(gettext(
886
			    "Executing custom_php_global_functions()..."));
887 dfc51883 Renato Botelho do Couto
			eval_once($pkg_config['custom_php_global_functions']);
888
			update_status(gettext("done.") . "\n");
889 57811192 Ermal
		}
890 dfc51883 Renato Botelho do Couto
		if ($pkg_config['custom_php_install_command']) {
891 6279f1b8 Renato Botelho do Couto
			update_status(gettext(
892
			    "Executing custom_php_install_command()..."));
893 dfc51883 Renato Botelho do Couto
			eval_once($pkg_config['custom_php_install_command']);
894
			update_status(gettext("done.") . "\n");
895
		}
896
		if ($pkg_config['custom_php_resync_config_command'] <> "") {
897 6279f1b8 Renato Botelho do Couto
			update_status(gettext(
898
			    "Executing custom_php_resync_config_command()..."));
899
			eval_once(
900
			    $pkg_config['custom_php_resync_config_command']);
901 dfc51883 Renato Botelho do Couto
			update_status(gettext("done.") . "\n");
902
		}
903
	}
904
	/* sidebar items */
905
	if (is_array($pkg_config['menu'])) {
906 c93b3fcd Reid Linnemann
		init_config_arr(array('installedpackages', 'menu'));
907
		$menus = config_get_path('installedpackages/menu', []);
908 dfc51883 Renato Botelho do Couto
		update_status(gettext("Menu items... "));
909
		foreach ($pkg_config['menu'] as $menu) {
910 c93b3fcd Reid Linnemann
			foreach ($menus as $amenu) {
911 80f1c44b Renato Botelho do Couto
				if ($amenu['name'] == $menu['name']) {
912
					continue 2;
913 49aec489 Phil Davis
				}
914 7597c8e8 Colin Smith
			}
915 c93b3fcd Reid Linnemann
			$menus[] = $menu;
916 7597c8e8 Colin Smith
		}
917 c93b3fcd Reid Linnemann
		config_set_path('installedpackages/menu', $menus);
918 dfc51883 Renato Botelho do Couto
		update_status(gettext("done.") . "\n");
919
	}
920
	/* services */
921 80f1c44b Renato Botelho do Couto
	init_config_arr(array('installedpackages', 'service'));
922 dfc51883 Renato Botelho do Couto
	if (is_array($pkg_config['service'])) {
923
		update_status(gettext("Services... "));
924 1983008e Reid Linnemann
		$services = config_get_path('installedpackages/service', []);
925 dfc51883 Renato Botelho do Couto
		foreach ($pkg_config['service'] as $service) {
926 b2459716 jim-p
			if (empty($service)) {
927
				continue;
928
			}
929 c93b3fcd Reid Linnemann
			foreach ($services as $aservice) {
930 b2459716 jim-p
				if (empty($aservice)) {
931
					continue;
932
				}
933 80f1c44b Renato Botelho do Couto
				if ($aservice['name'] == $service['name']) {
934
					continue 2;
935 49aec489 Phil Davis
				}
936 2dc264a4 Colin Smith
			}
937 c93b3fcd Reid Linnemann
			$services[] = $service;
938 2dc264a4 Colin Smith
		}
939 c93b3fcd Reid Linnemann
		config_set_path('installedpackages/service', $services);
940 dfc51883 Renato Botelho do Couto
		update_status(gettext("done.") . "\n");
941
	}
942
	if (is_array($pkg_config['tabs'])) {
943 99b3a5cb jim-p
		init_config_arr(array('installedpackages', 'package', $pkgid, 'tabs'));
944 c93b3fcd Reid Linnemann
		config_set_path("installedpackages/package/{$pkgid}/tabs",$pkg_config['tabs']);
945 dfc51883 Renato Botelho do Couto
	}
946
	/* plugins */
947
	if (isset($pkg_config['include_file'])) {
948 c93b3fcd Reid Linnemann
		config_set_path("installedpackages/package/{$pkgid}/include_file", $pkg_config['include_file']);
949 dfc51883 Renato Botelho do Couto
	}
950 99b3a5cb jim-p
	if (is_array($pkg_config['plugins'])) {
951
		init_config_arr(array('installedpackages', 'package', $pkgid, 'plugins'));
952 c93b3fcd Reid Linnemann
		config_set_path("installedpackages/package/{$pkgid}/plugins", $pkg_config['plugins']);
953 7597c8e8 Colin Smith
	}
954 2c794549 Ermal
955 e791dee8 Renato Botelho
	update_status(gettext("Writing configuration... "));
956 801fcf24 Renato Botelho
	write_config($changedesc);
957 0c9d489e Renato Botelho do Couto
	log_error(sprintf(gettext("Successfully installed package: %s."),
958
	    $pkg_info['name']));
959 e791dee8 Renato Botelho
	update_status(gettext("done.") . "\n");
960 801fcf24 Renato Botelho
	if ($pkg_info['after_install_info']) {
961 e791dee8 Renato Botelho
		update_status($pkg_info['after_install_info']);
962 2d26ee5e Sjon Hortensius
	}
963 801fcf24 Renato Botelho
964 3a0df77e jim-p
	/* set up package logging streams */
965
	if ($pkg_info['logging']) {
966
		system_syslogd_start(true);
967
	}
968
969 2c794549 Ermal
	return true;
970 64974db7 Scott Ullrich
}
971
972 3bb7e3e8 Renato Botelho
function delete_package_xml($package_name, $when = "post-deinstall") {
973 c93b3fcd Reid Linnemann
	global $g;
974 b2a66231 Ermal
975 6955830f Ermal Lu?i
976 3bb7e3e8 Renato Botelho
	$pkgid = get_package_id($package_name);
977 b2a66231 Ermal
	if ($pkgid == -1) {
978 abcdcfa0 Marcos Mendoza
		update_status(sprintf(gettext('The %1$s package is not ' .
979
		    'installed.%2$sDeletion aborted.'), $package_name, "\n\n"));
980 e65a287f Scott Ullrich
		ob_flush();
981
		sleep(1);
982
		return;
983
	}
984 086cf944 Phil Davis
	pkg_debug(sprintf(gettext("Removing %s package... "), $package_name));
985 0c9d489e Renato Botelho do Couto
	update_status(sprintf(gettext("Removing %s components..."),
986
	    $package_name) . "\n");
987 407bf67a Colin Smith
	/* parse package configuration */
988 c6c398c6 jim-p
	init_config_arr(array('installedpackages', 'package', $pkgid));
989 c93b3fcd Reid Linnemann
	$pkg_info = config_get_path("installedpackages/package/{$pkgid}",[]);
990 bfd3334b jim-p
	init_config_arr(array('installedpackages', 'menu'));
991 c93b3fcd Reid Linnemann
	$menus = config_get_path('installedpackages/menu', []);
992 bfd3334b jim-p
	init_config_arr(array('installedpackages', 'service'));
993 c93b3fcd Reid Linnemann
	$services = config_get_path('installedpackages/service', []);
994 49aec489 Phil Davis
	if (file_exists("/usr/local/pkg/" . $pkg_info['configurationfile'])) {
995 0c9d489e Renato Botelho do Couto
		$pkg_config = parse_xml_config_pkg("/usr/local/pkg/" .
996 b2a98518 Renato Botelho do Couto
		    $pkg_info['configurationfile'], "packagegui");
997 3f01fe47 Colin Smith
		/* remove menu items */
998 58e0bfbc Renato Botelho do Couto
		if (is_array($pkg_config['menu']) && is_array($menus)) {
999 e791dee8 Renato Botelho
			update_status(gettext("Menu items... "));
1000 58e0bfbc Renato Botelho do Couto
			foreach ($pkg_config['menu'] as $menu) {
1001
				foreach ($menus as $key => $instmenu) {
1002 fca0f301 jim-p
					if (empty($instmenu) || ($instmenu['name'] ==
1003
					    $menu['name'])) {
1004 c93b3fcd Reid Linnemann
						config_del_path("installedpackages/menu/{$key}");
1005 58e0bfbc Renato Botelho do Couto
						break;
1006 b2a66231 Ermal
					}
1007 8604523b Ermal Lu?i
				}
1008
			}
1009 e791dee8 Renato Botelho
			update_status(gettext("done.") . "\n");
1010 407bf67a Colin Smith
		}
1011 3c41c4ab Colin Smith
		/* remove services */
1012 413e939f Renato Botelho do Couto
		if (is_array($pkg_config['service']) && is_array($services)) {
1013 e791dee8 Renato Botelho
			update_status(gettext("Services... "));
1014 413e939f Renato Botelho do Couto
			foreach ($pkg_config['service'] as $service) {
1015 b2459716 jim-p
				if (empty($service)) {
1016
					continue;
1017
				}
1018 413e939f Renato Botelho do Couto
				foreach ($services as $key => $instservice) {
1019 b2459716 jim-p
					if (empty($instservice) ||
1020
					    ($instservice['name'] !=
1021
					    $service['name'])) {
1022 413e939f Renato Botelho do Couto
						continue;
1023
					}
1024
					if (platform_booting() != true) {
1025
						stop_service($service['name']);
1026
					}
1027
					if ($service['rcfile']) {
1028
						if (empty($service['prefix'])) {
1029
							$prefix = RCFILEPREFIX;
1030
						} else {
1031
							$prefix =
1032
							    $service['prefix'];
1033 8604523b Ermal Lu?i
						}
1034 413e939f Renato Botelho do Couto
						unlink_if_exists($prefix .
1035
						    $service['rcfile']);
1036 0cab7cad Colin Smith
					}
1037 c93b3fcd Reid Linnemann
					config_del_path("installedpackages/service/{$key}");
1038 3c41c4ab Colin Smith
				}
1039
			}
1040 e791dee8 Renato Botelho
			update_status(gettext("done.") . "\n");
1041 3c41c4ab Colin Smith
		}
1042 b2a66231 Ermal
		/*
1043 0c9d489e Renato Botelho do Couto
		 * XXX: Otherwise inclusion of config.inc again invalidates
1044
		 *      actions taken.
1045 a2febf9a Stephen Beaver
		 *	Same is done during installation.
1046 b2a66231 Ermal
		 */
1047 0c9d489e Renato Botelho do Couto
		write_config(sprintf(gettext("Intermediate config write " .
1048
		    "during package removal for %s."), $package_name));
1049 b2a66231 Ermal
1050
		/*
1051 0c9d489e Renato Botelho do Couto
		 * If a require exists, include it. this will
1052 b2a66231 Ermal
		 * show us where an error exists in a package
1053
		 * instead of making us blindly guess
1054 892aef15 Scott Ullrich
		 */
1055 fcf92dae Ermal
		$missing_include = false;
1056 49aec489 Phil Davis
		if ($pkg_config['include_file'] <> "") {
1057 2b6de647 Renato Botelho do Couto
			update_status(gettext("Loading package instructions...")
1058
			    . "\n");
1059 49aec489 Phil Davis
			if (file_exists($pkg_config['include_file'])) {
1060 2b6de647 Renato Botelho do Couto
				pkg_debug("require_once(\"" .
1061
				    "{$pkg_config['include_file']}\")\n");
1062 1570d27a Ermal Lu?i
				require_once($pkg_config['include_file']);
1063 49aec489 Phil Davis
			} else {
1064 2b6de647 Renato Botelho do Couto
				pkg_debug("Missing include " .
1065
				    $pkg_config['include_file'] . "\n");
1066 fcf92dae Ermal
				$missing_include = true;
1067 0c9d489e Renato Botelho do Couto
				update_status(sprintf(gettext("Include file " .
1068
				    "%s could not be found for inclusion."),
1069
				    basename($pkg_config['include_file'])) .
1070
				    "\n");
1071 fcf92dae Ermal
			}
1072
		}
1073 0c9d489e Renato Botelho do Couto
		/*
1074 fcf92dae Ermal
		 * NOTE: It is not possible to handle parse errors on eval.
1075 0c9d489e Renato Botelho do Couto
		 * So we prevent it from being run at all to not interrupt all
1076
		 * the other code.
1077 fcf92dae Ermal
		 */
1078 3bb7e3e8 Renato Botelho
		if ($when == "deinstall" && $missing_include == false) {
1079 0c9d489e Renato Botelho do Couto
			/*
1080
			 * evaluate this package's global functions and pre
1081
			 * deinstall commands
1082
			 */
1083 49aec489 Phil Davis
			if ($pkg_config['custom_php_global_functions'] <> "") {
1084 fcf92dae Ermal
				eval_once($pkg_config['custom_php_global_functions']);
1085 49aec489 Phil Davis
			}
1086
			if ($pkg_config['custom_php_pre_deinstall_command'] <> "") {
1087 fcf92dae Ermal
				eval_once($pkg_config['custom_php_pre_deinstall_command']);
1088 49aec489 Phil Davis
			}
1089 43db85f8 Scott Ullrich
		}
1090 644d2d59 Colin Smith
		/* deinstall commands */
1091 2b6de647 Renato Botelho do Couto
		if ($when == "deinstall" &&
1092
		    $pkg_config['custom_php_deinstall_command'] <> "") {
1093 e791dee8 Renato Botelho
			update_status(gettext("Deinstall commands... "));
1094 fcf92dae Ermal
			if ($missing_include == false) {
1095
				eval_once($pkg_config['custom_php_deinstall_command']);
1096 e791dee8 Renato Botelho
				update_status(gettext("done.") . "\n");
1097 49aec489 Phil Davis
			} else {
1098 0c9d489e Renato Botelho do Couto
				update_status("\n". gettext("Not executing " .
1099
				    "custom deinstall hook because an " .
1100
				    "include is missing.") . "\n");
1101 49aec489 Phil Davis
			}
1102 644d2d59 Colin Smith
		}
1103 407bf67a Colin Smith
	}
1104 2addd5b2 Ermal
	/* syslog */
1105 ce7edfff doktornotor
	$need_syslog_restart = false;
1106 71024ca1 Viktor G
	if (is_array($pkg_info['logging']) && !empty($pkg_info['logging']['logfilename'])) {
1107 e8c516a0 Phil Davis
		update_status(gettext("Syslog entries... "));
1108 71024ca1 Viktor G
		/* remove package-related syslog configuration but retain log data,
1109
		 * see https://redmine.pfsense.org/issues/11846 */
1110
		@unlink_if_exists("{$g['varetc_path']}/syslog.d/" . basename($pkg_info['logging']['logfilename']) . ".conf");
1111 e791dee8 Renato Botelho
		update_status("done.\n");
1112 ce7edfff doktornotor
		$need_syslog_restart = true;
1113 2addd5b2 Ermal
	}
1114 2d26ee5e Sjon Hortensius
1115 6b861ecd Renato Botelho
	if ($when == "post-deinstall") {
1116
		/* remove config.xml entries */
1117
		update_status(gettext("Configuration... "));
1118 c93b3fcd Reid Linnemann
		config_del_path("installedpackages/package/{$pkgid}");
1119 6b861ecd Renato Botelho
		update_status(gettext("done.") . "\n");
1120 0c9d489e Renato Botelho do Couto
		write_config(sprintf(gettext("Removed %s package."),
1121
		    $package_name));
1122
		/*
1123
		 * remove package entry from /etc/syslog.conf if needed
1124
		 * this must be done after removing the entries from config.xml
1125
		 */
1126 8724b1ad jim-p
		if ($need_syslog_restart) {
1127 3a0df77e jim-p
			system_syslogd_start(true);
1128 8724b1ad jim-p
		}
1129 6b861ecd Renato Botelho
	}
1130 f0a550fd Colin Smith
}
1131 5025a56c Scott Ullrich
1132 46903fb9 Renato Botelho
/*
1133 f3f98e97 Phil Davis
 * Used during upgrade process or restore backup process, verify all
1134 46903fb9 Renato Botelho
 * packages installed in config.xml and install pkg accordingly
1135
 */
1136
function package_reinstall_all() {
1137 c93b3fcd Reid Linnemann
	global $g;
1138 c53eb903 Ermal
1139 c93b3fcd Reid Linnemann
	$pkgs = config_get_path('installedpackages/package');
1140
	if ($pkgs === null) {
1141 46903fb9 Renato Botelho
		return true;
1142
	}
1143
1144 10511c3b Renato Botelho
	/*
1145
	 * Configure default pkg repo for current version instead of
1146
	 * using it from backup, that could be older
1147
	 */
1148
	$default_repo = pkg_get_default_repo();
1149
	$current_repo_path = "";
1150 c93b3fcd Reid Linnemann
	if (!empty(config_get_path('system/pkg_repo_conf_path'))) {
1151
		$current_repo_path = config_get_path('system/pkg_repo_conf_path');
1152 8552be10 Renato Botelho
	}
1153
1154 10511c3b Renato Botelho
	if ($current_repo_path != $default_repo['path']) {
1155 c93b3fcd Reid Linnemann
		config_set_path('system/pkg_repo_conf_path', $default_repo['path']);
1156 10511c3b Renato Botelho
		write_config( "Configured default pkg repo after restore");
1157 654dc4ac Luiz Otavio O Souza
		pkg_switch_repo($default_repo['path'], $default_repo['name']);
1158 10511c3b Renato Botelho
	}
1159 3610a08e Renato Botelho
1160 10511c3b Renato Botelho
	/* wait for internet connection */
1161
	log_error(gettext("Waiting for Internet connection to update pkg " .
1162
	    "metadata and finish package reinstallation"));
1163
	$ntries = 3;
1164
	while ($ntries > 0) {
1165
		if (pkg_update(true)) {
1166
			break;
1167 3610a08e Renato Botelho
		}
1168 10511c3b Renato Botelho
		sleep(1);
1169
		$ntries--;
1170 46903fb9 Renato Botelho
	}
1171
1172 10511c3b Renato Botelho
	if ($ntries == 0) {
1173
		return false;
1174 4221eba1 Renato Botelho
	}
1175
1176 c93b3fcd Reid Linnemann
	if (!empty($pkgs)) { 
1177 1bedcacc Renato Botelho
		$pkg_info = get_pkg_info();
1178
	}
1179 10511c3b Renato Botelho
1180 c93b3fcd Reid Linnemann
	foreach ($pkgs as $package) {
1181 46903fb9 Renato Botelho
		$found = false;
1182
		foreach ($pkg_info as $pkg) {
1183
			pkg_remove_prefix($pkg['name']);
1184 468cd92b Viktor G
			if ($pkg['name'] == $package['internal_name']) {
1185 2568e151 Christian McDonald
				pkg_install(g_get('pkg_prefix') . $package['internal_name'], true);
1186 468cd92b Viktor G
				$found = true;
1187
			} elseif ($pkg['name'] == $package['name']) {
1188
				/* some packages use 'name' as the package name,
1189
				 * see https://redmine.pfsense.org/issues/12766 */
1190 2568e151 Christian McDonald
				pkg_install(g_get('pkg_prefix') . $package['name'], true);
1191 46903fb9 Renato Botelho
				$found = true;
1192 468cd92b Viktor G
			}
1193
			if ($found) {
1194 46903fb9 Renato Botelho
				break;
1195
			}
1196
		}
1197
1198
		if (!$found) {
1199
			if (!function_exists("file_notice")) {
1200
				require_once("notices.inc");
1201
			}
1202
1203 b7ca68bc jim-p
			/* Name of the package that cannot be found. If it has
1204
			 * an internal name, include that as well. */
1205
			$pkgname = $package['name'];
1206
			if (!empty($package['internal_name'])) {
1207
				$pkgname .= " ({$package['internal_name']})";
1208
			}
1209 46903fb9 Renato Botelho
			file_notice(gettext("Package reinstall"),
1210 10511c3b Renato Botelho
			    sprintf(gettext("Package %s does not exist in " .
1211
			    "current %s version and it has been removed."),
1212 2568e151 Christian McDonald
			    $pkgname, g_get('product_label')));
1213 c0cb3c73 Renato Botelho
			uninstall_package($package);
1214 46903fb9 Renato Botelho
		}
1215
	}
1216
1217 a55718c8 Renato Botelho
	/*
1218
	 * Verify remaining binary packages not present in current config
1219
	 * during backup restore and remove them
1220
	 */
1221 10511c3b Renato Botelho
	$installed_packages = get_pkg_info('all', true, true);
1222
	foreach ($installed_packages as $package) {
1223
		$shortname = $package['name'];
1224
		pkg_remove_prefix($shortname);
1225
		if (get_package_id($shortname) != -1) {
1226
			continue;
1227 a55718c8 Renato Botelho
		}
1228 10511c3b Renato Botelho
		pkg_delete($package['name']);
1229 a55718c8 Renato Botelho
	}
1230
1231 46903fb9 Renato Botelho
	return true;
1232 9b193619 Scott Ullrich
}
1233
1234 60dd7649 jim-p
function stop_packages() {
1235
	require_once("config.inc");
1236
	require_once("functions.inc");
1237
	require_once("filter.inc");
1238
	require_once("shaper.inc");
1239
	require_once("captiveportal.inc");
1240
	require_once("pkg-utils.inc");
1241
	require_once("pfsense-utils.inc");
1242
	require_once("service-utils.inc");
1243
1244 e8c516a0 Phil Davis
	log_error(gettext("Stopping all packages."));
1245 60dd7649 jim-p
1246 c5966711 phildd
	$rcfiles = glob(RCFILEPREFIX . "*.sh");
1247 49aec489 Phil Davis
	if (!$rcfiles) {
1248 60dd7649 jim-p
		$rcfiles = array();
1249 49aec489 Phil Davis
	} else {
1250 60dd7649 jim-p
		$rcfiles = array_flip($rcfiles);
1251 49aec489 Phil Davis
		if (!$rcfiles) {
1252 60dd7649 jim-p
			$rcfiles = array();
1253 49aec489 Phil Davis
		}
1254 60dd7649 jim-p
	}
1255
1256 c93b3fcd Reid Linnemann
	foreach (config_get_path('installedpackages/package', []) as $package) {
1257
		$internal_name = get_package_internal_name($package);
1258
		if (is_service_running($internal_name)) {
1259
			echo " Stopping package {$package['name']}...";
1260
			stop_service($internal_name);
1261
			echo "done.\n";
1262
			unset($rcfiles[RCFILEPREFIX . strtolower($internal_name) . ".sh"]);
1263 60dd7649 jim-p
		}
1264
	}
1265
1266 6186cdc4 jim-p
	foreach ($rcfiles as $rcfile => $number) {
1267
		$shell = @popen("/bin/sh", "w");
1268
		if ($shell) {
1269 60dd7649 jim-p
			echo " Stopping {$rcfile}...";
1270 0c9d489e Renato Botelho do Couto
			if (!@fwrite($shell,
1271
			    "{$rcfile} stop >>/tmp/bootup_messages 2>&1")) {
1272 49aec489 Phil Davis
				if ($shell) {
1273 61ef1385 Ermal
					pclose($shell);
1274 49aec489 Phil Davis
				}
1275 61ef1385 Ermal
				$shell = @popen("/bin/sh", "w");
1276
			}
1277 60dd7649 jim-p
			echo "done.\n";
1278 6186cdc4 jim-p
			pclose($shell);
1279 60dd7649 jim-p
		}
1280
	}
1281
}
1282
1283 d5f0597b Renato Botelho
/* Identify which meta package is installed */
1284
function get_meta_pkg_name() {
1285
	global $g;
1286
1287
	/* XXX: Use pkg annotation */
1288 2568e151 Christian McDonald
	if (is_pkg_installed(g_get('product_name'))) {
1289
		return g_get('product_name');
1290 b395c4f2 Renato Botelho
	}
1291 2568e151 Christian McDonald
	foreach (g_get('alternativemetaports') as $suffix) {
1292
		if (is_pkg_installed(g_get('product_name') . '-' . $suffix)) {
1293
			return g_get('product_name') . '-' . $suffix;
1294 b395c4f2 Renato Botelho
		}
1295 d5f0597b Renato Botelho
	}
1296
	return false;
1297
}
1298
1299
/* Identify which base package is installed */
1300
function get_base_pkg_name() {
1301
	global $g;
1302
1303
	/* XXX: Use pkg annotation */
1304 2568e151 Christian McDonald
	if (is_pkg_installed(g_get('product_name') . '-base-' . g_get('product_name'))) {
1305
		return g_get('product_name') . '-base-' . g_get('product_name');
1306
	} else if (is_pkg_installed(g_get('product_name') . '-base')) {
1307
		return g_get('product_name') . '-base';
1308 d5f0597b Renato Botelho
	}
1309
	return false;
1310
}
1311
1312
/* Verify if system needs upgrade (meta package or base) */
1313 e8f8aeb6 Renato Botelho
function get_system_pkg_version($baseonly = false, $use_cache = true) {
1314 d5f0597b Renato Botelho
	global $g;
1315
1316 620a9745 Viktor G
	if (!check_dnsavailable('any')) {
1317 bbb3bbeb Viktor G
		return false;
1318
	}
1319
1320 2568e151 Christian McDonald
	$cache_file = g_get('version_cache_file');
1321 e8f8aeb6 Renato Botelho
	$rc_file = $cache_file . '.rc';
1322
1323
	$rc = "";
1324
	if ($use_cache && file_exists($rc_file) &&
1325 2568e151 Christian McDonald
	    (time()-filemtime($rc_file) < g_get('version_cache_refresh'))) {
1326 e8f8aeb6 Renato Botelho
		$rc = chop(@file_get_contents($rc_file));
1327
	}
1328
1329
	if ($rc == "2") {
1330
		$output = @file_get_contents($cache_file);
1331
	} else if ($rc != "0") {
1332
		$output = exec(
1333
		    "/usr/local/sbin/{$g['product_name']}-upgrade -c", $_gc,
1334
		    $rc);
1335 429091c8 Renato Botelho
1336
		/* Update cache if it succeeded */
1337
		if ($rc == 0 || $rc == 2) {
1338
			@file_put_contents($cache_file, $output);
1339
			@file_put_contents($rc_file, $rc);
1340 6701a859 Renato Botelho do Couto
		} else {
1341
			return false;
1342 429091c8 Renato Botelho
		}
1343 e8f8aeb6 Renato Botelho
	}
1344 ee836314 Renato Botelho
1345
	/* pfSense-upgrade returns 2 when there is a new version */
1346 e8f8aeb6 Renato Botelho
	if ($rc == "2") {
1347 ee836314 Renato Botelho
		$new_version = explode(' ', $output)[0];
1348
	}
1349
1350 d5f0597b Renato Botelho
	$base_pkg = get_base_pkg_name();
1351
	$meta_pkg = get_meta_pkg_name();
1352
1353
	if (!$base_pkg || !$meta_pkg) {
1354
		return false;
1355
	}
1356
1357 d4fbf5b7 Renato Botelho
	$info = get_pkg_info($base_pkg, true, true);
1358 d5f0597b Renato Botelho
1359
	$pkg_info = array();
1360
	foreach ($info as $item) {
1361
		if ($item['name'] == $base_pkg) {
1362
			$pkg_info = $item;
1363 ee836314 Renato Botelho
			break;
1364 d5f0597b Renato Botelho
		}
1365
	}
1366
1367 ee836314 Renato Botelho
	if (empty($pkg_info) || (!$baseonly && ($pkg_info['version'] ==
1368
	    $pkg_info['installed_version']))) {
1369 d4fbf5b7 Renato Botelho
		$info = get_pkg_info($meta_pkg, true, true);
1370 d5f0597b Renato Botelho
1371
		foreach ($info as $item) {
1372 59d256a1 Renato Botelho
			if ($item['name'] == $meta_pkg) {
1373 d5f0597b Renato Botelho
				$pkg_info = $item;
1374 ee836314 Renato Botelho
				break;
1375 d5f0597b Renato Botelho
			}
1376
		}
1377
	}
1378
1379
	if (empty($pkg_info)) {
1380
		return false;
1381
	}
1382
1383 8d5ff32b Renato Botelho
	$result = array(
1384 ee836314 Renato Botelho
	    'version'           => $new_version ?: $pkg_info['version'],
1385 d5f0597b Renato Botelho
	    'installed_version' => $pkg_info['installed_version']
1386
	);
1387 8d5ff32b Renato Botelho
1388
	$result['pkg_version_compare'] = pkg_version_compare(
1389
	    $result['installed_version'], $result['version']);
1390
1391
	return $result;
1392 d5f0597b Renato Botelho
}
1393
1394 db8621d8 Renato Botelho
/* List available repos */
1395
function pkg_list_repos() {
1396 ad3c9763 Renato Botelho
	global $g;
1397
1398 654dc4ac Luiz Otavio O Souza
	$repo_base = "{$g['pkg_repos_path']}/{$g['product_name']}-repo";
1399
	$result = array();
1400
	$name_files = glob("{$repo_base}-*.name");
1401
	foreach ($name_files as $name_file) {
1402
		$repo_name = file_get_contents($name_file);
1403
		if ($repo_name == false || strlen($repo_name) <= 1) {
1404
			continue;
1405
		}
1406
		$repo_name_base = "{$repo_base}-{$repo_name}";
1407
		$descr_file = "{$repo_name_base}.descr";
1408 db8621d8 Renato Botelho
		if (file_exists($descr_file)) {
1409 654dc4ac Luiz Otavio O Souza
			$descr = file_get_contents($descr_file);
1410
			if ($descr == false) {
1411
				$descr = 'Unknown';
1412
			}
1413 db8621d8 Renato Botelho
		} else {
1414
			$descr = 'Unknown';
1415
		}
1416
		$entry = array(
1417 654dc4ac Luiz Otavio O Souza
		    'name' => $repo_name,
1418
		    'path' => "{$repo_name_base}.conf",
1419 db8621d8 Renato Botelho
		    'descr' => $descr
1420
		);
1421 654dc4ac Luiz Otavio O Souza
		if (file_exists("{$repo_name_base}.default")) {
1422 fa5e9db2 Renato Botelho
			$entry['default'] = true;
1423
		}
1424 db8621d8 Renato Botelho
		$result[] = $entry;
1425 ad3c9763 Renato Botelho
	}
1426
1427 db8621d8 Renato Botelho
	return $result;
1428
}
1429
1430 8552be10 Renato Botelho
function pkg_get_default_repo() {
1431
	$repos = pkg_list_repos();
1432
1433
	foreach ($repos as $repo) {
1434
		if (isset($repo['default'])) {
1435
			return $repo;
1436
		}
1437
	}
1438
1439
	/* No default found, return the first one */
1440
	return ($repos[0]);
1441
}
1442
1443 b870f03d Renato Botelho
/* List available repos on a format to be used by selectors */
1444
function pkg_build_repo_list() {
1445
	$repos = pkg_list_repos();
1446
	$list = array();
1447
1448
	foreach ($repos as $repo) {
1449
		$list[$repo['name']] = $repo['descr'];
1450
	}
1451
1452
	return($list);
1453
}
1454
1455
/* Find repo by path */
1456
function pkg_get_repo_name($path) {
1457
	$repos = pkg_list_repos();
1458
1459 fa5e9db2 Renato Botelho
	$default = $repos[0]['name'];
1460 b870f03d Renato Botelho
	foreach ($repos as $repo) {
1461
		if ($repo['path'] == $path) {
1462
			return $repo['name'];
1463
		}
1464 fa5e9db2 Renato Botelho
		if (isset($repo['default'])) {
1465
			$default = $repo['name'];
1466
		}
1467 b870f03d Renato Botelho
	}
1468
1469
	/* Default */
1470 fa5e9db2 Renato Botelho
	return $default;
1471 b870f03d Renato Botelho
}
1472
1473 2f723b39 Luiz Otavio O Souza
/* Find the current or default package help file. */
1474
function pkg_get_repo_help() {
1475
	global $g;
1476
1477
	$repo_conf_path = config_get_path('system/pkg_repo_conf_path');
1478
	/* Get the current or the default repo name. */
1479
	$repo_name = pkg_get_repo_name($repo_conf_path);
1480
	$repo_base = "{$g['pkg_repos_path']}/{$g['product_name']}-repo";
1481
	return "{$repo_base}-{$repo_name}.help";
1482
}
1483
1484 7fe4d351 Renato Botelho
/* Switch between stable and devel repos */
1485 654dc4ac Luiz Otavio O Souza
function pkg_switch_repo($repo_path, $repo_name) {
1486
	global $g, $config;
1487 7fe4d351 Renato Botelho
1488
	safe_mkdir("/usr/local/etc/pkg/repos");
1489
	@unlink("/usr/local/etc/pkg/repos/{$g['product_name']}.conf");
1490 654dc4ac Luiz Otavio O Souza
	$repo = "{$repo_path}/{$g['product_name']}-repo-{$repo_name}.conf";
1491
	@symlink($repo, "/usr/local/etc/pkg/repos/{$g['product_name']}.conf");
1492 7fe4d351 Renato Botelho
1493 654dc4ac Luiz Otavio O Souza
	/* Do not fetch new settings, only setup the repo pkg.conf. */
1494
	mwexec("/usr/local/sbin/{$g['product_name']}-repo-setup -U");
1495 7fe4d351 Renato Botelho
1496 b58c1588 Renato Botelho
	/* Update pfSense_version cache */
1497
	mwexec_bg("/etc/rc.update_pkg_metadata now");
1498
	return;
1499 ad3c9763 Renato Botelho
}
1500
1501 654dc4ac Luiz Otavio O Souza
/*
1502
 * Update the repository settings.
1503
 */
1504
function update_repos() {
1505
1506
	$rc = -1;
1507
	$out = NULL;
1508
	$product_name = g_get('product_name');
1509
1510
	$res = exec("/usr/local/sbin/{$product_name}-repoc", $out, $rc);
1511
	if ($res === false || $out === NULL) {
1512
		return (array( "error" => 1,
1513
		    "messages" => array("We could not connect to Netgate servers. Please try again later.")));
1514
	}
1515
	$rtrn = array( "error" => $rc, "messages" => array() );
1516
	if (isset($out) && is_array($out) &&
1517
	    count($out) > 1 && $out[0] === "Messages:") {
1518
		for ($i = 1; $i < count($out); $i++) {
1519
			$rtrn['messages'][] = $out[$i];
1520
		}
1521
	}
1522
1523
	return ($rtrn);
1524
}
1525
1526 61ef1385 Ermal
?>