· 4 years ago · Jun 25, 2021, 09:10 AM
1<%--
2 jsp File browser 1.2
3 Copyright (C) 2003-2006 Boris von Loesch
4 This program is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 2 of the License, or (at your option)
7 any later version.
8 This program is distributed in the hope that it will be useful, but
9 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
11 You should have received a copy of the GNU General Public License along with
12 this program; if not, write to the
13 Free Software Foundation, Inc.,
14 59 Temple Place, Suite 330,
15 Boston, MA 02111-1307 USA
16 - Description: jsp File browser v1.2 -- This JSP program allows remote web-based
17 file access and manipulation. You can copy, create, move and delete files.
18 Text files can be edited and groups of files and folders can be downloaded
19 as a single zip file that's created on the fly.
20 - Credits: Taylor Bastien, David Levine, David Cowan, Lieven Govaerts
21--%>
22<%@page import="java.util.*,
23 java.net.*,
24 java.text.*,
25 java.util.zip.*,
26 java.io.*"
27%>
28<%!
29 //FEATURES
30 private static final boolean NATIVE_COMMANDS = true;
31 /**
32 *If true, all operations (besides upload and native commands)
33 *which change something on the file system are permitted
34 */
35 private static final boolean READ_ONLY = false;
36 //If true, uploads are allowed even if READ_ONLY = true
37 private static final boolean ALLOW_UPLOAD = true;
38
39 //Allow browsing and file manipulation only in certain directories
40 private static final boolean RESTRICT_BROWSING = false;
41 //If true, the user is allowed to browse only in RESTRICT_PATH,
42 //if false, the user is allowed to browse all directories besides RESTRICT_PATH
43 private static final boolean RESTRICT_WHITELIST = false;
44 //Paths, sperated by semicolon
45 //private static final String RESTRICT_PATH = "C:\\CODE;E:\\"; //Win32: Case important!!
46 private static final String RESTRICT_PATH = "/etc;/var";
47
48 //The refresh time in seconds of the upload monitor window
49 private static final int UPLOAD_MONITOR_REFRESH = 2;
50 //The number of colums for the edit field
51 private static final int EDITFIELD_COLS = 85;
52 //The number of rows for the edit field
53 private static final int EDITFIELD_ROWS = 30;
54 //Open a new window to view a file
55 private static final boolean USE_POPUP = true;
56 /**
57 * If USE_DIR_PREVIEW = true, then for every directory a tooltip will be
58 * created (hold the mouse over the link) with the first DIR_PREVIEW_NUMBER entries.
59 * This can yield to performance issues. Turn it off, if the directory loads to slow.
60 */
61 private static final boolean USE_DIR_PREVIEW = false;
62 private static final int DIR_PREVIEW_NUMBER = 10;
63 /**
64 * The name of an optional CSS Stylesheet file
65 */
66 private static final String CSS_NAME = "Browser.css";
67 /**
68 * The compression level for zip file creation (0-9)
69 * 0 = No compression
70 * 1 = Standard compression (Very fast)
71 * ...
72 * 9 = Best compression (Very slow)
73 */
74 private static final int COMPRESSION_LEVEL = 1;
75 /**
76 * The FORBIDDEN_DRIVES are not displayed on the list. This can be usefull, if the
77 * server runs on a windows platform, to avoid a message box, if you try to access
78 * an empty removable drive (See KNOWN BUGS in Readme.txt).
79 */
80 private static final String[] FORBIDDEN_DRIVES = {"a:\\"};
81
82 /**
83 * Command of the shell interpreter and the parameter to run a programm
84 */
85 private static final String[] COMMAND_INTERPRETER = {"cmd", "/C"}; // Dos,Windows
86 //private static final String[] COMMAND_INTERPRETER = {"/bin/sh","-c"}; // Unix
87
88 /**
89 * Max time in ms a process is allowed to run, before it will be terminated
90 */
91 private static final long MAX_PROCESS_RUNNING_TIME = 30 * 1000; //30 seconds
92
93 //Button names
94 private static final String SAVE_AS_ZIP = "Download selected files as (z)ip";
95 private static final String RENAME_FILE = "(R)ename File";
96 private static final String DELETE_FILES = "(Del)ete selected files";
97 private static final String CREATE_DIR = "Create (D)ir";
98 private static final String CREATE_FILE = "(C)reate File";
99 private static final String MOVE_FILES = "(M)ove Files";
100 private static final String COPY_FILES = "Cop(y) Files";
101 private static final String LAUNCH_COMMAND = "(L)aunch external program";
102 private static final String UPLOAD_FILES = "Upload";
103
104 //Normally you should not change anything after this line
105 //----------------------------------------------------------------------------------
106 //Change this to locate the tempfile directory for upload (not longer needed)
107 private static String tempdir = ".";
108 private static String VERSION_NR = "1.2";
109 private static DateFormat dateFormat = DateFormat.getDateTimeInstance();
110
111 public class UplInfo {
112
113 public long totalSize;
114 public long currSize;
115 public long starttime;
116 public boolean aborted;
117
118 public UplInfo() {
119 totalSize = 0l;
120 currSize = 0l;
121 starttime = System.currentTimeMillis();
122 aborted = false;
123 }
124
125 public UplInfo(int size) {
126 totalSize = size;
127 currSize = 0;
128 starttime = System.currentTimeMillis();
129 aborted = false;
130 }
131
132 public String getUprate() {
133 long time = System.currentTimeMillis() - starttime;
134 if (time != 0) {
135 long uprate = currSize * 1000 / time;
136 return convertFileSize(uprate) + "/s";
137 }
138 else return "n/a";
139 }
140
141 public int getPercent() {
142 if (totalSize == 0) return 0;
143 else return (int) (currSize * 100 / totalSize);
144 }
145
146 public String getTimeElapsed() {
147 long time = (System.currentTimeMillis() - starttime) / 1000l;
148 if (time - 60l >= 0){
149 if (time % 60 >=10) return time / 60 + ":" + (time % 60) + "m";
150 else return time / 60 + ":0" + (time % 60) + "m";
151 }
152 else return time<10 ? "0" + time + "s": time + "s";
153 }
154
155 public String getTimeEstimated() {
156 if (currSize == 0) return "n/a";
157 long time = System.currentTimeMillis() - starttime;
158 time = totalSize * time / currSize;
159 time /= 1000l;
160 if (time - 60l >= 0){
161 if (time % 60 >=10) return time / 60 + ":" + (time % 60) + "m";
162 else return time / 60 + ":0" + (time % 60) + "m";
163 }
164 else return time<10 ? "0" + time + "s": time + "s";
165 }
166
167 }
168
169 public class FileInfo {
170
171 public String name = null, clientFileName = null, fileContentType = null;
172 private byte[] fileContents = null;
173 public File file = null;
174 public StringBuffer sb = new StringBuffer(100);
175
176 public void setFileContents(byte[] aByteArray) {
177 fileContents = new byte[aByteArray.length];
178 System.arraycopy(aByteArray, 0, fileContents, 0, aByteArray.length);
179 }
180 }
181
182 public static class UploadMonitor {
183
184 static Hashtable uploadTable = new Hashtable();
185
186 static void set(String fName, UplInfo info) {
187 uploadTable.put(fName, info);
188 }
189
190 static void remove(String fName) {
191 uploadTable.remove(fName);
192 }
193
194 static UplInfo getInfo(String fName) {
195 UplInfo info = (UplInfo) uploadTable.get(fName);
196 return info;
197 }
198 }
199
200 // A Class with methods used to process a ServletInputStream
201 public class HttpMultiPartParser {
202
203 //private final String lineSeparator = System.getProperty("line.separator", "\n");
204 private final int ONE_MB = 1024 * 1;
205
206 public Hashtable processData(ServletInputStream is, String boundary, String saveInDir,
207 int clength) throws IllegalArgumentException, IOException {
208 if (is == null) throw new IllegalArgumentException("InputStream");
209 if (boundary == null || boundary.trim().length() < 1) throw new IllegalArgumentException(
210 "\"" + boundary + "\" is an illegal boundary indicator");
211 boundary = "--" + boundary;
212 StringTokenizer stLine = null, stFields = null;
213 FileInfo fileInfo = null;
214 Hashtable dataTable = new Hashtable(5);
215 String line = null, field = null, paramName = null;
216 boolean saveFiles = (saveInDir != null && saveInDir.trim().length() > 0);
217 boolean isFile = false;
218 if (saveFiles) { // Create the required directory (including parent dirs)
219 File f = new File(saveInDir);
220 f.mkdirs();
221 }
222 line = getLine(is);
223 if (line == null || !line.startsWith(boundary)) throw new IOException(
224 "Boundary not found; boundary = " + boundary + ", line = " + line);
225 while (line != null) {
226 if (line == null || !line.startsWith(boundary)) return dataTable;
227 line = getLine(is);
228 if (line == null) return dataTable;
229 stLine = new StringTokenizer(line, ";\r\n");
230 if (stLine.countTokens() < 2) throw new IllegalArgumentException(
231 "Bad data in second line");
232 line = stLine.nextToken().toLowerCase();
233 if (line.indexOf("form-data") < 0) throw new IllegalArgumentException(
234 "Bad data in second line");
235 stFields = new StringTokenizer(stLine.nextToken(), "=\"");
236 if (stFields.countTokens() < 2) throw new IllegalArgumentException(
237 "Bad data in second line");
238 fileInfo = new FileInfo();
239 stFields.nextToken();
240 paramName = stFields.nextToken();
241 isFile = false;
242 if (stLine.hasMoreTokens()) {
243 field = stLine.nextToken();
244 stFields = new StringTokenizer(field, "=\"");
245 if (stFields.countTokens() > 1) {
246 if (stFields.nextToken().trim().equalsIgnoreCase("filename")) {
247 fileInfo.name = paramName;
248 String value = stFields.nextToken();
249 if (value != null && value.trim().length() > 0) {
250 fileInfo.clientFileName = value;
251 isFile = true;
252 }
253 else {
254 line = getLine(is); // Skip "Content-Type:" line
255 line = getLine(is); // Skip blank line
256 line = getLine(is); // Skip blank line
257 line = getLine(is); // Position to boundary line
258 continue;
259 }
260 }
261 }
262 else if (field.toLowerCase().indexOf("filename") >= 0) {
263 line = getLine(is); // Skip "Content-Type:" line
264 line = getLine(is); // Skip blank line
265 line = getLine(is); // Skip blank line
266 line = getLine(is); // Position to boundary line
267 continue;
268 }
269 }
270 boolean skipBlankLine = true;
271 if (isFile) {
272 line = getLine(is);
273 if (line == null) return dataTable;
274 if (line.trim().length() < 1) skipBlankLine = false;
275 else {
276 stLine = new StringTokenizer(line, ": ");
277 if (stLine.countTokens() < 2) throw new IllegalArgumentException(
278 "Bad data in third line");
279 stLine.nextToken(); // Content-Type
280 fileInfo.fileContentType = stLine.nextToken();
281 }
282 }
283 if (skipBlankLine) {
284 line = getLine(is);
285 if (line == null) return dataTable;
286 }
287 if (!isFile) {
288 line = getLine(is);
289 if (line == null) return dataTable;
290 dataTable.put(paramName, line);
291 // If parameter is dir, change saveInDir to dir
292 if (paramName.equals("dir")) saveInDir = line;
293 line = getLine(is);
294 continue;
295 }
296 try {
297 UplInfo uplInfo = new UplInfo(clength);
298 UploadMonitor.set(fileInfo.clientFileName, uplInfo);
299 OutputStream os = null;
300 String path = null;
301 if (saveFiles) os = new FileOutputStream(path = getFileName(saveInDir,
302 fileInfo.clientFileName));
303 else os = new ByteArrayOutputStream(ONE_MB);
304 boolean readingContent = true;
305 byte previousLine[] = new byte[2 * ONE_MB];
306 byte temp[] = null;
307 byte currentLine[] = new byte[2 * ONE_MB];
308 int read, read3;
309 if ((read = is.readLine(previousLine, 0, previousLine.length)) == -1) {
310 line = null;
311 break;
312 }
313 while (readingContent) {
314 if ((read3 = is.readLine(currentLine, 0, currentLine.length)) == -1) {
315 line = null;
316 uplInfo.aborted = true;
317 break;
318 }
319 if (compareBoundary(boundary, currentLine)) {
320 os.write(previousLine, 0, read - 2);
321 line = new String(currentLine, 0, read3);
322 break;
323 }
324 else {
325 os.write(previousLine, 0, read);
326 uplInfo.currSize += read;
327 temp = currentLine;
328 currentLine = previousLine;
329 previousLine = temp;
330 read = read3;
331 }//end else
332 }//end while
333 os.flush();
334 os.close();
335 if (!saveFiles) {
336 ByteArrayOutputStream baos = (ByteArrayOutputStream) os;
337 fileInfo.setFileContents(baos.toByteArray());
338 }
339 else fileInfo.file = new File(path);
340 dataTable.put(paramName, fileInfo);
341 uplInfo.currSize = uplInfo.totalSize;
342 }//end try
343 catch (IOException e) {
344 throw e;
345 }
346 }
347 return dataTable;
348 }
349
350 /**
351 * Compares boundary string to byte array
352 */
353 private boolean compareBoundary(String boundary, byte ba[]) {
354 if (boundary == null || ba == null) return false;
355 for (int i = 0; i < boundary.length(); i++)
356 if ((byte) boundary.charAt(i) != ba[i]) return false;
357 return true;
358 }
359
360 /** Convenience method to read HTTP header lines */
361 private synchronized String getLine(ServletInputStream sis) throws IOException {
362 byte b[] = new byte[1024];
363 int read = sis.readLine(b, 0, b.length), index;
364 String line = null;
365 if (read != -1) {
366 line = new String(b, 0, read);
367 if ((index = line.indexOf('\n')) >= 0) line = line.substring(0, index - 1);
368 }
369 return line;
370 }
371
372 public String getFileName(String dir, String fileName) throws IllegalArgumentException {
373 String path = null;
374 if (dir == null || fileName == null) throw new IllegalArgumentException(
375 "dir or fileName is null");
376 int index = fileName.lastIndexOf('/');
377 String name = null;
378 if (index >= 0) name = fileName.substring(index + 1);
379 else name = fileName;
380 index = name.lastIndexOf('\\');
381 if (index >= 0) fileName = name.substring(index + 1);
382 path = dir + File.separator + fileName;
383 if (File.separatorChar == '/') return path.replace('\\', File.separatorChar);
384 else return path.replace('/', File.separatorChar);
385 }
386 } //End of class HttpMultiPartParser
387
388 /**
389 * This class is a comparator to sort the filenames and dirs
390 */
391 class FileComp implements Comparator {
392
393 int mode;
394 int sign;
395
396 FileComp() {
397 this.mode = 1;
398 this.sign = 1;
399 }
400
401 /**
402 * @param mode sort by 1=Filename, 2=Size, 3=Date, 4=Type
403 * The default sorting method is by Name
404 * Negative mode means descending sort
405 */
406 FileComp(int mode) {
407 if (mode < 0) {
408 this.mode = -mode;
409 sign = -1;
410 }
411 else {
412 this.mode = mode;
413 this.sign = 1;
414 }
415 }
416
417 public int compare(Object o1, Object o2) {
418 File f1 = (File) o1;
419 File f2 = (File) o2;
420 if (f1.isDirectory()) {
421 if (f2.isDirectory()) {
422 switch (mode) {
423 //Filename or Type
424 case 1:
425 case 4:
426 return sign
427 * f1.getAbsolutePath().toUpperCase().compareTo(
428 f2.getAbsolutePath().toUpperCase());
429 //Filesize
430 case 2:
431 return sign * (new Long(f1.length()).compareTo(new Long(f2.length())));
432 //Date
433 case 3:
434 return sign
435 * (new Long(f1.lastModified())
436 .compareTo(new Long(f2.lastModified())));
437 default:
438 return 1;
439 }
440 }
441 else return -1;
442 }
443 else if (f2.isDirectory()) return 1;
444 else {
445 switch (mode) {
446 case 1:
447 return sign
448 * f1.getAbsolutePath().toUpperCase().compareTo(
449 f2.getAbsolutePath().toUpperCase());
450 case 2:
451 return sign * (new Long(f1.length()).compareTo(new Long(f2.length())));
452 case 3:
453 return sign
454 * (new Long(f1.lastModified()).compareTo(new Long(f2.lastModified())));
455 case 4: { // Sort by extension
456 int tempIndexf1 = f1.getAbsolutePath().lastIndexOf('.');
457 int tempIndexf2 = f2.getAbsolutePath().lastIndexOf('.');
458 if ((tempIndexf1 == -1) && (tempIndexf2 == -1)) { // Neither have an extension
459 return sign
460 * f1.getAbsolutePath().toUpperCase().compareTo(
461 f2.getAbsolutePath().toUpperCase());
462 }
463 // f1 has no extension
464 else if (tempIndexf1 == -1) return -sign;
465 // f2 has no extension
466 else if (tempIndexf2 == -1) return sign;
467 // Both have an extension
468 else {
469 String tempEndf1 = f1.getAbsolutePath().toUpperCase()
470 .substring(tempIndexf1);
471 String tempEndf2 = f2.getAbsolutePath().toUpperCase()
472 .substring(tempIndexf2);
473 return sign * tempEndf1.compareTo(tempEndf2);
474 }
475 }
476 default:
477 return 1;
478 }
479 }
480 }
481 }
482
483 /**
484 * Wrapperclass to wrap an OutputStream around a Writer
485 */
486 class Writer2Stream extends OutputStream {
487
488 Writer out;
489
490 Writer2Stream(Writer w) {
491 super();
492 out = w;
493 }
494
495 public void write(int i) throws IOException {
496 out.write(i);
497 }
498
499 public void write(byte[] b) throws IOException {
500 for (int i = 0; i < b.length; i++) {
501 int n = b[i];
502 //Convert byte to ubyte
503 n = ((n >>> 4) & 0xF) * 16 + (n & 0xF);
504 out.write(n);
505 }
506 }
507
508 public void write(byte[] b, int off, int len) throws IOException {
509 for (int i = off; i < off + len; i++) {
510 int n = b[i];
511 n = ((n >>> 4) & 0xF) * 16 + (n & 0xF);
512 out.write(n);
513 }
514 }
515 } //End of class Writer2Stream
516
517 static Vector expandFileList(String[] files, boolean inclDirs) {
518 Vector v = new Vector();
519 if (files == null) return v;
520 for (int i = 0; i < files.length; i++)
521 v.add(new File(URLDecoder.decode(files[i])));
522 for (int i = 0; i < v.size(); i++) {
523 File f = (File) v.get(i);
524 if (f.isDirectory()) {
525 File[] fs = f.listFiles();
526 for (int n = 0; n < fs.length; n++)
527 v.add(fs[n]);
528 if (!inclDirs) {
529 v.remove(i);
530 i--;
531 }
532 }
533 }
534 return v;
535 }
536
537 /**
538 * Method to build an absolute path
539 * @param dir the root dir
540 * @param name the name of the new directory
541 * @return if name is an absolute directory, returns name, else returns dir+name
542 */
543 static String getDir(String dir, String name) {
544 if (!dir.endsWith(File.separator)) dir = dir + File.separator;
545 File mv = new File(name);
546 String new_dir = null;
547 if (!mv.isAbsolute()) {
548 new_dir = dir + name;
549 }
550 else new_dir = name;
551 return new_dir;
552 }
553
554 /**
555 * This Method converts a byte size in a kbytes or Mbytes size, depending on the size
556 * @param size The size in bytes
557 * @return String with size and unit
558 */
559 static String convertFileSize(long size) {
560 int divisor = 1;
561 String unit = "bytes";
562 if (size >= 1024 * 1024) {
563 divisor = 1024 * 1024;
564 unit = "MB";
565 }
566 else if (size >= 1024) {
567 divisor = 1024;
568 unit = "KB";
569 }
570 if (divisor == 1) return size / divisor + " " + unit;
571 String aftercomma = "" + 100 * (size % divisor) / divisor;
572 if (aftercomma.length() == 1) aftercomma = "0" + aftercomma;
573 return size / divisor + "." + aftercomma + " " + unit;
574 }
575
576 /**
577 * Copies all data from in to out
578 * @param in the input stream
579 * @param out the output stream
580 * @param buffer copy buffer
581 */
582 static void copyStreams(InputStream in, OutputStream out, byte[] buffer) throws IOException {
583 copyStreamsWithoutClose(in, out, buffer);
584 in.close();
585 out.close();
586 }
587
588 /**
589 * Copies all data from in to out
590 * @param in the input stream
591 * @param out the output stream
592 * @param buffer copy buffer
593 */
594 static void copyStreamsWithoutClose(InputStream in, OutputStream out, byte[] buffer)
595 throws IOException {
596 int b;
597 while ((b = in.read(buffer)) != -1)
598 out.write(buffer, 0, b);
599 }
600
601 /**
602 * Returns the Mime Type of the file, depending on the extension of the filename
603 */
604 static String getMimeType(String fName) {
605 fName = fName.toLowerCase();
606 if (fName.endsWith(".jpg") || fName.endsWith(".jpeg") || fName.endsWith(".jpe")) return "image/jpeg";
607 else if (fName.endsWith(".gif")) return "image/gif";
608 else if (fName.endsWith(".pdf")) return "application/pdf";
609 else if (fName.endsWith(".htm") || fName.endsWith(".html") || fName.endsWith(".shtml")) return "text/html";
610 else if (fName.endsWith(".avi")) return "video/x-msvideo";
611 else if (fName.endsWith(".mov") || fName.endsWith(".qt")) return "video/quicktime";
612 else if (fName.endsWith(".mpg") || fName.endsWith(".mpeg") || fName.endsWith(".mpe")) return "video/mpeg";
613 else if (fName.endsWith(".zip")) return "application/zip";
614 else if (fName.endsWith(".tiff") || fName.endsWith(".tif")) return "image/tiff";
615 else if (fName.endsWith(".rtf")) return "application/rtf";
616 else if (fName.endsWith(".mid") || fName.endsWith(".midi")) return "audio/x-midi";
617 else if (fName.endsWith(".xl") || fName.endsWith(".xls") || fName.endsWith(".xlv")
618 || fName.endsWith(".xla") || fName.endsWith(".xlb") || fName.endsWith(".xlt")
619 || fName.endsWith(".xlm") || fName.endsWith(".xlk")) return "application/excel";
620 else if (fName.endsWith(".doc") || fName.endsWith(".dot")) return "application/msword";
621 else if (fName.endsWith(".png")) return "image/png";
622 else if (fName.endsWith(".xml")) return "text/xml";
623 else if (fName.endsWith(".svg")) return "image/svg+xml";
624 else if (fName.endsWith(".mp3")) return "audio/mp3";
625 else if (fName.endsWith(".ogg")) return "audio/ogg";
626 else return "text/plain";
627 }
628
629 /**
630 * Converts some important chars (int) to the corresponding html string
631 */
632 static String conv2Html(int i) {
633 if (i == '&') return "&";
634 else if (i == '<') return "<";
635 else if (i == '>') return ">";
636 else if (i == '"') return """;
637 else return "" + (char) i;
638 }
639
640 /**
641 * Converts a normal string to a html conform string
642 */
643 static String conv2Html(String st) {
644 StringBuffer buf = new StringBuffer();
645 for (int i = 0; i < st.length(); i++) {
646 buf.append(conv2Html(st.charAt(i)));
647 }
648 return buf.toString();
649 }
650
651 /**
652 * Starts a native process on the server
653 * @param command the command to start the process
654 * @param dir the dir in which the process starts
655 */
656 static String startProcess(String command, String dir) throws IOException {
657 StringBuffer ret = new StringBuffer();
658 String[] comm = new String[3];
659 comm[0] = COMMAND_INTERPRETER[0];
660 comm[1] = COMMAND_INTERPRETER[1];
661 comm[2] = command;
662 long start = System.currentTimeMillis();
663 try {
664 //Start process
665 Process ls_proc = Runtime.getRuntime().exec(comm, null, new File(dir));
666 //Get input and error streams
667 BufferedInputStream ls_in = new BufferedInputStream(ls_proc.getInputStream());
668 BufferedInputStream ls_err = new BufferedInputStream(ls_proc.getErrorStream());
669 boolean end = false;
670 while (!end) {
671 int c = 0;
672 while ((ls_err.available() > 0) && (++c <= 1000)) {
673 ret.append(conv2Html(ls_err.read()));
674 }
675 c = 0;
676 while ((ls_in.available() > 0) && (++c <= 1000)) {
677 ret.append(conv2Html(ls_in.read()));
678 }
679 try {
680 ls_proc.exitValue();
681 //if the process has not finished, an exception is thrown
682 //else
683 while (ls_err.available() > 0)
684 ret.append(conv2Html(ls_err.read()));
685 while (ls_in.available() > 0)
686 ret.append(conv2Html(ls_in.read()));
687 end = true;
688 }
689 catch (IllegalThreadStateException ex) {
690 //Process is running
691 }
692 //The process is not allowed to run longer than given time.
693 if (System.currentTimeMillis() - start > MAX_PROCESS_RUNNING_TIME) {
694 ls_proc.destroy();
695 end = true;
696 ret.append("!!!! Process has timed out, destroyed !!!!!");
697 }
698 try {
699 Thread.sleep(50);
700 }
701 catch (InterruptedException ie) {}
702 }
703 }
704 catch (IOException e) {
705 ret.append("Error: " + e);
706 }
707 return ret.toString();
708 }
709
710 /**
711 * Converts a dir string to a linked dir string
712 * @param dir the directory string (e.g. /usr/local/httpd)
713 * @param browserLink web-path to Browser.jsp
714 */
715 static String dir2linkdir(String dir, String browserLink, int sortMode) {
716 File f = new File(dir);
717 StringBuffer buf = new StringBuffer();
718 while (f.getParentFile() != null) {
719 if (f.canRead()) {
720 String encPath = URLEncoder.encode(f.getAbsolutePath());
721 buf.insert(0, "<a href=\"" + browserLink + "?sort=" + sortMode + "&dir="
722 + encPath + "\">" + conv2Html(f.getName()) + File.separator + "</a>");
723 }
724 else buf.insert(0, conv2Html(f.getName()) + File.separator);
725 f = f.getParentFile();
726 }
727 if (f.canRead()) {
728 String encPath = URLEncoder.encode(f.getAbsolutePath());
729 buf.insert(0, "<a href=\"" + browserLink + "?sort=" + sortMode + "&dir=" + encPath
730 + "\">" + conv2Html(f.getAbsolutePath()) + "</a>");
731 }
732 else buf.insert(0, f.getAbsolutePath());
733 return buf.toString();
734 }
735
736 /**
737 * Returns true if the given filename tends towards a packed file
738 */
739 static boolean isPacked(String name, boolean gz) {
740 return (name.toLowerCase().endsWith(".zip") || name.toLowerCase().endsWith(".jar")
741 || (gz && name.toLowerCase().endsWith(".gz")) || name.toLowerCase()
742 .endsWith(".war"));
743 }
744
745 /**
746 * If RESTRICT_BROWSING = true this method checks, whether the path is allowed or not
747 */
748 static boolean isAllowed(File path, boolean write) throws IOException{
749 if (READ_ONLY && write) return false;
750 if (RESTRICT_BROWSING) {
751 StringTokenizer stk = new StringTokenizer(RESTRICT_PATH, ";");
752 while (stk.hasMoreTokens()){
753 if (path!=null && path.getCanonicalPath().startsWith(stk.nextToken()))
754 return RESTRICT_WHITELIST;
755 }
756 return !RESTRICT_WHITELIST;
757 }
758 else return true;
759 }
760
761 //---------------------------------------------------------------------------------------------------------------
762
763 %>
764<%
765 //Get the current browsing directory
766 request.setAttribute("dir", request.getParameter("dir"));
767 // The browser_name variable is used to keep track of the URI
768 // of the jsp file itself. It is used in all link-backs.
769 final String browser_name = request.getRequestURI();
770 final String FOL_IMG = "";
771 boolean nohtml = false;
772 boolean dir_view = true;
773 //Get Javascript
774 if (request.getParameter("Javascript") != null) {
775 dir_view = false;
776 nohtml = true;
777 //Tell the browser that it should cache the javascript
778 response.setHeader("Cache-Control", "public");
779 Date now = new Date();
780 SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z", Locale.US);
781 response.setHeader("Expires", sdf.format(new Date(now.getTime() + 1000 * 60 * 60 * 24*2)));
782 response.setHeader("Content-Type", "text/javascript");
783 %>
784 <%// This section contains the Javascript used for interface elements %>
785 var check = false;
786 <%// Disables the checkbox feature %>
787 function dis(){check = true;}
788
789 var DOM = 0, MS = 0, OP = 0, b = 0;
790 <%// Determine the browser type %>
791 function CheckBrowser(){
792 if (b == 0){
793 if (window.opera) OP = 1;
794 // Moz or Netscape
795 if(document.getElementById) DOM = 1;
796 // Micro$oft
797 if(document.all && !OP) MS = 1;
798 b = 1;
799 }
800 }
801 <%// Allows the whole row to be selected %>
802 function selrow (element, i){
803 var erst;
804 CheckBrowser();
805 if ((OP==1)||(MS==1)) erst = element.firstChild.firstChild;
806 else if (DOM==1) erst = element.firstChild.nextSibling.firstChild;
807 <%// MouseIn %>
808 if (i==0){
809 if (erst.checked == true) element.className='mousechecked';
810 else element.className='mousein';
811 }
812 <%// MouseOut %>
813 else if (i==1){
814 if (erst.checked == true) element.className='checked';
815 else element.className='mouseout';
816 }
817 <% // MouseClick %>
818 else if ((i==2)&&(!check)){
819 if (erst.checked==true) element.className='mousein';
820 else element.className='mousechecked';
821 erst.click();
822 }
823 else check=false;
824 }
825 <%// Filter files and dirs in FileList%>
826 function filter (begriff){
827 var suche = begriff.value.toLowerCase();
828 var table = document.getElementById("filetable");
829 var ele;
830 for (var r = 1; r < table.rows.length; r++){
831 ele = table.rows[r].cells[1].innerHTML.replace(/<[^>]+>/g,"");
832 if (ele.toLowerCase().indexOf(suche)>=0 )
833 table.rows[r].style.display = '';
834 else table.rows[r].style.display = 'none';
835 }
836 }
837 <%//(De)select all checkboxes%>
838 function AllFiles(){
839 for(var x=0;x < document.FileList.elements.length;x++){
840 var y = document.FileList.elements[x];
841 var ytr = y.parentNode.parentNode;
842 var check = document.FileList.selall.checked;
843 if(y.name == 'selfile' && ytr.style.display != 'none'){
844 if (y.disabled != true){
845 y.checked = check;
846 if (y.checked == true) ytr.className = 'checked';
847 else ytr.className = 'mouseout';
848 }
849 }
850 }
851 }
852
853 function shortKeyHandler(_event){
854 if (!_event) _event = window.event;
855 if (_event.which) {
856 keycode = _event.which;
857 } else if (_event.keyCode) {
858 keycode = _event.keyCode;
859 }
860 var t = document.getElementById("text_Dir");
861 //z
862 if (keycode == 122){
863 document.getElementById("but_Zip").click();
864 }
865 //r, F2
866 else if (keycode == 113 || keycode == 114){
867 var path = prompt("Please enter new filename", "");
868 if (path == null) return;
869 t.value = path;
870 document.getElementById("but_Ren").click();
871 }
872 //c
873 else if (keycode == 99){
874 var path = prompt("Please enter filename", "");
875 if (path == null) return;
876 t.value = path;
877 document.getElementById("but_NFi").click();
878 }
879 //d
880 else if (keycode == 100){
881 var path = prompt("Please enter directory name", "");
882 if (path == null) return;
883 t.value = path;
884 document.getElementById("but_NDi").click();
885 }
886 //m
887 else if (keycode == 109){
888 var path = prompt("Please enter move destination", "");
889 if (path == null) return;
890 t.value = path;
891 document.getElementById("but_Mov").click();
892 }
893 //y
894 else if (keycode == 121){
895 var path = prompt("Please enter copy destination", "");
896 if (path == null) return;
897 t.value = path;
898 document.getElementById("but_Cop").click();
899 }
900 //l
901 else if (keycode == 108){
902 document.getElementById("but_Lau").click();
903 }
904 //Del
905 else if (keycode == 46){
906 document.getElementById("but_Del").click();
907 }
908 }
909
910 function popUp(URL){
911 fname = document.getElementsByName("myFile")[0].value;
912 if (fname != "")
913 window.open(URL+"?first&uplMonitor="+encodeURIComponent(fname),"","width=400,height=150,resizable=yes,depend=yes")
914 }
915
916 document.onkeypress = shortKeyHandler;
917<% }
918 // View file
919 else if (request.getParameter("file") != null) {
920 File f = new File(request.getParameter("file"));
921 if (!isAllowed(f, false)) {
922 request.setAttribute("dir", f.getParent());
923 request.setAttribute("error", "You are not allowed to access "+f.getAbsolutePath());
924 }
925 else if (f.exists() && f.canRead()) {
926 if (isPacked(f.getName(), false)) {
927 //If zipFile, do nothing here
928 }
929 else{
930 String mimeType = getMimeType(f.getName());
931 response.setContentType(mimeType);
932 if (mimeType.equals("text/plain")) response.setHeader(
933 "Content-Disposition", "inline;filename=\"temp.txt\"");
934 else response.setHeader("Content-Disposition", "inline;filename=\""
935 + f.getName() + "\"");
936 BufferedInputStream fileInput = new BufferedInputStream(new FileInputStream(f));
937 byte buffer[] = new byte[8 * 1024];
938 out.clearBuffer();
939 OutputStream out_s = new Writer2Stream(out);
940 copyStreamsWithoutClose(fileInput, out_s, buffer);
941 fileInput.close();
942 out_s.flush();
943 nohtml = true;
944 dir_view = false;
945 }
946 }
947 else {
948 request.setAttribute("dir", f.getParent());
949 request.setAttribute("error", "File " + f.getAbsolutePath()
950 + " does not exist or is not readable on the server");
951 }
952 }
953 // Download selected files as zip file
954 else if ((request.getParameter("Submit") != null)
955 && (request.getParameter("Submit").equals(SAVE_AS_ZIP))) {
956 Vector v = expandFileList(request.getParameterValues("selfile"), false);
957 //Check if all files in vector are allowed
958 String notAllowedFile = null;
959 for (int i = 0;i < v.size(); i++){
960 File f = (File) v.get(i);
961 if (!isAllowed(f, false)){
962 notAllowedFile = f.getAbsolutePath();
963 break;
964 }
965 }
966 if (notAllowedFile != null){
967 request.setAttribute("error", "You are not allowed to access " + notAllowedFile);
968 }
969 else if (v.size() == 0) {
970 request.setAttribute("error", "No files selected");
971 }
972 else {
973 File dir_file = new File("" + request.getAttribute("dir"));
974 int dir_l = dir_file.getAbsolutePath().length();
975 response.setContentType("application/zip");
976 response.setHeader("Content-Disposition", "attachment;filename=\"rename_me.zip\"");
977 out.clearBuffer();
978 ZipOutputStream zipout = new ZipOutputStream(new Writer2Stream(out));
979 zipout.setComment("Created by jsp File Browser v. " + VERSION_NR);
980 zipout.setLevel(COMPRESSION_LEVEL);
981 for (int i = 0; i < v.size(); i++) {
982 File f = (File) v.get(i);
983 if (f.canRead()) {
984 zipout.putNextEntry(new ZipEntry(f.getAbsolutePath().substring(dir_l + 1)));
985 BufferedInputStream fr = new BufferedInputStream(new FileInputStream(f));
986 byte buffer[] = new byte[0xffff];
987 copyStreamsWithoutClose(fr, zipout, buffer);
988 /* int b;
989 while ((b=fr.read())!=-1) zipout.write(b);*/
990 fr.close();
991 zipout.closeEntry();
992 }
993 }
994 zipout.finish();
995 out.flush();
996 nohtml = true;
997 dir_view = false;
998 }
999 }
1000 // Download file
1001 else if (request.getParameter("downfile") != null) {
1002 String filePath = request.getParameter("downfile");
1003 File f = new File(filePath);
1004 if (!isAllowed(f, false)){
1005 request.setAttribute("dir", f.getParent());
1006 request.setAttribute("error", "You are not allowed to access " + f.getAbsoluteFile());
1007 }
1008 else if (f.exists() && f.canRead()) {
1009 response.setContentType("application/octet-stream");
1010 response.setHeader("Content-Disposition", "attachment;filename=\"" + f.getName()
1011 + "\"");
1012 response.setContentLength((int) f.length());
1013 BufferedInputStream fileInput = new BufferedInputStream(new FileInputStream(f));
1014 byte buffer[] = new byte[8 * 1024];
1015 out.clearBuffer();
1016 OutputStream out_s = new Writer2Stream(out);
1017 copyStreamsWithoutClose(fileInput, out_s, buffer);
1018 fileInput.close();
1019 out_s.flush();
1020 nohtml = true;
1021 dir_view = false;
1022 }
1023 else {
1024 request.setAttribute("dir", f.getParent());
1025 request.setAttribute("error", "File " + f.getAbsolutePath()
1026 + " does not exist or is not readable on the server");
1027 }
1028 }
1029 if (nohtml) return;
1030 //else
1031 // If no parameter is submitted, it will take the path from jsp file browser
1032 if (request.getAttribute("dir") == null) {
1033 String path = null;
1034 if (application.getRealPath(request.getRequestURI()) != null) {
1035 File f = new File(application.getRealPath(request.getRequestURI())).getParentFile();
1036 //This is a hack needed for tomcat
1037 while (f != null && !f.exists())
1038 f = f.getParentFile();
1039 if (f != null)
1040 path = f.getAbsolutePath();
1041 }
1042 if (path == null) { // handle the case where we are not in a directory (ex: war file)
1043 path = new File(".").getAbsolutePath();
1044 }
1045 //Check path
1046 if (!isAllowed(new File(path), false)){
1047 //TODO Blacklist
1048 if (RESTRICT_PATH.indexOf(";")<0) path = RESTRICT_PATH;
1049 else path = RESTRICT_PATH.substring(0, RESTRICT_PATH.indexOf(";"));
1050 }
1051 request.setAttribute("dir", path);
1052 }%>
1053<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
1054"http://www.w3.org/TR/html4/loose.dtd">
1055<html>
1056<head>
1057<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
1058<meta name="robots" content="noindex">
1059<meta http-equiv="expires" content="0">
1060<meta http-equiv="pragma" content="no-cache">
1061<%
1062 //If a cssfile exists, it will take it
1063 String cssPath = null;
1064 if (application.getRealPath(request.getRequestURI()) != null) cssPath = new File(
1065 application.getRealPath(request.getRequestURI())).getParent()
1066 + File.separator + CSS_NAME;
1067 if (cssPath == null) cssPath = application.getResource(CSS_NAME).toString();
1068 if (new File(cssPath).exists()) {
1069%>
1070<link rel="stylesheet" type="text/css" href="<%=CSS_NAME%>">
1071 <%}
1072 else if (request.getParameter("uplMonitor") == null) {%>
1073 <style type="text/css">
1074 input.button {background-color: #c0c0c0; color: #666666;
1075 border: 1px solid #999999; margin: 5px 1px 5px 1px;}
1076 input.textfield {margin: 5px 1px 5px 1px;}
1077 input.button:Hover { color: #444444 }
1078 table.filelist {background-color:#666666; width:100%; border:0px none #ffffff}
1079 .formular {margin: 1px; background-color:#ffffff; padding: 1em; border:1px solid #000000;}
1080 .formular2 {margin: 1px;}
1081 th { background-color:#c0c0c0 }
1082 tr.mouseout { background-color:#ffffff; }
1083 tr.mousein { background-color:#eeeeee; }
1084 tr.checked { background-color:#cccccc }
1085 tr.mousechecked { background-color:#c0c0c0 }
1086 td { font-family:Verdana, Arial, Helvetica, sans-serif; font-size: 8pt; color: #666666;}
1087 td.message { background-color: #FFFF00; color: #000000; text-align:center; font-weight:bold}
1088 td.error { background-color: #FF0000; color: #000000; text-align:center; font-weight:bold}
1089 A { text-decoration: none; }
1090 A:Hover { color : Red; text-decoration : underline; }
1091 BODY { font-family:Verdana, Arial, Helvetica, sans-serif; font-size: 8pt; color: #666666;}
1092 </style>
1093 <%}
1094
1095 //Check path
1096 if (!isAllowed(new File((String)request.getAttribute("dir")), false)){
1097 request.setAttribute("error", "You are not allowed to access " + request.getAttribute("dir"));
1098 }
1099 //Upload monitor
1100 else if (request.getParameter("uplMonitor") != null) {%>
1101 <style type="text/css">
1102 BODY { font-family:Verdana, Arial, Helvetica, sans-serif; font-size: 8pt; color: #666666;}
1103 </style><%
1104 String fname = request.getParameter("uplMonitor");
1105 //First opening
1106 boolean first = false;
1107 if (request.getParameter("first") != null) first = true;
1108 UplInfo info = new UplInfo();
1109 if (!first) {
1110 info = UploadMonitor.getInfo(fname);
1111 if (info == null) {
1112 //Windows
1113 int posi = fname.lastIndexOf("\\");
1114 if (posi != -1) info = UploadMonitor.getInfo(fname.substring(posi + 1));
1115 }
1116 if (info == null) {
1117 //Unix
1118 int posi = fname.lastIndexOf("/");
1119 if (posi != -1) info = UploadMonitor.getInfo(fname.substring(posi + 1));
1120 }
1121 }
1122 dir_view = false;
1123 request.setAttribute("dir", null);
1124 if (info.aborted) {
1125 UploadMonitor.remove(fname);
1126 %>
1127</head>
1128<body>
1129<b>Upload of <%=fname%></b><br><br>
1130Upload aborted.</body>
1131</html><%
1132 }
1133 else if (info.totalSize != info.currSize || info.currSize == 0) {
1134 %>
1135<META HTTP-EQUIV="Refresh" CONTENT="<%=UPLOAD_MONITOR_REFRESH%>;URL=<%=browser_name %>?uplMonitor=<%=URLEncoder.encode(fname)%>">
1136</head>
1137<body>
1138<b>Upload of <%=fname%></b><br><br>
1139<center>
1140<table height="20px" width="90%" bgcolor="#eeeeee" style="border:1px solid #cccccc"><tr>
1141<td bgcolor="blue" width="<%=info.getPercent()%>%"></td><td width="<%=100-info.getPercent()%>%"></td>
1142</tr></table></center>
1143<%=convertFileSize(info.currSize)%> from <%=convertFileSize(info.totalSize)%>
1144(<%=info.getPercent()%> %) uploaded (Speed: <%=info.getUprate()%>).<br>
1145Time: <%=info.getTimeElapsed()%> from <%=info.getTimeEstimated()%>
1146</body>
1147</html><%
1148 }
1149 else {
1150 UploadMonitor.remove(fname);
1151 %>
1152</head>
1153<body onload="javascript:window.close()">
1154<b>Upload of <%=fname%></b><br><br>
1155Upload finished.
1156</body>
1157</html><%
1158 }
1159 }
1160 //Comandwindow
1161 else if (request.getParameter("command") != null) {
1162 if (!NATIVE_COMMANDS){
1163 request.setAttribute("error", "Execution of native commands is not allowed!");
1164 }
1165 else if (!"Cancel".equalsIgnoreCase(request.getParameter("Submit"))) {
1166%>
1167<title>Launch commands in <%=request.getAttribute("dir")%></title>
1168</head>
1169<body><center>
1170<h2><%=LAUNCH_COMMAND %></h2><br />
1171<%
1172 out.println("<form action=\"" + browser_name + "\" method=\"Post\">\n"
1173 + "<textarea name=\"text\" wrap=\"off\" cols=\"" + EDITFIELD_COLS
1174 + "\" rows=\"" + EDITFIELD_ROWS + "\" readonly>");
1175 String ret = "";
1176 if (!request.getParameter("command").equalsIgnoreCase(""))
1177 ret = startProcess(
1178 request.getParameter("command"), (String) request.getAttribute("dir"));
1179 out.println(ret);
1180%></textarea>
1181 <input type="hidden" name="dir" value="<%= request.getAttribute("dir")%>">
1182 <br /><br />
1183 <table class="formular">
1184 <tr><td title="Enter your command">
1185 Command: <input size="<%=EDITFIELD_COLS-5%>" type="text" name="command" value="">
1186 </td></tr>
1187 <tr><td><input class="button" type="Submit" name="Submit" value="Launch">
1188 <input type="hidden" name="sort" value="<%=request.getParameter("sort")%>">
1189 <input type="Submit" class="button" name="Submit" value="Cancel"></td></tr>
1190 </table>
1191 </form>
1192 <br />
1193 <hr>
1194 <center>
1195 <small>jsp File Browser version <%= VERSION_NR%> by <a href="http://www.vonloesch.de">www.vonloesch.de</a></small>
1196 </center>
1197 </center>
1198</body>
1199</html>
1200<%
1201 dir_view = false;
1202 request.setAttribute("dir", null);
1203 }
1204 }
1205
1206 //Click on a filename, special viewer (zip+jar file)
1207 else if (request.getParameter("file") != null) {
1208 File f = new File(request.getParameter("file"));
1209 if (!isAllowed(f, false)){
1210 request.setAttribute("error", "You are not allowed to access " + f.getAbsolutePath());
1211 }
1212 else if (isPacked(f.getName(), false)) {
1213 //ZipFile
1214 try {
1215 ZipFile zf = new ZipFile(f);
1216 Enumeration entries = zf.entries();
1217%>
1218<title><%= f.getAbsolutePath()%></title>
1219</head>
1220<body>
1221 <h2>Content of <%=conv2Html(f.getName())%></h2><br />
1222 <table class="filelist" cellspacing="1px" cellpadding="0px">
1223 <th>Name</th><th>Uncompressed size</th><th>Compressed size</th><th>Compr. ratio</th><th>Date</th>
1224<%
1225 long size = 0;
1226 int fileCount = 0;
1227 while (entries.hasMoreElements()) {
1228 ZipEntry entry = (ZipEntry) entries.nextElement();
1229 if (!entry.isDirectory()) {
1230 fileCount++;
1231 size += entry.getSize();
1232 long ratio = 0;
1233 if (entry.getSize() != 0) ratio = (entry.getCompressedSize() * 100)
1234 / entry.getSize();
1235 out.println("<tr class=\"mouseout\"><td>" + conv2Html(entry.getName())
1236 + "</td><td>" + convertFileSize(entry.getSize()) + "</td><td>"
1237 + convertFileSize(entry.getCompressedSize()) + "</td><td>"
1238 + ratio + "%" + "</td><td>"
1239 + dateFormat.format(new Date(entry.getTime())) + "</td></tr>");
1240
1241 }
1242 }
1243 zf.close();
1244 //No directory view
1245 dir_view = false;
1246 request.setAttribute("dir", null);
1247%>
1248 </table>
1249 <p align=center>
1250 <b><%=convertFileSize(size)%> in <%=fileCount%> files in <%=f.getName()%>. Compression ratio: <%=(f.length() * 100) / size%>%
1251 </b></p>
1252</body></html>
1253<%
1254 }
1255 catch (ZipException ex) {
1256 request.setAttribute("error", "Cannot read " + f.getName()
1257 + ", no valid zip file");
1258 }
1259 catch (IOException ex) {
1260 request.setAttribute("error", "Reading of " + f.getName() + " aborted. Error: "
1261 + ex);
1262 }
1263 }
1264 }
1265 // Upload
1266 else if ((request.getContentType() != null)
1267 && (request.getContentType().toLowerCase().startsWith("multipart"))) {
1268 if (!ALLOW_UPLOAD){
1269 request.setAttribute("error", "Upload is forbidden!");
1270 }
1271 response.setContentType("text/html");
1272 HttpMultiPartParser parser = new HttpMultiPartParser();
1273 boolean error = false;
1274 try {
1275 int bstart = request.getContentType().lastIndexOf("oundary=");
1276 String bound = request.getContentType().substring(bstart + 8);
1277 int clength = request.getContentLength();
1278 Hashtable ht = parser
1279 .processData(request.getInputStream(), bound, tempdir, clength);
1280 if (!isAllowed(new File((String)ht.get("dir")), false)){
1281 //This is a hack, cos we are writing to this directory
1282 request.setAttribute("error", "You are not allowed to access " + ht.get("dir"));
1283 error = true;
1284 }
1285 else if (ht.get("myFile") != null) {
1286 FileInfo fi = (FileInfo) ht.get("myFile");
1287 File f = fi.file;
1288 UplInfo info = UploadMonitor.getInfo(fi.clientFileName);
1289 if (info != null && info.aborted) {
1290 f.delete();
1291 request.setAttribute("error", "Upload aborted");
1292 }
1293 else {
1294 // Move file from temp to the right dir
1295 String path = (String) ht.get("dir");
1296 if (!path.endsWith(File.separator)) path = path + File.separator;
1297 if (!f.renameTo(new File(path + f.getName()))) {
1298 request.setAttribute("error", "Cannot upload file.");
1299 error = true;
1300 f.delete();
1301 }
1302 }
1303 }
1304 else {
1305 request.setAttribute("error", "No file selected for upload");
1306 error = true;
1307 }
1308 request.setAttribute("dir", (String) ht.get("dir"));
1309 }
1310 catch (Exception e) {
1311 request.setAttribute("error", "Error " + e + ". Upload aborted");
1312 error = true;
1313 }
1314 if (!error) request.setAttribute("message", "File upload correctly finished.");
1315 }
1316 // The form to edit a text file
1317 else if (request.getParameter("editfile") != null) {
1318 File ef = new File(request.getParameter("editfile"));
1319 if (!isAllowed(ef, true)){
1320 request.setAttribute("error", "You are not allowed to access " + ef.getAbsolutePath());
1321 }
1322 else{
1323%>
1324<title>Edit <%=conv2Html(request.getParameter("editfile"))%></title>
1325</head>
1326<body>
1327<center>
1328<h2>Edit <%=conv2Html(request.getParameter("editfile"))%></h2><br />
1329<%
1330 BufferedReader reader = new BufferedReader(new FileReader(ef));
1331 String disable = "";
1332 if (!ef.canWrite()) disable = " readonly";
1333 out.println("<form action=\"" + browser_name + "\" method=\"Post\">\n"
1334 + "<textarea name=\"text\" wrap=\"off\" cols=\"" + EDITFIELD_COLS
1335 + "\" rows=\"" + EDITFIELD_ROWS + "\"" + disable + ">");
1336 String c;
1337 // Write out the file and check if it is a win or unix file
1338 int i;
1339 boolean dos = false;
1340 boolean cr = false;
1341 while ((i = reader.read()) >= 0) {
1342 out.print(conv2Html(i));
1343 if (i == '\r') cr = true;
1344 else if (cr && (i == '\n')) dos = true;
1345 else cr = false;
1346 }
1347 reader.close();
1348 //No File directory is shown
1349 request.setAttribute("dir", null);
1350 dir_view = false;
1351
1352%></textarea><br /><br />
1353<table class="formular">
1354 <input type="hidden" name="nfile" value="<%= request.getParameter("editfile")%>">
1355 <input type="hidden" name="sort" value="<%=request.getParameter("sort")%>">
1356 <tr><td colspan="2"><input type="radio" name="lineformat" value="dos" <%= dos?"checked":""%>>Ms-Dos/Windows
1357 <input type="radio" name="lineformat" value="unix" <%= dos?"":"checked"%>>Unix
1358 <input type="checkbox" name="Backup" checked>Write backup</td></tr>
1359 <tr><td title="Enter the new filename"><input type="text" name="new_name" value="<%=ef.getName()%>">
1360 <input type="Submit" name="Submit" value="Save"></td>
1361 </form>
1362 <form action="<%=browser_name%>" method="Post">
1363 <td align="left">
1364 <input type="Submit" name="Submit" value="Cancel">
1365 <input type="hidden" name="nfile" value="<%= request.getParameter("editfile")%>">
1366 <input type="hidden" name="sort" value="<%=request.getParameter("sort")%>">
1367 </td>
1368 </form>
1369 </tr>
1370 </table>
1371 </center>
1372 <br />
1373 <hr>
1374 <center>
1375 <small>jsp File Browser version <%= VERSION_NR%> by <a href="http://www.vonloesch.de">www.vonloesch.de</a></small>
1376 </center>
1377</body>
1378</html>
1379<%
1380 }
1381 }
1382 // Save or cancel the edited file
1383 else if (request.getParameter("nfile") != null) {
1384 File f = new File(request.getParameter("nfile"));
1385 if (request.getParameter("Submit").equals("Save")) {
1386 File new_f = new File(getDir(f.getParent(), request.getParameter("new_name")));
1387 if (!isAllowed(new_f, true)){
1388 request.setAttribute("error", "You are not allowed to access " + new_f.getAbsolutePath());
1389 }
1390 if (new_f.exists() && new_f.canWrite() && request.getParameter("Backup") != null) {
1391 File bak = new File(new_f.getAbsolutePath() + ".bak");
1392 bak.delete();
1393 new_f.renameTo(bak);
1394 }
1395 if (new_f.exists() && !new_f.canWrite()) request.setAttribute("error",
1396 "Cannot write to " + new_f.getName() + ", file is write protected.");
1397 else {
1398 BufferedWriter outs = new BufferedWriter(new FileWriter(new_f));
1399 StringReader text = new StringReader(request.getParameter("text"));
1400 int i;
1401 boolean cr = false;
1402 String lineend = "\n";
1403 if (request.getParameter("lineformat").equals("dos")) lineend = "\r\n";
1404 while ((i = text.read()) >= 0) {
1405 if (i == '\r') cr = true;
1406 else if (i == '\n') {
1407 outs.write(lineend);
1408 cr = false;
1409 }
1410 else if (cr) {
1411 outs.write(lineend);
1412 cr = false;
1413 }
1414 else {
1415 outs.write(i);
1416 cr = false;
1417 }
1418 }
1419 outs.flush();
1420 outs.close();
1421 }
1422 }
1423 request.setAttribute("dir", f.getParent());
1424 }
1425 //Unpack file to the current directory without overwriting
1426 else if (request.getParameter("unpackfile") != null) {
1427 File f = new File(request.getParameter("unpackfile"));
1428 String root = f.getParent();
1429 request.setAttribute("dir", root);
1430 if (!isAllowed(new File(root), true)){
1431 request.setAttribute("error", "You are not allowed to access " + root);
1432 }
1433 //Check if file exists
1434 else if (!f.exists()) {
1435 request.setAttribute("error", "Cannot unpack " + f.getName()
1436 + ", file does not exist");
1437 }
1438 //Check if directory is readonly
1439 else if (!f.getParentFile().canWrite()) {
1440 request.setAttribute("error", "Cannot unpack " + f.getName()
1441 + ", directory is write protected.");
1442 }
1443 //GZip
1444 else if (f.getName().toLowerCase().endsWith(".gz")) {
1445 //New name is old Name without .gz
1446 String newName = f.getAbsolutePath().substring(0, f.getAbsolutePath().length() - 3);
1447 try {
1448 byte buffer[] = new byte[0xffff];
1449 copyStreams(new GZIPInputStream(new FileInputStream(f)), new FileOutputStream(
1450 newName), buffer);
1451 }
1452 catch (IOException ex) {
1453 request.setAttribute("error", "Unpacking of " + f.getName()
1454 + " aborted. Error: " + ex);
1455 }
1456 }
1457 //Else try Zip
1458 else {
1459 try {
1460 ZipFile zf = new ZipFile(f);
1461 Enumeration entries = zf.entries();
1462 //First check whether a file already exist
1463 boolean error = false;
1464 while (entries.hasMoreElements()) {
1465 ZipEntry entry = (ZipEntry) entries.nextElement();
1466 if (!entry.isDirectory()
1467 && new File(root + File.separator + entry.getName()).exists()) {
1468 request.setAttribute("error", "Cannot unpack " + f.getName()
1469 + ", File " + entry.getName() + " already exists.");
1470 error = true;
1471 break;
1472 }
1473 }
1474 if (!error) {
1475 //Unpack File
1476 entries = zf.entries();
1477 byte buffer[] = new byte[0xffff];
1478 while (entries.hasMoreElements()) {
1479 ZipEntry entry = (ZipEntry) entries.nextElement();
1480 File n = new File(root + File.separator + entry.getName());
1481 if (entry.isDirectory()) n.mkdirs();
1482 else {
1483 n.getParentFile().mkdirs();
1484 n.createNewFile();
1485 copyStreams(zf.getInputStream(entry), new FileOutputStream(n),
1486 buffer);
1487 }
1488 }
1489 zf.close();
1490 request.setAttribute("message", "Unpack of " + f.getName()
1491 + " was successful.");
1492 }
1493 }
1494 catch (ZipException ex) {
1495 request.setAttribute("error", "Cannot unpack " + f.getName()
1496 + ", no valid zip file");
1497 }
1498 catch (IOException ex) {
1499 request.setAttribute("error", "Unpacking of " + f.getName()
1500 + " aborted. Error: " + ex);
1501 }
1502 }
1503 }
1504 // Delete Files
1505 else if ((request.getParameter("Submit") != null)
1506 && (request.getParameter("Submit").equals(DELETE_FILES))) {
1507 Vector v = expandFileList(request.getParameterValues("selfile"), true);
1508 boolean error = false;
1509 //delete backwards
1510 for (int i = v.size() - 1; i >= 0; i--) {
1511 File f = (File) v.get(i);
1512 if (!isAllowed(f, true)){
1513 request.setAttribute("error", "You are not allowed to access " + f.getAbsolutePath());
1514 error = true;
1515 break;
1516 }
1517 if (!f.canWrite() || !f.delete()) {
1518 request.setAttribute("error", "Cannot delete " + f.getAbsolutePath()
1519 + ". Deletion aborted");
1520 error = true;
1521 break;
1522 }
1523 }
1524 if ((!error) && (v.size() > 1)) request.setAttribute("message", "All files deleted");
1525 else if ((!error) && (v.size() > 0)) request.setAttribute("message", "File deleted");
1526 else if (!error) request.setAttribute("error", "No files selected");
1527 }
1528 // Create Directory
1529 else if ((request.getParameter("Submit") != null)
1530 && (request.getParameter("Submit").equals(CREATE_DIR))) {
1531 String dir = "" + request.getAttribute("dir");
1532 String dir_name = request.getParameter("cr_dir");
1533 String new_dir = getDir(dir, dir_name);
1534 if (!isAllowed(new File(new_dir), true)){
1535 request.setAttribute("error", "You are not allowed to access " + new_dir);
1536 }
1537 else if (new File(new_dir).mkdirs()) {
1538 request.setAttribute("message", "Directory created");
1539 }
1540 else request.setAttribute("error", "Creation of directory " + new_dir + " failed");
1541 }
1542 // Create a new empty file
1543 else if ((request.getParameter("Submit") != null)
1544 && (request.getParameter("Submit").equals(CREATE_FILE))) {
1545 String dir = "" + request.getAttribute("dir");
1546 String file_name = request.getParameter("cr_dir");
1547 String new_file = getDir(dir, file_name);
1548 if (!isAllowed(new File(new_file), true)){
1549 request.setAttribute("error", "You are not allowed to access " + new_file);
1550 }
1551 // Test, if file_name is empty
1552 else if (!"".equals(file_name.trim()) && !file_name.endsWith(File.separator)) {
1553 if (new File(new_file).createNewFile()) request.setAttribute("message",
1554 "File created");
1555 else request.setAttribute("error", "Creation of file " + new_file + " failed");
1556 }
1557 else request.setAttribute("error", "Error: " + file_name + " is not a valid filename");
1558 }
1559 // Rename a file
1560 else if ((request.getParameter("Submit") != null)
1561 && (request.getParameter("Submit").equals(RENAME_FILE))) {
1562 Vector v = expandFileList(request.getParameterValues("selfile"), true);
1563 String dir = "" + request.getAttribute("dir");
1564 String new_file_name = request.getParameter("cr_dir");
1565 String new_file = getDir(dir, new_file_name);
1566 if (!isAllowed(new File(new_file), true)){
1567 request.setAttribute("error", "You are not allowed to access " + new_file);
1568 }
1569 // The error conditions:
1570 // 1) Zero Files selected
1571 else if (v.size() <= 0) request.setAttribute("error",
1572 "Select exactly one file or folder. Rename failed");
1573 // 2a) Multiple files selected and the first isn't a dir
1574 // Here we assume that expandFileList builds v from top-bottom, starting with the dirs
1575 else if ((v.size() > 1) && !(((File) v.get(0)).isDirectory())) request.setAttribute(
1576 "error", "Select exactly one file or folder. Rename failed");
1577 // 2b) If there are multiple files from the same directory, rename fails
1578 else if ((v.size() > 1) && ((File) v.get(0)).isDirectory()
1579 && !(((File) v.get(0)).getPath().equals(((File) v.get(1)).getParent()))) {
1580 request.setAttribute("error", "Select exactly one file or folder. Rename failed");
1581 }
1582 else {
1583 File f = (File) v.get(0);
1584 if (!isAllowed(f, true)){
1585 request.setAttribute("error", "You are not allowed to access " + f.getAbsolutePath());
1586 }
1587 // Test, if file_name is empty
1588 else if ((new_file.trim() != "") && !new_file.endsWith(File.separator)) {
1589 if (!f.canWrite() || !f.renameTo(new File(new_file.trim()))) {
1590 request.setAttribute("error", "Creation of file " + new_file + " failed");
1591 }
1592 else request.setAttribute("message", "Renamed file "
1593 + ((File) v.get(0)).getName() + " to " + new_file);
1594 }
1595 else request.setAttribute("error", "Error: \"" + new_file_name
1596 + "\" is not a valid filename");
1597 }
1598 }
1599 // Move selected file(s)
1600 else if ((request.getParameter("Submit") != null)
1601 && (request.getParameter("Submit").equals(MOVE_FILES))) {
1602 Vector v = expandFileList(request.getParameterValues("selfile"), true);
1603 String dir = "" + request.getAttribute("dir");
1604 String dir_name = request.getParameter("cr_dir");
1605 String new_dir = getDir(dir, dir_name);
1606 if (!isAllowed(new File(new_dir), false)){
1607 request.setAttribute("error", "You are not allowed to access " + new_dir);
1608 }
1609 else{
1610 boolean error = false;
1611 // This ensures that new_dir is a directory
1612 if (!new_dir.endsWith(File.separator)) new_dir += File.separator;
1613 for (int i = v.size() - 1; i >= 0; i--) {
1614 File f = (File) v.get(i);
1615 if (!isAllowed(f, true)){
1616 request.setAttribute("error", "You are not allowed to access " + f.getAbsolutePath());
1617 error = true;
1618 break;
1619 }
1620 else if (!f.canWrite() || !f.renameTo(new File(new_dir
1621 + f.getAbsolutePath().substring(dir.length())))) {
1622 request.setAttribute("error", "Cannot move " + f.getAbsolutePath()
1623 + ". Move aborted");
1624 error = true;
1625 break;
1626 }
1627 }
1628 if ((!error) && (v.size() > 1)) request.setAttribute("message", "All files moved");
1629 else if ((!error) && (v.size() > 0)) request.setAttribute("message", "File moved");
1630 else if (!error) request.setAttribute("error", "No files selected");
1631 }
1632 }
1633 // Copy Files
1634 else if ((request.getParameter("Submit") != null)
1635 && (request.getParameter("Submit").equals(COPY_FILES))) {
1636 Vector v = expandFileList(request.getParameterValues("selfile"), true);
1637 String dir = (String) request.getAttribute("dir");
1638 if (!dir.endsWith(File.separator)) dir += File.separator;
1639 String dir_name = request.getParameter("cr_dir");
1640 String new_dir = getDir(dir, dir_name);
1641 if (!isAllowed(new File(new_dir), true)){
1642 request.setAttribute("error", "You are not allowed to access " + new_dir);
1643 }
1644 else{
1645 boolean error = false;
1646 if (!new_dir.endsWith(File.separator)) new_dir += File.separator;
1647 try {
1648 byte buffer[] = new byte[0xffff];
1649 for (int i = 0; i < v.size(); i++) {
1650 File f_old = (File) v.get(i);
1651 File f_new = new File(new_dir + f_old.getAbsolutePath().substring(dir.length()));
1652 if (!isAllowed(f_old, false)|| !isAllowed(f_new, true)){
1653 request.setAttribute("error", "You are not allowed to access " + f_new.getAbsolutePath());
1654 error = true;
1655 }
1656 else if (f_old.isDirectory()) f_new.mkdirs();
1657 // Overwriting is forbidden
1658 else if (!f_new.exists()) {
1659 copyStreams(new FileInputStream(f_old), new FileOutputStream(f_new), buffer);
1660 }
1661 else {
1662 // File exists
1663 request.setAttribute("error", "Cannot copy " + f_old.getAbsolutePath()
1664 + ", file already exists. Copying aborted");
1665 error = true;
1666 break;
1667 }
1668 }
1669 }
1670 catch (IOException e) {
1671 request.setAttribute("error", "Error " + e + ". Copying aborted");
1672 error = true;
1673 }
1674 if ((!error) && (v.size() > 1)) request.setAttribute("message", "All files copied");
1675 else if ((!error) && (v.size() > 0)) request.setAttribute("message", "File copied");
1676 else if (!error) request.setAttribute("error", "No files selected");
1677 }
1678 }
1679 // Directory viewer
1680 if (dir_view && request.getAttribute("dir") != null) {
1681 File f = new File("" + request.getAttribute("dir"));
1682 //Check, whether the dir exists
1683 if (!f.exists() || !isAllowed(f, false)) {
1684 if (!f.exists()){
1685 request.setAttribute("error", "Directory " + f.getAbsolutePath() + " does not exist.");
1686 }
1687 else{
1688 request.setAttribute("error", "You are not allowed to access " + f.getAbsolutePath());
1689 }
1690 //if attribute olddir exists, it will change to olddir
1691 if (request.getAttribute("olddir") != null && isAllowed(new File((String) request.getAttribute("olddir")), false)) {
1692 f = new File("" + request.getAttribute("olddir"));
1693 }
1694 //try to go to the parent dir
1695 else {
1696 if (f.getParent() != null && isAllowed(f, false)) f = new File(f.getParent());
1697 }
1698 //If this dir also do also not exist, go back to browser.jsp root path
1699 if (!f.exists()) {
1700 String path = null;
1701 if (application.getRealPath(request.getRequestURI()) != null) path = new File(
1702 application.getRealPath(request.getRequestURI())).getParent();
1703
1704 if (path == null) // handle the case were we are not in a directory (ex: war file)
1705 path = new File(".").getAbsolutePath();
1706 f = new File(path);
1707 }
1708 if (isAllowed(f, false)) request.setAttribute("dir", f.getAbsolutePath());
1709 else request.setAttribute("dir", null);
1710 }
1711%>
1712<script type="text/javascript" src="<%=browser_name %>?Javascript">
1713</script>
1714<title><%=request.getAttribute("dir")%></title>
1715</head>
1716<body>
1717<%
1718 //Output message
1719 if (request.getAttribute("message") != null) {
1720 out.println("<table border=\"0\" width=\"100%\"><tr><td class=\"message\">");
1721 out.println(request.getAttribute("message"));
1722 out.println("</td></tr></table>");
1723 }
1724 //Output error
1725 if (request.getAttribute("error") != null) {
1726 out.println("<table border=\"0\" width=\"100%\"><tr><td class=\"error\">");
1727 out.println(request.getAttribute("error"));
1728 out.println("</td></tr></table>");
1729 }
1730 if (request.getAttribute("dir") != null){
1731%>
1732
1733 <form class="formular" action="<%= browser_name %>" method="Post" name="FileList">
1734 Filename filter: <input name="filt" onKeypress="event.cancelBubble=true;" onkeyup="filter(this)" type="text">
1735 <br /><br />
1736 <table id="filetable" class="filelist" cellspacing="1px" cellpadding="0px">
1737<%
1738 // Output the table, starting with the headers.
1739 String dir = URLEncoder.encode("" + request.getAttribute("dir"));
1740 String cmd = browser_name + "?dir=" + dir;
1741 int sortMode = 1;
1742 if (request.getParameter("sort") != null) sortMode = Integer.parseInt(request
1743 .getParameter("sort"));
1744 int[] sort = new int[] {1, 2, 3, 4};
1745 for (int i = 0; i < sort.length; i++)
1746 if (sort[i] == sortMode) sort[i] = -sort[i];
1747 out.print("<tr><th> </th><th title=\"Sort files by name\" align=left><a href=\""
1748 + cmd + "&sort=" + sort[0] + "\">Name</a></th>"
1749 + "<th title=\"Sort files by size\" align=\"right\"><a href=\"" + cmd
1750 + "&sort=" + sort[1] + "\">Size</a></th>"
1751 + "<th title=\"Sort files by type\" align=\"center\"><a href=\"" + cmd
1752 + "&sort=" + sort[3] + "\">Type</a></th>"
1753 + "<th title=\"Sort files by date\" align=\"left\"><a href=\"" + cmd
1754 + "&sort=" + sort[2] + "\">Date</a></th>"
1755 + "<th> </th>");
1756 if (!READ_ONLY) out.print ("<th> </th>");
1757 out.println("</tr>");
1758 char trenner = File.separatorChar;
1759 // Output the Root-Dirs, without FORBIDDEN_DRIVES
1760 File[] entry = File.listRoots();
1761 for (int i = 0; i < entry.length; i++) {
1762 boolean forbidden = false;
1763 for (int i2 = 0; i2 < FORBIDDEN_DRIVES.length; i2++) {
1764 if (entry[i].getAbsolutePath().toLowerCase().equals(FORBIDDEN_DRIVES[i2])) forbidden = true;
1765 }
1766 if (!forbidden) {
1767 out.println("<tr class=\"mouseout\" onmouseover=\"this.className='mousein'\""
1768 + "onmouseout=\"this.className='mouseout'\">");
1769 out.println("<td> </td><td align=left >");
1770 String name = URLEncoder.encode(entry[i].getAbsolutePath());
1771 String buf = entry[i].getAbsolutePath();
1772 out.println(" <a href=\"" + browser_name + "?sort=" + sortMode
1773 + "&dir=" + name + "\">[" + buf + "]</a>");
1774 out.print("</td><td> </td><td> </td><td> </td><td> </td><td></td></tr>");
1775 }
1776 }
1777 // Output the parent directory link ".."
1778 if (f.getParent() != null) {
1779 out.println("<tr class=\"mouseout\" onmouseover=\"this.className='mousein'\""
1780 + "onmouseout=\"this.className='mouseout'\">");
1781 out.println("<td></td><td align=left>");
1782 out.println(" <a href=\"" + browser_name + "?sort=" + sortMode + "&dir="
1783 + URLEncoder.encode(f.getParent()) + "\">" + FOL_IMG + "[..]</a>");
1784 out.print("</td><td> </td><td> </td><td> </td><td> </td><td></td></tr>");
1785 }
1786 // Output all files and dirs and calculate the number of files and total size
1787 entry = f.listFiles();
1788 if (entry == null) entry = new File[] {};
1789 long totalSize = 0; // The total size of the files in the current directory
1790 long fileCount = 0; // The count of files in the current working directory
1791 if (entry != null && entry.length > 0) {
1792 Arrays.sort(entry, new FileComp(sortMode));
1793 for (int i = 0; i < entry.length; i++) {
1794 String name = URLEncoder.encode(entry[i].getAbsolutePath());
1795 String type = "File"; // This String will tell the extension of the file
1796 if (entry[i].isDirectory()) type = "DIR"; // It's a DIR
1797 else {
1798 String tempName = entry[i].getName().replace(' ', '_');
1799 if (tempName.lastIndexOf('.') != -1) type = tempName.substring(
1800 tempName.lastIndexOf('.')).toLowerCase();
1801 }
1802 String ahref = "<a onmousedown=\"dis()\" href=\"" + browser_name + "?sort="
1803 + sortMode + "&";
1804 String dlink = " "; // The "Download" link
1805 String elink = " "; // The "Edit" link
1806 String buf = conv2Html(entry[i].getName());
1807 if (!entry[i].canWrite()) buf = "<i>" + buf + "</i>";
1808 String link = buf; // The standard view link, uses Mime-type
1809 if (entry[i].isDirectory()) {
1810 if (entry[i].canRead() && USE_DIR_PREVIEW) {
1811 //Show the first DIR_PREVIEW_NUMBER directory entries in a tooltip
1812 File[] fs = entry[i].listFiles();
1813 if (fs == null) fs = new File[] {};
1814 Arrays.sort(fs, new FileComp());
1815 StringBuffer filenames = new StringBuffer();
1816 for (int i2 = 0; (i2 < fs.length) && (i2 < 10); i2++) {
1817 String fname = conv2Html(fs[i2].getName());
1818 if (fs[i2].isDirectory()) filenames.append("[" + fname + "];");
1819 else filenames.append(fname + ";");
1820 }
1821 if (fs.length > DIR_PREVIEW_NUMBER) filenames.append("...");
1822 else if (filenames.length() > 0) filenames
1823 .setLength(filenames.length() - 1);
1824 link = ahref + "dir=" + name + "\" title=\"" + filenames + "\">"
1825 + FOL_IMG + "[" + buf + "]</a>";
1826 }
1827 else if (entry[i].canRead()) {
1828 link = ahref + "dir=" + name + "\">" + FOL_IMG + "[" + buf + "]</a>";
1829 }
1830 else link = FOL_IMG + "[" + buf + "]";
1831 }
1832 else if (entry[i].isFile()) { //Entry is file
1833 totalSize = totalSize + entry[i].length();
1834 fileCount = fileCount + 1;
1835 if (entry[i].canRead()) {
1836 dlink = ahref + "downfile=" + name + "\">Download</a>";
1837 //If you click at the filename
1838 if (USE_POPUP) link = ahref + "file=" + name + "\" target=\"_blank\">"
1839 + buf + "</a>";
1840 else link = ahref + "file=" + name + "\">" + buf + "</a>";
1841 if (entry[i].canWrite()) { // The file can be edited
1842 //If it is a zip or jar File you can unpack it
1843 if (isPacked(name, true)) elink = ahref + "unpackfile=" + name
1844 + "\">Unpack</a>";
1845 else elink = ahref + "editfile=" + name + "\">Edit</a>";
1846 }
1847 else { // If the file cannot be edited
1848 //If it is a zip or jar File you can unpack it
1849 if (isPacked(name, true)) elink = ahref + "unpackfile=" + name
1850 + "\">Unpack</a>";
1851 else elink = ahref + "editfile=" + name + "\">View</a>";
1852 }
1853 }
1854 else {
1855 link = buf;
1856 }
1857 }
1858 String date = dateFormat.format(new Date(entry[i].lastModified()));
1859 out.println("<tr class=\"mouseout\" onmouseup=\"selrow(this, 2)\" "
1860 + "onmouseover=\"selrow(this, 0);\" onmouseout=\"selrow(this, 1)\">");
1861 if (entry[i].canRead()) {
1862 out.println("<td align=center><input type=\"checkbox\" name=\"selfile\" value=\""
1863 + name + "\" onmousedown=\"dis()\"></td>");
1864 }
1865 else {
1866 out.println("<td align=center><input type=\"checkbox\" name=\"selfile\" disabled></td>");
1867 }
1868 out.print("<td align=left> " + link + "</td>");
1869 if (entry[i].isDirectory()) out.print("<td> </td>");
1870 else {
1871 out.print("<td align=right title=\"" + entry[i].length() + " bytes\">"
1872 + convertFileSize(entry[i].length()) + "</td>");
1873 }
1874 out.println("<td align=\"center\">" + type + "</td><td align=left> " + // The file type (extension)
1875 date + "</td><td>" + // The date the file was created
1876 dlink + "</td>"); // The download link
1877 if (!READ_ONLY)
1878 out.print ("<td>" + elink + "</td>"); // The edit link (or view, depending)
1879 out.println("</tr>");
1880 }
1881 }%>
1882 </table>
1883 <input type="checkbox" name="selall" onClick="AllFiles(this.form)">Select all
1884 <p align=center>
1885 <b title="<%=totalSize%> bytes">
1886 <%=convertFileSize(totalSize)%></b><b> in <%=fileCount%> files in <%= dir2linkdir((String) request.getAttribute("dir"), browser_name, sortMode)%>
1887 </b>
1888 </p>
1889 <input type="hidden" name="dir" value="<%=request.getAttribute("dir")%>">
1890 <input type="hidden" name="sort" value="<%=sortMode%>">
1891 <input title="Download selected files and directories as one zip file" class="button" id="but_Zip" type="Submit" name="Submit" value="<%=SAVE_AS_ZIP%>">
1892 <% if (!READ_ONLY) {%>
1893 <input title="Delete all selected files and directories incl. subdirs" class="button" id="but_Del" type="Submit" name="Submit" value="<%=DELETE_FILES%>"
1894 onclick="return confirm('Do you really want to delete the entries?')">
1895 <% } %>
1896 <% if (!READ_ONLY) {%>
1897 <br />
1898 <input title="Enter new dir or filename or the relative or absolute path" class="textfield" type="text" onKeypress="event.cancelBubble=true;" id="text_Dir" name="cr_dir">
1899 <input title="Create a new directory with the given name" class="button" id="but_NDi" type="Submit" name="Submit" value="<%=CREATE_DIR%>">
1900 <input title="Create a new empty file with the given name" class="button" id="but_NFi" type="Submit" name="Submit" value="<%=CREATE_FILE%>">
1901 <input title="Move selected files and directories to the entered path" id="but_Mov" class="button" type="Submit" name="Submit" value="<%=MOVE_FILES%>">
1902 <input title="Copy selected files and directories to the entered path" id="but_Cop" class="button" type="Submit" name="Submit" value="<%=COPY_FILES%>">
1903 <input title="Rename selected file or directory to the entered name" id="but_Ren" class="button" type="Submit" name="Submit" value="<%=RENAME_FILE%>">
1904 <% } %>
1905 </form>
1906 <br />
1907 <div class="formular">
1908 <% if (ALLOW_UPLOAD) { %>
1909 <form class="formular2" action="<%= browser_name%>" enctype="multipart/form-data" method="POST">
1910 <input type="hidden" name="dir" value="<%=request.getAttribute("dir")%>">
1911 <input type="hidden" name="sort" value="<%=sortMode%>">
1912 <input type="file" class="textfield" onKeypress="event.cancelBubble=true;" name="myFile">
1913 <input title="Upload selected file to the current working directory" type="Submit" class="button" name="Submit" value="<%=UPLOAD_FILES%>"
1914 onClick="javascript:popUp('<%= browser_name%>')">
1915 </form>
1916 <%} %>
1917 <% if (NATIVE_COMMANDS) {%>
1918 <form class="formular2" action="<%= browser_name%>" method="POST">
1919 <input type="hidden" name="dir" value="<%=request.getAttribute("dir")%>">
1920 <input type="hidden" name="sort" value="<%=sortMode%>">
1921 <input type="hidden" name="command" value="">
1922 <input title="Launch command in current directory" type="Submit" class="button" id="but_Lau" name="Submit" value="<%=LAUNCH_COMMAND%>">
1923 </form><%
1924 }%>
1925 </div>
1926 <%}%>
1927 <hr>
1928 <center>
1929 <small>jsp File Browser version <%= VERSION_NR%> by <a href="http://www.vonloesch.de">www.vonloesch.de</a></small>
1930 </center>
1931</body>
1932</html><%
1933 }
1934%>