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