TracAdmin: sok9.php

File sok9.php, 69.5 kB (added by anonymous, 2 years ago)
Line 
1 <?php
2 /*
3  * webadmin.php - a simple Web-based file manager
4  * Copyright (C) 2004  Daniel Wacker <daniel.wacker@web.de>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  *
20  * -------------------------------------------------------------------------
21  * While using this script, do NOT navigate with your browser's back and
22  * forward buttons! Always open files in a new browser tab!
23  * -------------------------------------------------------------------------
24  *
25  * This is Version 0.9, revision 9
26  * =========================================================================
27  *
28  * Changes of revision 9
29  * <daniel.wacker@web.de>
30  *    added workaround for directory listing, if lstat() is disabled
31  *    fixed permisson of uploaded files (thanks to Stephan Duffner)
32  *
33  * Changes of revision 8
34  * <okankan@stud.sdu.edu.tr>
35  *    added Turkish translation
36  * <j@kub.cz>
37  *    added Czech translation
38  * <daniel.wacker@web.de>
39  *    improved charset handling
40  *
41  * Changes of revision 7
42  * <szuniga@vtr.net>
43  *    added Spanish translation
44  * <lars@soelgaard.net>
45  *    added Danish translation
46  * <daniel.wacker@web.de>
47  *    improved rename dialog
48  *
49  * Changes of revision 6
50  * <nederkoorn@tiscali.nl>
51  *    added Dutch translation
52  *
53  * Changes of revision 5
54  * <daniel.wacker@web.de>
55  *    added language auto select
56  *    fixed symlinks in directory listing
57  *    removed word-wrap in edit textarea
58  *
59  * Changes of revision 4
60  * <daloan@guideo.fr>
61  *    added French translation
62  * <anders@wiik.cc>
63  *    added Swedish translation
64  *
65  * Changes of revision 3
66  * <nzunta@gabriele-erba.it>
67  *    improved Italian translation
68  *
69  * Changes of revision 2
70  * <daniel.wacker@web.de>
71  *    got images work in some old browsers
72  *    fixed creation of directories
73  *    fixed files deletion
74  *    improved path handling
75  *    added missing word 'not_created'
76  * <till@tuxen.de>
77  *    improved human readability of file sizes
78  * <nzunta@gabriele-erba.it>
79  *    added Italian translation
80  *
81  * Changes of revision 1
82  * <daniel.wacker@web.de>
83  *    webadmin.php completely rewritten:
84  *    - clean XHTML/CSS output
85  *    - several files selectable
86  *    - support for windows servers
87  *    - no more treeview, because
88  *      - webadmin.php is a >simple< file manager
89  *      - performance problems (too much additional code)
90  *      - I don't like: frames, java-script, to reload after every treeview-click
91  *    - execution of shell scripts
92  *    - introduced revision numbers
93  *
94 /* ------------------------------------------------------------------------- */
95
96 /* Your language:
97  * 'en' - English
98  * 'de' - German
99  * 'fr' - French
100  * 'it' - Italian
101  * 'nl' - Dutch
102  * 'se' - Swedish
103  * 'sp' - Spanish
104  * 'dk' - Danish
105  * 'tr' - Turkish
106  * 'cs' - Czech
107  * 'auto' - autoselect
108  */
109 $lang = 'auto';
110
111 /* Charset of output:
112  * possible values are described in the charset table at
113  * http://www.php.net/manual/en/function.htmlentities.php
114  * 'auto' - use the same charset as the words of my language are encoded
115  */
116 $site_charset = 'auto';
117
118 /* Homedir:
119  * For example: './' - the script's directory
120  */
121 $homedir = './';
122
123 /* Size of the edit textarea
124  */
125 $editcols = 80;
126 $editrows = 25;
127
128 /* -------------------------------------------
129  * Optional configuration (remove # to enable)
130  */
131
132 /* Permission of created directories:
133  * For example: 0705 would be 'drwx---r-x'.
134  */
135 # $dirpermission = 0705;
136
137 /* Permission of created files:
138  * For example: 0604 would be '-rw----r--'.
139  */
140 # $filepermission = 0604;
141
142 /* Filenames related to the apache web server:
143  */
144 $htaccess = '.htaccess';
145 $htpasswd = '.htpasswd';
146
147 /* ------------------------------------------------------------------------- */
148
149 if (get_magic_quotes_gpc()) {
150     array_walk($_GET, 'strip');
151     array_walk($_POST, 'strip');
152     array_walk($_REQUEST, 'strip');
153 }
154
155 if (array_key_exists('image', $_GET)) {
156     header('Content-Type: image/gif');
157     die(getimage($_GET['image']));
158 }
159
160 if (!function_exists('lstat')) {
161     function lstat ($filename) {
162         return stat($filename);
163     }
164 }
165
166 $delim = DIRECTORY_SEPARATOR;
167
168 if (function_exists('php_uname')) {
169     $win = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? true : false;
170 } else {
171     $win = ($delim == '\\') ? true : false;
172 }
173
174 if (!empty($_SERVER['PATH_TRANSLATED'])) {
175     $scriptdir = dirname($_SERVER['PATH_TRANSLATED']);
176 } elseif (!empty($_SERVER['SCRIPT_FILENAME'])) {
177     $scriptdir = dirname($_SERVER['SCRIPT_FILENAME']);
178 } elseif (function_exists('getcwd')) {
179     $scriptdir = getcwd();
180 } else {
181     $scriptdir = '.';
182 }
183 $homedir = relative2absolute($homedir, $scriptdir);
184
185 $dir = (array_key_exists('dir', $_REQUEST)) ? $_REQUEST['dir'] : $homedir;
186
187 if (array_key_exists('olddir', $_POST) && !path_is_relative($_POST['olddir'])) {
188     $dir = relative2absolute($dir, $_POST['olddir']);
189 }
190
191 $directory = simplify_path(addslash($dir));
192
193 $files = array();
194 $action = '';
195 if (!empty($_POST['submit_all'])) {
196     $action = $_POST['action_all'];
197     for ($i = 0; $i < $_POST['num']; $i++) {
198         if (array_key_exists("checked$i", $_POST) && $_POST["checked$i"] == 'true') {
199             $files[] = $_POST["file$i"];
200         }
201     }
202 } elseif (!empty($_REQUEST['action'])) {
203     $action = $_REQUEST['action'];
204     $files[] = relative2absolute($_REQUEST['file'], $directory);
205 } elseif (!empty($_POST['submit_upload']) && !empty($_FILES['upload']['name'])) {
206     $files[] = $_FILES['upload'];
207     $action = 'upload';
208 } elseif (array_key_exists('num', $_POST)) {
209     for ($i = 0; $i < $_POST['num']; $i++) {
210         if (array_key_exists("submit$i", $_POST)) break;
211     }
212     if ($i < $_POST['num']) {
213         $action = $_POST["action$i"];
214         $files[] = $_POST["file$i"];
215     }
216 }
217 if (empty($action) && (!empty($_POST['submit_create']) || (array_key_exists('focus', $_POST) && $_POST['focus'] == 'create')) && !empty($_POST['create_name'])) {
218     $files[] = relative2absolute($_POST['create_name'], $directory);
219     switch ($_POST['create_type']) {
220     case 'directory':
221         $action = 'create_directory';
222         break;
223     case 'file':
224         $action = 'create_file';
225     }
226 }
227 if (sizeof($files) == 0) $action = ''; else $file = reset($files);
228
229 if ($lang == 'auto') {
230     if (array_key_exists('HTTP_ACCEPT_LANGUAGE', $_SERVER) && strlen($_SERVER['HTTP_ACCEPT_LANGUAGE']) >= 2) {
231         $lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
232     } else {
233         $lang = 'en';
234     }
235 }
236
237 $words = getwords($lang);
238
239 if ($site_charset == 'auto') {
240     $site_charset = $word_charset;
241 }
242
243 $cols = ($win) ? 4 : 7;
244
245 if (!isset($dirpermission)) {
246     $dirpermission = (function_exists('umask')) ? (0777 & ~umask()) : 0755;
247 }
248 if (!isset($filepermission)) {
249     $filepermission = (function_exists('umask')) ? (0666 & ~umask()) : 0644;
250 }
251
252 if (!empty($_SERVER['SCRIPT_NAME'])) {
253     $self = html(basename($_SERVER['SCRIPT_NAME']));
254 } elseif (!empty($_SERVER['PHP_SELF'])) {
255     $self = html(basename($_SERVER['PHP_SELF']));
256 } else {
257     $self = '';
258 }
259
260 if (!empty($_SERVER['SERVER_SOFTWARE'])) {
261     if (strtolower(substr($_SERVER['SERVER_SOFTWARE'], 0, 6)) == 'apache') {
262         $apache = true;
263     } else {
264         $apache = false;
265     }
266 } else {
267     $apache = true;
268 }
269
270 switch ($action) {
271
272 case 'view':
273
274     if (is_script($file)) {
275
276         /* highlight_file is a mess! */
277         ob_start();
278         highlight_file($file);
279         $src = ereg_replace('<font color="([^"]*)">', '<span style="color: \1">', ob_get_contents());
280         $src = str_replace(array('</font>', "\r", "\n"), array('</span>', '', ''), $src);
281         ob_end_clean();
282
283         html_header();
284         echo '<h2 style="text-align: left; margin-bottom: 0">' . html($file) . '</h2>
285
286 <hr />
287
288 <table>
289 <tr>
290 <td style="text-align: right; vertical-align: top; color: gray; padding-right: 3pt; border-right: 1px solid gray">
291 <pre style="margin-top: 0"><code>';
292
293         for ($i = 1; $i <= sizeof(file($file)); $i++) echo "$i\n";
294
295         echo '</code></pre>
296 </td>
297 <td style="text-align: left; vertical-align: top; padding-left: 3pt">
298 <pre style="margin-top: 0">' . $src . '</pre>
299 </td>
300 </tr>
301 </table>
302
303 ';
304
305         html_footer();
306
307     } else {
308
309         header('Content-Type: ' . getmimetype($file));
310         header('Content-Disposition: filename=' . basename($file));
311
312         readfile($file);
313
314     }
315
316     break;
317
318 case 'download':
319
320     header('Pragma: public');
321     header('Expires: 0');
322     header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
323     header('Content-Type: ' . getmimetype($file));
324     header('Content-Disposition: attachment; filename=' . basename($file) . ';');
325     header('Content-Length: ' . filesize($file));
326
327     readfile($file);
328
329     break;
330
331 case 'upload':
332
333     $dest = relative2absolute($file['name'], $directory);
334
335     if (@file_exists($dest)) {
336         listing_page(error('already_exists', $dest));
337     } elseif (@move_uploaded_file($file['tmp_name'], $dest)) {
338         @chmod($dest, $filepermission);
339         listing_page(notice('uploaded', $file['name']));
340     } else {
341         listing_page(error('not_uploaded', $file['name']));
342     }
343
344     break;
345
346 case 'create_directory':
347
348     if (@file_exists($file)) {
349         listing_page(error('already_exists', $file));
350     } else {
351         $old = @umask(0777 & ~$dirpermission);
352         if (@mkdir($file, $dirpermission)) {
353             listing_page(notice('created', $file));
354         } else {
355             listing_page(error('not_created', $file));
356         }
357         @umask($old);
358     }
359
360     break;
361
362 case 'create_file':
363
364     if (@file_exists($file)) {
365         listing_page(error('already_exists', $file));
366     } else {
367         $old = @umask(0777 & ~$filepermission);
368         if (@touch($file)) {
369             edit($file);
370         } else {
371             listing_page(error('not_created', $file));
372         }
373         @umask($old);
374     }
375
376     break;
377
378 case 'execute':
379
380     chdir(dirname($file));
381
382     $output = array();
383     $retval = 0;
384     exec('echo "./' . basename($file) . '" | /bin/sh', $output, $retval);
385
386     $error = ($retval == 0) ? false : true;
387
388     if (sizeof($output) == 0) $output = array('<' . $words['no_output'] . '>');
389
390     if ($error) {
391         listing_page(error('not_executed', $file, implode("\n", $output)));
392     } else {
393         listing_page(notice('executed', $file, implode("\n", $output)));
394     }
395
396     break;
397
398 case 'delete':
399
400     if (!empty($_POST['no'])) {
401         listing_page();
402     } elseif (!empty($_POST['yes'])) {
403
404         $failure = array();
405         $success = array();
406
407         foreach ($files as $file) {
408             if (del($file)) {
409                 $success[] = $file;
410             } else {
411                 $failure[] = $file;
412             }
413         }
414
415         $message = '';
416         if (sizeof($failure) > 0) {
417             $message = error('not_deleted', implode("\n", $failure));
418         }
419         if (sizeof($success) > 0) {
420             $message .= notice('deleted', implode("\n", $success));
421         }
422
423         listing_page($message);
424
425     } else {
426
427         html_header();
428
429         echo '<form action="' . $self . '" method="post">
430 <table class="dialog">
431 <tr>
432 <td class="dialog">
433 ';
434
435         request_dump();
436
437         echo "\t<b>" . word('really_delete') . '</b>
438     <p>
439 ';
440
441         foreach ($files as $file) {
442             echo "\t" . html($file) . "<br />\n";
443         }
444
445         echo '    </p>
446     <hr />
447     <input type="submit" name="no" value="' . word('no') . '" id="red_button" />
448     <input type="submit" name="yes" value="' . word('yes') . '" id="green_button" style="margin-left: 50px" />
449 </td>
450 </tr>
451 </table>
452 </form>
453
454 ';
455
456         html_footer();
457
458     }
459
460     break;
461
462 case 'rename':
463
464     if (!empty($_POST['destination'])) {
465
466         $dest = relative2absolute($_POST['destination'], $directory);
467
468         if (!@file_exists($dest) && @rename($file, $dest)) {
469             listing_page(notice('renamed', $file, $dest));
470         } else {
471             listing_page(error('not_renamed', $file, $dest));
472         }
473
474     } else {
475
476         $name = basename($file);
477
478         html_header();
479
480         echo '<form action="' . $self . '" method="post">
481
482 <table class="dialog">
483 <tr>
484 <td class="dialog">
485     <input type="hidden" name="action" value="rename" />
486     <input type="hidden" name="file" value="' . html($file) . '" />
487     <input type="hidden" name="dir" value="' . html($directory) . '" />
488     <b>' . word('rename_file') . '</b>
489     <p>' . html($file) . '</p>
490     <b>' . substr($file, 0, strlen($file) - strlen($name)) . '</b>
491     <input type="text" name="destination" size="' . textfieldsize($name) . '" value="' . html($name) . '" />
492     <hr />
493     <input type="submit" value="' . word('rename') . '" />
494 </td>
495 </tr>
496 </table>
497
498 <p><a href="' . $self . '?dir=' . urlencode($directory) . '">[ ' . word('back') . ' ]</a></p>
499
500 </form>
501
502 ';
503
504         html_footer();
505
506     }
507
508     break;
509
510 case 'move':
511
512     if (!empty($_POST['destination'])) {
513
514         $dest = relative2absolute($_POST['destination'], $directory);
515
516         $failure = array();
517         $success = array();
518
519         foreach ($files as $file) {
520             $filename = substr($file, strlen($directory));
521             $d = $dest . $filename;
522             if (!@file_exists($d) && @rename($file, $d)) {
523                 $success[] = $file;
524             } else {
525                 $failure[] = $file;
526             }
527         }
528
529         $message = '';
530         if (sizeof($failure) > 0) {
531             $message = error('not_moved', implode("\n", $failure), $dest);
532         }
533         if (sizeof($success) > 0) {
534             $message .= notice('moved', implode("\n", $success), $dest);
535         }
536
537         listing_page($message);
538
539     } else {
540
541         html_header();
542
543         echo '<form action="' . $self . '" method="post">
544
545 <table class="dialog">
546 <tr>
547 <td class="dialog">
548 ';
549
550         request_dump();
551
552         echo "\t<b>" . word('move_files') . '</b>
553     <p>
554 ';
555
556         foreach ($files as $file) {
557             echo "\t" . html($file) . "<br />\n";
558         }
559
560         echo '    </p>
561     <hr />
562     ' . word('destination') . ':
563     <input type="text" name="destination" size="' . textfieldsize($directory) . '" value="' . html($directory) . '" />
564     <input type="submit" value="' . word('move') . '" />
565 </td>
566 </tr>
567 </table>
568
569 <p><a href="' . $self . '?dir=' . urlencode($directory) . '">[ ' . word('back') . ' ]</a></p>
570
571 </form>
572
573 ';
574
575         html_footer();
576
577     }
578
579     break;
580
581 case 'copy':
582
583     if (!empty($_POST['destination'])) {
584
585         $dest = relative2absolute($_POST['destination'], $directory);
586
587         if (@is_dir($dest)) {
588
589             $failure = array();
590             $success = array();
591
592             foreach ($files as $file) {
593                 $filename = substr($file, strlen($directory