Project

General

Profile

Download (16.6 KB) Statistics
| Branch: | Tag: | Revision:
1 ee11cc6e Scott Ullrich
#!/usr/local/bin/php
2
<?php
3
/*
4
    pkg_mgr_install.php
5 d2a1bba6 Scott Ullrich
    Part of pfSense (www.pfSense.com)
6 ee11cc6e Scott Ullrich
    Copyright (C) 2004 Scott Ullrich
7
    All rights reserved.
8
9
    Redistribution and use in source and binary forms, with or without
10
    modification, are permitted provided that the following conditions are met:
11
12
    1. Redistributions of source code must retain the above copyright notice,
13
       this list of conditions and the following disclaimer.
14
15
    2. Redistributions in binary form must reproduce the above copyright
16
       notice, this list of conditions and the following disclaimer in the
17
       documentation and/or other materials provided with the distribution.
18
19
    THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20
    INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
21
    AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22
    AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
23
    OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
    POSSIBILITY OF SUCH DAMAGE.
29
*/
30
31
require("guiconfig.inc");
32
require("xmlparse_pkg.inc");
33
34 425cbd0a Scott Ullrich
if(!file_exists("/usr/local/pkg/")) mwexec("mkdir -p /usr/local/pkg/");
35 8aca7e9b Scott Ullrich
if(!file_exists("/usr/local/www/ext/")) mwexec("mkdir -p /usr/local/www/ext");
36 425cbd0a Scott Ullrich
37 b4ff3ccd Scott Ullrich
$pb_percent = 1;
38
39 55e50bd6 Scott Ullrich
/*
40
 *   open logging facility
41
 */
42 1a05a4ee Scott Ullrich
$fd_log = fopen("/tmp/pkg_mgr.log", "w");
43
fwrite($fd_log, "Begin of Package Manager installation session.\n");
44
45 55e50bd6 Scott Ullrich
/*
46
 *   update_output_window: update top textarea dynamically.
47
 */
48 ee11cc6e Scott Ullrich
function update_status($status) {
49
            echo "\n<script language=\"JavaScript\">document.forms[0].status.value=\"" . $status . "\";</script>";
50
}
51
52 55e50bd6 Scott Ullrich
/*
53
 *   update_output_window: update bottom textarea dynamically.
54
 */
55
function update_output_window($text) {
56
            $log = ereg_replace("\n", "\\n", $text);
57
            echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"" . $log . "\";</script>";
58
}
59
60
/*
61
 *   get_dir: return an array of $dir
62
 */
63
function get_dir($dir) {
64
            $dir_array = array();
65
            $d = dir($dir);
66
            while (false !== ($entry = $d->read())) {
67
                        array_push($dir_array, $entry);
68
            }
69
            $d->close();
70
            return $dir_array;
71
}
72
73 c6c150e9 Scott Ullrich
/*
74
 *   exec_command_and_return_text_array: execute command and return output
75
 */
76
function exec_command_and_return_text_array($command) {
77
            $counter = 0;
78
            $fd = popen($command . " 2>&1 ", "r");
79
            while(!feof($fd)) {
80
                        $tmp .= fread($fd,49);
81
            }
82
            fclose($fd);
83
            $temp_array = split("\n", $tmp);
84
            return $tmp_array;
85
}
86
87 55e50bd6 Scott Ullrich
/*
88
 *   exec_command_and_return_text: execute command and return output
89
 */
90 1a05a4ee Scott Ullrich
function exec_command_and_return_text($command) {
91
            $counter = 0;
92
            $tmp = "";
93
            $fd = popen($command . " 2>&1 ", "r");
94
            while(!feof($fd)) {
95 55e50bd6 Scott Ullrich
                        $tmp .= fread($fd,49);
96 1a05a4ee Scott Ullrich
            }
97
            fclose($fd);
98
            return $tmp;
99
}
100
101 55e50bd6 Scott Ullrich
/*
102
 *   exec_command_and_return_text: execute command and update output window dynamically
103
 */
104 ee11cc6e Scott Ullrich
function execute_command_return_output($command) {
105 b4ff3ccd Scott Ullrich
    global $fd_log, $pb_percent;
106
    if($pb_percent > 100) $pb_percent = 1;
107
    update_progress_bar($pb_percent);
108 ee11cc6e Scott Ullrich
    $fd = popen($command . " 2>&1 ", "r");
109
    echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"\";</script>";
110
    $counter = 0;
111
    $counter2 = 0;
112
    while(!feof($fd)) {
113 1a05a4ee Scott Ullrich
	$tmp = fread($fd, 50);
114
        fwrite($fd_log, $tmp);
115 ee11cc6e Scott Ullrich
	$tmp1 = ereg_replace("\n","\\n", $tmp);
116
	$text = ereg_replace("\"","'", $tmp1);
117
	if($lasttext == "..") {
118
	    $text = "";
119
	    $lasttext = "";
120
	    $counter=$counter-2;
121
	} else {
122
	    $lasttext .= $text;
123
	}
124
	if($counter > 51) {
125
	    $counter = 0;
126
	    $extrabreak = "\\n";
127
	} else {
128
	    $extrabreak = "";
129
	    $counter++;
130
	}
131
	if($counter2 > 600) {
132
	    echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"\";</script>";
133
	    $counter2 = 0;
134
	} else
135
	    $counter2++;
136
	echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = this.document.forms[0].output.value + \"" . $text . $extrabreak .  "\"; f('output'); </script>";
137
    }
138 b4ff3ccd Scott Ullrich
    $pb_percent++;
139 ee11cc6e Scott Ullrich
    fclose($fd);
140
}
141
142 b4ff3ccd Scott Ullrich
function update_progress_bar($percent) {
143
            if($percent > 100) $percent = 1;
144
            echo "\n<script type=\"text/javascript\" language=\"javascript\">";
145
            echo "\ndocument.progressbar.style.width='" . $percent . "%';";
146
            echo "\n</script>";
147
}
148
149 ee11cc6e Scott Ullrich
$a_out = &$pkg_config['packages'];
150
151
?>
152
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
153
<html>
154
<head>
155
<title><?=gentitle("System: Package Manager: Install Package");?></title>
156
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
157
<link href="gui.css" rel="stylesheet" type="text/css">
158
</head>
159
160
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
161 859329c8 Scott Ullrich
<?php
162
$config_tmp = $config;
163
$config = $pfSense_config;
164
include("fbegin.inc");
165
$config = $config_tmp;
166
?>
167 ee11cc6e Scott Ullrich
<p class="pgtitle">System: Package Manager: Install Package</p>
168
<form action="firewall_nat_out_load_balancing.php" method="post">
169
<?php if ($savemsg) print_info_box($savemsg); ?>
170
<?php
171
if(!file_exists("/tmp/pkg_config.xml")) {
172
            mwexec("cd {$g['tmp_path']} && /usr/bin/fetch \"http://www.pfsense.com/packages/pkg_config.xml\" >/dev/null 2>&1 ");
173
            if(!file_exists("{$g['tmp_path']}/pkg_config.xml")) {
174
                        print_info_box_np("Could not download pkg_config.xml from pfSense.com.  Check your DNS settings.");
175
                        die;
176
            }
177
}
178
179 19fd2947 Scott Ullrich
$pkg_config = parse_xml_config_pkg("{$g['tmp_path']}/pkg_config.xml", "pfsensepkgs");
180 ee11cc6e Scott Ullrich
181
$id = $_GET['id'];
182
183
if(!$pkg_config['packages']) {
184
            print_info_box_np("Could not find any packages in pkg_config.xml");
185
}
186
?>
187
<table width="100%" border="0" cellpadding="0" cellspacing="0">  <tr><td>
188
  <ul id="tabnav">
189 55e50bd6 Scott Ullrich
    <li class="tabinact"><a href="pkg_mgr.php">Available Packages</a></li>
190
    <li class="tabact">Installed Packages</a></li>
191 ee11cc6e Scott Ullrich
  </ul>
192
  </td></tr>
193
  <tr>
194
    <td class="tabcont">
195
              <table width="100%" border="0" cellpadding="6" cellspacing="0">
196
               <tr>
197
                 <td>
198 b4ff3ccd Scott Ullrich
                     <!-- progress bar -->
199
                     <center>
200
                     <table id="progholder" name="progholder" height='20' border='1' bordercolor='black' width='420' bordercolordark='#000000' bordercolorlight='#000000' style='border-collapse: collapse' colspacing='2' cellpadding='2' cellspacing='2'><tr><td><img border='0' src='progress_bar.gif' width='280' height='23' name='progressbar' id='progressbar'></td></tr></table>
201
                     <br>
202
	             <!-- status box -->
203
                     <textarea cols="60" rows="1" name="status" id="status" wrap="hard">One moment please... This will take a while!</textarea>
204
                     <!-- command output box -->
205
	             <textarea cols="60" rows="25" name="output" id="output" wrap="hard"></textarea>
206
                     </center>
207 ee11cc6e Scott Ullrich
                 </td>
208
               </tr>
209
        </table>
210
    </td>
211
  </tr>
212
</table>
213
</form>
214
<?php include("fend.inc"); ?>
215
</body>
216
</html>
217
218 b4ff3ccd Scott Ullrich
<?php
219
220
update_progress_bar($pb_percent);
221
$pb_percent += 10;
222 ee11cc6e Scott Ullrich
223
/* install the package */
224
225 c6c150e9 Scott Ullrich
// Ensure directories are in place for pkg_add.
226
mwexec("mkdir /usr/local/www/ext/Services >/dev/null 2>&1");
227
mwexec("mkdir /usr/local/www/ext/System >/dev/null 2>&1");
228
mwexec("mkdir /usr/local/www/ext/Interfaces >/dev/null 2>&1");
229
mwexec("mkdir /usr/local/www/ext/Firewall >/dev/null 2>&1");
230
mwexec("mkdir /usr/local/www/ext/VPN >/dev/null 2>&1");
231
mwexec("mkdir /usr/local/www/ext/Status >/dev/null 2>&1");
232 3eaeb703 Scott Ullrich
mwexec("mkdir /usr/local/www/ext/Diagnostics >/dev/null 2>&1");
233 d2a1bba6 Scott Ullrich
mwexec("mkdir /usr/local/pkg >/dev/null 2>&1");
234 c6c150e9 Scott Ullrich
235 b4ff3ccd Scott Ullrich
update_progress_bar($pb_percent);
236
$pb_percent += 10;
237
238 ee11cc6e Scott Ullrich
$a_out = &$pkg_config['packages']['package'];
239
$pkgent = array();
240
$pkgent['name'] = $pkg_config['packages']['package'][$id]['name'];
241
$pkgent['descr'] = $pkg_config['packages']['package'][$id]['descr'];
242
$pkgent['category'] = $pkg_config['packages']['package'][$id]['category'];
243
$pkgent['depends_on_package'] = $a_out[$id]['depends_on_package'];
244 19fd2947 Scott Ullrich
$pkgent['depends_on_package_base_url'] = $a_out[$id]['depends_on_package_base_url'];
245 ee11cc6e Scott Ullrich
$pkgent['pfsense_package'] = $a_out[$id]['pfsense_package'];
246 19fd2947 Scott Ullrich
$pkgent['pfsense_package_base_url'] = $a_out[$id]['pfsense_package_base_url'];
247 1a05a4ee Scott Ullrich
$pkgent['configurationfile'] = $a_out[$id]['configurationfile'];
248 19fd2947 Scott Ullrich
if($pkg_config['packages']['package'][$id]['logging']) {
249
    // logging facilities.
250
    $pkgent['logging']['facility'] = $pkg_config['packages']['package'][$id]['logging']['facility'];
251
    $pkgent['logging']['logfile_name'] = $pkg_config['packages']['package'][$id]['logging']['logfile_name'];
252 8aca7e9b Scott Ullrich
    mwexec("/usr/sbin/clog -i -s 32768 /var/log/" . $pkgent['logging']['logfile_name']);
253 19fd2947 Scott Ullrich
    mwexec("chmod 0600 /var/log/" . $pkgent['logging']['logfile_name']);
254 b0cd4ded Scott Ullrich
    add_text_to_file("/etc/syslog.conf", $pkgent['logging']['facilityname'] . "\t\t\t" . $pkgent['logging']['logfilename']);
255 19fd2947 Scott Ullrich
    mwexec("/usr/bin/killall -HUP syslogd");
256
}
257
$a_out = &$config['packages']['package']; // save item to installedpkgs
258 ee11cc6e Scott Ullrich
259 b4ff3ccd Scott Ullrich
update_progress_bar($pb_percent);
260
$pb_percent += 10;
261
262 55e50bd6 Scott Ullrich
fwrite($fd_log, "ls /var/db/pkg | grep " . $pkgent['name'] . "\n" . $status);
263 1a05a4ee Scott Ullrich
if($status <> "") {
264
            // package is already installed!?
265
            print_info_box_np("NOTICE! " . $pkgent['name'] . " is already installed!  Installation will be registered.");
266
}
267 ee11cc6e Scott Ullrich
268 19fd2947 Scott Ullrich
if($pkg_config['packages']['package'][$id]['config_file'] <> "") {
269
    update_status("Downloading configuration file.");
270
    fwrite($fd_log, "Downloading configuration file " . $pkg_config['packages']['package'][$id]['config_file'] . " ... \n");
271
    update_progress_bar($pb_percent);
272
    $pb_percent += 10;
273
    mwexec("cd /usr/local/pkg/ && fetch " . $pkg_config['packages']['package'][$id]['config_file']);
274
    if(!file_exists("/usr/local/pkg/" . $pkgent['name'] . ".xml")) {
275
        update_output_window("ERROR!  Could not fetch " . $pkg_config['packages']['package'][$id]['config_file'] . "\n");
276
    }
277
}
278
279 55e50bd6 Scott Ullrich
update_status("Downloading and installing " . $pkgent['name'] . " - " . $pkgent['pfsense_package'] . " and its dependencies ... This could take a moment ...");
280 1a05a4ee Scott Ullrich
fwrite($fd_log, "Downloading and installing " . $pkgent['name'] . " ... \n");
281 ee11cc6e Scott Ullrich
282 b4ff3ccd Scott Ullrich
update_progress_bar($pb_percent);
283
$pb_percent += 10;
284
285 19fd2947 Scott Ullrich
if ($pkgent['pfsense_package_base_url'] <> "") {
286
    $text = exec_command_and_return_text("cd /tmp/ && /usr/sbin/pkg_add -r " . $pkgent['pfsense_package_base_url'] . "/" . $pkgent['pfsense_package']);
287
    update_output_window($text);
288
    fwrite($fd_log, "Executing: cd /tmp/ && /usr/sbin/pkg_add -r " . $pkgent['pfsense_package_base_url'] . "/" . $pkgent['pfsense_package'] . "\n" . $text);
289
}
290 ee11cc6e Scott Ullrich
291 b4ff3ccd Scott Ullrich
update_progress_bar($pb_percent);
292
$pb_percent += 10;
293
294 19fd2947 Scott Ullrich
if ($pkgent['depends_on_package_base_url'] <> "") {
295 d2a1bba6 Scott Ullrich
            update_status("Downloading and installing " . $pkgent['name'] . " and its dependencies ... This could take a moment ...");
296 19fd2947 Scott Ullrich
            $text = exec_command_and_return_text("cd /tmp/ && /usr/sbin/pkg_add -r " . $pkgent['depends_on_package_base_url'] . "/" . $pkgent['depends_on_package']);
297 1a05a4ee Scott Ullrich
            update_output_window($text);
298 19fd2947 Scott Ullrich
            fwrite($fd_log, "cd /tmp/ && /usr/sbin/pkg_add -r " . $pkgent['depends_on_package_base_url'] . "/" . $pkgent['depends_on_package'] . "\n" . $text);;
299 1a05a4ee Scott Ullrich
}
300 ee11cc6e Scott Ullrich
301 d2a1bba6 Scott Ullrich
// fetch additional files needed for package if defined
302
// and uncompress if needed.
303
if ($pkgent['additional_files_needed'] <> "") {
304
            foreach($pkgent['additional_files_needed']['item'] as $afn) {
305
                        update_progress_bar($pb_percent);
306 a1845bbf Scott Ullrich
                        $pb_percent += 10;
307 d2a1bba6 Scott Ullrich
                        $filename = get_filename_from_url($afn['url']);
308
                        update_status("Downloading additional files needed for package " . $filename . " ...");
309
                        system("cd /usr/local/pkg && /usr/bin/fetch " .  $afn['url']);
310
                        if(stristr($filename, '.tgz') <> "")
311
                                    system("cd /usr/local/pkg && tar xzvf " . $filename);
312
            }
313
}
314
315 b4ff3ccd Scott Ullrich
update_progress_bar($pb_percent);
316
$pb_percent += 10;
317
318 ee11cc6e Scott Ullrich
$config = parse_xml_config("{$g['conf_path']}/config.xml", $g['xml_rootobj']);
319
320 b4ff3ccd Scott Ullrich
update_progress_bar($pb_percent);
321
$pb_percent += 10;
322
323 ee11cc6e Scott Ullrich
$config['installedpackages']['package'][] = $pkgent;
324
325
if (isset($id) && $a_out[$id])
326
        $a_out[$id] = $pkgent;
327
else
328
        $a_out[] = $pkgent;
329
330 b4ff3ccd Scott Ullrich
update_progress_bar($pb_percent);
331
$pb_percent += 10;
332
333 ee11cc6e Scott Ullrich
write_config();
334
335 b4ff3ccd Scott Ullrich
update_progress_bar($pb_percent);
336
$pb_percent += 10;
337
338 55e50bd6 Scott Ullrich
$name = $pkgent['name'];
339
340 b4ff3ccd Scott Ullrich
update_progress_bar($pb_percent);
341
$pb_percent++;
342
343 55e50bd6 Scott Ullrich
// parse the config file for this package and install neededtext items.
344
if(file_exists("/usr/local/pkg/" . $pkgent['name'] . ".xml")) {
345 19fd2947 Scott Ullrich
            $package_conf = parse_xml_config_pkg("/usr/local/pkg/" . $pkgent['name'] . ".xml", "packagegui");
346
            if($package_conf['modify_system']['item'] <> "") {
347
                foreach ($package_conf['modify_system']['item'] as $ms) {
348
                    update_progress_bar($pb_percent);
349
                    $pb_percent += 10;
350
                    if($ms['textneeded']) {
351
                        add_text_to_file($ms['modifyfilename'],$ms['textneeded']);
352
                    }
353
                }
354 55e50bd6 Scott Ullrich
            }
355 7bb0d0fc Scott Ullrich
            // loop through menu installation items
356
            // installing multiple items if need be.
357
            foreach ($package_conf['menu'] as $menu) {
358
                        // install menu item into the ext folder
359
                        fwrite($fd_log, "Adding menu option to " . $menu['section'] . "/" . $menu['name'] . "\n");
360
                        $fd = fopen("/usr/local/www/ext/" . $menu['section'] . "/" . $menu['name'] , "w");
361
                        if($menu['url'] <> "") {
362
                                    fwrite($fd, $menu['url'] . "\n");
363
                        } else {
364 a1845bbf Scott Ullrich
                                    fwrite($fd, "/pkg.php?xml=" . strtolower($menu['name']) . ".xml\n");
365 7bb0d0fc Scott Ullrich
                        }
366
                        fclose($fd);
367
            }
368 55e50bd6 Scott Ullrich
} else {
369
            update_output_window("WARNING! /usr/local/pkg/" . $pkgent['name'] . ".xml" . " does not exist!\n");
370
            fwrite($fd_log, "WARNING! /usr/local/pkg/" . $pkgent['name'] . ".xml" . " does not exist!\n");
371
}
372
fwrite($fd_log, "End of Package Manager installation session.\n");
373
374 b4ff3ccd Scott Ullrich
update_progress_bar($pb_percent);
375
$pb_percent += 10;
376
377 55e50bd6 Scott Ullrich
// return dependency list to output later.
378
$command = "TODELETE=`ls /var/db/pkg | grep " . $name . "` && /usr/sbin/pkg_info -r \$TODELETE | grep Dependency: | cut -d\" \" -f2";
379
$dependencies = exec_command_and_return_text($command);
380 a7f908db Scott Ullrich
fwrite($fd_log, "Installed " . $name . " and the following dependencies:\n" . $dependencies);
381 55e50bd6 Scott Ullrich
382 b4ff3ccd Scott Ullrich
update_progress_bar($pb_percent);
383
$pb_percent += 10;
384
385 1a05a4ee Scott Ullrich
$status = exec_command_and_return_text("ls /var/db/pkg | grep " . $pkgent['name']);
386 55e50bd6 Scott Ullrich
fwrite($fd_log, "ls /var/db/pkg | grep " . $pkgent['name'] . "\n" . $status);
387 1a05a4ee Scott Ullrich
if($status <> "") {
388
            update_status("Package installation completed.");
389
            fwrite($fd_log, "Package installation completed.\n");
390
} else {
391
            update_status("Package WAS NOT installed properly.");
392
            fwrite($fd_log, "Package WAS NOT installed properly.\n");
393
}
394
395 b4ff3ccd Scott Ullrich
update_progress_bar($pb_percent);
396
$pb_percent += 10;
397
398 55e50bd6 Scott Ullrich
// close log
399 1a05a4ee Scott Ullrich
fclose($fd_log);
400
401 19fd2947 Scott Ullrich
if($package_conf['custom_php_install_command']) {
402
    eval($package_conf['custom_php_install_command']);
403 6483da5d Scott Ullrich
}
404
405 55e50bd6 Scott Ullrich
// reopen and read log in
406 1a05a4ee Scott Ullrich
$fd_log = fopen("/tmp/pkg_mgr.log", "r");
407
$tmp = "";
408
while(!feof($fd_log)) {
409
            $tmp .= fread($fd_log,49);
410
}
411 55e50bd6 Scott Ullrich
fclose($fd_log);
412 1a05a4ee Scott Ullrich
$log = ereg_replace("\n", "\\n", $tmp);
413 3eaeb703 Scott Ullrich
//echo "\n<script language=\"JavaScript\">this.document.forms[0].output.value = \"" . $log . "\";</script>";
414 1a05a4ee Scott Ullrich
415 b4ff3ccd Scott Ullrich
update_progress_bar(100);
416
417
echo "\n<script language=\"JavaScript\">document.progressbar.style.visibility='hidden';</script>";
418
echo "\n<script language=\"JavaScript\">document.progholder.style.visibility='hidden';</script>";
419
420 19fd2947 Scott Ullrich
function add_text_to_file($file, $text) {
421 8aca7e9b Scott Ullrich
    global $fd_log;
422 19fd2947 Scott Ullrich
    fwrite($fd_log, "Adding needed text items:\n");
423
    $filecontents = exec_command_and_return_text("cat " . $file);
424 b0cd4ded Scott Ullrich
    $filecontents = str_replace($text, "", $filecontents);
425
    $text = $filecontents . $text;
426 19fd2947 Scott Ullrich
    fwrite($fd_log, $text . "\n");
427
    $fd = fopen($file, "w");
428
    fwrite($fd, $text . "\n");
429
    fclose($fd);
430
}
431
432 d2a1bba6 Scott Ullrich
function get_filename_from_url($url) {
433
            $filenamesplit = split("/", $url);
434 a1845bbf Scott Ullrich
            foreach($filenamesplit as $fn) $filename = $fn;
435 d2a1bba6 Scott Ullrich
            return $filename;
436
}
437
438 ee11cc6e Scott Ullrich
?>
439
440
441
442
443
444
445
446