Project

General

Profile

Download (29.5 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	pfSense-utils.inc
4
	Utilities specific to pfSense
5
	part of pfSense (www.pfSense.com)
6

    
7
	Copyright (C) 2005 Scott Ullrich (sullrich@gmail.com)
8
	All rights reserved.
9

    
10
	Redistribution and use in source and binary forms, with or without
11
	modification, are permitted provided that the following conditions are met:
12

    
13
	1. Redistributions of source code must retain the above copyright notice,
14
	   this list of conditions and the following disclaimer.
15

    
16
	2. Redistributions in binary form must reproduce the above copyright
17
	   notice, this list of conditions and the following disclaimer in the
18
	   documentation and/or other materials provided with the distribution.
19

    
20
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
21
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
22
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
24
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
	POSSIBILITY OF SUCH DAMAGE.
30
*/
31

    
32
/*
33
 * log_error: send string to syslog
34
 */
35
function log_error($error) {
36
    syslog(LOG_WARNING, $error);
37
    return;
38
}
39

    
40
/*
41
 * return_dir_as_array($dir): returns $dir contents as an array
42
 */
43
function return_dir_as_array($dir) {
44
    $dir_array = array();
45
    if (is_dir($dir)) {
46
	If ($dh = opendir($dir)) {
47
	    while (($file = readdir($dh)) !== false) {
48
		$canadd = 0;
49
		if($file == ".") $canadd = 1;
50
		if($file == "..") $canadd = 1;
51
		if($canadd == 0)
52
		    array_push($dir_array, $file);
53
	    }
54
	    closedir($dh);
55
	}
56
    }
57
    return $dir_array;
58
}
59

    
60
/*
61
 * enable_hardware_offloading() enables hardware features of nics if they are supported
62
 */
63
function enable_hardware_offloading($interface) {
64
    global $config;
65
    global $g;
66
    if($g['booting']) {
67
	$supported_ints = array('fxp');
68
	foreach($supported_ints as $int) {
69
	    if(stristr($interface,$int) != false) {
70
		mwexec("/sbin/ifconfig $interface link0");
71
	    }
72
	}
73
    }
74
}
75

    
76
/*
77
 * return_filename_as_array($filename): returns $filename contents as a string
78
 */
79
function return_filename_as_array($filename) {
80
    $file = array();
81
    if(file_exists($filename)) {
82
        $text = return_filename_as_string($filename);
83
        $text_split = split("\n", $text);
84

    
85
        /* Strip out comments */
86
        while (($line = array_shift($text_split)) != NULL) {
87
            if(strpos($line, "#") !== 0)
88
                array_push($file, $line);
89
        }
90
    }
91
    return $file;
92
}
93

    
94
/*
95
 * return_dir_as_array($filename): returns $filename contents as a string
96
 */
97
function return_filename_as_string($filename) {
98
    $tmp = "";
99
    $fd = fopen($filename, "r");
100
    if(!$fd) {
101
	log_error("Could not open {$filename}");
102
	return;
103
    }
104
    while(!feof($fd)) {
105
	$tmp .= fread($fd,49);
106
    }
107
    fclose($fd);
108
    return $tmp;
109
}
110

    
111
/*
112
 * is_carp_defined: returns true if carp is detected in kernel
113
 */
114
function is_carp_defined() {
115
	/* is carp compiled into the kernel and userland? */
116
	$command = "/sbin/sysctl -a | grep carp";
117
	$fd = popen($command . " 2>&1 ", "r");
118
	if(!$fd) {
119
		log_error("Warning, could not execute command {$command}");
120
		return 0;
121
	}
122
	while(!feof($fd)) {
123
		    $tmp .= fread($fd,49);
124
	}
125
	fclose($fd);
126

    
127
	if($tmp == "")
128
		return false;
129
	else
130
		return true;
131
}
132

    
133
/*
134
 * find_number_of_created_carp_interfaces() returns the number of currently created carp interfaces
135
 */
136
function find_number_of_created_carp_interfaces() {
137
	$command = "/sbin/ifconfig | /usr/bin/grep \"carp*:\" | /usr/bin/wc -l";
138
	$fd = popen($command . " 2>&1 ", "r");
139
	if(!$fd) {
140
		log_error("Warning, could not execute command {$command}");
141
		return 0;
142
	}
143
	while(!feof($fd)) {
144
		    $tmp .= fread($fd,49);
145
	}
146
	fclose($fd);
147
	$tmp = intval($tmp);
148
	return $tmp;
149
}
150

    
151
/*
152
 * link_ip_to_carp_interface($ip): finds where a carp interface links to.
153
*/
154
function link_ip_to_carp_interface($ip) {
155
	global $config;
156
	if($ip == "") return;
157
        $i = 0;
158

    
159
        $ifdescrs = array('wan', 'lan');
160
        for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
161
                $ifdescrs['opt' . $j] = "opt" . $j;
162
        }
163

    
164
	$ft = split("\.", $ip);
165
	$ft_ip = $ft[0] . "." . $ft[1] . "." . $ft[2] . ".";
166

    
167
	$carp_ints = "";
168
	$num_carp_ints = find_number_of_created_carp_interfaces();
169
        foreach ($ifdescrs as $ifdescr => $ifname) {
170
                for($x=0; $x<$num_carp_ints; $x++) {
171
                        $carp_int = "carp{$x}";
172
			$carp_ip = find_interface_ip($carp_int);
173
			$carp_ft = split("\.", $carp_ip);
174
			$carp_ft_ip = $carp_ft[0] . "." . $carp_ft[1] . "." . $carp_ft[2] . ".";
175
                        $result = does_interface_exist($carp_int);
176
                        if($result <> true) break;
177
                        $interface = filter_opt_interface_to_real($ifname);
178
			if($ft_ip == $carp_ft_ip)
179
			    if(stristr($carp_ints,$carp_int) == false)
180
				$carp_ints .= " " . $carp_int;
181
                }
182
        }
183
	return $carp_ints;
184
}
185

    
186

    
187
/*
188
 * exec_command($command): execute command return string of result
189
 */
190
function exec_command($command) {
191
            $counter = 0;
192
            $tmp = "";
193
            $fd = popen($command . " 2>&1 ", "r");
194
            while(!feof($fd)) {
195
                        $tmp .= fread($fd,49);
196
            }
197
            fclose($fd);
198
            return $tmp;
199
}
200

    
201
/*
202
 * does_interface_exist($interface): return true or false if a interface is detected.
203
 */
204
function does_interface_exist($interface) {
205
    $ints = exec_command("/sbin/ifconfig -l");
206
    if(stristr($ints, $interface) !== false)
207
	return true;
208
    else
209
	return false;
210
}
211

    
212
/*
213
 * convert_ip_to_network_format($ip, $subnet): converts an ip address to network form
214
 */
215
function convert_ip_to_network_format($ip, $subnet) {
216
    $ipsplit = split('[.]', $ip);
217
    $string = $ipsplit[0] . "." . $ipsplit[1] . "." . $ipsplit[2] . ".0/" . $subnet;
218
    return $string;
219
}
220

    
221
/*
222
 * find_interface_ip($interface): return the interface ip (first found)
223
 */
224
function find_interface_ip($interface) {
225
    if(does_interface_exist($interface) == false) return;
226
    $ip = exec_command("/sbin/ifconfig {$interface} | /usr/bin/grep -w \"inet\" | /usr/bin/cut -d\" \" -f 2");
227
    $ip = str_replace("\n","",$ip);
228
    return $ip;
229
}
230

    
231
function filter_opt_interface_to_real($opt) {
232
	global $config;
233
	return $config['interfaces'][$opt]['if'];
234
}
235

    
236
function filter_get_opt_interface_descr($opt) {
237
	global $config;
238
	return $config['interfaces'][$opt]['descr'];
239
}
240

    
241
function get_friendly_interface_list_as_array() {
242
	global $config;
243
	$ints = array();
244
	$i = 0;
245
	$ifdescrs = array('wan', 'lan');
246
	for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
247
		$ifdescrs['opt' . $j] = "opt" . $j;
248
	}
249
	$ifdescrs = get_interface_list();
250
	foreach ($ifdescrs as $ifdescr => $ifname) {
251
	    array_push($ints,$ifdescr);
252
	}
253
	return $ints;
254
}
255

    
256
/*
257
 * find_ip_interface($ip): return the interface where an ip is defined
258
 */
259
function find_ip_interface($ip) {
260
	global $config;
261
	$i = 0;
262
	$ifdescrs = array('wan', 'lan');
263
	for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
264
		$ifdescrs['opt' . $j] = "opt" . $j;
265
	}
266
	foreach ($ifdescrs as $ifdescr => $ifname) {
267
	    $int = filter_translate_type_to_real_interface($ifname);
268
	    $ifconfig = exec_command("/sbin/ifconfig {$int}");
269
	    if(stristr($ifconfig,$ip) <> false)
270
		return $int;
271
	}
272
	return false;
273
}
274

    
275
/*
276
 *  filter_translate_type_to_real_interface($interface): returns the real interface name
277
 *                                                       for a friendly interface.  ie: wan
278
 */
279
function filter_translate_type_to_real_interface($interface) {
280
        global $config;
281
	return $config['interfaces'][$interface]['if'];
282
}
283

    
284
/*
285
 * get_carp_interface_status($carpinterface): returns the status of a carp ip
286
 */
287
function get_carp_interface_status($carpinterface) {
288
    $result = does_interface_exist($carpinterface);
289
    if($result <> true) return false;
290
    $status = exec_command("/sbin/ifconfig {$carpinterface} | /usr/bin/grep \"carp:\" | /usr/bin/cut -d\" \" -f2");
291
    return $status;
292
}
293

    
294
/*
295
 * get_pfsync_interface_status($pfsyncinterface): returns the status of a pfsync
296
 */
297
function get_pfsync_interface_status($pfsyncinterface) {
298
    $result = does_interface_exist($pfsyncinterface);
299
    if($result <> true) return;
300
    $status = exec_command("/sbin/ifconfig {$pfsyncinterface} | /usr/bin/grep \"pfsync:\" | /usr/bin/cut -d\" \" -f5");
301
    return $status;
302
}
303

    
304
/*
305
 * find_carp_interface($ip): return the carp interface where an ip is defined
306
 */
307
function find_carp_interface($ip) {
308
    $num_carp_ints = find_number_of_created_carp_interfaces();
309
    for($x=0; $x<$num_carp_ints; $x++) {
310
        $result = does_interface_exist("carp{$x}");
311
	if($result <> true) return;
312
	$ifconfig = exec_command("/sbin/ifconfig carp{$x}");
313
	if(stristr($ifconfig,$ip))
314
	    return "carp" . $x;
315
    }
316
}
317

    
318
/*
319
 * add_rule_to_anchor($anchor, $rule): adds the specified rule to an anchor
320
 */
321
function add_rule_to_anchor($anchor, $rule, $label) {
322
    mwexec("echo " . $rule . " | /sbin/pfctl -a " . $anchor . ":" . $label . " -f -");
323
}
324

    
325
/*
326
 * remove_text_from_file
327
 * remove $text from file $file
328
 */
329
function remove_text_from_file($file, $text) {
330
    global $fd_log;
331
    fwrite($fd_log, "Adding needed text items:\n");
332
    $filecontents = exec_command_and_return_text("cat " . $file);
333
    $textTMP = str_replace($text, "", $filecontents);
334
    $text .= $textTMP;
335
    fwrite($fd_log, $text . "\n");
336
    $fd = fopen($file, "w");
337
    fwrite($fd, $text);
338
    fclose($fd);
339
}
340

    
341
/*
342
 * lookup pkg array id#
343
 */
344
function get_pkg_id($pkg_name) {
345
            global $config;
346
            global $pkg_config;
347
            $i=0;
348
            foreach ($config['installedpackages']['package'] as $pkg) {
349
                        if($pkg['name'] == $pkg_name) return $i;
350
                        $i++;
351
            }
352
            return -1;
353
}
354

    
355
/*
356
 *  get_latest_package_version($pkgname): get current version of a package.
357
 *  returns latest package version
358
 */
359
function get_latest_package_version($pkg_name) {
360
    global $g;
361
    fetch_latest_pkg_config();
362
    $pkg_config = parse_xml_config_pkg("{$g['tmp_path']}/pkg_config.xml", "pfsensepkgs");
363
    foreach($pkg_config['packages']['package'] as $pkg) {
364
	if($pkg['name'] == $pkg_name) {
365
	    return $pkg['version'];
366
	}
367
    }
368
    return;
369
}
370

    
371
/*
372
 * Lookup pkg_id in pkg_config.xml
373
 */
374
function get_available_pkg_id($pkg_name) {
375
    fetch_latest_pkg_config();
376
    $pkg_config = parse_xml_config_pkg("{$g['tmp_path']}/pkg_config.xml", "pfsensepkgs");
377
    $id = 0;
378
    foreach($pkg_config as $pkg) {
379
	if($pkg_config['name'] == $pkg_name) {
380
	    return $id;
381
	}
382
	$id++;
383
    }
384
    return;
385
}
386

    
387
/*
388
 * fetch_latest_pkg_config: download the latest pkg_config.xml to /tmp/ directory
389
 */
390
function fetch_latest_pkg_config() {
391
    global $g;
392
    if(!file_exists("{$g['tmp_path']}/pkg_config.xml")) {
393
	mwexec("/usr/bin/fetch -o {$g['tmp_path']}/pkg_config.xml {$g['pkg_config_location']}");
394
	if(!file_exists("{$g['tmp_path']}/pkg_config.xml")) {
395
	    print_info_box_np("Could not download pkg_config.xml from pfSense.com.  Check your DNS settings.");
396
	    die;
397
	}
398
    }
399
    return;
400
}
401

    
402
/*
403
 * add_text_to_file($file, $text): adds $text to $file.
404
 * replaces the text if it already exists.
405
 */
406
function add_text_to_file($file, $text) {
407
    global $fd_log;
408
    fwrite($fd_log, "Adding needed text items:\n");
409
    $filecontents = exec_command_and_return_text("cat " . $file);
410
    $filecontents = str_replace($text, "", $filecontents);
411
    $text = $filecontents . $text;
412
    fwrite($fd_log, $text . "\n");
413
    $fd = fopen($file, "w");
414
    fwrite($fd, $text . "\n");
415
    fclose($fd);
416
}
417

    
418
/*
419
 * get_filename_from_url($url): converts a url to its filename.
420
 */
421
function get_filename_from_url($url) {
422
            $filenamesplit = split("/", $url);
423
            foreach($filenamesplit as $fn) $filename = $fn;
424
            return $filename;
425
}
426

    
427
/*
428
 *   update_output_window: update bottom textarea dynamically.
429
 */
430
function update_output_window($text) {
431
            $log = ereg_replace("\n", "\\n", $text);
432
            echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"" . $log . "\";</script>";
433
}
434

    
435
/*
436
 *   get_dir: return an array of $dir
437
 */
438
function get_dir($dir) {
439
            $dir_array = array();
440
            $d = dir($dir);
441
            while (false !== ($entry = $d->read())) {
442
                        array_push($dir_array, $entry);
443
            }
444
            $d->close();
445
            return $dir_array;
446
}
447

    
448
/*
449
 *   update_output_window: update top textarea dynamically.
450
 */
451
function update_status($status) {
452
            echo "\n<script language=\"JavaScript\">document.forms[0].status.value=\"" . $status . "\";</script>";
453
}
454

    
455
/*
456
 *   exec_command_and_return_text_array: execute command and return output
457
 */
458
function exec_command_and_return_text_array($command) {
459
            $counter = 0;
460
            $fd = popen($command . " 2>&1 ", "r");
461
            while(!feof($fd)) {
462
                        $tmp .= fread($fd,49);
463
            }
464
            fclose($fd);
465
            $temp_array = split("\n", $tmp);
466
            return $tmp_array;
467
}
468

    
469
/*
470
 *   exec_command_and_return_text: execute command and return output
471
 */
472
function exec_command_and_return_text($command) {
473
	    return exec_command($command);
474
}
475

    
476
/*
477
 *   exec_command_and_return_text: execute command and update output window dynamically
478
 */
479
function execute_command_return_output($command) {
480
    global $fd_log;
481
    $fd = popen($command . " 2>&1 ", "r");
482
    echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"\";</script>";
483
    $counter = 0;
484
    $counter2 = 0;
485
    while(!feof($fd)) {
486
	$tmp = fread($fd, 50);
487
	$tmp1 = ereg_replace("\n","\\n", $tmp);
488
	$text = ereg_replace("\"","'", $tmp1);
489
	if($lasttext == "..") {
490
	    $text = "";
491
	    $lasttext = "";
492
	    $counter=$counter-2;
493
	} else {
494
	    $lasttext .= $text;
495
	}
496
	if($counter > 51) {
497
	    $counter = 0;
498
	    $extrabreak = "\\n";
499
	} else {
500
	    $extrabreak = "";
501
	    $counter++;
502
	}
503
	if($counter2 > 600) {
504
	    echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"\";</script>";
505
	    $counter2 = 0;
506
	} else
507
	    $counter2++;
508
	echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = this.document.forms[0].output.value + \"" . $text . $extrabreak .  "\"; f('output'); </script>";
509
    }
510
    fclose($fd);
511
}
512

    
513
/*
514
 * convert_friendly_interface_to_real_interface_name($interface): convert WAN to FXP0
515
 */
516
function convert_friendly_interface_to_real_interface_name($interface) {
517
    global $config;
518
    $lc_interface = strtolower($interface);
519
    if($lc_interface == "lan") return $config['interfaces']['lan']['if'];
520
    if($lc_interface == "wan") return $config['interfaces']['wan']['if'];
521
    $i = 0;
522
    $ifdescrs = array();
523
    for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++)
524
	$ifdescrs['opt' . $j] = "opt" . $j;
525
    foreach ($ifdescrs as $ifdescr => $ifname) {
526
	if(strtolower($ifname) == $lc_interface)
527
	    return $config['interfaces'][$ifname]['if'];
528
	if(strtolower($config['interfaces'][$ifname]['descr']) == $lc_interface)
529
	    return $config['interfaces'][$ifname]['if'];
530
    }
531
    return $interface;
532
}
533

    
534
/*
535
 * convert_real_interface_to_friendly_interface_name($interface): convert fxp0 -> wan, etc.
536
 */
537
function convert_real_interface_to_friendly_interface_name($interface) {
538
	global $config;
539
	$i = 0;
540
	$ifdescrs = array('wan', 'lan');
541
	for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++)
542
	    $ifdescrs['opt' . $j] = "opt" . $j;
543
	foreach ($ifdescrs as $ifdescr => $ifname) {
544
	    $int = filter_translate_type_to_real_interface($ifname);
545
	    if($ifname == $interface) return $ifname;
546
	    if($int == $interface) return $ifname;
547
	}
548
	return $interface;
549
}
550

    
551
/*
552
 * update_progress_bar($percent): updates the javascript driven progress bar.
553
 */
554
function update_progress_bar($percent) {
555
            if($percent > 100) $percent = 1;
556
            echo "\n<script type=\"text/javascript\" language=\"javascript\">";
557
            echo "\ndocument.progressbar.style.width='" . $percent . "%';";
558
            echo "\n</script>";
559
}
560

    
561
/*
562
 * resync_all_package_configs_bootup() Force packages to setup their configuration and rc.d files at bootup.
563
 * This function also prints output to the terminal indicating progress.
564
 */
565
function resync_all_package_configs_bootup($show_message) {
566
	global $config;
567
	$i = 0;
568
	log_error("Resyncing configuration for all packages.");
569
	if(!$config['installedpackages']['package']) return;
570
	if($show_message == true) print "Syncing packages:";
571
	foreach($config['installedpackages']['package'] as $package) {
572
		if($show_message == true) print " " . $package['name'];
573
		sync_package($i, true, true);
574
		$i++;
575
	}
576
	if($show_message == true) print ".\n";
577
}
578

    
579
/*
580
 * sweep_package_processes(): Periodically kill a package's unnecessary processes
581
 *			      that may still be running (a server that does not automatically timeout, for example)
582
 */
583
function sweep_package_processes() {
584
    global $config;
585
    if(!$config['installedpackages']['package']) return;
586
    foreach($config['installedpackages']['package'] as $package) {
587
        $pkg_config = parse_xml_config_pkg("/usr/local/pkg/" . $package['configurationfile'], "packagegui");
588
        if($pkg_config['swept_processes'] <> "") {
589
                mwexec("/usr/bin/killall " . $pkg_config['swept_processes']);
590
                log_error("Killed " . $package['name'] . "'s unnecessary processes.");
591
        }
592
    }
593
}
594

    
595
/*
596
 * gather_altq_queue_stats():  gather alq queue stats and return an array that
597
 *                             is queuename|qlength|measured_packets
598
 *                             NOTE: this command takes 5 seconds to run
599
 */
600
function gather_altq_queue_stats($dont_return_root_queues) {
601
    mwexec("/usr/bin/killall -9 pfctl");
602
    $stats = `/sbin/pfctl -vvsq & /bin/sleep 5;/usr/bin/killall pfctl 2>/dev/null`;
603
    $stats_array = split("\n", $stats);
604
    $queue_stats = array();
605
    foreach ($stats_array as $stats_line) {
606
        if (preg_match_all("/queue\s+(\w+)\s+/",$stats_line,$match_array))
607
            $queue_name = $match_array[1][0];
608
        if (preg_match_all("/measured:\s+.*packets\/s\,\s(.*)\s+\]/",$stats_line,$match_array))
609
            $speed = $match_array[1][0];
610
        if (preg_match_all("/borrows:\s+(.*)/",$stats_line,$match_array))
611
            $borrows = $match_array[1][0];
612
        if (preg_match_all("/suspends:\s+(.*)/",$stats_line,$match_array))
613
            $suspends = $match_array[1][0];
614
        if (preg_match_all("/dropped pkts:\s+(.*)/",$stats_line,$match_array))
615
            $drops = $match_array[1][0];
616
        if (preg_match_all("/measured:\s+(.*)packets/",$stats_line,$match_array)) {
617
            $measured = $match_array[1][0];
618
	    if($dont_return_root_queues == true)
619
		if(stristr($queue_name,"root_") == false)
620
		    array_push($queue_stats, "{$queue_name}|{$speed}|{$measured}|{$borrows}|{$suspends}|{$drops}");
621
        }
622
    }
623
    return $queue_stats;
624
}
625

    
626
/*
627
 * reverse_strrchr($haystack, $needle):  Return everything in $haystack up to the *last* instance of $needle.
628
 *					 Useful for finding paths and stripping file extensions.
629
 */
630
function reverse_strrchr($haystack, $needle) {
631
	$pos = strrpos($haystack, $needle);
632
	if($post === false) {
633
		return $haystack;
634
	}
635
	return substr($haystack, 0, $post + 1);
636
}
637

    
638
/*
639
 * get_pkg_depends($pkg_name, $filetype = ".xml", $format = "files", return_nosync = 1):  Return a package's dependencies.
640
 *
641
 * $filetype = "all" || ".xml", ".tgz", etc.
642
 * $format = "files" (full filenames) || "names" (stripped / parsed depend names)
643
 * $return_nosync = 1 (return depends that have nosync set) | 0 (ignore packages with nosync)
644
 *
645
 */
646
function get_pkg_depends($pkg_name, $filetype = ".xml", $format = "files", $return_nosync = 1) {
647
        global $config;
648
	if(!is_numeric($pkg_name)) {
649
                $pkg_name = get_pkg_id($pkg_name);
650
                if($pkg_id == -1) return -1; // This package doesn't really exist - exit the function.
651
        } else {
652
                if(!isset($config['installedpackages']['package'][$pkg_id])) return; // No package belongs to the pkg_id passed to this function.
653
        }
654
        $package = $config['installedpackages']['package'][$pkg_id];
655
	print '$package done.';
656
        if(!file_exists("/usr/local/pkg/" . $package['configurationfile'])) { // If the package's config file doesn't exist, log an error and fetch it.
657
		log_error("Fetching missing configuration XML for " . $package['name']);
658
		mwexec("/usr/bin/fetch -o /usr/local/pkg/" . $package['configurationfile'] . " http://www.pfsense.com/packages/config/" . $package['configurationfile']);
659
	}
660
        $pkg_xml = parse_xml_config_pkg("/usr/local/pkg/" . $package['configurationfile'], "packagegui");
661
        if($pkg_xml['additional_files_needed'] != "") {
662
                foreach($pkg_xml['additional_files_needed'] as $item) {
663
			if (($return_nosync == 0) && (isset($item['nosync']))) continue; // Do not return depends with nosync set if not required.
664
                        $depend_file = substr(strrchr($item['item']['0'], '/'),1); // Strip URLs down to filenames.
665
                        $depend_name = substr(substr($depend_file,0,strpos($depend_file,".")+1),0,-1); // Strip filename down to dependency name.
666
                        if (($filetype != "all") && (!preg_match("/${filetype}/i", $depend_file))) continue;
667
                        if ($item['prefix'] != "") {
668
                                $prefix = $item['prefix'];
669
                        } else {
670
                                $prefix = "/usr/local/pkg/";
671
                        }
672
                        if(!file_exists($prefix . $pkg_name)) {
673
                                log_error("Fetching missing dependency (" . $depend_name . ") for " . $pkg_name);
674
                                mwexec("/usr/local/bin/fetch -o " . $prefix . $depend_file . " " . $item['name']['0']);
675
                                if($item['chmod'] != "") mwexec("/bin/chmod " . $item['chmod'] . $prefix . $depend_file); // Handle chmods.
676
                        }
677
                        switch ($format) {
678
                        case "files":
679
                                $depends[] = $depend_file;
680
                                break;
681
                        case "names":
682
                                switch ($filetype) {
683
                                case "all":
684
                                        if(preg_match("/\.xml/i", $depend_file)) {
685
                                                $depend_xml = parse_xml_config_pkg("/usr/local/pkg/" . $depend_file, "packagegui");
686
                                                $depends[] = $depend_xml['name'];
687
                                                break;
688
                                        } else {
689
                                                $depends[] = $depend_name; // If this dependency isn't package XML, use the stripped filename.
690
                                                break;
691
                                        }
692
                                case ".xml":
693
                                        $depend_xml = parse_xml_config_pkg("/usr/local/pkg/" . $depend_file, "packagegui");
694
                                        $depends[] = $depend_xml['name'];
695
                                        break;
696
                                default:
697
                                        $depends[] = $depend_name; // If we aren't looking for XML, use the stripped filename (it's all we have).
698
                                        break;
699
                                }
700
                        }
701
                }
702
        return $depends;
703
        }
704
}
705

    
706
/*
707
 * is_service_running($service_name): checks to see if a service is running.
708
 *                                    if the service is running returns 1.
709
 */
710
function is_service_running($service_name) {
711
    $status = `/bin/ps ax | grep {$service_name} | grep -v grep`;
712
    $status_split = split("\n", $service_name);
713
    $counter = 0;
714
    foreach ($status_split as $ss) $counter++;
715
    if($counter > 0) return 1;
716
    return 0;
717
}
718

    
719
/*
720
 *  backup_config_section($section): returns as an xml file string of
721
 *                                   the configuration section
722
 */
723
function backup_config_section($section) {
724
    global $config;
725
    $new_section = &$config[$section];
726
    /* generate configuration XML */
727
    $xmlconfig = dump_xml_config($new_section, $section);
728
    return $xmlconfig;
729
}
730

    
731
/*
732
 *  restore_config_section($section, new_contents): restore a configuration section,
733
 *                                                  and write the configuration out
734
 *                                                  to disk/cf.
735
 */
736
function restore_config_section($section, $new_contents) {
737
    global $config;
738
    conf_mount_rw();
739
    config_lock();
740
    $fout = fopen("{$g['tmp_path']}/tmpxml","w");
741
    fwrite($fout, $new_contents);
742
    fclose($fout);
743
    $section_xml = parse_xml_config_pkg($g['tmp_path'] . "/tmpxml", $section);
744
    $config[$section] = &$section_xml;
745
    unlink($g['tmp_path'] . "/tmpxml");
746
    write_config();
747
    conf_mount_ro();
748
    config_unlock();
749
    return;
750
}
751

    
752
/*
753
 * http_post($server, po$port, $url, $vars): does an http post to a web server
754
 *                                           posting the vars array.
755
 * written by nf@bigpond.net.au
756
 */
757
function http_post($server, $port, $url, $vars) {
758
	$user_agent = "Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)";
759
	$urlencoded = "";
760
	while (list($key,$value) = each($vars))
761
		$urlencoded.= urlencode($key) . "=" . urlencode($value) . "&";
762
	$urlencoded = substr($urlencoded,0,-1);
763

    
764
	$content_length = strlen($urlencoded);
765

    
766
	$headers = "POST $url HTTP/1.1
767
Accept: */*
768
Accept-Language: en-au
769
Content-Type: application/x-www-form-urlencoded
770
User-Agent: $user_agent
771
Host: $server
772
Connection: Keep-Alive
773
Cache-Control: no-cache
774
Content-Length: $content_length
775

    
776
";
777

    
778
	$fp = fsockopen($server, $port, $errno, $errstr);
779
	if (!$fp) {
780
		return false;
781
	}
782

    
783
	fputs($fp, $headers);
784
	fputs($fp, $urlencoded);
785

    
786
	$ret = "";
787
	while (!feof($fp))
788
		$ret.= fgets($fp, 1024);
789

    
790
	fclose($fp);
791

    
792
	return $ret;
793

    
794
}
795

    
796
/*
797
 *  php_check_syntax($code_tocheck, $errormessage): checks $code_to_check for errors
798
 */
799
if (!function_exists('php_check_syntax')){
800
   function php_check_syntax($code_to_check, &$errormessage){
801
	return false;
802
        $fout = fopen("/tmp/codetocheck.php","w");
803
        $code = $_POST['content'];
804
        $code = str_replace("<?php", "", $code);
805
        $code = str_replace("?>", "", $code);
806
        fwrite($fout, "<?php\n\n");
807
        fwrite($fout, $code);
808
        fwrite($fout, "\n\n?>\n");
809
        fclose($fout);
810
        $command = "/usr/local/bin/php -l /tmp/codetocheck.php";
811
        $output = exec_command($command);
812
        if (stristr($output, "Errors parsing") == false) {
813
            echo "false\n";
814
            $errormessage = '';
815
            return(false);
816
        } else {
817
            $errormessage = $output;
818
            return(true);
819
        }
820
    }
821
}
822

    
823
/*
824
 *  php_check_filename_syntax($filename, $errormessage): checks the file $filename for errors
825
 */
826
if (!function_exists('php_check_syntax')){
827
   function php_check_syntax($code_to_check, &$errormessage){
828
	return false;
829
        $command = "/usr/local/bin/php -l " . $code_to_check;
830
        $output = exec_command($command);
831
        if (stristr($output, "Errors parsing") == false) {
832
            echo "false\n";
833
            $errormessage = '';
834
            return(false);
835
        } else {
836
            $errormessage = $output;
837
            return(true);
838
        }
839
    }
840
}
841

    
842
/*
843
 * sync_package($pkg_name, $sync_depends = true, $show_message = false) Force a package to setup its configuration and rc.d files.
844
 */
845
function sync_package($pkg_name, $sync_depends = true, $show_message = false) {
846
	global $config;
847
	if(!$config['installedpackages']['package']) return;
848
	if(!is_numeric($pkg_name)) {
849
		$pkg_id = get_pkg_id($pkg_name);
850
		if($pkg_id == -1) return -1; // This package doesn't really exist - exit the function.
851
	} else {
852
		$pkg_id = $pkg_name;
853
		if(!isset($config['installedpackages']['package'][$pkg_id])) {
854
			return;  // No package belongs to the pkg_id passed to this function.
855
		}
856
	}
857
	$package = $config['installedpackages']['package'][$pkg_id];
858
	if(!file_exists("/usr/local/pkg/" . $package['configurationfile'])) {
859
		//if($show_message == true) print "(f)"; Don't mess with this until the package system has settled.
860
		log_error("Fetching missing configuration XML for " . $package['name']);
861
		mwexec("/usr/bin/fetch -o /usr/local/pkg/" . $package['configurationfile'] . " http://www.pfsense.com/packages/config/" . $package['configurationfile']);
862
        }
863
        $pkg_config = parse_xml_config_pkg("/usr/local/pkg/" . $package['configurationfile'], "packagegui");
864
	if(isset($pkg_config['nosync'])) continue;
865
	//if($show_message == true) print "Syncing " . $pkg_name;
866
        if($pkg_config['custom_php_command_before_form'] <> "") {
867
		eval($pkg_config['custom_php_command_before_form']);
868
	}
869
        if($pkg_config['custom_php_resync_config_command'] <> "") {
870
	   	eval($pkg_config['custom_php_resync_config_command']);
871
        }
872
        if($sync_depends == true) {
873
		$depends = get_pkg_depends($pkg_name, ".xml", "files", 1); // Call dependency handler and do a little more error checking.
874
        	if(is_array($depends)) {
875
            		foreach($depends as $item) {
876
				$item_config = parse_xml_config_pkg("/usr/local/pkg/" . $item, "packagegui");
877
				if(isset($item_config['nosync'])) continue;
878
				if($item_config['custom_php_command_before_form'] <> "")
879
					eval($item_config['custom_php_command_before_form']);
880
					print "Evaled dependency.";
881
				if($item_config['custom_php_resync_config_command'] <> "")
882
					eval($item_config['custom_php_resync_config_command']);
883
					print "Evaled dependency.";
884
				if($show_message == true) print " " . $item_config['name'];
885
			}
886
		}
887
	}
888
	// if($show_message == true) print ".";
889
}
890
?>
(9-9/14)