Project

General

Profile

Download (29.9 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
 *  is_package_installed($packagename): returns 1 if a package is installed, 0 otherwise.
343
 */
344
function is_package_installed($packagename) {
345
    global $config;
346
    if($config['installedpackages']['package'] <> "")
347
	foreach ($config['installedpackages']['package'] as $pkg) {
348
	    if($pkg['name'] == $packagename) return 1;
349
	}
350
    return 0;
351
}
352

    
353
/*
354
 * lookup pkg array id#
355
 */
356
function get_pkg_id($pkg_name) {
357
    global $config;
358
    global $pkg_config;
359
    $i=0;
360
    foreach ($config['installedpackages']['package'] as $pkg) {
361
	if($pkg['name'] == $pkg_name) return $i;
362
	$i++;
363
    }
364
    return -1;
365
}
366

    
367
/*
368
 *  get_latest_package_version($pkgname): Get current version of a package. Returns latest package version or false
369
 *  					  if package isn't defined in the currently used pkg_config.xml.
370
 */
371
function get_latest_package_version($pkg_name) {
372
    global $g;
373
    fetch_latest_pkg_config();
374
    $pkg_config = parse_xml_config_pkg("{$g['tmp_path']}/pkg_config.xml", "pfsensepkgs");
375
    foreach($pkg_config['packages']['package'] as $pkg) {
376
	if($pkg['name'] == $pkg_name) {
377
	    return $pkg['version'];
378
	}
379
    }
380
    return false;
381
}
382

    
383
/*
384
 * Lookup pkg_id in pkg_config.xml
385
 */
386
function get_available_pkg_id($pkg_name) {
387
    fetch_latest_pkg_config();
388
    $pkg_config = parse_xml_config_pkg("{$g['tmp_path']}/pkg_config.xml", "pfsensepkgs");
389
    $id = 0;
390
    foreach($pkg_config as $pkg) {
391
	if($pkg_config['name'] == $pkg_name) {
392
	    return $id;
393
	}
394
	$id++;
395
    }
396
    return;
397
}
398

    
399
/*
400
 * fetch_latest_pkg_config: download the latest pkg_config.xml to /tmp/ directory
401
 */
402
function fetch_latest_pkg_config() {
403
    global $g;
404
    global $config;
405
    if(!file_exists("{$g['tmp_path']}/pkg_config.xml")) {
406
	$pkg_config_location = $g['pkg_config_location'];
407
	$pkg_config_base_url = $g['pkg_config_base_url'];
408
	if(isset($config['system']['alt_pkgconfig_url']['enabled'])) {
409
	    $pkg_config_location = $config['system']['alt_pkgconfig_url']['pkgconfig_base_url'] . $config['system']['alt_pkgconfig_url']['pkgconfig_filename'];
410
	    $pkg_config_base_url = $config['system']['alt_pkgconfig_url']['pkgconfig_base_url'];
411
	}
412
	mwexec("/usr/bin/fetch -o {$g['tmp_path']}/pkg_config.xml {$pkg_config_location}");
413
	if(!file_exists("{$g['tmp_path']}/pkg_config.xml")) {
414
	    print_info_box_np("Could not download pkg_config.xml from " . $pkg_config_base_url . ". Check your DNS settings.");
415
	    die;
416
    	}
417
    }
418
    return;
419
}
420

    
421
/*
422
 * add_text_to_file($file, $text): adds $text to $file.
423
 * replaces the text if it already exists.
424
 */
425
function add_text_to_file($file, $text) {
426
    global $fd_log;
427
    fwrite($fd_log, "Adding needed text items:\n");
428
    $filecontents = exec_command_and_return_text("cat " . $file);
429
    $filecontents = str_replace($text, "", $filecontents);
430
    $text = $filecontents . $text;
431
    fwrite($fd_log, $text . "\n");
432
    $fd = fopen($file, "w");
433
    fwrite($fd, $text . "\n");
434
    fclose($fd);
435
}
436

    
437
/*
438
 * get_filename_from_url($url): converts a url to its filename.
439
 */
440
function get_filename_from_url($url) {
441
    $filenamesplit = split("/", $url);
442
    foreach($filenamesplit as $fn) $filename = $fn;
443
    return $filename;
444
}
445

    
446
/*
447
 *   update_output_window: update bottom textarea dynamically.
448
 */
449
function update_output_window($text) {
450
    $log = ereg_replace("\n", "\\n", $text);
451
    echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"" . $log . "\";</script>";
452
}
453

    
454
/*
455
 *   get_dir: return an array of $dir
456
 */
457
function get_dir($dir) {
458
    $dir_array = array();
459
    $d = dir($dir);
460
    while (false !== ($entry = $d->read())) {
461
	array_push($dir_array, $entry);
462
    }
463
    $d->close();
464
    return $dir_array;
465
}
466

    
467
/*
468
 *   update_output_window: update top textarea dynamically.
469
 */
470
function update_status($status) {
471
    echo "\n<script language=\"JavaScript\">document.forms[0].status.value=\"" . $status . "\";</script>";
472
}
473

    
474
/*
475
 *   exec_command_and_return_text_array: execute command and return output
476
 */
477
function exec_command_and_return_text_array($command) {
478
    $counter = 0;
479
    $fd = popen($command . " 2>&1 ", "r");
480
    while(!feof($fd)) {
481
	$tmp .= fread($fd,49);
482
    }
483
    fclose($fd);
484
    $temp_array = split("\n", $tmp);
485
    return $tmp_array;
486
}
487

    
488
/*
489
 *   exec_command_and_return_text: execute command and return output
490
 */
491
function exec_command_and_return_text($command) {
492
    return exec_command($command);
493
}
494

    
495
/*
496
 *   exec_command_and_return_text: execute command and update output window dynamically
497
 */
498
function execute_command_return_output($command) {
499
    global $fd_log;
500
    $fd = popen($command . " 2>&1 ", "r");
501
    echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"\";</script>";
502
    $counter = 0;
503
    $counter2 = 0;
504
    while(!feof($fd)) {
505
	$tmp = fread($fd, 50);
506
	$tmp1 = ereg_replace("\n","\\n", $tmp);
507
	$text = ereg_replace("\"","'", $tmp1);
508
	if($lasttext == "..") {
509
	    $text = "";
510
	    $lasttext = "";
511
	    $counter=$counter-2;
512
	} else {
513
	    $lasttext .= $text;
514
	}
515
	if($counter > 51) {
516
	    $counter = 0;
517
	    $extrabreak = "\\n";
518
	} else {
519
	    $extrabreak = "";
520
	    $counter++;
521
	}
522
	if($counter2 > 600) {
523
	    echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"\";</script>";
524
	    $counter2 = 0;
525
	} else
526
	    $counter2++;
527
	echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = this.document.forms[0].output.value + \"" . $text . $extrabreak .  "\"; f('output'); </script>";
528
    }
529
    fclose($fd);
530
}
531

    
532
/*
533
 * convert_friendly_interface_to_real_interface_name($interface): convert WAN to FXP0
534
 */
535
function convert_friendly_interface_to_real_interface_name($interface) {
536
    global $config;
537
    $lc_interface = strtolower($interface);
538
    if($lc_interface == "lan") return $config['interfaces']['lan']['if'];
539
    if($lc_interface == "wan") return $config['interfaces']['wan']['if'];
540
    $i = 0;
541
    $ifdescrs = array();
542
    for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++)
543
	$ifdescrs['opt' . $j] = "opt" . $j;
544
    foreach ($ifdescrs as $ifdescr => $ifname) {
545
	if(strtolower($ifname) == $lc_interface)
546
	    return $config['interfaces'][$ifname]['if'];
547
	if(strtolower($config['interfaces'][$ifname]['descr']) == $lc_interface)
548
	    return $config['interfaces'][$ifname]['if'];
549
    }
550
    return $interface;
551
}
552

    
553
/*
554
 * convert_real_interface_to_friendly_interface_name($interface): convert fxp0 -> wan, etc.
555
 */
556
function convert_real_interface_to_friendly_interface_name($interface) {
557
    global $config;
558
    $i = 0;
559
    $ifdescrs = array('wan', 'lan');
560
    for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++)
561
	$ifdescrs['opt' . $j] = "opt" . $j;
562
    foreach ($ifdescrs as $ifdescr => $ifname) {
563
	$int = filter_translate_type_to_real_interface($ifname);
564
	if($ifname == $interface) return $ifname;
565
	if($int == $interface) return $ifname;
566
    }
567
    return $interface;
568
}
569

    
570
/*
571
 * update_progress_bar($percent): updates the javascript driven progress bar.
572
 */
573
function update_progress_bar($percent) {
574
    if($percent > 100) $percent = 1;
575
    echo "\n<script type=\"text/javascript\" language=\"javascript\">";
576
    echo "\ndocument.progressbar.style.width='" . $percent . "%';";
577
    echo "\n</script>";
578
}
579

    
580
/*
581
 * resync_all_package_configs() Force packages to setup their configuration and rc.d files.
582
 * This function may also print output to the terminal indicating progress.
583
 */
584
function resync_all_package_configs($show_message = false) {
585
    global $config;
586
    $i = 0;
587
    log_error("Resyncing configuration for all packages.");
588
    if(!$config['installedpackages']['package']) return;
589
    if($show_message == true) print "Syncing packages:";
590
    foreach($config['installedpackages']['package'] as $package) {
591
	if($show_message == true) print " " . $package['name'];
592
	sync_package($i, true, true);
593
	$i++;
594
    }
595
    if($show_message == true) print ".\n";
596
}
597

    
598
/*
599
 * sweep_package_processes(): Periodically kill a package's unnecessary processes
600
 *			      that may still be running (a server that does not automatically timeout, for example)
601
 */
602
function sweep_package_processes() {
603
    global $config;
604
    if(!$config['installedpackages']['package']) return;
605
    foreach($config['installedpackages']['package'] as $package) {
606
        $pkg_config = parse_xml_config_pkg("/usr/local/pkg/" . $package['configurationfile'], "packagegui");
607
        if($pkg_config['swept_processes'] <> "") {
608
            mwexec("/usr/bin/killall " . $pkg_config['swept_processes']);
609
            log_error("Killed " . $package['name'] . "'s unnecessary processes.");
610
        }
611
    }
612
}
613

    
614
/*
615
 * gather_altq_queue_stats():  gather alq queue stats and return an array that
616
 *                             is queuename|qlength|measured_packets
617
 *                             NOTE: this command takes 5 seconds to run
618
 */
619
function gather_altq_queue_stats($dont_return_root_queues) {
620
    mwexec("/usr/bin/killall -9 pfctl");
621
    $stats = `/sbin/pfctl -vvsq & /bin/sleep 5;/usr/bin/killall pfctl 2>/dev/null`;
622
    $stats_array = split("\n", $stats);
623
    $queue_stats = array();
624
    foreach ($stats_array as $stats_line) {
625
        if (preg_match_all("/queue\s+(\w+)\s+/",$stats_line,$match_array))
626
            $queue_name = $match_array[1][0];
627
        if (preg_match_all("/measured:\s+.*packets\/s\,\s(.*)\s+\]/",$stats_line,$match_array))
628
            $speed = $match_array[1][0];
629
        if (preg_match_all("/borrows:\s+(.*)/",$stats_line,$match_array))
630
            $borrows = $match_array[1][0];
631
        if (preg_match_all("/suspends:\s+(.*)/",$stats_line,$match_array))
632
            $suspends = $match_array[1][0];
633
        if (preg_match_all("/dropped pkts:\s+(.*)/",$stats_line,$match_array))
634
            $drops = $match_array[1][0];
635
        if (preg_match_all("/measured:\s+(.*)packets/",$stats_line,$match_array)) {
636
            $measured = $match_array[1][0];
637
	    if($dont_return_root_queues == true)
638
		if(stristr($queue_name,"root_") == false)
639
		    array_push($queue_stats, "{$queue_name}|{$speed}|{$measured}|{$borrows}|{$suspends}|{$drops}");
640
        }
641
    }
642
    return $queue_stats;
643
}
644

    
645
/*
646
 * reverse_strrchr($haystack, $needle):  Return everything in $haystack up to the *last* instance of $needle.
647
 *					 Useful for finding paths and stripping file extensions.
648
 */
649
function reverse_strrchr($haystack, $needle) {
650
    $pos = strrpos($haystack, $needle);
651
    if($post === false) {
652
	return $haystack;
653
    }
654
    return substr($haystack, 0, $post + 1);
655
}
656

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

    
726
/*
727
 * is_service_running($service_name): checks to see if a service is running.
728
 *                                    if the service is running returns 1.
729
 */
730
function is_service_running($service_name) {
731
    $status = `/bin/ps ax | grep {$service_name} | grep -v grep`;
732
    $status_split = split("\n", $service_name);
733
    $counter = 0;
734
    foreach ($status_split as $ss) $counter++;
735
    if($counter > 0) return 1;
736
    return 0;
737
}
738

    
739
/*
740
 *  backup_config_section($section): returns as an xml file string of
741
 *                                   the configuration section
742
 */
743
function backup_config_section($section) {
744
    global $config;
745
    $new_section = &$config[$section];
746
    /* generate configuration XML */
747
    $xmlconfig = dump_xml_config($new_section, $section);
748
    return $xmlconfig;
749
}
750

    
751
/*
752
 *  restore_config_section($section, new_contents): restore a configuration section,
753
 *                                                  and write the configuration out
754
 *                                                  to disk/cf.
755
 */
756
function restore_config_section($section, $new_contents) {
757
    global $config;
758
    conf_mount_rw();
759
    config_lock();
760
    $fout = fopen("{$g['tmp_path']}/tmpxml","w");
761
    fwrite($fout, $new_contents);
762
    fclose($fout);
763
    $section_xml = parse_xml_config_pkg($g['tmp_path'] . "/tmpxml", $section);
764
    $config[$section] = &$section_xml;
765
    unlink($g['tmp_path'] . "/tmpxml");
766
    write_config("Restored {$section} of config file (maybe from CARP partner)");
767
    conf_mount_ro();
768
    config_unlock();
769
    return;
770
}
771

    
772
/*
773
 * http_post($server, po$port, $url, $vars): does an http post to a web server
774
 *                                           posting the vars array.
775
 * written by nf@bigpond.net.au
776
 */
777
function http_post($server, $port, $url, $vars) {
778
    $user_agent = "Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)";
779
    $urlencoded = "";
780
    while (list($key,$value) = each($vars))
781
	$urlencoded.= urlencode($key) . "=" . urlencode($value) . "&";
782
    $urlencoded = substr($urlencoded,0,-1);
783

    
784
    $content_length = strlen($urlencoded);
785

    
786
    $headers = "POST $url HTTP/1.1
787
Accept: */*
788
Accept-Language: en-au
789
Content-Type: application/x-www-form-urlencoded
790
User-Agent: $user_agent
791
Host: $server
792
Connection: Keep-Alive
793
Cache-Control: no-cache
794
Content-Length: $content_length
795

    
796
";
797

    
798
    $fp = fsockopen($server, $port, $errno, $errstr);
799
    if (!$fp) {
800
	return false;
801
    }
802

    
803
    fputs($fp, $headers);
804
    fputs($fp, $urlencoded);
805

    
806
    $ret = "";
807
    while (!feof($fp))
808
	$ret.= fgets($fp, 1024);
809

    
810
    fclose($fp);
811

    
812
    return $ret;
813

    
814
}
815

    
816
/*
817
 *  php_check_syntax($code_tocheck, $errormessage): checks $code_to_check for errors
818
 */
819
if (!function_exists('php_check_syntax')){
820
   function php_check_syntax($code_to_check, &$errormessage){
821
	return false;
822
        $fout = fopen("/tmp/codetocheck.php","w");
823
        $code = $_POST['content'];
824
        $code = str_replace("<?php", "", $code);
825
        $code = str_replace("?>", "", $code);
826
        fwrite($fout, "<?php\n\n");
827
        fwrite($fout, $code);
828
        fwrite($fout, "\n\n?>\n");
829
        fclose($fout);
830
        $command = "/usr/local/bin/php -l /tmp/codetocheck.php";
831
        $output = exec_command($command);
832
        if (stristr($output, "Errors parsing") == false) {
833
            echo "false\n";
834
            $errormessage = '';
835
            return(false);
836
        } else {
837
            $errormessage = $output;
838
            return(true);
839
        }
840
    }
841
}
842

    
843
/*
844
 *  php_check_filename_syntax($filename, $errormessage): checks the file $filename for errors
845
 */
846
if (!function_exists('php_check_syntax')){
847
   function php_check_syntax($code_to_check, &$errormessage){
848
	return false;
849
        $command = "/usr/local/bin/php -l " . $code_to_check;
850
        $output = exec_command($command);
851
        if (stristr($output, "Errors parsing") == false) {
852
            echo "false\n";
853
            $errormessage = '';
854
            return(false);
855
        } else {
856
            $errormessage = $output;
857
            return(true);
858
        }
859
    }
860
}
861

    
862
/*
863
 * sync_package($pkg_name, $sync_depends = true, $show_message = false) Force a package to setup its configuration and rc.d files.
864
 */
865
function sync_package($pkg_name, $sync_depends = true, $show_message = false) {
866
    global $config;
867
    if(!$config['installedpackages']['package']) return;
868
    if(!is_numeric($pkg_name)) {
869
	$pkg_id = get_pkg_id($pkg_name);
870
	if($pkg_id == -1) return -1; // This package doesn't really exist - exit the function.
871
    } else {
872
	$pkg_id = $pkg_name;
873
	if(!isset($config['installedpackages']['package'][$pkg_id]))
874
	    return;  // No package belongs to the pkg_id passed to this function.
875
    }
876
    $package = $config['installedpackages']['package'][$pkg_id];
877
    if(!file_exists("/usr/local/pkg/" . $package['configurationfile'])) {
878
	//if($show_message == true) print "(f)"; Don't mess with this until the package system has settled.
879
	log_error("Fetching missing configuration XML for " . $package['name']);
880
	mwexec("/usr/bin/fetch -o /usr/local/pkg/" . $package['configurationfile'] . " http://www.pfsense.com/packages/config/" . $package['configurationfile']);
881
    }
882
    $pkg_config = parse_xml_config_pkg("/usr/local/pkg/" . $package['configurationfile'], "packagegui");
883
    if(isset($pkg_config['nosync'])) continue;
884
    //if($show_message == true) print "Syncing " . $pkg_name;
885
    if($pkg['custom_php_global_functions'] <> "")
886
        eval($pkg['custom_php_global_functions']);
887
    if($pkg_config['custom_php_command_before_form'] <> "")
888
	eval($pkg_config['custom_php_command_before_form']);
889
    if($pkg_config['custom_php_resync_config_command'] <> "")
890
	eval($pkg_config['custom_php_resync_config_command']);
891
    if($sync_depends == true) {
892
	$depends = get_pkg_depends($pkg_name, ".xml", "files", 1); // Call dependency handler and do a little more error checking.
893
	if(is_array($depends)) {
894
	    foreach($depends as $item) {
895
		$item_config = parse_xml_config_pkg("/usr/local/pkg/" . $item, "packagegui");
896
		if(isset($item_config['nosync'])) continue;
897
		if($item_config['custom_php_command_before_form'] <> "") {
898
		    eval($item_config['custom_php_command_before_form']);
899
		    print "Evaled dependency.";
900
		}
901
		if($item_config['custom_php_resync_config_command'] <> "") {
902
		    eval($item_config['custom_php_resync_config_command']);
903
		    print "Evaled dependency.";
904
		}
905
		if($show_message == true) print " " . $item_config['name'];
906
	    }
907
	}
908
    }
909
    // if($show_message == true) print ".";
910
}
911

    
912
/*
913
 * rmdir_recursive($path,$followLinks=false)
914
 * Recursively remove a directory tree (rm -rf path)
915
 * This is for directories _only_
916
 */
917
function rmdir_recursive($path,$follow_links=false) {
918
	$dir = opendir($path) ;
919

    
920
	while ($entry = readdir($dir)) {
921
		if (is_file("$path/$entry") || ((!$follow_links) && is_link("$path/$entry")))
922
			unlink("$path/$entry");
923
       		elseif (is_dir("$path/$entry") && $entry!='.' && $entry!='..')
924
			rmdir_recursive("$path/$entry");
925
	}
926
	closedir($dir) ;
927
	return rmdir($path);
928
}
929

    
930
/*
931
 * safe_mkdir($path, $mode = 0755)
932
 * create directory if it doesn't already exist and isn't a file!
933
 */
934
function safe_mkdir($path, $mode=0755) {
935
	if (!is_file($path) && !is_dir($path))
936
		return mkdir($path, $mode);
937
	else
938
		return false;
939
}
940

    
941
/*
942
 * make_dirs($path, $mode = 0755)
943
 * create directory tree recursively (mkdir -p)
944
 */
945
function make_dirs($path, $mode = 0755)
946
{
947
	return is_dir($path) || (make_dirs(dirname($path), $mode) && safe_mkdir($path, $mode));
948
}
949

    
950
?>
(9-9/14)