diff --git a/jsp/jsp_File_browser.jsp b/jsp/jsp_File_browser.jsp new file mode 100644 index 0000000..fd41d27 --- /dev/null +++ b/jsp/jsp_File_browser.jsp @@ -0,0 +1,1934 @@ +<%-- + jsp File browser 1.2 + Copyright (C) 2003-2006 Boris von Loesch + This program is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your option) + any later version. + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + You should have received a copy of the GNU General Public License along with + this program; if not, write to the + Free Software Foundation, Inc., + 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + - Description: jsp File browser v1.2 -- This JSP program allows remote web-based + file access and manipulation. You can copy, create, move and delete files. + Text files can be edited and groups of files and folders can be downloaded + as a single zip file that's created on the fly. + - Credits: Taylor Bastien, David Levine, David Cowan, Lieven Govaerts +--%> +<%@page import="java.util.*, + java.net.*, + java.text.*, + java.util.zip.*, + java.io.*" +%> +<%! + //FEATURES + private static final boolean NATIVE_COMMANDS = true; + /** + *If true, all operations (besides upload and native commands) + *which change something on the file system are permitted + */ + private static final boolean READ_ONLY = false; + //If true, uploads are allowed even if READ_ONLY = true + private static final boolean ALLOW_UPLOAD = true; + + //Allow browsing and file manipulation only in certain directories + private static final boolean RESTRICT_BROWSING = false; + //If true, the user is allowed to browse only in RESTRICT_PATH, + //if false, the user is allowed to browse all directories besides RESTRICT_PATH + private static final boolean RESTRICT_WHITELIST = false; + //Paths, sperated by semicolon + //private static final String RESTRICT_PATH = "C:\\CODE;E:\\"; //Win32: Case important!! + private static final String RESTRICT_PATH = "/etc;/var"; + + //The refresh time in seconds of the upload monitor window + private static final int UPLOAD_MONITOR_REFRESH = 2; + //The number of colums for the edit field + private static final int EDITFIELD_COLS = 85; + //The number of rows for the edit field + private static final int EDITFIELD_ROWS = 30; + //Open a new window to view a file + private static final boolean USE_POPUP = true; + /** + * If USE_DIR_PREVIEW = true, then for every directory a tooltip will be + * created (hold the mouse over the link) with the first DIR_PREVIEW_NUMBER entries. + * This can yield to performance issues. Turn it off, if the directory loads to slow. + */ + private static final boolean USE_DIR_PREVIEW = false; + private static final int DIR_PREVIEW_NUMBER = 10; + /** + * The name of an optional CSS Stylesheet file + */ + private static final String CSS_NAME = "Browser.css"; + /** + * The compression level for zip file creation (0-9) + * 0 = No compression + * 1 = Standard compression (Very fast) + * ... + * 9 = Best compression (Very slow) + */ + private static final int COMPRESSION_LEVEL = 1; + /** + * The FORBIDDEN_DRIVES are not displayed on the list. This can be usefull, if the + * server runs on a windows platform, to avoid a message box, if you try to access + * an empty removable drive (See KNOWN BUGS in Readme.txt). + */ + private static final String[] FORBIDDEN_DRIVES = {"a:\\"}; + + /** + * Command of the shell interpreter and the parameter to run a programm + */ + private static final String[] COMMAND_INTERPRETER = {"cmd", "/C"}; // Dos,Windows + //private static final String[] COMMAND_INTERPRETER = {"/bin/sh","-c"}; // Unix + + /** + * Max time in ms a process is allowed to run, before it will be terminated + */ + private static final long MAX_PROCESS_RUNNING_TIME = 30 * 1000; //30 seconds + + //Button names + private static final String SAVE_AS_ZIP = "Download selected files as (z)ip"; + private static final String RENAME_FILE = "(R)ename File"; + private static final String DELETE_FILES = "(Del)ete selected files"; + private static final String CREATE_DIR = "Create (D)ir"; + private static final String CREATE_FILE = "(C)reate File"; + private static final String MOVE_FILES = "(M)ove Files"; + private static final String COPY_FILES = "Cop(y) Files"; + private static final String LAUNCH_COMMAND = "(L)aunch external program"; + private static final String UPLOAD_FILES = "Upload"; + + //Normally you should not change anything after this line + //---------------------------------------------------------------------------------- + //Change this to locate the tempfile directory for upload (not longer needed) + private static String tempdir = "."; + private static String VERSION_NR = "1.2"; + private static DateFormat dateFormat = DateFormat.getDateTimeInstance(); + + public class UplInfo { + + public long totalSize; + public long currSize; + public long starttime; + public boolean aborted; + + public UplInfo() { + totalSize = 0l; + currSize = 0l; + starttime = System.currentTimeMillis(); + aborted = false; + } + + public UplInfo(int size) { + totalSize = size; + currSize = 0; + starttime = System.currentTimeMillis(); + aborted = false; + } + + public String getUprate() { + long time = System.currentTimeMillis() - starttime; + if (time != 0) { + long uprate = currSize * 1000 / time; + return convertFileSize(uprate) + "/s"; + } + else return "n/a"; + } + + public int getPercent() { + if (totalSize == 0) return 0; + else return (int) (currSize * 100 / totalSize); + } + + public String getTimeElapsed() { + long time = (System.currentTimeMillis() - starttime) / 1000l; + if (time - 60l >= 0){ + if (time % 60 >=10) return time / 60 + ":" + (time % 60) + "m"; + else return time / 60 + ":0" + (time % 60) + "m"; + } + else return time<10 ? "0" + time + "s": time + "s"; + } + + public String getTimeEstimated() { + if (currSize == 0) return "n/a"; + long time = System.currentTimeMillis() - starttime; + time = totalSize * time / currSize; + time /= 1000l; + if (time - 60l >= 0){ + if (time % 60 >=10) return time / 60 + ":" + (time % 60) + "m"; + else return time / 60 + ":0" + (time % 60) + "m"; + } + else return time<10 ? "0" + time + "s": time + "s"; + } + + } + + public class FileInfo { + + public String name = null, clientFileName = null, fileContentType = null; + private byte[] fileContents = null; + public File file = null; + public StringBuffer sb = new StringBuffer(100); + + public void setFileContents(byte[] aByteArray) { + fileContents = new byte[aByteArray.length]; + System.arraycopy(aByteArray, 0, fileContents, 0, aByteArray.length); + } + } + + public static class UploadMonitor { + + static Hashtable uploadTable = new Hashtable(); + + static void set(String fName, UplInfo info) { + uploadTable.put(fName, info); + } + + static void remove(String fName) { + uploadTable.remove(fName); + } + + static UplInfo getInfo(String fName) { + UplInfo info = (UplInfo) uploadTable.get(fName); + return info; + } + } + + // A Class with methods used to process a ServletInputStream + public class HttpMultiPartParser { + + //private final String lineSeparator = System.getProperty("line.separator", "\n"); + private final int ONE_MB = 1024 * 1; + + public Hashtable processData(ServletInputStream is, String boundary, String saveInDir, + int clength) throws IllegalArgumentException, IOException { + if (is == null) throw new IllegalArgumentException("InputStream"); + if (boundary == null || boundary.trim().length() < 1) throw new IllegalArgumentException( + "\"" + boundary + "\" is an illegal boundary indicator"); + boundary = "--" + boundary; + StringTokenizer stLine = null, stFields = null; + FileInfo fileInfo = null; + Hashtable dataTable = new Hashtable(5); + String line = null, field = null, paramName = null; + boolean saveFiles = (saveInDir != null && saveInDir.trim().length() > 0); + boolean isFile = false; + if (saveFiles) { // Create the required directory (including parent dirs) + File f = new File(saveInDir); + f.mkdirs(); + } + line = getLine(is); + if (line == null || !line.startsWith(boundary)) throw new IOException( + "Boundary not found; boundary = " + boundary + ", line = " + line); + while (line != null) { + if (line == null || !line.startsWith(boundary)) return dataTable; + line = getLine(is); + if (line == null) return dataTable; + stLine = new StringTokenizer(line, ";\r\n"); + if (stLine.countTokens() < 2) throw new IllegalArgumentException( + "Bad data in second line"); + line = stLine.nextToken().toLowerCase(); + if (line.indexOf("form-data") < 0) throw new IllegalArgumentException( + "Bad data in second line"); + stFields = new StringTokenizer(stLine.nextToken(), "=\""); + if (stFields.countTokens() < 2) throw new IllegalArgumentException( + "Bad data in second line"); + fileInfo = new FileInfo(); + stFields.nextToken(); + paramName = stFields.nextToken(); + isFile = false; + if (stLine.hasMoreTokens()) { + field = stLine.nextToken(); + stFields = new StringTokenizer(field, "=\""); + if (stFields.countTokens() > 1) { + if (stFields.nextToken().trim().equalsIgnoreCase("filename")) { + fileInfo.name = paramName; + String value = stFields.nextToken(); + if (value != null && value.trim().length() > 0) { + fileInfo.clientFileName = value; + isFile = true; + } + else { + line = getLine(is); // Skip "Content-Type:" line + line = getLine(is); // Skip blank line + line = getLine(is); // Skip blank line + line = getLine(is); // Position to boundary line + continue; + } + } + } + else if (field.toLowerCase().indexOf("filename") >= 0) { + line = getLine(is); // Skip "Content-Type:" line + line = getLine(is); // Skip blank line + line = getLine(is); // Skip blank line + line = getLine(is); // Position to boundary line + continue; + } + } + boolean skipBlankLine = true; + if (isFile) { + line = getLine(is); + if (line == null) return dataTable; + if (line.trim().length() < 1) skipBlankLine = false; + else { + stLine = new StringTokenizer(line, ": "); + if (stLine.countTokens() < 2) throw new IllegalArgumentException( + "Bad data in third line"); + stLine.nextToken(); // Content-Type + fileInfo.fileContentType = stLine.nextToken(); + } + } + if (skipBlankLine) { + line = getLine(is); + if (line == null) return dataTable; + } + if (!isFile) { + line = getLine(is); + if (line == null) return dataTable; + dataTable.put(paramName, line); + // If parameter is dir, change saveInDir to dir + if (paramName.equals("dir")) saveInDir = line; + line = getLine(is); + continue; + } + try { + UplInfo uplInfo = new UplInfo(clength); + UploadMonitor.set(fileInfo.clientFileName, uplInfo); + OutputStream os = null; + String path = null; + if (saveFiles) os = new FileOutputStream(path = getFileName(saveInDir, + fileInfo.clientFileName)); + else os = new ByteArrayOutputStream(ONE_MB); + boolean readingContent = true; + byte previousLine[] = new byte[2 * ONE_MB]; + byte temp[] = null; + byte currentLine[] = new byte[2 * ONE_MB]; + int read, read3; + if ((read = is.readLine(previousLine, 0, previousLine.length)) == -1) { + line = null; + break; + } + while (readingContent) { + if ((read3 = is.readLine(currentLine, 0, currentLine.length)) == -1) { + line = null; + uplInfo.aborted = true; + break; + } + if (compareBoundary(boundary, currentLine)) { + os.write(previousLine, 0, read - 2); + line = new String(currentLine, 0, read3); + break; + } + else { + os.write(previousLine, 0, read); + uplInfo.currSize += read; + temp = currentLine; + currentLine = previousLine; + previousLine = temp; + read = read3; + }//end else + }//end while + os.flush(); + os.close(); + if (!saveFiles) { + ByteArrayOutputStream baos = (ByteArrayOutputStream) os; + fileInfo.setFileContents(baos.toByteArray()); + } + else fileInfo.file = new File(path); + dataTable.put(paramName, fileInfo); + uplInfo.currSize = uplInfo.totalSize; + }//end try + catch (IOException e) { + throw e; + } + } + return dataTable; + } + + /** + * Compares boundary string to byte array + */ + private boolean compareBoundary(String boundary, byte ba[]) { + if (boundary == null || ba == null) return false; + for (int i = 0; i < boundary.length(); i++) + if ((byte) boundary.charAt(i) != ba[i]) return false; + return true; + } + + /** Convenience method to read HTTP header lines */ + private synchronized String getLine(ServletInputStream sis) throws IOException { + byte b[] = new byte[1024]; + int read = sis.readLine(b, 0, b.length), index; + String line = null; + if (read != -1) { + line = new String(b, 0, read); + if ((index = line.indexOf('\n')) >= 0) line = line.substring(0, index - 1); + } + return line; + } + + public String getFileName(String dir, String fileName) throws IllegalArgumentException { + String path = null; + if (dir == null || fileName == null) throw new IllegalArgumentException( + "dir or fileName is null"); + int index = fileName.lastIndexOf('/'); + String name = null; + if (index >= 0) name = fileName.substring(index + 1); + else name = fileName; + index = name.lastIndexOf('\\'); + if (index >= 0) fileName = name.substring(index + 1); + path = dir + File.separator + fileName; + if (File.separatorChar == '/') return path.replace('\\', File.separatorChar); + else return path.replace('/', File.separatorChar); + } + } //End of class HttpMultiPartParser + + /** + * This class is a comparator to sort the filenames and dirs + */ + class FileComp implements Comparator { + + int mode; + int sign; + + FileComp() { + this.mode = 1; + this.sign = 1; + } + + /** + * @param mode sort by 1=Filename, 2=Size, 3=Date, 4=Type + * The default sorting method is by Name + * Negative mode means descending sort + */ + FileComp(int mode) { + if (mode < 0) { + this.mode = -mode; + sign = -1; + } + else { + this.mode = mode; + this.sign = 1; + } + } + + public int compare(Object o1, Object o2) { + File f1 = (File) o1; + File f2 = (File) o2; + if (f1.isDirectory()) { + if (f2.isDirectory()) { + switch (mode) { + //Filename or Type + case 1: + case 4: + return sign + * f1.getAbsolutePath().toUpperCase().compareTo( + f2.getAbsolutePath().toUpperCase()); + //Filesize + case 2: + return sign * (new Long(f1.length()).compareTo(new Long(f2.length()))); + //Date + case 3: + return sign + * (new Long(f1.lastModified()) + .compareTo(new Long(f2.lastModified()))); + default: + return 1; + } + } + else return -1; + } + else if (f2.isDirectory()) return 1; + else { + switch (mode) { + case 1: + return sign + * f1.getAbsolutePath().toUpperCase().compareTo( + f2.getAbsolutePath().toUpperCase()); + case 2: + return sign * (new Long(f1.length()).compareTo(new Long(f2.length()))); + case 3: + return sign + * (new Long(f1.lastModified()).compareTo(new Long(f2.lastModified()))); + case 4: { // Sort by extension + int tempIndexf1 = f1.getAbsolutePath().lastIndexOf('.'); + int tempIndexf2 = f2.getAbsolutePath().lastIndexOf('.'); + if ((tempIndexf1 == -1) && (tempIndexf2 == -1)) { // Neither have an extension + return sign + * f1.getAbsolutePath().toUpperCase().compareTo( + f2.getAbsolutePath().toUpperCase()); + } + // f1 has no extension + else if (tempIndexf1 == -1) return -sign; + // f2 has no extension + else if (tempIndexf2 == -1) return sign; + // Both have an extension + else { + String tempEndf1 = f1.getAbsolutePath().toUpperCase() + .substring(tempIndexf1); + String tempEndf2 = f2.getAbsolutePath().toUpperCase() + .substring(tempIndexf2); + return sign * tempEndf1.compareTo(tempEndf2); + } + } + default: + return 1; + } + } + } + } + + /** + * Wrapperclass to wrap an OutputStream around a Writer + */ + class Writer2Stream extends OutputStream { + + Writer out; + + Writer2Stream(Writer w) { + super(); + out = w; + } + + public void write(int i) throws IOException { + out.write(i); + } + + public void write(byte[] b) throws IOException { + for (int i = 0; i < b.length; i++) { + int n = b[i]; + //Convert byte to ubyte + n = ((n >>> 4) & 0xF) * 16 + (n & 0xF); + out.write(n); + } + } + + public void write(byte[] b, int off, int len) throws IOException { + for (int i = off; i < off + len; i++) { + int n = b[i]; + n = ((n >>> 4) & 0xF) * 16 + (n & 0xF); + out.write(n); + } + } + } //End of class Writer2Stream + + static Vector expandFileList(String[] files, boolean inclDirs) { + Vector v = new Vector(); + if (files == null) return v; + for (int i = 0; i < files.length; i++) + v.add(new File(URLDecoder.decode(files[i]))); + for (int i = 0; i < v.size(); i++) { + File f = (File) v.get(i); + if (f.isDirectory()) { + File[] fs = f.listFiles(); + for (int n = 0; n < fs.length; n++) + v.add(fs[n]); + if (!inclDirs) { + v.remove(i); + i--; + } + } + } + return v; + } + + /** + * Method to build an absolute path + * @param dir the root dir + * @param name the name of the new directory + * @return if name is an absolute directory, returns name, else returns dir+name + */ + static String getDir(String dir, String name) { + if (!dir.endsWith(File.separator)) dir = dir + File.separator; + File mv = new File(name); + String new_dir = null; + if (!mv.isAbsolute()) { + new_dir = dir + name; + } + else new_dir = name; + return new_dir; + } + + /** + * This Method converts a byte size in a kbytes or Mbytes size, depending on the size + * @param size The size in bytes + * @return String with size and unit + */ + static String convertFileSize(long size) { + int divisor = 1; + String unit = "bytes"; + if (size >= 1024 * 1024) { + divisor = 1024 * 1024; + unit = "MB"; + } + else if (size >= 1024) { + divisor = 1024; + unit = "KB"; + } + if (divisor == 1) return size / divisor + " " + unit; + String aftercomma = "" + 100 * (size % divisor) / divisor; + if (aftercomma.length() == 1) aftercomma = "0" + aftercomma; + return size / divisor + "." + aftercomma + " " + unit; + } + + /** + * Copies all data from in to out + * @param in the input stream + * @param out the output stream + * @param buffer copy buffer + */ + static void copyStreams(InputStream in, OutputStream out, byte[] buffer) throws IOException { + copyStreamsWithoutClose(in, out, buffer); + in.close(); + out.close(); + } + + /** + * Copies all data from in to out + * @param in the input stream + * @param out the output stream + * @param buffer copy buffer + */ + static void copyStreamsWithoutClose(InputStream in, OutputStream out, byte[] buffer) + throws IOException { + int b; + while ((b = in.read(buffer)) != -1) + out.write(buffer, 0, b); + } + + /** + * Returns the Mime Type of the file, depending on the extension of the filename + */ + static String getMimeType(String fName) { + fName = fName.toLowerCase(); + if (fName.endsWith(".jpg") || fName.endsWith(".jpeg") || fName.endsWith(".jpe")) return "image/jpeg"; + else if (fName.endsWith(".gif")) return "image/gif"; + else if (fName.endsWith(".pdf")) return "application/pdf"; + else if (fName.endsWith(".htm") || fName.endsWith(".html") || fName.endsWith(".shtml")) return "text/html"; + else if (fName.endsWith(".avi")) return "video/x-msvideo"; + else if (fName.endsWith(".mov") || fName.endsWith(".qt")) return "video/quicktime"; + else if (fName.endsWith(".mpg") || fName.endsWith(".mpeg") || fName.endsWith(".mpe")) return "video/mpeg"; + else if (fName.endsWith(".zip")) return "application/zip"; + else if (fName.endsWith(".tiff") || fName.endsWith(".tif")) return "image/tiff"; + else if (fName.endsWith(".rtf")) return "application/rtf"; + else if (fName.endsWith(".mid") || fName.endsWith(".midi")) return "audio/x-midi"; + else if (fName.endsWith(".xl") || fName.endsWith(".xls") || fName.endsWith(".xlv") + || fName.endsWith(".xla") || fName.endsWith(".xlb") || fName.endsWith(".xlt") + || fName.endsWith(".xlm") || fName.endsWith(".xlk")) return "application/excel"; + else if (fName.endsWith(".doc") || fName.endsWith(".dot")) return "application/msword"; + else if (fName.endsWith(".png")) return "image/png"; + else if (fName.endsWith(".xml")) return "text/xml"; + else if (fName.endsWith(".svg")) return "image/svg+xml"; + else if (fName.endsWith(".mp3")) return "audio/mp3"; + else if (fName.endsWith(".ogg")) return "audio/ogg"; + else return "text/plain"; + } + + /** + * Converts some important chars (int) to the corresponding html string + */ + static String conv2Html(int i) { + if (i == '&') return "&"; + else if (i == '<') return "<"; + else if (i == '>') return ">"; + else if (i == '"') return """; + else return "" + (char) i; + } + + /** + * Converts a normal string to a html conform string + */ + static String conv2Html(String st) { + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < st.length(); i++) { + buf.append(conv2Html(st.charAt(i))); + } + return buf.toString(); + } + + /** + * Starts a native process on the server + * @param command the command to start the process + * @param dir the dir in which the process starts + */ + static String startProcess(String command, String dir) throws IOException { + StringBuffer ret = new StringBuffer(); + String[] comm = new String[3]; + comm[0] = COMMAND_INTERPRETER[0]; + comm[1] = COMMAND_INTERPRETER[1]; + comm[2] = command; + long start = System.currentTimeMillis(); + try { + //Start process + Process ls_proc = Runtime.getRuntime().exec(comm, null, new File(dir)); + //Get input and error streams + BufferedInputStream ls_in = new BufferedInputStream(ls_proc.getInputStream()); + BufferedInputStream ls_err = new BufferedInputStream(ls_proc.getErrorStream()); + boolean end = false; + while (!end) { + int c = 0; + while ((ls_err.available() > 0) && (++c <= 1000)) { + ret.append(conv2Html(ls_err.read())); + } + c = 0; + while ((ls_in.available() > 0) && (++c <= 1000)) { + ret.append(conv2Html(ls_in.read())); + } + try { + ls_proc.exitValue(); + //if the process has not finished, an exception is thrown + //else + while (ls_err.available() > 0) + ret.append(conv2Html(ls_err.read())); + while (ls_in.available() > 0) + ret.append(conv2Html(ls_in.read())); + end = true; + } + catch (IllegalThreadStateException ex) { + //Process is running + } + //The process is not allowed to run longer than given time. + if (System.currentTimeMillis() - start > MAX_PROCESS_RUNNING_TIME) { + ls_proc.destroy(); + end = true; + ret.append("!!!! Process has timed out, destroyed !!!!!"); + } + try { + Thread.sleep(50); + } + catch (InterruptedException ie) {} + } + } + catch (IOException e) { + ret.append("Error: " + e); + } + return ret.toString(); + } + + /** + * Converts a dir string to a linked dir string + * @param dir the directory string (e.g. /usr/local/httpd) + * @param browserLink web-path to Browser.jsp + */ + static String dir2linkdir(String dir, String browserLink, int sortMode) { + File f = new File(dir); + StringBuffer buf = new StringBuffer(); + while (f.getParentFile() != null) { + if (f.canRead()) { + String encPath = URLEncoder.encode(f.getAbsolutePath()); + buf.insert(0, "" + conv2Html(f.getName()) + File.separator + ""); + } + else buf.insert(0, conv2Html(f.getName()) + File.separator); + f = f.getParentFile(); + } + if (f.canRead()) { + String encPath = URLEncoder.encode(f.getAbsolutePath()); + buf.insert(0, "" + conv2Html(f.getAbsolutePath()) + ""); + } + else buf.insert(0, f.getAbsolutePath()); + return buf.toString(); + } + + /** + * Returns true if the given filename tends towards a packed file + */ + static boolean isPacked(String name, boolean gz) { + return (name.toLowerCase().endsWith(".zip") || name.toLowerCase().endsWith(".jar") + || (gz && name.toLowerCase().endsWith(".gz")) || name.toLowerCase() + .endsWith(".war")); + } + + /** + * If RESTRICT_BROWSING = true this method checks, whether the path is allowed or not + */ + static boolean isAllowed(File path, boolean write) throws IOException{ + if (READ_ONLY && write) return false; + if (RESTRICT_BROWSING) { + StringTokenizer stk = new StringTokenizer(RESTRICT_PATH, ";"); + while (stk.hasMoreTokens()){ + if (path!=null && path.getCanonicalPath().startsWith(stk.nextToken())) + return RESTRICT_WHITELIST; + } + return !RESTRICT_WHITELIST; + } + else return true; + } + + //--------------------------------------------------------------------------------------------------------------- + + %> +<% + //Get the current browsing directory + request.setAttribute("dir", request.getParameter("dir")); + // The browser_name variable is used to keep track of the URI + // of the jsp file itself. It is used in all link-backs. + final String browser_name = request.getRequestURI(); + final String FOL_IMG = ""; + boolean nohtml = false; + boolean dir_view = true; + //Get Javascript + if (request.getParameter("Javascript") != null) { + dir_view = false; + nohtml = true; + //Tell the browser that it should cache the javascript + response.setHeader("Cache-Control", "public"); + Date now = new Date(); + SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z", Locale.US); + response.setHeader("Expires", sdf.format(new Date(now.getTime() + 1000 * 60 * 60 * 24*2))); + response.setHeader("Content-Type", "text/javascript"); + %> + <%// This section contains the Javascript used for interface elements %> + var check = false; + <%// Disables the checkbox feature %> + function dis(){check = true;} + + var DOM = 0, MS = 0, OP = 0, b = 0; + <%// Determine the browser type %> + function CheckBrowser(){ + if (b == 0){ + if (window.opera) OP = 1; + // Moz or Netscape + if(document.getElementById) DOM = 1; + // Micro$oft + if(document.all && !OP) MS = 1; + b = 1; + } + } + <%// Allows the whole row to be selected %> + function selrow (element, i){ + var erst; + CheckBrowser(); + if ((OP==1)||(MS==1)) erst = element.firstChild.firstChild; + else if (DOM==1) erst = element.firstChild.nextSibling.firstChild; + <%// MouseIn %> + if (i==0){ + if (erst.checked == true) element.className='mousechecked'; + else element.className='mousein'; + } + <%// MouseOut %> + else if (i==1){ + if (erst.checked == true) element.className='checked'; + else element.className='mouseout'; + } + <% // MouseClick %> + else if ((i==2)&&(!check)){ + if (erst.checked==true) element.className='mousein'; + else element.className='mousechecked'; + erst.click(); + } + else check=false; + } + <%// Filter files and dirs in FileList%> + function filter (begriff){ + var suche = begriff.value.toLowerCase(); + var table = document.getElementById("filetable"); + var ele; + for (var r = 1; r < table.rows.length; r++){ + ele = table.rows[r].cells[1].innerHTML.replace(/<[^>]+>/g,""); + if (ele.toLowerCase().indexOf(suche)>=0 ) + table.rows[r].style.display = ''; + else table.rows[r].style.display = 'none'; + } + } + <%//(De)select all checkboxes%> + function AllFiles(){ + for(var x=0;x < document.FileList.elements.length;x++){ + var y = document.FileList.elements[x]; + var ytr = y.parentNode.parentNode; + var check = document.FileList.selall.checked; + if(y.name == 'selfile' && ytr.style.display != 'none'){ + if (y.disabled != true){ + y.checked = check; + if (y.checked == true) ytr.className = 'checked'; + else ytr.className = 'mouseout'; + } + } + } + } + + function shortKeyHandler(_event){ + if (!_event) _event = window.event; + if (_event.which) { + keycode = _event.which; + } else if (_event.keyCode) { + keycode = _event.keyCode; + } + var t = document.getElementById("text_Dir"); + //z + if (keycode == 122){ + document.getElementById("but_Zip").click(); + } + //r, F2 + else if (keycode == 113 || keycode == 114){ + var path = prompt("Please enter new filename", ""); + if (path == null) return; + t.value = path; + document.getElementById("but_Ren").click(); + } + //c + else if (keycode == 99){ + var path = prompt("Please enter filename", ""); + if (path == null) return; + t.value = path; + document.getElementById("but_NFi").click(); + } + //d + else if (keycode == 100){ + var path = prompt("Please enter directory name", ""); + if (path == null) return; + t.value = path; + document.getElementById("but_NDi").click(); + } + //m + else if (keycode == 109){ + var path = prompt("Please enter move destination", ""); + if (path == null) return; + t.value = path; + document.getElementById("but_Mov").click(); + } + //y + else if (keycode == 121){ + var path = prompt("Please enter copy destination", ""); + if (path == null) return; + t.value = path; + document.getElementById("but_Cop").click(); + } + //l + else if (keycode == 108){ + document.getElementById("but_Lau").click(); + } + //Del + else if (keycode == 46){ + document.getElementById("but_Del").click(); + } + } + + function popUp(URL){ + fname = document.getElementsByName("myFile")[0].value; + if (fname != "") + window.open(URL+"?first&uplMonitor="+encodeURIComponent(fname),"","width=400,height=150,resizable=yes,depend=yes") + } + + document.onkeypress = shortKeyHandler; +<% } + // View file + else if (request.getParameter("file") != null) { + File f = new File(request.getParameter("file")); + if (!isAllowed(f, false)) { + request.setAttribute("dir", f.getParent()); + request.setAttribute("error", "You are not allowed to access "+f.getAbsolutePath()); + } + else if (f.exists() && f.canRead()) { + if (isPacked(f.getName(), false)) { + //If zipFile, do nothing here + } + else{ + String mimeType = getMimeType(f.getName()); + response.setContentType(mimeType); + if (mimeType.equals("text/plain")) response.setHeader( + "Content-Disposition", "inline;filename=\"temp.txt\""); + else response.setHeader("Content-Disposition", "inline;filename=\"" + + f.getName() + "\""); + BufferedInputStream fileInput = new BufferedInputStream(new FileInputStream(f)); + byte buffer[] = new byte[8 * 1024]; + out.clearBuffer(); + OutputStream out_s = new Writer2Stream(out); + copyStreamsWithoutClose(fileInput, out_s, buffer); + fileInput.close(); + out_s.flush(); + nohtml = true; + dir_view = false; + } + } + else { + request.setAttribute("dir", f.getParent()); + request.setAttribute("error", "File " + f.getAbsolutePath() + + " does not exist or is not readable on the server"); + } + } + // Download selected files as zip file + else if ((request.getParameter("Submit") != null) + && (request.getParameter("Submit").equals(SAVE_AS_ZIP))) { + Vector v = expandFileList(request.getParameterValues("selfile"), false); + //Check if all files in vector are allowed + String notAllowedFile = null; + for (int i = 0;i < v.size(); i++){ + File f = (File) v.get(i); + if (!isAllowed(f, false)){ + notAllowedFile = f.getAbsolutePath(); + break; + } + } + if (notAllowedFile != null){ + request.setAttribute("error", "You are not allowed to access " + notAllowedFile); + } + else if (v.size() == 0) { + request.setAttribute("error", "No files selected"); + } + else { + File dir_file = new File("" + request.getAttribute("dir")); + int dir_l = dir_file.getAbsolutePath().length(); + response.setContentType("application/zip"); + response.setHeader("Content-Disposition", "attachment;filename=\"rename_me.zip\""); + out.clearBuffer(); + ZipOutputStream zipout = new ZipOutputStream(new Writer2Stream(out)); + zipout.setComment("Created by jsp File Browser v. " + VERSION_NR); + zipout.setLevel(COMPRESSION_LEVEL); + for (int i = 0; i < v.size(); i++) { + File f = (File) v.get(i); + if (f.canRead()) { + zipout.putNextEntry(new ZipEntry(f.getAbsolutePath().substring(dir_l + 1))); + BufferedInputStream fr = new BufferedInputStream(new FileInputStream(f)); + byte buffer[] = new byte[0xffff]; + copyStreamsWithoutClose(fr, zipout, buffer); + /* int b; + while ((b=fr.read())!=-1) zipout.write(b);*/ + fr.close(); + zipout.closeEntry(); + } + } + zipout.finish(); + out.flush(); + nohtml = true; + dir_view = false; + } + } + // Download file + else if (request.getParameter("downfile") != null) { + String filePath = request.getParameter("downfile"); + File f = new File(filePath); + if (!isAllowed(f, false)){ + request.setAttribute("dir", f.getParent()); + request.setAttribute("error", "You are not allowed to access " + f.getAbsoluteFile()); + } + else if (f.exists() && f.canRead()) { + response.setContentType("application/octet-stream"); + response.setHeader("Content-Disposition", "attachment;filename=\"" + f.getName() + + "\""); + response.setContentLength((int) f.length()); + BufferedInputStream fileInput = new BufferedInputStream(new FileInputStream(f)); + byte buffer[] = new byte[8 * 1024]; + out.clearBuffer(); + OutputStream out_s = new Writer2Stream(out); + copyStreamsWithoutClose(fileInput, out_s, buffer); + fileInput.close(); + out_s.flush(); + nohtml = true; + dir_view = false; + } + else { + request.setAttribute("dir", f.getParent()); + request.setAttribute("error", "File " + f.getAbsolutePath() + + " does not exist or is not readable on the server"); + } + } + if (nohtml) return; + //else + // If no parameter is submitted, it will take the path from jsp file browser + if (request.getAttribute("dir") == null) { + String path = null; + if (application.getRealPath(request.getRequestURI()) != null) { + File f = new File(application.getRealPath(request.getRequestURI())).getParentFile(); + //This is a hack needed for tomcat + while (f != null && !f.exists()) + f = f.getParentFile(); + if (f != null) + path = f.getAbsolutePath(); + } + if (path == null) { // handle the case where we are not in a directory (ex: war file) + path = new File(".").getAbsolutePath(); + } + //Check path + if (!isAllowed(new File(path), false)){ + //TODO Blacklist + if (RESTRICT_PATH.indexOf(";")<0) path = RESTRICT_PATH; + else path = RESTRICT_PATH.substring(0, RESTRICT_PATH.indexOf(";")); + } + request.setAttribute("dir", path); + }%> + + +
+ + + + +<% + //If a cssfile exists, it will take it + String cssPath = null; + if (application.getRealPath(request.getRequestURI()) != null) cssPath = new File( + application.getRealPath(request.getRequestURI())).getParent() + + File.separator + CSS_NAME; + if (cssPath == null) cssPath = application.getResource(CSS_NAME).toString(); + if (new File(cssPath).exists()) { +%> + + <%} + else if (request.getParameter("uplMonitor") == null) {%> + + <%} + + //Check path + if (!isAllowed(new File((String)request.getAttribute("dir")), false)){ + request.setAttribute("error", "You are not allowed to access " + request.getAttribute("dir")); + } + //Upload monitor + else if (request.getParameter("uplMonitor") != null) {%> + <% + String fname = request.getParameter("uplMonitor"); + //First opening + boolean first = false; + if (request.getParameter("first") != null) first = true; + UplInfo info = new UplInfo(); + if (!first) { + info = UploadMonitor.getInfo(fname); + if (info == null) { + //Windows + int posi = fname.lastIndexOf("\\"); + if (posi != -1) info = UploadMonitor.getInfo(fname.substring(posi + 1)); + } + if (info == null) { + //Unix + int posi = fname.lastIndexOf("/"); + if (posi != -1) info = UploadMonitor.getInfo(fname.substring(posi + 1)); + } + } + dir_view = false; + request.setAttribute("dir", null); + if (info.aborted) { + UploadMonitor.remove(fname); + %> + + +Upload of <%=fname%>| + |