Project

General

Profile

Download (29.7 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.
369
 *  returns latest package version
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;
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
	mwexec("/usr/bin/fetch -o {$g['tmp_path']}/pkg_config.xml {$pkg_config_location}");
412
	if(!file_exists("{$g['tmp_path']}/pkg_config.xml")) {
413
	    print_info_box_np("Could not download pkg_config.xml from " . $pkg_config_base_url ". Check your DNS settings.");
414
	    die;
415
	}
416
    }
417
    return;
418
}
419

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
783
    $content_length = strlen($urlencoded);
784

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

    
795
";
796

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

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

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

    
809
    fclose($fp);
810

    
811
    return $ret;
812

    
813
}
814

    
815
/*
816
 *  php_check_syntax($code_tocheck, $errormessage): checks $code_to_check for errors
817
 */
818
if (!function_exists('php_check_syntax')){
819
   function php_check_syntax($code_to_check, &$errormessage){
820
	return false;
821
        $fout = fopen("/tmp/codetocheck.php","w");
822
        $code = $_POST['content'];
823
        $code = str_replace("<?php", "", $code);
824
        $code = str_replace("?>", "", $code);
825
        fwrite($fout, "<?php\n\n");
826
        fwrite($fout, $code);
827
        fwrite($fout, "\n\n?>\n");
828
        fclose($fout);
829
        $command = "/usr/local/bin/php -l /tmp/codetocheck.php";
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
 *  php_check_filename_syntax($filename, $errormessage): checks the file $filename for errors
844
 */
845
if (!function_exists('php_check_syntax')){
846
   function php_check_syntax($code_to_check, &$errormessage){
847
	return false;
848
        $command = "/usr/local/bin/php -l " . $code_to_check;
849
        $output = exec_command($command);
850
        if (stristr($output, "Errors parsing") == false) {
851
            echo "false\n";
852
            $errormessage = '';
853
            return(false);
854
        } else {
855
            $errormessage = $output;
856
            return(true);
857
        }
858
    }
859
}
860

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

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

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

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

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

    
949
?>
(9-9/14)