Project

General

Profile

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