Project

General

Profile

Download (30.6 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/****h* pfSense/pkg-utils
3
 * NAME
4
 *   pkg-utils.inc - Package subsystem
5
 * DESCRIPTION
6
 *   This file contains various functions used by the pfSense package system.
7
 * HISTORY
8
 *   $Id$
9
 ******
10
 *
11
 * Copyright (C) 2005 Colin Smith (ethethlay@gmail.com)
12
 * All rights reserved.
13
 * Redistribution and use in source and binary forms, with or without
14
 * modification, are permitted provided that the following conditions are met:
15
 *
16
 * 1. Redistributions of source code must retain the above copyright notice,
17
 * this list of conditions and the following disclaimer.
18
 *
19
 * 2. Redistributions in binary form must reproduce the above copyright
20
 * notice, this list of conditions and the following disclaimer in the
21
 * documentation and/or other materials provided with the distribution.
22
 *
23
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
25
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26
 * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
27
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
 * RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
 * POSSIBILITY OF SUCH DAMAGE.
33
 *
34
 */
35
require_once("xmlrpc.inc");
36
require_once("xmlparse.inc");
37

    
38
/* add package specific listtags to XML parser */
39
$listtags = array_merge($listtags, array("onetoone", "queue", "rule", "servernat", "alias", "additional_files_needed", "tab", "template", "menu", "rowhelperfield", "service", "step", "package", "columnitem", "option", "item", "field", "package"));
40

    
41
require_once("pfsense-utils.inc");
42
require_once("globals.inc");
43

    
44
safe_mkdir("/var/db/pkg");
45
safe_mkdir("/usr/local/pkg");
46
safe_mkdir("/usr/local/pkg/pf");
47

    
48

    
49
/****f* pkg-utils/is_package_installed
50
 * NAME
51
 *   is_package_installed - Check whether a package is installed.
52
 * INPUTS
53
 *   $packagename	- name of the package to check
54
 * RESULT
55
 *   boolean	- true if the package is installed, false otherwise
56
 * NOTES
57
 *   This function is deprecated - get_pkg_id() can already check for installation.
58
 ******/
59
function is_package_installed($packagename) {
60
	$pkg = get_pkg_id($packagename);
61
	if($pkg == -1) return false;
62
	return true;
63
}
64
            
65
/****f* pkg-utils/get_pkg_id
66
 * NAME
67
 *   get_pkg_id - Find a package's numeric ID.
68
 * INPUTS
69
 *   $pkg_name	- name of the package to check
70
 * RESULT
71
 *   integer    - -1 if package is not found, >-1 otherwise
72
 ******/
73
function get_pkg_id($pkg_name) {
74
    global $config;
75
    if(is_array($config['installedpackages']['package'])) {
76
        $i = 0;
77
        foreach($config['installedpackages']['package'] as $pkg) {
78
            if($pkg['name'] == $pkg_name) return $i;
79
            $i++;
80
        }
81
    }
82
    return -1;
83
}
84

    
85
/****f* pkg-utils/get_pkg_info
86
 * NAME
87
 *   get_pkg_info - Retrive package information from pfsense.com.
88
 * INPUTS
89
 *   $pkgs - 'all' to retrive all packages, an array containing package names otherwise
90
 *   $info - 'all' to retrive all information, an array containing keys otherwise
91
 * RESULT
92
 *   $raw_versions - Array containing retrieved information, indexed by package name.
93
 ******/
94
function get_pkg_info($pkgs = 'all', $info = 'all') {
95
	global $g;
96
        $params = array("pkg" => $pkgs, "info" => $info);
97
        $msg = new XML_RPC_Message('pfsense.get_pkgs', array(php_value_to_xmlrpc($params)));
98
        $cli = new XML_RPC_Client($g['xmlrpcpath'], $g['xmlrpcbaseurl']);
99
        $resp = $cli->send($msg, 10);
100
	if($resp and !$resp->faultCode()) {
101
        	$raw_versions = $resp->value();
102
		return xmlrpc_value_to_php($raw_versions);
103
	} else {
104
		return array();
105
	}
106
}
107

    
108
/*
109
 * resync_all_package_configs() Force packages to setup their configuration and rc.d files.
110
 * This function may also print output to the terminal indicating progress.
111
 */
112
function resync_all_package_configs($show_message = false) {
113
    global $config;
114
    $i = 0;
115
    log_error("Resyncing configuration for all packages.");
116
    if(!$config['installedpackages']['package']) return;
117
    if($show_message == true) print "Syncing packages:";
118
    foreach($config['installedpackages']['package'] as $package) {
119
        if($show_message == true) print " " . $package['name'];
120
        sync_package($i, true, true);
121
        $i++;
122
    }
123
    if($show_message == true) print ".\n";
124
}
125

    
126
/*
127
 * is_freebsd_pkg_installed() - Check /var/db/pkg to determine whether or not a FreeBSD
128
 *				package is installed.
129
 */
130
function is_freebsd_pkg_installed($pkg) {
131
	global $g;
132
	if(in_array($pkg, return_dir_as_array("{$g['vardb_path']}/pkg"))) return true;
133
	return false;
134
}
135

    
136
/*
137
 * get_pkg_depends($pkg_name, $filetype = ".xml", $format = "files", return_nosync = 1):  Return a package's dependencies.
138
 *
139
 * $filetype = "all" || ".xml", ".tgz", etc.
140
 * $format = "files" (full filenames) || "names" (stripped / parsed depend names)
141
 * $return_nosync = 1 (return depends that have nosync set) | 0 (ignore packages with nosync)
142
 *
143
 */
144
function get_pkg_depends($pkg_name, $filetype = ".xml", $format = "files", $return_nosync = 1) {
145
    global $config;                                                                             
146
    if(!is_numeric($pkg_name)) {
147
        $pkg_id = get_pkg_id($pkg_name);
148
        if($pkg_id == -1) return -1; // This package doesn't really exist - exit the function.
149
    } else {                                                                                  
150
        if(!isset($config['installedpackages']['package'][$pkg_id])) return; // No package belongs to the pkg_id passed to this function.
151
    }                                                                                                                                    
152
    $package = $config['installedpackages']['package'][$pkg_id];
153
    if(!file_exists("/usr/local/pkg/" . $package['configurationfile'])) {
154
        file_notice($package['name'], "The {$package['name']} package is missing its configuration file and must be reinstalled.", "Packages", "/pkg_mgr_install.php?mode=reinstallpkg&pkg={$package['name']}", 1);
155
		return;
156
	}
157
	$pkg_xml = parse_xml_config("/usr/local/pkg/" . $package['configurationfile'], "packagegui");
158
    if($pkg_xml['additional_files_needed'] != "") {                                                  
159
        foreach($pkg_xml['additional_files_needed'] as $item) {
160
            if (($return_nosync == 0) && (isset($item['nosync']))) continue; // Do not return depends with nosync set if not required.
161
            $depend_file = substr(strrchr($item['item']['0'], '/'),1); // Strip URLs down to filenames.
162
            $depend_name = substr(substr($depend_file,0,strpos($depend_file,".")+1),0,-1); // Strip filename down to dependency name.
163
            if (($filetype != "all") && (!preg_match("/${filetype}/i", $depend_file))) continue;
164
            if ($item['prefix'] != "") {
165
                $prefix = $item['prefix'];
166
            } else {
167
                $prefix = "/usr/local/pkg/";
168
            }
169
            if(!file_exists($prefix . $pkg_name)) {
170
				file_notice($package['name'], "The {$package['name']} package is missing required dependencies and must be reinstalled.", "Packages", "/pkg_mgr_install.php?mode=reinstallpkg&pkg={$package['name']}", 1);
171
            }
172
            switch ($format) {
173
            case "files":
174
                $depends[] = $depend_file;
175
                break;
176
            case "names":
177
                switch ($filetype) {
178
                case "all":
179
                    if(preg_match("/\.xml/i", $depend_file)) {
180
                        $depend_xml = parse_xml_config("/usr/local/pkg/" . $depend_file, "packagegui");
181
                        $depends[] = $depend_xml['name'];
182
                        break;
183
                    } else {
184
                        $depends[] = $depend_name; // If this dependency isn't package XML, use the stripped filename.
185
                        break;
186
                    }
187
                case ".xml":
188
                    $depend_xml = parse_xml_config("/usr/local/pkg/" . $depend_file, "packagegui");
189
                    $depends[] = $depend_xml['name'];
190
                    break;
191
                default:
192
                    $depends[] = $depend_name; // If we aren't looking for XML, use the stripped filename (it's all we have).
193
                    break;
194
                }
195
            }
196
        }
197
        return $depends;
198
    }
199
}
200

    
201
/*
202
 * sync_package($pkg_name, $sync_depends = true, $show_message = false) Force a package to setup its configuration and rc.d files.
203
 */
204
function sync_package($pkg_name, $sync_depends = true, $show_message = false) {
205
    global $config;
206

    
207
    if(!file_exists("/usr/local/pkg")) mwexec("/bin/mkdir -p /usr/local/pkg/pf");
208
    if(!$config['installedpackages']['package']) return;                         
209
    if(!is_numeric($pkg_name)) {                        
210
        $pkg_id = get_pkg_id($pkg_name);
211
        if($pkg_id == -1) return -1; // This package doesn't really exist - exit the function.
212
    } else {                                                                                  
213
        $pkg_id = $pkg_name;
214
        if(!isset($config['installedpackages']['package'][$pkg_id]))
215
            return;  // No package belongs to the pkg_id passed to this function.
216
    }                                                                            
217
    $package = $config['installedpackages']['package'][$pkg_id];
218
    if(!file_exists("/usr/local/pkg/" . $package['configurationfile'])) {
219
    	file_notice($package['name'], "The {$package['name']} package is missing its configuration file and must be reinstalled.", "Packages", "/pkg_mgr_install.php?mode=reinstallpkg&pkg={$package['name']}", 1);
220
    } else {
221
        $pkg_config = parse_xml_config("/usr/local/pkg/" . $package['configurationfile'], "packagegui");
222
		if(isset($pkg_config['nosync'])) continue;                                                          
223
		if($pkg['custom_php_global_functions'] <> "")            
224
	        eval($pkg['custom_php_global_functions']);
225
	    if($pkg_config['custom_php_command_before_form'] <> "")
226
	        eval($pkg_config['custom_php_command_before_form']);
227
	    if($pkg_config['custom_php_resync_config_command'] <> "")
228
	        eval($pkg_config['custom_php_resync_config_command']);
229
	    if($sync_depends == true) {
230
	        $depends = get_pkg_depends($pkg_name, ".xml", "files", 1); // Call dependency handler and do a little more error checking.
231
	        if(is_array($depends)) {
232
	            foreach($depends as $item) {
233
					if(!file_exists("/usr/local/pkg" . $item)) {
234
						file_notice($package['name'], "The {$package['name']} package is missing required dependencies and must be reinstalled.", "Packages", "/pkg_mgr_install.php?mode=reinstallpkg&pkg={$package['name']}", 1);
235
					} else {
236
		                $item_config = parse_xml_config("/usr/local/pkg/" . $item, "packagegui");
237
		                if(isset($item_config['nosync'])) continue;
238
		                if($item_config['custom_php_command_before_form'] <> "") {
239
		                    eval($item_config['custom_php_command_before_form']);
240
		                }
241
		                if($item_config['custom_php_resync_config_command'] <> "") {
242
		                    eval($item_config['custom_php_resync_config_command']);
243
		                }
244
		                if($show_message == true) print " " . $item_config['name'];
245
                  }
246
              }
247
          }
248
      }
249
    }
250
}
251

    
252
/*
253
 * pkg_fetch_recursive: Download and install a FreeBSD package and its dependencies. This function provides output to
254
 * 			a progress bar and output window.
255
 *
256
 * XXX: This function needs to return where a pkg_add fails. Our current error messages aren't very descriptive.
257
 */
258
function pkg_fetch_recursive($pkgname, $filename, $dependlevel = 0, $base_url = 'http://ftp2.freebsd.org/pub/FreeBSD/ports/i386/packages-5.4-release/Latest') {
259
        global $pkgent, $static_status, $static_output, $g, $pkg_interface, $fd_log;
260
        $pkg_extension = strrchr($filename, '.');
261
        $static_output .= "\n" . str_repeat(" ", $dependlevel * 2) . $pkgname . " ";
262
        $fetchto = "/tmp/apkg_" . $pkgname . $pkg_extension;
263
	download_file_with_progress_bar($base_url . '/' . $filename, $fetchto);
264
//      update_output_window($static_output . "\n\n" . $pkg_progress);
265
        exec("/usr/bin/tar -O -f {$fetchto} -x +CONTENTS", $slaveout);
266
        $workingdir = preg_grep("/instmp/", $slaveout);
267
        $workingdir = $workingdir[0];
268
        $raw_depends_list = array_values(preg_grep("/\@pkgdep/", $slaveout));
269
        if($raw_depends_list != "") {
270
                if($pkgent['exclude_dependency'] != "")
271
                        $raw_depends_list = array_values(preg_grep($pkent['exclude_dependency'], PREG_GREP_INVERT));
272
                foreach($raw_depends_list as $adepend) {
273
                        $working_depend = explode(" ", $adepend);
274
                        //$working_depend = explode("-", $working_depend[1]);
275
                        $depend_filename = $working_depend[1] . $pkg_extension;
276
//                      $is_installed = array_values(preg_grep("/\b{$working_depend[0]}\b/i", $is_installed));
277
                        if(is_freebsd_pkg_installed($working_depend[1]) === false) {
278
                                pkg_fetch_recursive($working_depend[1], $depend_filename, $dependlevel + 1, $base_url);
279
                        } else {
280
                                $dependlevel++;
281
                                $static_output .= "\n" . str_repeat(" ", $dependlevel * 2) . $working_depend[1] . " ";
282
                                @fwrite($fd_log, $working_depend[1] . "\n");
283
                        }
284
                }
285
        }
286
        exec("cat {$g['tmp_path']}/y | /usr/sbin/pkg_add -fv {$fetchto} 2>&1", $pkgaddout);
287
        @fwrite($fd_log, $pkgname . " " . print_r($pkgaddout, true) . "\n");
288
        return true;
289
}
290

    
291
function download_file_with_progress_bar($url_file, $destination_file) {
292
        global $ch, $fout, $file_size, $downloaded, $counter, $pkg_interface;
293
        $file_size  = 1;
294
        $downloaded = 1;
295
        /* open destination file */
296
        $fout = fopen($destination_file, "wb");
297

    
298
        /*
299
                Originally by Author: Keyvan Minoukadeh
300
                Modified by Scott Ullrich to return Content-Length size
301
        */
302

    
303
        $ch = curl_init();
304
        curl_setopt($ch, CURLOPT_URL, $url_file);
305
        curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header');
306
        curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'read_body');
307
        curl_setopt($ch, CURLOPT_NOPROGRESS, '1');
308

    
309
        curl_exec($ch);
310
        fclose($fout);
311
        curl_close($ch);
312

    
313
        return 1;
314
}
315

    
316
function read_header($ch, $string) {
317
        global $file_size, $ch, $fout;
318
        $length = strlen($string);
319
        ereg("(Content-Length:) (.*)", $string, $regs);
320
        if($regs[2] <> "") {
321
                $file_size = intval($regs[2]);
322
        }
323
        return $length;
324
}
325

    
326
function read_body($ch, $string) {
327
        global $fout, $file_size, $downloaded, $counter, $sendto, $static_output, $lastseen, $pkg_interface;
328
        $length = strlen($string);
329
        $downloaded += intval($length);
330
        $downloadProgress = round(100 * (1 - $downloaded / $file_size), 0);
331
        $downloadProgress = 100 - $downloadProgress;
332
	if($lastseen <> $downloadProgress and $downloadProgress < 101) {
333
                if($sendto == "status") {
334
                        $tostatus = $static_status . $downloadProgress . "%";
335
                        update_status($tostatus);
336
                } else {
337
                        $tooutput = $static_output . $downloadProgress . "%";
338
                        update_output_window($tooutput);
339
                }
340
                update_progress_bar($downloadProgress);
341
                $lastseen = $downloadProgress;
342
        }
343
	fwrite($fout, $string);
344
	return $length;
345
}
346

    
347
function install_package($package, $pkg_info = "") {
348
	global $g, $config, $pkg_interface, $fd_log, $static_output;
349
	/* open logfiles and begin installation */
350
	if(!$fd_log) {
351
		if(!$fd_log = fopen("{$g['tmp_path']}/pkg_mgr_{$pkg}.log", "w")) {
352
			update_output_window("Warning, could not open log for writing.");
353
		}
354
	}
355
	@fwrite($fd_log, "Beginning package installation.\n");
356
	log_error('Beginning package installation for ' . $package . '.');
357
	update_status("Beginning package installation for " . $package . "...");
358
	/* fetch package information if needed */
359
	if(!$pkg_info or !is_array($pkg_info[$package])) {
360
		$pkg_info = get_pkg_info(array($package));
361
		$pkg_info = $pkg_info[$package]; // We're only dealing with one package, so we can strip away the extra array.
362
	}
363
	/* set up package logging streams */
364
	if($pkg_info['logging']) {
365
		mwexec("/usr/sbin/clog -i -s 32768 {$g['varlog_path']}" . $pkg_info['logging']['logfile_name']);
366
		chmod($g['varlog_path'] . $pkg_info['logging']['logfile_name'], 0600);
367
		@fwrite($fd_log, "Adding text to file /etc/syslog.conf\n");
368
		add_text_to_file("/etc/syslog.conf", $pkg_info['logging']['facilityname'] . "\t\t\t" . $pkg_info['logging']['logfilename']);
369
		mwexec("/usr/bin/killall -HUP syslogd");
370
	}
371
	/* fetch the package's configuration file */
372
	if($pkg_info['config_file'] != "") {
373
		$static_output .= "Downloading package configuration file... ";
374
		update_output_window($static_output);
375
		@fwrite($fd_log, "Downloading package configuration file...\n");
376
		$fetchto = substr(strrchr($pkg_info['config_file'], '/'), 1);
377
		download_file_with_progress_bar($pkg_info['config_file'], '/usr/local/pkg/' . $fetchto);
378
		if(!file_exists('/usr/local/pkg/' . $fetchto)) {
379
			@fwrite($fd_log, "ERROR! Unable to fetch package configuration file. Aborting installation.\n");
380
			if($pkg_interface == "console") {
381
				print "\nERROR! Unable to fetch package configuration file. Aborting package installation.\n";
382
				return;
383
			} else {
384
				$static_output .= "failed!\n\nInstallation aborted.";
385
				update_output_window($static_output);
386
				echo "<br>Show <a href=\"pkg_mgr_install.php?showlog=true\">install log</a></center>";
387
			 	exit;
388
			}
389
		}
390
		$static_output .= "done.\n";
391
		update_output_window($static_output);
392
	}
393
	/* make 'y' file */
394
	$fd = fopen("{$g['tmp_path']}/y", "w");
395
	for($line = 0; $line < 10; $line++) {
396
		fwrite($fd, "y\n");
397
	}
398
	fclose($fd);
399

    
400
	/* pkg_add the package and its dependencies */
401
	if($pkg_info['depends_on_package_base_url'] != "") {
402
		update_status("Installing " . $pkg_info['name'] . " and its dependencies.");
403
		$static_output .= "Downloading " . $pkg_info['name'] . " and its dependencies... ";
404
		$static_orig = $static_output;
405
		$static_output .= "\n";
406
		update_output_window($static_output);
407
		$pkg_name = substr(reverse_strrchr($pkg_info['depends_on_package'], "."), 0, -1);
408
		if(isset($pkg_info['skip_install_checks'])) {
409
			$pkg_installed = true;
410
		} else {
411
			$pkg_installed = is_freebsd_pkg_installed($pkg_name);
412
		}
413
		if($pkg_installed == false) pkg_fetch_recursive($pkg_name, $pkg_info['depends_on_package'], 0, $pkg_info['depends_on_package_base_url']);
414
		$static_output = $static_orig . "done.\nChecking for successful package installation... ";
415
		update_output_window($static_output);
416
		/* make sure our package was successfully installed */
417
		if($pkg_installed == false) $pkg_installed = is_freebsd_pkg_installed($pkg_name);
418
		if($pkg_installed == true) {
419
			$static_output .= "done.\n";
420
			update_output_window($static_output);
421
			fwrite($fd_log, "pkg_add successfully completed.\n");
422
		} else {
423
			$static_output .= "failed!\n\nInstallation aborted.";
424
			update_output_window($static_output);
425
			fwrite($fd_log, "Package WAS NOT installed properly.\n");
426
			fclose($fd_log);
427
			echo "\n<script language=\"JavaScript\">document.progressbar.style.visibility='hidden';</script>";
428
			echo "\n<script language=\"JavaScript\">document.progholder.style.visibility='hidden';</script>";
429
			sleep(1);
430
			die;
431
		}
432
	}
433
	/* add package information to config.xml */
434
	$pkgid = get_pkg_id($pkg_info['name']);
435
	$static_output .= "Saving updated package information... ";
436
	update_output_window($static_output);
437
	if($pkgid == -1) {
438
		$config['installedpackages']['package'][] = $pkg_info;
439
		$changedesc = "Installed {$pkg_info['name']} package.";
440
		$to_output = "done.\n";
441
	} else {
442
		$config['installedpackages']['package'][$pkgid] = $pkg_info;
443
		$changedesc = "Overwrote previous installation of {$pkg_info['name']}.";
444
		$to_output = "overwrite!\n";
445
	}
446
	$static_output .= $to_output;
447
	update_output_window($static_output);
448
	/* install other package components */
449
	install_package_xml($package);
450
	$static_output .= "Writing configuration... ";
451
	update_output_window($static_output);
452
	write_config($changedesc);
453
	$static_output .= "done.";
454
	update_output_window($static_output);
455
}
456

    
457
function eval_once($toeval) {
458
	global $evaled;
459
	if(!$evaled) $evaled = array();
460
	$evalmd5 = md5($toeval);
461
	if(!in_array($evalmd5, $evaled)) {
462
		eval($toeval);
463
		$evaled[] = $evalmd5;
464
	}
465
	return;
466
}
467
	
468

    
469
function install_package_xml($pkg) {
470
	global $g, $config, $fd_log, $static_output;
471
	if(($pkgid = get_pkg_id($pkg)) == -1) {
472
		$static_output .= "The {$pkg} package is not installed.\n\nInstallation aborted.";
473
		update_output_window($static_output);
474
		echo "\n<script language=\"JavaScript\">document.progressbar.style.visibility='hidden';</script>";
475
		echo "\n<script language=\"JavaScript\">document.progholder.style.visibility='hidden';</script>";
476
		sleep(1);
477
		return;
478
	} else {
479
		$pkg_info = $config['installedpackages']['package'][$pkgid];
480
	}
481
	/* set up logging if needed */
482
	if(!$fd_log) {
483
		if(!$fd_log = fopen("{$g['tmp_path']}/pkg_mgr_{$pkg}.log", "w")) {
484
			update_output_window("Warning, could not open log for writing.");
485
		}
486
	}
487

    
488
	$configfile = substr(strrchr($pkg_info['config_file'], '/'), 1);
489
	if(file_exists("/usr/local/pkg/" . $configfile)) {
490
		$static_output .= "Loading package configuration... ";
491
		update_output_window($static_output);
492
		$pkg_config = parse_xml_config("/usr/local/pkg/" . $configfile, "packagegui");
493
		$static_output .= "done.\n";
494
		update_output_window($static_output);
495
		$static_output .= "Configuring package components...\n";
496
		update_output_window($static_output);
497
		/* modify system files */
498
		if($pkg_config['modify_system']['item'] <> "") {
499
			$static_output .= "\tSystem files... ";
500
			update_output_window($static_output);
501
			foreach($pkg_config['modify_system']['item'] as $ms) {
502
				if($ms['textneeded']) {
503
					add_text_to_file($ms['modifyfilename'], $ms['textneeded']);
504
				}
505
			}
506
			$static_output .= "done.\n";
507
			update_output_window($static_output);
508
		}
509
		/* download additional files */
510
		if($pkg_config['additional_files_needed'] <> "") {
511
			$static_output .= "\tAdditional files... ";
512
			$static_orig = $static_output;
513
			update_output_window($static_output);
514
			foreach($pkg_config['additional_files_needed'] as $afn) {
515
				$filename = get_filename_from_url($afn['item'][0]);
516
				if($afn['chmod'] <> "") {
517
					$pkg_chmod = $afn['chmod'];
518
				} else {
519
					$pkg_chmod = "";
520
				}
521
				if($afn['prefix'] <> "") {
522
					$prefix = $afn['prefix'];
523
				} else {
524
					$prefix = "/usr/local/pkg/";
525
				}
526
				$static_output .= $filename . " ";
527
                                update_output_window($static_output);
528
				download_file_with_progress_bar($afn['item'][0], $prefix . $filename);
529
				if(stristr($filename, ".tgz") <> "") {
530
					fwrite($fd_log, "Extracting tarball to -C for " . $filename . "...\n");
531
					exec("/usr/bin/tar xvzf " . $prefix . $filename . " -C / 2>&1", $tarout);
532
					fwrite($fd_log, print_r($tarout, true) . "\n");
533
				}
534
				if($pkg_chmod <> "") {
535
					fwrite($fd_log, "Changing file mode to {$pkg_chmod} for {$prefix}{$filename}\n");
536
					chmod($prefix . $filename, $pkg_chmod);
537
					system("/bin/chmod {$pkg_chmod} {$prefix}{$filename}");
538
				}
539
				$static_output = $static_orig;
540
                                update_output_window($static_output);
541
			}
542
			$static_output .= "done.\n";
543
			update_output_window($static_output);
544
		}
545
		/* sidebar items */
546
		if($pkg_config['menu'] != "") {
547
			$static_output .= "\tMenu items... ";
548
			update_output_window($static_output);
549
			foreach($pkg_config['menu'] as $menu) {
550
				$config['installedpackages']['menu'][] = $menu;
551
			}
552
			$static_output .= "done.\n";
553
			update_output_window($static_output);
554
		}
555
		/* custom commands */
556
		if($pkg_config['custom_php_install_command'] <> "") {
557
			$static_output .= "\tCustom commands... ";
558
			update_output_window($static_output);
559
			if($pkg_config['custom_php_global_functions'] <> "") {
560
				eval_once($pkg_config['custom_php_global_functions']);
561
			}
562
			fwrite($fd_log, "Executing post install commands...\n");
563
			eval_once($pkg_config['custom_php_install_command']);
564
			$static_output .= "done.\n";
565
			update_output_window($static_output);
566
		}
567
		/* call our before form property since we may be declaring functions
568
		   in it that are called later */
569
		if($pkg_config['custom_php_command_before_form'] <> "") {
570
			eval_once($pkg_config['custom_php_command_before_form']);
571
		}
572
		/* call our resync function */
573
		if($pkg_config['custom_php_resync_config_command'] <> "") {
574
			eval_once($pkg_config['custom_php_resync_config_command']);
575
		}
576
	} else {
577
		$static_output .= "Loading package configuration... failed!\n\nInstallation aborted.";
578
		update_output_window($static_output);
579
		fwrite($fd_log, "Unable to load package configuration. Installation aborted.\n");
580
                fclose($fd_log);
581
                echo "\n<script language=\"JavaScript\">document.progressbar.style.visibility='hidden';</script>";
582
                echo "\n<script language=\"JavaScript\">document.progholder.style.visibility='hidden';</script>";
583
                sleep(1);
584
		return;
585
	}
586
}
587

    
588
function delete_package($pkg) {
589
	global $g, $config, $fd_log, $static_output;
590
	update_status("Removing package...");
591
	$static_output .= "Removing package... ";
592
	update_output_window($static_output);
593
	delete_package_recursive($pkg);
594
	$static_output .= "done.\n";
595
	update_output_window($static_output);
596
	return;
597
}
598

    
599
function delete_package_recursive($pkg) {
600
	exec("/usr/sbin/pkg_info -r " . $pkg . " 2>&1", $info);
601
	exec("cat {$g['tmp_path']}/y | /usr/sbin/pkg_delete " . $pkg ." > /dev/null 2>&1");
602
	exec("/bin/ls /var/db/pkg", $pkgdb);
603
	if(stristr($info[0], "can't find package") != false) return;
604
	foreach($info as $line) {
605
		$depend = trim(array_pop(explode(":", $line)));
606
		if(in_array($depend, $pkgdb)) delete_package_recursive($depend);
607
	}
608
	$fd = fopen("{$g['tmp_path']}/y", "w");
609
	for($line = 0; $line < 10; $line++) {
610
		fwrite($fd, "y\n");
611
	}
612
	fclose($fd);
613
	return;
614
}
615

    
616
function delete_package_xml($pkg) {
617
	global $g, $config, $fd_log, $static_output;
618
	if(($pkgid = get_pkg_id($pkg)) == -1) {
619
                $static_output .= "The {$pkg} package is not installed.\n\nDeletion aborted.";
620
                update_output_window($static_output);
621
                echo "\n<script language=\"JavaScript\">document.progressbar.style.visibility='hidden';</script>";
622
                echo "\n<script language=\"JavaScript\">document.progholder.style.visibility='hidden';</script>";
623
                sleep(1);
624
                return;
625
        }
626
	/* set up logging if needed */
627
        if(!$fd_log) {
628
                if(!$fd_log = fopen("{$g['tmp_path']}/pkg_mgr_{$pkg}.log", "w")) {
629
                        update_output_window("Warning, could not open log for writing.");
630
                }
631
        }
632
	update_status("Removing {$pkg} components...");
633
	fwrite($fd_log, "Removing {$pkg} package... ");
634
	$static_output .= "Removing {$pkg} components...\n";
635
	update_output_window($static_output);
636
	/* parse package configuration */
637
	$packages = &$config['installedpackages']['package'];
638
	$menus = &$config['installedpackages']['menu'];
639
	if(file_exists("/usr/local/pkg/" . $packages[$pkgid]['configurationfile'])) {
640
		$pkg_config = parse_xml_config("/usr/local/pkg/" . $packages[$pkgid]['configurationfile'], "packagegui");
641
		/* remove menu items */
642
		if(is_array($pkg_config['menu'])) {
643
			$static_output .= "\tMenu items... ";
644
			update_output_window($static_output);
645
			foreach($menus as $menu) $instmenus[] = $menu['name'];
646
			foreach($pkg_config['menu'] as $menu) {
647
				foreach($instmenus as $key => $instmenu) {
648
					if($instmenu == $menu['name']) unset($menus[$key]);
649
				}
650
			}
651
			$static_output .= "done.\n";
652
			update_output_window($static_output);
653
		}
654
		/* evalate this package's global functions and pre deinstall commands */
655
		if($pkg_config['custom_php_global_functions'] <> "")
656
			eval_once($pkg_config['custom_php_global_functions']);
657
		if($pkg_config['custom_php_pre_deinstall_command'] <> "") 
658
			eval_once($pkg_config['custom_php_pre_deinstall_command']);
659
		/* remove all additional files */
660
		if($pkg_config['additional_files_needed'] <> "") {
661
			$static_output .= "\tAuxiliary files... ";
662
			update_output_window($static_output);
663
			foreach($pkg_config['additional_files_needed'] as $afn) {
664
				$filename = get_filename_from_url($afn['item'][0]);
665
				if($afn['prefix'] <> "") {
666
					$prefix = $afn['prefix'];
667
				} else {
668
					$prefix = "/usr/local/pkg/";
669
				}
670
				unlink_if_exists($prefix . $filename);
671
				if(file_exists($prefix . $filename))
672
				    mwexec("rm -rf {$prefix}{$filename}");
673
			}
674
			$static_output .= "done.\n";
675
			update_output_window($static_output);
676
		}
677
		/* system files */
678
		if($pkg_config['modify_system']['item'] <> "") {
679
			$static_output .= "\tSystem files... ";
680
			update_output_window($static_output);
681
			foreach($pkg_config['modify_system']['item'] as $ms) {
682
				if($ms['textneeded']) remove_text_from_file($ms['modifyfilename'], $ms['textneeded']);
683
			}
684
			$static_output .= "done.\n";
685
			update_output_window($static_output);
686
		}
687
		/* syslog */
688
		if($pkg_config['logging']['logfile_name'] <> "") {
689
			$static_output .= "\tSyslog entries... ";
690
			update_output_window($static_output);
691
			remove_text_from_file("/etc/syslog.conf", $pkg_config['logging']['facilityname'] . "\t\t\t\t" . $pkg_config['logging']['logfilename']);
692
			$static_output .= "done.\n";
693
			update_output_window($static_output);
694
		}
695
		/* deinstall commands */
696
		if($pkg_config['custom_php_deinstall_command'] <> "") {
697
			$static_output .= "\tDeinstall commands... ";
698
			update_output_window($static_output);
699
			eval_once($pkg_config['custom_php_deinstall_command']);
700
			$static_output .= "done.\n";
701
			update_output_window($static_output);
702
		}
703
		/* package XML file */
704
		$static_output .= "\tPackage XML... ";
705
		update_output_window($static_output);
706
		unlink_if_exists("/usr/local/pkg/" . $packages[$pkgid]['configurationfile']);
707
		$static_output .= "done.\n";
708
		update_output_window($static_output);
709
	}
710
	/* remove config.xml entries */
711
	$static_output .= "\tConfiguration... ";
712
	update_output_window($static_output);
713
	unset($config['installedpackages']['package'][$pkgid]);
714
	$static_output .= "done.\n";
715
	update_output_window($static_output);
716
	write_config("Removed {$pkg} package.");
717
	/* file cleanup */
718
	$ctag = file("/etc/crontab");
719
	foreach($ctag as $line) {
720
		if(trim($line) != "") $towrite[] = $line;
721
	}
722
	$tmptab = fopen("/tmp/crontab", "w");
723
	foreach($towrite as $line) {
724
		fwrite($tmptab, $line);
725
	}
726
	fclose($tmptab);
727
	rename("/tmp/crontab", "/etc/crontab");
728
}
729
?>
(12-12/20)