Project

General

Profile

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