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