// dir.java // ----------------------- // part of the AnomicHTTPD caching proxy // (C) by Michael Peter Christen; mc@anomic.de // first published on http://www.anomic.de // Frankfurt, Germany, 2004, 2005 // last major change: 15.02.2005 // // 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 // // Using this software in any meaning (reading, learning, copying, compiling, // running) means that you agree that the Author(s) is (are) not responsible // for cost, loss of data or any harm that may be caused directly or indirectly // by usage of this softare or this documentation. The usage of this software // is on your own risk. The installation and usage (starting/running) of this // software may allow other people or application to access your computer and // any attached devices and is highly dependent on the configuration of the // software which must be done by the user of the software; the author(s) is // (are) also not responsible for proper configuration and usage of the // software, even if provoked by documentation provided together with // the software. // // Any changes to this file according to the GPL as documented in the file // gpl.txt aside this file in the shipment you received can be done to the // lines that follows this copyright notice here, but changes must not be // done inside the copyright notive above. A re-distribution must contain // the intact and unchanged copyright notice. // Contributions and changes to the program code must be marked as such. // You must compile this file with // javac -classpath /classes /htroot/htdocsdefault/dir.java // which most probably means to compile this with // javac -classpath ../../classes dir.java import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.net.URL; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Set; import de.anomic.http.httpHeader; import de.anomic.plasma.plasmaCondenser; import de.anomic.plasma.plasmaCrawlLURL; import de.anomic.plasma.plasmaSwitchboard; import de.anomic.plasma.plasmaURL; import de.anomic.plasma.plasmaWordIndexEntry; import de.anomic.server.serverCodings; import de.anomic.server.serverCore; import de.anomic.server.serverFileUtils; import de.anomic.server.serverObjects; import de.anomic.server.serverSwitch; import de.anomic.yacy.yacyCore; import de.anomic.yacy.yacySeed; public class dir { private static SimpleDateFormat SimpleFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); public static String dateString(Date date) { return SimpleFormatter.format(date); } public static serverObjects respond(httpHeader header, serverObjects post, serverSwitch env) { plasmaSwitchboard switchboard = (plasmaSwitchboard) env; serverObjects prop = new serverObjects(); //System.out.println("###Header="+ header); //System.out.println("###post=" + post); String action = ((post == null) ? "info" : post.get("action", "info")); String tree = ""; // variables for this path //File htroot = new File(switchboard.getRootPath(), switchboard.getConfig("htRootPath", "htroot")); File htroot = new File(switchboard.getRootPath(), switchboard.getConfig("htDocsPath", "DATA/HTDOCS")); String path = (String) header.get("PATH", "/"); int p = path.lastIndexOf("/"); if (p >= 0) path = path.substring(0, p + 1); File dir = new File(htroot, path); // general settings prop.put("peername", env.getConfig("peerName", "")); prop.put("peerdomain", env.getConfig("peerName", "").toLowerCase()); prop.put("peeraddress", yacyCore.seedDB.mySeed.getAddress()); prop.put("hostname", serverCore.publicIP().getHostName()); prop.put("hostip", serverCore.publicIP().getHostAddress()); prop.put("port", env.getConfig("port", "8080")); // generate upload/download authorizations String adminAccountBase64MD5 = switchboard.getConfig("adminAccountBase64MD5", ""); String uploadAccountBase64MD5 = switchboard.getConfig("uploadAccountBase64MD5", ""); String downloadAccountBase64MD5 = switchboard.getConfig("downloadAccountBase64MD5", ""); String logoutAccountBase64MD5 = serverCodings.standardCoder.encodeMD5Hex(serverCodings.standardCoder.encodeBase64String(":")); String authorizationMD5 = serverCodings.standardCoder.encodeMD5Hex(((String) header.get("Authorization", "xxxxxx")).trim().substring(6)); //if (logoutAccountBase64.equals(authorization)) boolean adminAuthorization = ((adminAccountBase64MD5.length() != 0) && (adminAccountBase64MD5.equals(authorizationMD5))); boolean uploadAuthorization = ((adminAuthorization) || ((uploadAccountBase64MD5.length() != 0) && (uploadAccountBase64MD5.equals(authorizationMD5)))); boolean downloadAuthorization = ((adminAuthorization) || (uploadAuthorization) || (downloadAccountBase64MD5.length() == 0) || (downloadAccountBase64MD5.equals(authorizationMD5))); // do authentitcate processes by triggering the http authenticate method if ((action.equals("authenticateAdmin")) && (!(adminAuthorization))) { prop.put("AUTHENTICATE", "admin log-in"); return prop; } if ((action.equals("authenticateUpload")) && (!(uploadAuthorization))) { prop.put("AUTHENTICATE", "upload log-in"); return prop; } if ((action.equals("authenticateDownload")) && (!(downloadAuthorization))) { prop.put("AUTHENTICATE", "download log-in"); return prop; } // work off actions if (action.equals("logout")) { if (adminAuthorization) { prop.put("AUTHENTICATE", "admin log-in"); return prop; } else if (uploadAuthorization) { prop.put("AUTHENTICATE", "upload log-in"); return prop; } else if (downloadAuthorization) { prop.put("AUTHENTICATE", "download log-in"); return prop; } else { action = ""; } } if ((action.equals("downloadPassword")) && (adminAuthorization)) { switchboard.setConfig("downloadAccountBase64MD5", (post.get("password", "").length() == 0) ? "" : serverCodings.standardCoder.encodeMD5Hex(serverCodings.standardCoder.encodeBase64String("download:" + post.get("password", "")))); } if ((action.equals("uploadPassword")) && (adminAuthorization)) { switchboard.setConfig("uploadAccountBase64MD5", (post.get("password", "").length() == 0) ? "" : serverCodings.standardCoder.encodeMD5Hex(serverCodings.standardCoder.encodeBase64String("upload:" + post.get("password", "")))); } if ((action.equals("upload")) && ((uploadAuthorization) || (adminAuthorization))) { String filename = new File(post.get("file", "dummy")).getName(); String description = post.get("description", ""); p = filename.lastIndexOf("\\"); if (p >= 0) filename = filename.substring(p + 1); File newfile = new File(dir, filename); File newfilemd5 = new File(dir, filename + ".md5"); byte[] binary = (byte[]) post.get((Object) "file$file", (Object) new byte[0]); try { serverFileUtils.write(binary, newfile); String md5s = serverCodings.encodeMD5Hex(newfile); serverFileUtils.write((md5s + "\n" + description).getBytes(), newfilemd5); // generate md5 // index file info if (post.get("indexing", "").equals("on")) { String urlstring = yacyhURL(yacyCore.seedDB.mySeed, filename, md5s); String phrase = filename.replace('.', ' ').replace('_', ' ').replace('-', ' '); indexPhrase(switchboard, urlstring, phrase, description); } } catch (IOException e) {} } if ((action.equals("newdir")) && ((uploadAuthorization) || (adminAuthorization))) { String newdirname = post.get("directory", "EmptyDir"); if ((newdirname != null) && (newdirname.length() > 0)) { File newdir = new File(dir, newdirname); newdir.mkdir(); try { serverFileUtils.copy(new File(dir,"dir.html"), new File(newdir, "dir.html")); serverFileUtils.copy(new File(dir,"dir.class"), new File(newdir, "dir.class")); } catch (IOException e) {} } } if ((action.equals("delete")) && (adminAuthorization)) { String filename = post.get("file", "foo"); File file = new File(dir, filename); if (file.exists()) { File filemd5 = new File(dir, post.get("file", "foo") + ".md5"); // read md5 and phrase String md5s = ""; String description = ""; if (filemd5.exists()) try { md5s = new String(serverFileUtils.read(filemd5)); p = md5s.indexOf('\n'); if (p >= 0) { description = md5s.substring(p + 1); md5s = md5s.substring(0, p); } } catch (IOException e) {} // delete file(s) if (file.isDirectory()) { String[] content = file.list(); for (int i = 0; i < content.length; i++) (new File(file, content[i])).delete(); file.delete(); } else if (file.isFile()) { file.delete(); if (filemd5.exists()) filemd5.delete(); } // delete index String urlstring = yacyhURL(yacyCore.seedDB.mySeed, filename, md5s); String phrase = filename.replace('.', ' ').replace('_', ' ').replace('-', ' '); deletePhrase(switchboard, urlstring, phrase, description); } } // if authorized, generate directory tree listing if ((adminAuthorization) || (uploadAuthorization) || (downloadAuthorization)) { // generate dir listing String[] list = dir.list(); File f, fmd5; String md5s, description; Date d; //tree += "path = " + path + "

"; if (list == null) tree += "This directory is empty.
"; else { int filecount = 0; tree += "" + ""; boolean dark = false; for (int i = 0; i < list.length; i++) if (!((list[i].startsWith("dir.")) || (list[i].endsWith(".md5")))) { tree += ""; dark = !dark; filecount++; f = new File(dir, list[i]); fmd5 = new File(dir, list[i] + ".md5"); try { if (fmd5.exists()) { md5s = new String(serverFileUtils.read(fmd5)); p = md5s.indexOf('\n'); if (p >= 0) { description = md5s.substring(p + 1); md5s = md5s.substring(0, p); } else { description = ""; } } else { // generate md5 on-the-fly md5s = serverCodings.encodeMD5Hex(f); description = ""; serverFileUtils.write((md5s + "\n" + description).getBytes(), fmd5); } } catch (IOException e) { md5s = ""; description = ""; } d = new Date(f.lastModified()); if (f.isDirectory()) { tree += ""; tree += ""; tree += ""; tree += ""; tree += ""; } else { tree += ""; tree += ""; tree += ""; tree += ""; //if (adminAuthorization) tree += " "; else tree += "
"; tree += "" + serverCore.crlfString; } tree += "
" + path + "
" + dateString(d) + "" + list[i] + "" + formatLong(0, 10) + "Directory"; tree += "" + dateString(d) + " "; tree += "" + list[i] + "" + formatLong(f.length(), 10) + "" + md5s + "" + (((description.length() == 0) && ((list[i].endsWith(".jpg")) || (list[i].endsWith(".gif")) || (list[i].endsWith(".png")))) ? (""; } if (adminAuthorization) tree += "" + "
" + "" + "" + "
"; if (filecount == 0) { tree += "EMPTY
"; } } } String ident = ""; String account = ""; String service = ""; String info = ""; String logout = ""; if (adminAuthorization) { ident = "Administrator"; account = "" + "" + "" + "
upload:
" + "" + " " + "" + "
download:
" + "" + " " + "" + "
"; logout = "
" + "" + " (enter empty account)" + "
"; service = "" + "" + "" + "" + "" + "" + "" + "
New Directory:
" + "" + " " + "" + "
File Upload:
" + "Resource = " + "
" + "Description = 
" + "Indexing : 
" + "" + "
"; info = "Admin and download accounts are necessary to grant their services to clients; " + "no password is required for the download-account unless you set one. " + "Files uploaded and indexed here have a special index entry 'yacyshare'; " + "if you want to find files that are indexed in any share zone, add the word 'yacyshare' to the search words."; } else if (uploadAuthorization) { ident = "Uploader"; account = "
" + "" + "" + "
"; if (uploadAccountBase64MD5.length() == 0) logout = ""; else logout = "
" + "" + " (enter empty account)" + "
"; service = "" + "" + "" + "" + "" + "" + "" + "
New Directory:
" + "" + " " + "" + "
File Upload:
" + "Resource = " + "
" + "Description = 
" + "Indexing : 
" + "" + "
"; info = "Uploaders are not granted to delete files or directories. If you want to do this, log-in as admin."; } else if (downloadAuthorization) { ident = "Downloader"; account = "
" + "" + "" + "
" + "
" + "" + "" + "
"; if (downloadAccountBase64MD5.length() == 0) logout = ""; else logout = "
" + "" + " (enter empty account)" + "
"; service = "You are granted to view directory listings and do downloads in this directory.
" + "If you want to upload, please log in as user 'upload'"; info = "Download is granted even if no download account has been defined. " + "If you are an administrator and you wish to block non-authorized downloades, please log in as user 'admin' " + "and set a download password."; } else { ident = "not authorized"; tree = "To inspect this directory you need either an admin, upload or download account. Please log in."; account = "
" + "" + "" + "
" + "
" + "" + "" + "
" + "
" + "" + "" + "
"; logout = ""; service = "No service available."; info = "You must log-in to upload or download."; } prop.put("dir", tree); prop.put("ident", ident); prop.put("account", account); prop.put("service", service); prop.put("info", info); prop.put("logout", logout); // return rewrite properties return prop; } private static String formatLong(long l, int length) { String r = "" + l; int rl = r.length(); for (int i = rl; i < length; i++) r = " " + r; return r; } // rDNS services: // http://www.xdr2.net/reverse_DNS_lookup.asp // http://remote.12dt.com/rns/ // http://bl.reynolds.net.au/search/ // http://www.declude.com/Articles.asp?ID=97 // http://www.dnsstuff.com/ // listlist: http://www.aspnetimap.com/help/welcome/dnsbl.html public static String yacyhURL(yacySeed seed, String filename, String md5) { return "http://share." + seed.getHexHash() + ".yacyh/" + filename + "?md5=" + md5; } public static void indexPhrase(plasmaSwitchboard switchboard, String urlstring, String phrase, String descr) { try { URL url = new URL(urlstring); plasmaCondenser condenser = new plasmaCondenser(new ByteArrayInputStream(("yacyshare. " + phrase + ". " + descr).getBytes())); plasmaCrawlLURL.Entry newEntry = switchboard.urlPool.loadedURL.addEntry( url, "YaCyShare: " + descr, new Date(), new Date(), "____________", /*initiator*/ yacyCore.seedDB.mySeed.hash, /*executor*/ "AAAAAAAAAAAA", /*referrer*/ 0, /*copycount*/ false, /*localneed*/ Integer.parseInt(condenser.getAnalysis().getProperty("INFORMATION_VALUE","0"), 16), "**", /*language*/ plasmaWordIndexEntry.DT_SHARE, /*doctype*/ phrase.length(), /*size*/ (int) Long.parseLong(condenser.getAnalysis().getProperty("NUMB_WORDS","0"), 16), 5 /*process case*/ ); String urlHash = newEntry.hash(); int words = switchboard.searchManager.addPageIndex(url, urlHash, new Date(), condenser, "**", plasmaWordIndexEntry.DT_SHARE); } catch (IOException e) {} } public static void deletePhrase(plasmaSwitchboard switchboard, String urlstring, String phrase, String descr) { try { String urlhash = plasmaURL.urlHash(new URL(urlstring)); Set words = plasmaCondenser.getWords(("yacyshare " + phrase + " " + descr).getBytes()); switchboard.removeReferences(urlhash, words); switchboard.urlPool.loadedURL.remove(urlhash); } catch (Exception e) { System.out.println("INTERNAL ERROR in dir.deletePhrase:"); e.printStackTrace(); } } }