merge of '285a9a021659672b12861eea3c150d47b5025275'

and 'a90a0715f156a732cf039bd2df9bbc3d90e82693'
This commit is contained in:
z3d
2010-11-10 14:37:57 +00:00
63 changed files with 2181 additions and 1017 deletions

View File

@@ -152,6 +152,9 @@ public class I2PSnarkUtil {
*/
synchronized public boolean connect() {
if (_manager == null) {
// try to find why reconnecting after stop
if (_log.shouldLog(Log.DEBUG))
_log.debug("Connecting to I2P", new Exception("I did it"));
Properties opts = new Properties();
if (_opts != null) {
for (Iterator iter = _opts.keySet().iterator(); iter.hasNext(); ) {
@@ -163,6 +166,10 @@ public class I2PSnarkUtil {
opts.setProperty("inbound.nickname", "I2PSnark");
if (opts.getProperty("outbound.nickname") == null)
opts.setProperty("outbound.nickname", "I2PSnark");
// Dont do this for now, it is set in I2PSocketEepGet for announces,
// we don't need fast handshake for peer connections.
//if (opts.getProperty("i2p.streaming.connectDelay") == null)
// opts.setProperty("i2p.streaming.connectDelay", "500");
if (opts.getProperty("i2p.streaming.inactivityTimeout") == null)
opts.setProperty("i2p.streaming.inactivityTimeout", "240000");
if (opts.getProperty("i2p.streaming.inactivityAction") == null)
@@ -186,6 +193,7 @@ public class I2PSnarkUtil {
*/
public void disconnect() {
I2PSocketManager mgr = _manager;
// FIXME this can cause race NPEs elsewhere
_manager = null;
_shitlist.clear();
mgr.destroySocketManager();
@@ -197,6 +205,9 @@ public class I2PSnarkUtil {
/** connect to the given destination */
I2PSocket connect(PeerID peer) throws IOException {
I2PSocketManager mgr = _manager;
if (mgr == null)
throw new IOException("No socket manager");
Destination addr = peer.getAddress();
if (addr == null)
throw new IOException("Null address");

View File

@@ -56,8 +56,8 @@ public class Peer implements Comparable
private long _id;
final static long CHECK_PERIOD = PeerCoordinator.CHECK_PERIOD; // 40 seconds
final static int RATE_DEPTH = PeerCoordinator.RATE_DEPTH; // make following arrays RATE_DEPTH long
private long uploaded_old[] = {-1,-1,-1,-1,-1,-1};
private long downloaded_old[] = {-1,-1,-1,-1,-1,-1};
private long uploaded_old[] = {-1,-1,-1};
private long downloaded_old[] = {-1,-1,-1};
/**
* Creates a disconnected peer given a PeerID, your own id and the
@@ -117,10 +117,15 @@ public class Peer implements Comparable
}
/**
* Returns socket (for debug printing)
* @return socket debug string (for debug printing)
*/
public String getSocket()
{
if (state != null) {
String r = state.getRequests();
if (r != null)
return sock.toString() + "<br>Requests: " + r;
}
return sock.toString();
}
@@ -387,6 +392,37 @@ public class Peer implements Comparable
s.havePiece(piece);
}
/**
* Tell the other side that we are no longer interested in any of
* the outstanding requests (if any) for this piece.
* @since 0.8.1
*/
void cancel(int piece) {
PeerState s = state;
if (s != null)
s.cancelPiece(piece);
}
/**
* Are we currently requesting the piece?
* @since 0.8.1
*/
boolean isRequesting(int p) {
PeerState s = state;
return s != null && s.isRequesting(p);
}
/**
* Update the request queue.
* Call after adding wanted pieces.
* @since 0.8.1
*/
void request() {
PeerState s = state;
if (s != null)
s.addRequest();
}
/**
* Whether or not the peer is interested in pieces we have. Returns
* false if not connected.
@@ -545,17 +581,8 @@ public class Peer implements Comparable
*/
public void setRateHistory(long up, long down)
{
setRate(up, uploaded_old);
setRate(down, downloaded_old);
}
private void setRate(long val, long array[])
{
synchronized(array) {
for (int i = RATE_DEPTH-1; i > 0; i--)
array[i] = array[i-1];
array[0] = val;
}
PeerCoordinator.setRate(up, uploaded_old);
PeerCoordinator.setRate(down, downloaded_old);
}
/**
@@ -563,28 +590,11 @@ public class Peer implements Comparable
*/
public long getUploadRate()
{
return getRate(uploaded_old);
return PeerCoordinator.getRate(uploaded_old);
}
public long getDownloadRate()
{
return getRate(downloaded_old);
return PeerCoordinator.getRate(downloaded_old);
}
private long getRate(long array[])
{
long rate = 0;
int i = 0;
synchronized(array) {
for ( ; i < RATE_DEPTH; i++){
if (array[i] < 0)
break;
rate += array[i];
}
}
if (i == 0)
return 0;
return rate / (i * CHECK_PERIOD / 1000);
}
}

View File

@@ -57,9 +57,9 @@ public class PeerCoordinator implements PeerListener
private long uploaded;
private long downloaded;
final static int RATE_DEPTH = 6; // make following arrays RATE_DEPTH long
private long uploaded_old[] = {-1,-1,-1,-1,-1,-1};
private long downloaded_old[] = {-1,-1,-1,-1,-1,-1};
final static int RATE_DEPTH = 3; // make following arrays RATE_DEPTH long
private long uploaded_old[] = {-1,-1,-1};
private long downloaded_old[] = {-1,-1,-1};
// synchronize on this when changing peers or downloaders
final List<Peer> peers = new ArrayList();
@@ -78,6 +78,7 @@ public class PeerCoordinator implements PeerListener
private final CoordinatorListener listener;
public I2PSnarkUtil _util;
private static final Random _random = I2PAppContext.getGlobalContext().random();
public String trackerProblems = null;
public int trackerSeenPeers = 0;
@@ -97,20 +98,29 @@ public class PeerCoordinator implements PeerListener
// Install a timer to check the uploaders.
// Randomize the first start time so multiple tasks are spread out,
// this will help the behavior with global limits
Random r = I2PAppContext.getGlobalContext().random();
timer.schedule(new PeerCheckerTask(_util, this), (CHECK_PERIOD / 2) + r.nextInt((int) CHECK_PERIOD), CHECK_PERIOD);
timer.schedule(new PeerCheckerTask(_util, this), (CHECK_PERIOD / 2) + _random.nextInt((int) CHECK_PERIOD), CHECK_PERIOD);
}
// only called externally from Storage after the double-check fails
public void setWantedPieces()
{
// Make a list of pieces
// FIXME synchronize, clear and re-add instead?
// Don't replace something we are synchronizing on.
wantedPieces = new ArrayList();
BitField bitfield = storage.getBitField();
for(int i = 0; i < metainfo.getPieces(); i++)
if (!bitfield.get(i))
wantedPieces.add(new Piece(i));
Collections.shuffle(wantedPieces);
int[] pri = storage.getPiecePriorities();
for(int i = 0; i < metainfo.getPieces(); i++) {
// only add if we don't have and the priority is >= 0
if ((!bitfield.get(i)) &&
(pri == null || pri[i] >= 0)) {
Piece p = new Piece(i);
if (pri != null)
p.setPriority(pri[i]);
wantedPieces.add(p);
}
}
Collections.shuffle(wantedPieces, _random);
}
public Storage getStorage() { return storage; }
@@ -183,7 +193,7 @@ public class PeerCoordinator implements PeerListener
setRate(down, downloaded_old);
}
private static void setRate(long val, long array[])
static void setRate(long val, long array[])
{
synchronized(array) {
for (int i = RATE_DEPTH-1; i > 0; i--)
@@ -214,20 +224,23 @@ public class PeerCoordinator implements PeerListener
return (r * 1000) / CHECK_PERIOD;
}
private long getRate(long array[])
static long getRate(long array[])
{
long rate = 0;
int i = 0;
int factor = 0;
synchronized(array) {
for ( ; i < RATE_DEPTH; i++) {
if (array[i] < 0)
break;
rate += array[i];
int f = RATE_DEPTH - i;
rate += array[i] * f;
factor += f;
}
}
if (i == 0)
return 0;
return rate / (i * CHECK_PERIOD / 1000);
return rate / (factor * CHECK_PERIOD / 1000);
}
public MetaInfo getMetaInfo()
@@ -454,7 +467,7 @@ public class PeerCoordinator implements PeerListener
}
/**
* Returns true if we don't have the given piece yet.
* @return true if we still want the given piece
*/
public boolean gotHave(Peer peer, int piece)
{
@@ -499,6 +512,12 @@ public class PeerCoordinator implements PeerListener
*/
private static final int END_GAME_THRESHOLD = 8;
/**
* Max number of peers to get a piece from when in end game
* @since 0.8.1
*/
private static final int MAX_PARALLEL_REQUESTS = 4;
/**
* Returns one of pieces in the given BitField that is still wanted or
* -1 if none of the given pieces are wanted.
@@ -520,6 +539,9 @@ public class PeerCoordinator implements PeerListener
while (piece == null && it.hasNext())
{
Piece p = it.next();
// sorted by priority, so when we hit a disabled piece we are done
if (p.isDisabled())
break;
if (havePieces.get(p.getId()) && !p.isRequested())
{
piece = p;
@@ -538,15 +560,32 @@ public class PeerCoordinator implements PeerListener
if (wantedPieces.size() > END_GAME_THRESHOLD)
return -1; // nothing to request and not in end game
// let's not all get on the same piece
Collections.shuffle(requested);
// Even better would be to sort by number of requests
Collections.shuffle(requested, _random);
Iterator<Piece> it2 = requested.iterator();
while (piece == null && it2.hasNext())
{
Piece p = it2.next();
if (havePieces.get(p.getId()))
{
if (havePieces.get(p.getId())) {
// limit number of parallel requests
int requestedCount = 0;
synchronized(peers) {
for (Peer pr : peers) {
if (pr.isRequesting(p.getId())) {
if (pr.equals(peer)) {
// don't give it to him again
requestedCount = MAX_PARALLEL_REQUESTS;
break;
}
if (++requestedCount >= MAX_PARALLEL_REQUESTS)
break;
}
}
}
if (requestedCount >= MAX_PARALLEL_REQUESTS)
continue;
piece = p;
}
}
}
if (piece == null) {
if (_log.shouldLog(Log.WARN))
@@ -555,7 +594,7 @@ public class PeerCoordinator implements PeerListener
// + " wanted = " + wantedPieces + " peerHas = " + havePieces);
return -1; //If we still can't find a piece we want, so be it.
} else {
// Should be a lot smarter here - limit # of parallel attempts and
// Should be a lot smarter here -
// share blocks rather than starting from 0 with each peer.
// This is where the flaws of the snark data model are really exposed.
// Could also randomize within the duplicate set rather than strict rarest-first
@@ -563,11 +602,83 @@ public class PeerCoordinator implements PeerListener
_log.debug("parallel request (end game?) for " + peer + ": piece = " + piece);
}
}
if (_log.shouldLog(Log.DEBUG))
_log.debug("Now requesting: piece " + piece + " priority " + piece.getPriority());
piece.setRequested(true);
return piece.getId();
}
}
/**
* Maps file priorities to piece priorities.
* Call after updating file priorities Storage.setPriority()
* @since 0.8.1
*/
public void updatePiecePriorities() {
int[] pri = storage.getPiecePriorities();
if (pri == null) {
_log.debug("Updated piece priorities called but no priorities to set?");
return;
}
synchronized(wantedPieces) {
// Add incomplete and previously unwanted pieces to the list
// Temp to avoid O(n**2)
BitField want = new BitField(pri.length);
for (Piece p : wantedPieces) {
want.set(p.getId());
}
BitField bitfield = storage.getBitField();
for (int i = 0; i < pri.length; i++) {
if (pri[i] >= 0 && !bitfield.get(i)) {
if (!want.get(i)) {
Piece piece = new Piece(i);
wantedPieces.add(piece);
// As connections are already up, new Pieces will
// not have their PeerID list populated, so do that.
synchronized(peers) {
for (Peer p : peers) {
PeerState s = p.state;
if (s != null) {
BitField bf = s.bitfield;
if (bf != null && bf.get(i))
piece.addPeer(p);
}
}
}
}
}
}
// now set the new priorities and remove newly unwanted pieces
for (Iterator<Piece> iter = wantedPieces.iterator(); iter.hasNext(); ) {
Piece p = iter.next();
int priority = pri[p.getId()];
if (priority >= 0) {
p.setPriority(priority);
} else {
iter.remove();
// cancel all peers
synchronized(peers) {
for (Peer peer : peers) {
peer.cancel(p.getId());
}
}
}
}
if (_log.shouldLog(Log.DEBUG))
_log.debug("Updated piece priorities, now wanted: " + wantedPieces);
// if we added pieces, they will be in-order unless we shuffle
Collections.shuffle(wantedPieces, _random);
// update request queues, in case we added wanted pieces
// and we were previously uninterested
synchronized(peers) {
for (Peer peer : peers) {
peer.request();
}
}
}
}
/**
* Returns a byte array containing the requested piece or null of
* the piece is unknown.
@@ -632,14 +743,18 @@ public class PeerCoordinator implements PeerListener
// No need to announce have piece to peers.
// Assume we got a good piece, we don't really care anymore.
return true;
// Well, this could be caused by a change in priorities, so
// only return true if we already have it, otherwise might as well keep it.
if (storage.getBitField().get(piece))
return true;
}
try
{
if (storage.putPiece(piece, bs))
{
_log.info("Got valid piece " + piece + "/" + metainfo.getPieces() +" from " + peer + " for " + metainfo.getName());
if (_log.shouldLog(Log.INFO))
_log.info("Got valid piece " + piece + "/" + metainfo.getPieces() +" from " + peer + " for " + metainfo.getName());
}
else
{

View File

@@ -55,12 +55,10 @@ class PeerState
final PeerConnectionOut out;
// Outstanding request
private final List outstandingRequests = new ArrayList();
private final List<Request> outstandingRequests = new ArrayList();
/** the tail (NOT the head) of the request queue */
private Request lastRequest = null;
// If we have te resend outstanding requests (true after we got choked).
private boolean resend = false;
private final static int MAX_PIPELINE = 5; // this is for outbound requests
private final static int MAX_PIPELINE_BYTES = 128*1024; // this is for inbound requests
public final static int PARTSIZE = 16*1024; // outbound request
@@ -91,14 +89,13 @@ class PeerState
if (_log.shouldLog(Log.DEBUG))
_log.debug(peer + " rcv " + (choke ? "" : "un") + "choked");
boolean resend = choked && !choke;
choked = choke;
if (choked)
resend = true;
listener.gotChoke(peer, choke);
if (!choked && interesting)
request();
if (interesting && !choked)
request(resend);
}
void interestedMessage(boolean interest)
@@ -278,7 +275,7 @@ class PeerState
synchronized private int getFirstOutstandingRequest(int piece)
{
for (int i = 0; i < outstandingRequests.size(); i++)
if (((Request)outstandingRequests.get(i)).piece == piece)
if (outstandingRequests.get(i).piece == piece)
return i;
return -1;
}
@@ -313,12 +310,12 @@ class PeerState
Request req;
synchronized(this)
{
req = (Request)outstandingRequests.get(r);
req = outstandingRequests.get(r);
while (req.piece == piece && req.off != begin
&& r < outstandingRequests.size() - 1)
{
r++;
req = (Request)outstandingRequests.get(r);
req = outstandingRequests.get(r);
}
// Something wrong?
@@ -342,7 +339,7 @@ class PeerState
+ ", wanted for peer: " + peer);
for (int i = 0; i < r; i++)
{
Request dropReq = (Request)outstandingRequests.remove(0);
Request dropReq = outstandingRequests.remove(0);
outstandingRequests.add(dropReq);
if (!choked)
out.sendRequest(dropReq);
@@ -366,11 +363,11 @@ class PeerState
{
Request req = null;
for (int i = 0; i < outstandingRequests.size(); i++) {
Request r1 = (Request)outstandingRequests.get(i);
Request r1 = outstandingRequests.get(i);
int j = getFirstOutstandingRequest(r1.piece);
if (j == -1)
continue;
Request r2 = (Request)outstandingRequests.get(j);
Request r2 = outstandingRequests.get(j);
if (r2.off > 0 && ((req == null) || (r2.off > req.off)))
req = r2;
}
@@ -398,7 +395,7 @@ class PeerState
}
Request req = null;
for (int i = 0; i < size; i++) {
Request r1 = (Request)outstandingRequests.get(i);
Request r1 = outstandingRequests.get(i);
if (pc != r1.piece) {
pc = r1.piece;
arr[pos++] = pc;
@@ -423,32 +420,19 @@ class PeerState
+ " length: " + bs.length);
}
/**
* We now have this piece.
* Tell the peer and cancel any requests for the piece.
*/
void havePiece(int piece)
{
if (_log.shouldLog(Log.DEBUG))
_log.debug("Tell " + peer + " havePiece(" + piece + ")");
synchronized(this)
{
// Tell the other side that we are no longer interested in any of
// the outstanding requests for this piece.
if (lastRequest != null && lastRequest.piece == piece)
lastRequest = null;
Iterator it = outstandingRequests.iterator();
while (it.hasNext())
{
Request req = (Request)it.next();
if (req.piece == piece)
{
it.remove();
// Send cancel even when we are choked to make sure that it is
// really never ever send.
out.sendCancel(req);
}
}
}
cancelPiece(piece);
// Tell the other side that we really have this piece.
out.sendHave(piece);
@@ -463,8 +447,46 @@ class PeerState
}
}
// Starts or resumes requesting pieces.
private void request()
/**
* Tell the other side that we are no longer interested in any of
* the outstanding requests (if any) for this piece.
* @since 0.8.1
*/
synchronized void cancelPiece(int piece) {
if (lastRequest != null && lastRequest.piece == piece)
lastRequest = null;
Iterator<Request> it = outstandingRequests.iterator();
while (it.hasNext())
{
Request req = it.next();
if (req.piece == piece)
{
it.remove();
// Send cancel even when we are choked to make sure that it is
// really never ever send.
out.sendCancel(req);
}
}
}
/**
* Are we currently requesting the piece?
* @since 0.8.1
*/
synchronized boolean isRequesting(int piece) {
for (Request req : outstandingRequests) {
if (req.piece == piece)
return true;
}
return false;
}
/**
* Starts or resumes requesting pieces.
* @param resend should we resend outstanding requests?
*/
private void request(boolean resend)
{
// Are there outstanding requests that have to be resend?
if (resend)
@@ -472,7 +494,6 @@ class PeerState
synchronized (this) {
out.sendRequests(outstandingRequests);
}
resend = false;
}
// Add/Send some more requests if necessary.
@@ -481,8 +502,11 @@ class PeerState
/**
* Adds a new request to the outstanding requests list.
* Then send interested if we weren't.
* Then send new requests if not choked.
* If nothing to request, send not interested if we were.
*/
synchronized private void addRequest()
synchronized void addRequest()
{
boolean more_pieces = true;
while (more_pieces)
@@ -526,6 +550,7 @@ class PeerState
/**
* Starts requesting first chunk of next piece. Returns true if
* something has been added to the requests, false otherwise.
* Caller should synchronize.
*/
private boolean requestNextPiece()
{
@@ -553,11 +578,10 @@ class PeerState
}
}
int nextPiece = listener.wantPiece(peer, bitfield);
if (_log.shouldLog(Log.DEBUG))
_log.debug(peer + " want piece " + nextPiece);
if (nextPiece != -1
&& (lastRequest == null || lastRequest.piece != nextPiece))
{
if (nextPiece != -1
&& (lastRequest == null || lastRequest.piece != nextPiece)) {
if (_log.shouldLog(Log.DEBUG))
_log.debug(peer + " want piece " + nextPiece);
// Fail safe to make sure we are interested
// When we transition into the end game we may not be interested...
if (!interesting) {
@@ -584,9 +608,25 @@ class PeerState
out.sendRequest(req);
lastRequest = req;
return true;
}
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug(peer + " no more pieces to request");
}
}
// failsafe
if (outstandingRequests.isEmpty())
lastRequest = null;
// If we are not in the end game, we may run out of things to request
// because we are asking other peers. Set not-interesting now rather than
// wait for those other requests to be satisfied via havePiece()
if (interesting && lastRequest == null) {
interesting = false;
out.sendInterest(false);
if (_log.shouldLog(Log.DEBUG))
_log.debug(peer + " nothing more to request, now uninteresting");
}
return false;
}
@@ -601,7 +641,7 @@ class PeerState
out.sendInterest(interest);
if (interesting && !choked)
request();
request(true); // we shouldnt have any pending requests, but if we do, resend them
}
}
@@ -627,4 +667,16 @@ class PeerState
if (interesting && !choked)
out.retransmitRequests(outstandingRequests);
}
/**
* debug
* @return string or null
* @since 0.8.1
*/
synchronized String getRequests() {
if (outstandingRequests.isEmpty())
return null;
else
return outstandingRequests.toString();
}
}

View File

@@ -1,22 +1,31 @@
package org.klomp.snark;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import net.i2p.util.ConcurrentHashSet;
public class Piece implements Comparable {
private int id;
private Set peers;
private Set<PeerID> peers;
private boolean requested;
/** @since 0.8.1 */
private int priority;
public Piece(int id) {
this.id = id;
this.peers = Collections.synchronizedSet(new HashSet());
this.requested = false;
this.peers = new ConcurrentHashSet();
}
/**
* Highest priority first,
* then rarest first
*/
public int compareTo(Object o) throws ClassCastException {
int pdiff = ((Piece)o).priority - this.priority; // reverse
if (pdiff != 0)
return pdiff;
return this.peers.size() - ((Piece)o).peers.size();
}
@@ -37,12 +46,25 @@ public class Piece implements Comparable {
}
public int getId() { return this.id; }
public Set getPeers() { return this.peers; }
/** @deprecated unused */
public Set<PeerID> getPeers() { return this.peers; }
public boolean addPeer(Peer peer) { return this.peers.add(peer.getPeerID()); }
public boolean removePeer(Peer peer) { return this.peers.remove(peer.getPeerID()); }
public boolean isRequested() { return this.requested; }
public void setRequested(boolean requested) { this.requested = requested; }
/** @return default 0 @since 0.8.1 */
public int getPriority() { return this.priority; }
/** @since 0.8.1 */
public void setPriority(int p) { this.priority = p; }
/** @since 0.8.1 */
public boolean isDisabled() { return this.priority < 0; }
/** @since 0.8.1 */
public void setDisabled() { this.priority = -1; }
@Override
public String toString() {
return String.valueOf(id);

View File

@@ -54,6 +54,7 @@ public class SnarkManager implements Snark.CompleteListener {
public static final String PROP_DIR = "i2psnark.dir";
public static final String PROP_META_PREFIX = "i2psnark.zmeta.";
public static final String PROP_META_BITFIELD_SUFFIX = ".bitfield";
public static final String PROP_META_PRIORITY_SUFFIX = ".priority";
private static final String CONFIG_FILE = "i2psnark.config";
public static final String PROP_AUTO_START = "i2snark.autoStart"; // oops
@@ -510,6 +511,7 @@ public class SnarkManager implements Snark.CompleteListener {
torrent = new Snark(_util, filename, null, -1, null, null, this,
_peerCoordinatorSet, _connectionAcceptor,
false, dataDir.getPath());
loadSavedFilePriorities(torrent);
torrent.completeListener = this;
synchronized (_snarks) {
_snarks.put(filename, torrent);
@@ -587,6 +589,33 @@ public class SnarkManager implements Snark.CompleteListener {
return new BitField(bitfield, len);
}
/**
* Get the saved priorities for a torrent from the config file.
* @since 0.8.1
*/
public void loadSavedFilePriorities(Snark snark) {
MetaInfo metainfo = snark.meta;
if (metainfo.getFiles() == null)
return;
byte[] ih = metainfo.getInfoHash();
String infohash = Base64.encode(ih);
infohash = infohash.replace('=', '$');
String pri = _config.getProperty(PROP_META_PREFIX + infohash + PROP_META_PRIORITY_SUFFIX);
if (pri == null)
return;
int filecount = metainfo.getFiles().size();
int[] rv = new int[filecount];
String[] arr = pri.split(",");
for (int i = 0; i < filecount && i < arr.length; i++) {
if (arr[i].length() > 0) {
try {
rv[i] = Integer.parseInt(arr[i]);
} catch (Throwable t) {}
}
}
snark.storage.setFilePriorities(rv);
}
/**
* Save the completion status of a torrent and the current time in the config file
* in the form "i2psnark.zmeta.$base64infohash=$time,$base64bitfield".
@@ -595,8 +624,9 @@ public class SnarkManager implements Snark.CompleteListener {
* The time is a standard long converted to string.
* The status is either a bitfield converted to Base64 or "." for a completed
* torrent to save space in the config file and in memory.
* @param priorities may be null
*/
public void saveTorrentStatus(MetaInfo metainfo, BitField bitfield) {
public void saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities) {
byte[] ih = metainfo.getInfoHash();
String infohash = Base64.encode(ih);
infohash = infohash.replace('=', '$');
@@ -609,6 +639,34 @@ public class SnarkManager implements Snark.CompleteListener {
bfs = Base64.encode(bf);
}
_config.setProperty(PROP_META_PREFIX + infohash + PROP_META_BITFIELD_SUFFIX, now + "," + bfs);
// now the file priorities
String prop = PROP_META_PREFIX + infohash + PROP_META_PRIORITY_SUFFIX;
if (priorities != null) {
boolean nonzero = false;
for (int i = 0; i < priorities.length; i++) {
if (priorities[i] != 0) {
nonzero = true;
break;
}
}
if (nonzero) {
// generate string like -5,,4,3,,,,,,-2 where no number is zero.
StringBuilder buf = new StringBuilder(2 * priorities.length);
for (int i = 0; i < priorities.length; i++) {
if (priorities[i] != 0)
buf.append(Integer.toString(priorities[i]));
if (i != priorities.length - 1)
buf.append(',');
}
_config.setProperty(prop, buf.toString());
} else {
_config.remove(prop);
}
} else {
_config.remove(prop);
}
saveConfig();
}
@@ -621,6 +679,7 @@ public class SnarkManager implements Snark.CompleteListener {
String infohash = Base64.encode(ih);
infohash = infohash.replace('=', '$');
_config.remove(PROP_META_PREFIX + infohash + PROP_META_BITFIELD_SUFFIX);
_config.remove(PROP_META_PREFIX + infohash + PROP_META_PRIORITY_SUFFIX);
saveConfig();
}
@@ -742,7 +801,7 @@ public class SnarkManager implements Snark.CompleteListener {
}
public void updateStatus(Snark snark) {
saveTorrentStatus(snark.meta, snark.storage.getBitField());
saveTorrentStatus(snark.meta, snark.storage.getBitField(), snark.storage.getFilePriorities());
}
private void monitorTorrents(File dir) {
@@ -823,7 +882,7 @@ public class SnarkManager implements Snark.CompleteListener {
// , "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"
, "CRSTRACK", "http://b4G9sCdtfvccMAXh~SaZrPqVQNyGQbhbYMbw6supq2XGzbjU4NcOmjFI0vxQ8w1L05twmkOvg5QERcX6Mi8NQrWnR0stLExu2LucUXg1aYjnggxIR8TIOGygZVIMV3STKH4UQXD--wz0BUrqaLxPhrm2Eh9Hwc8TdB6Na4ShQUq5Xm8D4elzNUVdpM~RtChEyJWuQvoGAHY3ppX-EJJLkiSr1t77neS4Lc-KofMVmgI9a2tSSpNAagBiNI6Ak9L1T0F9uxeDfEG9bBSQPNMOSUbAoEcNxtt7xOW~cNOAyMyGydwPMnrQ5kIYPY8Pd3XudEko970vE0D6gO19yoBMJpKx6Dh50DGgybLQ9CpRaynh2zPULTHxm8rneOGRcQo8D3mE7FQ92m54~SvfjXjD2TwAVGI~ae~n9HDxt8uxOecAAvjjJ3TD4XM63Q9TmB38RmGNzNLDBQMEmJFpqQU8YeuhnS54IVdUoVQFqui5SfDeLXlSkh4vYoMU66pvBfWbAAAA.i2p/tracker/announce.php=http://crstrack.i2p/tracker/"
// , "CRSTRACK", "http://b4G9sCdtfvccMAXh~SaZrPqVQNyGQbhbYMbw6supq2XGzbjU4NcOmjFI0vxQ8w1L05twmkOvg5QERcX6Mi8NQrWnR0stLExu2LucUXg1aYjnggxIR8TIOGygZVIMV3STKH4UQXD--wz0BUrqaLxPhrm2Eh9Hwc8TdB6Na4ShQUq5Xm8D4elzNUVdpM~RtChEyJWuQvoGAHY3ppX-EJJLkiSr1t77neS4Lc-KofMVmgI9a2tSSpNAagBiNI6Ak9L1T0F9uxeDfEG9bBSQPNMOSUbAoEcNxtt7xOW~cNOAyMyGydwPMnrQ5kIYPY8Pd3XudEko970vE0D6gO19yoBMJpKx6Dh50DGgybLQ9CpRaynh2zPULTHxm8rneOGRcQo8D3mE7FQ92m54~SvfjXjD2TwAVGI~ae~n9HDxt8uxOecAAvjjJ3TD4XM63Q9TmB38RmGNzNLDBQMEmJFpqQU8YeuhnS54IVdUoVQFqui5SfDeLXlSkh4vYoMU66pvBfWbAAAA.i2p/tracker/announce.php=http://crstrack.i2p/tracker/"
};
/** comma delimited list of name=announceURL=baseURL for the trackers to be displayed */

View File

@@ -42,6 +42,8 @@ public class Storage
private Object[] RAFlock; // lock on RAF access
private long[] RAFtime; // when was RAF last accessed, or 0 if closed
private File[] RAFfile; // File to make it easier to reopen
/** priorities by file; default 0; may be null. @since 0.8.1 */
private int[] priorities;
private final StorageListener listener;
private I2PSnarkUtil _util;
@@ -228,6 +230,8 @@ public class Storage
RAFlock = new Object[size];
RAFtime = new long[size];
RAFfile = new File[size];
priorities = new int[size];
int i = 0;
Iterator it = files.iterator();
@@ -330,6 +334,102 @@ public class Storage
return -1;
}
/**
* @param file canonical path (non-directory)
* @since 0.8.1
*/
public int getPriority(String file) {
if (complete() || metainfo.getFiles() == null || priorities == null)
return 0;
for (int i = 0; i < rafs.length; i++) {
File f = RAFfile[i];
// use canonical in case snark dir or sub dirs are symlinked
if (f != null) {
try {
String canonical = f.getCanonicalPath();
if (canonical.equals(file))
return priorities[i];
} catch (IOException ioe) {}
}
}
return 0;
}
/**
* Must call setPiecePriorities() after calling this
* @param file canonical path (non-directory)
* @param pri default 0; <0 to disable
* @since 0.8.1
*/
public void setPriority(String file, int pri) {
if (complete() || metainfo.getFiles() == null || priorities == null)
return;
for (int i = 0; i < rafs.length; i++) {
File f = RAFfile[i];
// use canonical in case snark dir or sub dirs are symlinked
if (f != null) {
try {
String canonical = f.getCanonicalPath();
if (canonical.equals(file)) {
priorities[i] = pri;
return;
}
} catch (IOException ioe) {}
}
}
}
/**
* Get the file priorities array.
* @return null on error, if complete, or if only one file
* @since 0.8.1
*/
public int[] getFilePriorities() {
return priorities;
}
/**
* Set the file priorities array.
* Only call this when stopped, but after check()
* @param p may be null
* @since 0.8.1
*/
void setFilePriorities(int[] p) {
priorities = p;
}
/**
* Call setPriority() for all changed files first,
* then call this.
* Set the piece priority to the highest priority
* of all files spanning the piece.
* Caller must pass array to the PeerCoordinator.
* @return null on error, if complete, or if only one file
* @since 0.8.1
*/
public int[] getPiecePriorities() {
if (complete() || metainfo.getFiles() == null || priorities == null)
return null;
int[] rv = new int[metainfo.getPieces()];
int file = 0;
long pcEnd = -1;
long fileEnd = lengths[0] - 1;
int psz = metainfo.getPieceLength(0);
for (int i = 0; i < rv.length; i++) {
pcEnd += psz;
int pri = priorities[file];
while (fileEnd <= pcEnd && file < lengths.length - 1) {
file++;
long oldFileEnd = fileEnd;
fileEnd += lengths[file];
if (priorities[file] > pri && oldFileEnd < pcEnd)
pri = priorities[file];
}
rv[i] = pri;
}
return rv;
}
/**
* The BitField that tells which pieces this storage contains.
* Do not change this since this is the current state of the storage.
@@ -436,10 +536,14 @@ public class Storage
changed = true;
checkCreateFiles();
}
if (complete())
if (complete()) {
_util.debug("Torrent is complete", Snark.NOTICE);
else
} else {
// fixme saved priorities
if (files != null)
priorities = new int[files.size()];
_util.debug("Still need " + needed + " out of " + metainfo.getPieces() + " pieces", Snark.NOTICE);
}
}
/**
@@ -565,6 +669,10 @@ public class Storage
changed = true;
synchronized(RAFlock[i]) {
allocateFile(i);
// close as we go so we don't run out of file descriptors
try {
closeRAF(i);
} catch (IOException ioe) {}
}
} else {
_util.debug("File '" + names[i] + "' exists, but has wrong length - repairing corruption", Snark.ERROR);
@@ -573,8 +681,10 @@ public class Storage
synchronized(RAFlock[i]) {
checkRAF(i);
rafs[i].setLength(lengths[i]);
try {
closeRAF(i);
} catch (IOException ioe) {}
}
// will be closed below
}
}
@@ -583,10 +693,25 @@ public class Storage
{
pieces = metainfo.getPieces();
byte[] piece = new byte[metainfo.getPieceLength(0)];
int file = 0;
long fileEnd = lengths[0];
long pieceEnd = 0;
for (int i = 0; i < pieces; i++)
{
int length = getUncheckedPiece(i, piece);
boolean correctHash = metainfo.checkPiece(i, piece, 0, length);
// close as we go so we don't run out of file descriptors
pieceEnd += length;
while (fileEnd <= pieceEnd) {
synchronized(RAFlock[file]) {
try {
closeRAF(file);
} catch (IOException ioe) {}
}
if (++file >= rafs.length)
break;
fileEnd += lengths[file];
}
if (correctHash)
{
bitfield.set(i);
@@ -601,13 +726,14 @@ public class Storage
_probablyComplete = complete();
// close all the files so we don't end up with a zillion open ones;
// we will reopen as needed
for (int i = 0; i < rafs.length; i++) {
synchronized(RAFlock[i]) {
try {
closeRAF(i);
} catch (IOException ioe) {}
}
}
// Now closed above to avoid running out of file descriptors
//for (int i = 0; i < rafs.length; i++) {
// synchronized(RAFlock[i]) {
// try {
// closeRAF(i);
// } catch (IOException ioe) {}
// }
//}
if (listener != null) {
listener.storageAllChecked(this);
@@ -616,6 +742,7 @@ public class Storage
}
}
/** this calls openRAF(); caller must synnchronize and call closeRAF() */
private void allocateFile(int nr) throws IOException
{
// caller synchronized
@@ -624,7 +751,12 @@ public class Storage
// the whole file?
listener.storageCreateFile(this, names[nr], lengths[nr]);
final int ZEROBLOCKSIZE = metainfo.getPieceLength(0);
byte[] zeros = new byte[ZEROBLOCKSIZE];
byte[] zeros;
try {
zeros = new byte[ZEROBLOCKSIZE];
} catch (OutOfMemoryError oom) {
throw new IOException(oom.toString());
}
int i;
for (i = 0; i < lengths[nr]/ZEROBLOCKSIZE; i++)
{

View File

@@ -266,9 +266,9 @@ public class TrackerClient extends I2PAppThread
// we only want to talk to new people if we need things
// from them (duh)
List ordered = new ArrayList(peers);
Collections.shuffle(ordered);
Collections.shuffle(ordered, r);
Iterator it = ordered.iterator();
while (it.hasNext()) {
while ((!stop) && it.hasNext()) {
Peer cur = (Peer)it.next();
// FIXME if id == us || dest == us continue;
// only delay if we actually make an attempt to add peer
@@ -357,7 +357,7 @@ public class TrackerClient extends I2PAppThread
+ "&uploaded=" + uploaded
+ "&downloaded=" + downloaded
+ "&left=" + left
+ "&compact"
+ "&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";

View File

@@ -133,6 +133,7 @@ public class I2PSnarkServlet extends Default {
// bypass the horrid Resource.getListHTML()
String pathInfo = req.getPathInfo();
String pathInContext = URI.addPaths(path, pathInfo);
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html; charset=UTF-8");
Resource resource = getResource(pathInContext);
@@ -140,7 +141,7 @@ public class I2PSnarkServlet extends Default {
resp.sendError(HttpResponse.__404_Not_Found);
} else {
String base = URI.addPaths(req.getRequestURI(), "/");
String listing = getListHTML(resource, base, true);
String listing = getListHTML(resource, base, true, method.equals("POST") ? req.getParameterMap() : null);
if (listing != null)
resp.getWriter().write(listing);
else // shouldn't happen
@@ -241,32 +242,32 @@ public class I2PSnarkServlet extends Default {
out.write(TABLE_HEADER);
out.write("<img border=\"0\" src=\"/themes/snark/ubergine/images/status.png\"");
out.write(" title=\"");
out.write(_("Torrent Status"));
out.write("\">");
out.write(_("Status"));
out.write("\"> ");
out.write(_("Status"));
if (_manager.util().connected() && !snarks.isEmpty()) {
out.write("<a href=\"");
out.write(" <a href=\"");
out.write(req.getRequestURI());
if (peerParam != null) {
out.write("\">");
out.write("<img border=\"0\" src=\"/themes/snark/ubergine/images/showpeers.png\" title=\"");
out.write(_("Toggle Peer Visibility"));
out.write("\" alt=\"");
out.write(_("Hide Peers"));
out.write("\">");
out.write("<img border=\"0\" src=\"/themes/snark/ubergine/images/showpeers.png\" title=\"");
out.write(_("Hide Peers"));
out.write("\" alt=\"");
out.write(_("Hide Peers"));
out.write("\">");
} else {
out.write("?p=1\">");
out.write("<img border=\"0\" src=\"/themes/snark/ubergine/images/hidepeers.png\" title=\"");
out.write(_("Toggle Peer Visibility"));
out.write("\" alt=\"");
out.write(_("Show Peers"));
out.write("\">");
out.write("<img border=\"0\" src=\"/themes/snark/ubergine/images/hidepeers.png\" title=\"");
out.write(_("Show Peers"));
out.write("\" alt=\"");
out.write(_("Show Peers"));
out.write("\">");
}
out.write("</a><br>\n");
}
out.write("</th>\n<th align=\"left\">");
out.write("<img border=\"0\" src=\"/themes/snark/ubergine/images/torrent.png\" title=\"");
out.write(_("Loaded Torrents"));
out.write(_("Torrent"));
out.write("\">");
out.write(_("Torrent"));
out.write("</th>\n<th align=\"center\">");
@@ -276,21 +277,21 @@ public class I2PSnarkServlet extends Default {
out.write(_("ETA"));
out.write("</th>\n<th align=\"center\">");
out.write("<img border=\"0\" src=\"/themes/console/images/inbound.png\" title=\"");
out.write(_("Data Downloaded"));
out.write(_("Downloaded"));
out.write("\">");
out.write(_("RX"));
out.write("</th>\n<th align=\"center\">");
out.write("<img border=\"0\" src=\"/themes/console/images/outbound.png\" title=\"");
out.write(_("Data Uploaded"));
out.write(_("Uploaded"));
out.write("\">");
out.write(_("TX"));
out.write("</th>\n<th align=\"center\">");
out.write("<img border=\"0\" src=\"/themes/console/images/inbound.png\" title=\"");
out.write(_("Download Speed"));
out.write(_("Down Rate"));
out.write("\">Rate");
out.write("</th>\n<th align=\"center\">");
out.write("<img border=\"0\" src=\"/themes/console/images/outbound.png\" title=\"");
out.write(_("Upload Speed"));
out.write(_("Up Rate"));
out.write("\">");
out.write(_("Rate"));
out.write("</th>\n");
@@ -301,7 +302,7 @@ public class I2PSnarkServlet extends Default {
out.write(_("Stop all torrents and the I2P tunnel"));
out.write("\">");
out.write("<img src=\"/themes/snark/ubergine/images/stop_all.png\" title=\"");
out.write(_("Stop All Torrents"));
out.write(_("Stop all torrents and the I2P tunnel"));
out.write("\" alt=\"");
out.write(_("Stop All"));
out.write("\">");
@@ -312,7 +313,7 @@ public class I2PSnarkServlet extends Default {
out.write(_("Start all torrents and the I2P tunnel"));
out.write("\">");
out.write("<img src=\"/themes/snark/ubergine/images/start_all.png\" title=\"");
out.write(_("Start All Torrents"));
out.write(_("Start all torrents and the I2P tunnel"));
out.write("\" alt=\"Start All\">");
out.write("</a>");
} else {
@@ -537,7 +538,7 @@ public class I2PSnarkServlet extends Default {
File torrentFile = new File(baseFile.getParent(), baseFile.getName() + ".torrent");
if (torrentFile.exists())
throw new IOException("Cannot overwrite an existing .torrent file: " + torrentFile.getPath());
_manager.saveTorrentStatus(info, s.getBitField()); // so addTorrent won't recheck
_manager.saveTorrentStatus(info, s.getBitField(), null); // so addTorrent won't recheck
// DirMonitor could grab this first, maybe hold _snarks lock?
FileOutputStream out = new FileOutputStream(torrentFile);
out.write(info.getTorrentData());
@@ -564,6 +565,8 @@ public class I2PSnarkServlet extends Default {
_manager.stopTorrent(snark.torrent, false);
}
if (_manager.util().connected()) {
// Give the stopped announces time to get out
try { Thread.sleep(2000); } catch (InterruptedException ie) {}
_manager.util().disconnect();
_manager.addMessage(_("I2P tunnel closed."));
}
@@ -695,55 +698,55 @@ public class I2PSnarkServlet extends Default {
if (isRunning && curPeers > 0 && !showPeers)
statusString = "<img border=\"0\" src=\"/themes/snark/ubergine/images/trackererror.png\" title=\"" + _("Tracker Error") +
"\"><a href=\"" + uri + "?p=" + Base64.encode(snark.meta.getInfoHash()) + "\">" +
curPeers + '/' +
' ' + curPeers + "&thinsp;/&thinsp;" +
ngettext("1 peer", "{0} peers", knownPeers) + "</a>";
else if (isRunning)
statusString = "<img border=\"0\" src=\"/themes/snark/ubergine/images/trackererror.png\" title=\"" + _("Tracker Error") +
"\">" + curPeers + '/' +
"\">" + ' ' + curPeers + "&thinsp;/&thinsp;" +
ngettext("1 peer", "{0} peers", knownPeers) + "</a>";
else {
if (err.length() > MAX_DISPLAYED_ERROR_LENGTH)
err = err.substring(0, MAX_DISPLAYED_ERROR_LENGTH) + "&hellip;";
statusString = "<img border=\"0\" src=\"/themes/snark/ubergine/images/trackererror.png\" title=\"" + _("Tracker Error") +
"\">" + err + "</a>";
"\"> " + err + "</a>";
}
} else if (remaining <= 0) {
if (isRunning && curPeers > 0 && !showPeers)
statusString = "<img border=\"0\" src=\"/themes/snark/ubergine/images/seeding.png\" title=\"" + _("Seeding") + "\">" +
"<a href=\"" + uri + "?p=" + Base64.encode(snark.meta.getInfoHash()) + "\">" +
curPeers + '/' +
' ' + curPeers + "&thinsp;/&thinsp;" +
ngettext("1 peer", "{0} peers", knownPeers) + "</a>";
else if (isRunning)
statusString = "<img border=\"0\" src=\"/themes/snark/ubergine/images/seeding.png\" title=\"" + _("Seeding") + "\">" +
curPeers + "/" +
' ' + curPeers + "&thinsp;/&thinsp;" +
ngettext("1 peer", "{0} peers", knownPeers) + "</a>";
else
statusString = "<img border=\"0\" src=\"/themes/snark/ubergine/images/complete.png\" title=\"" + _("Complete") + "\">" + _("Not Seeding");
statusString = "<img border=\"0\" src=\"/themes/snark/ubergine/images/complete.png\" title=\"" + _("Complete") + "\"> " + _("Complete");
} else {
if (isRunning && curPeers > 0 && downBps > 0 && !showPeers)
statusString = "<img border=\"0\" src=\"/themes/snark/ubergine/images/downloading.png\" title=\"" + _("Downloading") + "\">" +
"<a href=\"" + uri + "?p=" + Base64.encode(snark.meta.getInfoHash()) + "\">" +
curPeers + "/" +
' ' + curPeers + "&thinsp;/&thinsp;" +
ngettext("1 peer", "{0} peers", knownPeers) + "</a>";
else if (isRunning && curPeers > 0 && downBps > 0)
statusString = "<img border=\"0\" src=\"/themes/snark/ubergine/images/downloading.png\" title=\"" + _("Downloading") + "\">" +
" (" + curPeers + "/" +
' ' + curPeers + "&thinsp;/&thinsp;" +
ngettext("1 peer", "{0} peers", knownPeers);
else if (isRunning && curPeers > 0 && !showPeers)
statusString = "<img border=\"0\" src=\"/themes/snark/ubergine/images/stalled.png\" title=\"" + _("Stalled") + "\">" +
"<a href=\"" + uri + "?p=" + Base64.encode(snark.meta.getInfoHash()) + "\">" +
curPeers + '/' +
' ' + curPeers + "&thinsp;/&thinsp;" +
ngettext("1 peer", "{0} peers", knownPeers) + "</a>";
else if (isRunning && curPeers > 0)
statusString = "<img border=\"0\" src=\"/themes/snark/ubergine/images/stalled.png\" title=\"" + _("Stalled") + "\">" +
curPeers + '/' +
' ' + curPeers + "&thinsp;/&thinsp;" +
ngettext("1 peer", "{0} peers", knownPeers);
else if (isRunning)
statusString = "<img border=\"0\" src=\"/themes/snark/ubergine/images/nopeers.png\" title=\"" + _("No Peers") + "\">" +
curPeers + "/" +
' ' + curPeers + "&thinsp;/&thinsp;" +
ngettext("1 peer", "{0} peers", knownPeers);
else
statusString = "<img border=\"0\" src=\"/themes/snark/ubergine/images/stopped.png\" title=\"" + _("Stopped") + "\">" + _("Stopped");
statusString = "<img border=\"0\" src=\"/themes/snark/ubergine/images/stopped.png\" title=\"" + _("Stopped") + "\"> " + _("Stopped");
}
String rowClass = (row % 2 == 0 ? "snarkTorrentEven" : "snarkTorrentOdd");
@@ -790,7 +793,7 @@ public class I2PSnarkServlet extends Default {
baseURL = baseURL.substring(e + 1);
out.write("&nbsp;<a href=\"" + baseURL + "details.php?dllist=1&filelist=1&info_hash=");
out.write(TrackerClient.urlencode(snark.meta.getInfoHash()));
out.write("\" title=\"" + name + _("Tracker") + "\" target=\"_blank\">");
out.write("\" title=\"" + name + ' ' + _("Tracker") + "\" target=\"_blank\">");
out.write("<img border=\"0\" src=\"/themes/snark/ubergine/images/details.png\">");
out.write("</a>");
break;
@@ -804,7 +807,7 @@ public class I2PSnarkServlet extends Default {
out.write("</td>\n\t");
out.write("<td align=\"right\" class=\"snarkTorrentDownloaded " + rowClass + "\">");
if (remaining > 0)
out.write(formatSize(total-remaining) + "/" + formatSize(total)); // 18MB/3GB
out.write(formatSize(total-remaining) + "&thinsp;/&thinsp;" + formatSize(total)); // 18MB/3GB; thin space so it will line break well
else
out.write(formatSize(total)); // 3GB
out.write("</td>\n\t");
@@ -828,7 +831,7 @@ public class I2PSnarkServlet extends Default {
out.write(_("Stop the torrent"));
out.write("\">");
out.write("<img src=\"/themes/snark/ubergine/images/stop.png\" title=\"");
out.write(_("Stop Torrent"));
out.write(_("Stop the torrent"));
out.write("\" alt=\"");
out.write(_("Stop"));
out.write("\">");
@@ -840,7 +843,7 @@ public class I2PSnarkServlet extends Default {
out.write(_("Start the torrent"));
out.write("\">");
out.write("<img src=\"/themes/snark/ubergine/images/start.png\" title=\"");
out.write(_("Start Torrent"));
out.write(_("Start the torrent"));
out.write("\" alt=\"");
out.write(_("Start"));
out.write("\">");
@@ -856,7 +859,7 @@ public class I2PSnarkServlet extends Default {
out.write(_("Are you sure you want to delete the file \\''{0}.torrent\\'' (downloaded data will not be deleted) ?", fullFilename));
out.write("')) { return false; }\">");
out.write("<img src=\"/themes/snark/ubergine/images/remove.png\" title=\"");
out.write(_("Remove Torrent"));
out.write(_("Remove the torrent from the active list, deleting the .torrent file"));
out.write("\" alt=\"");
out.write(_("Remove"));
out.write("\">");
@@ -871,7 +874,7 @@ public class I2PSnarkServlet extends Default {
out.write(_("Are you sure you want to delete the torrent \\''{0}\\'' and all downloaded data?", fullFilename));
out.write("')) { return false; }\">");
out.write("<img src=\"/themes/snark/ubergine/images/delete.png\" title=\"");
out.write(_("Delete Torrent + Data"));
out.write(_("Delete the .torrent file and the associated data file(s)"));
out.write("\" alt=\"");
out.write(_("Delete"));
out.write("\">");
@@ -1007,7 +1010,7 @@ public class I2PSnarkServlet extends Default {
out.write(_("Add torrent"));
out.write("\" name=\"foo\" ><br>\n");
out.write("<tr><td>&nbsp;<td><span class=\"snarkAddInfo\">");
out.write(_("You can also copy .torrent files to: {0}.", "<code>" + _manager.getDataDir().getAbsolutePath ())) + "</code>";
out.write(_("You can also copy .torrent files to: {0}.", "<code>" + _manager.getDataDir().getAbsolutePath () + "</code>"));
out.write("\n");
out.write(_("Removing a .torrent will cause it to stop."));
out.write("<br></span></table>\n");
@@ -1262,19 +1265,21 @@ public class I2PSnarkServlet extends Default {
// rounding makes us look faster :)
private static String formatSize(long bytes) {
if (bytes < 5*1024)
return bytes + " B";
return bytes + "&nbsp;B";
else if (bytes < 5*1024*1024)
return ((bytes + 512)/1024) + " KB";
return ((bytes + 512)/1024) + "&nbsp;KB";
else if (bytes < 10*1024*1024*1024l)
return ((bytes + 512*1024)/(1024*1024)) + " MB";
return ((bytes + 512*1024)/(1024*1024)) + "&nbsp;MB";
else
return ((bytes + 512*1024*1024)/(1024*1024*1024)) + " GB";
return ((bytes + 512*1024*1024)/(1024*1024*1024)) + "&nbsp;GB";
}
/** @since 0.7.14 */
private static String urlify(String s) {
StringBuilder buf = new StringBuilder(256);
buf.append("<a href=\"").append(s).append("\">").append(s).append("</a>");
// browsers seem to work without doing this but let's be strict
String link = s.replace("&", "&amp;");
buf.append("<a href=\"").append(link).append("\">").append(link).append("</a>");
return buf.toString();
}
@@ -1313,10 +1318,11 @@ public class I2PSnarkServlet extends Default {
* @param r The Resource
* @param base The base URL
* @param parent True if the parent directory should be included
* @param postParams map of POST parameters or null if not a POST
* @return String of HTML
* @since 0.7.14
*/
private String getListHTML(Resource r, String base, boolean parent)
private String getListHTML(Resource r, String base, boolean parent, Map postParams)
throws IOException
{
if (!r.isDirectory())
@@ -1341,19 +1347,40 @@ public class I2PSnarkServlet extends Default {
else
torrentName = title;
Snark snark = _manager.getTorrentByBaseName(torrentName);
if (snark != null && postParams != null)
savePriorities(snark, postParams);
if (title.endsWith("/"))
title = title.substring(0, title.length() - 1);
title = _("Torrent") + ": " + title;
buf.append(title);
buf.append("</TITLE>").append(HEADER).append("<link rel=\"shortcut icon\" href=\"/themes/snark/ubergine/favicon.ico\"></HEAD><BODY>\n<center><div class=\"snarknavbar\"> <a href=\"/i2psnark/\" title=\"Torrents\"");
buf.append(" class=\"snarkRefresh\">I2PSnark</a>").append("</div>");
buf.append("<div class=\"page\"><div class=\"mainsection\">" +
"<TABLE BORDER=0 class=\"snarkTorrents\" cellpadding=\"5px 10px\">" +
if (parent)
{
buf.append("\n<br><A HREF=\"");
// corrupts utf-8
//buf.append(URI.encodePath(URI.addPaths(base,"../")));
buf.append(URI.addPaths(base,"../"));
buf.append("\"><img border=\"0\" src=\"/themes/console/images/outbound.png\"> ")
.append(_("Up to higher level directory")).append("</A>\n");
}
buf.append("</div><div class=\"page\"><div class=\"mainsection\">");
boolean showPriority = snark != null && !snark.storage.complete();
if (showPriority)
buf.append("<form action=\"").append(base).append("\" method=\"POST\">\n");
buf.append("<TABLE BORDER=0 class=\"snarkTorrents\" cellpadding=\"5px 10px\">" +
"<thead><tr><th>").append("<img border=\"0\" src=\"/themes/snark/ubergine/images/file.png\" title=\"").append(_("File")).append("\" alt=\"").append(_("File")).append("\">&nbsp;").append(title).append("</th><th align=\"right\">").append("<img border=\"0\" src=\"/themes/snark/ubergine/images/size.png\" title=\"").append(_("FileSize")).append("\" alt=\"").append(_("FileSize")).append("\">").append(_("Size"));
buf.append("</th><th>").append("<img border=\"0\" src=\"/themes/snark/ubergine/images/status.png\" title=\"").append(_("Download Status")).append("\">").append(_("Status")).append("</th></tr></thead>");
buf.append("</th><th>").append("<img border=\"0\" src=\"/themes/snark/ubergine/images/status.png\" title=\"").append(_("Download Status")).append("\">").append(_("Status")).append("</th>");
if (showPriority)
buf.append("<th>").append(_("Priority")).append("</th>");
buf.append("</tr></thead>\n");
//DateFormat dfmt=DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
// DateFormat.MEDIUM);
boolean showSaveButton = false;
for (int i=0 ; i< ls.length ; i++)
{
String encoded=URI.encodePath(ls[i]);
@@ -1391,7 +1418,8 @@ public class I2PSnarkServlet extends Default {
complete = true;
status = toImg("tick") + _("Complete");
} else {
status = toImg("clock") +
status =
(snark.storage.getPriority(f.getCanonicalPath()) < 0 ? toImg("cancel") : toImg("clock")) +
(100 * (length - remaining) / length) + "% " + _("complete") +
" (" + DataHelper.formatSize2(remaining) + _("bytes remaining") + ")";
}
@@ -1435,22 +1463,41 @@ public class I2PSnarkServlet extends Default {
buf.append("</TD><TD class=\"").append(rowClass).append(" snarkFileStatus\">");
//buf.append(dfmt.format(new Date(item.lastModified())));
buf.append(status);
buf.append("</TD></TR>\n");
buf.append("</TD>");
if (showPriority) {
buf.append("<td>");
File f = item.getFile();
if ((!complete) && (!item.isDirectory()) && f != null) {
int pri = snark.storage.getPriority(f.getCanonicalPath());
buf.append("<input type=\"radio\" value=\"5\" name=\"pri.").append(f.getCanonicalPath()).append("\" ");
if (pri > 0)
buf.append("checked=\"true\"");
buf.append('>').append(_("High"));
buf.append("<input type=\"radio\" value=\"0\" name=\"pri.").append(f.getCanonicalPath()).append("\" ");
if (pri == 0)
buf.append("checked=\"true\"");
buf.append('>').append(_("Normal"));
buf.append("<input type=\"radio\" value=\"-9\" name=\"pri.").append(f.getCanonicalPath()).append("\" ");
if (pri < 0)
buf.append("checked=\"true\"");
buf.append('>').append(_("Do not download"));
showSaveButton = true;
}
buf.append("</td>");
}
buf.append("</TR>\n");
}
if (parent)
{
buf.append("<tfoot align=\"left\"><tr><td colspan=\"3\"><A HREF=\"");
// corrupts utf-8
//buf.append(URI.encodePath(URI.addPaths(base,"../")));
buf.append(URI.addPaths(base,"../"));
buf.append("\"><img border=\"0\" src=\"/themes/snark/ubergine/images/up.png\"> ")
.append(_("Up to higher level directory")).append("</A></td></tr></thead>\n");
if (showSaveButton) {
buf.append("<thead><tr><th colspan=\"3\">&nbsp;</th><th align=\"center\"><input type=\"submit\" value=\"");
buf.append(_("Save priorities"));
buf.append("\" name=\"foo\" ></th></tr></thead>\n");
}
buf.append("</TABLE>\n");
buf.append("</div></div></center></BODY></HTML>\n");
if (showPriority)
buf.append("</form>");
buf.append("</div></div></BODY></HTML>\n");
return buf.toString();
}
@@ -1494,7 +1541,8 @@ buf.append("</div></div></center></BODY></HTML>\n");
plc.endsWith(".ape"))
icon = "music";
else if (mime.startsWith("video/") || plc.endsWith(".mkv") || plc.endsWith(".m4v") ||
plc.endsWith(".mp4") || plc.endsWith(".wmv") || plc.endsWith(".flv"))
plc.endsWith(".mp4") || plc.endsWith(".wmv") || plc.endsWith(".flv") ||
plc.endsWith(".ogm"))
icon = "film";
else if (mime.equals("application/zip") || mime.equals("application/x-gtar") ||
mime.equals("application/compress") || mime.equals("application/gzip") ||
@@ -1515,6 +1563,26 @@ buf.append("</div></div></center></BODY></HTML>\n");
return "<img alt=\"\" height=\"16\" width=\"16\" src=\"/i2psnark/_icons/" + icon + ".png\"> ";
}
/** @since 0.8.1 */
private void savePriorities(Snark snark, Map postParams) {
Set<Map.Entry> entries = postParams.entrySet();
for (Map.Entry entry : entries) {
String key = (String)entry.getKey();
if (key.startsWith("pri.")) {
try {
String file = key.substring(4);
String val = ((String[])entry.getValue())[0]; // jetty arrays
int pri = Integer.parseInt(val);
snark.storage.setPriority(file, pri);
//System.err.println("Priority now " + pri + " for " + file);
} catch (Throwable t) { t.printStackTrace(); }
}
}
if (snark.coordinator != null)
snark.coordinator.updatePiecePriorities();
_manager.saveTorrentStatus(snark.storage.getMetaInfo(), snark.storage.getBitField(), snark.storage.getFilePriorities());
}
/** inner class, don't bother reindenting */
private static class FetchAndAdd implements Runnable {

View File

@@ -9,8 +9,8 @@ msgstr ""
"Project-Id-Version: I2P i2psnark\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-07-08 08:03+0000\n"
"PO-Revision-Date: 2010-07-08 10:15+0100\n"
"Last-Translator: echelon <echelon@i2pmail.org>\n"
"PO-Revision-Date: 2010-11-04 23:34+0100\n"
"Last-Translator: \n"
"Language-Team: foo <foo@bar>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -25,27 +25,27 @@ msgstr "Füge Torrents in {0} Minuten hinzu"
#: ../java/src/org/klomp/snark/SnarkManager.java:258
#, java-format
msgid "Total uploaders limit changed to {0}"
msgstr "Totale Anzahl an Uploadslots geändert auf {0}"
msgstr "Gesamtanzahl an Uploadslots geändert auf {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:260
#, java-format
msgid "Minimum total uploaders limit is {0}"
msgstr "Minimale Anzahl and Uploadslots ist {0}"
msgstr "Minimale Anzahl an Uploadslots ist {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:272
#, java-format
msgid "Up BW limit changed to {0}KBps"
msgstr "Upload Bandbreite wurde geändert auf {0}kbyte/s"
msgstr "Upload Bandbreite wurde auf {0}kbyte/s geändert."
#: ../java/src/org/klomp/snark/SnarkManager.java:274
#, java-format
msgid "Minimum up bandwidth limit is {0}KBps"
msgstr "Minimales upload Bandbreiten Limit ist {0} kbyte/s"
msgstr "Minimales Limit der Upload-Bandbreite ist {0} kbyte/s."
#: ../java/src/org/klomp/snark/SnarkManager.java:286
#, java-format
msgid "Startup delay limit changed to {0} minutes"
msgstr "Startverzögerung geändert auf {0} Minuten"
msgstr "Startverzögerung auf {0} Minuten gesetzt"
#: ../java/src/org/klomp/snark/SnarkManager.java:333
msgid "I2CP and tunnel changes will take effect after stopping all torrents"
@@ -62,20 +62,20 @@ msgstr "I2CP Einstellungen geändert auf {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:347
msgid "Unable to connect with the new settings, reverting to the old I2CP settings"
msgstr "Konnte nicht mit den neuen Einstellungen verbinden, benutze wieder die alten I2CP Einstellungen"
msgstr "Konnte mich mit den neuen Einstellungen nicht verbinden, benutze wieder die alten I2CP-Einstellungen"
#: ../java/src/org/klomp/snark/SnarkManager.java:351
msgid "Unable to reconnect with the old settings!"
msgstr "Konnte nicht mit den alten Einstellungen verbinden!"
msgstr "Konnte mich mit den alten Einstellungen micht verbinden!"
#: ../java/src/org/klomp/snark/SnarkManager.java:353
msgid "Reconnected on the new I2CP destination"
msgstr "Verbunden auf dem neuem I2CP Ziel"
msgstr "Verbunden auf dem neuem I2CP-Ziel"
#: ../java/src/org/klomp/snark/SnarkManager.java:364
#, java-format
msgid "I2CP listener restarted for \"{0}\""
msgstr "I2CP Verbindung neu gestartet für \"{0}\""
msgstr "I2CP-Verbindung neu gestartet für \"{0}\""
#: ../java/src/org/klomp/snark/SnarkManager.java:375
msgid "Enabled autostart"
@@ -87,15 +87,15 @@ msgstr "Deaktiviere Autostart"
#: ../java/src/org/klomp/snark/SnarkManager.java:383
msgid "Enabled open trackers - torrent restart required to take effect."
msgstr "Open Tracker aktiviert - zum aktiv werden müssen die Torrents neu gestartet werden"
msgstr "OpenTracker aktiviert - Um dies anzuwenden, müssen die Torrents neu gestartet werden."
#: ../java/src/org/klomp/snark/SnarkManager.java:385
msgid "Disabled open trackers - torrent restart required to take effect."
msgstr "Open Tracker deaktiviert - zum aktiv werden müssen die Torrents neu gestartet werden"
msgstr "Open Tracker deaktiviert - Um dies anzuwenden, müssen die Torrents neu gestartet werden."
#: ../java/src/org/klomp/snark/SnarkManager.java:392
msgid "Open Tracker list changed - torrent restart required to take effect."
msgstr "Open Tracker Liste geändert - zum aktiv werden müssen die Torrents neu gestartet werden"
msgstr "OpenTracker Liste geändert - Um dies anzuwenden, müssen die Torrents neu gestartet werden"
#: ../java/src/org/klomp/snark/SnarkManager.java:399
msgid "Configuration unchanged."
@@ -104,7 +104,7 @@ msgstr "Konfiguration nicht geändert."
#: ../java/src/org/klomp/snark/SnarkManager.java:409
#, java-format
msgid "Unable to save the config to {0}"
msgstr "Konnte Konfiguration nicht nach {0} sichern"
msgstr "Konnte Konfiguration nicht in {0} speichern"
#: ../java/src/org/klomp/snark/SnarkManager.java:445
msgid "Connecting to I2P"
@@ -123,17 +123,17 @@ msgstr "Fehler: Konnte den Torrent nicht hinzufügen {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:479
#, java-format
msgid "Cannot open \"{0}\""
msgstr "Kann folgendes nicht öffnen: \"{0}\""
msgstr "Kann dies nicht öffnen: \"{0}\""
#: ../java/src/org/klomp/snark/SnarkManager.java:492
#, java-format
msgid "Warning - Ignoring non-i2p tracker in \"{0}\", will announce to i2p open trackers only"
msgstr "Warnung - ignoriere nicht-I2P Tracker in \"{0}\", publiziere nur zu I2P Open Tracker"
msgstr "Warnung - Ignoriere nicht-I2P Tracker in \"{0}\", nur bei I2P-OpenTracker bekanntgeben"
#: ../java/src/org/klomp/snark/SnarkManager.java:494
#, java-format
msgid "Warning - Ignoring non-i2p tracker in \"{0}\", and open trackers are disabled, you must enable open trackers before starting the torrent!"
msgstr "Warnung - Ignoriere nicht-I2P Tracker in \"{0}\" und Open Tracker sind deaktiviert, Sie müssen Open Tracker aktivieren bevor sie den Torrent starten!"
msgstr "Warnung - Ignoriere nicht-I2P Tracker in \"{0}\" und OpenTracker sind deaktiviert. Sie müssen OpenTracker aktivieren, bevor Sie den Torrent starten!"
#: ../java/src/org/klomp/snark/SnarkManager.java:513
#, java-format
@@ -153,27 +153,27 @@ msgstr "Torrent hinzugefügt: \"{0}\""
#: ../java/src/org/klomp/snark/SnarkManager.java:627
#, java-format
msgid "Too many files in \"{0}\" ({1}), deleting it!"
msgstr "Zu viele Dateien in \"{0}\" ({1}), lösche es! "
msgstr "Zu viele Dateien in \"{0}\" ({1}), wird gelöscht! "
#: ../java/src/org/klomp/snark/SnarkManager.java:629
#, java-format
msgid "Torrent file \"{0}\" cannot end in \".torrent\", deleting it!"
msgstr "Torrent Datei \"{0}\" darf nicht mit '.torrent' enden, lösche es!"
msgstr "Torrentdatei \"{0}\" darf nicht mit '.torrent' enden, wird gelöscht!"
#: ../java/src/org/klomp/snark/SnarkManager.java:631
#, java-format
msgid "No pieces in \"{0}\", deleting it!"
msgstr "Keine Teile in \"{0}\", entferne es!"
msgstr "Keine Teile in \"{0}\", wird entfernt!"
#: ../java/src/org/klomp/snark/SnarkManager.java:633
#, java-format
msgid "Too many pieces in \"{0}\", limit is {1}, deleting it!"
msgstr "Zu viele Teile in \"{0}\" , das Limit sind {1}, lösche es!"
msgstr "Zu viele Teile in \"{0}\" , das Limit sind {1}, werden gelöscht!"
#: ../java/src/org/klomp/snark/SnarkManager.java:635
#, java-format
msgid "Pieces are too large in \"{0}\" ({1}B), deleting it."
msgstr "Teile sind zu Groß in \"{0}\" ({1}B), lösche es."
msgstr "Teile sind zu groß in \"{0}\" ({1}B), lösche es."
#: ../java/src/org/klomp/snark/SnarkManager.java:636
#, java-format
@@ -183,12 +183,12 @@ msgstr "Limit ist \"{0}\"Byte"
#: ../java/src/org/klomp/snark/SnarkManager.java:644
#, java-format
msgid "Torrents larger than {0}B are not supported yet, deleting \"{1}\""
msgstr "Torrents größer als \"{0}\"Bytes werden nicht unterstützt, lösche \"{1}\""
msgstr "Torrents größer als \"{0}\"Bytes werden nicht unterstützt, lösche \"{1}\"."
#: ../java/src/org/klomp/snark/SnarkManager.java:660
#, java-format
msgid "Error: Could not remove the torrent {0}"
msgstr "Fehler: konnte den torrent \"{0}\" nicht entfernen"
msgstr "Fehler: Konnte den Torrent \"{0}\" nicht entfernen"
#: ../java/src/org/klomp/snark/SnarkManager.java:681
#, java-format
@@ -212,11 +212,11 @@ msgstr "Größe: {0}Byte"
#: ../java/src/org/klomp/snark/SnarkManager.java:757
msgid "Unable to connect to I2P!"
msgstr "Konnte nicht mit I2P verbinden!"
msgstr "Konnte mich nicht mit I2P verbinden!"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:174
msgid "I2PSnark - Anonymous BitTorrent Client"
msgstr "I2PSnark - Anonymer BitTorrent Klient"
msgstr "I2PSnark - Anonymer BitTorrent-Klient"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:185
msgid "Torrents"
@@ -243,11 +243,11 @@ msgstr "Status"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:246
msgid "Hide Peers"
msgstr "Verstecke Teilnehmer"
msgstr "Teilnehmer ausblenden"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:249
msgid "Show Peers"
msgstr "Zeige Teilnehmer"
msgstr "Teilnehmer einblenden"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:254
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1271
@@ -256,7 +256,7 @@ msgstr "Torrent"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:256
msgid "ETA"
msgstr "ETA"
msgstr "Fertig in"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:258
msgid "Downloaded"
@@ -268,15 +268,15 @@ msgstr "Hochgeladen"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:262
msgid "Down Rate"
msgstr "Down Rate"
msgstr "Ausgehend"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:264
msgid "Up Rate"
msgstr "Up Rate"
msgstr "Ausgehend"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:271
msgid "Stop all torrents and the I2P tunnel"
msgstr "Stoppe alle Torrents und den I2P Tunnel"
msgstr "Stoppe alle Torrents und den I2P-Tunnel"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:273
msgid "Stop All"
@@ -284,7 +284,7 @@ msgstr "Stoppe alle"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:278
msgid "Start all torrents and the I2P tunnel"
msgstr "Starte alle Torrents und den I2P Tunnel"
msgstr "Starte alle Torrents und den I2P-Tunnel"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:280
msgid "Start All"
@@ -296,7 +296,7 @@ msgstr "Keine Torrents geladen."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:302
msgid "Totals"
msgstr "Total"
msgstr "Gesamt"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:304
#, java-format
@@ -315,19 +315,19 @@ msgstr[1] "{0} verbundene Teilnehmer"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:336
#, java-format
msgid "Torrent file {0} does not exist"
msgstr "Torrent Datei {0} existiert nicht"
msgstr "Torrentdatei {0} existiert nicht"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:346
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1476
#, java-format
msgid "Torrent already running: {0}"
msgstr "Torrent rennt schon: {0}"
msgstr "Torrent läuft schon: {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:348
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1478
#, java-format
msgid "Torrent already in the queue: {0}"
msgstr "Torrent ist schon in der Queue: {0}"
msgstr "Torrent ist schon in der Warteliste: {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:352
#, java-format
@@ -351,7 +351,7 @@ msgstr "Hole {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:367
msgid "Invalid URL - must start with http://"
msgstr "Ungültige URL - muß mit http:// anfangen"
msgstr "Ungültige URL - muss mit http:// anfangen"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:397
#, java-format
@@ -362,19 +362,19 @@ msgstr "Starte Torrent {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:435
#, java-format
msgid "Torrent file deleted: {0}"
msgstr "Torrent Datei gelöscht: {0}"
msgstr "Torrentdatei gelöscht: {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:441
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:451
#, java-format
msgid "Data file deleted: {0}"
msgstr "Daten Datei gelöscht: {0}"
msgstr "Daten gelöscht: {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:443
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:453
#, java-format
msgid "Data file could not be deleted: {0}"
msgstr "Datendatei konnte nicht gelöscht werden: {0}"
msgstr "Daten konnten nicht gelöscht werden: {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:462
#, java-format
@@ -383,7 +383,7 @@ msgstr "Datenverzeichnis wurde gelöscht: {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:494
msgid "Error creating torrent - you must select a tracker"
msgstr "Fehler beim Erstellen des Torrent - Sie müssen einen Tracker auswählen"
msgstr "Fehler beim Erstellen des Torrents - Sie müssen einen Tracker auswählen"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:509
#, java-format
@@ -393,33 +393,33 @@ msgstr "Torrent erstellt für \"{0}\""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:512
#, java-format
msgid "Many I2P trackers require you to register new torrents before seeding - please do so before starting \"{0}\""
msgstr "Viele I2P Tracker erfordern eine Registrierung bevor der Torrent verteilt wird - bitte machen Sie dieses vor dem Start von \"{0}\""
msgstr "Viele I2P-Tracker erfordern eine Registrierung, bevor der Torrent verteilt wird. Bitte tun Sie dies vor dem Start von \"{0}\"!"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:514
#, java-format
msgid "Error creating a torrent for \"{0}\""
msgstr "Fehler beim Erstellen eines Torrent für \"{0}\""
msgstr "Fehler beim Erstellen eines Torrents für \"{0}\""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:517
#, java-format
msgid "Cannot create a torrent for the nonexistent data: {0}"
msgstr "Kann keinen Torrent für nicht existierende Daten erstellen: {0}"
msgstr "Kann keinen Torrent für nicht existente Daten erstellen: {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:520
msgid "Error creating torrent - you must enter a file or directory"
msgstr "Fehler beim Erstellen des Torrent - Sie müssen eine Datei oder Verzeichnis angeben."
msgstr "Fehler beim Erstellen des Torrents - Sie müssen eine Datei oder ein Verzeichnis angeben."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:523
msgid "Stopping all torrents and closing the I2P tunnel."
msgstr "Stoppt alle Torrents und beendet den I2P Tunnel."
msgstr "Stoppe alle Torrents und beende den I2P Tunnel."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:532
msgid "I2P tunnel closed."
msgstr "I2P Tunnel geschlossen."
msgstr "I2P-Tunnel geschlossen."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:535
msgid "Opening the I2P tunnel and starting all torrents."
msgstr "Öffnet den I2P Tunnel und startet alle Torrents."
msgstr "Öffne den I2P-Tunnel und starte alle Torrents."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:657
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:851
@@ -454,7 +454,7 @@ msgstr "Verteile"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:682
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1327
msgid "Complete"
msgstr "Komplett"
msgstr "Vollständig"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:685
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:690
@@ -464,7 +464,7 @@ msgstr "OK"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:693
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:698
msgid "Stalled"
msgstr "Gedrosselt"
msgstr "Stillstand"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:701
msgid "No Peers"
@@ -472,11 +472,11 @@ msgstr "Keine Teilnehmer"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:703
msgid "Stopped"
msgstr "Gestoppt"
msgstr "Angehalten"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:718
msgid "View files"
msgstr "Betrachte Dateien"
msgstr "Zeige Dateien"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:720
msgid "Open file"
@@ -497,7 +497,7 @@ msgstr "Stoppe den Torrent"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:787
msgid "Stop"
msgstr "Stop"
msgstr "Stopp"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:793
msgid "Start the torrent"
@@ -509,7 +509,7 @@ msgstr "Start"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:800
msgid "Remove the torrent from the active list, deleting the .torrent file"
msgstr "Entfernt den Torrent von der aktiven Liste und löscht die .torrent Datei"
msgstr "Entfernt den Torrent von der aktiven Liste und löscht die .torrent-Datei"
#. Can't figure out how to escape double quotes inside the onclick string.
#. Single quotes in translate strings with parameters must be doubled.
@@ -517,7 +517,7 @@ msgstr "Entfernt den Torrent von der aktiven Liste und löscht die .torrent Date
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:805
#, java-format
msgid "Are you sure you want to delete the file \\''{0}.torrent\\'' (downloaded data will not be deleted) ?"
msgstr "Sind Sie sicher, das Sie die Datei \\''{0}.torrent\\'' löschen wollen (heruntergeladene Daten werden nicht gelöscht)?"
msgstr "Sind Sie sicher, dass Sie die Datei \\''{0}.torrent\\'' löschen wollen? (Heruntergeladene Daten werden nicht gelöscht.)"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:807
msgid "Remove"
@@ -525,7 +525,7 @@ msgstr "Entfernen"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:811
msgid "Delete the .torrent file and the associated data file(s)"
msgstr "Löscht die .torrent Datei und dazugehörigen Daten Datei(en)"
msgstr "Löscht die .torrent-Datei und dazugehörige Daten Datei(en)"
#. Can't figure out how to escape double quotes inside the onclick string.
#. Single quotes in translate strings with parameters must be doubled.
@@ -533,7 +533,7 @@ msgstr "Löscht die .torrent Datei und dazugehörigen Daten Datei(en)"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:816
#, java-format
msgid "Are you sure you want to delete the torrent \\''{0}\\'' and all downloaded data?"
msgstr "Sind Sie sicher, das die die Torrentdatei \\''{0}\\'' und alle heruntergeladene Daten löschen wollen?"
msgstr "Sind Sie sicher, dass Sie die Torrentdatei \\''{0}\\'' und alle heruntergeladenen Daten löschen wollen?"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:818
msgid "Delete"
@@ -545,19 +545,19 @@ msgstr "Quelle"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:879
msgid "Uninteresting (The peer has no pieces we need)"
msgstr "Uninteressiert (Der Teilnehmer hat keine Teile die wir benötigen)"
msgstr "Uninteressant (Der Teilnehmer hat keine Teile die wir benötigen)"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:881
msgid "Choked (The peer is not allowing us to request pieces)"
msgstr "Gedrosselt (der Teilnehmer hat uns nicht erlaubt Teile anzufordern)"
msgstr "Gedrosselt (Der Teilnehmer hat uns nicht erlaubt, Teile anzufordern)"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:895
msgid "Uninterested (We have no pieces the peer needs)"
msgstr "Uninteressiert (Wir haben keine Teile die der Teilnehmer benötigt)"
msgstr "Uninteressiert (Wir haben keine Teile, die der Teilnehmer benötigt)"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:897
msgid "Choking (We are not allowing the peer to request pieces)"
msgstr "Gedrosselt (Wir erlauben dem Teilnehmer nicht Teile anzufordern)"
msgstr "Gedrosselt (Wir erlauben dem Teilnehmer nicht, Teile anzufordern)"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:927
msgid "Add Torrent"
@@ -565,7 +565,7 @@ msgstr "Füge Torrent hinzu"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:929
msgid "From URL"
msgstr "Quell URL"
msgstr "Quell-URL"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:934
msgid "Add torrent"
@@ -574,11 +574,11 @@ msgstr "Füge Torrent hinzu"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:937
#, java-format
msgid "Alternately, you can copy .torrent files to the directory {0}."
msgstr "Alternativ können Sie die .torrent Dateien auch nach {0} kopieren."
msgstr "Alternativ können Sie die .torrent-Dateien auch nach {0} kopieren."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:939
msgid "Removing a .torrent file will cause the torrent to stop."
msgstr "Entfernen der .torrent Datei stoppt einen Torrent."
msgstr "Entfernen der .torrent-Datei stoppt den jeweiligen Torrent."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:958
msgid "Create Torrent"
@@ -591,7 +591,7 @@ msgstr "Daten zum Verteilen"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:965
msgid "File or directory to seed (must be within the specified path)"
msgstr "Datei oder Verzeichnis zum Verteilen (muß im angegebenen Pfad sein)"
msgstr "Datei oder Verzeichnis zum Verteilen (muss im angegebenen Pfad sein)"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:969
msgid "Select a tracker"
@@ -603,7 +603,7 @@ msgstr "oder"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:985
msgid "Specify custom tracker announce URL"
msgstr "Geben Sie eine Tracker Announce URL an"
msgstr "Geben Sie eine Tracker-Announce-URL an!"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:988
msgid "Create torrent"
@@ -616,23 +616,23 @@ msgstr "Einstellungen"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1009
msgid "Data directory"
msgstr "Daten Verzeichnis"
msgstr "Datenverzeichnis"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1012
msgid "Directory to store torrents and data"
msgstr "Verzeichnis zum speichern von Torrent Dateien und Daten"
msgstr "Verzeichnis zum Speichern von Torrentdateien und Daten"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1014
msgid "Edit i2psnark.config and restart to change"
msgstr "Editiere i2psnark.config zum ändern und starte neu."
msgstr "Editiere i2psnark.config zum Ändern und starte neu."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1018
msgid "Auto start"
msgstr "Auto Start"
msgstr "Autostart"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1022
msgid "If checked, automatically start torrents that are added"
msgstr "Wenn markiert werden hinzugefügte Torrents automatisch gestartet."
msgstr "Wenn markiert, werden hinzugefügte Torrents automatisch gestartet."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1026
msgid "Startup delay"
@@ -644,7 +644,7 @@ msgstr "Minuten"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1052
msgid "Total uploader limit"
msgstr "Totales Uploader Limit."
msgstr "Gesamtlimit an Hochladern."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1055
msgid "peers"
@@ -652,47 +652,47 @@ msgstr "Teilnehmer"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1059
msgid "Up bandwidth limit"
msgstr "Upload Bandbreiten Limit."
msgstr "Bandbreitenlimit beim Hochladen."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1062
msgid "Half available bandwidth recommended."
msgstr "Halbe verfügbare Bandbreite ist empfohlen."
msgstr "Halbe verfügbare Bandbreite wird empfohlen."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1064
msgid "View or change router bandwidth"
msgstr "Router Bandbreite ansehen oder ändern"
msgstr "Routerbandbreite ansehen oder ändern"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1068
msgid "Use open trackers also"
msgstr "Benutze auch Open Tracker"
msgstr "Benutze auch OpenTracker"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1072
msgid "If checked, announce torrents to open trackers as well as the tracker listed in the torrent file"
msgstr "Wenn markiert wird der Torrent neben dem angegebenen Tracker auch bei den Open Trackers bekannt gegeben."
msgstr "Wenn markiert, wird der Torrent neben dem angegebenen Tracker auch bei den OpenTrackern bekannt gegeben."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1076
msgid "Open tracker announce URLs"
msgstr "Open Tracker Announce URL"
msgstr "OpenTracker-Announce-URL"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1088
msgid "Inbound Settings"
msgstr "Eingangseinstellungen"
msgstr "Einstellungen Eingehend"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1094
msgid "Outbound Settings"
msgstr "Ausgangseinstellungen"
msgstr "Einstellungen Ausgehend"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1101
msgid "I2CP host"
msgstr "I2CP Host"
msgstr "I2CP-Host"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1106
msgid "I2CP port"
msgstr "I2CP Port"
msgstr "I2CP-Port"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1118
msgid "I2CP options"
msgstr "I2CP Optionen"
msgstr "I2CP-Optionen"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1124
msgid "Save configuration"
@@ -715,7 +715,7 @@ msgstr[1] "{0} Tunnel"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1283
msgid "Up to higher level directory"
msgstr "Eine Hierachie nach oben"
msgstr "Eine Hierarchie nach oben"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1288
msgid "File"
@@ -727,7 +727,7 @@ msgstr "Größe"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1311
msgid "Directory"
msgstr "Daten Verzeichnis"
msgstr "Verzeichnis"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1316
msgid "Torrent not found?"
@@ -739,11 +739,11 @@ msgstr "Datei nicht gefunden im Torrent?"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1330
msgid "complete"
msgstr "Komplett"
msgstr "vollständig"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1331
msgid "bytes remaining"
msgstr "Bytes noch übrig"
msgstr "Bytes ausstehend"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1456
#, java-format
@@ -753,7 +753,7 @@ msgstr "Torrent geholt von {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1484
#, java-format
msgid "Torrent at {0} was not valid"
msgstr "Torrent bei {0} war nicht gültig"
msgstr "Torrent in {0} war nicht gültig"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1489
#, java-format

View File

@@ -175,7 +175,7 @@ public class EditBean extends IndexBean {
}
public String getAccessList(int tunnel) {
return getProperty(tunnel, "i2cp.accessList", "").replaceAll(",", "\n");
return getProperty(tunnel, "i2cp.accessList", "").replace(",", "\n");
}
public boolean getClose(int tunnel) {

View File

@@ -666,7 +666,7 @@ public class IndexBean {
}
public void setAccessList(String val) {
if (val != null)
_otherOptions.put("i2cp.accessList", val.trim().replaceAll("\r\n", ",").replaceAll("\n", ",").replaceAll(" ", ","));
_otherOptions.put("i2cp.accessList", val.trim().replace("\r\n", ",").replace("\n", ",").replace(" ", ","));
}
public void setCloseTime(String val) {
if (val != null) {

View File

@@ -159,7 +159,7 @@
%>
</label>
<input type="text" size="30" id="targetDestination" name="targetDestination" title="Destination of the Tunnel" value="<%=editBean.getClientDestination(curTunnel)%>" class="freetext" />
<span class="comment">(<%=intl._("name or destination")%>)</span>
<span class="comment">(<%=intl._("name or destination")%>; <%=intl._("b32 not recommended")%>)</span>
</div>
<% } %>
<% if (!"streamrclient".equals(tunnelType)) { %>

View File

@@ -9,7 +9,7 @@ msgstr ""
"Project-Id-Version: I2P i2ptunnel\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-06-13 19:23+0000\n"
"PO-Revision-Date: 2010-06-15 14:09+0100\n"
"PO-Revision-Date: 2010-11-06 23:49+0100\n"
"Last-Translator: echelon <echelon@i2pmail.org>\n"
"Language-Team: foo <foo@bar>\n"
"MIME-Version: 1.0\n"
@@ -20,11 +20,11 @@ msgstr ""
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:493
#, 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 "Um das Ziel in ihrer Host Datenbank zu besuchen, klicken Sie <a href=\"{0}\">hier</a>. Um das Ziel aus der kollidierenden Adresshelfer Anfrage zu besuchen, klicken Sie <a href=\"{1}\">hier</a>."
msgstr "Um das Ziel in Ihrer Host-Datenbank zu besuchen, klicken Sie <a href=\"{0}\">hier</a>. Um das Ziel aus der kollidierenden Adresshelfer-Anfrage zu besuchen, klicken Sie <a href=\"{1}\">hier</a>."
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:909
msgid "Click a link below to look for an address helper by using a \"jump\" service:"
msgstr "Durch klicken auf einen der unten stehenden Links bekommen Sie einen Adresshelfer von einem \"Jump\" Service:"
msgstr "Durch Klicken auf einen der untenstehenden Links bekommen Sie einen Adresshelfer von einem \"Sprung\"-Service:"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:369
msgid "New Tunnel"
@@ -32,47 +32,47 @@ msgstr "Neuer Tunnel"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:389
msgid "Standard client"
msgstr "Standard Klient"
msgstr "Standardklient"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:390
msgid "HTTP client"
msgstr "HTTP Klient"
msgstr "HTTP-Klient"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:391
msgid "IRC client"
msgstr "IRC Klient"
msgstr "IRC-Klient"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:392
msgid "Standard server"
msgstr "Standard Server"
msgstr "Standardserver"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:393
msgid "HTTP server"
msgstr "HTTP Server"
msgstr "HTTP-Server"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:394
msgid "SOCKS 4/4a/5 proxy"
msgstr "SOCKS 4/4a/5 Proxy"
msgstr "SOCKS-4/4a/5-Proxy"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:395
msgid "SOCKS IRC proxy"
msgstr "SOCKS IRC Proxy"
msgstr "SOCKS-IRC-Proxy"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:396
msgid "CONNECT/SSL/HTTPS proxy"
msgstr "CONNECT/SSL/HTTPS Proxy"
msgstr "CONNECT/SSL/HTTPS-Proxy"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:397
msgid "IRC server"
msgstr "IRC Server"
msgstr "IRC-Server"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:398
msgid "Streamr client"
msgstr "Streamr Klient"
msgstr "Streamr-Klient"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:399
msgid "Streamr server"
msgstr "Streamr Server"
msgstr "Streamr-Server"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:400
msgid "HTTP bidir"
@@ -80,15 +80,15 @@ msgstr "HTTP Bidir"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:73
msgid "I2P Tunnel Manager - Edit Client Tunnel"
msgstr "I2P Tunnel Manager - Edit Klienten Tunnel"
msgstr "I2P Tunnel Manager - Kliententunnel bearbeiten"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:93
msgid "Edit proxy settings"
msgstr "Editiere Proxy Einstellungen"
msgstr "Proxyeinstellungen bearbeiten"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:101
msgid "New proxy settings"
msgstr "Neue Proxy Einstellungen"
msgstr "Neue Proxyeinstellungen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:112
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:112
@@ -147,17 +147,17 @@ msgstr "Lokal (127.0.0.1)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:166
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:199
msgid "Everyone (0.0.0.0)"
msgstr "Jeder (0.0.0.0)"
msgstr "Überall (0.0.0.0)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:170
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:203
msgid "LAN Hosts (Please specify your LAN address)"
msgstr "LAN Hosts (Bitte geben Sie ihre LAN Adressen an)"
msgstr "LAN-Hosts (Bitte geben Sie ihre LAN-Adressen an!)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:186
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:205
msgid "Other"
msgstr "Andere"
msgstr "Anderen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:195
msgid "Outproxies"
@@ -165,7 +165,7 @@ msgstr "Ausgehende Proxies"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:202
msgid "Tunnel Destination"
msgstr "Tunnel Ziel"
msgstr "Ziel des Tunnels"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:214
msgid "name or destination"
@@ -184,7 +184,7 @@ msgstr "Interaktive Verbindung"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:231
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:248
msgid "bulk connection (downloads/websites/BT)"
msgstr "lose Verbindung (Download/Webseiten/BitTorrent)"
msgstr "Mengenverbindung (Download/Webseiten/BitTorrent)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:233
msgid "Delay Connect"
@@ -196,11 +196,11 @@ msgstr "für Verbindungen mit Anfragen/Antworten"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:239
msgid "Shared Client"
msgstr "Geteilter Klient"
msgstr "versch. Klienten"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:243
msgid "(Share tunnels with other clients and irc/httpclients? Change requires restart of client proxy)"
msgstr "(Teile Tunnel mit anderen Klienten und IRC/HTTP Klienten? Änderungen benötigen Neustart des Klientenproxys)"
msgstr "(Teile Tunnel mit anderen Klienten und IRC/HTTP-Klienten? Änderungen benötigen Neustart des Klientenproxys)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:247
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:124
@@ -210,21 +210,21 @@ msgstr "Automatischer Start"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:251
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:128
msgid "(Check the Box for 'YES')"
msgstr "(Aktiviere die Box für 'JA')"
msgstr "(Aktiviere das Kästchen für 'ja')"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:253
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:266
msgid "Advanced networking options"
msgstr "Erweiterte Netzwerk Optionen"
msgstr "Erweiterte Netzwerkoptionen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:255
msgid "(NOTE: when this client proxy is configured to share tunnels, then these options are for all the shared proxy clients!)"
msgstr "(HINWEIS: Ist dieser Klienten Proxy auf Teilen der Tunnel konfiguriert, dann gelten diese Optionen für alle Klienten des Proxy Klienten!)"
msgstr "(HINWEIS: Ist dieser Proxy konfiguriert, Tunnel mit anderen Klienten zu teilen, so gelten diese Optionen für alle Klienten des Proxys!)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:257
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:268
msgid "Tunnel Options"
msgstr "Tunnel Optionen"
msgstr "Tunneloptionen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:259
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:270
@@ -234,27 +234,27 @@ msgstr "Länge"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:266
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:277
msgid "0 hop tunnel (low anonymity, low latency)"
msgstr "0 Hop Tunnel (geringe Anonymität, geringe Latenz)"
msgstr "0-Hop-Tunnel (geringe Anonymität, geringe Latenz)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:270
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:281
msgid "1 hop tunnel (medium anonymity, medium latency)"
msgstr "1 Hop Tunnel (mittlere Anonymität, mittlere Latenz)"
msgstr "1-Hop-Tunnel (mittlere Anonymität, mittlere Latenz)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:274
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:285
msgid "2 hop tunnel (high anonymity, high latency)"
msgstr "2 Hop Tunnel (hohe Anonymität, hohe Latenz)"
msgstr "2-Hop-Tunnel (hohe Anonymität, hohe Latenz)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:278
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:289
msgid "3 hop tunnel (very high anonymity, poor performance)"
msgstr "3 Hop Tunnel (sehr hohe Anonymität, geringe Performance)"
msgstr "3-Hop-Tunnel (sehr hohe Anonymität, geringe Performance)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:287
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:298
msgid "hop tunnel (very poor performance)"
msgstr "Hop Tunnel (sehr geringe Performance)"
msgstr "Hop-Tunnel (sehr geringe Performance)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:292
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:303
@@ -264,52 +264,52 @@ msgstr "Varianz"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:299
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:310
msgid "0 hop variance (no randomisation, consistant performance)"
msgstr "0 Hop Varianz (keine zufällige Verteilung, konsistente Performance)"
msgstr "0-Hop-Varianz (keine zufällige Verteilung, konsistente Performance)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:303
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:314
msgid "+ 0-1 hop variance (medium additive randomisation, subtractive performance)"
msgstr "+ 0-1 Hop Varianz (mittlere, hinzufügende zufällige Verteilung, verringert Performance)"
msgstr "+ 0-1 Hop-Varianz (mittlere, hinzufügende zufällige Verteilung, verringert Performance)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:307
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:318
msgid "+ 0-2 hop variance (high additive randomisation, subtractive performance)"
msgstr "+ 0-2 Hop Varianz (hohe, hinzufügende zufällige Verteilung, verringert Performance)"
msgstr "+ 0-2 Hop-Varianz (hohe, hinzufügende zufällige Verteilung, verringert Performance)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:311
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:322
msgid "+/- 0-1 hop variance (standard randomisation, standard performance)"
msgstr "+ 0-1 Hop Varianz (standard zufällige Verteilung, standard Performance)"
msgstr "+/- 0-1 Hop-Varianz (geringe zufällige Verteilung, Standardperformance)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:315
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:326
msgid "+/- 0-2 hop variance (not recommended)"
msgstr "+/- 0-2 Hop Varianz (nicht empfohlen)"
msgstr "+/- 0-2 Hop-Varianz (nicht empfohlen)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:327
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:338
msgid "hop variance"
msgstr "Hop Varianz"
msgstr "Hop-Varianz"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:332
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:343
msgid "Count"
msgstr "Zähler"
msgstr "Anzahl"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:339
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:350
msgid "1 inbound, 1 outbound tunnel (low bandwidth usage, less reliability)"
msgstr "1 eingehender, 1 ausgehender Tunnel (geringe Bandbreitennutzung, wenig Zuverlässigkeit)"
msgstr "1 eingehender, 1 ausgehender Tunnel (geringe Bandbreitennutzung, weniger zuverlässig)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:343
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:354
msgid "2 inbound, 2 outbound tunnels (standard bandwidth usage, standard reliability)"
msgstr "2 eingehende, 2 ausgehende Tunnel (standard Bandbreitennutzung, standard Zuverlässigkeit)"
msgstr "2 eingehende, 2 ausgehende Tunnel (Standardbandbreitennutzung, zuverlässig)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:347
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:358
msgid "3 inbound, 3 outbound tunnels (higher bandwidth usage, higher reliability)"
msgstr "3 eingehende, 3 ausgehende Tunnel (hohe Bandbreitennutzung, hohe Zuverlässigkeit)"
msgstr "3 eingehende, 3 ausgehende Tunnel (hohe Bandbreitennutzung, zuverlässiger)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:356
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:367
@@ -319,37 +319,37 @@ msgstr "Tunnel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:361
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:372
msgid "Backup Count"
msgstr "Anzahl an Ersatz"
msgstr "Anzahl an Ersatztunneln"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:368
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:379
msgid "0 backup tunnels (0 redundancy, no added resource usage)"
msgstr "0 Backup Tunnel (0 Redundanz, keine zusätzliche Ressourcennutzung)"
msgstr "0 Ersatztunnel (0 Redundanz, keine zusätzliche Ressourcennutzung)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:372
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:383
msgid "1 backup tunnel each direction (low redundancy, low resource usage)"
msgstr "1 Backup Tunnel in jede Richtung (geringe Redundanz, geringe Ressourcennutzung)"
msgstr "1 Ersatztunnel in jede Richtung (geringe Redundanz, geringe Ressourcennutzung)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:376
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:387
msgid "2 backup tunnels each direction (medium redundancy, medium resource usage)"
msgstr "2 Backup Tunnel in jede Richtung (mittlere Redundanz, mittlere Ressourcennutzung)"
msgstr "2 Ersatztunnel in jede Richtung (mittlere Redundanz, mittlere Ressourcennutzung)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:380
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:391
msgid "3 backup tunnels each direction (high redundancy, high resource usage)"
msgstr "3 Backup Tunnel in jede Richtung (hohe Redundanz, hohe Ressourcennutzung)"
msgstr "3 Ersatztunnel in jede Richtung (hohe Redundanz, hohe Ressourcennutzung)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:389
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:400
msgid "backup tunnels"
msgstr "Backup Tunnel"
msgstr "Ersatztunnel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:394
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:405
msgid "I2CP Options"
msgstr "I2CP Optionen"
msgstr "I2CP-Optionen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:396
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:146
@@ -368,7 +368,7 @@ msgstr "Port"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:406
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:443
msgid "Reduce tunnel quantity when idle"
msgstr "Reduziert die Anzahl an Tunnel im Leerlauf"
msgstr "Reduziert die Anzahl an Tunneln im Leerlauf"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:408
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:422
@@ -379,22 +379,22 @@ msgstr "Reduziert die Anzahl an Tunnel im Leerlauf"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:433
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:445
msgid "Enable"
msgstr "Aktiviert"
msgstr "aktiviert"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:412
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:449
msgid "Reduced tunnel count"
msgstr "Reduzierte Tunnel Anzahl"
msgstr "Reduzierte Tunnelanzahl"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:416
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:436
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:453
msgid "Idle minutes"
msgstr "Minuten im Leerlauf"
msgstr "Minuten Inaktivität"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:420
msgid "Close tunnels when idle"
msgstr "Schliesse Tunnel im Leerlauf"
msgstr "Schließe nicht genutzte Tunnel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:426
msgid "New Keys on Reopen"
@@ -402,7 +402,7 @@ msgstr "Neue Schlüssel beim Wiederöffnen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:434
msgid "Disable"
msgstr "Deaktiviert"
msgstr "deaktiviert"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:440
msgid "Delay tunnel open until required"
@@ -433,7 +433,7 @@ msgstr "Eigene Optionen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:472
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:493
msgid "NOTE: If tunnel is currently running, most changes will not take effect until tunnel is stopped and restarted."
msgstr "HINWEIS: Falls der Tunnel gerade aktiv ist werden die meisten Änderungen erst nach einem Neustart des Tunnels wirksam."
msgstr "HINWEIS: Falls der Tunnel gerade aktiv ist, werden die meisten Änderungen erst nach einem Neustart des Tunnels wirksam."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:474
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:495
@@ -452,15 +452,15 @@ msgstr "Speichern"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:73
msgid "I2P Tunnel Manager - Edit Server Tunnel"
msgstr "I2P Tunnel Manager - Edit Server Tunnel"
msgstr "I2P-Tunnel-Manager - Server-Tunnel Bearbeiten"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:93
msgid "Edit server settings"
msgstr "Server Einstellungen ändern"
msgstr "Server-Einstellungen ändern"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:101
msgid "New server settings"
msgstr "Neue Server Einstellungen"
msgstr "Neue Server-Einstellungen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:214
msgid "Website name"
@@ -480,7 +480,7 @@ msgstr "Zum lokalen Adressbuch hinzufügen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:415
msgid "Encrypt Leaseset"
msgstr "verschlüsseltes Leaseset"
msgstr "Verschlüsseltes Leaseset"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:421
msgid "Encryption Key"
@@ -492,16 +492,16 @@ msgstr "Erzeuge neuen Schlüssel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:427
msgid "Generate"
msgstr "Erzeuge"
msgstr "Erzeugen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:429
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:487
msgid "(Tunnel must be stopped first)"
msgstr "(Tunnel muß zuerst beendet sein)"
msgstr "(Tunnel muss zuerst beendet sein)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:431
msgid "Restricted Access List"
msgstr "Liste zum beschränktem Zugang"
msgstr "Liste zum beschränkten Zugang"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:437
msgid "Access List"
@@ -509,7 +509,7 @@ msgstr "Zugangsliste"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:441
msgid "(Restrict to these clients only)"
msgstr "(Beschränkt auf nur diese Klienten)"
msgstr "(Beschränkt auf diese Klienten)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:457
msgid "New Certificate type"
@@ -549,11 +549,11 @@ msgstr "Modifizieren"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:71
msgid "I2P Tunnel Manager - List"
msgstr "I2P Tunnel Manager - List"
msgstr "I2P-Tunnel-Manager - List"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:83
msgid "Status Messages"
msgstr "Status Nachrichten"
msgstr "Statusnachrichten"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:87
msgid "Refresh"
@@ -561,11 +561,11 @@ msgstr "Auffrischen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:91
msgid "Stop All"
msgstr "Alle Stoppen"
msgstr "Alle stoppen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:95
msgid "Start All"
msgstr "Alle Starten"
msgstr "Alle starten"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:99
msgid "Restart All"
@@ -577,12 +577,12 @@ msgstr "Konfiguration neu einlesen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:105
msgid "I2P Server Tunnels"
msgstr "I2P Server Tunnel"
msgstr "I2P-Server-Tunnel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:109
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:130
msgid "Points at"
msgstr "Zeigt auf"
msgstr "Läuft auf"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:111
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:153
@@ -599,7 +599,7 @@ msgstr "Status"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:163
msgid "Base32 Address"
msgstr "Basis-32 Adresse"
msgstr "Basis-32-Adresse"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:171
msgid "No Preview"
@@ -608,7 +608,7 @@ msgstr "Keine Vorschau"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:184
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:285
msgid "Starting..."
msgstr "Starte..."
msgstr "Starte ..."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:191
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:205
@@ -616,7 +616,7 @@ msgstr "Starte..."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:306
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:320
msgid "Stop"
msgstr "Stop"
msgstr "Stopp"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:198
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:313
@@ -645,11 +645,11 @@ msgstr "Standard"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:238
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:370
msgid "Create"
msgstr "Erstelle"
msgstr "Erstellen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:240
msgid "I2P Client Tunnels"
msgstr "I2P Klienten Tunnel"
msgstr "I2P-Klienten-Tunnel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:248
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:274
@@ -670,5 +670,5 @@ msgstr "Ziel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:366
msgid "New client tunnel"
msgstr "Neuer Klienten Tunnel"
msgstr "Neuer Kliententunnel"

View File

@@ -45,6 +45,10 @@ public class I2PSocketEepGet extends EepGet {
/** this replaces _proxy in the superclass. Sadly, I2PSocket does not extend Socket. */
private I2PSocket _socket;
/** from ConnectionOptions */
private static final String PROP_CONNECT_DELAY = "i2p.streaming.connectDelay";
private static final String CONNECT_DELAY = "500";
public I2PSocketEepGet(I2PAppContext ctx, I2PSocketManager mgr, int numRetries, String outputFile, String url) {
this(ctx, mgr, numRetries, -1, -1, outputFile, null, url);
}
@@ -123,6 +127,10 @@ public class I2PSocketEepGet extends EepGet {
Properties props = new Properties();
props.setProperty(I2PSocketOptions.PROP_CONNECT_TIMEOUT, "" + CONNECT_TIMEOUT);
props.setProperty(I2PSocketOptions.PROP_READ_TIMEOUT, "" + INACTIVITY_TIMEOUT);
// This is important - even if the underlying socket doesn't have a connect delay,
// we want to set it for this connection, so the request headers will go out
// in the SYN packet, saving one RTT.
props.setProperty(PROP_CONNECT_DELAY, CONNECT_DELAY);
I2PSocketOptions opts = _socketManager.buildOptions(props);
_socket = _socketManager.connect(dest, opts);
} else {

View File

@@ -24,7 +24,10 @@ public class ConfigLoggingHelper extends HelperBase {
public String getMaxFileSize() {
int bytes = _context.logManager().getFileSize();
if (bytes <= 0) return "1.00 MB";
return DataHelper.formatSize2(bytes) + 'B';
// "&nbsp;" comes back in the POST as 0xc2 0xa0
// non-breaking space is U+00A0 which is 0xc2 0xa0 in UTF-8.
// we could figure out where the UTF-8 problem is but why bother.
return DataHelper.formatSize2(bytes).replace("&nbsp;", " ") + 'B';
}
public String getLogLevelTable() {
StringBuilder buf = new StringBuilder(32*1024);

View File

@@ -142,7 +142,7 @@ public class ConfigUpdateHandler extends FormHandler {
}
if ( (_updateURL != null) && (_updateURL.length() > 0) ) {
_updateURL = _updateURL.replaceAll("\r\n", ",").replaceAll("\n", ",");
_updateURL = _updateURL.replace("\r\n", ",").replace("\n", ",");
String oldURL = _context.router().getConfigSetting(PROP_UPDATE_URL);
if ( (oldURL == null) || (!_updateURL.equals(oldURL)) ) {
_context.router().setConfigSetting(PROP_UPDATE_URL, _updateURL);
@@ -151,7 +151,7 @@ public class ConfigUpdateHandler extends FormHandler {
}
if ( (_trustedKeys != null) && (_trustedKeys.length() > 0) ) {
_trustedKeys = _trustedKeys.replaceAll("\r\n", ",").replaceAll("\n", ",");
_trustedKeys = _trustedKeys.replace("\r\n", ",").replace("\n", ",");
String oldKeys = new TrustedUpdate(_context).getTrustedKeysString();
if ( (oldKeys == null) || (!_trustedKeys.equals(oldKeys)) ) {
_context.router().setConfigSetting(PROP_TRUSTED_KEYS, _trustedKeys);

View File

@@ -40,7 +40,7 @@ public class ConfigUpdateHelper extends HelperBase {
public String getUpdateURL() {
String url = _context.getProperty(ConfigUpdateHandler.PROP_UPDATE_URL);
if (url != null)
return url.replaceAll(",", "\n");
return url.replace(",", "\n");
else
return ConfigUpdateHandler.DEFAULT_UPDATE_URL;
}

View File

@@ -31,9 +31,9 @@ public class LogsHelper extends HelperBase {
}
String str = FileUtil.readTextFile(f.getAbsolutePath(), 250, false);
if (str == null)
return "";
return _("File not found") + ": <b><code>" + f.getAbsolutePath() + "</code></b>";
else {
str = str.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
str = str.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;");
return _("File location") + ": <b><code>" + f.getAbsolutePath() + "</code></b> <pre>" + str + "</pre>";
}
}
@@ -54,12 +54,14 @@ public class LogsHelper extends HelperBase {
buf.append("<code>\n");
for (int i = msgs.size(); i > 0; i--) {
String msg = msgs.get(i - 1);
msg = msg.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;");
buf.append("<li>");
if (colorize) {
String color;
// Homeland Security Advisory System
// http://www.dhs.gov/xinfoshare/programs/Copy_of_press_release_0046.shtm
// but pink instead of yellow for WARN
// FIXME doesnt work for translated levels
if (msg.contains("CRIT"))
color = "#cc0000";
else if (msg.contains("ERROR"))
@@ -71,7 +73,7 @@ public class LogsHelper extends HelperBase {
else
color = "#006600";
buf.append("<font color=\"").append(color).append("\">");
buf.append(msg.replaceAll("<", "&lt;").replaceAll(">", "&gt;"));
buf.append(msg);
buf.append("</font>");
} else {
buf.append(msg);

View File

@@ -112,7 +112,7 @@ public class TunnelRenderer {
if (lifetime > 10*60)
lifetime = 10*60;
int bps = 1024 * (int) cfg.getProcessedMessagesCount() / lifetime;
out.write("<td class=\"cells\" align=\"center\">" + bps + "Bps</td>");
out.write("<td class=\"cells\" align=\"center\">" + bps + " Bps</td>");
if (cfg.getSendTo() == null)
out.write("<td class=\"cells\" align=\"center\">" + _("Outbound Endpoint") + "</td>");
else if (cfg.getReceiveFrom() == null)

File diff suppressed because it is too large Load Diff

View File

@@ -15,8 +15,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Poedit-Language: German\n"
"X-Poedit-Basepath: /home/lee/work/i2p/monotone/i2p.i2p/apps/routerconsole/java\n"
"X-Poedit-Language: French\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:106
msgid "config networking"

View File

@@ -15,6 +15,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"X-Poedit-Language: Dutch\n"
#: ../../../router/java/src/net/i2p/router/Blocklist.java:126

View File

@@ -47,6 +47,9 @@ public class ConnectionOptions extends I2PSocketOptionsImpl {
private int _maxTotalConnsPerHour;
private int _maxTotalConnsPerDay;
// NOTE - almost all the options are below, but see
// I2PSocketOptions in ministreaming for a few more
public static final int PROFILE_BULK = 1;
public static final int PROFILE_INTERACTIVE = 2;

View File

@@ -9,7 +9,7 @@ msgstr ""
"Project-Id-Version: I2P susidns\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-06-13 19:24+0000\n"
"PO-Revision-Date: 2010-06-15 11:22+0100\n"
"PO-Revision-Date: 2010-11-06 23:00+0100\n"
"Last-Translator: echelon <echelon@i2pmail.org>\n"
"Language-Team: foo <foo@bar>\n"
"MIME-Version: 1.0\n"
@@ -25,7 +25,7 @@ msgstr "Suche"
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:203
msgid "Search within filtered list"
msgstr "Suche in gefilterte Liste"
msgstr "Suche in gefilterter Liste"
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:205
msgid "Filtered list"
@@ -76,7 +76,7 @@ msgstr "Hostname {0} ist bereits im Adressbuch, nicht geändert."
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:265
#, java-format
msgid "Host name {0} is already in addressbook with a different destination. Click \"Replace\" to overwrite."
msgstr "Hostname {0} ist bereits im Adressbuch mit einem anderen Ziel. Klicken Sie auf \"Ersetzen\" um den alten Eintrag zu ersetzen."
msgstr "Hostname {0} ist mit einem anderen Ziel bereits im Adressbuch. Klicken Sie auf \"Ersetzen\", um den alten Eintrag zu ersetzen!"
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:277
#, java-format
@@ -94,7 +94,7 @@ msgstr "Ungültiges Basis-64 Ziel"
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:288
msgid "Please enter a host name and destination"
msgstr "Bitte geben Sie einen Hostnamen und ein Ziel ein"
msgstr "Bitte geben Sie einen Hostnamen und ein Ziel ein!"
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:292
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:314
@@ -104,16 +104,16 @@ msgstr "Ausgewähltes löschen"
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:302
#, java-format
msgid "Destination {0} deleted."
msgstr "Ziel {0} gelöscht."
msgstr "Ziel {0} gelöscht"
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:304
#, java-format
msgid "{0} destinations deleted."
msgstr "{0} Ziele gelöscht."
msgstr "{0} Ziele gelöscht"
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:310
msgid "Addressbook saved."
msgstr "Adressbuch gespeichert."
msgstr "Adressbuch gespeichert"
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:313
msgid "ERROR: Could not write addressbook file."
@@ -123,7 +123,7 @@ msgstr "FEHLER: Konnte Adressbuchdatei nicht schreiben."
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:148
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:150
msgid "Invalid form submission, probably because you used the \"back\" or \"reload\" button on your browser. Please resubmit."
msgstr "Ungültige Datenübertragung, vielleicht haben Sie die \"Zurück\" oder \"Neu laden\" Schalter in ihrem Browser genutzt. Bitte neu senden."
msgstr "Ungültige Datenübertragung, vielleicht haben Sie die \"Zurück\"- oder \"Neu laden\"-Schalter in Ihrem Browser genutzt. Bitte neu senden!"
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:139
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:129
@@ -134,7 +134,7 @@ msgstr "Speichern"
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:141
msgid "Configuration saved."
msgstr "Einstellungen gespeichert."
msgstr "Einstellungen gespeichert"
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:142
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:144
@@ -145,7 +145,7 @@ msgstr "Neu laden"
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:144
msgid "Configuration reloaded."
msgstr "Einstellungen neu geladen."
msgstr "Einstellungen neu geladen"
#. Yes this is a hack.
#. No it doesn't work on a text-mode browser.
@@ -154,15 +154,15 @@ msgstr "Einstellungen neu geladen."
#. config reload and fetch.
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:138
msgid "Subscriptions saved, updating addressbook from subscription sources now."
msgstr "Abonnement gespeichert, aktualisiere jetzt das Adressbuch von unten stehenden Aboquellen."
msgstr "Abonnement gespeichert, aktualisiere jetzt das Adressbuch von untenstehenden Aboquellen."
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:142
msgid "Subscriptions saved."
msgstr "Abonnementquellen gespeichert."
msgstr "Abonnementquellen gespeichert"
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:146
msgid "Subscriptions reloaded."
msgstr "Abonnementquellen neu geladen."
msgstr "Abonnementquellen neu geladen"
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:125
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:145
@@ -254,7 +254,7 @@ msgstr "Ziel"
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:257
msgid "Mark for deletion"
msgstr "zum löschen markieren"
msgstr "zum Löschen markieren"
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:279
msgid "address helper link"
@@ -282,23 +282,23 @@ msgstr "Hinweise"
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:134
msgid "File and directory paths here are relative to the addressbook's working directory, which is normally ~/.i2p/addressbook/ (Linux) or %APPDATA%\\I2P\\addressbook\\ (Windows)."
msgstr "Dateien und Verzeichnispfade sind relativ zum Arbeitsverzeichnis des Adressbuches, normalerweise ~/.i2p/addressbook/ (Linux) oder %APPDATA%\\I2P\\addressbook\\ (Windows)."
msgstr "Dateien und Verzeichnispfade sind relativ zum Arbeitsverzeichnis des Adressbuchs - normalerweise ~/.i2p/addressbook/ (Linux) oder %APPDATA%\\I2P\\addressbook\\ (Windows)."
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:136
msgid "If you want to manually add lines to an addressbook, add them to the private or master addressbooks."
msgstr "Falls Sie manuell Einträge zum Adressbuch hinzufügen möchten, fügen Sie diese zum Privaten oder zum Master Adressbuch hinzu."
msgstr "Falls Sie manuell Einträge zum Adressbuch hinzufügen möchten, fügen Sie diese zum privaten oder zum Master-Adressbuch hinzu!"
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:138
msgid "The router addressbook and the published addressbook are updated by the addressbook application."
msgstr "Das Router Adressbuch und das veröffentlichte Adressbuch werden von der Adressbuch Anwendung aktualisiert."
msgstr "Das Router-Adressbuch und das veröffentlichte Adressbuch werden von der Adressbuch-Anwendung aktualisiert."
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:140
msgid "When you publish your addressbook, ALL destinations from the master and router addressbooks appear there."
msgstr "Falls Sie das Adressbuch veröffentlichen erscheinen dort ALLE Ziele aus dem Master und dem Router Adressbuch."
msgstr "Falls Sie das Adressbuch veröffentlichen, erscheinen dort ALLE Ziele aus dem Master- und dem Router-Adressbuch."
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:142
msgid "Use the private addressbook for private destinations, these are not published."
msgstr "Benutzen Sie das private Adressbuch für private Ziele, diese werden nicht veröffentlicht."
msgstr "Benutzen Sie das private Adressbuch für private Ziele. Diese werden nicht veröffentlicht."
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:144
msgid "Options"
@@ -306,15 +306,15 @@ msgstr "Optionen"
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:146
msgid "File containing the list of subscriptions URLs (no need to change)"
msgstr "Datei mit der Liste von Abonnement-URLs (braucht nicht geändert werden)"
msgstr "Datei mit der Liste von Abonnement-URLs (braucht nicht geändert zu werden)"
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:148
msgid "Update interval in hours"
msgstr "Update Intervall in Stunden"
msgstr "Aktualisierungsintervall in Stunden"
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:150
msgid "Your public hosts.txt file (choose a path within your webserver document root)"
msgstr "Ihre öffentliche hosts.txt datei (Wählen Sie einen Pfad in ihrem Webserver Wurzelverzeichnis)"
msgstr "Ihre öffentliche hosts.txt-Datei (Wählen Sie einen Pfad in Ihrem Webserver Wurzelverzeichnis!)"
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:152
msgid "Your hosts.txt (don't change)"
@@ -322,27 +322,27 @@ msgstr "Ihre hosts.txt (nicht ändern)"
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:154
msgid "Your personal addressbook, these hosts will be published"
msgstr "Ihr persönliches Adressbuch, diese Hosteinträge werden veröffentlicht"
msgstr "Ihr persönliches Adressbuch - diese Hosteinträge werden veröffentlicht"
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:156
msgid "Your private addressbook, it is never published"
msgstr "Ihr privates Adressbuch, dieses wird nie veröffentlicht"
msgstr "Ihr privates Adressbuch - dieses wird nie veröffentlicht"
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:158
msgid "Port for your eepProxy (no need to change)"
msgstr "Port zu Ihrem EepProxy (braucht nicht geändert werden)"
msgstr "Port zu Ihrem EepProxy (braucht nicht geändert zu werden)"
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:160
msgid "Hostname for your eepProxy (no need to change)"
msgstr "Hostname zu Ihrem EepProxy (braucht nicht geändert werden)"
msgstr "Hostname zu Ihrem EepProxy (braucht nicht geändert zu werden)"
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:162
msgid "Whether to update the published addressbook"
msgstr "Ob ihr veröffentlichtes Adressbuch aktualisiert werden soll"
msgstr "Soll Ihr veröffentlichtes Adressbuch aktualisiert werden?"
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:164
msgid "File containing the etags header from the fetched subscription URLs (no need to change)"
msgstr "Datei,die die etags-Kopfzeilen der bereits aktualisierten Abonnement URLs enthält (braucht nicht geändert werden)"
msgstr "Datei, die die etags-Kopfzeilen der bereits aktualisierten Abonnement-URLs enthält (braucht nicht geändert zu werden)"
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:166
msgid "File containing the modification timestamp for each fetched subscription URL (no need to change)"
@@ -350,11 +350,11 @@ msgstr "Datei, welche die Zeitstempel der letzten Modifikation für jede bereits
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:168
msgid "File to log activity to (change to /dev/null if you like)"
msgstr "Berichte zu Aktivitäten werden in dieser Datei gespeichert (ändern Sie es zu /dev/null falls Sie möchten)"
msgstr "Berichte zu Aktivitäten werden in dieser Datei gespeichert. (Ändern Sie es zu /dev/null, wenn Sie möchten!)"
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:91
msgid "Introduction"
msgstr "Einleittng - SusiDNS"
msgstr "Einleitung - SusiDNS"
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:109
msgid "What is the addressbook?"
@@ -362,11 +362,11 @@ msgstr "Was ist das Adressbuch?"
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:111
msgid "The addressbook application is part of your i2p installation."
msgstr "Das Adressbuch ist ein Teil Ihrer I2P Installation."
msgstr "Das Adressbuch ist ein Teil Ihrer I2P-Installation."
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:113
msgid "It regularly updates your hosts.txt file from distributed sources or \"subscriptions\"."
msgstr "Es aktualisiert regelmässig Ihre hosts.txt Datei aus verteilten Quellen oder den \"Abonnementquellen\"."
msgstr "Es aktualisiert regelmäßig Ihre hosts.txt-Datei aus verteilten Quellen oder den \"Abonnementquellen\"."
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:115
msgid "In the default configuration, the addressbook is only subscribed to www.i2p2.i2p."
@@ -374,11 +374,11 @@ msgstr "In der Standardeinstellung bezieht das Adressbuch sein Abonnement nur vo
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:117
msgid "Subscribing to additional sites is easy, just add them to your <a href=\"subscriptions.jsp\">subscriptions</a> file."
msgstr "Zusätzliche Abonnementquellen hinzufügen ist einfach, fügen Sie deren URL zu Ihrer <a href=\"subscriptions.jsp\">Abonnement</a> Datei hinzu."
msgstr "Zusätzliche Abonnementquellen hinzuzufügen ist einfach: Geben Sie dazu deren URL in Ihrer <a href=\"subscriptions.jsp\">Abonnement</a>-Datei an."
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:119
msgid "For more information on naming in i2p, see <a href=\"http://www.i2p2.i2p/naming.html\">the overview on www.i2p2.i2p</a>."
msgstr "Für mehr Informationen über das Namenssystem in I2P schauen Sie bitte auf der <a href=\"http://www.i2p2.i2p/naming.html\">&Uuml;bersichtsseite auf www.i2p2.i2p</a> nach."
msgstr "Für mehr Informationen über das Namenssystem in I2P konsultieren Sie bitte die <a href=\"http://www.i2p2.i2p/naming.html\">&Uuml;bersichtsseite auf www.i2p2.i2p</a>."
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:121
msgid "How does the addressbook work?"
@@ -386,15 +386,15 @@ msgstr "Wie funktioniert das Adressbuch?"
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:123
msgid "The addressbook application regularly polls your subscriptions and merges their content into your \"router\" addressbook, stored in the hosts.txt file."
msgstr "Die Adressbuch-Anwendung bezieht regelmässig ihre Abonnements und fügt deren Inhalt in Ihr \"Router\" Adressbuch zusammen, gespeichert in der hosts.txt Datei."
msgstr "Die Adressbuch-Anwendung bezieht regelmäßig ihre Abonnements und führt deren Inhalt mit dem Ihres \"Router\"-Adressbuchs zusammen, welches in der hosts.txt-Datei gespeichert ist."
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:125
msgid "Then it merges your \"master\" addressbook (userhosts.txt) into the router addressbook as well."
msgstr "Dann fügt diese auch Ihr \"Master\" Adressbuch (userhosts.txt) dem Router Adressbuch hinzu."
msgstr "Dann fügt sie auch Ihr \"Master\"-Adressbuch (userhosts.txt) dem Router-Adressbuch hinzu."
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:127
msgid "If configured, the router addressbook is now written to the \"published\" addressbook, which will be publicly available if you are running an eepsite."
msgstr "Falls eingestellt wird das Router Adressbuch jetzt in das \"veröffentlichte\" Adressbuch kopiert, dieses ist öffentlich erreichbar sobald Sie eine Eepseite aktiv haben."
msgstr "Falls eingestellt, wird das Router-Adressbuch jetzt in das \"veröffentlichte\" Adressbuch kopiert. Dieses ist öffentlich erreichbar, solange Sie eine Eepseite betreiben."
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:129
msgid "The router also uses a private addressbook (privatehosts.txt, not shown in the picture), which is not merged or published."
@@ -406,29 +406,29 @@ msgstr "Hosts in Ihrem privatem Adressbuch können von Ihnen aufgerufen werden,
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:133
msgid "The private addressbook can also be used for aliases of hosts in your other addressbooks."
msgstr "Das private Adressbuch kann auch für Verweise auf Hosts in ihren anderen Adressbüchern genutzt werden."
msgstr "Das private Adressbuch kann auch für Verweise auf Hosts in Ihren anderen Adressbüchern genutzt werden."
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:132
msgid "The subscription file contains a list of i2p URLs."
msgstr "Die Abonnementdatei enthält eine Liste von I2P URLs."
msgstr "Die Abonnementdatei enthält eine Liste von I2P-URLs."
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:134
msgid "The addressbook application regularly checks this list for new eepsites."
msgstr "Die Adressbuchanwendung prüft diese Liste regelmässig auf neue Eepsites."
msgstr "Die Adressbuchanwendung prüft diese Liste regelmäßig auf neue Eepsites."
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:136
msgid "Those URLs refer to published hosts.txt files."
msgstr "Diese URLs verweisen auf veröffentlichte hosts.txt Dateien."
msgstr "Diese URLs verweisen auf veröffentlichte hosts.txt-Dateien."
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:138
msgid "The default subscription is the hosts.txt from www.i2p2.i2p, which is updated infrequently."
msgstr "Das standard Abonnement ist die hosts.txt Datei von www.i2p2.i2p, welche nicht regelmässig aktualisiert wird."
msgstr "Das standardabonnement ist die hosts.txt-Datei von www.i2p2.i2p, welche nicht regelmäßig aktualisiert wird."
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:140
msgid "So it is a good idea to add additional subscriptions to sites that have the latest addresses."
msgstr "Somit ist es eine gute Idee weitere Abonnement von Seiten mit den neuesten Adressen hinzuzufügen."
msgstr "Somit ist es eine gute Idee, weitere Abonnements von Seiten mit den neuesten Adressen hinzuzufügen."
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:142
msgid "See the FAQ for a list of subscription URLs."
msgstr "Schauen Sie in den FAQ nach einer Liste von Abonnement-URLs."
msgstr "Schauen Sie in den FAQ nach einer Liste von Abonnement-URLs!"

View File

@@ -0,0 +1,21 @@
Bundled in ../java/lib/ are the binaries for systray4j version 2.4.1 2004-03-28,
which is still the latest.
Files are from systray4j-2.4.1-win32.zip.
SHA1Sums:
28acaea97816f53d188d01fd88b72e670e67286b systray4j-2.4.1-win32.zip
a7f5e02c3652f3f1a72559e54ee69226b8b97859 systray4j.dll
947bd91c483494256cf48ad87c211e8701b4f85b systray4j.jar
systray4j is GPLv2, see LICENSE.systray4j.txt.
I2P systray code in ../java/src is public domain.
SysTray is really obsolete. It supports Windows and kde3 only.
We only instantiate it on Windows.
The java.awt.SystemTray classes added in Java 6
(and used by apps/desktopgui) are the way to go now.
We could either rewrite this to use SystemTray, or switch to desktopgui.

View File

@@ -184,4 +184,20 @@ public class SysTray implements SysTrayMenuListener {
_sysTrayMenu.addItem(_itemOpenConsole);
refreshDisplay();
}
/**
* Starts SysTray, even on linux (but requires kde3 libsystray4j.so to do anything)
* @since 0.8.1
*/
public static void main(String args[]) {
System.err.println("SysTray4j version " + SysTrayMenu.VERSION);
System.err.println("Hit ^C to exit");
new SysTray();
Thread t = Thread.currentThread();
synchronized(t) {
try {
t.wait();
} catch (InterruptedException ie) {}
}
}
}

View File

@@ -6,6 +6,14 @@
<!--
<property name="javac.compilerargs" value="-warn:-unchecked,raw,unused,serial" />
-->
<!-- Add Apache Harmony's Pack200 library if you don't have java.util.jar.Pack200
See core/java/src/net/i2p/util/FileUtil.java for code changes required
to use this library instead of Sun's version.
Or to comment it all out if you don't have either.
-->
<!--
<property name="javac.classpath" value="/PATH/TO/pack200.jar" />
-->
<!-- You probably don't want to change anything from here down -->
<target name="help" depends="all" />
@@ -29,6 +37,8 @@
<echo message=" javadoc: generate javadoc for the entire project into ./build/javadoc" />
<echo message=" slackpkg: generate Slackware packages in ./Slackware/i2p and ./Slackware/i2p-base" />
<echo message=" debianhowto: instructions on building Debian packages" />
<echo message=" debian: generate Debian packages (source + binary)" />
<echo message=" debianrepo: build a Debian repository (reprepro required)" />
<echo message=" updaterWithDesktopgui: tar the built files and desktopgui in an i2pupdate.zip" />
<echo message=" pkgWithDesktopgui: distclean then package everything up with the desktopgui" />
<echo message=" distWithDesktopgui: pkgWithDesktopgui and javadoc" />
@@ -149,12 +159,34 @@
<target name="javadoc">
<mkdir dir="./build" />
<mkdir dir="./build/javadoc" />
<!-- get release and build version numbers -->
<exec executable="grep" outputproperty="versionLine" >
<arg value="public final static String VERSION" />
<arg value="core/java/src/net/i2p/CoreVersion.java" />
</exec>
<exec executable="cut" inputstring="${versionLine}" outputproperty="release.number" >
<arg value="-f2" />
<arg value="-d&quot;" />
</exec>
<exec executable="grep" outputproperty="buildLine" >
<arg value="public final static long BUILD" />
<arg value="router/java/src/net/i2p/router/RouterVersion.java" />
</exec>
<exec executable="cut" inputstring="${buildLine}" outputproperty="build.temp" >
<arg value="-f2" />
<arg value="-d=" />
</exec>
<exec executable="cut" inputstring="${build.temp}" outputproperty="build.number" >
<arg value="-f1" />
<arg value="-d;" />
</exec>
<javadoc access="package"
destdir="./build/javadoc"
packagenames="*"
use="true"
splitindex="true"
windowtitle="I2P Anonymous Network - Java Documentation">
doctitle="I2P Javadocs for Release ${release.number} Build ${build.number}"
windowtitle="I2P Anonymous Network - Java Documentation - Version ${release.number}">
<group title="Core SDK (i2p.jar)" packages="net.i2p:net.i2p.*:net.i2p.client:net.i2p.client.*:freenet.support.CPUInformation:org.bouncycastle.crypto:org.bouncycastle.crypto.*:gnu.crypto.*:gnu.gettext:org.xlattice.crypto.filters:com.nettgryppa.security" />
<group title="Streaming Library" packages="net.i2p.client.streaming" />
<group title="Router" packages="net.i2p.router:net.i2p.router.*:net.i2p.data.i2np:org.cybergarage.*:org.freenetproject" />
@@ -192,6 +224,9 @@
<pathelement location="installer/lib/wrapper/win32/wrapper.jar" />
<pathelement location="core/lib/junit.jar" />
</classpath>
<link offline="true" href="http://download.oracle.com/javase/6/docs/api/" packagelistLoc="installer/resources/package-lists/java/" />
<link offline="true" href="http://docs.i2p2.de/jetty/javadoc/" packagelistLoc="installer/resources/package-lists/jetty/" />
<link offline="true" href="http://docs.i2p2.de/jrobin/javadoc/" packagelistLoc="installer/resources/package-lists/jrobin/" />
</javadoc>
</target>
<target name="clean" depends="pkgclean" >
@@ -204,7 +239,13 @@
</target>
<target name="distclean" depends="clean">
<delete dir="debian/tmp" />
<delete dir="debian/repo" />
<delete dir="debian/db" />
<delete file="debian/files" />
<delete file="debian/build" />
<delete>
<fileset dir=".." includes="i2p_*.tar.gz,i2p_*.deb,i2p_*.dsc,i2p_*.changes" />
</delete>
<ant dir="core/java/" target="distclean" />
<ant dir="router/java/" target="distclean" />
<ant dir="apps/ministreaming/java/" target="distclean" />
@@ -881,6 +922,20 @@
</target>
<target name="debian">
<!-- same as debian-binary + debian-source, but only one build needed -->
<echo message="Did you update the version in these files?" />
<exec executable="ls" failonerror="true">
<arg value="-l" />
<arg value="debian/changelog" />
</exec>
<echo message="====================" />
<!-- bundle the 20MB jetty 5 lib since there probably isn't a deb for it -->
<ant dir="apps/jetty" target="ensureJettylib" />
<exec executable="dpkg-buildpackage" failifexecutionfails="true">
<arg value="-I_MTN" />
</exec>
</target>
<target name="debian-binary">
<!-- binary only -->
<echo message="Did you update the version in these files?" />
<exec executable="ls" failonerror="true">
@@ -894,7 +949,7 @@
</target>
<target name="debian-source">
<!-- bundle the 20MB jetty 5 lib since there probably isn't a deb for it -->
<ant dir="apps/jetty" target="verifyJettylib" />
<ant dir="apps/jetty" target="ensureJettylib" />
<echo message="Did you update the version in these files?" />
<exec executable="ls" failonerror="true">
<arg value="-l" />
@@ -906,6 +961,9 @@
<arg value="-I_MTN" />
</exec>
</target>
<target name="debianrepo" depends="debian">
<exec dir="debian" executable="./makerepo.sh" failonerror="true"/>
</target>
<!-- the following are appened to help build barebone portable version,
none of the above is modified for this purpose -->

View File

@@ -17,10 +17,11 @@
</target>
<!-- only used if not set by a higher build.xml -->
<property name="javac.compilerargs" value="" />
<property name="javac.classpath" value="" />
<target name="compile" depends="depend">
<mkdir dir="./build" />
<mkdir dir="./build/obj" />
<javac srcdir="./src" debug="true" source="1.5" target="1.5" deprecation="on" destdir="./build/obj" >
<javac srcdir="./src" debug="true" source="1.5" target="1.5" deprecation="on" destdir="./build/obj" classpath="${javac.classpath}" >
<compilerarg line="${javac.compilerargs}" />
</javac>
</target>

View File

@@ -45,7 +45,7 @@ public interface I2PClient {
* the router how to handle the new session, and to configure the end to end
* encryption.
* @param destKeyStream location from which to read the Destination, PrivateKey, and SigningPrivateKey from
* @param options set of options to configure the router with
* @param options set of options to configure the router with, if null will use System properties
* @return new session allowing a Destination to recieve all of its messages and send messages to any other Destination.
*/
public I2PSession createSession(InputStream destKeyStream, Properties options) throws I2PSessionException;

View File

@@ -67,14 +67,14 @@ class I2PClientImpl implements I2PClient {
/**
* Create a new session (though do not connect it yet)
*
* @param options set of options to configure the router with, if null will use System properties
*/
public I2PSession createSession(InputStream destKeyStream, Properties options) throws I2PSessionException {
return createSession(I2PAppContext.getGlobalContext(), destKeyStream, options);
}
/**
* Create a new session (though do not connect it yet)
*
* @param options set of options to configure the router with, if null will use System properties
*/
public I2PSession createSession(I2PAppContext context, InputStream destKeyStream, Properties options) throws I2PSessionException {
return new I2PSessionMuxedImpl(context, destKeyStream, options); // thread safe and muxed

View File

@@ -137,6 +137,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
* Create a new session, reading the Destination, PrivateKey, and SigningPrivateKey
* from the destKeyStream, and using the specified options to connect to the router
*
* @param options set of options to configure the router with, if null will use System properties
* @throws I2PSessionException if there is a problem loading the private keys or
*/
public I2PSessionImpl(I2PAppContext context, InputStream destKeyStream, Properties options) throws I2PSessionException {
@@ -531,6 +532,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
/**
* Retrieve the configuration options
* @return non-null, if insantiated with null options, this will be the System properties.
*/
Properties getOptions() { return _options; }

View File

@@ -49,6 +49,7 @@ class I2PSessionImpl2 extends I2PSessionImpl {
* Create a new session, reading the Destination, PrivateKey, and SigningPrivateKey
* from the destKeyStream, and using the specified options to connect to the router
*
* @param options set of options to configure the router with, if null will use System properties
* @throws I2PSessionException if there is a problem loading the private keys or
*/
public I2PSessionImpl2(I2PAppContext ctx, InputStream destKeyStream, Properties options) throws I2PSessionException {
@@ -56,7 +57,7 @@ class I2PSessionImpl2 extends I2PSessionImpl {
_log = ctx.logManager().getLog(I2PSessionImpl2.class);
_sendingStates = new HashSet(32);
// default is BestEffort
_noEffort = "none".equalsIgnoreCase(options.getProperty(I2PClient.PROP_RELIABILITY));
_noEffort = "none".equalsIgnoreCase(getOptions().getProperty(I2PClient.PROP_RELIABILITY));
ctx.statManager().createRateStat("i2cp.sendBestEffortTotalTime", "how long to do the full sendBestEffort call?", "i2cp", new long[] { 10*60*1000 } );
//ctx.statManager().createRateStat("i2cp.sendBestEffortStage0", "first part of sendBestEffort?", "i2cp", new long[] { 10*60*1000 } );

View File

@@ -67,6 +67,9 @@ import net.i2p.util.SimpleScheduler;
class I2PSessionMuxedImpl extends I2PSessionImpl2 implements I2PSession {
private I2PSessionDemultiplexer _demultiplexer;
/*
* @param options set of options to configure the router with, if null will use System properties
*/
public I2PSessionMuxedImpl(I2PAppContext ctx, InputStream destKeyStream, Properties options) throws I2PSessionException {
super(ctx, destKeyStream, options);
// also stored in _sessionListener but we keep it in _demultipexer

View File

@@ -67,6 +67,10 @@ class LookupDest {
}
public static void main(String args[]) {
System.out.println(lookupBase32Hash(I2PAppContext.getGlobalContext(), args[0]));
Destination dest = lookupBase32Hash(I2PAppContext.getGlobalContext(), args[0]);
if (dest == null)
System.out.println("Destination not found!");
else
System.out.println(dest.toBase64());
}
}

View File

@@ -1076,7 +1076,8 @@ public class DataHelper {
}
/**
* Like formatSize but with a space after the number
* Like formatSize but with a non-breaking space after the number
* Use only in HTML
* @since 0.7.14
*/
public static String formatSize2(long bytes) {
@@ -1091,11 +1092,11 @@ public class DataHelper {
String str = fmt.format(val);
switch (scale) {
case 1: return str + " K";
case 2: return str + " M";
case 3: return str + " G";
case 4: return str + " T";
default: return bytes + " ";
case 1: return str + "&nbsp;K";
case 2: return str + "&nbsp;M";
case 3: return str + "&nbsp;G";
case 4: return str + "&nbsp;T";
default: return bytes + "&nbsp;";
}
}

View File

@@ -13,10 +13,18 @@ import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarOutputStream;
import java.util.jar.Pack200;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
// Pack200 import
// you must also uncomment the correct line in unpack() below
// For gcj, gij, etc., comment both out
//
// For Sun, OpenJDK, IcedTea, etc, use this
import java.util.jar.Pack200;
// For Apache Harmony or if you put its pack200.jar in your library directory use this
//import org.apache.harmony.unpack200.Archive;
/**
* General helper methods for messing with files
@@ -119,7 +127,7 @@ public class FileUtil {
if (entry.getName().endsWith(".jar.pack") || entry.getName().endsWith(".war.pack")) {
target = new File(targetDir, entry.getName().substring(0, entry.getName().length() - ".pack".length()));
JarOutputStream fos = new JarOutputStream(new FileOutputStream(target));
Pack200.newUnpacker().unpack(in, fos);
unpack(in, fos);
fos.close();
System.err.println("INFO: File [" + entry.getName() + "] extracted and unpacked");
} else {
@@ -189,9 +197,7 @@ public class FileUtil {
} else {
if (p200TestRequired &&
(entry.getName().endsWith(".jar.pack") || entry.getName().endsWith(".war.pack"))) {
try {
Class.forName("java.util.jar.Pack200", false, ClassLoader.getSystemClassLoader());
} catch (Exception e) { // ClassNotFoundException but compiler not happy with that
if (!isPack200Supported()) {
System.err.println("ERROR: Zip verify failed, your JVM does not support unpack200");
return false;
}
@@ -224,6 +230,40 @@ public class FileUtil {
}
}
/**
* This won't work right if one of the two options in unpack() is commented out.
* @since 0.8.1
*/
private static boolean isPack200Supported() {
try {
Class.forName("java.util.jar.Pack200", false, ClassLoader.getSystemClassLoader());
return true;
} catch (Exception e) {}
try {
Class.forName("org.apache.harmony.pack200.Archive", false, ClassLoader.getSystemClassLoader());
return true;
} catch (Exception e) {}
return false;
}
/**
* Caller must close streams
* @since 0.8.1
*/
private static void unpack(InputStream in, JarOutputStream out) throws Exception {
// For Sun, OpenJDK, IcedTea, etc, use this
Pack200.newUnpacker().unpack(in, out);
// ------------------
// For Apache Harmony or if you put its pack200.jar in your library directory use this
//(new Archive(in, out)).unpack();
// ------------------
// For gcj, gij, etc., use this
//throw new IOException("Pack200 not supported");
}
/**
* Read in the last few lines of a (newline delimited) textfile, or null if
* the file doesn't exist.
@@ -352,6 +392,18 @@ public class FileUtil {
boolean copied = FileUtil.copy(args[1], args[2], false);
if (!copied)
System.err.println("Error copying [" + args[1] + "] to [" + args[2] + "]");
} else if ("unzip".equals(args[0])) {
File f = new File(args[1]);
File to = new File("tmp");
to.mkdir();
boolean copied = verifyZip(f);
if (!copied)
System.err.println("Error verifying " + args[1]);
copied = extractZip(f, to);
if (copied)
System.err.println("Unzipped [" + args[1] + "] to [" + to + "]");
else
System.err.println("Error unzipping [" + args[1] + "] to [" + to + "]");
}
}

View File

@@ -13,6 +13,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
@@ -429,7 +430,8 @@ public class LogManager {
v = v.substring(0, v.length() - 1);
char mod = v.charAt(v.length() - 1);
if (!Character.isDigit(mod)) v = v.substring(0, v.length() - 1);
double val = Double.parseDouble(v);
// output to form was in current locale, so have to parse it back that way
double val = (new DecimalFormat()).parse(v.trim()).doubleValue();
switch (mod) {
case 'K':
val *= 1024;

View File

@@ -56,7 +56,7 @@ public class SecureFileOutputStream extends FileOutputStream {
* Tries to set the permissions to 600,
* ignores errors
*/
private static void setPerms(File f) {
public static void setPerms(File f) {
if (!canSetPerms)
return;
try {

5
debian/changelog vendored
View File

@@ -1,3 +1,8 @@
i2p (0.8.0-1) all; urgency=low
* I2P 0.8
* Debian packaging improvements
-- HungryHobo@i2pmail.org <HungryHobo@mail.i2p> Mon, 08 Nov 2010 17:14:57 +0000
i2p (0.7.10-0) testing; urgency=low
* tweaks
um...

8
debian/copyright vendored
View File

@@ -1,8 +0,0 @@
everything is released according to the
terms of the I2P license policy. For the I2P SDK,
that means everything contained within this
module is released into the public domain unless
otherwise marked. Alternate licenses that may be
used include BSD (used by thecrypto's DSA, ElGamal,
and SHA256 implementations), Cryptix (used by cryptix's
AES implementation), and MIT.

11
debian/copyright.part1 vendored Normal file
View File

@@ -0,0 +1,11 @@
This is the Debian package of I2P. The latest version of I2P can always be found at:
http://www.i2p2.de/
I2P was originally developed by jrandom and others. The main developer now is zzz.
See http://www.i2p2.de/team for a list of past and present developers.
I2P is maintained in Monotone. The current development version may be checked out
by issuing the following two commands:
mtn --db i2p.mtn dn init
mtn --db i2p.mtn co mtn.i2p2.de i2p.i2p

42
debian/makerepo.sh vendored Executable file
View File

@@ -0,0 +1,42 @@
#!/bin/bash
# This script creates a Debian repository in ${DIR} using the reprepro tool.
# The packages are signed with the key referenced in the newest changelog entry.
set -e
cd $(dirname $0)
DIR=./repo
CONFDIR=conf
CONFFILE=${CONFDIR}/distributions
SIGNER=`parsechangelog --file changelog | grep Maintainer | cut -d: -f2`
SIGNER=${SIGNER//^ /}
SIGNER=`echo ${SIGNER} | cut -d\ -f1`
KEYID=`gpg --list-keys "${SIGNER}" | cut -d: -f2 | grep -w pub | cut -d/ -f2 | cut -d\ -f1`
echo Using signing key: ${SIGNER}
echo Key ID: ${KEYID}
# creating the reprepro config file dynamically allows us to specify the signer
mkdir -p ${CONFDIR}
echo "Origin: I2P" > ${CONFFILE}
echo "Label: I2P Debian Repository" >> ${CONFFILE}
echo "Suite: all" >> ${CONFFILE}
echo "Codename: all" >> ${CONFFILE}
echo "Architectures: i386 amd64 source" >> ${CONFFILE}
echo "Components: main" >> ${CONFFILE}
echo "SignWith: ${SIGNER}" >> ${CONFFILE}
# create the repository
echo Building the repository...
reprepro --ask-passphrase --outdir ${DIR} includedeb all ../../i2p_*.deb
reprepro --ask-passphrase --outdir ${DIR} include all ../../i2p_*.changes
# export the public key
gpg --armor --export ${SIGNER} > ${DIR}/0x${KEYID}.asc
# remove the config file created above
echo Cleaning up...
rm -f ${CONFFILE}
rmdir ${CONFDIR}
echo Debian repository created in `pwd`/${DIR}.

14
debian/rules vendored
View File

@@ -23,6 +23,20 @@ build:
ln -s /usr/lib/i2p/i2prouter debian/tmp/usr/bin/i2prouter
rm debian/tmp/usr/lib/i2p/a
touch debian/build
mkdir -p debian/tmp/usr/share/doc/i2p
# Create the Debian copyright file, move the licenses dir,
# and delete all license files that are already in /usr/share/common-licenses/
cat debian/copyright.part1 LICENSE.txt > debian/tmp/usr/share/doc/i2p/copyright
mv debian/tmp/usr/lib/i2p/licenses debian/tmp/usr/share/doc/i2p
rm debian/tmp/usr/lib/i2p/LICENSE.txt
rm debian/tmp/usr/share/doc/i2p/licenses/LICENSE-Apache2.0.txt
rm debian/tmp/usr/share/doc/i2p/licenses/LICENSE-GPLv2.txt
rm debian/tmp/usr/share/doc/i2p/licenses/LICENSE-LGPLv2.1.txt
# changelog
gzip -9c history.txt > debian/tmp/usr/share/doc/i2p/changelog.gz
gzip -9c debian/changelog > debian/tmp/usr/share/doc/i2p/changelog.Debian.gz
binary: build
mkdir -p debian/tmp/DEBIAN

13
debian/scripts/postrm vendored
View File

@@ -1,14 +1,11 @@
#!/bin/sh
# $1 is either "remove" or "purge". Since there are no config
# files left after a remove, exit here if called with "purge".
# This avoids calling userdel again which would cause an error.
if [ "$1" = "purge" ]; then
exit 0;
fi
I2PUSER=i2psvc
exec userdel $I2PUSER
# delete $I2PUSER if it exists (it will not if this is a purge after a remove)
id $I2PUSER 2>/dev/null
if [ $? -eq 0 ]; then
exec userdel $I2PUSER
fi
# if somebody did updates in-network, there may be new files that dpkg
# doesn't know about, so just to be sure

View File

@@ -1,9 +1,172 @@
2010-11-08 zzz
* I2CP: Fix NPE caused by null session options (seen in i2pbote)
2010-11-06 HungryHobo
* New Ant target: debianrepo
* Rename debian target to debian-binary
* New debian target generates binary and source packages
* Debian tweaks
2010-11-03 zzz
* Merge and snark fixups
2010-11-01 zzz
* ClientConnectionRunner: Add synch to fix race causing AIOOBE
(http://forum.i2p/viewtopic.php?t=5061)
* configlogging.jsp: Parse log limit with current locale
(ticket #118)
* i2psnark:
- Limit number of parallel requests of a single piece when in the end game
- Shorten and weight the speed tracker so the display is more
reflective of current speed
* logs.jsp: Add message if wrapper log not found
(ticket #103)
2010-10-30 zzz
* i2psnark:
- Priority mapping bugfix
- Close files as we go when creating/checking
so we don't run out of file descriptors
- Update request queues after priority change
- Only add wanted pieces to wanted list at startup
- Make sure lastRequest is null when it should be
- Delay during StopAll so we don't close the tunnel before the
stopped announces go out and reopen it
- Logging tweaks
2010-10-27 zzz
* i2psnark:
- Don't stay interested if we run out of pieces
to request (thanks sponge)
- Enhance debug mode to show requests
- Priority mapping bugfix
* Transport: Avoid rare NPE at startup
2010-10-24 zzz
* FileUtil: Make it easier to compile without Pack200, or with
Apache Harmony's Pack200, add unzip to main()
* i2psnark: Catch a race after disconnect()
* NTCP: Catch a race after stop()
* Router: Set permissions on wrapper.log when not called by RouterLaunch
* Systray: New doc and main()
2010-10-22 sponge
* Sanity and some fixs for slackware package
2010-10-22 sponge
* Fix rc.i2p for slackware package
2010-10-19 zzz
* Escape & in logs and i2psnark (much more to do)
* JobImpl: Deprecate two debugging methods
* replaceAll() -> replace() when we don't need regex
2010-10-15 zzz
* i2psnark: Add file priority feature
* I2PSocketEepGet: Set connect delay to save a RTT, will
speed announces in i2psnark
2010-10-12 zzz
*** 1.6 or higher JDK now required to build
* configlogging.jsp:
- Add easy way to add an override
- Make file size specifier more flexible
* Console:
- Sort RouterAddress options on netdb.jsp and peers.jsp
- Remove unused web-*.xml file from war
* Crypto:
- Convert all ArrayList caching to LBQs in YKGenerator,
HMACGenerator, and AESKeyCache.
- Change DSAEngine params from Hash to new SHA1Hash, since
these were really 20 byte hashes, not 32 byte Hashes.
- Add stats to track YKGenerator caching success
- Fix YKGenerator precalculation to be much more useful by
increasing the cache size and dramatically shortening the delay
- Option cleanups
- YKGenerator cleanups
- Mark HMAC256Generator unused
* EepGet: Reset length variable on redirect
* Files: Change permissions to 600/700 for all written files/directories.
Now requires Java 1.6 to build, but only 1.5+ to run.
(requires 1.6 to set permissiomns)
* GeoIP: Fix locking bug causing lookups to stop
* Hash: Throw IAE if data length is not 32 bytes,
now that DSAEngine abuse is gone
* HTTPResponseOutputStream:
- More caching
- Stats cleanup
- Max header length check
- Catch OOM
- Initializer cleanup
- Javadoc
* I2CP:
- Add new option i2cp.messageReliability=none, which prevents the
router from sending MessageStatusMessages back in reply to an
outbound SendMessageMessage. Since the streaming lib always ignored
the MSMs anyway, make it the default for streaming.
This will reduce the I2CP traffic significantly.
MSM handling now avoided, but it is still fairly broken, see
comments in I2PSessionImpl2.
- Cleanups to replace method calls with fields
- More cleanups, javadoc, rate reduction
* i2psnark:
- Compact response format
- Add link to finished torrent in message box
- Don't let one bad torrent prevent others from
starting or stopping
- Sort peers by completion %
- Add some missing mime types to web.xml
- shouldLog() cleanup
* i2ptunnel:
- Now that streaming flush() is fixed, use it in IRCClient, and
for initial data in I2PTunnel runner, to avoid the 250 ms
passive flush delay
- Add hostname DSA signature field, to be used for addkey forms.
Experimental, may be commented out later.
- More header blocking (thanks telecomix!)
- Remove unused web-*.xml file from war
* Installer: Add startup hint for non-x86
* Javadoc updates all over the place
* LogConsoleBuffer: Java 5
* Naming:
- Increase cache size and expiration time
- Add clearCache() method
- Don't use EepGet or Exec for b32
- Javadoc updates
* NetDB:
- Expire unreachable routers quickly, even if they don't have introducers,
so we don't have old data on routers that ran out of introducers.
- Fix rare NPEs at shutdown
* NTCP:
- Cleanups
* Streaming:
- Make flush() block less, by waiting only for "accept" into the
streaming queue rather than "completion" (i.e. ACK from the far end).
This prevents complete stalls when flushing, and should help performance
of apps that use flush(), like i2psnark (and SAM?).
close() still does a flush that waits for completion, as i2ptunnel
doesn't like a fast return from close().
- cleanups
* SusiDNS:
- Remove unused web-*.xml file from war
* TransportManager: Convert _transports from a List to a CHM
to prevent a rare concurrent exception
* Tunnels:
- Don't use peers < 0.7.9 for tunnels due to the old
message corruption bugs
- Javadoc
- Cleanups
* UDP:
- Beginnings of destroy message support
- Try to avoid running out of introducers by relaxing selection criteria
and increasing minimum number of potential introducers
- Avoid rare AIOOBE
- PacketBuilder refactor
- Make most classes package private
- Comments
- Logging cleanup
- Comment out a main()
2010-10-10 sponge
* Fulfill Request for name resolving in BOB

View File

@@ -24,21 +24,21 @@ Point your IRC client to <b>localhost:6668</b> and say hi to us on
</div>
<div lang="de">
<h4><ul><li>Gratulation zur erfolgreichen Installation von I2P!</li></ul></h4>
<h4><ul><li>Wir gratulatieren zur erfolgreichen Installation von I2P!</li></ul></h4>
<p>
<b>Willkommen bei I2P!</b>
Bitte noch <b>etwas Geduld</b> w&auml;hrend I2P startet und weitere I2P Router findet.
<b>Willkommen im I2P!</b>
Hab noch <b>etwas Geduld</b>, w&auml;hrend I2P startet und weitere I2P-Router findet.
</p>
<p>
Passe bitte In der Wartezeit <b>deine Einstellungen zur Bandbreite</b> auf der
<a href="config.jsp">Einstellungsseite</a> an.
Passe bitte in der Zwischenzeit <b>deine Einstellungen zur Bandbreite</b> auf der
<a href="config.jsp">Einstellungsseite</a> an!
</p>
<p>
Sobald auf der linken Seite eine "shared clients" Verbindung aufgelistet ist <b>besuche bitte</b> unsere <a href="http://www.i2p2.i2p/faq_de.html">FAQ</a>.
Sobald auf der linken Seite eine Verbindung namens "versch. Klienten" aufgelistet ist, kannst Du unsere <a href="http://www.i2p2.i2p/faq_de.html">FAQ</a> besuchen.
</p>
<p>
Verbinde deinen IRC Klienten mit dem Server auf <b>localhost:6668</b> und sage Hallo zu uns im Kanal
<a href="irc://127.0.0.1:6668/i2p-help">#i2p-help</a>, <a href="irc://127.0.0.1:6668/i2p-de">#i2p-de</a> oder <a href="irc://127.0.0.1:6668/i2p">#i2p</a>.
Verbinde deinen IRC-Klienten mit dem Server auf <b>localhost:6668</b> und schau bei uns im Kanal
<a href="irc://127.0.0.1:6668/i2p-help">#i2p-help</a>, <a href="irc://127.0.0.1:6668/i2p-de">#i2p-de</a> oder <a href="irc://127.0.0.1:6668/i2p">#i2p</a> vorbei!
</p>
</div>

View File

@@ -0,0 +1,203 @@
java.applet
java.awt
java.awt.color
java.awt.datatransfer
java.awt.dnd
java.awt.event
java.awt.font
java.awt.geom
java.awt.im
java.awt.im.spi
java.awt.image
java.awt.image.renderable
java.awt.print
java.beans
java.beans.beancontext
java.io
java.lang
java.lang.annotation
java.lang.instrument
java.lang.management
java.lang.ref
java.lang.reflect
java.math
java.net
java.nio
java.nio.channels
java.nio.channels.spi
java.nio.charset
java.nio.charset.spi
java.rmi
java.rmi.activation
java.rmi.dgc
java.rmi.registry
java.rmi.server
java.security
java.security.acl
java.security.cert
java.security.interfaces
java.security.spec
java.sql
java.text
java.text.spi
java.util
java.util.concurrent
java.util.concurrent.atomic
java.util.concurrent.locks
java.util.jar
java.util.logging
java.util.prefs
java.util.regex
java.util.spi
java.util.zip
javax.accessibility
javax.activation
javax.activity
javax.annotation
javax.annotation.processing
javax.crypto
javax.crypto.interfaces
javax.crypto.spec
javax.imageio
javax.imageio.event
javax.imageio.metadata
javax.imageio.plugins.bmp
javax.imageio.plugins.jpeg
javax.imageio.spi
javax.imageio.stream
javax.jws
javax.jws.soap
javax.lang.model
javax.lang.model.element
javax.lang.model.type
javax.lang.model.util
javax.management
javax.management.loading
javax.management.modelmbean
javax.management.monitor
javax.management.openmbean
javax.management.relation
javax.management.remote
javax.management.remote.rmi
javax.management.timer
javax.naming
javax.naming.directory
javax.naming.event
javax.naming.ldap
javax.naming.spi
javax.net
javax.net.ssl
javax.print
javax.print.attribute
javax.print.attribute.standard
javax.print.event
javax.rmi
javax.rmi.CORBA
javax.rmi.ssl
javax.script
javax.security.auth
javax.security.auth.callback
javax.security.auth.kerberos
javax.security.auth.login
javax.security.auth.spi
javax.security.auth.x500
javax.security.cert
javax.security.sasl
javax.sound.midi
javax.sound.midi.spi
javax.sound.sampled
javax.sound.sampled.spi
javax.sql
javax.sql.rowset
javax.sql.rowset.serial
javax.sql.rowset.spi
javax.swing
javax.swing.border
javax.swing.colorchooser
javax.swing.event
javax.swing.filechooser
javax.swing.plaf
javax.swing.plaf.basic
javax.swing.plaf.metal
javax.swing.plaf.multi
javax.swing.plaf.synth
javax.swing.table
javax.swing.text
javax.swing.text.html
javax.swing.text.html.parser
javax.swing.text.rtf
javax.swing.tree
javax.swing.undo
javax.tools
javax.transaction
javax.transaction.xa
javax.xml
javax.xml.bind
javax.xml.bind.annotation
javax.xml.bind.annotation.adapters
javax.xml.bind.attachment
javax.xml.bind.helpers
javax.xml.bind.util
javax.xml.crypto
javax.xml.crypto.dom
javax.xml.crypto.dsig
javax.xml.crypto.dsig.dom
javax.xml.crypto.dsig.keyinfo
javax.xml.crypto.dsig.spec
javax.xml.datatype
javax.xml.namespace
javax.xml.parsers
javax.xml.soap
javax.xml.stream
javax.xml.stream.events
javax.xml.stream.util
javax.xml.transform
javax.xml.transform.dom
javax.xml.transform.sax
javax.xml.transform.stax
javax.xml.transform.stream
javax.xml.validation
javax.xml.ws
javax.xml.ws.handler
javax.xml.ws.handler.soap
javax.xml.ws.http
javax.xml.ws.soap
javax.xml.ws.spi
javax.xml.ws.wsaddressing
javax.xml.xpath
org.ietf.jgss
org.omg.CORBA
org.omg.CORBA.DynAnyPackage
org.omg.CORBA.ORBPackage
org.omg.CORBA.TypeCodePackage
org.omg.CORBA.portable
org.omg.CORBA_2_3
org.omg.CORBA_2_3.portable
org.omg.CosNaming
org.omg.CosNaming.NamingContextExtPackage
org.omg.CosNaming.NamingContextPackage
org.omg.Dynamic
org.omg.DynamicAny
org.omg.DynamicAny.DynAnyFactoryPackage
org.omg.DynamicAny.DynAnyPackage
org.omg.IOP
org.omg.IOP.CodecFactoryPackage
org.omg.IOP.CodecPackage
org.omg.Messaging
org.omg.PortableInterceptor
org.omg.PortableInterceptor.ORBInitInfoPackage
org.omg.PortableServer
org.omg.PortableServer.CurrentPackage
org.omg.PortableServer.POAManagerPackage
org.omg.PortableServer.POAPackage
org.omg.PortableServer.ServantLocatorPackage
org.omg.PortableServer.portable
org.omg.SendingContext
org.omg.stub.java.rmi
org.w3c.dom
org.w3c.dom.bootstrap
org.w3c.dom.events
org.w3c.dom.ls
org.xml.sax
org.xml.sax.ext
org.xml.sax.helpers

View File

@@ -0,0 +1,37 @@
javax.servlet
javax.servlet.http
javax.servlet.jsp
javax.servlet.jsp.el
javax.servlet.jsp.tagext
org.mortbay.ftp
org.mortbay.html
org.mortbay.http
org.mortbay.http.ajp
org.mortbay.http.ajp.jmx
org.mortbay.http.handler
org.mortbay.http.handler.jmx
org.mortbay.http.ibmjsse
org.mortbay.http.jmx
org.mortbay.http.nio
org.mortbay.jaas
org.mortbay.jaas.callback
org.mortbay.jaas.spi
org.mortbay.jetty
org.mortbay.jetty.jmx
org.mortbay.jetty.plus
org.mortbay.jetty.plus.jmx
org.mortbay.jetty.servlet
org.mortbay.jetty.servlet.jmx
org.mortbay.jetty.win32
org.mortbay.jndi
org.mortbay.jndi.java
org.mortbay.jndi.local
org.mortbay.loadbalancer
org.mortbay.log
org.mortbay.log4j
org.mortbay.servlet
org.mortbay.start
org.mortbay.stop
org.mortbay.util
org.mortbay.util.jmx
org.mortbay.xml

View File

@@ -0,0 +1,2 @@
org.jrobin.core
org.jrobin.graph

View File

@@ -1,78 +1,78 @@
<div lang="de">
<div align="right">
<div class="langbox" align="right"><a href="/index.jsp?lang=en"><img src="/flags.jsp?c=us" title="English" alt="English"></a> <a href="/index.jsp?lang=zh"><img src="/flags.jsp?c=cn" title="Chinese" alt="Chinese"></a> <a href="/index.jsp?lang=de"><img src="/flags.jsp?c=de" title="Deutsch" alt="Deutsch"></a> <a href="/index.jsp?lang=fr"><img src="/flags.jsp?c=fr" title="Fran&ccedil;ais" alt="Fran&ccedil;ais"></a> <a href="/index.jsp?lang=nl"><img src="/flags.jsp?c=nl" title="Nederlands" alt="Nederlands"></a> <a href="/index.jsp?lang=ru"><img src="/flags.jsp?c=ru" title="Русский" alt="Русский"></a> <a href="/index.jsp?lang=sv"><img src="/flags.jsp?c=se" title="Svenska" alt="Svenska"></a></div>
</div>
<div class="welcome"><h2>Willkommen zu I2P!</h2></div>
<p>Wenn Du gerade I2P gestartet hast, sollten die "Active:" Zahlen links in den n&auml;chsten paar Minuten anwachsen und Du siehst dann dort ein "shared clients" lokales Ziel gelistet (falls nicht, <a href="#trouble">siehe Unten</a>). Sobald das erscheint, kannst Du:</p>
<ul>
<li><b>"Eepsites" besuchen</b> - In I2P sind anonym gehostete Websites -
Stelle Deinen Browser so ein, &uuml;ber den <b>HTTP proxy: 127.0.0.1 port 4444</b> zu surfen, dann besuche eine Eepsite:<br>
<ul class="links">
<li><a href="http://forum.i2p/">forum.i2p</a>: Eine sichere und anonyme Verbindung zu <a href="http://forum.i2p2.de/">forum.i2p2.de</a></li>
<li><a href="http://www.i2p2.i2p/index_de.html">www.i2p2.i2p</a> und der Spiegel <a href="http://i2p-projekt.i2p/index_de.html">i2p-projekt.i2p</a>:
Sichere und anonyme Verbindung zu <a href="http://www.i2p2.de/index_de.html">www.i2p2.de</a></li>
<li><a href="http://eepsites.i2p/">eepsites.i2p</a>: Eine anonym gehostete Suchseite f&uuml;r Eepsites</li>
<li><a href="http://ugha.i2p/">ugha.i2p</a>: Ugha's Eepsite, ein &ouml;ffentliches Wiki mit vielen Links</li>
<li><a href="http://fproxy.tino.i2p">fproxy.tino.i2p</a>: Freenet proxy</li>
<li><a href="http://echelon.i2p">echelon.i2p</a>: Software Archive und Informationen zu I2P</li>
<li><a href="http://paste.i2p2.i2p">paste.i2p2.i2p</a>: Anonymer Pastebin</li>
</ul><br />
Es gibt viel mehr Eepsites - folge einfach den Links die du findest,
bookmarke Deine Favoriten und besuche sie oft!</li><br />
<li class="tidylist"><b>Im Internet surfen</b> - Es gibt einen HTTP "outproxy" in I2P in Deinem
HTTP proxy auf Port 4444 - Konfiguriere Deine Browser's Proxy Einstellung
darauf (siehe Oben) und besuche jede normale URL - Deine Anfrage wird
durch das I2P Netzwerk geroutet.</li>
<li class="tidylist"><b>Daten austauschen</b> - Es gibt eine <a href="i2psnark/">Portierung</a> des
<a href="http://www.klomp.org/snark/">Snark</a> <a href="http://www.bittorrent.com/">BitTorrent</a>
Clients.</li>
<li class="tidylist"><b>Anonyme Email</b> - Postman hat ein Email System aufgebaut, das
kompatibel mit normalen Email-Clients (POP3 / SMTP) ist, welches erlaubt,
Email innerhalb von I2P sowie Email von und zum normalen Internet zu
schicken! Hole Dir Dein Emailkonto auf <a href="http://hq.postman.i2p/">hq.postman.i2p</a>.
Im Verbund dazu haben wir <a href="/susimail/susimail">susimail</a>, ein
Internet-Browser basierter, anonymer pop3/smtp Client, fertig eingerichtet
f&uuml;r Postman's Email Service.</li>
<li class="tidylist"><b>Anonymer Chat</b> - Starte Deinen Lieblings IRC Client und verbinde ihn
mit dem Server <b>127.0.0.1 Port 6668</b>. Das richtet Dich auf auf einen
von zwei anonym gehosteten IRC Servern, aber weder Du noch die wissen wer
der Andere ist.</li>
<li class="tidylist"><b>Anonymer Blog</b> - Probiere <a href="http://syndie.i2p2.de/">Syndie</a> aus</li>
<li class="tidylist">und Vieles mehr</li>
</ul>
<h2>Willst Du Deine eigene Eepsite?</h2>
<p>Wir bringen Software mit, damit Du Deine eigene Eepsite laufen lassen kannst
- Eine
<a href="http://jetty.mortbay.org/">Jetty</a> Instanz horcht auf
<a href="http://127.0.0.1:7658/">http://127.0.0.1:7658/</a>. Platziere einfach
Deine Dateien in das <code>eepsite/docroot/</code> Verzeichnis (oder jedes
Standard-JSP/Servlet <code>.war</code> unter <code>eepsite/webapps</code>,
oder CGI Scripte unter <code>eepsite/cgi-bin</code>) und schon sind sie
verf&uuml;gbar. Nach dem Start des <a href="/i2ptunnel/">Eepsite tunnels</a>
der darauf zeigt ist Deine Eepsite f&uuml;r Andere verf&uuml;gbar.
Detailierte Instruktionen zum Start Deiner eigenen Eepsite sind auf
<a href="http://127.0.0.1:7658/">Deine tempor&auml;re Eepsite</a>.
</p>
<h2><a name="trouble">Troubleshooting</a></h2>
<p>Sei geduldig - Am Anfang des ersten Starts kann I2P lange brauchen, da es
dann Verbindungen sucht. Falls nach 30 Minuten Deine
"Active: connected/recent" Zahl noch immer weniger als 10 Verbindungen
aufzeigt, solltest Du den I2P Port auf Deiner Firewall &ouml;ffnen um
f&uuml;r bessere Verbindung zu sorgen. Den bei dir benutzten I2P Port
(bei jeder Installation setzt I2P einen anderen) siehst Du auf der
<a href="config.jsp">Konfigurationsseite</a>.
Wenn Du gar keine Eepsites bekommst (auch nicht
<a href="http://www.i2p2.i2p/index_de.html">www.i2p2.i2p</a>), stelle sicher, dass Dein
Internet Browser auf den Proxy 127.0.0.1 Port 4444 eingestellt ist.
Vielleicht m&ouml;chtest Du auch die Informationen lesen, die auf der
<a href="http://www.i2p2.i2p/index_de.html">I2P website</a> sind, Nachrichten lesen und
ins <a href="http://forum.i2p2.de/">I2P discussion forum</a> posten, oder
chatten auf
<a href="irc://127.0.0.1:6668/i2p-help">#i2p-help</a>, <a href="irc://127.0.0.1:6668/i2p-de">#i2p-de</a>, <a href="irc://127.0.0.1:6668/i2p">#i2p</a> oder <a href="irc://127.0.0.1:6668/i2p-chat">#i2p-chat</a>
beim IRC auf
<a href="irc://irc.freenode.net/#i2p">irc.freenode.net</a>, irc.postman.i2p
oder irc.freshcoffee.i2p (die verbunden sind).</p><hr />
<div align="right">
<div class="langbox" align="right"><a href="/index.jsp?lang=en"><img src="/flags.jsp?c=us" title="English" alt="English"></a> <a href="/index.jsp?lang=zh"><img src="/flags.jsp?c=cn" title="Chinese" alt="Chinese"></a> <a href="/index.jsp?lang=de"><img src="/flags.jsp?c=de" title="Deutsch" alt="Deutsch"></a> <a href="/index.jsp?lang=fr"><img src="/flags.jsp?c=fr" title="Fran&ccedil;ais" alt="Fran&ccedil;ais"></a> <a href="/index.jsp?lang=nl"><img src="/flags.jsp?c=nl" title="Nederlands" alt="Nederlands"></a> <a href="/index.jsp?lang=ru"><img src="/flags.jsp?c=ru" title="Русский" alt="Русский"></a> <a href="/index.jsp?lang=sv"><img src="/flags.jsp?c=se" title="Svenska" alt="Svenska"></a></div>
</div>
<div class="welcome"><h2>Willkommen im I2P!</h2></div>
<p>Wenn Du I2P gerade gestartet hast, sollten die "Active:"-Zahlen links in den n&auml;chsten paar Minuten anwachsen, und Du siehst dann dort ein als "gemeinsam benutzt" bezeichnetes lokales Ziel gelistet (falls nicht, <a href="#trouble">siehe Unten</a>). Sobald das erscheint, kannst Du:</p>
<ul>
<li><b>"Eepsites" besuchen</b> - In I2P gibt es anonym gehostete Websites:
Konfiguriere Deinen Browser, &uuml;ber den <b>HTTP-Proxy: 127.0.0.1 Port 4444</b> zu surfen, dann besuche eine Eepsite:<br>
<ul class="links">
<li><a href="http://forum.i2p/">forum.i2p</a>: Eine sichere und anonyme Verbindung zu <a href="http://forum.i2p2.de/">forum.i2p2.de</a></li>
<li><a href="http://www.i2p2.i2p/index_de.html">www.i2p2.i2p</a> und der Spiegel <a href="http://i2p-projekt.i2p/index_de.html">i2p-projekt.i2p</a>:
Sichere und anonyme Verbindungen zu <a href="http://www.i2p2.de/index_de.html">www.i2p2.de</a></li>
<li><a href="http://eepsites.i2p/">eepsites.i2p</a>: Eine anonym gehostete Suchseite f&uuml;r Eepsites</li>
<li><a href="http://ugha.i2p/">ugha.i2p</a>: Ugha's Eepsite, ein &ouml;ffentliches Wiki mit vielen Links</li>
<li><a href="http://fproxy.tino.i2p">fproxy.tino.i2p</a>: ein Freenet-Proxy</li>
<li><a href="http://echelon.i2p">echelon.i2p</a>: Software-Archive und Informationen zu I2P (mit BitTorrent-Klienten, I2P-Messenger, I2P-Bote, ...)</li>
<li><a href="http://paste.i2p2.i2p">paste.i2p2.i2p</a>: Anonymer Pastebin</li>
</ul><br />
Es gibt viele andere Eepsites - folge einfach den Links, die du findest,
bookmarke Deine Favoriten und besuche sie oft!</li><br />
<li class="tidylist"><b>Im Internet surfen</b> - Es gibt in I2P einen HTTP-"Outproxy". Um ihn zu nutzen, kannst du ebenfalls den
HTTP-Proxy auf Port 4444 verwenden - Konfiguriere Deines Browsers Proxy-Einstellungen
darauf (siehe oben) und besuche jede normale URL - Deine Anfrage wird dann anonym
durch das I2P Netzwerk geroutet.</li>
<li class="tidylist"><b>Daten austauschen</b> - Es gibt eine <a href="i2psnark/">Portierung</a> des
<a href="http://www.klomp.org/snark/">Snark</a> <a href="http://www.bittorrent.com/">BitTorrent</a>-Klienten.</li>
<li class="tidylist"><b>Anonyme Email</b> - Postman hat ein Email-System aufgebaut, das
kompatibel zu normalen Email-Clients (POP3/SMTP) ist, und welches es erlaubt,
Emails innerhalb von I2P sowie Emails von und ins normale Internet zu
schicken! Hole Dir Dein Emailkonto auf <a href="http://hq.postman.i2p/">hq.postman.i2p</a>.
Im Verbund damit haben wir <a href="/susimail/susimail">susimail</a>, ein
browserbasierter, anonymer POP3/SMTP-Klient, fertig eingerichtet
f&uuml;r Postmans Email-Service.</li>
<li class="tidylist"><b>Anonymer Chat</b> - Starte Deinen Lieblings-IRC-Klienten und verbinde ihn
mit dem Server <b>127.0.0.1 Port 6668</b>. Das bringt Dich auf auf einen
von zwei anonym gehosteten IRC-Servern - aber weder Du noch die anderen Benutzer wissen, wer
der jeweils andere ist, nicht einmal der Server-Administrator.</li>
<li class="tidylist"><b>Anonymer Blog</b> - Probiere <a href="http://syndie.i2p2.de/">Syndie</a> aus</li>
<li class="tidylist">und vieles mehr</li>
</ul>
<h2>Willst Du Deine eigene Eepsite?</h2>
<p>I2P kommt mit Software, die es Dir erm&ouml;glicht, Deine eigene Eepsite laufen zu lassen
- Eine
<a href="http://jetty.mortbay.org/">Jetty</a>-Instanz horcht auf
<a href="http://127.0.0.1:7658/">http://127.0.0.1:7658/</a>. Platziere einfach
Deine Dateien im Verzeichnis <code>eepsite/docroot/</code> (oder jedes
Standard-JSP/Servlet <code>.war</code> unter <code>eepsite/webapps</code>,
CGI Scripte unter <code>eepsite/cgi-bin</code>) und schon sind sie
verf&uuml;gbar. Nach dem Start des <a href="/i2ptunnel/">Eepsite Tunnels</a>,
der darauf zeigt, ist Deine Eepsite f&uuml;r andere verf&uuml;gbar.
Detailierte Instruktionen zum Start Deiner eigenen Eepsite sind auf
<a href="http://127.0.0.1:7658/">Deiner tempor&auml;ren Eepsite</a>.
</p>
<h2><a name="trouble">Problembehebung</a></h2>
<p>Hab Geduld, denn nach dem ersten Start kann I2P lange brauchen, da es
dann Verbindungen sucht und das Netzwerk kennenlernen muss. Falls nach 30 Minuten Deine
die Zahl deiner aktiven Verbindungen (im Seitenpanel unter "Teilnehmer" die Zahl hinter "Aktiv:") noch immer geringer als 10 ist,
solltest Du den I2P-Port auf Deiner Firewall &ouml;ffnen, um
f&uuml;r bessere Verbindung zu sorgen. Den bei dir von I2P benutzten Port
(bei jeder Installation setzt I2P einen anderen) siehst Du auf der
<a href="config.jsp">Konfigurationsseite</a>.
Wenn Du gar keine Eepsites erreichen kannst (auch nicht
<a href="http://www.i2p2.i2p/index_de.html">www.i2p2.i2p</a>), dann stell sicher, dass Dein
Internet-Browser auf den Proxy 127.0.0.1 Port 4444 eingestellt ist!
Vielleicht m&ouml;chtest Du auch die Informationen lesen, die auf der
<a href="http://www.i2p2.i2p/index_de.html">I2P-Website</a> stehen, Nachrichten lesen und
im <a href="http://forum.i2p2.de/">I2P-Forum</a> posten, oder
in
<a href="irc://127.0.0.1:6668/i2p-help">#i2p-help</a>, <a href="irc://127.0.0.1:6668/i2p-de">#i2p-de</a>, <a href="irc://127.0.0.1:6668/i2p">#i2p</a> oder <a href="irc://127.0.0.1:6668/i2p-chat">#i2p-chat</a>
auf
irc.postman.i2p
oder irc.freshcoffee.i2p chatten. (Beide unter <a href="irc://localhost:6668">irc://localhost:6668</a> erreichbar; die Server sind verbunden.) Wenn Du keinen Zugriff auf I2P hast, kannst du #i2p, #i2p-help und #i2p-de auch auf <a href="irc://irc.freenode.net/#i2p">irc.freenode.net</a> erreichen, dann allerdings nicht anonym.</p><hr />
</div>

View File

@@ -39,11 +39,21 @@ public abstract class JobImpl implements Job {
return buf.toString();
}
/**
* @deprecated
* As of 0.8.1, this is a noop, as it just adds classes to the log manager
* class list for no good reason. Logging in jobs is almost always
* set explicitly rather than by class name.
*/
void addedToQueue() {
if (_context.logManager().getLog(getClass()).shouldLog(Log.DEBUG))
_addedBy = new Exception();
//if (_context.logManager().getLog(getClass()).shouldLog(Log.DEBUG))
// _addedBy = new Exception();
}
/**
* @deprecated
* @return null always
*/
public Exception getAddedBy() { return _addedBy; }
public long getMadeReadyOn() { return _madeReadyOn; }
public void madeReady() { _madeReadyOn = _context.clock().now(); }

View File

@@ -142,8 +142,9 @@ public class JobQueue {
public void addJob(Job job) {
if (job == null || !_alive) return;
if (job instanceof JobImpl)
((JobImpl)job).addedToQueue();
// This does nothing
//if (job instanceof JobImpl)
// ((JobImpl)job).addedToQueue();
long numReady = 0;
boolean alreadyExists = false;

View File

@@ -218,6 +218,19 @@ public class Router {
// NOW we start all the activity
_context.initAll();
// Set wrapper.log permissions.
// Just hope this is the right location, we don't know for sure,
// but this is the same method used in LogsHelper and we have no complaints.
// (we could look for the wrapper.config file and parse it I guess...)
// If we don't have a wrapper, RouterLaunch does this for us.
if (System.getProperty("wrapper.version") != null) {
File f = new File(System.getProperty("java.io.tmpdir"), "wrapper.log");
if (!f.exists())
f = new File(_context.getBaseDir(), "wrapper.log");
if (f.exists())
SecureFileOutputStream.setPerms(f);
}
_routerInfo = null;
_higherVersionSeen = false;
_log = _context.logManager().getLog(Router.class);

View File

@@ -18,10 +18,10 @@ public class RouterVersion {
/** deprecated */
public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 05;
public final static long BUILD = 11;
/** for example "-test" */
public final static String EXTRA = "";
public final static String EXTRA = "-rc";
public final static String FULL_VERSION = VERSION + "-" + BUILD + EXTRA;
public static void main(String args[]) {
System.out.println("I2P Router version: " + FULL_VERSION);

View File

@@ -361,18 +361,21 @@ public class ClientConnectionRunner {
// TunnelPool.locked_buildNewLeaseSet() ensures that leases are sorted,
// so the comparison will always work.
int leases = set.getLeaseCount();
if (_currentLeaseSet != null && _currentLeaseSet.getLeaseCount() == leases) {
for (int i = 0; i < leases; i++) {
if (! _currentLeaseSet.getLease(i).getTunnelId().equals(set.getLease(i).getTunnelId()))
break;
if (! _currentLeaseSet.getLease(i).getGateway().equals(set.getLease(i).getGateway()))
break;
if (i == leases - 1) {
if (_log.shouldLog(Log.INFO))
_log.info("Requested leaseSet hasn't changed");
if (onCreateJob != null)
_context.jobQueue().addJob(onCreateJob);
return; // no change
// synch so _currentLeaseSet isn't changed out from under us
synchronized (this) {
if (_currentLeaseSet != null && _currentLeaseSet.getLeaseCount() == leases) {
for (int i = 0; i < leases; i++) {
if (! _currentLeaseSet.getLease(i).getTunnelId().equals(set.getLease(i).getTunnelId()))
break;
if (! _currentLeaseSet.getLease(i).getGateway().equals(set.getLease(i).getGateway()))
break;
if (i == leases - 1) {
if (_log.shouldLog(Log.INFO))
_log.info("Requested leaseSet hasn't changed");
if (onCreateJob != null)
_context.jobQueue().addJob(onCreateJob);
return; // no change
}
}
}
}
@@ -590,7 +593,7 @@ public class ClientConnectionRunner {
+ " for session [" + _sessionId.getSessionId()
+ "] (with nonce=2), retrying after ["
+ (_context.clock().now() - _lastTried)
+ "]", getAddedBy());
+ "]");
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Updating message status for message " + _messageId + " to "

View File

@@ -76,7 +76,7 @@ public class SendMessageDirectJob extends JobImpl {
if (_expiration < now) {
if (_log.shouldLog(Log.WARN))
_log.warn("Timed out sending message " + _message + " directly (expiration = "
+ new Date(_expiration) + ") to " + _targetHash.toBase64(), getAddedBy());
+ new Date(_expiration) + ") to " + _targetHash.toBase64());
if (_onFail != null)
getContext().jobQueue().addJob(_onFail);
return;
@@ -104,7 +104,7 @@ public class SendMessageDirectJob extends JobImpl {
if (_log.shouldLog(Log.WARN))
_log.warn("Unable to find the router to send to: " + _targetHash
+ " after searching for " + (getContext().clock().now()-_searchOn)
+ "ms, message: " + _message, getAddedBy());
+ "ms, message: " + _message);
if (_onFail != null)
getContext().jobQueue().addJob(_onFail);
}

View File

@@ -112,10 +112,14 @@ public class WorkingDir {
// where we want to go
String rv = dirf.getAbsolutePath();
if (dirf.exists()) {
if (dirf.isDirectory())
return rv; // all is good, we found the user directory
System.err.println("Wanted to use " + rv + " for a working directory but it is not a directory");
return cwd;
if (dirf.isDirectory()) {
if (isSetup(dirf))
return rv; // all is good, we found the user directory
}
else {
System.err.println("Wanted to use " + rv + " for a working directory but it is not a directory");
return cwd;
}
}
// Check for a router.keys file or logs dir, if either exists it's an old install,
// and only migrate the data files if told to do so
@@ -131,7 +135,7 @@ public class WorkingDir {
return cwd;
boolean migrateOldData = false; // this is a terrible idea
if (!dirf.mkdir()) {
if (!dirf.exists() && !dirf.mkdir()) {
System.err.println("Wanted to use " + rv + " for a working directory but could not create it");
return cwd;
}
@@ -159,6 +163,18 @@ public class WorkingDir {
}
}
/** Returns <code>false</code> if a directory is empty, or contains nothing besides a subdirectory named plugins */
private static boolean isSetup(File dir) {
if (dir.isDirectory()) {
String[] files = dir.list();
if (files.length == 0)
return false;
if (files.length>1 || !"plugins".equals(files[0]))
return true;
}
return false;
}
/**
* files and directories from the base install to copy over
* None of these should be included in i2pupdate.zip

View File

@@ -136,17 +136,17 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
@Override
public boolean isBacklogged(Hash dest) {
return _manager.isBacklogged(dest);
return _manager != null && _manager.isBacklogged(dest);
}
@Override
public boolean isEstablished(Hash dest) {
return _manager.isEstablished(dest);
return _manager != null && _manager.isEstablished(dest);
}
@Override
public boolean wasUnreachable(Hash dest) {
return _manager.wasUnreachable(dest);
return _manager != null && _manager.wasUnreachable(dest);
}
@Override

View File

@@ -615,8 +615,8 @@ public class NTCPConnection implements FIFOBandwidthLimiter.CompleteListener {
if (_log.shouldLog(Log.INFO))
_log.info("Type " + msg.getMessage().getType() + " pri " + msg.getPriority() + " slot " + slot);
boolean removed = _outbound.remove(msg);
if ((!removed) && _log.shouldLog(Log.ERROR))
_log.info("Already removed??? " + msg.getMessage().getType());
if ((!removed) && _log.shouldLog(Log.WARN))
_log.warn("Already removed??? " + msg.getMessage().getType());
}
_currentOutbound = msg;
}

View File

@@ -2,6 +2,7 @@ package net.i2p.router.transport.ntcp;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ThreadFactory;
@@ -24,9 +25,9 @@ import net.i2p.util.Log;
*/
public class NTCPSendFinisher {
private static final int THREADS = 4;
private I2PAppContext _context;
private NTCPTransport _transport;
private Log _log;
private final I2PAppContext _context;
private final NTCPTransport _transport;
private final Log _log;
private int _count;
private ThreadPoolExecutor _executor;
@@ -47,7 +48,12 @@ public class NTCPSendFinisher {
}
public void add(OutNetMessage msg) {
_executor.execute(new RunnableEvent(msg));
try {
_executor.execute(new RunnableEvent(msg));
} catch (RejectedExecutionException ree) {
// race with stop()
_log.warn("NTCP send finisher stopped, discarding msg.afterSend()");
}
}
// not really needed for now but in case we want to add some hooks like afterExecute()

View File

@@ -317,7 +317,7 @@ class TestJob extends JobImpl {
public String getName() { return "Tunnel test timeout"; }
public void runJob() {
if (_log.shouldLog(Log.WARN))
_log.warn("Timeout: found? " + _found, getAddedBy());
_log.warn("Timeout: found? " + _found);
if (!_found) {
// don't clog up the SKM with old one-tag tagsets
if (_cfg.isInbound() && !_pool.getSettings().isExploratory()) {

View File

@@ -81,7 +81,7 @@ public class SendGarlicJob extends JobImpl {
long after = getContext().clock().now();
if ( (after - before) > 1000) {
if (_log.shouldLog(Log.WARN))
_log.warn("Building the garlic took too long [" + (after-before)+" ms]", getAddedBy());
_log.warn("Building the garlic took too long [" + (after-before)+" ms]");
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Building the garlic was fast! " + (after - before) + " ms");