propagate from branch 'i2p.i2p' (head e1c79060790ae24b2a96aff2857477d6528ae7c6)

to branch 'i2p.i2p.unittests' (head 357abd51672dd9950cbac6dd30ded117fe5695e0)
This commit is contained in:
str4d
2012-03-16 02:30:42 +00:00
407 changed files with 29670 additions and 16556 deletions

View File

@@ -2,6 +2,7 @@
source_file = apps/i2ptunnel/locale/messages_en.po
source_lang = en
trans.ar = apps/i2ptunnel/locale/messages_ar.po
trans.cs = apps/i2ptunnel/locale/messages_cs.po
trans.da = apps/i2ptunnel/locale/messages_da.po
trans.de = apps/i2ptunnel/locale/messages_de.po
trans.es = apps/i2ptunnel/locale/messages_es.po
@@ -18,6 +19,7 @@ trans.zh_CN = apps/i2ptunnel/locale/messages_zh.po
source_file = apps/routerconsole/locale/messages_en.po
source_lang = en
trans.ar = apps/routerconsole/locale/messages_ar.po
trans.cs = apps/routerconsole/locale/messages_cs.po
trans.da = apps/routerconsole/locale/messages_da.po
trans.de = apps/routerconsole/locale/messages_de.po
trans.et_EE = apps/routerconsole/locale/messages_ee.po
@@ -37,6 +39,7 @@ trans.zh_CN = apps/routerconsole/locale/messages_zh.po
source_file = apps/i2psnark/locale/messages_en.po
source_lang = en
trans.ar = apps/i2psnark/locale/messages_ar.po
trans.cs = apps/i2psnark/locale/messages_cs.po
trans.de = apps/i2psnark/locale/messages_de.po
trans.es = apps/i2psnark/locale/messages_es.po
trans.fr = apps/i2psnark/locale/messages_fr.po
@@ -53,6 +56,7 @@ trans.zh_CN = apps/i2psnark/locale/messages_zh.po
source_file = apps/susidns/locale/messages_en.po
source_lang = en
trans.ar = apps/susidns/locale/messages_ar.po
trans.cs = apps/susidns/locale/messages_cs.po
trans.da = apps/susidns/locale/messages_da.po
trans.de = apps/susidns/locale/messages_de.po
trans.es = apps/susidns/locale/messages_es.po
@@ -70,6 +74,7 @@ trans.zh_CN = apps/susidns/locale/messages_zh.po
source_file = apps/desktopgui/locale/messages_en.po
source_lang = en
trans.ar = apps/desktopgui/locale/messages_ar.po
trans.cs = apps/desktopgui/locale/messages_cs.po
trans.da = apps/desktopgui/locale/messages_da.po
trans.de = apps/desktopgui/locale/messages_de.po
trans.es = apps/desktopgui/locale/messages_es.po
@@ -86,6 +91,7 @@ trans.zh_CN = apps/desktopgui/locale/messages_zh.po
[I2P.susimail]
source_file = apps/susimail/locale/messages_en.po
source_lang = en
trans.cs = apps/susimail/locale/messages_cs.po
trans.de = apps/susimail/locale/messages_de.po
trans.es = apps/susimail/locale/messages_es.po
trans.fr = apps/susimail/locale/messages_fr.po
@@ -101,6 +107,7 @@ trans.zh_CN = apps/susimail/locale/messages_zh.po
[I2P.debconf]
source_file = debian/po/templates.pot
source_lang = en
trans.cs = debian/po/cs.po
trans.de = debian/po/de.po
trans.es = debian/po/es.po
trans.pl = debian/po/pl.po

View File

@@ -172,8 +172,9 @@ Applications:
By welterde.
See licenses/LICENSE-GPLv2.txt
Jetty 5.1.15:
Copyright 2000-2004 Mort Bay Consulting Pty. Ltd.
Jetty 6.1.26:
Copyright 1995-2009 Mort Bay Consulting Pty Ltd
See licenses/LICENSE-Jetty.txt
See licenses/LICENSE-Apache2.0.txt
See licenses/NOTICE-Commons-Logging.txt
@@ -215,8 +216,10 @@ Applications:
Copyright (C) 2005 <susi23@mail.i2p>
GPLv2 (or any later version)
See licenses/LICENSE-GPLv2.txt
Uses Apache Jakarta Standard Tag Library 1.1.2:
See licenses/LICENSE-Apache2.0.txt
Uses Glassfish Standard Tag Library (JSTL) 1.2:
Common Development and Distribution License (CDDL) version 1.0 + GNU General Public License (GPL) version 2
See https://glassfish.dev.java.net/public/CDDL+GPL.html
See licenses/LICENSE-GPLv2.txt
SusiMail:
Copyright (C) 2004-2005 <susi23@mail.i2p>
@@ -228,6 +231,10 @@ Applications:
Bundles systray4j-2.4.1:
See licenses/LICENSE-LGPLv2.1.txt
Tomcat 6.0.35:
Copyright 1999-2011 The Apache Software Foundation
See licenses/LICENSE-Apache2.0.txt
See licenses/NOTICE-Tomcat.txt
Other Applications and Libraries

View File

@@ -26,9 +26,9 @@ for i in *.config ; {
( cd $INST_DIR/eepsite
if [ -f jetty.xml ] ; then
rm jetty.xml.new
echo "Please check ${INST_DIR}/eepsite, as there are new files."
else
mv jetty.xml.new jetty.xml
find $PKG/$INSTALL_DIR/i2p -name "*.xml.new" -exec sh -c 'mv "$0" "${0/.new}"' {} \;
fi
)

View File

@@ -18,6 +18,7 @@
#
BUILD=1sponge
# INSTALL_DIR is referenced from /, don't prefix it with a '/'
INSTALL_DIR=opt
NAME=i2p
ARCH=noarch
@@ -104,7 +105,10 @@ sed "s|%INSTALL_PATH|/$INSTALL_DIR/i2p|g" runplain.sh > a
sed "s|%SYSTEM_java_io_tmpdir|/$INSTALL_DIR/i2p|g" a > runplain.sh
# i2prouter %INSTALL_PATH and %SYSTEM_java_io_tmpdir
sed "s|%INSTALL_PATH|/$INSTALL_DIR/i2p|g" i2prouter > a
sed "s|%SYSTEM_java_io_tmpdir|/$INSTALL_DIR/i2p|g" a > i2prouter
rm i2prouter
mv a i2prouter
sed "s|%SYSTEM_java_io_tmpdir|/$INSTALL_DIR/i2p|g" i2prouter > a
sed "s|#ALLOW_ROOT=true|ALLOW_ROOT=true|g" a > i2prouter
chmod 744 ./i2prouter
chmod 744 ./osid
@@ -116,7 +120,7 @@ rm -Rf ./lib/*.dll ./*.bat ./*.exe ./installer ./icons ./a postinstall.sh
mv $PKG/$INSTALL_DIR/i2p/*.config $PKG/install
mv $PKG/$INSTALL_DIR/i2p/blocklist.txt $PKG/$INSTALL_DIR/i2p/blocklist.txt.new
mv $PKG/$INSTALL_DIR/i2p/eepsite/jetty.xml $PKG/$INSTALL_DIR/i2p/eepsite/jetty.xml.new
find $PKG/$INSTALL_DIR/i2p -name "*.xml" -exec mv {} {}.new \;
mv $PKG/$INSTALL_DIR/i2p/eepsite/docroot/index.html $PKG/$INSTALL_DIR/i2p/eepsite/docroot/index.html.new
mv $PKG/$INSTALL_DIR/i2p/eepsite/docroot/favicon.ico $PKG/$INSTALL_DIR/i2p/eepsite/docroot/favicon.ico.new
sed "s|directory|/$INSTALL_DIR/i2p/|g" $CWD/doinst.sh > $PKG/install/doinst.sh

View File

@@ -56,6 +56,7 @@
<manifest>
<attribute name="Main-Class" value="addressbook.Daemon"/>
<attribute name="Implementation-Version" value="${full.version}" />
<attribute name="Built-By" value="${build.built-by}" />
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes}" />
@@ -75,6 +76,7 @@
<war basedir="${dist}/tmp" webxml="web.xml" destfile="${dist}/${war}">
<manifest>
<attribute name="Implementation-Version" value="${full.version}" />
<attribute name="Built-By" value="${build.built-by}" />
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />

View File

@@ -84,7 +84,7 @@ public class Servlet extends HttpServlet {
this.thread.setDaemon(true);
this.thread.setName("Addressbook");
this.thread.start();
System.out.println("INFO: Starting Addressbook " + Daemon.VERSION);
//System.out.println("INFO: Starting Addressbook " + Daemon.VERSION);
//System.out.println("INFO: config root under " + args[0]);
}

View File

@@ -0,0 +1,55 @@
# I2P
# Copyright (C) 2009 The I2P Project
# This file is distributed under the same license as the desktopgui package.
# To contribute translations, see http://www.i2p2.de/newdevelopers
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: https://trac.i2p2.de/\n"
"POT-Creation-Date: 2011-03-03 18:29+0000\n"
"PO-Revision-Date: 2012-02-12 19:44+0000\n"
"Last-Translator: Waseihou Watashi <waseihou@gmail.com>\n"
"Language-Team: Czech (http://www.transifex.net/projects/p/I2P/language/cs/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: cs\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2\n"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:23
msgid "Start I2P"
msgstr "Spustit I2P"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
msgid "I2P is starting!"
msgstr "I2P startuje!"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:38
msgid "Starting"
msgstr "Startuji"
#: src/net/i2p/desktopgui/InternalTrayManager.java:26
msgid "Launch I2P Browser"
msgstr "Spouštím I2P Browser"
#: src/net/i2p/desktopgui/InternalTrayManager.java:50
msgid "Configure desktopgui"
msgstr "Nastavuji desktopgui"
#: src/net/i2p/desktopgui/InternalTrayManager.java:67
msgid "Restart I2P"
msgstr "Restart I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:85
msgid "Stop I2P"
msgstr "Zastavit I2P"
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:44
msgid "Tray icon configuration"
msgstr "Nastavení ikony na liště (tray icon)"
#: src/net/i2p/desktopgui/gui/DesktopguiConfigurationFrame.java:47
msgid "Should tray icon be enabled?"
msgstr "Zapnout ikonu na liště?"

View File

Before

Width:  |  Height:  |  Size: 464 B

After

Width:  |  Height:  |  Size: 464 B

View File

Before

Width:  |  Height:  |  Size: 587 B

After

Width:  |  Height:  |  Size: 587 B

View File

Before

Width:  |  Height:  |  Size: 673 B

After

Width:  |  Height:  |  Size: 673 B

View File

Before

Width:  |  Height:  |  Size: 882 B

After

Width:  |  Height:  |  Size: 882 B

View File

Before

Width:  |  Height:  |  Size: 889 B

After

Width:  |  Height:  |  Size: 889 B

View File

Before

Width:  |  Height:  |  Size: 766 B

After

Width:  |  Height:  |  Size: 766 B

View File

Before

Width:  |  Height:  |  Size: 653 B

After

Width:  |  Height:  |  Size: 653 B

View File

Before

Width:  |  Height:  |  Size: 537 B

After

Width:  |  Height:  |  Size: 537 B

View File

Before

Width:  |  Height:  |  Size: 578 B

After

Width:  |  Height:  |  Size: 578 B

View File

Before

Width:  |  Height:  |  Size: 591 B

After

Width:  |  Height:  |  Size: 591 B

View File

Before

Width:  |  Height:  |  Size: 385 B

After

Width:  |  Height:  |  Size: 385 B

View File

Before

Width:  |  Height:  |  Size: 853 B

After

Width:  |  Height:  |  Size: 853 B

View File

Before

Width:  |  Height:  |  Size: 635 B

After

Width:  |  Height:  |  Size: 635 B

View File

Before

Width:  |  Height:  |  Size: 294 B

After

Width:  |  Height:  |  Size: 294 B

View File

Before

Width:  |  Height:  |  Size: 591 B

After

Width:  |  Height:  |  Size: 591 B

View File

Before

Width:  |  Height:  |  Size: 589 B

After

Width:  |  Height:  |  Size: 589 B

View File

Before

Width:  |  Height:  |  Size: 591 B

After

Width:  |  Height:  |  Size: 591 B

View File

Before

Width:  |  Height:  |  Size: 537 B

After

Width:  |  Height:  |  Size: 537 B

View File

@@ -19,6 +19,7 @@
<pathelement location="../../ministreaming/java/build/obj" />
<pathelement location="../../jetty/jettylib/org.mortbay.jetty.jar" />
<pathelement location="../../jetty/jettylib/javax.servlet.jar" />
<pathelement location="../../jetty/jettylib/jetty-util.jar" />
</classpath>
</depend>
</target>
@@ -34,7 +35,7 @@
debug="true" deprecation="on" source="1.5" target="1.5"
destdir="./build/obj"
includeAntRuntime="false"
classpath="../../../core/java/build/i2p.jar:../../jetty/jettylib/org.mortbay.jetty.jar:../../jetty/jettylib/javax.servlet.jar:../../ministreaming/java/build/mstreaming.jar" >
classpath="../../../core/java/build/i2p.jar:../../jetty/jettylib/org.mortbay.jetty.jar:../../jetty/jettylib/javax.servlet.jar:../../jetty/jettylib/jetty-util.jar:../../ministreaming/java/build/mstreaming.jar" >
<compilerarg line="${javac.compilerargs}" />
</javac>
</target>
@@ -61,6 +62,7 @@
<attribute name="Main-Class" value="org.klomp.snark.Snark" />
<attribute name="Class-Path" value="i2p.jar mstreaming.jar streaming.jar" />
<attribute name="Implementation-Version" value="${full.version}" />
<attribute name="Built-By" value="${build.built-by}" />
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
@@ -95,11 +97,16 @@
<target name="war" depends="jar, bundle, warUpToDate, listChangedFiles" unless="war.uptodate" >
<!-- set if unset -->
<property name="workspace.changes.tr" value="" />
<war destfile="../i2psnark.war" webxml="../web.xml" basedir="../" includes="_icons/*" >
<copy todir="build/icons/.icons" >
<fileset dir="../icons/" />
</copy>
<war destfile="../i2psnark.war" webxml="../web.xml" >
<!-- include only the web stuff, as of 0.7.12 the router will add i2psnark.jar to the classpath for the war -->
<classes dir="./build/obj" includes="**/web/*.class" />
<fileset dir="build/icons/" />
<manifest>
<attribute name="Implementation-Version" value="${full.version}" />
<attribute name="Built-By" value="${build.built-by}" />
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
@@ -109,7 +116,7 @@
<target name="warUpToDate">
<uptodate property="war.uptodate" targetfile="../i2psnark.war" >
<srcfiles dir= "." includes="build/obj/org/klomp/snark/web/*.class ../_icons/* ../web.xml" />
<srcfiles dir= "." includes="build/obj/org/klomp/snark/web/*.class ../icons/* ../web.xml" />
</uptodate>
</target>

View File

@@ -24,8 +24,6 @@ import org.klomp.snark.bencode.InvalidBEncodingException;
*/
abstract class ExtensionHandler {
private static final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(ExtensionHandler.class);
public static final int ID_HANDSHAKE = 0;
public static final int ID_METADATA = 1;
public static final String TYPE_METADATA = "ut_metadata";
@@ -39,15 +37,19 @@ abstract class ExtensionHandler {
/**
* @param metasize -1 if unknown
* @param pexAndMetadata advertise these capabilities
* @return bencoded outgoing handshake message
*/
public static byte[] getHandshake(int metasize) {
public static byte[] getHandshake(int metasize, boolean pexAndMetadata) {
Map<String, Object> handshake = new HashMap();
Map<String, Integer> m = new HashMap();
m.put(TYPE_METADATA, Integer.valueOf(ID_METADATA));
m.put(TYPE_PEX, Integer.valueOf(ID_PEX));
if (metasize >= 0)
handshake.put("metadata_size", Integer.valueOf(metasize));
if (pexAndMetadata) {
m.put(TYPE_METADATA, Integer.valueOf(ID_METADATA));
m.put(TYPE_PEX, Integer.valueOf(ID_PEX));
if (metasize >= 0)
handshake.put("metadata_size", Integer.valueOf(metasize));
}
// include the map even if empty so the far-end doesn't NPE
handshake.put("m", m);
handshake.put("p", Integer.valueOf(6881));
handshake.put("v", "I2PSnark");
@@ -56,21 +58,22 @@ abstract class ExtensionHandler {
}
public static void handleMessage(Peer peer, PeerListener listener, int id, byte[] bs) {
if (_log.shouldLog(Log.INFO))
_log.info("Got extension msg " + id + " length " + bs.length + " from " + peer);
Log log = I2PAppContext.getGlobalContext().logManager().getLog(ExtensionHandler.class);
if (log.shouldLog(Log.INFO))
log.info("Got extension msg " + id + " length " + bs.length + " from " + peer);
if (id == ID_HANDSHAKE)
handleHandshake(peer, listener, bs);
handleHandshake(peer, listener, bs, log);
else if (id == ID_METADATA)
handleMetadata(peer, listener, bs);
handleMetadata(peer, listener, bs, log);
else if (id == ID_PEX)
handlePEX(peer, listener, bs);
else if (_log.shouldLog(Log.INFO))
_log.info("Unknown extension msg " + id + " from " + peer);
handlePEX(peer, listener, bs, log);
else if (log.shouldLog(Log.INFO))
log.info("Unknown extension msg " + id + " from " + peer);
}
private static void handleHandshake(Peer peer, PeerListener listener, byte[] bs) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Got handshake msg from " + peer);
private static void handleHandshake(Peer peer, PeerListener listener, byte[] bs, Log log) {
if (log.shouldLog(Log.DEBUG))
log.debug("Got handshake msg from " + peer);
try {
// this throws NPE on missing keys
InputStream is = new ByteArrayInputStream(bs);
@@ -81,20 +84,20 @@ abstract class ExtensionHandler {
Map<String, BEValue> msgmap = map.get("m").getMap();
if (msgmap.get(TYPE_PEX) != null) {
if (_log.shouldLog(Log.WARN))
_log.debug("Peer supports PEX extension: " + peer);
if (log.shouldLog(Log.DEBUG))
log.debug("Peer supports PEX extension: " + peer);
// peer state calls peer listener calls sendPEX()
}
MagnetState state = peer.getMagnetState();
if (msgmap.get(TYPE_METADATA) == null) {
if (_log.shouldLog(Log.WARN))
_log.debug("Peer does not support metadata extension: " + peer);
if (log.shouldLog(Log.DEBUG))
log.debug("Peer does not support metadata extension: " + peer);
// drop if we need metainfo and we haven't found anybody yet
synchronized(state) {
if (!state.isInitialized()) {
_log.debug("Dropping peer, we need metadata! " + peer);
log.debug("Dropping peer, we need metadata! " + peer);
peer.disconnect();
}
}
@@ -103,20 +106,20 @@ abstract class ExtensionHandler {
BEValue msize = map.get("metadata_size");
if (msize == null) {
if (_log.shouldLog(Log.WARN))
_log.debug("Peer does not have the metainfo size yet: " + peer);
if (log.shouldLog(Log.DEBUG))
log.debug("Peer does not have the metainfo size yet: " + peer);
// drop if we need metainfo and we haven't found anybody yet
synchronized(state) {
if (!state.isInitialized()) {
_log.debug("Dropping peer, we need metadata! " + peer);
log.debug("Dropping peer, we need metadata! " + peer);
peer.disconnect();
}
}
return;
}
int metaSize = msize.getInt();
if (_log.shouldLog(Log.WARN))
_log.debug("Got the metainfo size: " + metaSize);
if (log.shouldLog(Log.DEBUG))
log.debug("Got the metainfo size: " + metaSize);
int remaining;
synchronized(state) {
@@ -125,21 +128,21 @@ abstract class ExtensionHandler {
if (state.isInitialized()) {
if (state.getSize() != metaSize) {
if (_log.shouldLog(Log.WARN))
_log.debug("Wrong metainfo size " + metaSize + " from: " + peer);
if (log.shouldLog(Log.DEBUG))
log.debug("Wrong metainfo size " + metaSize + " from: " + peer);
peer.disconnect();
return;
}
} else {
// initialize it
if (metaSize > MAX_METADATA_SIZE) {
if (_log.shouldLog(Log.WARN))
_log.debug("Huge metainfo size " + metaSize + " from: " + peer);
if (log.shouldLog(Log.DEBUG))
log.debug("Huge metainfo size " + metaSize + " from: " + peer);
peer.disconnect(false);
return;
}
if (_log.shouldLog(Log.INFO))
_log.info("Initialized state, metadata size = " + metaSize + " from " + peer);
if (log.shouldLog(Log.INFO))
log.info("Initialized state, metadata size = " + metaSize + " from " + peer);
state.initialize(metaSize);
}
remaining = state.chunksRemaining();
@@ -152,13 +155,13 @@ abstract class ExtensionHandler {
synchronized(state) {
chk = state.getNextRequest();
}
if (_log.shouldLog(Log.INFO))
_log.info("Request chunk " + chk + " from " + peer);
if (log.shouldLog(Log.INFO))
log.info("Request chunk " + chk + " from " + peer);
sendRequest(peer, chk);
}
} catch (Exception e) {
if (_log.shouldLog(Log.WARN))
_log.warn("Handshake exception from " + peer, e);
if (log.shouldLog(Log.WARN))
log.warn("Handshake exception from " + peer, e);
}
}
@@ -172,9 +175,9 @@ abstract class ExtensionHandler {
* REF: BEP 9
* @since 0.8.4
*/
private static void handleMetadata(Peer peer, PeerListener listener, byte[] bs) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Got metadata msg from " + peer);
private static void handleMetadata(Peer peer, PeerListener listener, byte[] bs, Log log) {
if (log.shouldLog(Log.DEBUG))
log.debug("Got metadata msg from " + peer);
try {
InputStream is = new ByteArrayInputStream(bs);
BDecoder dec = new BDecoder(is);
@@ -185,8 +188,8 @@ abstract class ExtensionHandler {
MagnetState state = peer.getMagnetState();
if (type == TYPE_REQUEST) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Got request for " + piece + " from: " + peer);
if (log.shouldLog(Log.DEBUG))
log.debug("Got request for " + piece + " from: " + peer);
byte[] pc;
synchronized(state) {
pc = state.getChunk(piece);
@@ -197,8 +200,8 @@ abstract class ExtensionHandler {
listener.uploaded(peer, pc.length);
} else if (type == TYPE_DATA) {
int size = map.get("total_size").getInt();
if (_log.shouldLog(Log.DEBUG))
_log.debug("Got data for " + piece + " length " + size + " from: " + peer);
if (log.shouldLog(Log.DEBUG))
log.debug("Got data for " + piece + " length " + size + " from: " + peer);
boolean done;
int chk = -1;
synchronized(state) {
@@ -207,14 +210,14 @@ abstract class ExtensionHandler {
int len = is.available();
if (len != size) {
// probably fatal
if (_log.shouldLog(Log.WARN))
_log.warn("total_size " + size + " but avail data " + len);
if (log.shouldLog(Log.WARN))
log.warn("total_size " + size + " but avail data " + len);
}
peer.downloaded(len);
listener.downloaded(peer, len);
done = state.saveChunk(piece, bs, bs.length - len, len);
if (_log.shouldLog(Log.INFO))
_log.info("Got chunk " + piece + " from " + peer);
if (log.shouldLog(Log.INFO))
log.info("Got chunk " + piece + " from " + peer);
if (!done)
chk = state.getNextRequest();
}
@@ -223,26 +226,26 @@ abstract class ExtensionHandler {
// Done!
// PeerState will call the listener (peer coord), who will
// check to see if the MagnetState has it
if (_log.shouldLog(Log.WARN))
_log.warn("Got last chunk from " + peer);
if (log.shouldLog(Log.WARN))
log.warn("Got last chunk from " + peer);
} else {
// get the next chunk
if (_log.shouldLog(Log.INFO))
_log.info("Request chunk " + chk + " from " + peer);
if (log.shouldLog(Log.INFO))
log.info("Request chunk " + chk + " from " + peer);
sendRequest(peer, chk);
}
} else if (type == TYPE_REJECT) {
if (_log.shouldLog(Log.WARN))
_log.warn("Got reject msg from " + peer);
if (log.shouldLog(Log.WARN))
log.warn("Got reject msg from " + peer);
peer.disconnect(false);
} else {
if (_log.shouldLog(Log.WARN))
_log.warn("Got unknown metadata msg from " + peer);
if (log.shouldLog(Log.WARN))
log.warn("Got unknown metadata msg from " + peer);
peer.disconnect(false);
}
} catch (Exception e) {
if (_log.shouldLog(Log.WARN))
_log.info("Metadata ext. msg. exception from " + peer, e);
if (log.shouldLog(Log.INFO))
log.info("Metadata ext. msg. exception from " + peer, e);
// fatal ?
peer.disconnect(false);
}
@@ -267,8 +270,8 @@ abstract class ExtensionHandler {
peer.sendExtension(hisMsgCode, payload);
} catch (Exception e) {
// NPE, no metadata capability
if (_log.shouldLog(Log.WARN))
_log.info("Metadata send req msg exception to " + peer, e);
//if (log.shouldLog(Log.INFO))
// log.info("Metadata send req msg exception to " + peer, e);
}
}
@@ -286,8 +289,8 @@ abstract class ExtensionHandler {
peer.sendExtension(hisMsgCode, payload);
} catch (Exception e) {
// NPE, no metadata caps
if (_log.shouldLog(Log.WARN))
_log.info("Metadata send piece msg exception to " + peer, e);
//if (log.shouldLog(Log.INFO))
// log.info("Metadata send piece msg exception to " + peer, e);
}
}
@@ -301,9 +304,9 @@ abstract class ExtensionHandler {
* added.f and dropped unsupported
* @since 0.8.4
*/
private static void handlePEX(Peer peer, PeerListener listener, byte[] bs) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Got PEX msg from " + peer);
private static void handlePEX(Peer peer, PeerListener listener, byte[] bs, Log log) {
if (log.shouldLog(Log.DEBUG))
log.debug("Got PEX msg from " + peer);
try {
InputStream is = new ByteArrayInputStream(bs);
BDecoder dec = new BDecoder(is);
@@ -325,8 +328,8 @@ abstract class ExtensionHandler {
// could include ourselves, listener must remove
listener.gotPeers(peer, peers);
} catch (Exception e) {
if (_log.shouldLog(Log.WARN))
_log.info("PEX msg exception from " + peer, e);
if (log.shouldLog(Log.INFO))
log.info("PEX msg exception from " + peer, e);
//peer.disconnect(false);
}
}
@@ -353,8 +356,8 @@ abstract class ExtensionHandler {
peer.sendExtension(hisMsgCode, payload);
} catch (Exception e) {
// NPE, no PEX caps
if (_log.shouldLog(Log.WARN))
_log.info("PEX msg exception to " + peer, e);
//if (log.shouldLog(Log.INFO))
// log.info("PEX msg exception to " + peer, e);
}
}

View File

@@ -219,6 +219,10 @@ public class I2PSnarkUtil {
// opts.setProperty("i2p.streaming.writeTimeout", "90000");
//if (opts.getProperty("i2p.streaming.readTimeout") == null)
// opts.setProperty("i2p.streaming.readTimeout", "120000");
if (opts.getProperty("i2p.streaming.maxConnsPerMinute") == null)
opts.setProperty("i2p.streaming.maxConnsPerMinute", "2");
if (opts.getProperty("i2p.streaming.maxTotalConnsPerMinute") == null)
opts.setProperty("i2p.streaming.maxTotalConnsPerMinute", "6");
_manager = I2PSocketManagerFactory.createManager(_i2cpHost, _i2cpPort, opts);
}
// FIXME this only instantiates krpc once, left stuck with old manager

View File

@@ -61,6 +61,7 @@ public class MetaInfo
private final int piece_length;
private final byte[] piece_hashes;
private final long length;
private final boolean privateTorrent;
private Map<String, BEValue> infoMap;
/**
@@ -71,7 +72,7 @@ public class MetaInfo
* @param lengths null for single-file torrent
*/
MetaInfo(String announce, String name, String name_utf8, List<List<String>> files, List<Long> lengths,
int piece_length, byte[] piece_hashes, long length)
int piece_length, byte[] piece_hashes, long length, boolean privateTorrent)
{
this.announce = announce;
this.name = name;
@@ -82,6 +83,7 @@ public class MetaInfo
this.piece_length = piece_length;
this.piece_hashes = piece_hashes;
this.length = length;
this.privateTorrent = privateTorrent;
// TODO if we add a parameter for other keys
//if (other != null) {
@@ -160,6 +162,10 @@ public class MetaInfo
else
name_utf8 = null;
// BEP 27
val = info.get("private");
privateTorrent = val != null && val.getString().equals("1");
val = info.get("piece length");
if (val == null)
throw new InvalidBEncodingException("Missing piece length number");
@@ -318,6 +324,14 @@ public class MetaInfo
return name;
}
/**
* Is it a private torrent?
* @since 0.9
*/
public boolean isPrivate() {
return privateTorrent;
}
/**
* Returns a list of lists of file name hierarchies or null if it is
* a single name. It has the same size as the list returned by
@@ -439,7 +453,7 @@ public class MetaInfo
{
return new MetaInfo(announce, name, name_utf8, files,
lengths, piece_length,
piece_hashes, length);
piece_hashes, length, privateTorrent);
}
/**
@@ -475,6 +489,10 @@ public class MetaInfo
info.put("name", name);
if (name_utf8 != null)
info.put("name.utf-8", name_utf8);
// BEP 27
if (privateTorrent)
info.put("private", "1");
info.put("piece length", Integer.valueOf(piece_length));
info.put("pieces", piece_hashes);
if (files == null)

View File

@@ -268,7 +268,8 @@ public class Peer implements Comparable
if (_log.shouldLog(Log.DEBUG))
_log.debug("Peer supports extensions, sending reply message");
int metasize = metainfo != null ? metainfo.getInfoBytes().length : -1;
out.sendExtension(0, ExtensionHandler.getHandshake(metasize));
boolean pexAndMetadata = metainfo == null || !metainfo.isPrivate();
out.sendExtension(0, ExtensionHandler.getHandshake(metasize, pexAndMetadata));
}
if ((options & OPTION_I2P_DHT) != 0 && util.getDHT() != null) {

View File

@@ -1186,6 +1186,8 @@ public class PeerCoordinator implements PeerListener
* @since 0.8.4
*/
void sendPeers(Peer peer) {
if (metainfo != null && metainfo.isPrivate())
return;
Map<String, BEValue> handshake = peer.getHandshakeMap();
if (handshake == null)
return;

View File

@@ -489,6 +489,13 @@ class PeerState implements DataLoader
/** @since 0.8.2 */
void extensionMessage(int id, byte[] bs)
{
if (metainfo != null && metainfo.isPrivate() &&
(id == ExtensionHandler.ID_METADATA || id == ExtensionHandler.ID_PEX)) {
// shouldn't get this since we didn't advertise it but they could send it anyway
if (_log.shouldLog(Log.WARN))
_log.warn("Private torrent, ignoring ext msg " + id);
return;
}
ExtensionHandler.handleMessage(peer, listener, id, bs);
// Peer coord will get metadata from MagnetState,
// verify, and then call gotMetaInfo()

View File

@@ -8,6 +8,8 @@ import java.io.FilenameFilter;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -35,8 +37,6 @@ import net.i2p.util.SecureFileOutputStream;
* Manage multiple snarks
*/
public class SnarkManager implements Snark.CompleteListener {
private static SnarkManager _instance = new SnarkManager();
public static SnarkManager instance() { return _instance; }
/**
* Map of (canonical) filename of the .torrent file to Snark instance.
@@ -57,6 +57,7 @@ public class SnarkManager implements Snark.CompleteListener {
private ConnectionAcceptor _connectionAcceptor;
private Thread _monitor;
private volatile boolean _running;
private final Map<String, String> _trackerMap;
public static final String PROP_I2CP_HOST = "i2psnark.i2cpHost";
public static final String PROP_I2CP_PORT = "i2psnark.i2cpPort";
@@ -89,6 +90,34 @@ public class SnarkManager implements Snark.CompleteListener {
public static final int DEFAULT_STARTUP_DELAY = 3;
public static final int DEFAULT_REFRESH_DELAY_SECS = 60;
/**
* "name", "announceURL=websiteURL" pairs
* '=' in announceURL must be escaped as &#44;
*/
private static final String DEFAULT_TRACKERS[] = {
// "Postman", "http://YRgrgTLGnbTq2aZOZDJQ~o6Uk5k6TK-OZtx0St9pb0G-5EGYURZioxqYG8AQt~LgyyI~NCj6aYWpPO-150RcEvsfgXLR~CxkkZcVpgt6pns8SRc3Bi-QSAkXpJtloapRGcQfzTtwllokbdC-aMGpeDOjYLd8b5V9Im8wdCHYy7LRFxhEtGb~RL55DA8aYOgEXcTpr6RPPywbV~Qf3q5UK55el6Kex-6VCxreUnPEe4hmTAbqZNR7Fm0hpCiHKGoToRcygafpFqDw5frLXToYiqs9d4liyVB-BcOb0ihORbo0nS3CLmAwZGvdAP8BZ7cIYE3Z9IU9D1G8JCMxWarfKX1pix~6pIA-sp1gKlL1HhYhPMxwyxvuSqx34o3BqU7vdTYwWiLpGM~zU1~j9rHL7x60pVuYaXcFQDR4-QVy26b6Pt6BlAZoFmHhPcAuWfu-SFhjyZYsqzmEmHeYdAwa~HojSbofg0TMUgESRXMw6YThK1KXWeeJVeztGTz25sL8AAAA.i2p/announce.php=http://tracker.postman.i2p/"
// , "eBook", "http://E71FRom6PZNEqTN2Lr8P-sr23b7HJVC32KoGnVQjaX6zJiXwhJy2HsXob36Qmj81TYFZdewFZa9mSJ533UZgGyQkXo2ahctg82JKYZfDe5uDxAn1E9YPjxZCWJaFJh0S~UwSs~9AZ7UcauSJIoNtpxrtbmRNVFLqnkEDdLZi26TeucfOmiFmIWnVblLniWv3tG1boE9Abd-6j3FmYVrRucYuepAILYt6katmVNOk6sXmno1Eynrp~~MBuFq0Ko6~jsc2E2CRVYXDhGHEMdt-j6JUz5D7S2RIVzDRqQyAZLKJ7OdQDmI31przzmne1vOqqqLC~1xUumZVIvF~yOeJUGNjJ1Vx0J8i2BQIusn1pQJ6UCB~ZtZZLQtEb8EPVCfpeRi2ri1M5CyOuxN0V5ekmPHrYIBNevuTCRC26NP7ZS5VDgx1~NaC3A-CzJAE6f1QXi0wMI9aywNG5KGzOPifcsih8eyGyytvgLtrZtV7ykzYpPCS-rDfITncpn5hliPUAAAA.i2p/pub/bt/announce.php=http://de-ebook-archiv.i2p/pub/bt/"
// , "Gaytorrents", "http://uxPWHbK1OIj9HxquaXuhMiIvi21iK0~ZiG9d8G0840ZXIg0r6CbiV71xlsqmdnU6wm0T2LySriM0doW2gUigo-5BNkUquHwOjLROiETnB3ZR0Ml4IGa6QBPn1aAq2d9~g1r1nVjLE~pcFnXB~cNNS7kIhX1d6nLgYVZf0C2cZopEow2iWVUggGGnAA9mHjE86zLEnTvAyhbAMTqDQJhEuLa0ZYSORqzJDMkQt90MV4YMjX1ICY6RfUSFmxEqu0yWTrkHsTtRw48l~dz9wpIgc0a0T9C~eeWvmBFTqlJPtQZwntpNeH~jF7nlYzB58olgV2HHFYpVYD87DYNzTnmNWxCJ5AfDorm6AIUCV2qaE7tZtI1h6fbmGpGlPyW~Kw5GXrRfJwNvr6ajwAVi~bPVnrBwDZezHkfW4slOO8FACPR28EQvaTu9nwhAbqESxV2hCTq6vQSGjuxHeOuzBOEvRWkLKOHWTC09t2DbJ94FSqETmZopTB1ukEmaxRWbKSIaAAAA.i2p/announce.php=http://gaytorrents.i2p/"
// , "NickyB", "http://9On6d3cZ27JjwYCtyJJbowe054d5tFnfMjv4PHsYs-EQn4Y4mk2zRixatvuAyXz2MmRfXG-NAUfhKr0KCxRNZbvHmlckYfT-WBzwwpiMAl0wDFY~Pl8cqXuhfikSG5WrqdPfDNNIBuuznS0dqaczf~OyVaoEOpvuP3qV6wKqbSSLpjOwwAaQPHjlRtNIW8-EtUZp-I0LT45HSoowp~6b7zYmpIyoATvIP~sT0g0MTrczWhbVTUZnEkZeLhOR0Duw1-IRXI2KHPbA24wLO9LdpKKUXed05RTz0QklW5ROgR6TYv7aXFufX8kC0-DaKvQ5JKG~h8lcoHvm1RCzNqVE-2aiZnO2xH08H-iCWoLNJE-Td2kT-Tsc~3QdQcnEUcL5BF-VT~QYRld2--9r0gfGl-yDrJZrlrihHGr5J7ImahelNn9PpkVp6eIyABRmJHf2iicrk3CtjeG1j9OgTSwaNmEpUpn4aN7Kx0zNLdH7z6uTgCGD9Kmh1MFYrsoNlTp4AAAA.i2p/bittorrent/announce.php=http://nickyb.i2p/bittorrent/"
// , "Orion", "http://gKik1lMlRmuroXVGTZ~7v4Vez3L3ZSpddrGZBrxVriosCQf7iHu6CIk8t15BKsj~P0JJpxrofeuxtm7SCUAJEr0AIYSYw8XOmp35UfcRPQWyb1LsxUkMT4WqxAT3s1ClIICWlBu5An~q-Mm0VFlrYLIPBWlUFnfPR7jZ9uP5ZMSzTKSMYUWao3ejiykr~mtEmyls6g-ZbgKZawa9II4zjOy-hdxHgP-eXMDseFsrym4Gpxvy~3Fv9TuiSqhpgm~UeTo5YBfxn6~TahKtE~~sdCiSydqmKBhxAQ7uT9lda7xt96SS09OYMsIWxLeQUWhns-C~FjJPp1D~IuTrUpAFcVEGVL-BRMmdWbfOJEcWPZ~CBCQSO~VkuN1ebvIOr9JBerFMZSxZtFl8JwcrjCIBxeKPBmfh~xYh16BJm1BBBmN1fp2DKmZ2jBNkAmnUbjQOqWvUcehrykWk5lZbE7bjJMDFH48v3SXwRuDBiHZmSbsTY6zhGY~GkMQHNGxPMMSIAAAA.i2p/bt/announce.php=http://orion.i2p/bt/"
// , "anonymity", "http://8EoJZIKrWgGuDrxA3nRJs1jsPfiGwmFWL91hBrf0HA7oKhEvAna4Ocx47VLUR9retVEYBAyWFK-eZTPcvhnz9XffBEiJQQ~kFSCqb1fV6IfPiV3HySqi9U5Caf6~hC46fRd~vYnxmaBLICT3N160cxBETqH3v2rdxdJpvYt8q4nMk9LUeVXq7zqCTFLLG5ig1uKgNzBGe58iNcsvTEYlnbYcE930ABmrzj8G1qQSgSwJ6wx3tUQNl1z~4wSOUMan~raZQD60lRK70GISjoX0-D0Po9WmPveN3ES3g72TIET3zc3WPdK2~lgmKGIs8GgNLES1cXTolvbPhdZK1gxddRMbJl6Y6IPFyQ9o4-6Rt3Lp-RMRWZ2TG7j2OMcNSiOmATUhKEFBDfv-~SODDyopGBmfeLw16F4NnYednvn4qP10dyMHcUASU6Zag4mfc2-WivrOqeWhD16fVAh8MoDpIIT~0r9XmwdaVFyLcjbXObabJczxCAW3fodQUnvuSkwzAAAA.i2p/anonymityTracker/announce.php=http://anonymityweb.i2p/anonymityTracker/"
// , "The freak's tracker", "http://mHKva9x24E5Ygfey2llR1KyQHv5f8hhMpDMwJDg1U-hABpJ2NrQJd6azirdfaR0OKt4jDlmP2o4Qx0H598~AteyD~RJU~xcWYdcOE0dmJ2e9Y8-HY51ie0B1yD9FtIV72ZI-V3TzFDcs6nkdX9b81DwrAwwFzx0EfNvK1GLVWl59Ow85muoRTBA1q8SsZImxdyZ-TApTVlMYIQbdI4iQRwU9OmmtefrCe~ZOf4UBS9-KvNIqUL0XeBSqm0OU1jq-D10Ykg6KfqvuPnBYT1BYHFDQJXW5DdPKwcaQE4MtAdSGmj1epDoaEBUa9btQlFsM2l9Cyn1hzxqNWXELmx8dRlomQLlV4b586dRzW~fLlOPIGC13ntPXogvYvHVyEyptXkv890jC7DZNHyxZd5cyrKC36r9huKvhQAmNABT2Y~pOGwVrb~RpPwT0tBuPZ3lHYhBFYmD8y~AOhhNHKMLzea1rfwTvovBMByDdFps54gMN1mX4MbCGT4w70vIopS9yAAAA.i2p/bytemonsoon/announce.php"
// , "mastertracker", "http://VzXD~stRKbL3MOmeTn1iaCQ0CFyTmuFHiKYyo0Rd~dFPZFCYH-22rT8JD7i-C2xzYFa4jT5U2aqHzHI-Jre4HL3Ri5hFtZrLk2ax3ji7Qfb6qPnuYkuiF2E2UDmKUOppI8d9Ye7tjdhQVCy0izn55tBaB-U7UWdcvSK2i85sauyw3G0Gfads1Rvy5-CAe2paqyYATcDmGjpUNLoxbfv9KH1KmwRTNH6k1v4PyWYYnhbT39WfKMbBjSxVQRdi19cyJrULSWhjxaQfJHeWx5Z8Ev4bSPByBeQBFl2~4vqy0S5RypINsRSa3MZdbiAAyn5tr5slWR6QdoqY3qBQgBJFZppy-3iWkFqqKgSxCPundF8gdDLC5ddizl~KYcYKl42y9SGFHIukH-TZs8~em0~iahzsqWVRks3zRG~tlBcX2U3M2~OJs~C33-NKhyfZT7-XFBREvb8Szmd~p66jDxrwOnKaku-G6DyoQipJqIz4VHmY9-y5T8RrUcJcM-5lVoMpAAAA.i2p/announce.php=http://tracker.mastertracker.i2p/"
// , "Galen", "http://5jpwQMI5FT303YwKa5Rd38PYSX04pbIKgTaKQsWbqoWjIfoancFdWCShXHLI5G5ofOb0Xu11vl2VEMyPsg1jUFYSVnu4-VfMe3y4TKTR6DTpetWrnmEK6m2UXh91J5DZJAKlgmO7UdsFlBkQfR2rY853-DfbJtQIFl91tbsmjcA5CGQi4VxMFyIkBzv-pCsuLQiZqOwWasTlnzey8GcDAPG1LDcvfflGV~6F5no9mnuisZPteZKlrv~~TDoXTj74QjByWc4EOYlwqK8sbU9aOvz~s31XzErbPTfwiawiaZ0RUI-IDrKgyvmj0neuFTWgjRGVTH8bz7cBZIc3viy6ioD-eMQOrXaQL0TCWZUelRwHRvgdPiQrxdYQs7ixkajeHzxi-Pq0EMm5Vbh3j3Q9kfUFW3JjFDA-MLB4g6XnjCbM5J1rC0oOBDCIEfhQkszru5cyLjHiZ5yeA0VThgu~c7xKHybv~OMXION7V8pBKOgET7ZgAkw1xgYe3Kkyq5syAAAA.i2p/tr/announce.php=http://galen.i2p/tr/"
"Postman", "http://tracker2.postman.i2p/announce.php=http://tracker2.postman.i2p/"
,"Welterde", "http://tracker.welterde.i2p/a=http://tracker.welterde.i2p/stats?mode=top5"
,"Diftracker", "http://n--XWjHjUPjnMNrSwXA2OYXpMIUL~u4FNXnrt2HtjK3y6j~4SOClyyeKzd0zRPlixxkCe2wfBIYye3bZsaqAD8bd0QMmowxbq91WpjsPfKMiphJbePKXtYAVARiy0cqyvh1d2LyDE-6wkvgaw45hknmS0U-Dg3YTJZbAQRU2SKXgIlAbWCv4R0kDFBLEVpReDiJef3rzAWHiW8yjmJuJilkYjMwlfRjw8xx1nl2s~yhlljk1pl13jGYb0nfawQnuOWeP-ASQWvAAyVgKvZRJE2O43S7iveu9piuv7plXWbt36ef7ndu2GNoNyPOBdpo9KUZ-NOXm4Kgh659YtEibL15dEPAOdxprY0sYUurVw8OIWqrpX7yn08nbi6qHVGqQwTpxH35vkL8qrCbm-ym7oQJQnNmSDrNTyWYRFSq5s5~7DAdFDzqRPW-pX~g0zEivWj5tzkhvG9rVFgFo0bpQX3X0PUAV9Xbyf8u~v8Zbr9K1pCPqBq9XEr4TqaLHw~bfAAAA.i2p/announce.php=http://diftracker.i2p/"
// , "CRSTRACK", "http://b4G9sCdtfvccMAXh~SaZrPqVQNyGQbhbYMbw6supq2XGzbjU4NcOmjFI0vxQ8w1L05twmkOvg5QERcX6Mi8NQrWnR0stLExu2LucUXg1aYjnggxIR8TIOGygZVIMV3STKH4UQXD--wz0BUrqaLxPhrm2Eh9Hwc8TdB6Na4ShQUq5Xm8D4elzNUVdpM~RtChEyJWuQvoGAHY3ppX-EJJLkiSr1t77neS4Lc-KofMVmgI9a2tSSpNAagBiNI6Ak9L1T0F9uxeDfEG9bBSQPNMOSUbAoEcNxtt7xOW~cNOAyMyGydwPMnrQ5kIYPY8Pd3XudEko970vE0D6gO19yoBMJpKx6Dh50DGgybLQ9CpRaynh2zPULTHxm8rneOGRcQo8D3mE7FQ92m54~SvfjXjD2TwAVGI~ae~n9HDxt8uxOecAAvjjJ3TD4XM63Q9TmB38RmGNzNLDBQMEmJFpqQU8YeuhnS54IVdUoVQFqui5SfDeLXlSkh4vYoMU66pvBfWbAAAA.i2p/tracker/announce.php=http://crstrack.i2p/tracker/"
// ,"Exotrack", "http://blbgywsjubw3d2zih2giokakhe3o2cko7jtte4risb3hohbcoyva.b32.i2p/announce.php=http://exotrack.i2p/"
};
/** comma delimited list of name=announceURL=baseURL for the trackers to be displayed */
public static final String PROP_TRACKERS = "i2psnark.trackers";
private static final SnarkManager _instance = new SnarkManager();
public static SnarkManager instance() { return _instance; }
private SnarkManager() {
_snarks = new ConcurrentHashMap();
_magnets = new ConcurrentHashSet();
@@ -100,6 +129,7 @@ public class SnarkManager implements Snark.CompleteListener {
_configFile = new File(CONFIG_FILE);
if (!_configFile.isAbsolute())
_configFile = new File(_context.getConfigDir(), CONFIG_FILE);
_trackerMap = Collections.synchronizedMap(new TreeMap(new IgnoreCaseComparator()));
loadConfig(null);
}
@@ -312,6 +342,7 @@ public class SnarkManager implements Snark.CompleteListener {
boolean bOT = useOT == null || Boolean.valueOf(useOT).booleanValue();
_util.setUseOpenTrackers(bOT);
getDataDir().mkdirs();
initTrackerMap();
}
private int getInt(String prop, int defaultVal) {
@@ -663,7 +694,9 @@ public class SnarkManager implements Snark.CompleteListener {
}
if (!TrackerClient.isValidAnnounce(info.getAnnounce())) {
if (_util.shouldUseOpenTrackers() && _util.getOpenTrackers() != null) {
if (info.isPrivate()) {
addMessage(_("ERROR - No I2P trackers in private torrent \"{0}\"", info.getName()));
} else if (_util.shouldUseOpenTrackers() && _util.getOpenTrackers() != null) {
//addMessage(_("Warning - No I2P trackers in \"{0}\", will announce to I2P open trackers and DHT only.", info.getName()));
addMessage(_("Warning - No I2P trackers in \"{0}\", will announce to I2P open trackers only.", info.getName()));
//} else if (_util.getDHT() != null) {
@@ -1356,57 +1389,59 @@ public class SnarkManager implements Snark.CompleteListener {
}
/**
* "name", "announceURL=websiteURL" pairs
* Sorted map of name to announceURL=baseURL
* Modifiable, not a copy
*/
private static final String DEFAULT_TRACKERS[] = {
// "Postman", "http://YRgrgTLGnbTq2aZOZDJQ~o6Uk5k6TK-OZtx0St9pb0G-5EGYURZioxqYG8AQt~LgyyI~NCj6aYWpPO-150RcEvsfgXLR~CxkkZcVpgt6pns8SRc3Bi-QSAkXpJtloapRGcQfzTtwllokbdC-aMGpeDOjYLd8b5V9Im8wdCHYy7LRFxhEtGb~RL55DA8aYOgEXcTpr6RPPywbV~Qf3q5UK55el6Kex-6VCxreUnPEe4hmTAbqZNR7Fm0hpCiHKGoToRcygafpFqDw5frLXToYiqs9d4liyVB-BcOb0ihORbo0nS3CLmAwZGvdAP8BZ7cIYE3Z9IU9D1G8JCMxWarfKX1pix~6pIA-sp1gKlL1HhYhPMxwyxvuSqx34o3BqU7vdTYwWiLpGM~zU1~j9rHL7x60pVuYaXcFQDR4-QVy26b6Pt6BlAZoFmHhPcAuWfu-SFhjyZYsqzmEmHeYdAwa~HojSbofg0TMUgESRXMw6YThK1KXWeeJVeztGTz25sL8AAAA.i2p/announce.php=http://tracker.postman.i2p/"
// , "eBook", "http://E71FRom6PZNEqTN2Lr8P-sr23b7HJVC32KoGnVQjaX6zJiXwhJy2HsXob36Qmj81TYFZdewFZa9mSJ533UZgGyQkXo2ahctg82JKYZfDe5uDxAn1E9YPjxZCWJaFJh0S~UwSs~9AZ7UcauSJIoNtpxrtbmRNVFLqnkEDdLZi26TeucfOmiFmIWnVblLniWv3tG1boE9Abd-6j3FmYVrRucYuepAILYt6katmVNOk6sXmno1Eynrp~~MBuFq0Ko6~jsc2E2CRVYXDhGHEMdt-j6JUz5D7S2RIVzDRqQyAZLKJ7OdQDmI31przzmne1vOqqqLC~1xUumZVIvF~yOeJUGNjJ1Vx0J8i2BQIusn1pQJ6UCB~ZtZZLQtEb8EPVCfpeRi2ri1M5CyOuxN0V5ekmPHrYIBNevuTCRC26NP7ZS5VDgx1~NaC3A-CzJAE6f1QXi0wMI9aywNG5KGzOPifcsih8eyGyytvgLtrZtV7ykzYpPCS-rDfITncpn5hliPUAAAA.i2p/pub/bt/announce.php=http://de-ebook-archiv.i2p/pub/bt/"
// , "Gaytorrents", "http://uxPWHbK1OIj9HxquaXuhMiIvi21iK0~ZiG9d8G0840ZXIg0r6CbiV71xlsqmdnU6wm0T2LySriM0doW2gUigo-5BNkUquHwOjLROiETnB3ZR0Ml4IGa6QBPn1aAq2d9~g1r1nVjLE~pcFnXB~cNNS7kIhX1d6nLgYVZf0C2cZopEow2iWVUggGGnAA9mHjE86zLEnTvAyhbAMTqDQJhEuLa0ZYSORqzJDMkQt90MV4YMjX1ICY6RfUSFmxEqu0yWTrkHsTtRw48l~dz9wpIgc0a0T9C~eeWvmBFTqlJPtQZwntpNeH~jF7nlYzB58olgV2HHFYpVYD87DYNzTnmNWxCJ5AfDorm6AIUCV2qaE7tZtI1h6fbmGpGlPyW~Kw5GXrRfJwNvr6ajwAVi~bPVnrBwDZezHkfW4slOO8FACPR28EQvaTu9nwhAbqESxV2hCTq6vQSGjuxHeOuzBOEvRWkLKOHWTC09t2DbJ94FSqETmZopTB1ukEmaxRWbKSIaAAAA.i2p/announce.php=http://gaytorrents.i2p/"
// , "NickyB", "http://9On6d3cZ27JjwYCtyJJbowe054d5tFnfMjv4PHsYs-EQn4Y4mk2zRixatvuAyXz2MmRfXG-NAUfhKr0KCxRNZbvHmlckYfT-WBzwwpiMAl0wDFY~Pl8cqXuhfikSG5WrqdPfDNNIBuuznS0dqaczf~OyVaoEOpvuP3qV6wKqbSSLpjOwwAaQPHjlRtNIW8-EtUZp-I0LT45HSoowp~6b7zYmpIyoATvIP~sT0g0MTrczWhbVTUZnEkZeLhOR0Duw1-IRXI2KHPbA24wLO9LdpKKUXed05RTz0QklW5ROgR6TYv7aXFufX8kC0-DaKvQ5JKG~h8lcoHvm1RCzNqVE-2aiZnO2xH08H-iCWoLNJE-Td2kT-Tsc~3QdQcnEUcL5BF-VT~QYRld2--9r0gfGl-yDrJZrlrihHGr5J7ImahelNn9PpkVp6eIyABRmJHf2iicrk3CtjeG1j9OgTSwaNmEpUpn4aN7Kx0zNLdH7z6uTgCGD9Kmh1MFYrsoNlTp4AAAA.i2p/bittorrent/announce.php=http://nickyb.i2p/bittorrent/"
// , "Orion", "http://gKik1lMlRmuroXVGTZ~7v4Vez3L3ZSpddrGZBrxVriosCQf7iHu6CIk8t15BKsj~P0JJpxrofeuxtm7SCUAJEr0AIYSYw8XOmp35UfcRPQWyb1LsxUkMT4WqxAT3s1ClIICWlBu5An~q-Mm0VFlrYLIPBWlUFnfPR7jZ9uP5ZMSzTKSMYUWao3ejiykr~mtEmyls6g-ZbgKZawa9II4zjOy-hdxHgP-eXMDseFsrym4Gpxvy~3Fv9TuiSqhpgm~UeTo5YBfxn6~TahKtE~~sdCiSydqmKBhxAQ7uT9lda7xt96SS09OYMsIWxLeQUWhns-C~FjJPp1D~IuTrUpAFcVEGVL-BRMmdWbfOJEcWPZ~CBCQSO~VkuN1ebvIOr9JBerFMZSxZtFl8JwcrjCIBxeKPBmfh~xYh16BJm1BBBmN1fp2DKmZ2jBNkAmnUbjQOqWvUcehrykWk5lZbE7bjJMDFH48v3SXwRuDBiHZmSbsTY6zhGY~GkMQHNGxPMMSIAAAA.i2p/bt/announce.php=http://orion.i2p/bt/"
// , "anonymity", "http://8EoJZIKrWgGuDrxA3nRJs1jsPfiGwmFWL91hBrf0HA7oKhEvAna4Ocx47VLUR9retVEYBAyWFK-eZTPcvhnz9XffBEiJQQ~kFSCqb1fV6IfPiV3HySqi9U5Caf6~hC46fRd~vYnxmaBLICT3N160cxBETqH3v2rdxdJpvYt8q4nMk9LUeVXq7zqCTFLLG5ig1uKgNzBGe58iNcsvTEYlnbYcE930ABmrzj8G1qQSgSwJ6wx3tUQNl1z~4wSOUMan~raZQD60lRK70GISjoX0-D0Po9WmPveN3ES3g72TIET3zc3WPdK2~lgmKGIs8GgNLES1cXTolvbPhdZK1gxddRMbJl6Y6IPFyQ9o4-6Rt3Lp-RMRWZ2TG7j2OMcNSiOmATUhKEFBDfv-~SODDyopGBmfeLw16F4NnYednvn4qP10dyMHcUASU6Zag4mfc2-WivrOqeWhD16fVAh8MoDpIIT~0r9XmwdaVFyLcjbXObabJczxCAW3fodQUnvuSkwzAAAA.i2p/anonymityTracker/announce.php=http://anonymityweb.i2p/anonymityTracker/"
// , "The freak's tracker", "http://mHKva9x24E5Ygfey2llR1KyQHv5f8hhMpDMwJDg1U-hABpJ2NrQJd6azirdfaR0OKt4jDlmP2o4Qx0H598~AteyD~RJU~xcWYdcOE0dmJ2e9Y8-HY51ie0B1yD9FtIV72ZI-V3TzFDcs6nkdX9b81DwrAwwFzx0EfNvK1GLVWl59Ow85muoRTBA1q8SsZImxdyZ-TApTVlMYIQbdI4iQRwU9OmmtefrCe~ZOf4UBS9-KvNIqUL0XeBSqm0OU1jq-D10Ykg6KfqvuPnBYT1BYHFDQJXW5DdPKwcaQE4MtAdSGmj1epDoaEBUa9btQlFsM2l9Cyn1hzxqNWXELmx8dRlomQLlV4b586dRzW~fLlOPIGC13ntPXogvYvHVyEyptXkv890jC7DZNHyxZd5cyrKC36r9huKvhQAmNABT2Y~pOGwVrb~RpPwT0tBuPZ3lHYhBFYmD8y~AOhhNHKMLzea1rfwTvovBMByDdFps54gMN1mX4MbCGT4w70vIopS9yAAAA.i2p/bytemonsoon/announce.php"
// , "mastertracker", "http://VzXD~stRKbL3MOmeTn1iaCQ0CFyTmuFHiKYyo0Rd~dFPZFCYH-22rT8JD7i-C2xzYFa4jT5U2aqHzHI-Jre4HL3Ri5hFtZrLk2ax3ji7Qfb6qPnuYkuiF2E2UDmKUOppI8d9Ye7tjdhQVCy0izn55tBaB-U7UWdcvSK2i85sauyw3G0Gfads1Rvy5-CAe2paqyYATcDmGjpUNLoxbfv9KH1KmwRTNH6k1v4PyWYYnhbT39WfKMbBjSxVQRdi19cyJrULSWhjxaQfJHeWx5Z8Ev4bSPByBeQBFl2~4vqy0S5RypINsRSa3MZdbiAAyn5tr5slWR6QdoqY3qBQgBJFZppy-3iWkFqqKgSxCPundF8gdDLC5ddizl~KYcYKl42y9SGFHIukH-TZs8~em0~iahzsqWVRks3zRG~tlBcX2U3M2~OJs~C33-NKhyfZT7-XFBREvb8Szmd~p66jDxrwOnKaku-G6DyoQipJqIz4VHmY9-y5T8RrUcJcM-5lVoMpAAAA.i2p/announce.php=http://tracker.mastertracker.i2p/"
// , "Galen", "http://5jpwQMI5FT303YwKa5Rd38PYSX04pbIKgTaKQsWbqoWjIfoancFdWCShXHLI5G5ofOb0Xu11vl2VEMyPsg1jUFYSVnu4-VfMe3y4TKTR6DTpetWrnmEK6m2UXh91J5DZJAKlgmO7UdsFlBkQfR2rY853-DfbJtQIFl91tbsmjcA5CGQi4VxMFyIkBzv-pCsuLQiZqOwWasTlnzey8GcDAPG1LDcvfflGV~6F5no9mnuisZPteZKlrv~~TDoXTj74QjByWc4EOYlwqK8sbU9aOvz~s31XzErbPTfwiawiaZ0RUI-IDrKgyvmj0neuFTWgjRGVTH8bz7cBZIc3viy6ioD-eMQOrXaQL0TCWZUelRwHRvgdPiQrxdYQs7ixkajeHzxi-Pq0EMm5Vbh3j3Q9kfUFW3JjFDA-MLB4g6XnjCbM5J1rC0oOBDCIEfhQkszru5cyLjHiZ5yeA0VThgu~c7xKHybv~OMXION7V8pBKOgET7ZgAkw1xgYe3Kkyq5syAAAA.i2p/tr/announce.php=http://galen.i2p/tr/"
"Postman", "http://tracker2.postman.i2p/announce.php=http://tracker2.postman.i2p/"
,"Welterde", "http://tracker.welterde.i2p/a=http://tracker.welterde.i2p/stats?mode=top5"
,"Diftracker", "http://n--XWjHjUPjnMNrSwXA2OYXpMIUL~u4FNXnrt2HtjK3y6j~4SOClyyeKzd0zRPlixxkCe2wfBIYye3bZsaqAD8bd0QMmowxbq91WpjsPfKMiphJbePKXtYAVARiy0cqyvh1d2LyDE-6wkvgaw45hknmS0U-Dg3YTJZbAQRU2SKXgIlAbWCv4R0kDFBLEVpReDiJef3rzAWHiW8yjmJuJilkYjMwlfRjw8xx1nl2s~yhlljk1pl13jGYb0nfawQnuOWeP-ASQWvAAyVgKvZRJE2O43S7iveu9piuv7plXWbt36ef7ndu2GNoNyPOBdpo9KUZ-NOXm4Kgh659YtEibL15dEPAOdxprY0sYUurVw8OIWqrpX7yn08nbi6qHVGqQwTpxH35vkL8qrCbm-ym7oQJQnNmSDrNTyWYRFSq5s5~7DAdFDzqRPW-pX~g0zEivWj5tzkhvG9rVFgFo0bpQX3X0PUAV9Xbyf8u~v8Zbr9K1pCPqBq9XEr4TqaLHw~bfAAAA.i2p/announce.php=http://diftracker.i2p/"
// , "CRSTRACK", "http://b4G9sCdtfvccMAXh~SaZrPqVQNyGQbhbYMbw6supq2XGzbjU4NcOmjFI0vxQ8w1L05twmkOvg5QERcX6Mi8NQrWnR0stLExu2LucUXg1aYjnggxIR8TIOGygZVIMV3STKH4UQXD--wz0BUrqaLxPhrm2Eh9Hwc8TdB6Na4ShQUq5Xm8D4elzNUVdpM~RtChEyJWuQvoGAHY3ppX-EJJLkiSr1t77neS4Lc-KofMVmgI9a2tSSpNAagBiNI6Ak9L1T0F9uxeDfEG9bBSQPNMOSUbAoEcNxtt7xOW~cNOAyMyGydwPMnrQ5kIYPY8Pd3XudEko970vE0D6gO19yoBMJpKx6Dh50DGgybLQ9CpRaynh2zPULTHxm8rneOGRcQo8D3mE7FQ92m54~SvfjXjD2TwAVGI~ae~n9HDxt8uxOecAAvjjJ3TD4XM63Q9TmB38RmGNzNLDBQMEmJFpqQU8YeuhnS54IVdUoVQFqui5SfDeLXlSkh4vYoMU66pvBfWbAAAA.i2p/tracker/announce.php=http://crstrack.i2p/tracker/"
// ,"Exotrack", "http://blbgywsjubw3d2zih2giokakhe3o2cko7jtte4risb3hohbcoyva.b32.i2p/announce.php=http://exotrack.i2p/"
};
/** comma delimited list of name=announceURL=baseURL for the trackers to be displayed */
public static final String PROP_TRACKERS = "i2psnark.trackers";
private static Map<String, String> trackerMap = null;
/** sorted map of name to announceURL=baseURL */
public Map<String, String> getTrackers() {
if (trackerMap != null) // only do this once, can't be updated while running
return trackerMap;
Map<String, String> rv = new TreeMap();
return _trackerMap;
}
/** @since 0.9 */
private void initTrackerMap() {
String trackers = _config.getProperty(PROP_TRACKERS);
if ( (trackers == null) || (trackers.trim().length() <= 0) )
trackers = _context.getProperty(PROP_TRACKERS);
_trackerMap.clear();
if ( (trackers == null) || (trackers.trim().length() <= 0) ) {
for (int i = 0; i < DEFAULT_TRACKERS.length; i += 2)
rv.put(DEFAULT_TRACKERS[i], DEFAULT_TRACKERS[i+1]);
_trackerMap.put(DEFAULT_TRACKERS[i], DEFAULT_TRACKERS[i+1]);
} else {
StringTokenizer tok = new StringTokenizer(trackers, ",");
while (tok.hasMoreTokens()) {
String pair = tok.nextToken();
int split = pair.indexOf('=');
if (split <= 0)
continue;
String name = pair.substring(0, split).trim();
String url = pair.substring(split+1).trim();
String[] toks = trackers.split(",");
for (int i = 0; i < toks.length; i += 2) {
String name = toks[i].trim().replace("&#44;", ",");
String url = toks[i+1].trim().replace("&#44;", ",");
if ( (name.length() > 0) && (url.length() > 0) )
rv.put(name, url);
_trackerMap.put(name, url);
}
}
trackerMap = rv;
return trackerMap;
}
/** @since 0.9 */
public void setDefaultTrackerMap() {
_trackerMap.clear();
for (int i = 0; i < DEFAULT_TRACKERS.length; i += 2) {
_trackerMap.put(DEFAULT_TRACKERS[i], DEFAULT_TRACKERS[i+1]);
}
if (_config.remove(PROP_TRACKERS) != null) {
saveConfig();
}
}
/** @since 0.9 */
public void saveTrackerMap() {
StringBuilder buf = new StringBuilder(2048);
boolean comma = false;
for (Map.Entry<String, String> e : _trackerMap.entrySet()) {
if (comma)
buf.append(',');
else
comma = true;
buf.append(e.getKey().replace(",", "&#44;")).append(',').append(e.getValue().replace(",", "&#44;"));
}
_config.setProperty(PROP_TRACKERS, buf.toString());
saveConfig();
}
private static class TorrentFilenameFilter implements FilenameFilter {
private static final TorrentFilenameFilter _filter = new TorrentFilenameFilter();
public static TorrentFilenameFilter instance() { return _filter; }
@@ -1426,4 +1461,14 @@ public class SnarkManager implements Snark.CompleteListener {
}
}
}
/**
* ignore case, current locale
* @since 0.9
*/
private static class IgnoreCaseComparator implements Comparator<String> {
public int compare(String l, String r) {
return l.toLowerCase().compareTo(r.toLowerCase());
}
}
}

View File

@@ -101,7 +101,8 @@ public class Storage
* @param announce may be null
* @param listener may be null
*/
public Storage(I2PSnarkUtil util, File baseFile, String announce, StorageListener listener)
public Storage(I2PSnarkUtil util, File baseFile, String announce,
boolean privateTorrent, StorageListener listener)
throws IOException
{
_util = util;
@@ -157,7 +158,7 @@ public class Storage
byte[] piece_hashes = fast_digestCreate();
metainfo = new MetaInfo(announce, baseFile.getName(), null, files,
lengthsList, piece_size, piece_hashes, total);
lengthsList, piece_size, piece_hashes, total, privateTorrent);
}

View File

@@ -156,7 +156,7 @@ public class TrackerClient extends I2PAppThread
primary = "";
}
List tlist = _util.getOpenTrackers();
if (tlist != null) {
if (tlist != null && (meta == null || !meta.isPrivate())) {
for (int i = 0; i < tlist.size(); i++) {
String url = (String)tlist.get(i);
if (!isValidAnnounce(url)) {
@@ -348,7 +348,7 @@ public class TrackerClient extends I2PAppThread
} // *** end of trackers loop here
// Get peers from PEX
if (left > 0 && coordinator.needPeers() && !stop) {
if (left > 0 && coordinator.needPeers() && (!meta.isPrivate()) && !stop) {
Set<PeerID> pids = coordinator.getPEXPeers();
if (!pids.isEmpty()) {
_util.debug("Got " + pids.size() + " from PEX", Snark.INFO);
@@ -370,7 +370,7 @@ public class TrackerClient extends I2PAppThread
// Get peers from DHT
// FIXME this needs to be in its own thread
if (_util.getDHT() != null && !stop) {
if (_util.getDHT() != null && (!meta.isPrivate()) && !stop) {
int numwant;
if (left == 0 || event.equals(STOPPED_EVENT) || !coordinator.needPeers())
numwant = 1;
@@ -444,22 +444,33 @@ public class TrackerClient extends I2PAppThread
long downloaded, long left, String event)
throws IOException
{
// What do we send for left in magnet mode? Can we omit it?
long tleft = left >= 0 ? left : 1;
String s = tr.announce
+ "?info_hash=" + infoHash
+ "&peer_id=" + peerID
+ "&port=" + port
+ "&ip=" + _util.getOurIPString() + ".i2p"
+ "&uploaded=" + uploaded
+ "&downloaded=" + downloaded
+ "&left=" + tleft
+ "&compact=1" // NOTE: opentracker will return 400 for &compact alone
+ ((! event.equals(NO_EVENT)) ? ("&event=" + event) : "");
if (left == 0 || event.equals(STOPPED_EVENT) || !coordinator.needPeers())
s += "&numwant=0";
StringBuilder buf = new StringBuilder(512);
buf.append(tr.announce);
if (tr.announce.contains("?"))
buf.append('&');
else
s += "&numwant=" + _util.getMaxConnections();
buf.append('?');
buf.append("info_hash=").append(infoHash)
.append("&peer_id=").append(peerID)
.append("&port=").append(port)
.append("&ip=" ).append(_util.getOurIPString()).append(".i2p")
.append("&uploaded=").append(uploaded)
.append("&downloaded=").append(downloaded)
.append("&left=");
// What do we send for left in magnet mode? Can we omit it?
if (left >= 0)
buf.append(left);
else
buf.append('1');
buf.append("&compact=1"); // NOTE: opentracker will return 400 for &compact alone
if (! event.equals(NO_EVENT))
buf.append("&event=").append(event);
buf.append("&numwant=");
if (left == 0 || event.equals(STOPPED_EVENT) || !coordinator.needPeers())
buf.append('0');
else
buf.append(_util.getMaxConnections());
String s = buf.toString();
_util.debug("Sending TrackerClient request: " + s, Snark.INFO);
tr.lastRequestTime = System.currentTimeMillis();

View File

@@ -43,17 +43,16 @@ import org.klomp.snark.SnarkManager;
import org.klomp.snark.Storage;
import org.klomp.snark.TrackerClient;
import org.mortbay.http.HttpResponse;
import org.mortbay.jetty.servlet.Default;
import org.mortbay.util.Resource;
import org.mortbay.util.URI;
import org.mortbay.jetty.servlet.DefaultServlet;
import org.mortbay.resource.Resource;
import org.mortbay.util.URIUtil;
/**
* We extend Default instead of HTTPServlet so we can handle
* i2psnark/ file requests with http:// instead of the flaky and
* often-blocked-by-the-browser file://
*/
public class I2PSnarkServlet extends Default {
public class I2PSnarkServlet extends DefaultServlet {
private I2PAppContext _context;
private Log _log;
private SnarkManager _manager;
@@ -99,13 +98,17 @@ public class I2PSnarkServlet extends Default {
* and we can't get any resources (like icons) out of the .war
*/
@Override
protected Resource getResource(String pathInContext) throws IOException
public Resource getResource(String pathInContext)
{
if (pathInContext == null || pathInContext.equals("/") || pathInContext.equals("/index.jsp") ||
pathInContext.equals("/index.html") || pathInContext.startsWith("/_icons/"))
pathInContext.equals("/index.html") || pathInContext.startsWith("/.icons/"))
return super.getResource(pathInContext);
// files in the i2psnark/ directory
return _resourceBase.addPath(pathInContext);
try {
return _resourceBase.addPath(pathInContext);
} catch (IOException ioe) {
throw new RuntimeException(ioe);
}
}
/**
@@ -113,10 +116,8 @@ public class I2PSnarkServlet extends Default {
* @since 0.8.3
*/
@Override
public void handleGet(HttpServletRequest request, HttpServletResponse response, String pathInContext, Resource resource, boolean endsWithSlash) throws ServletException, IOException {
if (resource.getName().startsWith("jar:file:"))
response.setHeader("Cache-Control", "max-age=86400"); // cache for a day
super.handleGet(request, response, pathInContext, resource, endsWithSlash);
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
super.doGet(request, response);
}
/**
@@ -144,33 +145,46 @@ public class I2PSnarkServlet extends Default {
// since we are not overriding handle*(), do this here
String method = req.getMethod();
if (!(method.equals("GET") || method.equals("HEAD") || method.equals("POST"))) {
resp.sendError(HttpResponse.__405_Method_Not_Allowed);
resp.sendError(405);
return;
}
_themePath = "/themes/snark/" + _manager.getTheme() + '/';
_imgPath = _themePath + "images/";
// this is the part after /i2psnark
String path = req.getServletPath();
// AJAX for mainsection
if ("/.ajax/xhr1.html".equals(path)) {
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html; charset=UTF-8");
PrintWriter out = resp.getWriter();
//if (_log.shouldLog(Log.DEBUG))
// _manager.addMessage((_context.clock().now() / 1000) + " xhr1 p=" + req.getParameter("p"));
writeMessages(out);
writeTorrents(out, req);
return;
}
boolean isConfigure = "/configure".equals(path);
// index.jsp doesn't work, it is grabbed by the war handler before here
if (!(path == null || path.equals("/") || path.equals("/index.jsp") || path.equals("/index.html") || path.equals("/_post") || isConfigure)) {
if (path.endsWith("/")) {
// bypass the horrid Resource.getListHTML()
String pathInfo = req.getPathInfo();
String pathInContext = URI.addPaths(path, pathInfo);
String pathInContext = URIUtil.addPaths(path, pathInfo);
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html; charset=UTF-8");
Resource resource = getResource(pathInContext);
if (resource == null || (!resource.exists())) {
resp.sendError(HttpResponse.__404_Not_Found);
resp.sendError(404);
} else {
String base = URI.addPaths(req.getRequestURI(), "/");
String base = URIUtil.addPaths(req.getRequestURI(), "/");
String listing = getListHTML(resource, base, true, method.equals("POST") ? req.getParameterMap() : null);
if (listing != null)
resp.getWriter().write(listing);
else // shouldn't happen
resp.sendError(HttpResponse.__404_Not_Found);
resp.sendError(404);
}
} else {
super.service(req, resp);
@@ -192,7 +206,8 @@ public class I2PSnarkServlet extends Default {
String peerParam = req.getParameter("p");
String peerString;
if (peerParam == null || !_manager.util().connected()) {
if (peerParam == null || (!_manager.util().connected()) ||
peerParam.replaceAll("[a-zA-Z0-9~=-]", "").length() > 0) { // XSS
peerString = "";
} else {
peerString = "?p=" + peerParam;
@@ -208,13 +223,24 @@ public class I2PSnarkServlet extends Default {
out.write("</title>\n");
// we want it to go to the base URI so we don't refresh with some funky action= value
int delay = 0;
if (!isConfigure) {
int delay = _manager.getRefreshDelaySeconds();
if (delay > 0)
out.write("<meta http-equiv=\"refresh\" content=\"" + delay + ";/i2psnark/" + peerString + "\">\n");
delay = _manager.getRefreshDelaySeconds();
if (delay > 0) {
//out.write("<meta http-equiv=\"refresh\" content=\"" + delay + ";/i2psnark/" + peerString + "\">\n");
out.write("<script src=\"/js/ajax.js\" type=\"text/javascript\"></script>\n" +
"<script type=\"text/javascript\">\n" +
"var failMessage = \"<b>" + _("Router is down") + "<\\/b>\";\n" +
"function requestAjax1() { ajax(\"/i2psnark/.ajax/xhr1.html" + peerString + "\", \"mainsection\", " + (delay*1000) + "); }\n" +
"function initAjax(delayMs) { setTimeout(requestAjax1, " + (delay*1000) +"); }\n" +
"</script>\n");
}
}
out.write(HEADER_A + _themePath + HEADER_B);
out.write("</head><body>");
out.write(HEADER_A + _themePath + HEADER_B + "</head>\n");
if (isConfigure || delay <= 0)
out.write("<body>");
else
out.write("<body onload=\"initAjax()\">");
out.write("<center>");
if (isConfigure) {
out.write("<div class=\"snarknavbar\"><a href=\"/i2psnark/\" title=\"");
@@ -249,25 +275,36 @@ public class I2PSnarkServlet extends Default {
String newURL = req.getParameter("newURL");
if (newURL != null && newURL.trim().length() > 0 && req.getMethod().equals("GET"))
_manager.addMessage(_("Click \"Add torrent\" button to fetch torrent"));
out.write("<div class=\"page\"><div class=\"mainsection\"><div class=\"snarkMessages\"><table><tr><td align=\"left\"><pre>");
out.write("<div class=\"page\"><div id=\"mainsection\" class=\"mainsection\">");
writeMessages(out);
if (isConfigure) {
// end of mainsection div
out.write("<div class=\"logshim\"></div></div>\n");
writeConfigForm(out, req);
writeTrackerForm(out, req);
} else {
writeTorrents(out, req);
// end of mainsection div
out.write("</div><div id=\"lowersection\">\n");
writeAddForm(out, req);
writeSeedForm(out, req);
writeConfigLink(out);
// end of lowersection div
out.write("</div>\n");
}
out.write(FOOTER);
}
private void writeMessages(PrintWriter out) throws IOException {
out.write("<div class=\"snarkMessages\"><table><tr><td align=\"left\"><pre>");
List msgs = _manager.getMessages();
for (int i = msgs.size()-1; i >= 0; i--) {
String msg = (String)msgs.get(i);
out.write(msg + "\n");
}
out.write("</pre></td></tr></table></div>");
if (isConfigure) {
out.write("<div class=\"logshim\"></div></div>\n");
writeConfigForm(out, req);
} else {
writeTorrents(out, req);
out.write("</div>\n");
writeAddForm(out, req);
writeSeedForm(out, req);
writeConfigLink(out);
}
out.write(FOOTER);
}
private void writeTorrents(PrintWriter out, HttpServletRequest req) throws IOException {
@@ -276,7 +313,6 @@ public class I2PSnarkServlet extends Default {
String peerParam = req.getParameter("p");
List snarks = getSortedSnarks(req);
String uri = req.getRequestURI();
boolean isForm = _manager.util().connected() || !snarks.isEmpty();
if (isForm) {
out.write("<form action=\"_post\" method=\"POST\">\n");
@@ -390,6 +426,7 @@ public class I2PSnarkServlet extends Default {
out.write("&nbsp;");
}
out.write("</th></tr></thead>\n");
String uri = "/i2psnark/";
for (int i = 0; i < snarks.size(); i++) {
Snark snark = (Snark)snarks.get(i);
boolean showDebug = "2".equals(peerParam);
@@ -650,14 +687,19 @@ public class I2PSnarkServlet extends Default {
_manager.updateConfig(dataDir, filesPublic, autoStart, refreshDel, startupDel,
seedPct, eepHost, eepPort, i2cpHost, i2cpPort, i2cpOpts,
upLimit, upBW, useOpenTrackers, openTrackers, theme);
} else if ("Save2".equals(action)) {
String taction = req.getParameter("taction");
if (taction != null)
processTrackerForm(taction, req);
} else if ("Create".equals(action)) {
String baseData = req.getParameter("baseFile");
if (baseData != null && baseData.trim().length() > 0) {
File baseFile = new File(_manager.getDataDir(), baseData);
String announceURL = req.getParameter("announceURL");
String announceURLOther = req.getParameter("announceURLOther");
if ( (announceURLOther != null) && (announceURLOther.trim().length() > "http://.i2p/announce".length()) )
announceURL = announceURLOther;
// make the user add a tracker on the config form now
//String announceURLOther = req.getParameter("announceURLOther");
//if ( (announceURLOther != null) && (announceURLOther.trim().length() > "http://.i2p/announce".length()) )
// announceURL = announceURLOther;
if (announceURL == null || announceURL.length() <= 0)
_manager.addMessage(_("Error creating torrent - you must select a tracker"));
@@ -668,7 +710,7 @@ public class I2PSnarkServlet extends Default {
try {
// This may take a long time to check the storage, but since it already exists,
// it shouldn't be THAT bad, so keep it in this thread.
Storage s = new Storage(_manager.util(), baseFile, announceURL, null);
Storage s = new Storage(_manager.util(), baseFile, announceURL, req.getParameter("private") != null, null);
s.close(); // close the files... maybe need a way to pass this Storage to addTorrent rather than starting over
MetaInfo info = s.getMetaInfo();
File torrentFile = new File(_manager.getDataDir(), s.getBaseName() + ".torrent");
@@ -713,6 +755,54 @@ public class I2PSnarkServlet extends Default {
_manager.addMessage("Unknown POST action: \"" + action + '\"');
}
}
/** @since 0.9 */
private void processTrackerForm(String action, HttpServletRequest req) {
if (action.equals(_("Delete selected"))) {
boolean changed = false;
Map<String, String> trackers = _manager.getTrackers();
Enumeration e = req.getParameterNames();
while (e.hasMoreElements()) {
Object o = e.nextElement();
if (!(o instanceof String))
continue;
String k = (String) o;
if (!k.startsWith("delete_"))
continue;
k = k.substring(7);
if (trackers.remove(k) != null) {
_manager.addMessage(_("Removed") + ": " + k);
changed = true;
}
}
if (changed) {
_manager.saveTrackerMap();
}
} else if (action.equals(_("Add tracker"))) {
String name = req.getParameter("tname");
String hurl = req.getParameter("thurl");
String aurl = req.getParameter("taurl");
if (name != null && hurl != null && aurl != null) {
name = name.trim();
hurl = hurl.trim();
aurl = aurl.trim().replace("=", "&#61;");
if (name.length() > 0 && hurl.startsWith("http://") && aurl.startsWith("http://")) {
Map<String, String> trackers = _manager.getTrackers();
trackers.put(name, aurl + '=' + hurl);
_manager.saveTrackerMap();
} else {
_manager.addMessage(_("Enter valid tracker name and URLs"));
}
} else {
_manager.addMessage(_("Enter valid tracker name and URLs"));
}
} else if (action.equals(_("Restore defaults"))) {
_manager.setDefaultTrackerMap();
_manager.addMessage(_("Restored default trackers"));
} else {
_manager.addMessage("Unknown POST action: \"" + action + '\"');
}
}
private static final String iopts[] = {"inbound.length", "inbound.quantity",
"outbound.length", "outbound.quantity" };
@@ -1222,7 +1312,7 @@ public class I2PSnarkServlet extends Default {
out.write("\"> \n");
// not supporting from file at the moment, since the file name passed isn't always absolute (so it may not resolve)
//out.write("From file: <input type=\"file\" name=\"newFile\" size=\"50\" value=\"" + newFile + "\" /><br>");
out.write("<input type=\"submit\" value=\"");
out.write("<input type=\"submit\" class=\"add\" value=\"");
out.write(_("Add torrent"));
out.write("\" name=\"foo\" ><br>\n");
out.write("<tr><td>&nbsp;<td><span class=\"snarkAddInfo\">");
@@ -1269,31 +1359,40 @@ public class I2PSnarkServlet extends Default {
//out.write(_("Open trackers and DHT only"));
out.write(_("Open trackers only"));
out.write("</option>\n");
Map trackers = _manager.getTrackers();
for (Iterator iter = trackers.entrySet().iterator(); iter.hasNext(); ) {
Map.Entry entry = (Map.Entry)iter.next();
String name = (String)entry.getKey();
String announceURL = (String)entry.getValue();
Map<String, String> trackers = _manager.getTrackers();
for (Map.Entry<String, String> entry : trackers.entrySet()) {
String name = entry.getKey();
String announceURL = entry.getValue();
int e = announceURL.indexOf('=');
if (e > 0)
announceURL = announceURL.substring(0, e);
announceURL = announceURL.substring(0, e).replace("&#61;", "=");
if (announceURL.equals(_lastAnnounceURL))
announceURL += "\" selected=\"selected";
out.write("\t<option value=\"" + announceURL + "\">" + name + "</option>\n");
}
out.write("</select>\n");
out.write(_("or"));
out.write("&nbsp;<input type=\"text\" name=\"announceURLOther\" size=\"57\" value=\"http://\" " +
"title=\"");
out.write(_("Specify custom tracker announce URL"));
out.write("\" > " +
"<input type=\"submit\" value=\"");
// make the user add a tracker on the config form now
//out.write(_("or"));
//out.write("&nbsp;<input type=\"text\" name=\"announceURLOther\" size=\"57\" value=\"http://\" " +
// "title=\"");
//out.write(_("Specify custom tracker announce URL"));
//out.write("\" > " +
out.write(" <input type=\"submit\" class=\"create\" value=\"");
out.write(_("Create torrent"));
out.write("\" name=\"foo\" ></table>\n" +
out.write("\" name=\"foo\" >\n" +
"</td></tr><tr><td>");
out.write(_("Private?"));
out.write(" </td><td> <input type=\"checkbox\" class=\"optbox\" name=\"private\" value=\"true\" title=\"");
out.write(_("Use for private trackers"));
out.write("\"");
if (req.getParameter("private") != null)
out.write(" checked");
out.write("></td></tr>" +
"</table>\n" +
"</form></div></div>");
}
private static final int[] times = { 30, 60, 2*60, 5*60, 10*60, 30*60, -1 };
private static final int[] times = { 5, 15, 30, 60, 2*60, 5*60, 10*60, 30*60, -1 };
private void writeConfigForm(PrintWriter out, HttpServletRequest req) throws IOException {
String dataDir = _manager.getDataDir().getAbsolutePath();
@@ -1356,7 +1455,7 @@ public class I2PSnarkServlet extends Default {
out.write(Integer.toString(times[i]));
out.write("\"");
if (times[i] == delay)
out.write(" selected=\"true\"");
out.write(" selected=\"selected\"");
out.write(">");
if (times[i] > 0)
out.write(DataHelper.formatDuration2(times[i] * 1000));
@@ -1379,15 +1478,15 @@ public class I2PSnarkServlet extends Default {
/*
out.write("Seed percentage: <select name=\"seedPct\" disabled=\"true\" >\n\t");
if (seedPct <= 0)
out.write("<option value=\"0\" selected=\"true\">Unlimited</option>\n\t");
out.write("<option value=\"0\" selected=\"selected\">Unlimited</option>\n\t");
else
out.write("<option value=\"0\">Unlimited</option>\n\t");
if (seedPct == 100)
out.write("<option value=\"100\" selected=\"true\">100%</option>\n\t");
out.write("<option value=\"100\" selected=\"selected\">100%</option>\n\t");
else
out.write("<option value=\"100\">100%</option>\n\t");
if (seedPct == 150)
out.write("<option value=\"150\" selected=\"true\">150%</option>\n\t");
out.write("<option value=\"150\" selected=\"selected\">150%</option>\n\t");
else
out.write("<option value=\"150\">150%</option>\n\t");
out.write("</select><br>\n");
@@ -1473,6 +1572,57 @@ public class I2PSnarkServlet extends Default {
"</table></div></div></form>");
}
/** @since 0.9 */
private void writeTrackerForm(PrintWriter out, HttpServletRequest req) throws IOException {
StringBuilder buf = new StringBuilder(1024);
buf.append("<form action=\"/i2psnark/configure\" method=\"POST\">\n" +
"<div class=\"configsectionpanel\"><div class=\"snarkConfig\">\n" +
"<input type=\"hidden\" name=\"nonce\" value=\"" + _nonce + "\" >\n" +
"<input type=\"hidden\" name=\"action\" value=\"Save2\" >\n" +
"<span class=\"snarkConfigTitle\">" +
"<img alt=\"\" border=\"0\" src=\"" + _imgPath + "config.png\"> ");
buf.append(_("Trackers"));
buf.append("</span><hr>\n" +
"<table><tr><th>")
//.append(_("Remove"))
.append("</th><th>")
.append(_("Name"))
.append("</th><th>")
.append(_("Website URL"))
.append("</th><th>")
.append(_("Announce URL"))
.append("</th></tr>\n");
Map<String, String> trackers = _manager.getTrackers();
for (Map.Entry<String, String> entry : trackers.entrySet()) {
String name = entry.getKey();
String announceURL = entry.getValue();
int e = announceURL.indexOf('=');
if (e <= 0)
continue;
String homeURL = announceURL.substring(e + 1);
announceURL = announceURL.substring(0, e).replace("&#61;", "=");
buf.append("<tr><td align=\"center\"><input type=\"checkbox\" class=\"optbox\" name=\"delete_")
.append(name).append("\">" +
"</td><td align=\"left\">").append(name)
.append("</td><td align=\"left\">").append(urlify(homeURL, 35))
.append("</td><td align=\"left\">").append(urlify(announceURL, 35))
.append("</td></tr>\n");
}
buf.append("<tr><td align=\"center\"><b>")
.append(_("Add")).append(":</b></td>" +
"<td align=\"left\"><input type=\"text\" size=\"16\" name=\"tname\"></td>" +
"<td align=\"left\"><input type=\"text\" size=\"40\" name=\"thurl\"></td>" +
"<td align=\"left\"><input type=\"text\" size=\"40\" name=\"taurl\"></td></tr>\n" +
"<tr><td colspan=\"2\"></td><td colspan=\"2\" align=\"left\">\n" +
"<input type=\"submit\" name=\"taction\" class=\"default\" value=\"").append(_("Add tracker")).append("\">\n" +
"<input type=\"submit\" name=\"taction\" class=\"delete\" value=\"").append(_("Delete selected")).append("\">\n" +
// "<input type=\"reset\" class=\"cancel\" value=\"").append(_("Cancel")).append("\">\n" +
"<input type=\"submit\" name=\"taction\" class=\"reload\" value=\"").append(_("Restore defaults")).append("\">\n" +
"<input type=\"submit\" name=\"taction\" class=\"add\" value=\"").append(_("Add tracker")).append("\">\n" +
"</td></tr></table></div></div></form>\n");
out.write(buf.toString());
}
private void writeConfigLink(PrintWriter out) throws IOException {
out.write("<div class=\"configsection\"><span class=\"snarkConfig\">\n" +
"<span class=\"snarkConfigTitle\"><a href=\"configure\">" +
@@ -1574,7 +1724,7 @@ public class I2PSnarkServlet extends Default {
for (int i = min; i <= max; i++) {
buf.append("<option value=\"").append(i).append("\" ");
if (i == now)
buf.append("selected=\"true\" ");
buf.append("selected=\"selected\" ");
// constants to prevent tagging
buf.append(">").append(ngettext(DUMMY1 + name, DUMMY0 + name + 's', i));
buf.append("</option>\n");
@@ -1622,16 +1772,26 @@ public class I2PSnarkServlet extends Default {
/** @since 0.7.14 */
private static String urlify(String s) {
return urlify(s, 100);
}
/** @since 0.9 */
private static String urlify(String s, int max) {
StringBuilder buf = new StringBuilder(256);
// browsers seem to work without doing this but let's be strict
String link = urlEncode(s);
buf.append("<a href=\"").append(link).append("\">").append(link).append("</a>");
String display;
if (s.length() <= max)
display = link;
else
display = urlEncode(s.substring(0, max)) + "&hellip;";
buf.append("<a href=\"").append(link).append("\">").append(display).append("</a>");
return buf.toString();
}
/** @since 0.8.13 */
private static String urlEncode(String s) {
return s.replace("&", "&amp;").replace(" ", "%20").replace(":", "%3A").replace("/", "%2F").replace(";", "%3B");
return s.replace(";", "%3B").replace("&", "&amp;").replace(" ", "%20");
}
private static final String DOCTYPE = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
@@ -1686,7 +1846,7 @@ public class I2PSnarkServlet extends Default {
StringBuilder buf=new StringBuilder(4096);
buf.append(DOCTYPE + "<HTML><HEAD><TITLE>");
String title = URI.decodePath(base);
String title = URIUtil.decodePath(base);
if (title.startsWith("/i2psnark/"))
title = title.substring("/i2psnark/".length());
@@ -1795,7 +1955,7 @@ public class I2PSnarkServlet extends Default {
.append(_("Priority")).append("</th>");
buf.append("</tr></thead>\n");
buf.append("<tr><td colspan=\"" + (showPriority ? '4' : '3') + "\" class=\"ParentDir\"><A HREF=\"");
buf.append(URI.addPaths(base,"../"));
buf.append(URIUtil.addPaths(base,"../"));
buf.append("\"><img alt=\"\" border=\"0\" src=\"" + _imgPath + "up.png\"> ")
.append(_("Up to higher level directory")).append("</A></td></tr>\n");
@@ -1805,7 +1965,7 @@ public class I2PSnarkServlet extends Default {
boolean showSaveButton = false;
for (int i=0 ; i< ls.length ; i++)
{
String encoded=URI.encodePath(ls[i]);
String encoded=URIUtil.encodePath(ls[i]);
// bugfix for I2P - Backport from Jetty 6 (zero file lengths and last-modified times)
// http://jira.codehaus.org/browse/JETTY-361?page=com.atlassian.jira.plugin.system.issuetabpanels%3Achangehistory-tabpanel#issue-tabs
// See resource.diff attachment
@@ -1861,9 +2021,9 @@ public class I2PSnarkServlet extends Default {
}
}
String path=URI.addPaths(base,encoded);
String path=URIUtil.addPaths(base,encoded);
if (item.isDirectory() && !path.endsWith("/"))
path=URI.addPaths(path,"/");
path=URIUtil.addPaths(path,"/");
String icon = toIcon(item);
if (complete) {
@@ -1991,12 +2151,12 @@ public class I2PSnarkServlet extends Default {
/** @since 0.7.14 */
private static String toImg(String icon) {
return "<img alt=\"\" height=\"16\" width=\"16\" src=\"/i2psnark/_icons/" + icon + ".png\">";
return "<img alt=\"\" height=\"16\" width=\"16\" src=\"/i2psnark/.icons/" + icon + ".png\">";
}
/** @since 0.8.2 */
private static String toImg(String icon, String altText) {
return "<img alt=\"" + altText + "\" height=\"16\" width=\"16\" src=\"/i2psnark/_icons/" + icon + ".png\">";
return "<img alt=\"" + altText + "\" height=\"16\" width=\"16\" src=\"/i2psnark/.icons/" + icon + ".png\">";
}
/** @since 0.8.1 */
@@ -2080,8 +2240,8 @@ private static class FetchAndAdd implements Runnable {
//if (peerParam != null)
// buf.append("<input type=\"hidden\" name=\"p\" value=\"").append(peerParam).append("\" >\n");
buf.append(_("Torrent was not retrieved from {0}", urlify(_url)));
String link = urlEncode(_url);
/**** FIXME ticket #575
String link = urlEncode(_url).replace(":", "%3A").replace("/", "%2F");
buf.append(" - [<a href=\"/i2psnark/?newURL=").append(link).append("#add\" >");
buf.append(_("Retry"));
buf.append("</a>]");

View File

@@ -31,6 +31,8 @@ public class RunStandalone {
if (!workDirCreated)
System.err.println("ERROR: Unable to create Jetty temporary work directory");
throw new RuntimeException("unsupported");
/****
try {
_server = new Server("jetty-i2psnark.xml");
// just blow up NPE if we don't have a context
@@ -39,13 +41,17 @@ public class RunStandalone {
} catch (Exception e) {
e.printStackTrace();
}
****/
}
public void stop() {
throw new RuntimeException("unsupported");
/****
try {
_server.stop();
} catch (InterruptedException ie) {
ie.printStackTrace();
}
****/
}
}

View File

@@ -0,0 +1,988 @@
# I2P
# Copyright (C) 2009 The I2P Project
# This file is distributed under the same license as the i2psnark package.
# To contribute translations, see http://www.i2p2.de/newdevelopers
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-02-17 11:41+0000\n"
"PO-Revision-Date: 2012-02-12 20:06+0000\n"
"Last-Translator: Waseihou Watashi <waseihou@gmail.com>\n"
"Language-Team: Czech (http://www.transifex.net/projects/p/I2P/language/cs/)\n"
"Language: cs\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2\n"
#: ../java/src/org/klomp/snark/SnarkManager.java:355
#, java-format
msgid "Total uploaders limit changed to {0}"
msgstr "Celkový limit sdílečů změněn na {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:357
#, java-format
msgid "Minimum total uploaders limit is {0}"
msgstr "Nejmenší celkový limit sdílečů je {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:369
#, java-format
msgid "Up BW limit changed to {0}KBps"
msgstr "Horní BW limit změněn na {0}KBps"
#: ../java/src/org/klomp/snark/SnarkManager.java:371
#, java-format
msgid "Minimum up bandwidth limit is {0}KBps"
msgstr "Nejmenší horní limit přenosové rychlist je {0}KBps"
#: ../java/src/org/klomp/snark/SnarkManager.java:383
#, java-format
msgid "Startup delay changed to {0}"
msgstr "Prodleva při startu změněna na {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:394
#, java-format
msgid "Refresh time changed to {0}"
msgstr "Doba aktualizace stavu (refresh time) změněna na {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:396
msgid "Refresh disabled"
msgstr "Aktualizace stavu vypnuta"
#: ../java/src/org/klomp/snark/SnarkManager.java:451
msgid "I2CP and tunnel changes will take effect after stopping all torrents"
msgstr "Změny I2CP a tunelu se projeví až po zastavení všech torrentů"
#: ../java/src/org/klomp/snark/SnarkManager.java:455
#, java-format
msgid "I2CP options changed to {0}"
msgstr "Nastavení (options) I2CP změněno na {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:460
msgid "Disconnecting old I2CP destination"
msgstr "Odpojuji se od starého I2CP cíle"
#: ../java/src/org/klomp/snark/SnarkManager.java:462
#, java-format
msgid "I2CP settings changed to {0}"
msgstr "Nastavení (settings) I2CP změněno na {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:467
msgid ""
"Unable to connect with the new settings, reverting to the old I2CP settings"
msgstr "Nemůžu se připojit s novým nastavením I2CP, vracím se k předhozímu."
#: ../java/src/org/klomp/snark/SnarkManager.java:471
msgid "Unable to reconnect with the old settings!"
msgstr "Nemohu se opětovně připojit ani s předchozím nastavením!"
#: ../java/src/org/klomp/snark/SnarkManager.java:473
msgid "Reconnected on the new I2CP destination"
msgstr "Opětovně připojeno k novému I2CP cíli"
#: ../java/src/org/klomp/snark/SnarkManager.java:480
#, java-format
msgid "I2CP listener restarted for \"{0}\""
msgstr "I2CP listener restartován pro \"{0}\""
#: ../java/src/org/klomp/snark/SnarkManager.java:492
msgid "New files will be publicly readable"
msgstr "Nové soubory budou veřejně přístupné"
#: ../java/src/org/klomp/snark/SnarkManager.java:494
msgid "New files will not be publicly readable"
msgstr "Nové soubory nebudou veřejně přístupné"
#: ../java/src/org/klomp/snark/SnarkManager.java:501
msgid "Enabled autostart"
msgstr "Automatické spuštění zapnuto"
#: ../java/src/org/klomp/snark/SnarkManager.java:503
msgid "Disabled autostart"
msgstr "Automatické spuštění vypnuto"
#: ../java/src/org/klomp/snark/SnarkManager.java:509
msgid "Enabled open trackers - torrent restart required to take effect."
msgstr "Zapnuto automatické spuštění"
#: ../java/src/org/klomp/snark/SnarkManager.java:511
msgid "Disabled open trackers - torrent restart required to take effect."
msgstr ""
"Otevřené trackery vypnuty - aby se změna projevila je nutné restartovat "
"všechny torrenty"
#: ../java/src/org/klomp/snark/SnarkManager.java:519
msgid "Open Tracker list changed - torrent restart required to take effect."
msgstr ""
"Seznam otevřených trackerů změněn - aby se změna projevila je nutné "
"restartovat všechny torrenty"
#: ../java/src/org/klomp/snark/SnarkManager.java:526
#, java-format
msgid "{0} theme loaded, return to main i2psnark page to view."
msgstr "Téma {0} bylo nahráno, přejděte prosím na hlavní stránku i2snark"
#: ../java/src/org/klomp/snark/SnarkManager.java:533
msgid "Configuration unchanged."
msgstr "Nastavení nebylo změněno."
#: ../java/src/org/klomp/snark/SnarkManager.java:543
#, java-format
msgid "Unable to save the config to {0}"
msgstr "Nemůžu uložit soubor s nastavením do souboru {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:608
msgid "Connecting to I2P"
msgstr "Připojuji se k I2P"
#: ../java/src/org/klomp/snark/SnarkManager.java:611
msgid "Error connecting to I2P - check your I2CP settings!"
msgstr ""
"Při připojování k I2P nastala chyba, zkontrolujte prosím nastavení I2CP!"
#: ../java/src/org/klomp/snark/SnarkManager.java:620
#, java-format
msgid "Error: Could not add the torrent {0}"
msgstr "Chyba: nepodařilo se přidat torrent {0}"
#. catch this here so we don't try do delete it below
#: ../java/src/org/klomp/snark/SnarkManager.java:642
#, java-format
msgid "Cannot open \"{0}\""
msgstr "Nejde otevřít \"{0}\""
#. TODO - if the existing one is a magnet, delete it and add the metainfo instead?
#: ../java/src/org/klomp/snark/SnarkManager.java:661
#: ../java/src/org/klomp/snark/SnarkManager.java:737
#: ../java/src/org/klomp/snark/SnarkManager.java:792
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2048
#, java-format
msgid "Torrent with this info hash is already running: {0}"
msgstr "Torrent s tímto infohašišem již běží: {0}"
#. addMessage(_("Warning - No I2P trackers in \"{0}\", will announce to I2P open trackers and DHT only.", info.getName()));
#: ../java/src/org/klomp/snark/SnarkManager.java:668
#, java-format
msgid ""
"Warning - No I2P trackers in \"{0}\", will announce to I2P open trackers "
"only."
msgstr ""
"Varování - v \"{0}\" nebyly nalezeny žádné I2P trackery, budou použity pouze "
"otevrené I2P trackery."
#. addMessage(_("Warning - No I2P trackers in \"{0}\", and DHT and open trackers are disabled, you should enable open trackers or DHT before starting the torrent.", info.getName()));
#: ../java/src/org/klomp/snark/SnarkManager.java:673
#, java-format
msgid ""
"Warning - No I2P Trackers found in \"{0}\". Make sure Open Tracker is "
"enabled before starting this torrent."
msgstr ""
"Varování - v \"{0}\" nebyly nalezeny žádné I2P trackery, před spuštěním "
"tohoto torrentu se ujistěte že otevřené trackery jsou povoleny."
#: ../java/src/org/klomp/snark/SnarkManager.java:694
#, java-format
msgid "Torrent in \"{0}\" is invalid"
msgstr "Torrent v \"{0}\" je chybný"
#: ../java/src/org/klomp/snark/SnarkManager.java:699
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2070
#, java-format
msgid "ERROR - Out of memory, cannot create torrent from {0}"
msgstr "CHYBA - nedostatek paměti, nemohu vytvořit torrent z {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:711
#, java-format
msgid "Torrent added and started: \"{0}\""
msgstr "Torrent přidán a spuštěn: \"{0}\""
#: ../java/src/org/klomp/snark/SnarkManager.java:713
#, java-format
msgid "Torrent added: \"{0}\""
msgstr "Torrent přidán: \"{0}\""
#: ../java/src/org/klomp/snark/SnarkManager.java:748
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:499
#, java-format
msgid "Fetching {0}"
msgstr "Získávám {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:751
#, java-format
msgid ""
"We have no saved peers and no other torrents are running. Fetch of {0} will "
"not succeed until you start another torrent."
msgstr ""
"Nejsou uloženi žádní sdíleči a žádné další torrenty neběží. Získání {0} "
"neuspěje dokud nespustíte nějaký další torrent."
#: ../java/src/org/klomp/snark/SnarkManager.java:755
#, java-format
msgid "Adding {0}"
msgstr "Přídávám {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:802
#: ../java/src/org/klomp/snark/SnarkManager.java:825
#: ../java/src/org/klomp/snark/SnarkManager.java:1260
#, java-format
msgid "Failed to copy torrent file to {0}"
msgstr "Chyba: nepodařilo se zkopírovat soubor torrentu do {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:1052
#, java-format
msgid "Too many files in \"{0}\" ({1}), deleting it!"
msgstr "V \"{0}\" ({1}) je příliš mnoho souborů, mažu je!"
#: ../java/src/org/klomp/snark/SnarkManager.java:1054
#, java-format
msgid "Torrent file \"{0}\" cannot end in \".torrent\", deleting it!"
msgstr "Jméno souboru torrentu \"{0}\" nemůže končit na \".torrent\", mažu ho!"
#: ../java/src/org/klomp/snark/SnarkManager.java:1056
#, java-format
msgid "No pieces in \"{0}\", deleting it!"
msgstr "\"{0}\" neobsahuje žádné části, mažu to!"
#: ../java/src/org/klomp/snark/SnarkManager.java:1058
#, java-format
msgid "Too many pieces in \"{0}\", limit is {1}, deleting it!"
msgstr "Příliš mnoho částí v \"{0}\", maximum je {1}, mažu to!"
#: ../java/src/org/klomp/snark/SnarkManager.java:1060
#, java-format
msgid "Pieces are too large in \"{0}\" ({1}B), deleting it."
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1061
#, java-format
msgid "Limit is {0}B"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1063
#, java-format
msgid "Torrent \"{0}\" has no data, deleting it!"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1071
#, java-format
msgid "Torrents larger than {0}B are not supported yet, deleting \"{1}\""
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1087
#, java-format
msgid "Error: Could not remove the torrent {0}"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1108
#: ../java/src/org/klomp/snark/SnarkManager.java:1126
#, java-format
msgid "Torrent stopped: \"{0}\""
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1147
#, java-format
msgid "Torrent removed: \"{0}\""
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1155
#, java-format
msgid "Adding torrents in {0}"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1208
#, java-format
msgid "Download finished: {0}"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1256
#, java-format
msgid "Metainfo received for {0}"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1257
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:534
#, java-format
msgid "Starting up torrent {0}"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1313
msgid "Unable to connect to I2P!"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1319
#, java-format
msgid "Unable to add {0}"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:205
msgid "I2PSnark - Anonymous BitTorrent Client"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:221
msgid "Torrents"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:224
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:231
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1053
msgid "I2PSnark"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:228
msgid "Refresh page"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:233
msgid "Forum"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:251
msgid "Click \"Add torrent\" button to fetch torrent"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:290
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1791
msgid "Status"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:296
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:298
msgid "Hide Peers"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:303
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:305
msgid "Show Peers"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:312
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1708
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1724
msgid "Torrent"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:316
msgid "Estimated time remaining"
msgstr ""
#. Translators: Please keep short or translate as " "
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:319
msgid "ETA"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:323
msgid "Downloaded"
msgstr ""
#. Translators: Please keep short or translate as " "
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:326
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:340
msgid "RX"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:330
msgid "Uploaded"
msgstr ""
#. Translators: Please keep short or translate as " "
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:333
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:350
msgid "TX"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:338
msgid "Down Rate"
msgstr ""
#. Translators: Please keep short or translate as " "
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:343
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:352
msgid "Rate"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:348
msgid "Up Rate"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:372
msgid "Stop all torrents and the I2P tunnel"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:374
msgid "Stop All"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:383
msgid "Start all torrents and the I2P tunnel"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:385
msgid "Start All"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:404
msgid "No torrents loaded."
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:409
msgid "Totals"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:411
#, java-format
msgid "1 torrent"
msgid_plural "{0} torrents"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:414
#, java-format
msgid "1 connected peer"
msgid_plural "{0} connected peers"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:498
msgid "Opening the I2P tunnel"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:505
#, java-format
msgid "Invalid URL: Must start with \"http://\", \"{0}\", or \"{1}\""
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:553
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:580
#, java-format
msgid "Magnet deleted: {0}"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:561
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:586
#, java-format
msgid "Torrent file deleted: {0}"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:592
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:603
#, java-format
msgid "Data file deleted: {0}"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:594
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:605
#, java-format
msgid "Data file could not be deleted: {0}"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:617
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:624
#, java-format
msgid "Data dir deleted: {0}"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:663
msgid "Error creating torrent - you must select a tracker"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:678
#, java-format
msgid "Torrent created for \"{0}\""
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:680
#, java-format
msgid ""
"Many I2P trackers require you to register new torrents before seeding - "
"please do so before starting \"{0}\""
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:682
#, java-format
msgid "Error creating a torrent for \"{0}\""
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:685
#, java-format
msgid "Cannot create a torrent for the nonexistent data: {0}"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:688
msgid "Error creating torrent - you must enter a file or directory"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:691
msgid "Stopping all torrents and closing the I2P tunnel."
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:702
msgid "I2P tunnel closed."
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:705
msgid "Opening the I2P tunnel and starting all torrents."
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:827
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:832
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:838
msgid "Tracker Error"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:830
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:834
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:846
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:850
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:858
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:862
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:867
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:871
#, java-format
msgid "1 peer"
msgid_plural "{0} peers"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:843
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:848
msgid "Seeding"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:852
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1730
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1842
msgid "Complete"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:855
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:860
msgid "OK"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:864
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:869
msgid "Stalled"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:873
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:876
msgid "No Peers"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:878
msgid "Stopped"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:911
msgid "Torrent details"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:923
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1187
msgid "Info"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:938
msgid "View files"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:940
msgid "Open file"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:982
msgid "Stop the torrent"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:984
msgid "Stop"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:994
msgid "Start the torrent"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:996
msgid "Start"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1007
msgid "Remove the torrent from the active list, deleting the .torrent file"
msgstr ""
#. Can't figure out how to escape double quotes inside the onclick string.
#. Single quotes in translate strings with parameters must be doubled.
#. Then the remaining single quite must be escaped
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1012
#, java-format
msgid ""
"Are you sure you want to delete the file \\''{0}.torrent\\'' (downloaded "
"data will not be deleted) ?"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1015
msgid "Remove"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1026
msgid "Delete the .torrent file and the associated data file(s)"
msgstr ""
#. Can't figure out how to escape double quotes inside the onclick string.
#. Single quotes in translate strings with parameters must be doubled.
#. Then the remaining single quite must be escaped
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1031
#, java-format
msgid ""
"Are you sure you want to delete the torrent \\''{0}\\'' and all downloaded "
"data?"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1034
msgid "Delete"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1069
msgid "Unknown"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1081
msgid "Seed"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1104
msgid "Uninteresting (The peer has no pieces we need)"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1106
msgid "Choked (The peer is not allowing us to request pieces)"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1126
msgid "Uninterested (We have no pieces the peer needs)"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1128
msgid "Choking (We are not allowing the peer to request pieces)"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1186
#, java-format
msgid "Details at {0} tracker"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1216
msgid "Add Torrent"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1218
msgid "From URL"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1221
msgid ""
"Enter the torrent file download URL (I2P only), magnet link, or maggot link"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1226
msgid "Add torrent"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1229
#, java-format
msgid "You can also copy .torrent files to: {0}."
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1231
msgid "Removing a .torrent will cause it to stop."
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1254
msgid "Create Torrent"
msgstr ""
#. out.write("From file: <input type=\"file\" name=\"newFile\" size=\"50\" value=\"" + newFile + "\" /><br>\n");
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1257
msgid "Data to seed"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1261
msgid "File or directory to seed (must be within the specified path)"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1263
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1749
msgid "Tracker"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1265
msgid "Select a tracker"
msgstr ""
#. out.write(_("Open trackers and DHT only"));
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1270
msgid "Open trackers only"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1285
msgid "or"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1288
msgid "Specify custom tracker announce URL"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1291
msgid "Create torrent"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1312
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1480
msgid "Configuration"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1316
msgid "Data directory"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1318
msgid "Edit i2psnark.config and restart to change"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1322
msgid "Files readable by all"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1326
msgid "If checked, other users may access the downloaded files"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1330
msgid "Auto start"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1334
msgid "If checked, automatically start torrents that are added"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1338
msgid "Theme"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1351
msgid "Refresh time"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1364
msgid "Never"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1370
msgid "Startup delay"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1372
msgid "minutes"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1396
msgid "Total uploader limit"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1399
msgid "peers"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1403
msgid "Up bandwidth limit"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1406
msgid "Half available bandwidth recommended."
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1408
msgid "View or change router bandwidth"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1412
msgid "Use open trackers also"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1416
msgid ""
"If checked, announce torrents to open trackers as well as the tracker listed "
"in the torrent file"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1420
msgid "Open tracker announce URLs"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1432
msgid "Inbound Settings"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1438
msgid "Outbound Settings"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1446
msgid "I2CP host"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1451
msgid "I2CP port"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1466
msgid "I2CP options"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1471
msgid "Save configuration"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1496
#, java-format
msgid "Invalid magnet URL {0}"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1530
#, java-format
msgid "Invalid info hash in magnet URL {0}"
msgstr ""
#. * dummies for translation
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1560
#, java-format
msgid "1 hop"
msgid_plural "{0} hops"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1561
#, java-format
msgid "1 tunnel"
msgid_plural "{0} tunnels"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1728
msgid "Completion"
msgstr ""
#. else unknown
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1732
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1788
msgid "Size"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1737
msgid "Files"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1739
msgid "Pieces"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1740
msgid "Piece size"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1762
msgid "Magnet link"
msgstr ""
#. We don't have the hash of the torrent file
#. buf.append("<br>").append(_("Maggot link")).append(": <a href=\"").append(MAGGOT).append(hex).append(':').append(hex).append("\">")
#. .append(MAGGOT).append(hex).append(':').append(hex).append("</a>");
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1768
msgid "Torrent file"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1786
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1825
msgid "Directory"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1795
msgid "Priority"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1800
msgid "Up to higher level directory"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1830
msgid "Torrent not found?"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1839
msgid "File not found in torrent?"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1852
msgid "complete"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1853
msgid "bytes remaining"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1878
msgid "Open"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1904
msgid "High"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1909
msgid "Normal"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1914
msgid "Skip"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1923
msgid "Save priorities"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2039
#, java-format
msgid "Torrent fetched from {0}"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2060
#, java-format
msgid "Torrent already running: {0}"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2062
#, java-format
msgid "Torrent already in the queue: {0}"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2068
#, java-format
msgid "Torrent at {0} was not valid"
msgstr ""
#. FIXME don't lose peer setting
#. String peerParam = req.getParameter("p");
#. if (peerParam != null)
#. buf.append("<input type=\"hidden\" name=\"p\" value=\"").append(peerParam).append("\" >\n");
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2082
#, java-format
msgid "Torrent was not retrieved from {0}"
msgstr ""

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -52,22 +52,22 @@
</target>
<!-- TODO: Move the web classes from the jar to the war - they are not part of the API
- This will require sponge to rewrite some seedless stuff that uses it.
-->
<!-- The web classes are now in the war not the jar - they are not part of the API -->
<target name="jar" depends="builddep, compile, jarUpToDate, listChangedFiles" unless="jar.uptodate" >
<!-- set if unset -->
<property name="workspace.changes.j.tr" value="" />
<jar destfile="./build/i2ptunnel.jar" basedir="./build/obj" includes="**/*.class">
<jar destfile="./build/i2ptunnel.jar" basedir="./build/obj" includes="**/*.class" excludes="**/EditBean.class **/IndexBean.class" >
<manifest>
<attribute name="Main-Class" value="net.i2p.i2ptunnel.I2PTunnel" />
<attribute name="Class-Path" value="i2p.jar mstreaming.jar" />
<attribute name="Implementation-Version" value="${full.version}" />
<attribute name="Built-By" value="${build.built-by}" />
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.j.tr}" />
</manifest>
</jar>
<jar destfile="./build/temp-beans.jar" basedir="./build/obj" includes="**/EditBean.class **/IndexBean.class" />
</target>
<target name="jarUpToDate">
@@ -129,13 +129,17 @@
</exec>
</target>
<!-- The web classes are now in the war not the jar - they are not part of the API -->
<target name="war" depends="precompilejsp, bundle, warUpToDate, listChangedFiles2" unless="war.uptodate" >
<!-- set if unset -->
<property name="workspace.changes.w.tr" value="" />
<copy file="build/obj/net/i2p/i2ptunnel/web/EditBean.class" todir="../jsp/WEB-INF/classes/net/i2p/i2ptunnel/web" />
<copy file="build/obj/net/i2p/i2ptunnel/web/IndexBean.class" todir="../jsp/WEB-INF/classes/net/i2p/i2ptunnel/web" />
<war destfile="build/i2ptunnel.war" webxml="../jsp/web-out.xml"
basedir="../jsp/" excludes="web.xml, web-fragment.xml, web-out.xml, **/*.java, *.jsp">
<manifest>
<attribute name="Implementation-Version" value="${full.version}" />
<attribute name="Built-By" value="${build.built-by}" />
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.w.tr}" />
@@ -171,11 +175,14 @@
<pathelement location="../../jetty/jettylib/javax.servlet.jar" />
<pathelement location="../../jetty/jettylib/commons-logging.jar" />
<pathelement location="../../jetty/jettylib/commons-el.jar" />
<pathelement location="../../jetty/jettylib/ant.jar" />
<pathelement location="../../jetty/jettylib/jsp-api.jar" />
<pathelement location="${ant.home}/lib/ant.jar" />
<pathelement location="build/i2ptunnel.jar" />
<pathelement location="build/temp-beans.jar" />
</classpath>
<arg value="-d" />
<arg value="../jsp/WEB-INF/classes" />
<arg value="-v" />
<arg value="-p" />
<arg value="net.i2p.i2ptunnel.jsp" />
<arg value="-webinc" />
@@ -192,7 +199,9 @@
<pathelement location="../../jetty/jettylib/javax.servlet.jar" />
<pathelement location="../../jetty/jettylib/commons-logging.jar" />
<pathelement location="../../jetty/jettylib/commons-el.jar" />
<pathelement location="../../jetty/jettylib/jsp-api.jar" />
<pathelement location="build/i2ptunnel.jar" />
<pathelement location="build/temp-beans.jar" />
</classpath>
</javac>
<copy file="../jsp/web.xml" tofile="../jsp/web-out.xml" />

View File

@@ -60,6 +60,14 @@ public abstract class I2PTunnelTask extends EventDispatcherImpl {
public abstract boolean close(boolean forced);
/**
* For tasks that don't call I2PTunnel.addSession() directly
* @since 0.8.13
*/
public void connected(I2PSession session) {
getTunnel().addSession(session);
}
public void disconnected(I2PSession session) {
routerDisconnected();
getTunnel().removeSession(session);

View File

@@ -0,0 +1,247 @@
/* I2PTunnel is GPL'ed (with the exception mentioned in I2PTunnel.java)
* (c) 2003 - 2004 mihi
*/
package net.i2p.i2ptunnel.localServer;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
import net.i2p.I2PAppContext;
import net.i2p.client.naming.NamingService;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;
import net.i2p.i2ptunnel.I2PTunnelHTTPClient;
import net.i2p.util.FileUtil;
import net.i2p.util.Log;
import net.i2p.util.Translate;
/**
* Very simple web server.
*
* Serve local files in the docs/ directory, for CSS and images in
* error pages, using the reserved address proxy.i2p
* (similar to p.p in privoxy).
* This solves the problems with including links to the router console,
* as assuming the router console is at 127.0.0.1 leads to broken
* links if it isn't.
*
* @since 0.7.6, moved from I2PTunnelHTTPClient in 0.9
*/
public abstract class LocalHTTPServer {
private final static byte[] ERR_404 =
("HTTP/1.1 404 Not Found\r\n"+
"Content-Type: text/plain\r\n"+
"\r\n"+
"HTTP Proxy local file not found")
.getBytes();
private final static byte[] ERR_ADD =
("HTTP/1.1 409 Bad\r\n"+
"Content-Type: text/plain\r\n"+
"\r\n"+
"Add to addressbook failed - bad parameters")
.getBytes();
/**
* Very simple web server.
*
* Serve local files in the docs/ directory, for CSS and images in
* error pages, using the reserved address proxy.i2p
* (similar to p.p in privoxy).
* This solves the problems with including links to the router console,
* as assuming the router console is at 127.0.0.1 leads to broken
* links if it isn't.
*
* Ignore all request headers (If-Modified-Since, etc.)
*
* There is basic protection here -
* FileUtil.readFile() prevents traversal above the base directory -
* but inproxy/gateway ops would be wise to block proxy.i2p to prevent
* exposing the docs/ directory or perhaps other issues through
* uncaught vulnerabilities.
* Restrict to the /themes/ directory for now.
*
* @param targetRequest decoded path only, non-null
* @param query raw (encoded), may be null
*/
public static void serveLocalFile(OutputStream out, String method, String targetRequest, String query, String proxyNonce) {
//System.err.println("targetRequest: \"" + targetRequest + "\"");
// a home page message for the curious...
if (targetRequest.equals("/")) {
try {
out.write(("HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nCache-Control: max-age=86400\r\n\r\nI2P HTTP proxy OK").getBytes());
out.flush();
} catch (IOException ioe) {}
return;
}
if ((method.equals("GET") || method.equals("HEAD")) &&
targetRequest.startsWith("/themes/") &&
!targetRequest.contains("..")) {
String filename = null;
try {
filename = targetRequest.substring(8); // "/themes/".length
} catch (IndexOutOfBoundsException ioobe) {
return;
}
// theme hack
if (filename.startsWith("console/default/"))
filename = filename.replaceFirst("default", I2PAppContext.getGlobalContext().getProperty("routerconsole.theme", "light"));
File themesDir = new File(I2PAppContext.getGlobalContext().getBaseDir(), "docs/themes");
File file = new File(themesDir, filename);
if (file.exists() && !file.isDirectory()) {
String type;
if (filename.endsWith(".css"))
type = "text/css";
else if (filename.endsWith(".ico"))
type = "image/x-icon";
else if (filename.endsWith(".png"))
type = "image/png";
else if (filename.endsWith(".jpg"))
type = "image/jpeg";
else type = "text/html";
try {
out.write("HTTP/1.1 200 OK\r\nContent-Type: ".getBytes());
out.write(type.getBytes());
out.write("\r\nCache-Control: max-age=86400\r\n\r\n".getBytes());
FileUtil.readFile(filename, themesDir.getAbsolutePath(), out);
} catch (IOException ioe) {}
return;
}
}
// Add to addressbook (form submit)
// Parameters are url, host, dest, nonce, and master | router | private.
// Do the add and redirect.
if (targetRequest.equals("/add")) {
Map<String, String> opts = new HashMap(8);
// this only works if all keys are followed by =value
StringTokenizer tok = new StringTokenizer(query, "=&;");
while (tok.hasMoreTokens()) {
String k = tok.nextToken();
if (!tok.hasMoreTokens())
break;
String v = tok.nextToken();
opts.put(decode(k), decode(v));
}
String url = opts.get("url");
String host = opts.get("host");
String b64Dest = opts.get("dest");
String nonce = opts.get("nonce");
String book = "privatehosts.txt";
if (opts.get("master") != null)
book = "userhosts.txt";
else if (opts.get("router") != null)
book = "hosts.txt";
Destination dest = null;
if (b64Dest != null) {
try {
dest = new Destination(b64Dest);
} catch (DataFormatException dfe) {
System.err.println("Bad dest to save?" + b64Dest);
}
}
//System.err.println("url : \"" + url + "\"");
//System.err.println("host : \"" + host + "\"");
//System.err.println("b64dest : \"" + b64Dest + "\"");
//System.err.println("book : \"" + book + "\"");
//System.err.println("nonce : \"" + nonce + "\"");
if (proxyNonce.equals(nonce) && url != null && host != null && dest != null) {
try {
NamingService ns = I2PAppContext.getGlobalContext().namingService();
Properties nsOptions = new Properties();
nsOptions.setProperty("list", book);
nsOptions.setProperty("s", _("Added via address helper"));
boolean success = ns.put(host, dest, nsOptions);
writeRedirectPage(out, success, host, book, url);
return;
} catch (IOException ioe) {}
}
try {
out.write(ERR_ADD);
out.flush();
} catch (IOException ioe) {}
return;
}
try {
out.write(ERR_404);
out.flush();
} catch (IOException ioe) {}
}
/** @since 0.8.7 */
private static void writeRedirectPage(OutputStream out, boolean success, String host, String book, String url) throws IOException {
out.write(("HTTP/1.1 200 OK\r\n"+
"Content-Type: text/html; charset=UTF-8\r\n"+
"\r\n"+
"<html><head>"+
"<title>" + _("Redirecting to {0}", host) + "</title>\n" +
"<link rel=\"shortcut icon\" href=\"http://proxy.i2p/themes/console/images/favicon.ico\" >\n" +
"<link href=\"http://proxy.i2p/themes/console/default/console.css\" rel=\"stylesheet\" type=\"text/css\" >\n" +
"<meta http-equiv=\"Refresh\" content=\"1; url=" + url + "\">\n" +
"</head><body>\n" +
"<div class=logo>\n" +
"<a href=\"http://127.0.0.1:7657/\" title=\"" + _("Router Console") + "\"><img src=\"http://proxy.i2p/themes/console/images/i2plogo.png\" alt=\"I2P Router Console\" border=\"0\"></a><hr>\n" +
"<a href=\"http://127.0.0.1:7657/config\">" + _("Configuration") + "</a> <a href=\"http://127.0.0.1:7657/help.jsp\">" + _("Help") + "</a> <a href=\"http://127.0.0.1:7657/susidns/index\">" + _("Addressbook") + "</a>\n" +
"</div>" +
"<div class=warning id=warning>\n" +
"<h3>" +
(success ?
_("Saved {0} to the {1} addressbook, redirecting now.", host, book) :
_("Failed to save {0} to the {1} addressbook, redirecting now.", host, book)) +
"</h3>\n<p><a href=\"" + url + "\">" +
_("Click here if you are not redirected automatically.") +
"</a></p></div>").getBytes("UTF-8"));
I2PTunnelHTTPClient.writeFooter(out);
out.flush();
}
/**
* Decode %xx encoding
* @since 0.8.7
*/
public static String decode(String s) {
if (!s.contains("%"))
return s;
StringBuilder buf = new StringBuilder(s.length());
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c != '%') {
buf.append(c);
} else {
try {
buf.append((char) Integer.parseInt(s.substring(++i, (++i) + 1), 16));
} catch (IndexOutOfBoundsException ioobe) {
break;
} catch (NumberFormatException nfe) {
break;
}
}
}
return buf.toString();
}
private static final String BUNDLE_NAME = "net.i2p.i2ptunnel.web.messages";
/** lang in routerconsole.lang property, else current locale */
protected static String _(String key) {
return Translate.getString(key, I2PAppContext.getGlobalContext(), BUNDLE_NAME);
}
/** {0} */
protected static String _(String key, Object o) {
return Translate.getString(key, o, I2PAppContext.getGlobalContext(), BUNDLE_NAME);
}
/** {0} and {1} */
protected static String _(String key, Object o, Object o2) {
return Translate.getString(key, o, o2, I2PAppContext.getGlobalContext(), BUNDLE_NAME);
}
}

View File

@@ -107,6 +107,7 @@ import net.i2p.util.Log;
try {
ByteArrayInputStream in = new ByteArrayInputStream(key);
_session = client.createSession(in, tunnel.getClientOptions());
connected(_session);
} catch(Exception exc) {
throw new RuntimeException("failed to create session", exc);
}

View File

@@ -103,6 +103,7 @@ public class I2PTunnelUDPServerBase extends I2PTunnelTask implements Source, Sin
try {
_session = client.createSession(privData, getTunnel().getClientOptions());
connected(_session);
} catch(I2PSessionException exc) {
throw new RuntimeException("failed to create session", exc);
}

View File

@@ -342,7 +342,8 @@ public class IndexBean {
String pk = cur.getPrivKeyFile();
if (pk == null)
pk = _privKeyFile;
if (pk != null && pk.startsWith("i2ptunnel") && pk.endsWith("-privKeys.dat")) {
if (pk != null && pk.startsWith("i2ptunnel") && pk.endsWith("-privKeys.dat") &&
((!isClient(cur.getType())) || cur.getPersistentClientKey())) {
File pkf = new File(_context.getConfigDir(), pk);
if (pkf.exists()) {
String name = cur.getName();

View File

@@ -1,25 +0,0 @@
package net.i2p.i2ptunnel.web;
/**
* A temporary data holder for the wizard pages
*
* Warning - This class is not part of the i2ptunnel API, and at some point
* it will be moved from the jar to the war.
* Usage by classes outside of i2ptunnel.war is deprecated.
*/
public class WizardBean extends EditBean {
private boolean _isClient;
public WizardBean() { super(); }
/**
* Whether the tunnel being set up is a client tunnel or not.
* @since 0.8.13
*/
public void setIsClient(String isClient) {
_isClient = Boolean.valueOf(isClient);
}
/** @since 0.8.13 */
public boolean getIsClient() {
return _isClient;
}
}

View File

@@ -2,6 +2,7 @@
// NOTE: Do the header carefully so there is no whitespace before the <?xml... line
%><%@page pageEncoding="UTF-8"
%><%@page trimDirectiveWhitespaces="true"
%><%@page contentType="text/html" import="net.i2p.i2ptunnel.web.EditBean"
%><%
String tun = request.getParameter("tunnel");

View File

@@ -1,4 +1,6 @@
<%@page contentType="text/html" import="net.i2p.i2ptunnel.web.EditBean"%><?xml version="1.0" encoding="UTF-8"?>
<%@page contentType="text/html" import="net.i2p.i2ptunnel.web.EditBean"
%><%@page trimDirectiveWhitespaces="true"
%><?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<jsp:useBean class="net.i2p.i2ptunnel.web.EditBean" id="editBean" scope="request" />
<jsp:useBean class="net.i2p.i2ptunnel.web.Messages" id="intl" scope="request" />
@@ -355,11 +357,11 @@
</label>
<table border="0"><tr><!-- I give up -->
<td><input value="1" type="radio" id="startOnLoad" name="newDest" title="New Destination"
<%=(editBean.getNewDest(curTunnel) ? " checked=\"checked\"" : "")%> class="tickbox" />
<td><%=intl._("Enable")%>
<%=(editBean.getNewDest(curTunnel) ? " checked=\"checked\"" : "")%> class="tickbox" /></td>
<td><%=intl._("Enable")%></td>
<td><input value="0" type="radio" id="startOnLoad" name="newDest" title="New Destination"
<%=(editBean.getNewDest(curTunnel) || editBean.getPersistentClientKey(curTunnel) ? "" : " checked=\"checked\"")%> class="tickbox" />
<td><%=intl._("Disable")%>
<%=(editBean.getNewDest(curTunnel) || editBean.getPersistentClientKey(curTunnel) ? "" : " checked=\"checked\"")%> class="tickbox" /></td>
<td><%=intl._("Disable")%></td></tr>
</table>
</div>
<div id="portField" class="rowItem">

View File

@@ -1,4 +1,6 @@
<%@page contentType="text/html" import="net.i2p.i2ptunnel.web.EditBean"%><?xml version="1.0" encoding="UTF-8"?>
<%@page contentType="text/html" import="net.i2p.i2ptunnel.web.EditBean"
%><%@page trimDirectiveWhitespaces="true"
%><?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<jsp:useBean class="net.i2p.i2ptunnel.web.EditBean" id="editBean" scope="request" />
<jsp:useBean class="net.i2p.i2ptunnel.web.Messages" id="intl" scope="request" />

View File

@@ -6,6 +6,7 @@
request.setCharacterEncoding("UTF-8");
%><%@page pageEncoding="UTF-8"
%><%@page trimDirectiveWhitespaces="true"
%><%@page contentType="text/html" import="net.i2p.i2ptunnel.web.IndexBean"
%><?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

View File

@@ -1,11 +1,15 @@
<%
// NOTE: Do the header carefully so there is no whitespace before the <?xml... line
// http://www.crazysquirrel.com/computing/general/form-encoding.jspx
if (request.getCharacterEncoding() == null)
request.setCharacterEncoding("UTF-8");
%><%@page pageEncoding="UTF-8"
%><%@page contentType="text/html" import="net.i2p.i2ptunnel.web.WizardBean"
%><%@page contentType="text/html" import="net.i2p.i2ptunnel.web.EditBean"
%><?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<jsp:useBean class="net.i2p.i2ptunnel.web.WizardBean" id="wizardBean" scope="request" />
<jsp:useBean class="net.i2p.i2ptunnel.web.EditBean" id="editBean" scope="request" />
<jsp:useBean class="net.i2p.i2ptunnel.web.Messages" id="intl" scope="request" />
<% String pageStr = request.getParameter("page");
/* Get the number of the page we came from */
@@ -45,14 +49,14 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title><%=intl._("I2P Tunnel Manager - Tunnel Creation Wizard")%></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
<link href="/themes/console/images/favicon.ico" type="image/x-icon" rel="shortcut icon" />
<% if (wizardBean.allowCSS()) {
%><link href="<%=wizardBean.getTheme()%>default.css" rel="stylesheet" type="text/css" />
<link href="<%=wizardBean.getTheme()%>i2ptunnel.css" rel="stylesheet" type="text/css" />
<% if (editBean.allowCSS()) {
%><link href="<%=editBean.getTheme()%>default.css" rel="stylesheet" type="text/css" />
<link href="<%=editBean.getTheme()%>i2ptunnel.css" rel="stylesheet" type="text/css" />
<% }
%>
</head>
@@ -82,7 +86,7 @@
} %>
<input type="hidden" name="page" value="<%=curPage%>" />
<input type="hidden" name="tunnel" value="null" />
<input type="hidden" name="nonce" value="<%=wizardBean.getNextNonce()%>" />
<input type="hidden" name="nonce" value="<%=editBean.getNextNonce()%>" />
</div>
<div class="separator">
@@ -93,12 +97,12 @@
if (curPage == 1) {
%><p>
<%=intl._("This wizard will take you through the various basic options available for manually creating tunnels in I2P.")%>
<%=intl._("This wizard will take you through the various options available for creating tunnels in I2P.")%>
</p>
<p>
<%=intl._("The first thing to decide is whether you want to create a client or server tunnel.")%>
<%=intl._("If you are trying to connect to a remote service (such as an IRC server inside I2P, or a code repository) then you will require a client tunnel.")%>
<%=intl._("Server tunnels are what client tunnels will connect to, and you will need to create one if you want to host a service - e.g. more eepsites, or an outproxy.")%>
<%=intl._("The first thing to decide is whether you want to create a server or a client tunnel.")%>
<%=intl._("If you need to connect to a remote service, such as an IRC server inside I2P or a code repository, then you will require a CLIENT tunnel.")%>
<%=intl._("On the other hand, if you wish to host a service for others to connect to you'll need to create a SERVER tunnel.")%>
</p>
<div id="typeField" class="rowItem">
<label><%=intl._("Server Tunnel")%></label>
@@ -122,21 +126,21 @@
if (tunnelIsClient) {
%>
<tr><td><%=intl._("Standard")%></td><td>
<%=intl._("A basic client tunnel for connecting to a single service inside I2P.")%>
<%=intl._("If none of the tunnel types below seem to fit your requirements, or you don't know what type of tunnel you need, try this one.")%>
<%=intl._("Basic tunnel for connecting to a single service inside I2P.")%>
<%=intl._("Try this if none of the tunnel types below fit your requirements, or you don't know what type of tunnel you need.")%>
</td></tr>
<tr><td>HTTP</td><td>
<%=intl._("A client tunnel that acts as an HTTP proxy.")%>
<%=intl._("With this tunnel type, you can connect to eepsites inside I2P by setting your browser to use the tunnel as a proxy, or setting the http_proxy environment variable for command-line applications in GNU/Linux.")%>
<%=intl._("Tunnel that acts as an HTTP proxy for reaching eepsites inside I2P.")%>
<%=intl._("Set your browser to use this tunnel as an http proxy, or set your \"http_proxy\" environment variable for command-line applications in GNU/Linux.")%>
<%=intl._("Websites outside I2P can also be reached if an HTTP proxy within I2P is known.")%>
</td></tr>
<tr><td>IRC</td><td>
<%=intl._("A customised client tunnel for connecting to a single IRC network inside I2P.")%>
<%=intl._("With this tunnel type, you would configure your IRC client to connect to a local port on your computer.")%>
<%=intl._("Each IRC network in I2P that you wish to connect to requires a separate tunnel.")%>
<%=intl._("Customised client tunnel specific for IRC connections.")%>
<%=intl._("With this tunnel type, your IRC client will be able to connect to an IRC network inside I2P.")%>
<%=intl._("Each IRC network in I2P that you wish to connect to will require its own tunnel. (See Also, SOCKS IRC)")%>
</td></tr>
<tr><td>SOCKS 4/4a/5</td><td>
<%=intl._("A client tunnel that implements the SOCKS protocol.")%>
<%=intl._("A tunnel that implements the SOCKS protocol.")%>
<%=intl._("This enables both TCP and UDP connections to be made through a SOCKS outproxy within I2P.")%>
</td></tr>
<tr><td>SOCKS IRC</td><td>
@@ -150,14 +154,14 @@
<%=intl._("This enables TCP connections to be made through an HTTP outproxy, assuming the proxy supports the CONNECT command.")%>
</td></tr>
<tr><td>Streamr</td><td>
<%=intl._("A customised client tunnel for Streamr.")%>
<%=intl._("I have no idea what this is.")%>
<%=intl._("A customised client tunnel for Streamr.")%><%
//XXX TODO<%=intl._("I have no idea what this is.")%>
</td></tr><%
} else {
%>
<tr><td><%=intl._("Standard")%></td><td>
<%=intl._("A basic server tunnel for hosting a generic service inside I2P.")%>
<%=intl._("If none of the tunnel types below seem to fit your requirements, or you don't know what type of tunnel you need, try this one.")%>
<%=intl._("Try this if none of the tunnel types below fit your requirements, or you don't know what type of tunnel you need.")%>
</td></tr>
<tr><td>HTTP</td><td>
<%=intl._("A server tunnel that is customised for HTTP connections.")%>
@@ -172,8 +176,8 @@
<%=intl._("Usually, a separate tunnel needs to be created for each IRC server that is to be accessible inside I2P.")%>
</td></tr>
<tr><td>Streamr</td><td>
<%=intl._("A customised server tunnel for Streamr.")%>
<%=intl._("I have no idea what this is.")%>
<%=intl._("A customised server tunnel for Streamr.")%><%
//XXX TODO<%=intl._("I have no idea what this is.")%>
</td></tr><%
}
%>
@@ -276,8 +280,8 @@
if ((tunnelIsClient && "streamrclient".equals(tunnelType)) || (!tunnelIsClient && !"streamrserver".equals(tunnelType))) {
if (curPage == 5) {
%><p>
<%=intl._("Some blurb explaining that this is the IP that the service is running on, and that the tunnel should direct requests to.")%>
<%=intl._("For some reason streamrclient also uses this.")%>
<%=intl._("This is the IP that your service is running on, this is usually on the same machine so 127.0.0.1 is autofilled.")%><%
//XXX TODO<%=intl._("For some reason streamrclient also uses this.")%>
</p>
<div id="hostField" class="rowItem">
<label for="targetHost" accesskey="H">
@@ -293,7 +297,7 @@
if (!tunnelIsClient) {
if (curPage == 5) {
%><p>
<%=intl._("Some blurb explaining that this is the port that the service is running on, and that the tunnel should direct requests to.")%>
<%=intl._("This is the port that the service is accepting connections on.")%>
</p>
<div id="portField" class="rowItem">
<label for="targetPort" accesskey="P">
@@ -309,8 +313,8 @@
if (tunnelIsClient || "httpbidirserver".equals(tunnelType)) {
if (curPage == 5) {
%><p>
<%=intl._("Some blurb explaining that this is the port that the client tunnel will be accessed from locally.")%>
<%=intl._("This is also the client port for the httpbidirserver tunnel.")%>
<%=intl._("This is the port that the client tunnel will be accessed from locally.")%>
<%=intl._("This is also the client port for the HTTPBidir server tunnel.")%>
</p>
<div id="portField" class="rowItem">
<label for="port" accesskey="P">
@@ -326,9 +330,10 @@
if ((tunnelIsClient && !"streamrclient".equals(tunnelType)) || "httpbidirserver".equals(tunnelType) || "streamrserver".equals(tunnelType)) {
if (curPage == 5) {
%><p>
<%=intl._("Some blurb explaining what Reachable By is.")%>
<%=intl._("Note that it is relevant to most Client tunnels, and httpbidirserver and streamrserver tunnels.")%>
<%=intl._("So the wording may need to change slightly for the client vs. server tunnels.")%>
<%=intl._("How do you want this tunnel to be accessed? By just this machine, your entire subnet, or external internet?")%>
<%=intl._("You will most likely want to just allow 127.0.0.1")%><%
//XXX TODO<%=intl._("Note that it is relevant to most Client tunnels, and httpbidirserver and streamrserver tunnels.")%><%
//XXX TODO<%=intl._("So the wording may need to change slightly for the client vs. server tunnels.")%>
</p>
<div id="reachField" class="rowItem">
<label for="reachableBy" accesskey="r">
@@ -340,7 +345,7 @@
if ("null".equals(clientInterface)) {
clientInterface = "127.0.0.1";
}
for (String ifc : wizardBean.interfaceSet()) {
for (String ifc : editBean.interfaceSet()) {
out.write("<option value=\"");
out.write(ifc);
out.write('\"');
@@ -351,7 +356,7 @@
out.write("</option>\n");
}
%>
</select>
</select>
</div><%
} else {
%><input type="hidden" name="reachableBy" value="<%=request.getParameter("reachableBy")%>" /><%
@@ -364,7 +369,7 @@
if (curPage == 6) {
%><p>
<%=intl._("The I2P router can optionally start the tunnel for you automatically when the router is started.")%>
<%=intl._("The I2P router can automatically start this tunnel for you when the router is started.")%>
<%=intl._("This can be useful for frequently-used tunnels (especially server tunnels), but for tunnels that are only used occassionally it would mean that the I2P router is creating and maintaining unnecessary tunnels.")%>
</p>
<div id="startupField" class="rowItem">
@@ -397,6 +402,67 @@
<%=intl._("You can do this by clicking the Start button on the main page which corresponds to the new tunnel.")%><%
} %>
</p>
<p>
<%=intl._("Below is a summary of the options you chose:")%>
</p>
<table>
<tr><td><%=intl._("Server or client tunnel?")%></td><td>
<%=(tunnelIsClient ? "Client" : "Server")%>
</td></tr>
<tr><td><%=intl._("Tunnel type")%></td><td><%
if ("client".equals(tunnelType) || "server".equals(tunnelType)) { %>
<%=intl._("Standard")%><%
} else if ("httpclient".equals(tunnelType) || "httpserver".equals(tunnelType)) { %>
HTTP<%
} else if ("httpbidirserver".equals(tunnelType)) { %>
HTTP bidir<%
} else if ("ircclient".equals(tunnelType) || "ircserver".equals(tunnelType)) { %>
IRC<%
} else if ("sockstunnel".equals(tunnelType)) { %>
SOCKS 4/4a/5<%
} else if ("socksirctunnel".equals(tunnelType)) { %>
SOCKS IRC<%
} else if ("connectclient".equals(tunnelType)) { %>
CONNECT<%
} else if ("streamrclient".equals(tunnelType) || "streamrserver".equals(tunnelType)) { %>
Streamr<%
} %>
</td></tr>
<tr><td><%=intl._("Tunnel name and description")%></td><td>
<%=request.getParameter("name")%><br />
<%=request.getParameter("description")%>
</td></tr><%
if (tunnelIsClient) { %>
<tr><td><%=intl._("Tunnel destination")%></td><td><%
if ("httpclient".equals(tunnelType) || "connectclient".equals(tunnelType) || "sockstunnel".equals(tunnelType) || "socksirctunnel".equals(tunnelType)) { %>
<%=request.getParameter("proxyList")%><%
} else if ("client".equals(tunnelType) || "ircclient".equals(tunnelType) || "streamrclient".equals(tunnelType)) { %>
<%=request.getParameter("targetDestination")%><%
} %>
</td></tr><%
} %>
<tr><td><%=intl._("Binding address and port")%></td><td><%
if ((tunnelIsClient && "streamrclient".equals(tunnelType)) || (!tunnelIsClient && !"streamrserver".equals(tunnelType))) { %>
<%=request.getParameter("targetHost")%><br /><%
}
if (!tunnelIsClient) { %>
<%=request.getParameter("targetPort")%><br /><%
}
if (tunnelIsClient || "httpbidirserver".equals(tunnelType)) { %>
<br /><%=request.getParameter("port")%><%
}
if ((tunnelIsClient && !"streamrclient".equals(tunnelType)) || "httpbidirserver".equals(tunnelType) || "streamrserver".equals(tunnelType)) { %>
<br /><%=request.getParameter("reachableBy")%><%
} %>
</td></tr>
<tr><td><%=intl._("Tunnel auto-start")%></td><td><%
if ("1".equals(request.getParameter("startOnLoad"))) { %>
Yes<%
} else { %>
No<%
} %>
</td></tr>
</table>
<p>
<%=intl._("Alongside these basic settings, there are a number of advanced options for tunnel configuration.")%>
<%=intl._("The wizard will set reasonably sensible default values for these, but you can view and/or edit these by clicking on the tunnel's name in the main I2PTunnel page.")%>
@@ -456,7 +522,7 @@ http://i2jump.i2p/" /><%
<div id="globalOperationsPanel" class="panel">
<div class="header"></div>
<div class="footer">
<div class=toolbox">
<div class="toolbox">
<a class="control" href="list"><%=intl._("Cancel")%></a>
<% if (curPage != 1 && curPage != 7) {
%><button id="controlPrevious" accesskey="P" class="control" type="submit" name="action" value="Previous page" title="Previous Page"><%=intl._("Previous")%>(<span class="accessKey">P</span>)</button><%

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -2,122 +2,119 @@
# Copyright (C) 2009 The I2P Project
# This file is distributed under the same license as the i2ptunnel package.
# To contribute translations, see http://www.i2p2.de/newdevelopers
#
#
# Translators:
# Martin Svensson <digitalmannen@gmail.com>, 2011, 2012.
msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-12-15 20:14+0000\n"
"PO-Revision-Date: 2011-08-26 09:28+0000\n"
"Last-Translator: digitalmannen <digitalmannen@gmail.com>\n"
"Language-Team: Swedish (Sweden) (http://www.transifex.net/projects/p/I2P/"
"team/sv_SE/)\n"
"Language: sv_SE\n"
"Report-Msgid-Bugs-To: https://trac.i2p2.de/\n"
"POT-Creation-Date: 2012-02-17 11:25+0000\n"
"PO-Revision-Date: 2012-02-20 15:28+0000\n"
"Last-Translator: Martin Svensson <digitalmannen@gmail.com>\n"
"Language-Team: Swedish (Sweden) (http://www.transifex.net/projects/p/I2P/language/sv_SE/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: sv_SE\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:487
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:492
msgid "This seems to be a bad destination:"
msgstr "Detta verkar vara ett felaktigt mål"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:487
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:492
msgid "i2paddresshelper cannot help you with a destination like that!"
msgstr "i2padresshjälp kan inte hjälpa dig med ett sådant mål!"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:556
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:561
#, java-format
msgid ""
"To visit the destination in your host database, click <a href=\"{0}\">here</"
"a>. To visit the conflicting addresshelper destination, click <a href="
"\"{1}\">here</a>."
msgstr ""
"För att besöka målet i din värd databas href=\"{0}\"> klicka <a här </ a>. "
"För att besöka de motstridiga hjälpaddresserna,<a href=\"{1}\"> klicka <a "
"här </ a>."
"To visit the destination in your host database, click <a "
"href=\"{0}\">here</a>. To visit the conflicting addresshelper destination, "
"click <a href=\"{1}\">here</a>."
msgstr "För att besöka målet i din värd databas href=\"{0}\"> klicka <a här </ a>. För att besöka de motstridiga hjälpaddresserna,<a href=\"{1}\"> klicka <a här </ a>."
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:932
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:937
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:398
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:142
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:401
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:391
msgid "Host"
msgstr "Värd"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:933
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:370
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:938
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:372
msgid "Destination"
msgstr "Mål"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:938
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:943
#, java-format
msgid "Continue to {0} without saving"
msgstr "Fortsätt till {0} utan att spara"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:943
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:948
#, java-format
msgid "Save {0} to router address book and continue to eepsite"
msgstr "Spara {0} till routeradressboken och fortsätt till eepsite "
#. only blockfile supports multiple books
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:946
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:951
#, java-format
msgid "Save {0} to master address book and continue to eepsite"
msgstr "Spara {0} till huvudadressboken och fortsätt till eepsite "
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:947
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:952
#, java-format
msgid "Save {0} to private address book and continue to eepsite"
msgstr "Spara {0} till privatadressbok och fortsätt till eepsite "
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1102
#, fuzzy
msgid "HTTP Outproxy"
msgstr "Utproxy"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1107
msgid ""
"Click a link below to look for an address helper by using a \"jump\" service:"
msgstr ""
"Klicka på en länk nedan för att söka efter en hjälpaddress genom att använda "
"en \"hopp\" tjänst"
msgid "HTTP Outproxy"
msgstr "HTTP Utproxy"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1325
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1112
msgid ""
"Click a link below to look for an address helper by using a \"jump\" "
"service:"
msgstr "Klicka på en länk nedan för att söka efter en hjälpaddress genom att använda en \"hopp\" tjänst"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1330
msgid "Added via address helper"
msgstr "Tillagd via adresshjälpen "
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1349
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1354
#, java-format
msgid "Redirecting to {0}"
msgstr "Om dirigerar till {0}"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1355
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1360
msgid "Router Console"
msgstr "Router konsol "
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1356
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1361
msgid "Addressbook"
msgstr "Adressbok"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1356
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1361
msgid "Configuration"
msgstr "Konfiguration"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1356
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1361
msgid "Help"
msgstr "Hjälp"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1361
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1366
#, java-format
msgid "Saved {0} to the {1} addressbook, redirecting now."
msgstr "Spara {0} till {1}adressboken, omdirigerar nu "
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1362
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1367
#, java-format
msgid "Failed to save {0} to the {1} addressbook, redirecting now."
msgstr "Misslyckades med att spara {0} till {1}adressboken, omdirigerar nu "
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1364
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1369
msgid "Click here if you are not redirected automatically."
msgstr "Klicka här om du inte omdirigeras automatiskt "
@@ -130,9 +127,7 @@ msgstr "Intern "
msgid ""
"Invalid form submission, probably because you used the 'back' or 'reload' "
"button on your browser. Please resubmit."
msgstr ""
"Ogiltigt formulärbegäran, beror troligtvis på attt du använde 'tillbaka' "
"eller 'uppdatera' knappen. Försök att skicka igen"
msgstr "Ogiltigt formulärbegäran, beror troligtvis på attt du använde 'tillbaka' eller 'uppdatera' knappen. Försök att skicka igen"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:222
msgid "Configuration reloaded for all tunnels"
@@ -209,12 +204,12 @@ msgid "HTTP bidir"
msgstr "HTTP bidir"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:555
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:293
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:295
msgid "Host not set"
msgstr "Ingen värd angiven"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:559
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:275
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:277
msgid "Port not set"
msgstr "Ingen port angiven"
@@ -232,24 +227,26 @@ msgstr "Inställningar för ny proxy "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:112
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:112
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:110
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:124
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:245
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:260
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:112
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:126
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:247
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:262
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:307
msgid "Name"
msgstr "Namn"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:116
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:116
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:249
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:282
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:251
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:284
msgid "Type"
msgstr "Typ"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:120
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:120
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:229
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:389
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:231
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:391
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:311
msgid "Description"
msgstr "Beskrivning"
@@ -275,22 +272,27 @@ msgstr "krävs"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:159
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:178
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:460
msgid "Reachable by"
msgstr "Nåbar via"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:180
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:339
msgid "Outproxies"
msgstr "utgående proxy"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:187
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:359
msgid "Tunnel Destination"
msgstr "Tunnel mål"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:199
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:363
msgid "name or destination"
msgstr "namn eller mål"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:202
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:366
msgid "b32 not recommended"
msgstr "b32 rekommenderas ej"
@@ -302,18 +304,18 @@ msgstr "Delad klient"
msgid ""
"(Share tunnels with other clients and irc/httpclients? Change requires "
"restart of client proxy)"
msgstr ""
"(Dela tunnlarna med andra klienter och irc/HTTP-klienter? Ändring kräver "
"omstart av klientproxyn)"
msgstr "(Dela tunnlarna med andra klienter och irc/HTTP-klienter? Ändring kräver omstart av klientproxyn)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:216
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:124
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:500
msgid "Auto Start"
msgstr "Starta automatiskt"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:220
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:228
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:128
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:504
msgid "(Check the Box for 'YES')"
msgstr "(Markera i boxen för 'Ja')"
@@ -330,9 +332,7 @@ msgstr "Avancerade nätverks instälningar"
msgid ""
"(NOTE: when this client proxy is configured to share tunnels, then these "
"options are for all the shared proxy clients!)"
msgstr ""
"(OBS: när denna klientproxyn är konfigurerad för att dela tunnlar, då gäller "
"dessa alternativ för alla delade proxyklienter!)"
msgstr "(OBS: när denna klientproxyn är konfigurerad för att dela tunnlar, då gäller dessa alternativ för alla delade proxyklienter!)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:236
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:245
@@ -414,26 +414,20 @@ msgstr "Antal"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:318
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:327
msgid "1 inbound, 1 outbound tunnel (low bandwidth usage, less reliability)"
msgstr ""
"1 inkommande, 1 utgående tunnlar (låg bandbreddsanvändning, låg "
"tillförlitlighet)"
msgstr "1 inkommande, 1 utgående tunnlar (låg bandbreddsanvändning, låg tillförlitlighet)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:322
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:331
msgid ""
"2 inbound, 2 outbound tunnels (standard bandwidth usage, standard "
"reliability)"
msgstr ""
"2 inkommande, 2 utgående tunnlar (normal bandbreddsanvändning, normal "
"tillförlitlighet)"
msgstr "2 inkommande, 2 utgående tunnlar (normal bandbreddsanvändning, normal tillförlitlighet)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:326
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:335
msgid ""
"3 inbound, 3 outbound tunnels (higher bandwidth usage, higher reliability)"
msgstr ""
"3 inkommande, 3 utgående tunnlar (Högre bandbreddsanvändning, högre "
"tillförlitlighet)"
msgstr "3 inkommande, 3 utgående tunnlar (Högre bandbreddsanvändning, högre tillförlitlighet)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:335
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:344
@@ -448,8 +442,7 @@ msgstr "Antal reserver"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:347
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:356
msgid "0 backup tunnels (0 redundancy, no added resource usage)"
msgstr ""
"0 reserv tunnlar i varje riktning (ingen redundans, ingen resursanvändning)"
msgstr "0 reserv tunnlar i varje riktning (ingen redundans, ingen resursanvändning)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:351
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:360
@@ -460,15 +453,12 @@ msgstr "1 reserv tunnel i varje riktning (låg redundans, låg resursanvändning
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:364
msgid ""
"2 backup tunnels each direction (medium redundancy, medium resource usage)"
msgstr ""
"2 reserv tunnlar i varje riktning (medel hög redundans, medel hög "
"resursanvändning)"
msgstr "2 reserv tunnlar i varje riktning (medel hög redundans, medel hög resursanvändning)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:359
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:368
msgid "3 backup tunnels each direction (high redundancy, high resource usage)"
msgstr ""
"3 reserv tunnlar i varje riktning (hög redundans, hög resursanvändning)"
msgstr "3 reserv tunnlar i varje riktning (hög redundans, hög resursanvändning)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:368
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:377
@@ -506,8 +496,9 @@ msgstr "I2CP Routeradress"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:406
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:148
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:409
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:247
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:269
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:249
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:271
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:412
msgid "Port"
msgstr "Port"
@@ -605,12 +596,11 @@ msgstr "Anpassade alternativ"
msgid ""
"NOTE: If tunnel is currently running, most changes will not take effect "
"until tunnel is stopped and restarted."
msgstr ""
"OBS: Om tunneln är igång, kommer de flesta ändringarna inte att träda i "
"kraft förrän tunneln stoppats och startats om."
msgstr "OBS: Om tunneln är igång, kommer de flesta ändringarna inte att träda i kraft förrän tunneln stoppats och startats om."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:524
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:531
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:678
msgid "Cancel"
msgstr "Avbryt"
@@ -769,115 +759,466 @@ msgstr "Status meddelande "
msgid "Refresh"
msgstr "Uppdatera"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:94
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:92
msgid "Tunnel Wizard"
msgstr "Tunnel guide"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:96
msgid "Stop All"
msgstr "Stoppa alla"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:98
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:100
msgid "Start All"
msgstr "Starta alla"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:102
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:104
msgid "Restart All"
msgstr "Starta om alla"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:106
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:108
msgid "Reload Config"
msgstr "Uppdatera konfigurationen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:108
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:110
msgid "I2P Server Tunnels"
msgstr "I2P Servertunnlel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:112
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:133
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:114
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:135
msgid "Points at"
msgstr "Pekar på"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:114
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:156
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:160
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:116
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:158
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:162
msgid "Preview"
msgstr "förhandsvisning"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:116
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:180
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:253
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:300
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:118
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:182
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:255
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:302
msgid "Status"
msgstr "Status"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:166
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:168
msgid "Base32 Address"
msgstr "Bas32 adress"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:174
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:176
msgid "No Preview"
msgstr "Ingen förhandsvisning"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:187
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:307
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:189
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:309
msgid "Starting..."
msgstr "Startar..."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:194
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:208
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:314
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:328
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:342
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:196
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:210
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:316
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:330
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:344
msgid "Stop"
msgstr "Stopp"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:201
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:335
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:203
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:337
msgid "Running"
msgstr "Kör"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:215
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:349
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:217
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:351
msgid "Stopped"
msgstr "Stoppad"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:222
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:356
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:224
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:358
msgid "Start"
msgstr "Start"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:237
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:239
msgid "New server tunnel"
msgstr "Ny severtunnel "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:239
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:399
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:241
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:401
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:204
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:246
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:276
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:282
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:554
msgid "Standard"
msgstr "Standard"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:241
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:401
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:243
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:403
msgid "Create"
msgstr "Skapa"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:243
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:245
msgid "I2P Client Tunnels"
msgstr "I2P Klienttunnel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:251
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:286
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:253
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:288
msgid "Interface"
msgstr "Gränssnitt "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:321
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:323
msgid "Standby"
msgstr "Standby"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:366
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:368
msgid "Outproxy"
msgstr "Utproxy"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:384
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:386
msgid "none"
msgstr "Ingen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:397
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:399
msgid "New client tunnel"
msgstr "Ny klienttunnel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:102
msgid "I2P Tunnel Manager - Tunnel Creation Wizard"
msgstr "I2P Tunnelhanterare - Guide för skapande av tunnlar "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:120
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:545
msgid "Server or client tunnel?"
msgstr "Server- eller klient-tunnel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:126
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:549
msgid "Tunnel type"
msgstr "Tunnel typ"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:132
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:579
msgid "Tunnel name and description"
msgstr "Tunnelnamn och beskrivning "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:138
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:588
msgid "Tunnel destination"
msgstr "Mål för tunnel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:144
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:604
msgid "Binding address and port"
msgstr "Adress och port"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:150
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:630
msgid "Tunnel auto-start"
msgstr "Tunnel auto-start"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:156
msgid "Wizard completed"
msgstr "Guiden färdig "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:170
msgid ""
"This wizard will take you through the various options available for creating"
" tunnels in I2P."
msgstr "Guiden tar dig igenom de olika inställningsmöjligheterna för att skapa tunnlar."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:172
msgid ""
"The first thing to decide is whether you want to create a server or a client"
" tunnel."
msgstr "Det första är att bestämma om det skall vara en server- eller klient-tunnel. "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:174
msgid ""
"If you need to connect to a remote service, such as an IRC server inside I2P"
" or a code repository, then you will require a CLIENT tunnel."
msgstr "Om du ansluter till en fjärrtjänst så som tex en IRC-server inom I2P, behövs en KLIENT-tunnel. "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:176
msgid ""
"On the other hand, if you wish to host a service for others to connect to "
"you'll need to create a SERVER tunnel."
msgstr "Men om du vill göra en tjänst tillgänglig för andra behövs en SERVER-tunnel."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:178
msgid "Server Tunnel"
msgstr "Server-tunnel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:180
msgid "Client Tunnel"
msgstr "Klient-tunnel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:198
msgid "There are several types of tunnels to choose from:"
msgstr "Det finns flera typer av tunnlar att välja på:"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:206
msgid "Basic tunnel for connecting to a single service inside I2P."
msgstr "Grundläggande tunnel för anslutning till en snigel tjänst innanför I2P. "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:208
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:250
msgid ""
"Try this if none of the tunnel types below fit your requirements, or you "
"don't know what type of tunnel you need."
msgstr "Prova detta om ingen av valen passar eller du inte vet vilken typ av tunnel som behövs."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:210
msgid "Tunnel that acts as an HTTP proxy for reaching eepsites inside I2P."
msgstr "Tunneln agerar som en HTTP-proxy för att komma åt eepsites innanför I2P. "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:212
msgid ""
"Set your browser to use this tunnel as an http proxy, or set your "
"\"http_proxy\" environment variable for command-line applications in "
"GNU/Linux."
msgstr "Peka din webbläsare på denna tunnel som en http-proxy eller ställ in miljövariabeln \"http_proxy\" för terminal baserade applikationer i GNU/Linux."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:214
msgid ""
"Websites outside I2P can also be reached if an HTTP proxy within I2P is "
"known."
msgstr "Webbplats utanför I2P kan nås om en HTTP-proxy innanför I2P är känd."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:216
msgid "Customised client tunnel specific for IRC connections."
msgstr "Specialiserad tunnel för IRC anslutningar. "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:218
msgid ""
"With this tunnel type, your IRC client will be able to connect to an IRC "
"network inside I2P."
msgstr "Med denna tunneltyp kan IRC-klienter ansluta till IRC-nät inom I2P "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:220
msgid ""
"Each IRC network in I2P that you wish to connect to will require its own "
"tunnel. (See Also, SOCKS IRC)"
msgstr "Varje IRC-nät inom I2P som du vill ansluta till kräver en egen tunnel (Se även: SOCKS IRC) "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:222
msgid "A tunnel that implements the SOCKS protocol."
msgstr "En tunnel som implementerar SOCKS protokollet."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:224
msgid ""
"This enables both TCP and UDP connections to be made through a SOCKS "
"outproxy within I2P."
msgstr "Detta möjliggör både TCP och UDP anslutningar genom SOCKS utgående-proxy innanför I2P "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:226
msgid ""
"A client tunnel implementing the SOCKS protocol, which is customised for "
"connecting to IRC networks."
msgstr "En klient tunnel för SOCKS protokollet som är anpassad för IRC-nät."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:228
msgid ""
"With this tunnel type, IRC networks in I2P can be reached by typing the I2P "
"address into your IRC client, and configuring the IRC client to use this "
"SOCKS tunnel."
msgstr "Med denna tunnel typen kan IRC-nät inom I2P nås genom att skriva in I2P adressen i IRC-klienten och konfigurera IRC-klienten att använda denna SOCKS-tunneln."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:230
msgid ""
"This means that only one I2P tunnel is required rather than a separate "
"tunnel per IRC network."
msgstr "Detta innebär att enbart en I2P-tunnel behövs istället för en tunnel per IRC-nät."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:232
msgid ""
"IRC networks outside I2P can also be reached if a SOCKS outproxy within I2P "
"is known, though it depends on whether or not the outproxy has been blocked "
"by the IRC network."
msgstr "IRC-nät utanför I2P kan nås om en SOCKS-proxy innanför I2P är känd, men det bror på om utgående-proxy har blockerats av IRC-nätet."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:234
msgid "A client tunnel that implements the HTTP CONNECT command."
msgstr "En klient-tunnel som implementerar HTTP CONNECT kommandot. "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:236
msgid ""
"This enables TCP connections to be made through an HTTP outproxy, assuming "
"the proxy supports the CONNECT command."
msgstr "Detta möjliggör TCP anslutningar genom en HTTP utgående-proxy om proxyn stödjer CONNECT kommandot"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:238
msgid "A customised client tunnel for Streamr."
msgstr "En anpassad tunnel för Streamr."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:248
msgid "A basic server tunnel for hosting a generic service inside I2P."
msgstr "En server-tunnel för en godtycklig tjänst innanför I2P."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:252
msgid "A server tunnel that is customised for HTTP connections."
msgstr "En server-tunnel anpassad för HTTP anslutningar."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:254
msgid "Use this tunnel type if you want to host an eepsite."
msgstr "Använd denna denna typ av tunnel om du vill köra en eepsite."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:256
msgid ""
"A customised server tunnel that can both serve HTTP data and connect to "
"other server tunnels."
msgstr "En anpassad server tunnel som hanterar både HTTP data och anslutningar till andra server-tunnlar."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:258
msgid "This tunnel type is predominantly used when running a Seedless server."
msgstr "Tunneltypen använd vanligtvis när en Seedless server körs."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:260
msgid "A customised server tunnel for hosting IRC networks inside I2P."
msgstr "En server-tunnel för IRC-Nät innanför I2P."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:262
msgid ""
"Usually, a separate tunnel needs to be created for each IRC server that is "
"to be accessible inside I2P."
msgstr "Vanligtvis behövs en separat tunnel för varje IRC-server som skall anslutas till innanför I2P."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:264
msgid "A customised server tunnel for Streamr."
msgstr "En server-tunnel för Streamr."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:303
msgid "Choose a name and description for your tunnel."
msgstr "Välj namn och beskrivning av tunneln."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:305
msgid ""
"These can be anything you want - they are just for ease of identifying the "
"tunnel in the routerconsole."
msgstr "Kan vad som helst, används enbart för att enkelt identifiera tunneln i routerkonsolen "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:335
msgid ""
"If you know of any outproxies for this type of tunnel (either HTTP or "
"SOCKS), fill them in below."
msgstr "Om du känner till några utgående proxies för denna typen av tunnlar (HTTP eller SOCKS), fyll i dem nedan. "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:337
msgid "Separate multiple proxies with commas."
msgstr "Separera flera proxyservrar med komma."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:355
msgid ""
"Type in the I2P destination of the service that this client tunnel should "
"connect to."
msgstr "Ange I2P destinationen för tjänsten som tunneln skall ansluta till."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:357
msgid ""
"This could be the full base 64 destination key, or an I2P URL from your "
"address book."
msgstr "Kan vara hela base 64 målsnyckeln eller en I2P URL från adressboken."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:387
msgid ""
"This is the IP that your service is running on, this is usually on the same "
"machine so 127.0.0.1 is autofilled."
msgstr "Detta är IP-adressen som tjänsten körs på, detta är vanligtvis på samma maskin så 127.0.0.1 fylls i automatiskt. "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:410
msgid "This is the port that the service is accepting connections on."
msgstr "Porten som tjänsten accepterar anslutningar via."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:431
msgid "This is the port that the client tunnel will be accessed from locally."
msgstr "Porten som klient-tunneln kommer att ansluta till lokalt."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:433
msgid "This is also the client port for the HTTPBidir server tunnel."
msgstr "Detta är också en klient-port för HTTPBidir server-tunneln."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:452
msgid ""
"How do you want this tunnel to be accessed? By just this machine, your "
"entire subnet, or external internet?"
msgstr "Hur du vill att tunneln ska nås? Enbart denna maskinen, ditt lokala nät eller hela internet? "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:454
msgid "You will most likely want to just allow 127.0.0.1"
msgstr "Med största sannolikhet vill du enbart tillåta 127.0.0.1"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:496
msgid ""
"The I2P router can automatically start this tunnel for you when the router "
"is started."
msgstr "I2P routern kan starta denna tunneln automatiskt vid uppstart."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:498
msgid ""
"This can be useful for frequently-used tunnels (especially server tunnels), "
"but for tunnels that are only used occassionally it would mean that the I2P "
"router is creating and maintaining unnecessary tunnels."
msgstr "Detta kan vara användbart för tunnlar som används ofta (tex server-tunnlar) men för tunnlar som används sällan innebär det att onödiga tunnlar upprättas. "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:524
msgid "The wizard has now collected enough information to create your tunnel."
msgstr "Guiden hat samlat tillräckligt med information för att skapa tunneln. "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:526
msgid ""
"Upon clicking the Save button below, the wizard will set up the tunnel, and "
"take you back to the main I2PTunnel page."
msgstr "När du klickar på \"spara\" kommer guiden att skapa tunneln och sedan ta dig till sidan för tunnlar."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:531
msgid ""
"Because you chose to automatically start the tunnel when the router starts, "
"you don't have to do anything further."
msgstr "Efter som du valt att starta tunneln samtidigt som routern startas behövs inget mer göras. "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:533
msgid "The router will start the tunnel once it has been set up."
msgstr "Routern starta tunneln när den skapats. "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:537
msgid ""
"Because you chose not to automatically start the tunnel, you will have to "
"manually start it."
msgstr "Efter som du valt att inte starta tunneln samtidigt som routern startas, behövs den startas manuellt."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:539
msgid ""
"You can do this by clicking the Start button on the main page which "
"corresponds to the new tunnel."
msgstr "Du gör det genom att klicka på startknappen vid tunneln på huvudsidan."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:543
msgid "Below is a summary of the options you chose:"
msgstr "Nedan är en sammanfattning över valen du kan göra:"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:641
msgid ""
"Alongside these basic settings, there are a number of advanced options for "
"tunnel configuration."
msgstr "Vid sidan om dessa grundägande inställningar finns att par avancerade val för tunneln. "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:643
msgid ""
"The wizard will set reasonably sensible default values for these, but you "
"can view and/or edit these by clicking on the tunnel's name in the main "
"I2PTunnel page."
msgstr "Guiden väljer lämpliga värden för dessa. Men du kan ändra/se värdena på huvudsidan för I2P-tunnlar."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:683
msgid "Previous"
msgstr "Föregående"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:691
msgid "Save Tunnel"
msgstr "Spara tunnel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:697
msgid "Finish"
msgstr "Färdig"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:703
msgid "Next"
msgstr "Nästa"

View File

@@ -5,123 +5,117 @@
#
# Translators:
# Denis <gribua@gmail.com>, 2011.
# Denis Lysenko <gribua@gmail.com>, 2012.
msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: https://trac.i2p2.de/\n"
"POT-Creation-Date: 2011-12-12 11:18+0000\n"
"PO-Revision-Date: 2011-12-16 22:15+0000\n"
"Last-Translator: Denis <gribua@gmail.com>\n"
"Language-Team: Ukrainian (Ukraine) (http://www.transifex.net/projects/p/I2P/team/uk_UA/)\n"
"POT-Creation-Date: 2012-02-17 11:25+0000\n"
"PO-Revision-Date: 2012-02-17 12:01+0000\n"
"Last-Translator: Denis Lysenko <gribua@gmail.com>\n"
"Language-Team: Ukrainian (Ukraine) (http://www.transifex.net/projects/p/I2P/language/uk_UA/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: uk_UA\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:487
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:492
msgid "This seems to be a bad destination:"
msgstr "Скоріше всього це поганий адрес призначення:"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:487
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:492
msgid "i2paddresshelper cannot help you with a destination like that!"
msgstr "i2paddresshelper не може допомогти Вам з місцем призначення як це!"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:556
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:561
#, java-format
msgid ""
"To visit the destination in your host database, click <a "
"href=\"{0}\">here</a>. To visit the conflicting addresshelper destination, "
"click <a href=\"{1}\">here</a>."
msgstr ""
"Для того щоб перейти по локальному посиланню з локальної адресної книги, "
"натисніть ось<a href=\"{0}\">тут</a>. Для переходу по новому addresshelper-"
"посиланню, натисніть будь-ласка <a href=\"{1}\">тут</a>."
msgstr "Для того щоб перейти по локальному посиланню з локальної адресної книги, натисніть ось<a href=\"{0}\">тут</a>. Для переходу по новому addresshelper-посиланню, натисніть будь-ласка <a href=\"{1}\">тут</a>."
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:932
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:937
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:398
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:142
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:401
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:391
msgid "Host"
msgstr "Адрес"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:933
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:370
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:938
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:372
msgid "Destination"
msgstr "Адреса призначення"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:938
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:943
#, java-format
msgid "Continue to {0} without saving"
msgstr "Продовжити до {0} без збереження"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:943
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:948
#, java-format
msgid "Save {0} to router address book and continue to eepsite"
msgstr ""
"Зберегти {0} в адресну книгу роутера и продовжити перехід до eep-сайту"
msgstr "Зберегти {0} в адресну книгу роутера и продовжити перехід до eep-сайту"
#. only blockfile supports multiple books
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:946
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:951
#, java-format
msgid "Save {0} to master address book and continue to eepsite"
msgstr ""
"Зберегти {0} в основну адресну книгу і продовжити перехід до еер-сайту"
msgstr "Зберегти {0} в основну адресну книгу і продовжити перехід до еер-сайту"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:947
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:952
#, java-format
msgid "Save {0} to private address book and continue to eepsite"
msgstr ""
"Зберегти {0} в приватну адресну книгу і продовжити перехід до еер-сайту."
msgstr "Зберегти {0} в приватну адресну книгу і продовжити перехід до еер-сайту."
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1102
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1107
msgid "HTTP Outproxy"
msgstr "Вихідний HTTP проксі"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1107
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1112
msgid ""
"Click a link below to look for an address helper by using a \"jump\" "
"service:"
msgstr ""
"\"Jump\" сервіси, які, можливо, знають необхідне Вам addresshelper-"
"посилання."
msgstr "\"Jump\" сервіси, які, можливо, знають необхідне Вам addresshelper-посилання."
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1325
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1330
msgid "Added via address helper"
msgstr "Додано через address helper"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1349
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1354
#, java-format
msgid "Redirecting to {0}"
msgstr "Перенаправляємо до {0}"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1355
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1360
msgid "Router Console"
msgstr "Консоль роутера"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1356
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1361
msgid "Addressbook"
msgstr "Адресна книга"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1356
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1361
msgid "Configuration"
msgstr "Настройки"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1356
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1361
msgid "Help"
msgstr "Допомога"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1361
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1366
#, java-format
msgid "Saved {0} to the {1} addressbook, redirecting now."
msgstr "{0} збережено в {1} адресної книги, перенапрявляємо."
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1362
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1367
#, java-format
msgid "Failed to save {0} to the {1} addressbook, redirecting now."
msgstr "Не вдалось зберегти {0} в {1} адресної книги, перенаправляємо."
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1364
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1369
msgid "Click here if you are not redirected automatically."
msgstr "Клацніть тут якщо вас не перенаправило автоматично."
@@ -134,9 +128,7 @@ msgstr "внутрішній"
msgid ""
"Invalid form submission, probably because you used the 'back' or 'reload' "
"button on your browser. Please resubmit."
msgstr ""
"Неправильно передана форма, можливо ви використовуєте дію браузера \"назад\""
" або \"оновити\". Будь-ласка повторіть спробу."
msgstr "Неправильно передана форма, можливо ви використовуєте дію браузера \"назад\" або \"оновити\". Будь-ласка повторіть спробу."
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:222
msgid "Configuration reloaded for all tunnels"
@@ -210,17 +202,15 @@ msgstr "Streamr сервер"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:467
msgid "HTTP bidir"
msgstr ""
"HTTP bidir (експерементальний двухнаправлений режим, інструкцію запитуйте у "
"sponge)"
msgstr "HTTP bidir (експерементальний двухнаправлений режим, інструкцію запитуйте у sponge)"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:555
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:293
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:295
msgid "Host not set"
msgstr "Хост не заданий"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:559
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:275
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:277
msgid "Port not set"
msgstr "Порт не заданий"
@@ -238,24 +228,26 @@ msgstr "Нові налаштування проксі"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:112
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:112
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:110
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:124
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:245
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:260
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:112
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:126
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:247
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:262
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:307
msgid "Name"
msgstr "Назва"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:116
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:116
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:249
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:282
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:251
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:284
msgid "Type"
msgstr "Тип"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:120
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:120
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:229
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:389
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:231
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:391
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:311
msgid "Description"
msgstr "Опис"
@@ -281,22 +273,27 @@ msgstr "необхідно"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:159
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:178
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:460
msgid "Reachable by"
msgstr "Доступно цим"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:180
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:339
msgid "Outproxies"
msgstr "Список вихідних проксі (Outproxies)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:187
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:359
msgid "Tunnel Destination"
msgstr "Адреса Призначення Тунелю"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:199
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:363
msgid "name or destination"
msgstr "ім'я або призначення"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:202
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:366
msgid "b32 not recommended"
msgstr "b32 не рекомендується"
@@ -308,18 +305,18 @@ msgstr "Колективний Клієнт"
msgid ""
"(Share tunnels with other clients and irc/httpclients? Change requires "
"restart of client proxy)"
msgstr ""
"(Використовувати тунелі спільно з іншими клієнтами і irc/httpclients? Зміна"
" налаштування потребує перезапуску тунелю)"
msgstr "(Використовувати тунелі спільно з іншими клієнтами і irc/httpclients? Зміна налаштування потребує перезапуску тунелю)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:216
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:124
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:500
msgid "Auto Start"
msgstr "Автозапуск"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:220
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:228
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:128
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:504
msgid "(Check the Box for 'YES')"
msgstr "(Виберіть чекбокс 'ТАК')"
@@ -336,9 +333,7 @@ msgstr "Розширені мережеві опції"
msgid ""
"(NOTE: when this client proxy is configured to share tunnels, then these "
"options are for all the shared proxy clients!)"
msgstr ""
"(Зверніть увагу: коли цей клієнтський проксі настроєний ділитись тунелями, "
"то ці опції будуть дійсні для всіх проксі клієнтів з якими ви ділитесь!)"
msgstr "(Зверніть увагу: коли цей клієнтський проксі настроєний ділитись тунелями, то ці опції будуть дійсні для всіх проксі клієнтів з якими ви ділитесь!)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:236
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:245
@@ -368,8 +363,7 @@ msgstr "2 хоп тунель (висока анонімність, велики
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:257
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:266
msgid "3 hop tunnel (very high anonymity, poor performance)"
msgstr ""
"3 хоп тунель (дуже висока анонімність, погана продуктивність (комп'ютера))"
msgstr "3 хоп тунель (дуже висока анонімність, погана продуктивність (комп'ютера))"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:266
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:275
@@ -390,21 +384,18 @@ msgstr "0 хоп розкид (без рандомізації, фіксован
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:291
msgid ""
"+ 0-1 hop variance (medium additive randomisation, subtractive performance)"
msgstr ""
"+0-1 хоп розкид (помірна збільшена рандомізація, понижена продуктивність)"
msgstr "+0-1 хоп розкид (помірна збільшена рандомізація, понижена продуктивність)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:286
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:295
msgid ""
"+ 0-2 hop variance (high additive randomisation, subtractive performance)"
msgstr ""
"+0-2 хоп розкид (дуже збільшена рандомізація, понижена продуктивність)"
msgstr "+0-2 хоп розкид (дуже збільшена рандомізація, понижена продуктивність)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:290
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:299
msgid "+/- 0-1 hop variance (standard randomisation, standard performance)"
msgstr ""
"+/- 0-1 хоп розкид (стандартна рандомізація, стандартна продуктивнсть)"
msgstr "+/- 0-1 хоп розкид (стандартна рандомізація, стандартна продуктивнсть)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:294
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:303
@@ -424,26 +415,20 @@ msgstr "Кількість"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:318
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:327
msgid "1 inbound, 1 outbound tunnel (low bandwidth usage, less reliability)"
msgstr ""
"1 вхідний, 1 вихідний тунель (низька пропускна спроможність, низька "
"надійність)"
msgstr "1 вхідний, 1 вихідний тунель (низька пропускна спроможність, низька надійність)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:322
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:331
msgid ""
"2 inbound, 2 outbound tunnels (standard bandwidth usage, standard "
"reliability)"
msgstr ""
"2 вхідні, 2 вихідні тунелі (стандартна пропускна спроможність, стандартна "
"надійність)"
msgstr "2 вхідні, 2 вихідні тунелі (стандартна пропускна спроможність, стандартна надійність)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:326
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:335
msgid ""
"3 inbound, 3 outbound tunnels (higher bandwidth usage, higher reliability)"
msgstr ""
"3 вхідні, 3 вихідні тунелі (висока пропускна спроможність, висока "
"надійність)"
msgstr "3 вхідні, 3 вихідні тунелі (висока пропускна спроможність, висока надійність)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:335
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:344
@@ -458,31 +443,23 @@ msgstr "Резервна кількість"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:347
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:356
msgid "0 backup tunnels (0 redundancy, no added resource usage)"
msgstr ""
"0 резервних тунелів (0 надлишок, відсутність додаткового навантаження на "
"систему) "
msgstr "0 резервних тунелів (0 надлишок, відсутність додаткового навантаження на систему) "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:351
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:360
msgid "1 backup tunnel each direction (low redundancy, low resource usage)"
msgstr ""
"1 резервний тунель в кожному напрямку (низька надлишковість, низьке "
"використання ресурсів системи)"
msgstr "1 резервний тунель в кожному напрямку (низька надлишковість, низьке використання ресурсів системи)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:355
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:364
msgid ""
"2 backup tunnels each direction (medium redundancy, medium resource usage)"
msgstr ""
"2 резервні тунелі в кожному напрямку (середня надмірність, середнє "
"навантаження на систему)"
msgstr "2 резервні тунелі в кожному напрямку (середня надмірність, середнє навантаження на систему)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:359
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:368
msgid "3 backup tunnels each direction (high redundancy, high resource usage)"
msgstr ""
"3 резервні тунелі в кожному напрямку (висока надмірність, високе "
"навантаження на систему)"
msgstr "3 резервні тунелі в кожному напрямку (висока надмірність, високе навантаження на систему)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:368
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:377
@@ -502,8 +479,7 @@ msgstr "оптимізувати для малих затримок (irc)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:386
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:395
msgid "bulk connection (downloads/websites/BT)"
msgstr ""
"оптимізувати для великого об'єму (завантаження/веб-серфінг/Бітторрент)"
msgstr "оптимізувати для великого об'єму (завантаження/веб-серфінг/Бітторрент)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:388
msgid "Delay Connect"
@@ -511,9 +487,7 @@ msgstr "Затримка Зєднання"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:392
msgid "for request/response connections"
msgstr ""
"оптимізація для з'єднань, які починаються з запиту клієнта/відповіді "
"сервера. "
msgstr "оптимізація для з'єднань, які починаються з запиту клієнта/відповіді сервера. "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:396
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:399
@@ -523,8 +497,9 @@ msgstr "I2CP Адрес Роутера"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:406
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:148
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:409
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:247
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:269
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:249
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:271
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:412
msgid "Port"
msgstr "Порт"
@@ -622,12 +597,11 @@ msgstr "Вибіркові параметри"
msgid ""
"NOTE: If tunnel is currently running, most changes will not take effect "
"until tunnel is stopped and restarted."
msgstr ""
"Примітка: Якщо тунель зараз активний, то більшість змін не почнуть діяти до "
"того моменту поки тунель не зупинять і перезапустять."
msgstr "Примітка: Якщо тунель зараз активний, то більшість змін не почнуть діяти до того моменту поки тунель не зупинять і перезапустять."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:524
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:531
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:678
msgid "Cancel"
msgstr "Відмінити"
@@ -786,117 +760,466 @@ msgstr "Повідомлення про стан"
msgid "Refresh"
msgstr "Оновити"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:94
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:92
msgid "Tunnel Wizard"
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:96
msgid "Stop All"
msgstr "Зупинити все"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:98
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:100
msgid "Start All"
msgstr "Запустити все"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:102
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:104
msgid "Restart All"
msgstr "Перезапустити все"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:106
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:108
msgid "Reload Config"
msgstr "Перезапустити настройки"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:108
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:110
msgid "I2P Server Tunnels"
msgstr "Серверні I2P тунелі"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:112
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:133
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:114
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:135
msgid "Points at"
msgstr "Вказує на"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:114
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:156
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:160
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:116
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:158
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:162
msgid "Preview"
msgstr "Попередній перегляд"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:116
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:180
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:253
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:300
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:118
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:182
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:255
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:302
msgid "Status"
msgstr "Статус"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:166
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:168
msgid "Base32 Address"
msgstr "Base32-адрес"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:174
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:176
msgid "No Preview"
msgstr "Попередній перегляд недоступний"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:187
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:307
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:189
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:309
msgid "Starting..."
msgstr "Запускається..."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:194
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:208
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:314
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:328
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:342
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:196
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:210
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:316
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:330
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:344
msgid "Stop"
msgstr "Зупинити"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:201
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:335
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:203
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:337
msgid "Running"
msgstr "Працює"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:215
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:349
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:217
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:351
msgid "Stopped"
msgstr "Зупинений"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:222
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:356
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:224
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:358
msgid "Start"
msgstr "Запустити"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:237
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:239
msgid "New server tunnel"
msgstr "Новий серверний тунель"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:239
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:399
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:241
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:401
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:204
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:246
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:276
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:282
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:554
msgid "Standard"
msgstr "Стандартний"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:241
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:401
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:243
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:403
msgid "Create"
msgstr "Створити"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:243
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:245
msgid "I2P Client Tunnels"
msgstr "Клієнтскі I2P тунелі"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:251
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:286
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:253
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:288
msgid "Interface"
msgstr "Мережевий інтерфейс"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:321
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:323
msgid "Standby"
msgstr "Режим очікування"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:366
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:368
msgid "Outproxy"
msgstr "Outproxy (зовнішній проксі)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:384
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:386
msgid "none"
msgstr "ні"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:397
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:399
msgid "New client tunnel"
msgstr "Новий клієнтський тунель"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:102
msgid "I2P Tunnel Manager - Tunnel Creation Wizard"
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:120
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:545
msgid "Server or client tunnel?"
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:126
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:549
msgid "Tunnel type"
msgstr "Тип тунелю"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:132
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:579
msgid "Tunnel name and description"
msgstr "Ім'я і опис тунелю"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:138
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:588
msgid "Tunnel destination"
msgstr "Місце призначення тунелю"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:144
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:604
msgid "Binding address and port"
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:150
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:630
msgid "Tunnel auto-start"
msgstr "Авто-старт тунелю"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:156
msgid "Wizard completed"
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:170
msgid ""
"This wizard will take you through the various options available for creating"
" tunnels in I2P."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:172
msgid ""
"The first thing to decide is whether you want to create a server or a client"
" tunnel."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:174
msgid ""
"If you need to connect to a remote service, such as an IRC server inside I2P"
" or a code repository, then you will require a CLIENT tunnel."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:176
msgid ""
"On the other hand, if you wish to host a service for others to connect to "
"you'll need to create a SERVER tunnel."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:178
msgid "Server Tunnel"
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:180
msgid "Client Tunnel"
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:198
msgid "There are several types of tunnels to choose from:"
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:206
msgid "Basic tunnel for connecting to a single service inside I2P."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:208
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:250
msgid ""
"Try this if none of the tunnel types below fit your requirements, or you "
"don't know what type of tunnel you need."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:210
msgid "Tunnel that acts as an HTTP proxy for reaching eepsites inside I2P."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:212
msgid ""
"Set your browser to use this tunnel as an http proxy, or set your "
"\"http_proxy\" environment variable for command-line applications in "
"GNU/Linux."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:214
msgid ""
"Websites outside I2P can also be reached if an HTTP proxy within I2P is "
"known."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:216
msgid "Customised client tunnel specific for IRC connections."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:218
msgid ""
"With this tunnel type, your IRC client will be able to connect to an IRC "
"network inside I2P."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:220
msgid ""
"Each IRC network in I2P that you wish to connect to will require its own "
"tunnel. (See Also, SOCKS IRC)"
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:222
msgid "A tunnel that implements the SOCKS protocol."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:224
msgid ""
"This enables both TCP and UDP connections to be made through a SOCKS "
"outproxy within I2P."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:226
msgid ""
"A client tunnel implementing the SOCKS protocol, which is customised for "
"connecting to IRC networks."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:228
msgid ""
"With this tunnel type, IRC networks in I2P can be reached by typing the I2P "
"address into your IRC client, and configuring the IRC client to use this "
"SOCKS tunnel."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:230
msgid ""
"This means that only one I2P tunnel is required rather than a separate "
"tunnel per IRC network."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:232
msgid ""
"IRC networks outside I2P can also be reached if a SOCKS outproxy within I2P "
"is known, though it depends on whether or not the outproxy has been blocked "
"by the IRC network."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:234
msgid "A client tunnel that implements the HTTP CONNECT command."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:236
msgid ""
"This enables TCP connections to be made through an HTTP outproxy, assuming "
"the proxy supports the CONNECT command."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:238
msgid "A customised client tunnel for Streamr."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:248
msgid "A basic server tunnel for hosting a generic service inside I2P."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:252
msgid "A server tunnel that is customised for HTTP connections."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:254
msgid "Use this tunnel type if you want to host an eepsite."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:256
msgid ""
"A customised server tunnel that can both serve HTTP data and connect to "
"other server tunnels."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:258
msgid "This tunnel type is predominantly used when running a Seedless server."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:260
msgid "A customised server tunnel for hosting IRC networks inside I2P."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:262
msgid ""
"Usually, a separate tunnel needs to be created for each IRC server that is "
"to be accessible inside I2P."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:264
msgid "A customised server tunnel for Streamr."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:303
msgid "Choose a name and description for your tunnel."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:305
msgid ""
"These can be anything you want - they are just for ease of identifying the "
"tunnel in the routerconsole."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:335
msgid ""
"If you know of any outproxies for this type of tunnel (either HTTP or "
"SOCKS), fill them in below."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:337
msgid "Separate multiple proxies with commas."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:355
msgid ""
"Type in the I2P destination of the service that this client tunnel should "
"connect to."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:357
msgid ""
"This could be the full base 64 destination key, or an I2P URL from your "
"address book."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:387
msgid ""
"This is the IP that your service is running on, this is usually on the same "
"machine so 127.0.0.1 is autofilled."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:410
msgid "This is the port that the service is accepting connections on."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:431
msgid "This is the port that the client tunnel will be accessed from locally."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:433
msgid "This is also the client port for the HTTPBidir server tunnel."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:452
msgid ""
"How do you want this tunnel to be accessed? By just this machine, your "
"entire subnet, or external internet?"
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:454
msgid "You will most likely want to just allow 127.0.0.1"
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:496
msgid ""
"The I2P router can automatically start this tunnel for you when the router "
"is started."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:498
msgid ""
"This can be useful for frequently-used tunnels (especially server tunnels), "
"but for tunnels that are only used occassionally it would mean that the I2P "
"router is creating and maintaining unnecessary tunnels."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:524
msgid "The wizard has now collected enough information to create your tunnel."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:526
msgid ""
"Upon clicking the Save button below, the wizard will set up the tunnel, and "
"take you back to the main I2PTunnel page."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:531
msgid ""
"Because you chose to automatically start the tunnel when the router starts, "
"you don't have to do anything further."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:533
msgid "The router will start the tunnel once it has been set up."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:537
msgid ""
"Because you chose not to automatically start the tunnel, you will have to "
"manually start it."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:539
msgid ""
"You can do this by clicking the Start button on the main page which "
"corresponds to the new tunnel."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:543
msgid "Below is a summary of the options you chose:"
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:641
msgid ""
"Alongside these basic settings, there are a number of advanced options for "
"tunnel configuration."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:643
msgid ""
"The wizard will set reasonably sensible default values for these, but you "
"can view and/or edit these by clicking on the tunnel's name in the main "
"I2PTunnel page."
msgstr ""
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:683
msgid "Previous"
msgstr "Попередній"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:691
msgid "Save Tunnel"
msgstr "Зберегти тунель"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:697
msgid "Finish"
msgstr "Завершити"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:703
msgid "Next"
msgstr "Далі"

View File

@@ -0,0 +1,16 @@
Apache Tomcat
Copyright 1999-2011 The Apache Software Foundation
This product includes software developed by
The Apache Software Foundation (http://www.apache.org/).
The Windows Installer is built with the Nullsoft
Scriptable Install Sysem (NSIS), which is
open source software. The original software and
related information is available at
http://nsis.sourceforge.net.
Java compilation software for JSP pages is provided by Eclipse,
which is open source software. The original software and
related information is available at
http://www.eclipse.org.

View File

@@ -0,0 +1,14 @@
This is Apache Tomcat 6.x, supporting Servlet 2.5 and JSP 2.1.
The Glassfish JSP 2.1 bundled in Jetty 6 is way too old.
Retrieved from the file
apache-tomcat-6.0.35-deployer.tar.gz
minus the following files and directores:
build.xml
deployer-howto.html
images/*
lib/catalina*
LICENSE (see ../../../licenses/LICENSE-Apache2.0.txt, it's also inside every jar)
RELEASE-NOTES

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,15 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project basedir="." default="all" name="jetty">
<property name="jetty.base" value="jetty-5.1.15" />
<property name="jetty.sha1" value="3a7a3de50f86f0cdb23c33aec632ea7f44132c5e" />
<property name="jetty.filename" value="${jetty.base}.tgz" />
<property name="jetty.url" value="http://dist.codehaus.org/jetty/jetty-5.1.x/${jetty.filename}" />
<property name="jetty.ver" value="6.1.26" />
<property name="jetty.base" value="jetty-${jetty.ver}" />
<property name="jetty.sha1" value="9485913f1a1945a849a90f1a34853d22350bc524" />
<property name="jetty.filename" value="${jetty.base}.zip" />
<property name="jetty.url" value="http://dist.codehaus.org/jetty/${jetty.base}/${jetty.filename}" />
<property name="verified.filename" value="verified.txt" />
<property name="javac.compilerargs" value="" />
<property name="tomcat.lib" value="apache-tomcat-deployer/lib" />
<target name="all" depends="build" />
<!--
<target name="ensureJettylib" >
<available property="jetty.zip.available" file="${jetty.filename}" type="file" />
<available property="jetty.zip.extracted" file="jettylib" type="dir" />
@@ -17,6 +20,8 @@
<ant target="verifyJettylib" />
<ant target="extractJettylib" />
</target>
-->
<target name="ensureJettylib" depends="extractJettylib" />
<target name="fetchJettylib" unless="jetty.zip.available" >
<echo message="It seems that you don't have '${jetty.filename}' deployed." />
@@ -63,27 +68,92 @@
<touch file="${verified.filename}" />
</target>
<!--
<target name="extractJettylib" unless="jetty.zip.extracted" >
-->
<target name="extractJettylib" >
<!-- for .tgz -->
<!--
<gunzip src="${jetty.filename}" dest="jetty.tar" />
<untar src="jetty.tar" dest="." />
-->
<!-- for .zip -->
<!--
<unzip src="${jetty.filename}" dest="." />
-->
<mkdir dir="jettylib" />
<copy todir="jettylib" preservelastmodified="true" >
<fileset dir="${jetty.base}/lib">
<include name="*.jar" />
</fileset>
<fileset dir="${jetty.base}/ext">
<include name="ant.jar" />
<include name="commons-el.jar" />
<include name="commons-logging.jar" />
<include name="jasper-compiler.jar" />
<include name="jasper-runtime.jar" />
</fileset>
</copy>
<!-- We copy everything to names without the version numbers so we
can update them later. Where there was something similar in Jetty 5,
we use the same names so they will overwrite the Jetty 5 jar on upgrade.
Otherwise we use the same name as the symlink in Ubuntu /usr/share/java.
Reasons for inclusion:
start.jar: Needed for clients.config startup of eepsites
jetty-util-xxx.jar: LifeCycle (base class for stuff), URIUtil (used in i2psnark)
jetty-sslengine-xxx.jar: SSL NIO Connector for console
jetty-java5-threadpool-xxx.jar: Concurrent thread pool for eepsite
glassfish 2.1: Not used, too old, see Tomcat below.
jetty-rewrite-handler: Not used by I2P, but only 20KB and could be useful for eepsites
jetty-management: Not used by I2P, but only 34KB and could be useful for eepsites, and we bundled it with Jetty 5
All of these are available in the Ubuntu packages libjetty-java and libjetty-extra-java
-->
<copy preservelastmodified="true" file="${jetty.base}/start.jar" tofile="jettylib/jetty-start.jar" />
<copy file="${jetty.base}/lib/${jetty.base}.jar" tofile="jettylib/org.mortbay.jetty.jar" />
<copy preservelastmodified="true" file="${jetty.base}/lib/jetty-util-${jetty.ver}.jar" tofile="jettylib/jetty-util.jar" />
<copy preservelastmodified="true" file="${jetty.base}/lib/ext/jetty-java5-threadpool-${jetty.ver}.jar" tofile="jettylib/jetty-java5-threadpool.jar" />
<copy preservelastmodified="true" file="${jetty.base}/lib/ext/jetty-rewrite-handler-${jetty.ver}.jar" tofile="jettylib/jetty-rewrite-handler.jar" />
<copy preservelastmodified="true" file="${jetty.base}/lib/ext/jetty-sslengine-${jetty.ver}.jar" tofile="jettylib/jetty-sslengine.jar" />
<copy preservelastmodified="true" file="${jetty.base}/lib/management/jetty-management-${jetty.ver}.jar" tofile="jettylib/org.mortbay.jmx.jar" />
<delete file="jetty.tar" />
<!--
<delete dir="${jetty.base}" />
-->
<!-- commons-logging.jar not in Jetty 6 but we have it in launch4j so copy it over,
needed for old plugins and things. We add tomcat-juli below.
-->
<jar destfile="jettylib/commons-logging.jar" filesetmanifest="mergewithoutmain" >
<zipfileset excludes="META-INF/LICENSE.txt META-INF/NOTICE.txt" src="../../installer/lib/launch4j/lib/commons-logging.jar" />
</jar>
<ant target="copyTomcatLib" />
</target>
<!-- Tomcat.
The glassfish jars bundled in Jetty 6 are way too old.
For compatibility with very old I2P installations where the classpath
was set individually in wrapper.config, we rename and combine the jars as follows:
jasper.jar : jasper-runtime.jar
jasper-el.jar + el-api.jar : commons-el.jar
servlet-api.jar + jsp-api.jar : javax.servlet.jar
tomcat-juli.jar : Add to commons-logging.jar
empty jar : jasper-compiler.jar
Also, take NOTICE and LICENSE out of each one, we bundle those separately.
-->
<target name="copyTomcatLib" >
<jar destfile="jettylib/jasper-runtime.jar" filesetmanifest="merge" >
<zipfileset excludes="META-INF/LICENSE META-INF/NOTICE" src="${tomcat.lib}/jasper.jar" />
</jar>
<jar destfile="jettylib/commons-el.jar" duplicate="preserve" filesetmanifest="merge" >
<zipfileset excludes="META-INF/LICENSE META-INF/NOTICE" src="${tomcat.lib}/jasper-el.jar" />
<zipfileset excludes="META-INF/**/*" src="${tomcat.lib}/el-api.jar" />
</jar>
<jar destfile="jettylib/javax.servlet.jar" duplicate="preserve" filesetmanifest="mergewithoutmain" >
<zipfileset excludes="META-INF/LICENSE META-INF/NOTICE" src="${tomcat.lib}/servlet-api.jar" />
<zipfileset excludes="META-INF/**/*" src="${tomcat.lib}/jsp-api.jar" />
</jar>
<!-- Ant bug, don't set update and filesetmanifest or the update doesn't happen,
Their bug tracker claims fixed in 1.8.0 but broken for me in 1.8.1
-->
<jar destfile="jettylib/commons-logging.jar" update="true" >
<zipfileset excludes="META-INF/LICENSE META-INF/NOTICE" src="${tomcat.lib}/tomcat-juli.jar" />
</jar>
<jar destfile="jettylib/jasper-compiler.jar" >
<manifest>
<attribute name="Note" value="Intentionally empty" />
</manifest>
</jar>
</target>
<target name="build" depends="jar" />
<target name="builddep" />
<target name="compile" depends="builddep, ensureJettylib" >
<mkdir dir="./build" />
@@ -93,7 +163,7 @@
debug="true" source="1.5" target="1.5"
destdir="./build/obj"
includeAntRuntime="false"
classpath="./jettylib/commons-logging.jar:./jettylib/javax.servlet.jar:./jettylib/org.mortbay.jetty.jar" >
classpath="../../core/java/build/i2p.jar:./jettylib/commons-logging.jar:./jettylib/javax.servlet.jar:./jettylib/org.mortbay.jetty.jar:./jettylib/jetty-util.jar" >
<compilerarg line="${javac.compilerargs}" />
</javac>
</target>
@@ -112,11 +182,18 @@
</exec>
</target>
<!-- With Jetty 5 we replaced classes in the jar, but with Jetty 6 we
put our stuff in its own jar so we can work with standard Jetty 6 packages
-->
<target name="jar" depends="compile, jarUpToDate, listChangedFiles" unless="jar.uptodate" >
<!-- set if unset -->
<property name="workspace.changes.tr" value="" />
<jar destfile="./jettylib/org.mortbay.jetty.jar" basedir="./build/obj" includes="**/*.class" update="true" >
<!-- old jetty 5 classes blow up the build if you forgot to do distclean -->
<delete dir="build/obj/org" />
<copy todir="build/obj" file="resources/log4j.properties" />
<jar destfile="./jettylib/jetty-i2p.jar" basedir="./build/obj" includes="**/*.class log4j.properties" >
<manifest>
<attribute name="Built-By" value="${build.built-by}" />
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
@@ -125,7 +202,7 @@
</target>
<target name="jarUpToDate">
<uptodate property="jar.uptodate" targetfile="jettylib/org.mortbay.jetty.jar" >
<uptodate property="jar.uptodate" targetfile="jettylib/jetty-i2p.jar" >
<srcfiles dir= "build/obj" includes="**/*.class" />
</uptodate>
<condition property="shouldListChanges" >
@@ -145,7 +222,9 @@
<target name="cleandep" depends="clean" />
<target name="distclean" depends="clean">
<delete dir="./jettylib" />
<!--
<echo message="Not actually deleting the jetty libs (since they're so large)" />
-->
</target>
<target name="reallyclean" depends="distclean">
</target>

View File

@@ -0,0 +1,186 @@
// ========================================================================
// Copyright 2004-2005 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================
package net.i2p.jetty;
import net.i2p.I2PAppContext;
import net.i2p.util.Log;
import org.mortbay.jetty.Server;
import org.mortbay.log.Logger;
/**
* Modified from Jetty 6.1.26 StdErrLog.java and Slf4jLog.java
*
* Usage: org.mortbay.log.Log.setLog(new I2PLogger(ctx));
*
* @since Jetty 6
*/
public class I2PLogger implements Logger
{
private final Log _log;
StringBuilder _buffer = new StringBuilder();
static {
// So people don't wonder where the logs went
System.out.println("INFO: Jetty " + Server.getVersion() + " logging to I2P logs using class " + Server.class.getName());
}
public I2PLogger()
{
this(I2PAppContext.getGlobalContext());
}
public I2PLogger(I2PAppContext ctx)
{
_log = ctx.logManager().getLog(Server.class);
if (System.getProperty("DEBUG") != null)
setDebugEnabled(true);
}
public boolean isDebugEnabled()
{
return _log.shouldLog(Log.DEBUG);
}
public void setDebugEnabled(boolean enabled)
{
if (enabled)
_log.setMinimumPriority(Log.DEBUG);
else
// LogManager.getDefaultLimit() returns a String, not worth it
_log.setMinimumPriority(Log.ERROR);
}
public void info(String msg,Object arg0, Object arg1)
{
if (arg0 == null && arg1 == null) {
_log.info(msg);
} else if (arg0 != null && arg1 == null && arg0 instanceof Throwable) {
_log.info(msg, (Throwable) arg0);
} else if (_log.shouldLog(Log.INFO)) {
synchronized(_buffer) {
format(msg,arg0,arg1);
_log.info(_buffer.toString());
}
}
}
public void debug(String msg,Throwable th)
{
_log.debug(msg,th);
}
public void debug(String msg,Object arg0, Object arg1)
{
if (arg0 == null && arg1 == null) {
_log.debug(msg);
} else if (arg0 != null && arg1 == null && arg0 instanceof Throwable) {
_log.debug(msg, (Throwable) arg0);
} else if (_log.shouldLog(Log.DEBUG)) {
synchronized(_buffer) {
format(msg,arg0,arg1);
_log.debug(_buffer.toString());
}
}
}
public void warn(String msg,Object arg0, Object arg1)
{
if (arg0 == null && arg1 == null) {
_log.warn(msg);
} else if (arg0 != null && arg1 == null && arg0 instanceof Throwable) {
_log.error(msg, (Throwable) arg0);
} else if (_log.shouldLog(Log.WARN)) {
synchronized(_buffer) {
format(msg,arg0,arg1);
_log.warn(_buffer.toString());
}
}
}
public void warn(String msg, Throwable th)
{
// This doesn't cover ClassNotFoundException, etc.
//if (th instanceof RuntimeException || th instanceof Error)
_log.error(msg, th);
//else
// _log.warn(msg,th);
}
private void format(String msg, Object arg0, Object arg1)
{
_buffer.setLength(0);
int i0=msg==null?-1:msg.indexOf("{}");
int i1=i0<0?-1:msg.indexOf("{}",i0+2);
if (i0>=0)
{
format(msg.substring(0,i0));
format(String.valueOf(arg0==null?"null":arg0));
if (i1>=0)
{
format(msg.substring(i0+2,i1));
format(String.valueOf(arg1==null?"null":arg1));
format(msg.substring(i1+2));
}
else
{
format(msg.substring(i0+2));
if (arg1!=null)
{
_buffer.append(' ');
format(String.valueOf(arg1));
}
}
}
else
{
format(msg);
if (arg0!=null)
{
_buffer.append(' ');
format(String.valueOf(arg0));
}
if (arg1!=null)
{
_buffer.append(' ');
format(String.valueOf(arg1));
}
}
}
private void format(String msg)
{
if (msg == null)
_buffer.append("null");
else
_buffer.append(msg);
}
public Logger getLogger(String name)
{
return this;
}
@Override
public String toString()
{
return "I2PLogger";
}
}

View File

@@ -0,0 +1,513 @@
//========================================================================
//Copyright 1997-2006 Mort Bay Consulting Pty. Ltd.
//------------------------------------------------------------------------
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//http://www.apache.org/licenses/LICENSE-2.0
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
//========================================================================
package net.i2p.jetty;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Locale;
import java.util.TimeZone;
import javax.servlet.http.Cookie;
import org.mortbay.component.AbstractLifeCycle;
import org.mortbay.jetty.HttpHeaders;
import org.mortbay.jetty.Request;
import org.mortbay.jetty.RequestLog;
import org.mortbay.jetty.Response;
import org.mortbay.jetty.servlet.PathMap;
import org.mortbay.log.Log;
import org.mortbay.util.DateCache;
import org.mortbay.util.RolloverFileOutputStream;
import org.mortbay.util.StringUtil;
import org.mortbay.util.TypeUtil;
import org.mortbay.util.Utf8StringBuffer;
/**
* This {@link RequestLog} implementation outputs logs in the pseudo-standard NCSA common log format.
* Configuration options allow a choice between the standard Common Log Format (as used in the 3 log format)
* and the Combined Log Format (single log format).
* This log format can be output by most web servers, and almost all web log analysis software can understand
* these formats.
*
* ** I2P Mods **
*
* For Jetty 5, this extended NCSARequestLog to
* override log() to put in the requestor's destination hash,
* instead of 127.0.0.1,
* which is placed in the X-I2P-DestHash field in the request headers
* by I2PTunnelHTTPServer.
* But we also had to modify NCSARequestLog to do so, to change private
* fields to protected.
*
* So that we will work with system Jetty 6 packages, we just copy the whole thing
* and modify log() as required.
* We leave the package as org.mortbay.http for compatibility with old
* jetty.xml files.
*
* @author Greg Wilkins
* @author Nigel Canonizado
*
*/
public class I2PRequestLog extends AbstractLifeCycle implements RequestLog
{
private String _filename;
private boolean _extended;
private boolean _append;
private int _retainDays;
private boolean _closeOut;
private boolean _preferProxiedForAddress;
private String _logDateFormat="dd/MMM/yyyy:HH:mm:ss Z";
private String _filenameDateFormat = null;
private Locale _logLocale = Locale.getDefault();
private String _logTimeZone = "GMT";
private String[] _ignorePaths;
private boolean _logLatency = false;
private boolean _logCookies = false;
private boolean _logServer = false;
private transient OutputStream _out;
private transient OutputStream _fileOut;
private transient DateCache _logDateCache;
private transient PathMap _ignorePathMap;
private transient Writer _writer;
private transient ArrayList _buffers;
private transient char[] _copy;
public I2PRequestLog()
{
_extended = true;
_append = true;
_retainDays = 31;
}
/* ------------------------------------------------------------ */
/**
* @param filename The filename for the request log. This may be in the format expected by {@link RolloverFileOutputStream}
*/
public I2PRequestLog(String filename)
{
_extended = true;
_append = true;
_retainDays = 31;
setFilename(filename);
}
/* ------------------------------------------------------------ */
/**
* @param filename The filename for the request log. This may be in the format expected by {@link RolloverFileOutputStream}
*/
public void setFilename(String filename)
{
if (filename != null)
{
filename = filename.trim();
if (filename.length() == 0)
filename = null;
}
_filename = filename;
}
public String getFilename()
{
return _filename;
}
public String getDatedFilename()
{
if (_fileOut instanceof RolloverFileOutputStream)
return ((RolloverFileOutputStream)_fileOut).getDatedFilename();
return null;
}
/* ------------------------------------------------------------ */
/**
* @param format Format for the timestamps in the log file. If not set,
* the pre-formated request timestamp is used.
*/
public void setLogDateFormat(String format)
{
_logDateFormat = format;
}
public String getLogDateFormat()
{
return _logDateFormat;
}
public void setLogLocale(Locale logLocale)
{
_logLocale = logLocale;
}
public Locale getLogLocale()
{
return _logLocale;
}
public void setLogTimeZone(String tz)
{
_logTimeZone = tz;
}
public String getLogTimeZone()
{
return _logTimeZone;
}
public void setRetainDays(int retainDays)
{
_retainDays = retainDays;
}
public int getRetainDays()
{
return _retainDays;
}
public void setExtended(boolean extended)
{
_extended = extended;
}
public boolean isExtended()
{
return _extended;
}
public void setAppend(boolean append)
{
_append = append;
}
public boolean isAppend()
{
return _append;
}
public void setIgnorePaths(String[] ignorePaths)
{
_ignorePaths = ignorePaths;
}
public String[] getIgnorePaths()
{
return _ignorePaths;
}
public void setLogCookies(boolean logCookies)
{
_logCookies = logCookies;
}
public boolean getLogCookies()
{
return _logCookies;
}
public boolean getLogServer()
{
return _logServer;
}
public void setLogServer(boolean logServer)
{
_logServer=logServer;
}
public void setLogLatency(boolean logLatency)
{
_logLatency = logLatency;
}
public boolean getLogLatency()
{
return _logLatency;
}
public void setPreferProxiedForAddress(boolean preferProxiedForAddress)
{
_preferProxiedForAddress = preferProxiedForAddress;
}
/* ------------------------------------------------------------ */
public void log(Request request, Response response)
{
if (!isStarted())
return;
try
{
if (_ignorePathMap != null && _ignorePathMap.getMatch(request.getRequestURI()) != null)
return;
if (_fileOut == null)
return;
Utf8StringBuffer u8buf;
StringBuffer buf;
synchronized(_writer)
{
int size=_buffers.size();
u8buf = size==0?new Utf8StringBuffer(160):(Utf8StringBuffer)_buffers.remove(size-1);
buf = u8buf.getStringBuffer();
}
synchronized(buf) // for efficiency until we can use StringBuilder
{
if (_logServer)
{
buf.append(request.getServerName());
buf.append(' ');
}
String addr = null;
if (_preferProxiedForAddress)
{
addr = request.getHeader(HttpHeaders.X_FORWARDED_FOR);
}
if (addr == null) {
// TODO offer B32 option
addr = request.getHeader("X-I2P-DestHash");
if(addr != null)
addr += ".i2p";
else
addr = request.getRemoteAddr();
}
buf.append(addr);
buf.append(" - ");
String user = request.getRemoteUser();
buf.append((user == null)? " - " : user);
buf.append(" [");
if (_logDateCache!=null)
buf.append(_logDateCache.format(request.getTimeStamp()));
else
buf.append(request.getTimeStampBuffer().toString());
buf.append("] \"");
buf.append(request.getMethod());
buf.append(' ');
request.getUri().writeTo(u8buf);
buf.append(' ');
buf.append(request.getProtocol());
buf.append("\" ");
int status = response.getStatus();
if (status<=0)
status=404;
buf.append((char)('0'+((status/100)%10)));
buf.append((char)('0'+((status/10)%10)));
buf.append((char)('0'+(status%10)));
long responseLength=response.getContentCount();
if (responseLength >=0)
{
buf.append(' ');
if (responseLength > 99999)
buf.append(Long.toString(responseLength));
else
{
if (responseLength > 9999)
buf.append((char)('0' + ((responseLength / 10000)%10)));
if (responseLength > 999)
buf.append((char)('0' + ((responseLength /1000)%10)));
if (responseLength > 99)
buf.append((char)('0' + ((responseLength / 100)%10)));
if (responseLength > 9)
buf.append((char)('0' + ((responseLength / 10)%10)));
buf.append((char)('0' + (responseLength)%10));
}
buf.append(' ');
}
else
buf.append(" - ");
}
if (!_extended && !_logCookies && !_logLatency)
{
synchronized(_writer)
{
buf.append(StringUtil.__LINE_SEPARATOR);
int l=buf.length();
if (l>_copy.length)
l=_copy.length;
buf.getChars(0,l,_copy,0);
_writer.write(_copy,0,l);
_writer.flush();
u8buf.reset();
_buffers.add(u8buf);
}
}
else
{
synchronized(_writer)
{
int l=buf.length();
if (l>_copy.length)
l=_copy.length;
buf.getChars(0,l,_copy,0);
_writer.write(_copy,0,l);
u8buf.reset();
_buffers.add(u8buf);
// TODO do outside synchronized scope
if (_extended)
logExtended(request, response, _writer);
// TODO do outside synchronized scope
if (_logCookies)
{
Cookie[] cookies = request.getCookies();
if (cookies == null || cookies.length == 0)
_writer.write(" -");
else
{
_writer.write(" \"");
for (int i = 0; i < cookies.length; i++)
{
if (i != 0)
_writer.write(';');
_writer.write(cookies[i].getName());
_writer.write('=');
_writer.write(cookies[i].getValue());
}
_writer.write('\"');
}
}
if (_logLatency)
{
_writer.write(' ');
_writer.write(TypeUtil.toString(System.currentTimeMillis() - request.getTimeStamp()));
}
_writer.write(StringUtil.__LINE_SEPARATOR);
_writer.flush();
}
}
}
catch (IOException e)
{
Log.warn(e);
}
}
/* ------------------------------------------------------------ */
protected void logExtended(Request request,
Response response,
Writer writer) throws IOException
{
String referer = request.getHeader(HttpHeaders.REFERER);
if (referer == null)
writer.write("\"-\" ");
else
{
writer.write('"');
writer.write(referer);
writer.write("\" ");
}
String agent = request.getHeader(HttpHeaders.USER_AGENT);
if (agent == null)
writer.write("\"-\" ");
else
{
writer.write('"');
writer.write(agent);
writer.write('"');
}
}
/* ------------------------------------------------------------ */
protected void doStart() throws Exception
{
if (_logDateFormat!=null)
{
_logDateCache = new DateCache(_logDateFormat, _logLocale);
_logDateCache.setTimeZoneID(_logTimeZone);
}
if (_filename != null)
{
_fileOut = new RolloverFileOutputStream(_filename,_append,_retainDays,TimeZone.getTimeZone(_logTimeZone),_filenameDateFormat,null);
_closeOut = true;
Log.info("Opened "+getDatedFilename());
}
else
_fileOut = System.err;
_out = _fileOut;
if (_ignorePaths != null && _ignorePaths.length > 0)
{
_ignorePathMap = new PathMap();
for (int i = 0; i < _ignorePaths.length; i++)
_ignorePathMap.put(_ignorePaths[i], _ignorePaths[i]);
}
else
_ignorePathMap = null;
_writer = new OutputStreamWriter(_out);
_buffers = new ArrayList();
_copy = new char[1024];
super.doStart();
}
/* ------------------------------------------------------------ */
protected void doStop() throws Exception
{
super.doStop();
try {if (_writer != null) _writer.flush();} catch (IOException e) {Log.ignore(e);}
if (_out != null && _closeOut)
try {_out.close();} catch (IOException e) {Log.ignore(e);}
_out = null;
_fileOut = null;
_closeOut = false;
_logDateCache = null;
_writer = null;
_buffers = null;
_copy = null;
}
/* ------------------------------------------------------------ */
/**
* @return the log File Date Format
*/
public String getFilenameDateFormat()
{
return _filenameDateFormat;
}
/* ------------------------------------------------------------ */
/** Set the log file date format.
* see RolloverFileOutputStream(String, boolean, int, TimeZone, String, String)
* @param logFileDateFormat the logFileDateFormat to pass to RolloverFileOutputStream
*/
public void setFilenameDateFormat(String logFileDateFormat)
{
_filenameDateFormat=logFileDateFormat;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,182 +0,0 @@
// ========================================================================
// $Id: NCSARequestLog.java,v 1.35 2005/08/13 00:01:24 gregwilkins Exp $
// Copyright 2000-2004 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================
package org.mortbay.http;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Locale;
import java.util.TimeZone;
import javax.servlet.http.Cookie;
import org.apache.commons.logging.Log;
import org.mortbay.log.LogFactory;
import org.mortbay.util.DateCache;
import org.mortbay.util.LogSupport;
import org.mortbay.util.RolloverFileOutputStream;
import org.mortbay.util.StringUtil;
/* ------------------------------------------------------------ */
/** NCSA HTTP Request Log.
*
* Override log() to put in the requestor's destination hash,
* instead of 127.0.0.1,
* which is placed in the X-I2P-DestHash field in the request headers
* by I2PTunnelHTTPServer.
*
* NCSA common or NCSA extended (combined) request log.
* @version $Id: NCSARequestLog.java,v 1.35 2005/08/13 00:01:24 gregwilkins Exp $
* @author Tony Thompson
* @author Greg Wilkins
*/
public class I2PRequestLog extends NCSARequestLog
{
/* ------------------------------------------------------------ */
/** Constructor.
*/
public I2PRequestLog()
{
super();
}
/* ------------------------------------------------------------ */
/** Constructor.
* @param filename Filename, which can be in
* rolloverFileOutputStream format
* @see org.mortbay.util.RolloverFileOutputStream
* @exception IOException
*/
public I2PRequestLog(String filename)
throws IOException
{
super(filename);
}
/* ------------------------------------------------------------ */
/** Log a request.
* @param request The request
* @param response The response to this request.
* @param responseLength The bytes written to the response.
*/
public void log(HttpRequest request,
HttpResponse response,
int responseLength)
{
try{
// ignore ignorables
if (_ignorePathMap != null &&
_ignorePathMap.getMatch(request.getPath()) != null)
return;
// log the rest
if (_fileOut==null)
return;
StringBuilder buf = new StringBuilder(160);
String addr = request.getField("X-I2P-DestHash");
if(addr != null)
buf.append(addr).append(".i2p");
else
buf.append(request.getRemoteAddr());
buf.append(" - ");
String user = request.getAuthUser();
buf.append((user==null)?"-":user);
buf.append(" [");
buf.append(_logDateCache.format(request.getTimeStamp()));
buf.append("] \"");
buf.append(request.getMethod());
buf.append(' ');
buf.append(request.getURI());
buf.append(' ');
buf.append(request.getVersion());
buf.append("\" ");
int status=response.getStatus();
buf.append((char)('0'+((status/100)%10)));
buf.append((char)('0'+((status/10)%10)));
buf.append((char)('0'+(status%10)));
if (responseLength>=0)
{
buf.append(' ');
if (responseLength>99999)
buf.append(Integer.toString(responseLength));
else
{
if (responseLength>9999)
buf.append((char)('0'+((responseLength/10000)%10)));
if (responseLength>999)
buf.append((char)('0'+((responseLength/1000)%10)));
if (responseLength>99)
buf.append((char)('0'+((responseLength/100)%10)));
if (responseLength>9)
buf.append((char)('0'+((responseLength/10)%10)));
buf.append((char)('0'+(responseLength%10)));
}
buf.append(' ');
}
else
buf.append(" - ");
String log =buf.toString();
synchronized(_writer)
{
_writer.write(log);
if (isExtended())
{
logExtended(request,response,_writer);
if (!getLogCookies())
_writer.write(" -");
}
if (getLogCookies())
{
Cookie[] cookies = request.getCookies();
if (cookies==null || cookies.length==0)
_writer.write(" -");
else
{
_writer.write(" \"");
for (int i=0;i<cookies.length;i++)
{
if (i!=0)
_writer.write(';');
_writer.write(cookies[i].getName());
_writer.write('=');
_writer.write(cookies[i].getValue());
}
_writer.write("\"");
}
}
if (getLogLatency())
_writer.write(" "+(System.currentTimeMillis()-request.getTimeStamp()));
_writer.write(StringUtil.__LINE_SEPARATOR);
_writer.flush();
}
}
catch(IOException e)
{
log.warn(LogSupport.EXCEPTION,e);
}
}
}

View File

@@ -1,505 +0,0 @@
// ========================================================================
// $Id: NCSARequestLog.java,v 1.35 2005/08/13 00:01:24 gregwilkins Exp $
// Copyright 2000-2004 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================
package org.mortbay.http;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Locale;
import java.util.TimeZone;
import javax.servlet.http.Cookie;
import org.apache.commons.logging.Log;
import org.mortbay.log.LogFactory;
import org.mortbay.util.DateCache;
import org.mortbay.util.LogSupport;
import org.mortbay.util.RolloverFileOutputStream;
import org.mortbay.util.StringUtil;
/* ------------------------------------------------------------ */
/** NCSA HTTP Request Log.
* NCSA common or NCSA extended (combined) request log.
*
* Taken from 5.1.12 source and modded to change some private vars to protected
* so we can extend it for I2P.
*
* @version $Id: NCSARequestLog.java,v 1.35 2005/08/13 00:01:24 gregwilkins Exp $
* @author Tony Thompson
* @author Greg Wilkins
*/
public class NCSARequestLog implements RequestLog
{
protected static Log log = LogFactory.getLog(NCSARequestLog.class);
private String _filename;
private boolean _extended;
private boolean _append;
private int _retainDays;
private boolean _closeOut;
private boolean _preferProxiedForAddress;
private String _logDateFormat="dd/MMM/yyyy:HH:mm:ss ZZZ";
private Locale _logLocale=Locale.getDefault();
private String _logTimeZone=TimeZone.getDefault().getID();
private String[] _ignorePaths;
private boolean _logLatency=false;
private boolean _logCookies=false;
protected transient OutputStream _out;
protected transient OutputStream _fileOut;
protected transient DateCache _logDateCache;
protected transient PathMap _ignorePathMap;
protected transient Writer _writer;
/* ------------------------------------------------------------ */
/** Constructor.
*/
public NCSARequestLog()
{
_extended=true;
_append=true;
_retainDays=31;
}
/* ------------------------------------------------------------ */
/** Constructor.
* @param filename Filename, which can be in
* rolloverFileOutputStream format
* @see org.mortbay.util.RolloverFileOutputStream
* @exception IOException
*/
public NCSARequestLog(String filename)
throws IOException
{
_extended=true;
_append=true;
_retainDays=31;
setFilename(filename);
}
/* ------------------------------------------------------------ */
/** Set the log filename.
* @see NCSARequestLog#setRetainDays(int)
* @param filename The filename to use. If the filename contains the
* string "yyyy_mm_dd", then a RolloverFileOutputStream is used and the
* log is rolled over nightly and aged according setRetainDays. If no
* filename is set or a null filename
* passed, then requests are logged to System.err.
*/
public void setFilename(String filename)
{
if (filename!=null)
{
filename=filename.trim();
if (filename.length()==0)
filename=null;
}
_filename=filename;
}
/* ------------------------------------------------------------ */
/** Get the log filename.
* @see NCSARequestLog#getDatedFilename()
* @return The log filename without any date expansion.
*/
public String getFilename()
{
return _filename;
}
/* ------------------------------------------------------------ */
/** Get the dated log filename.
* @see NCSARequestLog#getFilename()
* @return The log filename with any date encoding expanded.
*/
public String getDatedFilename()
{
if (_fileOut instanceof RolloverFileOutputStream)
return ((RolloverFileOutputStream)_fileOut).getDatedFilename();
return null;
}
/* ------------------------------------------------------------ */
/**
* @param format The date format to use within the log file.
*/
public void setLogDateFormat(String format)
{
_logDateFormat=format;
}
/* ------------------------------------------------------------ */
/**
* @return The date format to use within the log file.
*/
public String getLogDateFormat()
{
return _logDateFormat;
}
/* ------------------------------------------------------------ */
/**
* @param tz The date format timezone to use within the log file.
*/
public void setLogTimeZone(String tz)
{
_logTimeZone=tz;
}
/* ------------------------------------------------------------ */
/**
* @return The date format timezone to use within the log file.
*/
public String getLogTimeZone()
{
return _logTimeZone;
}
/* ------------------------------------------------------------ */
/**
* @return The number of days to retain rollovered log files.
*/
public int getRetainDays()
{
return _retainDays;
}
/* ------------------------------------------------------------ */
/**
* @param retainDays The number of days to retain rollovered log files.
*/
public void setRetainDays(int retainDays)
{
_retainDays = retainDays;
}
/* ------------------------------------------------------------ */
/**
* @return True if NCSA extended format is to be used.
*/
public boolean isExtended()
{
return _extended;
}
/* ------------------------------------------------------------ */
/**
* @param e True if NCSA extended format is to be used.
*/
public void setExtended(boolean e)
{
_extended=e;
}
/* ------------------------------------------------------------ */
/**
* @return True if logs are appended to existing log files.
*/
public boolean isAppend()
{
return _append;
}
/* ------------------------------------------------------------ */
/**
* @param a True if logs are appended to existing log files.
*/
public void setAppend(boolean a)
{
_append=a;
}
/* ------------------------------------------------------------ */
/**
* @deprecated ignored
*/
public void setBuffered(boolean b)
{}
/* ------------------------------------------------------------ */
/** Set which paths to ignore.
*
* @param ignorePaths Array of path specifications to ignore
*/
public void setIgnorePaths(String[] ignorePaths)
{
// Contributed by Martin Vilcans (martin@jadestone.se)
_ignorePaths = ignorePaths;
}
/* ------------------------------------------------------------ */
public String[] getIgnorePaths()
{
return _ignorePaths;
}
/* ------------------------------------------------------------ */
/**
* @return Returns the logCookies.
*/
public boolean getLogCookies()
{
return _logCookies;
}
/* ------------------------------------------------------------ */
/**
* @param logCookies The logCookies to set.
*/
public void setLogCookies(boolean logCookies)
{
_logCookies = logCookies;
}
/* ------------------------------------------------------------ */
/**
* @return Returns true if logging latency
*/
public boolean getLogLatency()
{
return _logLatency;
}
/* ------------------------------------------------------------ */
/**
* @param logLatency If true, latency is logged at the end of the log line
*/
public void setLogLatency(boolean logLatency)
{
_logLatency = logLatency;
}
/* ------------------------------------------------------------ */
/**
* Prefer to log the proxied-for IP address (if present in
* the request header) over the native requester IP address.
* Useful in reverse-proxy situations when you'd rather see
* the IP address of the host before the most recent proxy
* server, as opposed to your own proxy server(s) every time.
*
* jlrobins@socialserve.com, March 2004.
**/
public void setPreferProxiedForAddress(boolean value)
{
_preferProxiedForAddress = value;
}
/* ------------------------------------------------------------ */
public void start()
throws Exception
{
_logDateCache=new DateCache(_logDateFormat,_logLocale);
_logDateCache.setTimeZoneID(_logTimeZone);
if (_filename != null)
{
_fileOut=new RolloverFileOutputStream(_filename,_append,_retainDays);
_closeOut=true;
}
else
_fileOut=System.err;
_out=_fileOut;
if (_ignorePaths!=null && _ignorePaths.length>0)
{
_ignorePathMap=new PathMap();
for (int i=0;i<_ignorePaths.length;i++)
_ignorePathMap.put(_ignorePaths[i],_ignorePaths[i]);
}
else
_ignorePathMap=null;
_writer=new OutputStreamWriter(_out);
}
/* ------------------------------------------------------------ */
public boolean isStarted()
{
return _fileOut!=null;
}
/* ------------------------------------------------------------ */
public void stop()
{
try{if (_writer!=null)_writer.flush();} catch (IOException e){LogSupport.ignore(log,e);}
if (_out!=null && _closeOut)
try{_out.close();}catch(IOException e){LogSupport.ignore(log,e);}
_out=null;
_fileOut=null;
_closeOut=false;
_logDateCache=null;
_writer=null;
}
/* ------------------------------------------------------------ */
/** Log a request.
* @param request The request
* @param response The response to this request.
* @param responseLength The bytes written to the response.
*/
public void log(HttpRequest request,
HttpResponse response,
int responseLength)
{
try{
// ignore ignorables
if (_ignorePathMap != null &&
_ignorePathMap.getMatch(request.getPath()) != null)
return;
// log the rest
if (_fileOut==null)
return;
StringBuffer buf = new StringBuffer(160);
String addr = null;
if(_preferProxiedForAddress)
{
// If header is not present, addr will remain null ...
addr = request.getField(HttpFields.__XForwardedFor);
}
if(addr == null)
addr = request.getRemoteAddr();
buf.append(addr);
buf.append(" - ");
String user = request.getAuthUser();
buf.append((user==null)?"-":user);
buf.append(" [");
buf.append(_logDateCache.format(request.getTimeStamp()));
buf.append("] \"");
buf.append(request.getMethod());
buf.append(' ');
buf.append(request.getURI());
buf.append(' ');
buf.append(request.getVersion());
buf.append("\" ");
int status=response.getStatus();
buf.append((char)('0'+((status/100)%10)));
buf.append((char)('0'+((status/10)%10)));
buf.append((char)('0'+(status%10)));
if (responseLength>=0)
{
buf.append(' ');
if (responseLength>99999)
buf.append(Integer.toString(responseLength));
else
{
if (responseLength>9999)
buf.append((char)('0'+((responseLength/10000)%10)));
if (responseLength>999)
buf.append((char)('0'+((responseLength/1000)%10)));
if (responseLength>99)
buf.append((char)('0'+((responseLength/100)%10)));
if (responseLength>9)
buf.append((char)('0'+((responseLength/10)%10)));
buf.append((char)('0'+(responseLength%10)));
}
buf.append(' ');
}
else
buf.append(" - ");
String log =buf.toString();
synchronized(_writer)
{
_writer.write(log);
if (_extended)
{
logExtended(request,response,_writer);
if (!_logCookies)
_writer.write(" -");
}
if (_logCookies)
{
Cookie[] cookies = request.getCookies();
if (cookies==null || cookies.length==0)
_writer.write(" -");
else
{
_writer.write(" \"");
for (int i=0;i<cookies.length;i++)
{
if (i!=0)
_writer.write(';');
_writer.write(cookies[i].getName());
_writer.write('=');
_writer.write(cookies[i].getValue());
}
_writer.write("\"");
}
}
if (_logLatency)
_writer.write(" "+(System.currentTimeMillis()-request.getTimeStamp()));
_writer.write(StringUtil.__LINE_SEPARATOR);
_writer.flush();
}
}
catch(IOException e)
{
log.warn(LogSupport.EXCEPTION,e);
}
}
/* ------------------------------------------------------------ */
/** Log Extended fields.
* This method can be extended by a derived class to add extened fields to
* each log entry. It is called by the log method after all standard
* fields have been added, but before the line terminator.
* Derived implementations should write extra fields to the Writer
* provided.
* The default implementation writes the referer and user agent.
* @param request The request to log.
* @param response The response to log.
* @param log The writer to write the extra fields to.
* @exception IOException Problem writing log
*/
protected void logExtended(HttpRequest request,
HttpResponse response,
Writer log)
throws IOException
{
String referer = request.getField(HttpFields.__Referer);
if(referer==null)
log.write("\"-\" ");
else
{
log.write('"');
log.write(referer);
log.write("\" ");
}
String agent = request.getField(HttpFields.__UserAgent);
if(agent==null)
log.write("\"-\"");
else
{
log.write('"');
log.write(agent);
log.write('"');
}
}
}

View File

@@ -1,809 +0,0 @@
// ========================================================================
// $Id: ResourceHandler.java,v 1.66 2005/08/24 08:18:17 gregwilkins Exp $
// Copyright 199-2004 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================
package org.mortbay.http.handler;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.List;
import org.apache.commons.logging.Log;
import org.mortbay.log.LogFactory;
import org.mortbay.http.HttpException;
import org.mortbay.http.HttpFields;
import org.mortbay.http.HttpRequest;
import org.mortbay.http.HttpResponse;
import org.mortbay.http.InclusiveByteRange;
import org.mortbay.http.MultiPartResponse;
import org.mortbay.http.ResourceCache;
import org.mortbay.util.CachedResource;
import org.mortbay.util.IO;
import org.mortbay.util.LogSupport;
import org.mortbay.util.Resource;
import org.mortbay.util.StringMap;
import org.mortbay.util.TypeUtil;
import org.mortbay.util.URI;
/* ------------------------------------------------------------ */
/** Handler to serve files and resources.
* Serves files from a given resource URL base and implements
* the GET, HEAD, DELETE, OPTIONS, PUT, MOVE methods and the
* IfModifiedSince and IfUnmodifiedSince header fields.
* A simple memory cache is also provided to reduce file I/O.
* HTTP/1.1 ranges are supported.
*
* @version $Id: ResourceHandler.java,v 1.66 2005/08/24 08:18:17 gregwilkins Exp $
* @author Nuno Pregui?a (sorry, wasn't UTF-8)
* @author Greg Wilkins
*/
public class ResourceHandler extends AbstractHttpHandler
{
private static Log log = LogFactory.getLog(ResourceHandler.class);
/* ----------------------------------------------------------------- */
private boolean _acceptRanges=true;
private boolean _redirectWelcomeFiles ;
private String[] _methods=null;
private String _allowed;
private boolean _dirAllowed=true;
private int _minGzipLength =-1;
private StringMap _methodMap = new StringMap();
{
setAllowedMethods(new String[]
{
HttpRequest.__GET,
HttpRequest.__POST,
HttpRequest.__HEAD,
HttpRequest.__OPTIONS,
HttpRequest.__TRACE
});
}
/* ----------------------------------------------------------------- */
/** Construct a ResourceHandler.
*/
public ResourceHandler()
{}
/* ----------------------------------------------------------------- */
public synchronized void start()
throws Exception
{
super.start();
}
/* ----------------------------------------------------------------- */
public void stop()
throws InterruptedException
{
super.stop();
}
/* ------------------------------------------------------------ */
public String[] getAllowedMethods()
{
return _methods;
}
/* ------------------------------------------------------------ */
public void setAllowedMethods(String[] methods)
{
StringBuffer b = new StringBuffer();
_methods=methods;
_methodMap.clear();
for (int i=0;i<methods.length;i++)
{
_methodMap.put(methods[i],methods[i]);
if (i>0)
b.append(',');
b.append(methods[i]);
}
_allowed=b.toString();
}
/* ------------------------------------------------------------ */
public boolean isMethodAllowed(String method)
{
return _methodMap.get(method)!=null;
}
/* ------------------------------------------------------------ */
public String getAllowedString()
{
return _allowed;
}
/* ------------------------------------------------------------ */
public boolean isDirAllowed()
{
return _dirAllowed;
}
/* ------------------------------------------------------------ */
public void setDirAllowed(boolean dirAllowed)
{
_dirAllowed = dirAllowed;
}
/* ------------------------------------------------------------ */
public boolean isAcceptRanges()
{
return _acceptRanges;
}
/* ------------------------------------------------------------ */
/**
* @return True if welcome files are redirected to. False if forward is used.
*/
public boolean getRedirectWelcome()
{
return _redirectWelcomeFiles;
}
/* ------------------------------------------------------------ */
/**
* @param redirectWelcome True if welcome files are redirected to. False
* if forward is used.
*/
public void setRedirectWelcome(boolean redirectWelcome)
{
_redirectWelcomeFiles = redirectWelcome;
}
/* ------------------------------------------------------------ */
/** Set if the handler accepts range requests.
* Default is false;
* @param ar True if the handler should accept ranges
*/
public void setAcceptRanges(boolean ar)
{
_acceptRanges=ar;
}
/* ------------------------------------------------------------ */
/** Get minimum content length for GZIP encoding.
* @return Minimum length of content for gzip encoding or -1 if disabled.
*/
public int getMinGzipLength()
{
return _minGzipLength;
}
/* ------------------------------------------------------------ */
/** Set minimum content length for GZIP encoding.
* @param minGzipLength If set to a positive integer, then static content
* larger than this will be served as gzip content encoded
* if a matching resource is found ending with ".gz"
*/
public void setMinGzipLength(int minGzipLength)
{
_minGzipLength = minGzipLength;
}
/* ------------------------------------------------------------ */
/** get Resource to serve.
* Map a path to a resource. The default implementation calls
* HttpContext.getResource but derived handers may provide
* their own mapping.
* @param pathInContext The path to find a resource for.
* @return The resource to serve.
*/
protected Resource getResource(String pathInContext)
throws IOException
{
return getHttpContext().getResource(pathInContext);
}
/* ------------------------------------------------------------ */
public void handle(String pathInContext,
String pathParams,
HttpRequest request,
HttpResponse response)
throws HttpException, IOException
{
Resource resource = getResource(pathInContext);
if (resource==null)
return;
// Is the method allowed?
if (!isMethodAllowed(request.getMethod()))
{
if(log.isDebugEnabled())log.debug("Method not allowed: "+request.getMethod());
if (resource.exists())
{
setAllowHeader(response);
response.sendError(HttpResponse.__405_Method_Not_Allowed);
}
return;
}
// Handle the request
try
{
if(log.isDebugEnabled())log.debug("PATH="+pathInContext+" RESOURCE="+resource);
// check filename
String method=request.getMethod();
if (method.equals(HttpRequest.__GET) ||
method.equals(HttpRequest.__POST) ||
method.equals(HttpRequest.__HEAD))
handleGet(request, response, pathInContext, pathParams, resource);
else if (method.equals(HttpRequest.__PUT))
handlePut(request, response, pathInContext, resource);
else if (method.equals(HttpRequest.__DELETE))
handleDelete(request, response, pathInContext, resource);
else if (method.equals(HttpRequest.__OPTIONS))
handleOptions(response, pathInContext);
else if (method.equals(HttpRequest.__MOVE))
handleMove(request, response, pathInContext, resource);
else if (method.equals(HttpRequest.__TRACE))
handleTrace(request, response);
else
{
if(log.isDebugEnabled())log.debug("Unknown action:"+method);
// anything else...
try{
if (resource.exists())
response.sendError(HttpResponse.__501_Not_Implemented);
}
catch(Exception e) {LogSupport.ignore(log,e);}
}
}
catch(IllegalArgumentException e)
{
LogSupport.ignore(log,e);
}
finally
{
if (resource!=null && !(resource instanceof CachedResource))
resource.release();
}
}
/* ------------------------------------------------------------------- */
public void handleGet(HttpRequest request,
HttpResponse response,
String pathInContext,
String pathParams,
Resource resource)
throws IOException
{
if(log.isDebugEnabled())log.debug("Looking for "+resource);
if (resource!=null && resource.exists())
{
// check if directory
if (resource.isDirectory())
{
if (!pathInContext.endsWith("/") && !pathInContext.equals("/"))
{
log.debug("Redirect to directory/");
String q=request.getQuery();
// Properly fix URI
URI urifix = new URI(request.getRequestURL().toString());
urifix.setPath(urifix.getPath());
StringBuffer buf = new StringBuffer(urifix.toString());
urifix = null;
if (q!=null&&q.length()!=0)
{
buf.append('?');
buf.append(q);
}
response.setField(HttpFields.__Location, URI.addPaths(buf.toString(),"/"));
response.setStatus(302);
request.setHandled(true);
return;
}
// See if index file exists
String welcome=getHttpContext().getWelcomeFile(resource);
if (welcome!=null)
{
// Forward to the index
String ipath=URI.addPaths(pathInContext,welcome);
if (_redirectWelcomeFiles)
{
// Redirect to the index
ipath=URI.addPaths(getHttpContext().getContextPath(),ipath);
response.setContentLength(0);
response.sendRedirect(ipath);
}
else
{
URI uri=request.getURI();
uri.setPath(URI.addPaths(uri.getPath(),welcome));
getHttpContext().handle(ipath,pathParams,request,response);
}
return;
}
// Check modified dates
if (!passConditionalHeaders(request,response,resource))
return;
// If we got here, no forward to index took place
sendDirectory(request,response,resource,pathInContext.length()>1);
}
// check if it is a file
else if (resource.exists())
{
// Check modified dates
if (!passConditionalHeaders(request,response,resource))
return;
sendData(request,response,pathInContext,resource,true);
}
else
// don't know what it is
log.warn("Unknown file type");
}
}
/* ------------------------------------------------------------ */
/* Check modification date headers.
*/
private boolean passConditionalHeaders(HttpRequest request,
HttpResponse response,
Resource resource)
throws IOException
{
if (!request.getMethod().equals(HttpRequest.__HEAD))
{
// If we have meta data for the file
// Try a direct match for most common requests. Avoids
// parsing the date.
ResourceCache.ResourceMetaData metaData =
(ResourceCache.ResourceMetaData)resource.getAssociate();
if (metaData!=null)
{
String ifms=request.getField(HttpFields.__IfModifiedSince);
String mdlm=metaData.getLastModified();
if (ifms!=null && mdlm!=null && ifms.equals(mdlm))
{
response.setStatus(HttpResponse.__304_Not_Modified);
request.setHandled(true);
return false;
}
}
long date=0;
// Parse the if[un]modified dates and compare to resource
if ((date=request.getDateField(HttpFields.__IfUnmodifiedSince))>0)
{
if (resource.lastModified()/1000 > date/1000)
{
response.sendError(HttpResponse.__412_Precondition_Failed);
return false;
}
}
if ((date=request.getDateField(HttpFields.__IfModifiedSince))>0)
{
if (resource.lastModified()/1000 <= date/1000)
{
response.setStatus(HttpResponse.__304_Not_Modified);
request.setHandled(true);
return false;
}
}
}
return true;
}
/* ------------------------------------------------------------ */
void handlePut(HttpRequest request,
HttpResponse response,
String pathInContext,
Resource resource)
throws IOException
{
if(log.isDebugEnabled())log.debug("PUT "+pathInContext+" in "+resource);
boolean exists=resource!=null && resource.exists();
if (exists &&
!passConditionalHeaders(request,response,resource))
return;
if (pathInContext.endsWith("/"))
{
if (!exists)
{
if (!resource.getFile().mkdirs())
response.sendError(HttpResponse.__403_Forbidden, "Directories could not be created");
else
{
request.setHandled(true);
response.setStatus(HttpResponse.__201_Created);
response.commit();
}
}
else
{
request.setHandled(true);
response.setStatus(HttpResponse.__200_OK);
response.commit();
}
}
else
{
try
{
int toRead = request.getContentLength();
InputStream in = request.getInputStream();
OutputStream out = resource.getOutputStream();
if (toRead>=0)
IO.copy(in,out,toRead);
else
IO.copy(in,out);
out.close();
request.setHandled(true);
response.setStatus(exists
?HttpResponse.__200_OK
:HttpResponse.__201_Created);
response.commit();
}
catch (Exception ex)
{
log.warn(LogSupport.EXCEPTION,ex);
response.sendError(HttpResponse.__403_Forbidden,
ex.getMessage());
}
}
}
/* ------------------------------------------------------------ */
void handleDelete(HttpRequest request,
HttpResponse response,
String pathInContext,
Resource resource)
throws IOException
{
if(log.isDebugEnabled())log.debug("DELETE "+pathInContext+" from "+resource);
if (!resource.exists() ||
!passConditionalHeaders(request,response,resource))
return;
try
{
// delete the file
if (resource.delete())
response.setStatus(HttpResponse.__204_No_Content);
else
response.sendError(HttpResponse.__403_Forbidden);
// Send response
request.setHandled(true);
}
catch (SecurityException sex)
{
log.warn(LogSupport.EXCEPTION,sex);
response.sendError(HttpResponse.__403_Forbidden, sex.getMessage());
}
}
/* ------------------------------------------------------------ */
void handleMove(HttpRequest request,
HttpResponse response,
String pathInContext,
Resource resource)
throws IOException
{
if (!resource.exists() || !passConditionalHeaders(request,response,resource))
return;
String newPath = URI.canonicalPath(request.getField("New-uri"));
if (newPath==null)
{
response.sendError(HttpResponse.__405_Method_Not_Allowed,
"Bad new uri");
return;
}
String contextPath = getHttpContext().getContextPath();
if (contextPath!=null && !newPath.startsWith(contextPath))
{
response.sendError(HttpResponse.__405_Method_Not_Allowed,
"Not in context");
return;
}
// Find path
try
{
// TODO - Check this
String newInfo=newPath;
if (contextPath!=null)
newInfo=newInfo.substring(contextPath.length());
Resource newFile = getHttpContext().getBaseResource().addPath(newInfo);
if(log.isDebugEnabled())log.debug("Moving "+resource+" to "+newFile);
resource.renameTo(newFile);
response.setStatus(HttpResponse.__204_No_Content);
request.setHandled(true);
}
catch (Exception ex)
{
log.warn(LogSupport.EXCEPTION,ex);
setAllowHeader(response);
response.sendError(HttpResponse.__405_Method_Not_Allowed,
"Error:"+ex);
return;
}
}
/* ------------------------------------------------------------ */
void handleOptions(HttpResponse response, String pathInContext)
throws IOException
{
if ("*".equals(pathInContext))
return;
setAllowHeader(response);
response.commit();
}
/* ------------------------------------------------------------ */
void setAllowHeader(HttpResponse response)
{
response.setField(HttpFields.__Allow, getAllowedString());
}
/* ------------------------------------------------------------ */
public void writeHeaders(HttpResponse response,Resource resource, long count)
throws IOException
{
ResourceCache.ResourceMetaData metaData =
(ResourceCache.ResourceMetaData)resource.getAssociate();
response.setContentType(metaData.getMimeType());
if (count != -1)
{
if (count==resource.length())
response.setField(HttpFields.__ContentLength,metaData.getLength());
else
response.setContentLength((int)count);
}
response.setField(HttpFields.__LastModified,metaData.getLastModified());
if (_acceptRanges && response.getHttpRequest().getDotVersion()>0)
response.setField(HttpFields.__AcceptRanges,"bytes");
}
/* ------------------------------------------------------------ */
public void sendData(HttpRequest request,
HttpResponse response,
String pathInContext,
Resource resource,
boolean writeHeaders)
throws IOException
{
long resLength=resource.length();
// see if there are any range headers
Enumeration reqRanges =
request.getDotVersion()>0
?request.getFieldValues(HttpFields.__Range)
:null;
if (!writeHeaders || reqRanges == null || !reqRanges.hasMoreElements())
{
// look for a gziped content.
Resource data=resource;
if (_minGzipLength>0)
{
String accept=request.getField(HttpFields.__AcceptEncoding);
if (accept!=null && resLength>_minGzipLength &&
!pathInContext.endsWith(".gz"))
{
Resource gz = getHttpContext().getResource(pathInContext+".gz");
if (gz.exists() && accept.indexOf("gzip")>=0)
{
if(log.isDebugEnabled())log.debug("gzip="+gz);
response.setField(HttpFields.__ContentEncoding,"gzip");
data=gz;
resLength=data.length();
}
}
}
writeHeaders(response,resource,resLength);
request.setHandled(true);
OutputStream out = response.getOutputStream();
data.writeTo(out,0,resLength);
return;
}
// Parse the satisfiable ranges
List ranges =InclusiveByteRange.satisfiableRanges(reqRanges,resLength);
if(log.isDebugEnabled())log.debug("ranges: " + reqRanges + " == " + ranges);
// if there are no satisfiable ranges, send 416 response
if (ranges==null || ranges.size()==0)
{
log.debug("no satisfiable ranges");
writeHeaders(response, resource, resLength);
response.setStatus(HttpResponse.__416_Requested_Range_Not_Satisfiable);
response.setReason((String)HttpResponse.__statusMsg
.get(TypeUtil.newInteger(HttpResponse.__416_Requested_Range_Not_Satisfiable)));
response.setField(HttpFields.__ContentRange,
InclusiveByteRange.to416HeaderRangeString(resLength));
OutputStream out = response.getOutputStream();
resource.writeTo(out,0,resLength);
request.setHandled(true);
return;
}
// if there is only a single valid range (must be satisfiable
// since were here now), send that range with a 216 response
if ( ranges.size()== 1)
{
InclusiveByteRange singleSatisfiableRange =
(InclusiveByteRange)ranges.get(0);
if(log.isDebugEnabled())log.debug("single satisfiable range: " + singleSatisfiableRange);
long singleLength = singleSatisfiableRange.getSize(resLength);
writeHeaders(response,resource,singleLength);
response.setStatus(HttpResponse.__206_Partial_Content);
response.setReason((String)HttpResponse.__statusMsg
.get(TypeUtil.newInteger(HttpResponse.__206_Partial_Content)));
response.setField(HttpFields.__ContentRange,
singleSatisfiableRange.toHeaderRangeString(resLength));
OutputStream out = response.getOutputStream();
resource.writeTo(out,
singleSatisfiableRange.getFirst(resLength),
singleLength);
request.setHandled(true);
return;
}
// multiple non-overlapping valid ranges cause a multipart
// 216 response which does not require an overall
// content-length header
//
ResourceCache.ResourceMetaData metaData =
(ResourceCache.ResourceMetaData)resource.getAssociate();
String encoding = metaData.getMimeType();
MultiPartResponse multi = new MultiPartResponse(response);
response.setStatus(HttpResponse.__206_Partial_Content);
response.setReason((String)HttpResponse.__statusMsg
.get(TypeUtil.newInteger(HttpResponse.__206_Partial_Content)));
// If the request has a "Request-Range" header then we need to
// send an old style multipart/x-byteranges Content-Type. This
// keeps Netscape and acrobat happy. This is what Apache does.
String ctp;
if (request.containsField(HttpFields.__RequestRange))
ctp = "multipart/x-byteranges; boundary=";
else
ctp = "multipart/byteranges; boundary=";
response.setContentType(ctp+multi.getBoundary());
InputStream in=(resource instanceof CachedResource)
?null:resource.getInputStream();
OutputStream out = response.getOutputStream();
long pos=0;
for (int i=0;i<ranges.size();i++)
{
InclusiveByteRange ibr = (InclusiveByteRange) ranges.get(i);
String header=HttpFields.__ContentRange+": "+
ibr.toHeaderRangeString(resLength);
if(log.isDebugEnabled())log.debug("multi range: "+encoding+" "+header);
multi.startPart(encoding,new String[]{header});
long start=ibr.getFirst(resLength);
long size=ibr.getSize(resLength);
if (in!=null)
{
// Handle non cached resource
if (start<pos)
{
in.close();
in=resource.getInputStream();
pos=0;
}
if (pos<start)
{
in.skip(start-pos);
pos=start;
}
IO.copy(in,out,size);
pos+=size;
}
else
// Handle cached resource
resource.writeTo(out,start,size);
}
if (in!=null)
in.close();
multi.close();
request.setHandled(true);
return;
}
/* ------------------------------------------------------------------- */
void sendDirectory(HttpRequest request,
HttpResponse response,
Resource resource,
boolean parent)
throws IOException
{
if (!_dirAllowed)
{
response.sendError(HttpResponse.__403_Forbidden);
return;
}
request.setHandled(true);
if(log.isDebugEnabled())log.debug("sendDirectory: "+resource);
byte[] data=null;
if (resource instanceof CachedResource)
data=((CachedResource)resource).getCachedData();
if (data==null)
{
String base = URI.addPaths(request.getPath(),"/");
String dir = resource.getListHTML(URI.encodePath(base),parent);
if (dir==null)
{
response.sendError(HttpResponse.__403_Forbidden,
"No directory");
return;
}
data=dir.getBytes("UTF8");
if (resource instanceof CachedResource)
((CachedResource)resource).setCachedData(data);
}
response.setContentType("text/html; charset=UTF8");
response.setContentLength(data.length);
if (request.getMethod().equals(HttpRequest.__HEAD))
{
response.commit();
return;
}
response.getOutputStream().write(data,0,data.length);
response.commit();
}
}

View File

@@ -1,617 +0,0 @@
// ========================================================================
// $Id: Server.java,v 1.40 2005/10/21 13:52:11 gregwilkins Exp $
// Copyright 2002-2004 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================
package org.mortbay.jetty;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import org.apache.commons.logging.Log;
import org.mortbay.log.LogFactory;
import org.mortbay.http.HttpContext;
import org.mortbay.http.HttpServer;
import org.mortbay.jetty.servlet.ServletHttpContext;
import org.mortbay.jetty.servlet.WebApplicationContext;
import org.mortbay.util.LogSupport;
import org.mortbay.util.Resource;
import org.mortbay.xml.XmlConfiguration;
/* ------------------------------------------------------------ */
/** The Jetty HttpServer.
*
* This specialization of org.mortbay.http.HttpServer adds knowledge
* about servlets and their specialized contexts. It also included
* support for initialization from xml configuration files
* that follow the XmlConfiguration dtd.
*
* HttpContexts created by Server are of the type
* org.mortbay.jetty.servlet.ServletHttpContext unless otherwise
* specified.
*
* This class also provides a main() method which starts a server for
* each config file passed on the command line. If the system
* property JETTY_NO_SHUTDOWN_HOOK is not set to true, then a shutdown
* hook is thread is registered to stop these servers.
*
* @see org.mortbay.xml.XmlConfiguration
* @see org.mortbay.jetty.servlet.ServletHttpContext
* @version $Revision: 1.40 $
* @author Greg Wilkins (gregw)
*/
public class Server extends HttpServer
{
static Log log = LogFactory.getLog(Server.class);
private String[] _webAppConfigurationClassNames =
new String[]{"org.mortbay.jetty.servlet.XMLConfiguration", "org.mortbay.jetty.servlet.JettyWebConfiguration"};
private String _configuration;
private String _rootWebApp;
private static ShutdownHookThread hookThread = new ShutdownHookThread();
/* ------------------------------------------------------------ */
/** Constructor.
*/
public Server()
{
}
/* ------------------------------------------------------------ */
/** Constructor.
* @param configuration The filename or URL of the XML
* configuration file.
*/
public Server(String configuration)
throws IOException
{
this(Resource.newResource(configuration).getURL());
}
/* ------------------------------------------------------------ */
/** Constructor.
* @param configuration The filename or URL of the XML
* configuration file.
*/
public Server(Resource configuration)
throws IOException
{
this(configuration.getURL());
}
/* ------------------------------------------------------------ */
/** Constructor.
* @param configuration The filename or URL of the XML
* configuration file.
*/
public Server(URL configuration)
throws IOException
{
_configuration=configuration.toString();
Server.hookThread.add(this);
try
{
XmlConfiguration config=new XmlConfiguration(configuration);
config.configure(this);
}
catch(IOException e)
{
throw e;
}
catch(InvocationTargetException e)
{
log.warn(LogSupport.EXCEPTION,e.getTargetException());
throw new IOException("Jetty configuration problem: "+e.getTargetException());
}
catch(Exception e)
{
log.warn(LogSupport.EXCEPTION,e);
throw new IOException("Jetty configuration problem: "+e);
}
}
/* ------------------------------------------------------------ */
public boolean getStopAtShutdown()
{
return hookThread.contains(this);
}
/* ------------------------------------------------------------ */
public void setStopAtShutdown(boolean stop)
{
if (stop)
hookThread.add(this);
else
hookThread.remove(this);
}
/* ------------------------------------------------------------ */
/** Get the root webapp name.
* @return The name of the root webapp (eg. "root" for root.war).
*/
public String getRootWebApp()
{
return _rootWebApp;
}
/* ------------------------------------------------------------ */
/** Set the root webapp name.
* @param rootWebApp The name of the root webapp (eg. "root" for root.war).
*/
public void setRootWebApp(String rootWebApp)
{
_rootWebApp = rootWebApp;
}
/* ------------------------------------------------------------ */
/** Configure the server from an XML file.
* @param configuration The filename or URL of the XML
* configuration file.
*/
public void configure(String configuration)
throws IOException
{
URL url=Resource.newResource(configuration).getURL();
if (_configuration!=null && _configuration.equals(url.toString()))
return;
if (_configuration!=null)
throw new IllegalStateException("Already configured with "+_configuration);
try
{
XmlConfiguration config=new XmlConfiguration(url);
_configuration=url.toString();
config.configure(this);
}
catch(IOException e)
{
throw e;
}
catch(Exception e)
{
log.warn(LogSupport.EXCEPTION,e);
throw new IOException("Jetty configuration problem: "+e);
}
}
/* ------------------------------------------------------------ */
public String getConfiguration()
{
return _configuration;
}
/* ------------------------------------------------------------ */
/** Create a new ServletHttpContext.
* Ths method is called by HttpServer to creat new contexts. Thus
* calls to addContext or getContext that result in a new Context
* being created will return an
* org.mortbay.jetty.servlet.ServletHttpContext instance.
* @return ServletHttpContext
*/
protected HttpContext newHttpContext()
{
return new ServletHttpContext();
}
/* ------------------------------------------------------------ */
/** Create a new WebApplicationContext.
* Ths method is called by Server to creat new contexts for web
* applications. Thus calls to addWebApplication that result in
* a new Context being created will return an correct class instance.
* Derived class can override this method to create instance of its
* own class derived from WebApplicationContext in case it needs more
* functionality.
* @param webApp The Web application directory or WAR file.
* @return WebApplicationContext
*/
protected WebApplicationContext newWebApplicationContext(
String webApp
)
{
return new WebApplicationContext(webApp);
}
/* ------------------------------------------------------------ */
/** Add Web Application.
* @param contextPathSpec The context path spec. Which must be of
* the form / or /path/*
* @param webApp The Web application directory or WAR file.
* @return The WebApplicationContext
* @exception IOException
*/
public WebApplicationContext addWebApplication(String contextPathSpec,
String webApp)
throws IOException
{
return addWebApplication(null,contextPathSpec,webApp);
}
/* ------------------------------------------------------------ */
/** Add Web Application.
* @param virtualHost Virtual host name or null
* @param contextPathSpec The context path spec. Which must be of
* the form / or /path/*
* @param webApp The Web application directory or WAR file.
* @return The WebApplicationContext
* @exception IOException
*/
public WebApplicationContext addWebApplication(String virtualHost,
String contextPathSpec,
String webApp)
throws IOException
{
WebApplicationContext appContext =
newWebApplicationContext(webApp);
appContext.setContextPath(contextPathSpec);
addContext(virtualHost,appContext);
if(log.isDebugEnabled())log.debug("Web Application "+appContext+" added");
return appContext;
}
/* ------------------------------------------------------------ */
/** Add Web Applications.
* Add auto webapplications to the server. The name of the
* webapp directory or war is used as the context name. If a
* webapp is called "root" it is added at "/".
* @param webapps Directory file name or URL to look for auto webapplication.
* @exception IOException
*/
public WebApplicationContext[] addWebApplications(String webapps)
throws IOException
{
return addWebApplications(null,webapps,null,false);
}
/* ------------------------------------------------------------ */
/** Add Web Applications.
* Add auto webapplications to the server. The name of the
* webapp directory or war is used as the context name. If the
* webapp matches the rootWebApp it is added as the "/" context.
* @param host Virtual host name or null
* @param webapps Directory file name or URL to look for auto webapplication.
* @exception IOException
*/
public WebApplicationContext[] addWebApplications(String host,
String webapps)
throws IOException
{
return addWebApplications(host,webapps,null,false);
}
/* ------------------------------------------------------------ */
/** Add Web Applications.
* Add auto webapplications to the server. The name of the
* webapp directory or war is used as the context name. If the
* webapp matches the rootWebApp it is added as the "/" context.
* @param host Virtual host name or null
* @param webapps Directory file name or URL to look for auto
* webapplication.
* @param extract If true, extract war files
* @exception IOException
*/
public WebApplicationContext[] addWebApplications(String host,
String webapps,
boolean extract)
throws IOException
{
return addWebApplications(host,webapps,null,extract);
}
/* ------------------------------------------------------------ */
/** Add Web Applications.
* Add auto webapplications to the server. The name of the
* webapp directory or war is used as the context name. If the
* webapp matches the rootWebApp it is added as the "/" context.
* @param host Virtual host name or null
* @param webapps Directory file name or URL to look for auto
* webapplication.
* @param defaults The defaults xml filename or URL which is
* loaded before any in the web app. Must respect the web.dtd.
* If null the default defaults file is used. If the empty string, then
* no defaults file is used.
* @param extract If true, extract war files
* @exception IOException
*/
public WebApplicationContext[] addWebApplications(String host,
String webapps,
String defaults,
boolean extract)
throws IOException
{
return addWebApplications(host,webapps,defaults,extract,true,null);
}
/* ------------------------------------------------------------ */
/** Add Web Applications.
* Add auto webapplications to the server. The name of the
* webapp directory or war is used as the context name. If the
* webapp matches the rootWebApp it is added as the "/" context.
* @param host Virtual host name or null
* @param webapps Directory file name or URL to look for auto
* webapplication.
* @param defaults The defaults xml filename or URL which is
* loaded before any in the web app. Must respect the web.dtd.
* If null the default defaults file is used. If the empty string, then
* no defaults file is used.
* @param extract If true, extract war files
* @param java2CompliantClassLoader True if java2 compliance is applied to all webapplications
* @exception IOException
*/
public WebApplicationContext[] addWebApplications(String host,
String webapps,
String defaults,
boolean extract,
boolean java2CompliantClassLoader)
throws IOException
{
return addWebApplications(host,webapps,defaults,extract,java2CompliantClassLoader,null);
}
/* ------------------------------------------------------------ */
/** Add Web Applications.
* Add auto webapplications to the server. The name of the
* webapp directory or war is used as the context name. If the
* webapp matches the rootWebApp it is added as the "/" context.
* @param host Virtual host name or null
* @param webapps Directory file name or URL to look for auto
* webapplication.
* @param defaults The defaults xml filename or URL which is
* loaded before any in the web app. Must respect the web.dtd.
* If null the default defaults file is used. If the empty string, then
* no defaults file is used.
* @param extract If true, extract war files
* @param java2CompliantClassLoader True if java2 compliance is applied to all webapplications
* @param Attributes[] A set of attributes to pass to setAttribute, format is first item is the key, second item is the value.
* @exception IOException
*/
public WebApplicationContext[] addWebApplications(String host,
String webapps,
String defaults,
boolean extract,
boolean java2CompliantClassLoader,
String Attributes[])
throws IOException
{
ArrayList wacs = new ArrayList();
Resource r=Resource.newResource(webapps);
if (!r.exists())
throw new IllegalArgumentException("No such webapps resource "+r);
if (!r.isDirectory())
throw new IllegalArgumentException("Not directory webapps resource "+r);
if(Attributes != null) {
if(((Attributes.length / 2) * 2) != Attributes.length) {
throw new IllegalArgumentException("Attributes must be in pairs of key,value.");
}
}
String[] files=r.list();
for (int f=0;files!=null && f<files.length;f++)
{
String context=files[f];
if (context.equalsIgnoreCase("CVS/") ||
context.equalsIgnoreCase("CVS") ||
context.startsWith("."))
continue;
String app = r.addPath(r.encode(files[f])).toString();
if (context.toLowerCase().endsWith(".war") ||
context.toLowerCase().endsWith(".jar"))
{
context=context.substring(0,context.length()-4);
Resource unpacked=r.addPath(context);
if (unpacked!=null && unpacked.exists() && unpacked.isDirectory())
continue;
}
if (_rootWebApp!=null && (context.equals(_rootWebApp)||context.equals(_rootWebApp+"/")))
context="/";
else
context="/"+context;
WebApplicationContext wac= addWebApplication(host,
context,
app);
wac.setExtractWAR(extract);
wac.setClassLoaderJava2Compliant(java2CompliantClassLoader);
if (defaults!=null)
{
if (defaults.length()==0)
wac.setDefaultsDescriptor(null);
else
wac.setDefaultsDescriptor(defaults);
}
if(Attributes != null) {
for(int i = 0; i < Attributes.length; i++, i++) {
wac.setAttribute(Attributes[i],Attributes[i + 1]);
}
}
wacs.add(wac);
}
return (WebApplicationContext[])wacs.toArray(new WebApplicationContext[wacs.size()]);
}
/* ------------------------------------------------------------ */
/** setWebApplicationConfigurationClasses
* Set up the list of classnames of WebApplicationContext.Configuration
* implementations that will be applied to configure every webapp.
* The list can be overridden by individual WebApplicationContexts.
* @param configurationClasses
*/
public void setWebApplicationConfigurationClassNames (String[] configurationClassNames)
{
if (configurationClassNames != null)
{
_webAppConfigurationClassNames = new String[configurationClassNames.length];
System.arraycopy(configurationClassNames, 0, _webAppConfigurationClassNames, 0, configurationClassNames.length);
}
}
public String[] getWebApplicationConfigurationClassNames ()
{
return _webAppConfigurationClassNames;
}
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
public static void main(String[] arg)
{
String[] dftConfig={"etc/jetty.xml"};
if (arg.length==0)
{
log.info("Using default configuration: etc/jetty.xml");
arg=dftConfig;
}
final Server[] servers=new Server[arg.length];
// create and start the servers.
for (int i=0;i<arg.length;i++)
{
try
{
servers[i] = new Server(arg[i]);
servers[i].setStopAtShutdown(true);
servers[i].start();
}
catch(Exception e)
{
log.warn(LogSupport.EXCEPTION,e);
}
}
// create and start the servers.
for (int i=0;i<arg.length;i++)
{
try{servers[i].join();}
catch (Exception e){LogSupport.ignore(log,e);}
}
}
/**
* ShutdownHook thread for stopping all servers.
*
* Thread is hooked first time list of servers is changed.
*/
private static class ShutdownHookThread extends Thread {
private boolean hooked = false;
private ArrayList servers = new ArrayList();
/**
* Hooks this thread for shutdown.
* @see java.lang.Runtime#addShutdownHook(java.lang.Thread)
*/
private void createShutdownHook() {
if (!Boolean.getBoolean("JETTY_NO_SHUTDOWN_HOOK") && !hooked) {
try {
Method shutdownHook = java.lang.Runtime.class.getMethod("addShutdownHook",
new Class[] { java.lang.Thread.class });
shutdownHook.invoke(Runtime.getRuntime(), new Object[] { this });
this.hooked = true;
} catch (Exception e) {
if (log.isDebugEnabled()) log.debug("No shutdown hook in JVM ", e);
}
}
}
/**
* Add Server to servers list.
*/
public boolean add(Server server) {
createShutdownHook();
return this.servers.add(server);
}
/**
* Contains Server in servers list?
*/
public boolean contains(Server server) {
return this.servers.contains(server);
}
/**
* Append all Servers from Collection
*/
public boolean addAll(Collection c) {
createShutdownHook();
return this.servers.addAll(c);
}
/**
* Clear list of Servers.
*/
public void clear() {
createShutdownHook();
this.servers.clear();
}
/**
* Remove Server from list.
*/
public boolean remove(Server server) {
createShutdownHook();
return this.servers.remove(server);
}
/**
* Remove all Servers in Collection from list.
*/
public boolean removeAll(Collection c) {
createShutdownHook();
return this.servers.removeAll(c);
}
/**
* Stop all Servers in list.
*/
public void run() {
setName("Shutdown");
log.info("Shutdown hook executing");
Iterator it = servers.iterator();
while (it.hasNext()) {
Server svr = (Server) it.next();
if (svr == null) continue;
try {
svr.stop();
} catch (Exception e) {
log.warn(LogSupport.EXCEPTION, e);
}
log.info("Shutdown hook complete");
// Try to avoid JVM crash
try {
Thread.sleep(1000);
} catch (Exception e) {
log.warn(LogSupport.EXCEPTION, e);
}
}
}
}
}

View File

@@ -1,352 +0,0 @@
// ========================================================================
// $Id: FileResource.java,v 1.31 2006/01/04 13:55:31 gregwilkins Exp $
// Copyright 1996-2004 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================
package org.mortbay.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.security.Permission;
import org.apache.commons.logging.Log;
import org.mortbay.log.LogFactory;
/* ------------------------------------------------------------ */
/** File Resource.
*
* Handle resources of implied or explicit file type.
* This class can check for aliasing in the filesystem (eg case
* insensitivity). By default this is turned on if the platform does
* not have the "/" path separator, or it can be controlled with the
* "org.mortbay.util.FileResource.checkAliases" system parameter.
*
* If alias checking is turned on, then aliased resources are
* treated as if they do not exist, nor can they be created.
*
* @version $Revision: 1.31 $
* @author Greg Wilkins (gregw)
*/
public class FileResource extends URLResource
{
private static Log log = LogFactory.getLog(Credential.class);
private static boolean __checkAliases;
static
{
__checkAliases=
"true".equalsIgnoreCase
(System.getProperty("org.mortbay.util.FileResource.checkAliases","true"));
if (__checkAliases)
log.info("Checking Resource aliases");
}
/* ------------------------------------------------------------ */
private File _file;
private transient URL _alias=null;
private transient boolean _aliasChecked=false;
/* ------------------------------------------------------------------------------- */
/** setCheckAliases.
* @param checkAliases True of resource aliases are to be checked for (eg case insensitivity or 8.3 short names) and treated as not found.
*/
public static void setCheckAliases(boolean checkAliases)
{
__checkAliases=checkAliases;
}
/* ------------------------------------------------------------------------------- */
/** getCheckAliases.
* @return True of resource aliases are to be checked for (eg case insensitivity or 8.3 short names) and treated as not found.
*/
public static boolean getCheckAliases()
{
return __checkAliases;
}
/* -------------------------------------------------------- */
FileResource(URL url)
throws IOException, URISyntaxException
{
super(url,null);
try
{
// Try standard API to convert URL to file.
_file =new File(new URI(url.toString()));
}
catch (Exception e)
{
LogSupport.ignore(log,e);
try
{
// Assume that File.toURL produced unencoded chars. So try
// encoding them.
String urls=
"file:"+org.mortbay.util.URI.encodePath(url.toString().substring(5));
_file =new File(new URI(urls));
}
catch (Exception e2)
{
LogSupport.ignore(log,e2);
// Still can't get the file. Doh! try good old hack!
checkConnection();
Permission perm = _connection.getPermission();
_file = new File(perm==null?url.getFile():perm.getName());
}
}
if (_file.isDirectory() && !_urlString.endsWith("/"))
_urlString=_urlString+"/";
}
/* -------------------------------------------------------- */
FileResource(URL url, URLConnection connection, File file)
{
super(url,connection);
_file=file;
if (_file.isDirectory() && !_urlString.endsWith("/"))
_urlString=_urlString+"/";
}
/* -------------------------------------------------------- */
public Resource addPath(String path)
throws IOException,MalformedURLException
{
FileResource r=null;
if (!isDirectory())
{
r=(FileResource)super.addPath(path);
}
else
{
path = org.mortbay.util.URI.canonicalPath(path);
// treat all paths being added as relative
String rel=path;
if (path.startsWith("/"))
rel = path.substring(1);
File newFile = new File(_file,rel.replace('/', File.separatorChar));
r=new FileResource(newFile.toURI().toURL(),null,newFile);
}
String encoded=org.mortbay.util.URI.encodePath(path);
int expected=r._urlString.length()-encoded.length();
int index = r._urlString.lastIndexOf(encoded, expected);
if (expected!=index && ((expected-1)!=index || path.endsWith("/") || !r.isDirectory()))
{
r._alias=r._url;
r._aliasChecked=true;
}
return r;
}
/* ------------------------------------------------------------ */
public URL getAlias()
{
if (__checkAliases) {
if (!_aliasChecked)
{
try
{
String abs=_file.getAbsolutePath();
String can=_file.getCanonicalPath();
if (abs.length()!=can.length() || !abs.equals(can))
_alias=new File(can).toURI().toURL();
_aliasChecked=true;
if (_alias!=null && log.isDebugEnabled())
{
log.debug("ALIAS abs="+abs);
log.debug("ALIAS can="+can);
}
}
catch(Exception e)
{
log.warn(LogSupport.EXCEPTION,e);
return getURL();
}
}
} else return null;
return _alias;
}
/* -------------------------------------------------------- */
/**
* Returns true if the resource exists.
*/
public boolean exists()
{
return _file.exists();
}
/* -------------------------------------------------------- */
/**
* Returns the last modified time
*/
public long lastModified()
{
return _file.lastModified();
}
/* -------------------------------------------------------- */
/**
* Returns true if the respresenetd resource is a container/directory.
*/
public boolean isDirectory()
{
return _file.isDirectory();
}
/* --------------------------------------------------------- */
/**
* Return the length of the resource
*/
public long length()
{
return _file.length();
}
/* --------------------------------------------------------- */
/**
* Returns the name of the resource
*/
public String getName()
{
return _file.getAbsolutePath();
}
/* ------------------------------------------------------------ */
/**
* Returns an File representing the given resource or NULL if this
* is not possible.
*/
public File getFile()
{
return _file;
}
/* --------------------------------------------------------- */
/**
* Returns an input stream to the resource
*/
public InputStream getInputStream() throws IOException
{
return new FileInputStream(_file);
}
/* --------------------------------------------------------- */
/**
* Returns an output stream to the resource
*/
public OutputStream getOutputStream()
throws java.io.IOException, SecurityException
{
return new FileOutputStream(_file);
}
/* --------------------------------------------------------- */
/**
* Deletes the given resource
*/
public boolean delete()
throws SecurityException
{
return _file.delete();
}
/* --------------------------------------------------------- */
/**
* Rename the given resource
*/
public boolean renameTo( Resource dest)
throws SecurityException
{
if( dest instanceof FileResource)
return _file.renameTo( ((FileResource)dest)._file);
else
return false;
}
/* --------------------------------------------------------- */
/**
* Returns a list of resources contained in the given resource
*/
public String[] list()
{
String[] list =_file.list();
if (list==null)
return null;
for (int i=list.length;i-->0;)
{
if (new File(_file,list[i]).isDirectory() &&
!list[i].endsWith("/"))
list[i]+="/";
}
return list;
}
/* ------------------------------------------------------------ */
/** Encode according to this resource type.
* File URIs are encoded.
* @param uri URI to encode.
* @return The uri unchanged.
*/
public String encode(String uri)
{
return uri;
}
/* ------------------------------------------------------------ */
/**
* @param o
* @return
*/
public boolean equals( Object o)
{
if (this == o)
return true;
if (null == o || ! (o instanceof FileResource))
return false;
FileResource f=(FileResource)o;
return f._file == _file || (null != _file && _file.equals(f._file));
}
/* ------------------------------------------------------------ */
/**
* @return the hashcode.
*/
public int hashCode()
{
return null == _file ? super.hashCode() : _file.hashCode();
}
}

View File

@@ -1,253 +0,0 @@
// ========================================================================
// $Id: InetAddrPort.java,v 1.7 2004/10/23 09:03:22 gregwilkins Exp $
// Copyright 1996-2004 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================
package org.mortbay.util;
import java.io.Serializable;
import java.net.InetAddress;
/* ======================================================================== */
/** InetAddress and Port.
*/
public class InetAddrPort implements Serializable
{
/* ------------------------------------------------------------ */
public final static String __0_0_0_0 = "0.0.0.0";
/* ------------------------------------------------------------ */
private InetAddress _addr=null;
private boolean _addrIsHost=false;
private int _port=0;
/* ------------------------------------------------------------------- */
public InetAddrPort()
{}
/* ------------------------------------------------------------ */
/** Constructor for a port on all local host address.
* @param port
*/
public InetAddrPort(int port)
{
_port=port;
}
/* ------------------------------------------------------------ */
/** Constructor.
* @param addr
* @param port
*/
public InetAddrPort(InetAddress addr, int port)
{
_addr=addr;
_port=port;
}
/* ------------------------------------------------------------ */
/** Constructor.
* @param host
* @param port
*/
public InetAddrPort(String host, int port)
throws java.net.UnknownHostException
{
setHost(host);
setPort(port);
}
/* ------------------------------------------------------------ */
/** Constructor.
* Patched to support [::1]:port for I2P
*
* @param inetAddrPort String of the form "addr:port"
*/
public InetAddrPort(String inetAddrPort)
throws java.net.UnknownHostException
{
int b = inetAddrPort.indexOf('[');
if (b>0)
throw new java.net.UnknownHostException("Bad [] syntax");
if (b==0) // IPV6
{
int b2 = inetAddrPort.indexOf(']');
if (b2<2)
throw new java.net.UnknownHostException("Bad [] syntax");
String addr=inetAddrPort.substring(1,b2);
if (addr.indexOf('/')>0)
addr=addr.substring(addr.indexOf('/')+1);
inetAddrPort=inetAddrPort.substring(b2+1);
int c = inetAddrPort.indexOf(':');
if (c>0)
throw new java.net.UnknownHostException("Bad [] syntax");
if (c==0)
inetAddrPort=inetAddrPort.substring(1);
if (addr.length()>0 && ! __0_0_0_0.equals(addr))
{
_addrIsHost=!Character.isDigit((addr.charAt(0)));
this._addr=InetAddress.getByName(addr);
}
} else { // IPV4
int c = inetAddrPort.indexOf(':');
if (c>=0)
{
String addr=inetAddrPort.substring(0,c);
if (addr.indexOf('/')>0)
addr=addr.substring(addr.indexOf('/')+1);
inetAddrPort=inetAddrPort.substring(c+1);
if (addr.length()>0 && ! __0_0_0_0.equals(addr))
{
_addrIsHost=!Character.isDigit((addr.charAt(0)));
this._addr=InetAddress.getByName(addr);
}
}
}
_port = Integer.parseInt(inetAddrPort);
}
/* ------------------------------------------------------------ */
/** Constructor.
* @param address InetAddrPort top copy.
*/
public InetAddrPort(InetAddrPort address)
{
if (address!=null)
{
_addr=address._addr;
_port=address._port;
}
}
/* ------------------------------------------------------------ */
/** Get the Host.
* @return The IP address
*/
public String getHost()
{
if (_addr==null)
return __0_0_0_0;
return _addrIsHost?_addr.getHostName():_addr.getHostAddress();
}
/* ------------------------------------------------------------ */
/** Set the Host.
* @param host
* @exception java.net.UnknownHostException
*/
public void setHost(String host)
throws java.net.UnknownHostException
{
_addr=null;
if (host!=null)
{
if (host.indexOf('/')>0)
host=host.substring(0,host.indexOf('/'));
_addrIsHost=!Character.isDigit((host.charAt(0)));
_addr=InetAddress.getByName(host);
}
}
/* ------------------------------------------------------------ */
/** Get the IP address.
* @return The IP address
*/
public InetAddress getInetAddress()
{
return _addr;
}
/* ------------------------------------------------------------ */
/** Set the IP address.
* @param addr The IP address
*/
public void setInetAddress(InetAddress addr)
{
_addrIsHost=false;
_addr=addr;
}
/* ------------------------------------------------------------ */
/** Get the port.
* @return The port number
*/
public int getPort()
{
return _port;
}
/* ------------------------------------------------------------ */
/** Set the port.
* @param port The port number
*/
public void setPort(int port)
{
_port=port;
}
/* ------------------------------------------------------------------- */
public String toString()
{
return getHost()+':'+_port;
}
/* ------------------------------------------------------------ */
/** Clone the InetAddrPort.
* @return A new instance.
*/
public Object clone()
{
return new InetAddrPort(this);
}
/* ------------------------------------------------------------ */
/** Hash Code.
* @return hash Code.
*/
public int hashCode()
{
return _port+((_addr==null)?0:_addr.hashCode());
}
/* ------------------------------------------------------------ */
/** Equals.
* @param o
* @return True if is the same address and port.
*/
public boolean equals(Object o)
{
if (o==null)
return false;
if (o==this)
return true;
if (o instanceof InetAddrPort)
{
InetAddrPort addr=(InetAddrPort)o;
return addr._port==_port &&
( addr._addr==_addr ||
addr._addr!=null && addr._addr.equals(_addr));
}
return false;
}
}

View File

@@ -1,431 +0,0 @@
// ========================================================================
// $Id: Resource.java,v 1.32 2009/05/16 01:53:36 gregwilkins Exp $
// Copyright 1996-2004 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================
package org.mortbay.util;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.text.DateFormat;
import java.util.Arrays;
import java.util.Date;
import org.apache.commons.logging.Log;
import org.mortbay.log.LogFactory;
/* ------------------------------------------------------------ */
/** Abstract resource class.
*
* @version $Id: Resource.java,v 1.32 2009/05/16 01:53:36 gregwilkins Exp $
* @author Nuno Preguica
* @author Greg Wilkins (gregw)
*/
public abstract class Resource implements Serializable
{
private static Log log = LogFactory.getLog(Resource.class);
Object _associate;
/* ------------------------------------------------------------ */
/** Construct a resource from a url.
* @param url A URL.
* @return A Resource object.
*/
public static Resource newResource(URL url)
throws IOException
{
if (url==null)
return null;
String urls=url.toExternalForm();
if( urls.startsWith( "file:"))
{
try
{
FileResource fileResource= new FileResource(url);
return fileResource;
}
catch(Exception e)
{
log.debug(LogSupport.EXCEPTION,e);
return new BadResource(url,e.toString());
}
}
else if( urls.startsWith( "jar:file:"))
{
return new JarFileResource(url);
}
else if( urls.startsWith( "jar:"))
{
return new JarResource(url);
}
return new URLResource(url,null);
}
/* ------------------------------------------------------------ */
/** Construct a resource from a string.
* @param resource A URL or filename.
* @return A Resource object.
*/
public static Resource newResource(String resource)
throws MalformedURLException, IOException
{
URL url=null;
try
{
// Try to format as a URL?
url = new URL(resource);
}
catch(MalformedURLException e)
{
if(!resource.startsWith("ftp:") &&
!resource.startsWith("file:") &&
!resource.startsWith("jar:"))
{
try
{
// It's a file.
if (resource.startsWith("./"))
resource=resource.substring(2);
File file=new File(resource).getCanonicalFile();
url=file.toURI().toURL();
URLConnection connection=url.openConnection();
FileResource fileResource= new FileResource(url,connection,file);
return fileResource;
}
catch(Exception e2)
{
log.debug(LogSupport.EXCEPTION,e2);
throw e;
}
}
else
{
log.warn("Bad Resource: "+resource);
throw e;
}
}
String nurl=url.toString();
if (nurl.length()>0 &&
nurl.charAt(nurl.length()-1)!=
resource.charAt(resource.length()-1))
{
if ((nurl.charAt(nurl.length()-1)!='/' ||
nurl.charAt(nurl.length()-2)!=resource.charAt(resource.length()-1))
&&
(resource.charAt(resource.length()-1)!='/' ||
resource.charAt(resource.length()-2)!=nurl.charAt(nurl.length()-1)
))
{
return new BadResource(url,"Trailing special characters stripped by URL in "+resource);
}
}
return newResource(url);
}
/* ------------------------------------------------------------ */
/** Construct a system resource from a string.
* The resource is tried as classloader resource before being
* treated as a normal resource.
*/
public static Resource newSystemResource(String resource)
throws IOException
{
URL url=null;
// Try to format as a URL?
ClassLoader
loader=Thread.currentThread().getContextClassLoader();
if (loader!=null)
{
url=loader.getResource(resource);
if (url==null && resource.startsWith("/"))
url=loader.getResource(resource.substring(1));
}
if (url==null)
{
loader=Resource.class.getClassLoader();
if (loader!=null)
{
url=loader.getResource(resource);
if (url==null && resource.startsWith("/"))
url=loader.getResource(resource.substring(1));
}
}
if (url==null)
{
url=ClassLoader.getSystemResource(resource);
if (url==null && resource.startsWith("/"))
url=loader.getResource(resource.substring(1));
}
if (url==null)
return null;
return newResource(url);
}
/* ------------------------------------------------------------ */
protected void finalize()
{
release();
}
/* ------------------------------------------------------------ */
/** Release any resources held by the resource.
*/
public abstract void release();
/* ------------------------------------------------------------ */
/**
* Returns true if the respresened resource exists.
*/
public abstract boolean exists();
/* ------------------------------------------------------------ */
/**
* Returns true if the respresenetd resource is a container/directory.
* If the resource is not a file, resources ending with "/" are
* considered directories.
*/
public abstract boolean isDirectory();
/* ------------------------------------------------------------ */
/**
* Returns the last modified time
*/
public abstract long lastModified();
/* ------------------------------------------------------------ */
/**
* Return the length of the resource
*/
public abstract long length();
/* ------------------------------------------------------------ */
/**
* Returns an URL representing the given resource
*/
public abstract URL getURL();
/* ------------------------------------------------------------ */
/**
* Returns an File representing the given resource or NULL if this
* is not possible.
*/
public abstract File getFile()
throws IOException;
/* ------------------------------------------------------------ */
/**
* Returns the name of the resource
*/
public abstract String getName();
/* ------------------------------------------------------------ */
/**
* Returns an input stream to the resource
*/
public abstract InputStream getInputStream()
throws java.io.IOException;
/* ------------------------------------------------------------ */
/**
* Returns an output stream to the resource
*/
public abstract OutputStream getOutputStream()
throws java.io.IOException, SecurityException;
/* ------------------------------------------------------------ */
/**
* Deletes the given resource
*/
public abstract boolean delete()
throws SecurityException;
/* ------------------------------------------------------------ */
/**
* Rename the given resource
*/
public abstract boolean renameTo( Resource dest)
throws SecurityException;
/* ------------------------------------------------------------ */
/**
* Returns a list of resource names contained in the given resource
* The resource names are not URL encoded.
*/
public abstract String[] list();
/* ------------------------------------------------------------ */
/**
* Returns the resource contained inside the current resource with the
* given name.
* @param path The path segment to add, which should be encoded by the
* encode method.
*/
public abstract Resource addPath(String path)
throws IOException,MalformedURLException;
/* ------------------------------------------------------------ */
/** Encode according to this resource type.
* The default implementation calls URI.encodePath(uri)
* @param uri
* @return String encoded for this resource type.
*/
public String encode(String uri)
{
return URI.encodePath(uri);
}
/* ------------------------------------------------------------ */
public Object getAssociate()
{
return _associate;
}
/* ------------------------------------------------------------ */
public void setAssociate(Object o)
{
_associate=o;
}
/* ------------------------------------------------------------ */
/**
* @return The canonical Alias of this resource or null if none.
*/
public URL getAlias()
{
return null;
}
/* ------------------------------------------------------------ */
public CachedResource cache()
throws IOException
{
return new CachedResource(this);
}
/* ------------------------------------------------------------ */
/** Get the resource list as a HTML directory listing.
* @param base The base URL
* @param parent True if the parent directory should be included
* @return String of HTML
*/
public String getListHTML(String base,
boolean parent)
throws IOException
{
if (!isDirectory())
return null;
String[] ls = list();
if (ls==null)
return null;
Arrays.sort(ls);
String title = "Directory: "+URI.decodePath(base);
title=StringUtil.replace(StringUtil.replace(title,"<","&lt;"),">","&gt;");
StringBuffer buf=new StringBuffer(4096);
buf.append("<HTML><HEAD><TITLE>");
buf.append(title);
buf.append("</TITLE></HEAD><BODY>\n<H1>");
buf.append(title);
buf.append("</H1><TABLE BORDER=0>");
if (parent)
{
buf.append("<TR><TD><A HREF=");
buf.append(URI.encodePath(URI.addPaths(base,"../")));
buf.append(">Parent Directory</A></TD><TD></TD><TD></TD></TR>\n");
}
DateFormat dfmt=DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
DateFormat.MEDIUM);
for (int i=0 ; i< ls.length ; i++)
{
String encoded=URI.encodePath(ls[i]);
// bugfix for I2P - Backport from Jetty 6 (zero file lengths and last-modified times)
// http://jira.codehaus.org/browse/JETTY-361?page=com.atlassian.jira.plugin.system.issuetabpanels%3Achangehistory-tabpanel#issue-tabs
// See resource.diff attachment
//Resource item = addPath(encoded);
Resource item = addPath(ls[i]);
buf.append("<TR><TD><A HREF=\"");
String path=URI.addPaths(base,encoded);
if (item.isDirectory() && !path.endsWith("/"))
path=URI.addPaths(path,"/");
buf.append(path);
buf.append("\">");
buf.append(StringUtil.replace(StringUtil.replace(ls[i],"<","&lt;"),">","&gt;"));
buf.append("</A>&nbsp;");
buf.append("</TD><TD ALIGN=right>");
buf.append(item.length());
buf.append(" bytes&nbsp;</TD><TD>");
buf.append(dfmt.format(new Date(item.lastModified())));
buf.append("</TD></TR>\n");
}
buf.append("</TABLE>\n");
buf.append("</BODY></HTML>\n");
return buf.toString();
}
/* ------------------------------------------------------------ */
/**
* @param out
* @param start First byte to write
* @param count Bytes to write or -1 for all of them.
*/
public void writeTo(OutputStream out,long start,long count)
throws IOException
{
InputStream in = getInputStream();
try
{
in.skip(start);
if (count<0)
IO.copy(in,out);
else
IO.copy(in,out,(int)count);
}
finally
{
in.close();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
This is only what we need out of the 25 MB Jetty-6.1.26.zip.
NOTICE and LICENSE files moved to ../../../licenses

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,9 @@
# This is not needed by Jetty - but it helps with many web apps.
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

View File

@@ -51,6 +51,7 @@
<jar destfile="./build/mstreaming.jar" basedir="./build/obj" includes="**/*.class" >
<manifest>
<attribute name="Implementation-Version" value="${full.version}" />
<attribute name="Built-By" value="${build.built-by}" />
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />

View File

@@ -21,7 +21,12 @@
<pathelement location="../../../core/java/build/obj" />
<pathelement location="../../../router/java/build/obj" />
<pathelement location="../../jetty/jettylib/org.mortbay.jetty.jar" />
<pathelement location="../../jetty/jettylib/jetty-util.jar" />
<pathelement location="../../jetty/jettylib/jetty-sslengine.jar" />
<pathelement location="../../jetty/jettylib/jetty-java5-threadpool.jar" />
<pathelement location="../../jetty/jettylib/javax.servlet.jar" />
<pathelement location="../../jetty/jettylib/jsp-api.jar" />
<pathelement location="../../jetty/jettylib/jetty-i2p.jar" />
<pathelement location="../../systray/java/build/obj" />
<pathelement location="../../systray/java/lib/systray4j.jar" />
<pathelement location="../../desktopgui/build" />
@@ -54,7 +59,12 @@
<pathelement location="../../../core/java/build/i2p.jar" />
<pathelement location="../../../router/java/build/router.jar" />
<pathelement location="../../jetty/jettylib/org.mortbay.jetty.jar" />
<pathelement location="../../jetty/jettylib/jetty-util.jar" />
<pathelement location="../../jetty/jettylib/jetty-sslengine.jar" />
<pathelement location="../../jetty/jettylib/jetty-java5-threadpool.jar" />
<pathelement location="../../jetty/jettylib/javax.servlet.jar" />
<pathelement location="../../jetty/jettylib/jsp-api.jar" />
<pathelement location="../../jetty/jettylib/jetty-i2p.jar" />
<pathelement location="../../systray/java/build/systray.jar" />
<pathelement location="../../systray/java/lib/systray4j.jar" />
<pathelement location="../../desktopgui/dist/desktopgui.jar" />
@@ -92,6 +102,7 @@
<!-- DTG added in 0.8.4, not in the classpath for very old installs, before we changed wrapper.config to specify * -->
<attribute name="Class-Path" value="i2p.jar router.jar jrobin.jar desktopgui.jar" />
<attribute name="Implementation-Version" value="${full.version}" />
<attribute name="Built-By" value="${build.built-by}" />
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.j.tr}" />
@@ -172,6 +183,7 @@
basedir="../jsp/" excludes="web.xml, *.css, **/*.java, *.jsp, *.jsi, web-fragment.xml, web-out.xml">
<manifest>
<attribute name="Implementation-Version" value="${full.version}" />
<attribute name="Built-By" value="${build.built-by}" />
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.w.tr}" />
@@ -236,7 +248,9 @@
<pathelement location="../../jetty/jettylib/javax.servlet.jar" />
<pathelement location="../../jetty/jettylib/commons-logging.jar" />
<pathelement location="../../jetty/jettylib/commons-el.jar" />
<pathelement location="../../jetty/jettylib/ant.jar" />
<pathelement location="../../jetty/jettylib/jsp-api.jar" />
<pathelement location="${ant.home}/lib/ant.jar" />
<pathelement location="../../jetty/jettylib/jetty-i2p.jar" />
<pathelement location="../../systray/java/build/obj" />
<pathelement location="../../systray/java/lib/systray4j.jar" />
<pathelement location="../../desktopgui/dist/desktopgui.jar" />
@@ -269,6 +283,11 @@
<pathelement location="../../jetty/jettylib/commons-logging.jar" />
<pathelement location="../../jetty/jettylib/commons-el.jar" />
<pathelement location="../../jetty/jettylib/org.mortbay.jetty.jar" />
<pathelement location="../../jetty/jettylib/jetty-util.jar" />
<pathelement location="../../jetty/jettylib/jetty-sslengine.jar" />
<pathelement location="../../jetty/jettylib/jetty-java5-threadpool.jar" />
<pathelement location="../../jetty/jettylib/jsp-api.jar" />
<pathelement location="../../jetty/jettylib/jetty-i2p.jar" />
<pathelement location="../../systray/java/build/obj" />
<pathelement location="../../systray/java/lib/systray4j.jar" />
<pathelement location="../../desktopgui/dist/desktopgui.jar" />

View File

@@ -14,7 +14,7 @@ import net.i2p.router.client.ClientManagerFacadeImpl;
import net.i2p.router.startup.ClientAppConfig;
import net.i2p.router.startup.LoadClientAppsJob;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.handler.ContextHandlerCollection;
/**
* Saves changes to clients.config or webapps.config
@@ -290,7 +290,7 @@ public class ConfigClientsHandler extends FormHandler {
* requested and add the .war to that one
*/
private void startWebApp(String app) {
Server s = WebAppStarter.getConsoleServer();
ContextHandlerCollection s = WebAppStarter.getConsoleServer();
if (s != null) {
try {
File path = new File(_context.getBaseDir(), "webapps");

View File

@@ -52,7 +52,7 @@ public class ConfigClientsHelper extends HelperBase {
if ((mode == 0 && disabled) ||
(mode == 1 && (!disabled) && (!ssl)) ||
(mode == 2 && (!disabled) && ssl))
return "checked=\"true\"";
return "checked=\"checked\"";
return "";
}
@@ -60,7 +60,7 @@ public class ConfigClientsHelper extends HelperBase {
public String getAuth() {
boolean enabled = _context.getBooleanProperty(PROP_AUTH);
if (enabled)
return "checked=\"true\"";
return "checked=\"checked\"";
return "";
}
@@ -253,9 +253,9 @@ public class ConfigClientsHelper extends HelperBase {
}
buf.append("</td><td align=\"center\" width=\"10%\"><input type=\"checkbox\" class=\"optbox\" name=\"").append(index).append(".enabled\" value=\"true\" ");
if (enabled) {
buf.append("checked=\"true\" ");
buf.append("checked=\"checked\" ");
if (ro)
buf.append("disabled=\"true\" ");
buf.append("disabled=\"disabled\" ");
}
buf.append("></td><td align=\"center\" width=\"15%\">");
// The icons were way too much, so there's an X in each button class,

View File

@@ -0,0 +1,113 @@
package net.i2p.router.web;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.Map;
import net.i2p.data.DataHelper;
/**
* Simple home page configuration.
*
* @since 0.9
*/
public class ConfigHomeHandler extends FormHandler {
private Map _settings;
@Override
protected void processForm() {
if (_action == null) return;
String group = getJettyString("group");
boolean deleting = _action.equals(_("Delete selected"));
boolean adding = _action.equals(_("Add item"));
boolean restoring = _action.equals(_("Restore defaults"));
if (_action.equals(_("Save")) && "0".equals(group)) {
boolean old = _context.getBooleanProperty(HomeHelper.PROP_OLDHOME);
boolean nnew = getJettyString("oldHome") != null;
if (old != nnew) {
_context.router().saveConfig(HomeHelper.PROP_OLDHOME, "" + nnew);
addFormNotice(_("Home page changed"));
}
} else if (adding || deleting || restoring) {
String prop;
String dflt;
if ("1".equals(group)) {
prop = HomeHelper.PROP_FAVORITES;
dflt = HomeHelper.DEFAULT_FAVORITES;
} else if ("2".equals(group)) {
prop = HomeHelper.PROP_SERVICES;
dflt = HomeHelper.DEFAULT_SERVICES;
} else if ("3".equals(group)) {
prop = SearchHelper.PROP_ENGINES;
dflt = SearchHelper.ENGINES_DEFAULT;
} else {
addFormError("Bad group");
return;
}
if (restoring) {
_context.router().saveConfig(prop, dflt);
addFormNotice(_("Restored default settings"));
return;
}
String config = _context.getProperty(prop, dflt);
Collection<HomeHelper.App> apps;
if ("3".equals(group))
apps = HomeHelper.buildSearchApps(config);
else
apps = HomeHelper.buildApps(_context, config);
if (adding) {
String name = getJettyString("name");
if (name == null || name.length() <= 0) {
addFormError(_("No name entered"));
return;
}
String url = getJettyString("url");
if (url == null || url.length() <= 0) {
addFormError(_("No URL entered"));
return;
}
name = DataHelper.escapeHTML(name).replace(",", "&#44;"); // HomeHelper.S
url = DataHelper.escapeHTML(url).replace(",", "&#44;");
HomeHelper.App app = new HomeHelper.App(name, "", url, "/themes/console/images/itoopie_sm.png");
apps.add(app);
addFormNotice(_("Added") + ": " + app.name);
} else {
// deleting
Set<String> toDelete = new HashSet();
for (Object o : _settings.keySet()) {
if (!(o instanceof String))
continue;
String k = (String) o;
if (!k.startsWith("delete_"))
continue;
k = k.substring(7);
toDelete.add(k);
}
for (Iterator<HomeHelper.App> iter = apps.iterator(); iter.hasNext(); ) {
HomeHelper.App app = iter.next();
if (toDelete.contains(app.name)) {
iter.remove();
addFormNotice(_("Removed") + ": " + app.name);
}
}
}
HomeHelper.saveApps(_context, prop, apps, !("3".equals(group)));
} else {
addFormError(_("Unsupported"));
}
}
public void setSettings(Map settings) { _settings = new HashMap(settings); }
/** curses Jetty for returning arrays */
private String getJettyString(String key) {
String[] arr = (String[]) _settings.get(key);
if (arr == null)
return null;
return arr[0].trim();
}
}

View File

@@ -70,7 +70,7 @@ public class ConfigLoggingHandler extends FormHandler {
private void saveChanges() {
boolean shouldSave = false;
if (_levels != null || _newLogClass != null) {
if ((_levels != null && _levels.length() > 0) || _newLogClass != null) {
try {
Properties props = new Properties();
if (_levels != null)
@@ -85,8 +85,9 @@ public class ConfigLoggingHandler extends FormHandler {
_context.logManager().getLog(ConfigLoggingHandler.class).error("Error reading from the props?", ioe);
addFormError("Error updating the log limits - levels not valid");
}
} else {
} else if (!_context.logManager().getLimits().isEmpty()) {
_context.logManager().setLimits(null);
shouldSave = true;
addFormNotice("Log limits cleared");
}

View File

@@ -80,7 +80,7 @@ public class ConfigLoggingHelper extends HelperBase {
String l = levels[i];
buf.append("<option value=\"").append(l).append('\"');
if (l.equals(cur))
buf.append(" selected=\"true\"");
buf.append(" selected=\"selected\"");
buf.append('>').append(_(l)).append("</option>\n");
}
@@ -121,7 +121,7 @@ public class ConfigLoggingHelper extends HelperBase {
StringBuilder buf = new StringBuilder(65536);
buf.append("<select name=\"newlogclass\">\n" +
"<option value=\"\" selected=\"true\">")
"<option value=\"\" selected=\"selected\">")
.append(_("Select a class to add"))
.append("</option>\n");

View File

@@ -11,12 +11,13 @@ public class ConfigNavHelper extends HelperBase {
/** configX.jsp */
private static final String pages[] =
{"", "net", "ui", "service", "update", "tunnels",
{"", "net", "ui", "home", "service", "update", "tunnels",
"clients", "peer", "keyring", "logging", "stats",
"reseed", "advanced" };
private static final String titles[] =
{_x("Bandwidth"), _x("Network"), _x("UI"), _x("Service"), _x("Update"), _x("Tunnels"),
{_x("Bandwidth"), _x("Network"), _x("UI"), _x("Home Page"),
_x("Service"), _x("Update"), _x("Tunnels"),
_x("Clients"), _x("Peers"), _x("Keyring"), _x("Logging"), _x("Stats"),
_x("Reseeding"), _x("Advanced") };

View File

@@ -20,8 +20,8 @@ public class ConfigNetHelper extends HelperBase {
public final static String PROP_I2NP_NTCP_PORT = "i2np.ntcp.port";
public final static String PROP_I2NP_NTCP_AUTO_PORT = "i2np.ntcp.autoport";
public final static String PROP_I2NP_NTCP_AUTO_IP = "i2np.ntcp.autoip";
private final static String CHECKED = " checked=\"true\" ";
private final static String DISABLED = " disabled=\"true\" ";
private final static String CHECKED = " checked=\"checked\" ";
private final static String DISABLED = " disabled=\"disabled\" ";
public String getUdphostname() {
return _context.getProperty(UDPTransport.PROP_EXTERNAL_HOST, "");
@@ -250,7 +250,7 @@ public class ConfigNetHelper extends HelperBase {
}
buf.append("<option style=\"text-align: right;\" value=\"").append(val).append("\" ");
if (pct == val) {
buf.append("selected=\"true\" ");
buf.append("selected=\"selected\" ");
found = true;
}
buf.append(">").append(val).append("%</option>\n");

View File

@@ -56,7 +56,7 @@ public class ConfigReseedHelper extends HelperBase {
if ((mode == 0 && (!disabled) && (!required)) ||
(mode == 1 && (!disabled) && required) ||
(mode == 2 && disabled))
return "checked=\"true\"";
return "checked=\"checked\"";
return "";
}
@@ -82,7 +82,7 @@ public class ConfigReseedHelper extends HelperBase {
private String checked(String prop) {
boolean enabled = _context.getBooleanProperty(prop);
if (enabled)
return "checked=\"true\"";
return "checked=\"checked\"";
return "";
}

View File

@@ -59,8 +59,16 @@ public class ConfigStatsHelper extends HelperBase {
_filters.add(tok.nextToken().trim());
}
public ConfigStatsHelper() {}
/**
* Just hide for everybody unless already set.
* To enable set advanced config stat.logFilters=foo before starting...
* it has to be set at startup anyway for logging to be enabled at all
* @since 0.9
*/
public boolean shouldShowLog() {
return !_filters.isEmpty();
}
public String getFilename() { return _context.statManager().getStatFile(); }
/**

Some files were not shown because too many files have changed in this diff Show More