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