Compare commits

..

1 Commits

Author SHA1 Message Date
idk
fadf25dc8f Create a branch for 1.7.1 2022-04-20 08:58:59 -04:00
725 changed files with 33726 additions and 73059 deletions

View File

@ -29,4 +29,3 @@ installer/build
router/java/build
router/build
override.properties

2
.gitignore vendored
View File

@ -61,5 +61,3 @@ sloccount.sc
# TODO: why does this file appear?
apps/routerconsole/jsp/favicon.ico
.tx
/*.sh

View File

@ -52,7 +52,6 @@ test:ant:
- echo junit.home=/usr/share/java >> override.properties
- echo hamcrest.home=/usr/share/java >> override.properties
- echo mockito.home=/usr/share/java >> override.properties
- echo build.built-by=GitHub Actions >> override.properties
script:
- ant test
only:

View File

@ -9,7 +9,6 @@ trans.cs = apps/i2ptunnel/locale/messages_cs.po
trans.da = apps/i2ptunnel/locale/messages_da.po
trans.de = apps/i2ptunnel/locale/messages_de.po
trans.es = apps/i2ptunnel/locale/messages_es.po
trans.es_AR = apps/i2ptunnel/locale/messages_es_AR.po
trans.fa = apps/i2ptunnel/locale/messages_fa.po
trans.fi = apps/i2ptunnel/locale/messages_fi.po
trans.fr = apps/i2ptunnel/locale/messages_fr.po
@ -44,7 +43,6 @@ trans.cs = apps/i2ptunnel/locale-proxy/messages_cs.po
trans.de = apps/i2ptunnel/locale-proxy/messages_de.po
trans.el = apps/i2ptunnel/locale-proxy/messages_el.po
trans.es = apps/i2ptunnel/locale-proxy/messages_es.po
trans.es_AR = apps/i2ptunnel/locale-proxy/messages_es_AR.po
trans.fa = apps/i2ptunnel/locale-proxy/messages_fa.po
trans.fi = apps/i2ptunnel/locale-proxy/messages_fi.po
trans.fr = apps/i2ptunnel/locale-proxy/messages_fr.po
@ -68,7 +66,6 @@ trans.tr_TR = apps/i2ptunnel/locale-proxy/messages_tr.po
trans.uk_UA = apps/i2ptunnel/locale-proxy/messages_uk.po
trans.vi = apps/i2ptunnel/locale-proxy/messages_vi.po
trans.zh_CN = apps/i2ptunnel/locale-proxy/messages_zh.po
trans.zh_TW = apps/i2ptunnel/locale-proxy/messages_zh_TW.po
[I2P.core]
type = PO
@ -119,7 +116,6 @@ trans.da = router/locale/messages_da.po
trans.de = router/locale/messages_de.po
trans.el = router/locale/messages_el.po
trans.es = router/locale/messages_es.po
trans.es_AR = router/locale/messages_es_AR.po
trans.et_EE = router/locale/messages_et.po
trans.fa = router/locale/messages_fa.po
trans.fi = router/locale/messages_fi.po
@ -157,7 +153,6 @@ trans.da = apps/routerconsole/locale/messages_da.po
trans.de = apps/routerconsole/locale/messages_de.po
trans.el = apps/routerconsole/locale/messages_el.po
trans.es = apps/routerconsole/locale/messages_es.po
trans.es_AR = apps/routerconsole/locale/messages_es_AR.po
trans.et_EE = apps/routerconsole/locale/messages_et.po
trans.fa = apps/routerconsole/locale/messages_fa.po
trans.fi = apps/routerconsole/locale/messages_fi.po
@ -191,7 +186,6 @@ trans.cs = apps/routerconsole/locale-news/messages_cs.po
trans.de = apps/routerconsole/locale-news/messages_de.po
trans.el = apps/routerconsole/locale-news/messages_el.po
trans.es = apps/routerconsole/locale-news/messages_es.po
trans.es_AR = apps/routerconsole/locale-news/messages_es_AR.po
trans.fa = apps/routerconsole/locale-news/messages_fa.po
trans.fi = apps/routerconsole/locale-news/messages_fi.po
trans.fr = apps/routerconsole/locale-news/messages_fr.po
@ -237,7 +231,6 @@ trans.da = apps/routerconsole/locale-countries/messages_da.po
trans.de = apps/routerconsole/locale-countries/messages_de.po
trans.el = apps/routerconsole/locale-countries/messages_el.po
trans.es = apps/routerconsole/locale-countries/messages_es.po
trans.es_AR = apps/routerconsole/locale-countries/messages_es_AR.po
trans.et_EE = apps/routerconsole/locale-countries/messages_et.po
trans.fa = apps/routerconsole/locale-countries/messages_fa.po
trans.fi = apps/routerconsole/locale-countries/messages_fi.po
@ -279,11 +272,9 @@ source_file = apps/i2psnark/locale/messages_en.po
source_lang = en
trans.ar = apps/i2psnark/locale/messages_ar.po
trans.cs = apps/i2psnark/locale/messages_cs.po
trans.da = apps/i2psnark/locale/messages_da.po
trans.de = apps/i2psnark/locale/messages_de.po
trans.el = apps/i2psnark/locale/messages_el.po
trans.es = apps/i2psnark/locale/messages_es.po
trans.es_AR = apps/i2psnark/locale/messages_es_AR.po
trans.fa = apps/i2psnark/locale/messages_fa.po
trans.fi = apps/i2psnark/locale/messages_fi.po
trans.fr = apps/i2psnark/locale/messages_fr.po
@ -318,7 +309,6 @@ trans.da = apps/susidns/locale/messages_da.po
trans.de = apps/susidns/locale/messages_de.po
trans.el = apps/susidns/locale/messages_el.po
trans.es = apps/susidns/locale/messages_es.po
trans.es_AR = apps/susidns/locale/messages_es_AR.po
trans.fa = apps/susidns/locale/messages_fa.po
trans.fi = apps/susidns/locale/messages_fi.po
trans.fr = apps/susidns/locale/messages_fr.po
@ -398,7 +388,6 @@ trans.da = apps/susimail/locale/messages_da.po
trans.de = apps/susimail/locale/messages_de.po
trans.el = apps/susimail/locale/messages_el.po
trans.es = apps/susimail/locale/messages_es.po
trans.es_AR = apps/susimail/locale/messages_es_AR.po
trans.fa = apps/susimail/locale/messages_fa.po
trans.fi = apps/susimail/locale/messages_fi.po
trans.fr = apps/susimail/locale/messages_fr.po
@ -439,7 +428,6 @@ trans.cs = debian/po/cs.po
trans.de = debian/po/de.po
trans.el = debian/po/el.po
trans.es = debian/po/es.po
trans.es_AR = debian/po/es_AR.po
trans.fi = debian/po/fi.po
trans.fr = debian/po/fr.po
trans.gl = debian/po/gl.po
@ -473,7 +461,6 @@ trans.az = installer/resources/locale/po/messages_az.po
trans.ca = installer/resources/locale/po/messages_ca.po
trans.de = installer/resources/locale/po/messages_de.po
trans.es = installer/resources/locale/po/messages_es.po
trans.es_AR = installer/resources/locale/po/messages_es_AR.po
trans.fi = installer/resources/locale/po/messages_fi.po
trans.fr = installer/resources/locale/po/messages_fr.po
trans.id = installer/resources/locale/po/messages_id.po
@ -492,7 +479,6 @@ trans.sv_SE = installer/resources/locale/po/messages_sv.po
trans.tr_TR = installer/resources/locale/po/messages_tr.po
trans.uk_UA = installer/resources/locale/po/messages_uk.po
trans.zh_CN = installer/resources/locale/po/messages_zh.po
trans.zh_TW = installer/resources/locale/po/messages_zh_TW.po
[I2P.getopt]
;;
@ -519,7 +505,6 @@ trans.az = core/java/src/gnu/getopt/MessagesBundle_az.properties
trans.cs = core/java/src/gnu/getopt/MessagesBundle_cs.properties
trans.de = core/java/src/gnu/getopt/MessagesBundle_de.properties
trans.es = core/java/src/gnu/getopt/MessagesBundle_es.properties
trans.es_AR = core/java/src/gnu/getopt/MessagesBundle_es_AR.properties
trans.fi = core/java/src/gnu/getopt/MessagesBundle_fi.properties
trans.fr = core/java/src/gnu/getopt/MessagesBundle_fr.properties
trans.gl = core/java/src/gnu/getopt/MessagesBundle_gl.properties
@ -556,7 +541,6 @@ trans.ca = apps/ministreaming/locale/messages_ca.po
trans.cs = apps/ministreaming/locale/messages_cs.po
trans.de = apps/ministreaming/locale/messages_de.po
trans.es = apps/ministreaming/locale/messages_es.po
trans.es_AR = apps/ministreaming/locale/messages_es_AR.po
trans.fa = apps/ministreaming/locale/messages_fa.po
trans.fi = apps/ministreaming/locale/messages_fi.po
trans.fr = apps/ministreaming/locale/messages_fr.po
@ -579,7 +563,6 @@ trans.tk = apps/ministreaming/locale/messages_tk.po
trans.tr_TR = apps/ministreaming/locale/messages_tr.po
trans.uk_UA = apps/ministreaming/locale/messages_uk.po
trans.zh_CN = apps/ministreaming/locale/messages_zh.po
trans.zh_TW = apps/ministreaming/locale/messages_zh_TW.po
[I2P.manpages]
;;
@ -593,7 +576,6 @@ trans.ar = installer/resources/locale-man/man_ar.po
trans.az = installer/resources/locale-man/man_az.po
trans.de = installer/resources/locale-man/man_de.po
trans.es = installer/resources/locale-man/man_es.po
trans.es_AR = installer/resources/locale-man/man_es_AR.po
trans.fi = installer/resources/locale-man/man_fi.po
trans.fr = installer/resources/locale-man/man_fr.po
trans.hu = installer/resources/locale-man/man_hu.po
@ -610,7 +592,6 @@ trans.ru_RU = installer/resources/locale-man/man_ru.po
trans.sv_SE = installer/resources/locale-man/man_sv.po
trans.tr_TR = installer/resources/locale-man/man_tr.po
trans.zh_CN = installer/resources/locale-man/man_zh.po
trans.zh_TW = installer/resources/locale-man/man_zh_TW.po
[I2P.eepsite]
;;
@ -650,9 +631,6 @@ trans.zh_CN = installer/resources/eepsite/docroot/help/index_zh.html
;;
;; Text on /console
;;
;; NOTE: No support for country suffixes right now.
;; See ResourceHelper.java
;;
type = HTML
source_file = apps/routerconsole/resources/docs/readme.html
source_lang = en
@ -672,7 +650,6 @@ trans.sl = apps/routerconsole/resources/docs/readme_sl.html
trans.tr_TR = apps/routerconsole/resources/docs/readme_tr.html
trans.uk_UA = apps/routerconsole/resources/docs/readme_uk.html
trans.zh_CN = apps/routerconsole/resources/docs/readme_zh.html
trans.zh_TW = apps/routerconsole/resources/docs/readme_zh_TW.html
[main]
host = https://www.transifex.com

View File

@ -10,12 +10,7 @@ version: "3.5"
services:
i2p:
image: geti2p/i2p
ports:
- 127.0.0.1:4444:4444
- 127.0.0.1:6668:6668
- 127.0.0.1:7657:7657
- 54321:12345
- 54321:12345/udp
network_mode: host
volumes:
- ./i2pconfig:/i2p/.i2p
- ./i2ptorrents:/i2psnark
@ -28,22 +23,11 @@ Note that this quick-start approach is not recommended for production deployment
### Building an image
There is an i2P image available over at [DockerHub](https://hub.docker.com). If you do not want to use that one, you can build one yourself:
```
docker build -t geti2p/i2p .
docker build -t i2p .
```
### Running a container
#### Environment Variables
It is possible to set the IP address where the I2P router is accessible by setting
the `IP_ADDR` environment variable in your `docker run` command or your `docker-compose`
file. For example, if you want to make your I2P router listen on all addresses, then
you should pass `-e IP_ADDR=0.0.0.0` to your `docker run` command.
It is also possible to configure the memory available to the I2P router using
environment variables. To do this, use the: `JVM_XMX` environment variable by passing,
for example, `-e JVM_XMX=256m`.
#### Volumes
The container requires a volume for the configuration data to be mounted. Optionally, you can mount a separate volume for torrent ("i2psnark") downloads. See the example below.
@ -75,19 +59,16 @@ A best-practices guide for cloud deployments is beyond the scope of this documen
#### Example
Here is an example container that mounts `i2phome` as home directory, `i2ptorrents` for torrents, and opens HTTP Proxy, IRC, Router Console and I2NP Protocols. It also limits the memory available to the JVM to 256MB.
```
docker build -t geti2p/i2p .
# I2NP port needs TCP and UDP. Change the 54321 to something random, greater than 1024.
docker run \
-e JVM_XMX=256m \
-v i2phome:/i2p/.i2p \
-v i2ptorrents:/i2psnark \
-p 127.0.0.1:4444:4444 \
-p 127.0.0.1:6668:6668 \
-p 127.0.0.1:7657:7657 \
-p 4444:4444 \
-p 6668:6668 \
-p 7657:7657 \
-p 54321:12345 \
-p 54321:12345/udp \
geti2p/i2p:latest
-p 54321:12345/udp \ # I2NP port needs TCP and UDP. Change the 54321 to something random, greater than 1024.
i2p:latest
```

View File

@ -1,28 +1,24 @@
FROM alpine:3.17.1 as builder
FROM jlesage/baseimage:alpine-3.15-glibc as builder
ENV APP_HOME="/i2p"
WORKDIR /tmp/build
COPY . .
RUN apk add --virtual build-base gettext tar bzip2 apache-ant openjdk17 \
&& echo "build.built-by=Docker" >> override.properties \
RUN add-pkg --virtual build-base gettext tar bzip2 apache-ant openjdk8 \
&& ant preppkg-linux-only \
&& rm -rf pkg-temp/osid pkg-temp/lib/wrapper pkg-temp/lib/wrapper.* \
&& apk del build-base gettext tar bzip2 apache-ant openjdk17
&& del-pkg build-base gettext tar bzip2 apache-ant openjdk8
FROM alpine:3.17.1
FROM jlesage/baseimage:alpine-3.15-glibc
ENV APP_HOME="/i2p"
RUN apk add openjdk17-jre ttf-dejavu
RUN add-pkg openjdk8-jre
WORKDIR ${APP_HOME}
COPY --from=builder /tmp/build/pkg-temp .
# "install" i2p by copying over installed files
COPY --chown=root:root docker/rootfs/ /
RUN chmod +x /startapp.sh
COPY docker/rootfs/ /
# Mount home and snark
VOLUME ["${APP_HOME}/.i2p"]
@ -38,4 +34,3 @@ LABEL \
org.label-schema.vcs-url="https://github.com/i2p/i2p.i2p" \
org.label-schema.schema-version="1.0"
ENTRYPOINT ["/startapp.sh"]

View File

@ -212,6 +212,10 @@ Applications:
Copyright (c) 2006, Matthew Estes
See licenses/LICENSE-BlockFile.txt
BOB (BOB.jar):
Copyright (C) sponge
See licenses/COPYING-BOB.txt
Desktopgui (desktopgui.jar):
Copyright (c) Mathias De Maré
See licenses/LICENSE-DesktopGUI.txt
@ -335,9 +339,9 @@ Applications:
Systray (systray.jar):
Public domain.
Tomcat 9.0.62 (jasper-runtime.jar):
Tomcat 9.0.54 (jasper-runtime.jar):
(not included in most distribution packages)
Copyright 1999-2022 The Apache Software Foundation
Copyright 1999-2021 The Apache Software Foundation
See licenses/LICENSE-Apache2.0.txt
See licenses/NOTICE-Tomcat.txt

14
apps/BOB/bob.config Normal file
View File

@ -0,0 +1,14 @@
#bob.config
#Tue Dec 30 00:00:00 UTC 2008
# Please leave this file here for testing.
# Thank you,
# Sponge
i2cp.tcp.port=7654
BOB.host=localhost
inbound.lengthVariance=0
i2cp.messageReliability=BestEffort
BOB.port=45678
outbound.length=1
inbound.length=1
outbound.lengthVariance=0
i2cp.tcp.host=localhost

12
apps/BOB/build.gradle Normal file
View File

@ -0,0 +1,12 @@
sourceSets {
main {
java {
srcDir 'src'
}
}
}
dependencies {
compile project(':core')
compile project(':apps:ministreaming')
}

115
apps/BOB/build.xml Normal file
View File

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- You may freely edit this file. See commented blocks below for -->
<!-- some examples of how to customize the build. -->
<!-- (If you delete it and reopen the project it will be recreated.) -->
<!-- By default, only the Clean and Build commands use this build script. -->
<!-- Commands such as Run, Debug, and Test only use this build script if -->
<!-- the Compile on Save feature is turned off for the project. -->
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
<!-- in the project's Project Properties dialog box.-->
<project name="BOB" default="default" basedir=".">
<description>Builds, tests, and runs the project BOB.</description>
<import file="nbproject/build-impl.xml"/>
<!--
There exist several targets which are by default empty and which can be
used for execution of your tasks. These targets are usually executed
before and after some main targets. They are:
-pre-init: called before initialization of project properties
-post-init: called after initialization of project properties
-pre-compile: called before javac compilation
-post-compile: called after javac compilation
-pre-compile-single: called before javac compilation of single file
-post-compile-single: called after javac compilation of single file
-pre-compile-test: called before javac compilation of JUnit tests
-post-compile-test: called after javac compilation of JUnit tests
-pre-compile-test-single: called before javac compilation of single JUnit test
-post-compile-test-single: called after javac compilation of single JUunit test
-pre-jar: called before JAR building
-post-jar: called after JAR building
-post-clean: called after cleaning build products
(Targets beginning with '-' are not intended to be called on their own.)
Example of inserting an obfuscator after compilation could look like this:
<target name="-post-compile">
<obfuscate>
<fileset dir="${build.classes.dir}"/>
</obfuscate>
</target>
For list of available properties check the imported
nbproject/build-impl.xml file.
Another way to customize the build is by overriding existing main targets.
The targets of interest are:
-init-macrodef-javac: defines macro for javac compilation
-init-macrodef-junit: defines macro for junit execution
-init-macrodef-debug: defines macro for class debugging
-init-macrodef-java: defines macro for class execution
-do-jar-with-manifest: JAR building (if you are using a manifest)
-do-jar-without-manifest: JAR building (if you are not using a manifest)
run: execution of project
-javadoc-build: Javadoc generation
test-report: JUnit report generation
An example of overriding the target for project execution could look like this:
<target name="run" depends="BOB-impl.jar">
<exec dir="bin" executable="launcher.exe">
<arg file="${dist.jar}"/>
</exec>
</target>
Notice that the overridden target depends on the jar target and not only on
the compile target as the regular run target does. Again, for a list of available
properties which you can use, check the target you are overriding in the
nbproject/build-impl.xml file.
-->
<target depends="jar" description="Build BOB into a SINGLE JAR." name="onejar">
<!-- Make needed working dirs -->
<mkdir dir="${dist.dir}/lib" />
<mkdir dir="${dist.dir}/classes" />
<!-- Copy jars -->
<copy todir="${dist.dir}/lib" flatten="true" >
<path>
<pathelement path="${javac.classpath}" />
</path>
</copy>
<copy todir="${dist.dir}/lib" file="../../build/jbigi.jar" />
<!-- Extract the classes inside the jar files -->
<unjar dest="${dist.dir}/classes" >
<fileset dir="${dist.dir}/lib" >
<include name="**/*.jar" />
</fileset>
</unjar>
<!-- Recombine the classes into a new jar file -->
<jar jarfile="${dist.dir}/lib/all-in-one.jar" >
<fileset dir="${dist.dir}/classes" />
</jar>
<!-- Clean up work area -->
<delete dir="${dist.dir}/classes" followsymlinks="false" includeemptydirs="true"/>
<!-- Make the single jar file -->
<jar jarfile="dist/BOB-one.jar" >
<zipfileset src="${dist.jar}" excludes="META-INF/*" />
<zipfileset src="${dist.dir}/lib/all-in-one.jar" excludes="**/META-INF/*" />
<manifest>
<attribute name="Main-Class" value="net.i2p.BOB.Main" />
</manifest>
</jar>
<!-- Clean up the fake jar file -->
<delete file="${dist.dir}/lib/all-in-one.jar" />
</target>
</project>

3
apps/BOB/manifest.mf Normal file
View File

@ -0,0 +1,3 @@
Manifest-Version: 1.0
X-COMMENT: Main-Class will be added automatically by build

View File

@ -0,0 +1,643 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
*** GENERATED FROM project.xml - DO NOT EDIT ***
*** EDIT ../build.xml INSTEAD ***
For the purpose of easier reading the script
is divided into following sections:
- initialization
- compilation
- jar
- execution
- debugging
- javadoc
- junit compilation
- junit execution
- junit debugging
- applet
- cleanup
-->
<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="BOB-impl">
<target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>
<!--
======================
INITIALIZATION SECTION
======================
-->
<target name="-pre-init">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="-pre-init" name="-init-private">
<property file="nbproject/private/config.properties"/>
<property file="nbproject/private/configs/${config}.properties"/>
<property file="nbproject/private/private.properties"/>
</target>
<target depends="-pre-init,-init-private" name="-init-user">
<property file="${user.properties.file}"/>
<!-- The two properties below are usually overridden -->
<!-- by the active platform. Just a fallback. -->
<property name="default.javac.source" value="1.8"/>
<property name="default.javac.target" value="1.8"/>
<property name="javac.release" value="8"/>
</target>
<target depends="-pre-init,-init-private,-init-user" name="-init-project">
<property file="nbproject/configs/${config}.properties"/>
<property file="nbproject/project.properties"/>
</target>
<target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init">
<available file="${manifest.file}" property="manifest.available"/>
<condition property="manifest.available+main.class">
<and>
<isset property="manifest.available"/>
<isset property="main.class"/>
<not>
<equals arg1="${main.class}" arg2="" trim="true"/>
</not>
</and>
</condition>
<condition property="manifest.available+main.class+mkdist.available">
<and>
<istrue value="${manifest.available+main.class}"/>
<isset property="libs.CopyLibs.classpath"/>
</and>
</condition>
<condition property="have.tests">
<or>
<available file="${test.src.dir}"/>
</or>
</condition>
<condition property="have.sources">
<or>
<available file="${src.dir}"/>
</or>
</condition>
<condition property="netbeans.home+have.tests">
<and>
<isset property="netbeans.home"/>
<isset property="have.tests"/>
</and>
</condition>
<condition property="no.javadoc.preview">
<and>
<isset property="javadoc.preview"/>
<isfalse value="${javadoc.preview}"/>
</and>
</condition>
<property name="run.jvmargs" value=""/>
<property name="javac.compilerargs" value=""/>
<property name="work.dir" value="${basedir}"/>
<condition property="no.deps">
<and>
<istrue value="${no.dependencies}"/>
</and>
</condition>
<property name="javac.debug" value="true"/>
<property name="javadoc.preview" value="true"/>
<property name="application.args" value=""/>
<property name="source.encoding" value="${file.encoding}"/>
<condition property="javadoc.encoding.used" value="${javadoc.encoding}">
<and>
<isset property="javadoc.encoding"/>
<not>
<equals arg1="${javadoc.encoding}" arg2=""/>
</not>
</and>
</condition>
<property name="javadoc.encoding.used" value="${source.encoding}"/>
<property name="includes" value="**"/>
<property name="excludes" value=""/>
<property name="do.depend" value="false"/>
<condition property="do.depend.true">
<istrue value="${do.depend}"/>
</condition>
<condition else="" property="javac.compilerargs.jaxws" value="-Djava.endorsed.dirs='${jaxws.endorsed.dir}'">
<and>
<isset property="jaxws.endorsed.dir"/>
<available file="nbproject/jaxws-build.xml"/>
</and>
</condition>
</target>
<target name="-post-init">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">
<fail unless="src.dir">Must set src.dir</fail>
<fail unless="test.src.dir">Must set test.src.dir</fail>
<fail unless="build.dir">Must set build.dir</fail>
<fail unless="dist.dir">Must set dist.dir</fail>
<fail unless="build.classes.dir">Must set build.classes.dir</fail>
<fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>
<fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>
<fail unless="build.test.results.dir">Must set build.test.results.dir</fail>
<fail unless="build.classes.excludes">Must set build.classes.excludes</fail>
<fail unless="dist.jar">Must set dist.jar</fail>
</target>
<target name="-init-macrodef-property">
<macrodef name="property" uri="http://www.netbeans.org/ns/j2se-project/1">
<attribute name="name"/>
<attribute name="value"/>
<sequential>
<property name="@{name}" value="${@{value}}"/>
</sequential>
</macrodef>
</target>
<target name="-init-macrodef-javac">
<macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${src.dir}" name="srcdir"/>
<attribute default="${build.classes.dir}" name="destdir"/>
<attribute default="${javac.classpath}" name="classpath"/>
<attribute default="${includes}" name="includes"/>
<attribute default="${excludes}" name="excludes"/>
<attribute default="${javac.debug}" name="debug"/>
<attribute default="/does/not/exist" name="sourcepath"/>
<element name="customize" optional="true"/>
<sequential>
<javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" release="${javac.release}">
<classpath>
<path path="@{classpath}"/>
</classpath>
<compilerarg line="${javac.compilerargs} ${javac.compilerargs.jaxws}"/>
<customize/>
</javac>
</sequential>
</macrodef>
<macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${src.dir}" name="srcdir"/>
<attribute default="${build.classes.dir}" name="destdir"/>
<attribute default="${javac.classpath}" name="classpath"/>
<sequential>
<depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">
<classpath>
<path path="@{classpath}"/>
</classpath>
</depend>
</sequential>
</macrodef>
<macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${build.classes.dir}" name="destdir"/>
<sequential>
<fail unless="javac.includes">Must set javac.includes</fail>
<pathconvert pathsep="," property="javac.includes.binary">
<path>
<filelist dir="@{destdir}" files="${javac.includes}"/>
</path>
<globmapper from="*.java" to="*.class"/>
</pathconvert>
<delete>
<files includes="${javac.includes.binary}"/>
</delete>
</sequential>
</macrodef>
</target>
<target name="-init-macrodef-junit">
<macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${includes}" name="includes"/>
<attribute default="${excludes}" name="excludes"/>
<attribute default="**" name="testincludes"/>
<sequential>
<junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" showoutput="true">
<batchtest todir="${build.test.results.dir}">
<fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
<filename name="@{testincludes}"/>
</fileset>
</batchtest>
<classpath>
<path path="${run.test.classpath}"/>
</classpath>
<syspropertyset>
<propertyref prefix="test-sys-prop."/>
<mapper from="test-sys-prop.*" to="*" type="glob"/>
</syspropertyset>
<formatter type="brief" usefile="false"/>
<formatter type="xml"/>
<jvmarg line="${run.jvmargs}"/>
</junit>
</sequential>
</macrodef>
</target>
<target depends="-init-debug-args" name="-init-macrodef-nbjpda">
<macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
<attribute default="${main.class}" name="name"/>
<attribute default="${debug.classpath}" name="classpath"/>
<attribute default="" name="stopclassname"/>
<sequential>
<nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="${debug-transport}">
<classpath>
<path path="@{classpath}"/>
</classpath>
</nbjpdastart>
</sequential>
</macrodef>
<macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/j2se-project/1">
<attribute default="${build.classes.dir}" name="dir"/>
<sequential>
<nbjpdareload>
<fileset dir="@{dir}" includes="${fix.classes}">
<include name="${fix.includes}*.class"/>
</fileset>
</nbjpdareload>
</sequential>
</macrodef>
</target>
<target name="-init-debug-args">
<property name="version-output" value="java version &quot;${ant.java.version}"/>
<condition property="have-jdk-older-than-1.4">
<or>
<contains string="${version-output}" substring="java version &quot;1.0"/>
<contains string="${version-output}" substring="java version &quot;1.1"/>
<contains string="${version-output}" substring="java version &quot;1.2"/>
<contains string="${version-output}" substring="java version &quot;1.3"/>
</or>
</condition>
<condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
<istrue value="${have-jdk-older-than-1.4}"/>
</condition>
<condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">
<os family="windows"/>
</condition>
<condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">
<isset property="debug.transport"/>
</condition>
</target>
<target depends="-init-debug-args" name="-init-macrodef-debug">
<macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">
<attribute default="${main.class}" name="classname"/>
<attribute default="${debug.classpath}" name="classpath"/>
<element name="customize" optional="true"/>
<sequential>
<java classname="@{classname}" dir="${work.dir}" fork="true">
<jvmarg line="${debug-args-line}"/>
<jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
<jvmarg line="${run.jvmargs}"/>
<classpath>
<path path="@{classpath}"/>
</classpath>
<syspropertyset>
<propertyref prefix="run-sys-prop."/>
<mapper from="run-sys-prop.*" to="*" type="glob"/>
</syspropertyset>
<customize/>
</java>
</sequential>
</macrodef>
</target>
<target name="-init-macrodef-java">
<macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
<attribute default="${main.class}" name="classname"/>
<element name="customize" optional="true"/>
<sequential>
<java classname="@{classname}" dir="${work.dir}" fork="true">
<jvmarg line="${run.jvmargs}"/>
<classpath>
<path path="${run.classpath}"/>
</classpath>
<syspropertyset>
<propertyref prefix="run-sys-prop."/>
<mapper from="run-sys-prop.*" to="*" type="glob"/>
</syspropertyset>
<customize/>
</java>
</sequential>
</macrodef>
</target>
<target name="-init-presetdef-jar">
<presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">
<jar compress="${jar.compress}" jarfile="${dist.jar}">
<j2seproject1:fileset dir="${build.classes.dir}"/>
</jar>
</presetdef>
</target>
<target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-junit,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar" name="init"/>
<!--
===================
COMPILATION SECTION
===================
-->
<target depends="init" name="deps-jar" unless="no.deps"/>
<target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/>
<target depends="init" name="-check-automatic-build">
<available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/>
</target>
<target depends="init" if="netbeans.automatic.build" name="-clean-after-automatic-build">
<antcall target="clean"/>
</target>
<target depends="init,deps-jar" name="-pre-pre-compile">
<mkdir dir="${build.classes.dir}"/>
</target>
<target name="-pre-compile">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target if="do.depend.true" name="-compile-depend">
<j2seproject3:depend/>
</target>
<target depends="init,deps-jar,-pre-pre-compile,-pre-compile,-compile-depend" if="have.sources" name="-do-compile">
<j2seproject3:javac/>
<copy todir="${build.classes.dir}">
<fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
</copy>
</target>
<target name="-post-compile">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
<target name="-pre-compile-single">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
<fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
<j2seproject3:force-recompile/>
<j2seproject3:javac excludes="" includes="${javac.includes}" sourcepath="${src.dir}"/>
</target>
<target name="-post-compile-single">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
<!--
====================
JAR BUILDING SECTION
====================
-->
<target depends="init" name="-pre-pre-jar">
<dirname file="${dist.jar}" property="dist.jar.dir"/>
<mkdir dir="${dist.jar.dir}"/>
</target>
<target name="-pre-jar">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar" name="-do-jar-without-manifest" unless="manifest.available">
<j2seproject1:jar/>
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available" name="-do-jar-with-manifest" unless="manifest.available+main.class">
<j2seproject1:jar manifest="${manifest.file}"/>
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available+main.class" name="-do-jar-with-mainclass" unless="manifest.available+main.class+mkdist.available">
<j2seproject1:jar manifest="${manifest.file}">
<j2seproject1:manifest>
<j2seproject1:attribute name="Main-Class" value="${main.class}"/>
</j2seproject1:manifest>
</j2seproject1:jar>
<echo>To run this application from the command line without Ant, try:</echo>
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
<property location="${dist.jar}" name="dist.jar.resolved"/>
<pathconvert property="run.classpath.with.dist.jar">
<path path="${run.classpath}"/>
<map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>
</pathconvert>
<echo>java -cp "${run.classpath.with.dist.jar}" ${main.class}</echo>
</target>
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available+main.class+mkdist.available" name="-do-jar-with-libraries">
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
<pathconvert property="run.classpath.without.build.classes.dir">
<path path="${run.classpath}"/>
<map from="${build.classes.dir.resolved}" to=""/>
</pathconvert>
<pathconvert pathsep=" " property="jar.classpath">
<path path="${run.classpath.without.build.classes.dir}"/>
<chainedmapper>
<flattenmapper/>
<globmapper from="*" to="lib/*"/>
</chainedmapper>
</pathconvert>
<taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
<copylibs compress="${jar.compress}" jarfile="${dist.jar}" manifest="${manifest.file}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
<fileset dir="${build.classes.dir}"/>
<manifest>
<attribute name="Main-Class" value="${main.class}"/>
<attribute name="Class-Path" value="${jar.classpath}"/>
</manifest>
</copylibs>
<echo>To run this application from the command line without Ant, try:</echo>
<property location="${dist.jar}" name="dist.jar.resolved"/>
<echo>java -jar "${dist.jar.resolved}"</echo>
</target>
<target name="-post-jar">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,compile,-pre-jar,-do-jar-with-manifest,-do-jar-without-manifest,-do-jar-with-mainclass,-do-jar-with-libraries,-post-jar" description="Build JAR." name="jar"/>
<!--
=================
EXECUTION SECTION
=================
-->
<target depends="init,compile" description="Run a main class." name="run">
<j2seproject1:java>
<customize>
<arg line="${application.args}"/>
</customize>
</j2seproject1:java>
</target>
<target name="-do-not-recompile">
<property name="javac.includes.binary" value=""/>
</target>
<target depends="init,-do-not-recompile,compile-single" name="run-single">
<fail unless="run.class">Must select one file in the IDE or set run.class</fail>
<j2seproject1:java classname="${run.class}"/>
</target>
<!--
=================
DEBUGGING SECTION
=================
-->
<target depends="init" if="netbeans.home" name="-debug-start-debugger">
<j2seproject1:nbjpdastart name="${debug.class}"/>
</target>
<target depends="init,compile" name="-debug-start-debuggee">
<j2seproject3:debug>
<customize>
<arg line="${application.args}"/>
</customize>
</j2seproject3:debug>
</target>
<target depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE." if="netbeans.home" name="debug"/>
<target depends="init" if="netbeans.home" name="-debug-start-debugger-stepinto">
<j2seproject1:nbjpdastart stopclassname="${main.class}"/>
</target>
<target depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee" if="netbeans.home" name="debug-stepinto"/>
<target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">
<fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
<j2seproject3:debug classname="${debug.class}"/>
</target>
<target depends="init,-do-not-recompile,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>
<target depends="init" name="-pre-debug-fix">
<fail unless="fix.includes">Must set fix.includes</fail>
<property name="javac.includes" value="${fix.includes}.java"/>
</target>
<target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">
<j2seproject1:nbjpdareload/>
</target>
<target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>
<!--
===============
JAVADOC SECTION
===============
-->
<target depends="init" name="-javadoc-build">
<mkdir dir="${dist.javadoc.dir}"/>
<javadoc additionalparam="${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
<classpath>
<path path="${javac.classpath}"/>
</classpath>
<fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
<filename name="**/*.java"/>
</fileset>
</javadoc>
</target>
<target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
<nbbrowse file="${dist.javadoc.dir}/index.html"/>
</target>
<target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>
<!--
=========================
JUNIT COMPILATION SECTION
=========================
-->
<target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">
<mkdir dir="${build.test.classes.dir}"/>
</target>
<target name="-pre-compile-test">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target if="do.depend.true" name="-compile-test-depend">
<j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>
</target>
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">
<j2seproject3:javac classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>
<copy todir="${build.test.classes.dir}">
<fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
</copy>
</target>
<target name="-post-compile-test">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>
<target name="-pre-compile-test-single">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
<fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
<j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>
<j2seproject3:javac classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" sourcepath="${test.src.dir}" srcdir="${test.src.dir}"/>
<copy todir="${build.test.classes.dir}">
<fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
</copy>
</target>
<target name="-post-compile-test-single">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>
<!--
=======================
JUNIT EXECUTION SECTION
=======================
-->
<target depends="init" if="have.tests" name="-pre-test-run">
<mkdir dir="${build.test.results.dir}"/>
</target>
<target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
<j2seproject3:junit testincludes="**/*Test.java"/>
</target>
<target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
<fail if="tests.failed">Some tests failed; see details above.</fail>
</target>
<target depends="init" if="have.tests" name="test-report"/>
<target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
<target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>
<target depends="init" if="have.tests" name="-pre-test-run-single">
<mkdir dir="${build.test.results.dir}"/>
</target>
<target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
<fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
<j2seproject3:junit excludes="" includes="${test.includes}"/>
</target>
<target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
<fail if="tests.failed">Some tests failed; see details above.</fail>
</target>
<target depends="init,-do-not-recompile,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
<!--
=======================
JUNIT DEBUGGING SECTION
=======================
-->
<target depends="init,compile-test" if="have.tests" name="-debug-start-debuggee-test">
<fail unless="test.class">Must select one file in the IDE or set test.class</fail>
<property location="${build.test.results.dir}/TEST-${test.class}.xml" name="test.report.file"/>
<delete file="${test.report.file}"/>
<mkdir dir="${build.test.results.dir}"/>
<j2seproject3:debug classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner" classpath="${ant.home}/lib/ant.jar:${ant.home}/lib/ant-junit.jar:${debug.test.classpath}">
<customize>
<syspropertyset>
<propertyref prefix="test-sys-prop."/>
<mapper from="test-sys-prop.*" to="*" type="glob"/>
</syspropertyset>
<arg value="${test.class}"/>
<arg value="showoutput=true"/>
<arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.BriefJUnitResultFormatter"/>
<arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,${test.report.file}"/>
</customize>
</j2seproject3:debug>
</target>
<target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">
<j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>
</target>
<target depends="init,-do-not-recompile,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
<target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
<j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>
</target>
<target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>
<!--
=========================
APPLET EXECUTION SECTION
=========================
-->
<target depends="init,compile-single" name="run-applet">
<fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
<j2seproject1:java classname="sun.applet.AppletViewer">
<customize>
<arg value="${applet.url}"/>
</customize>
</j2seproject1:java>
</target>
<!--
=========================
APPLET DEBUGGING SECTION
=========================
-->
<target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-applet">
<fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
<j2seproject3:debug classname="sun.applet.AppletViewer">
<customize>
<arg value="${applet.url}"/>
</customize>
</j2seproject3:debug>
</target>
<target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet" if="netbeans.home" name="debug-applet"/>
<!--
===============
CLEANUP SECTION
===============
-->
<target depends="init" name="deps-clean" unless="no.deps"/>
<target depends="init" name="-do-clean">
<delete dir="${build.dir}"/>
<delete dir="${dist.dir}"/>
</target>
<target name="-post-clean">
<!-- Empty placeholder for easier customization. -->
<!-- You can override this target in the ../build.xml file. -->
</target>
<target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>
</project>

View File

@ -0,0 +1,8 @@
build.xml.data.CRC32=209349b6
build.xml.script.CRC32=403e69e6
build.xml.stylesheet.CRC32=958a1d3e
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=209349b6
nbproject/build-impl.xml.script.CRC32=c51e188e
nbproject/build-impl.xml.stylesheet.CRC32=65b8de21

View File

@ -0,0 +1,84 @@
application.homepage=http://bob.i2p/
application.title=BOB
application.vendor=Sponge
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.expand-tabs=false
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.indent-shift-width=8
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.spaces-per-tab=8
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.tab-size=8
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width=80
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.usedProfile=project
build.classes.dir=${build.dir}/classes
build.classes.excludes=**/*.java,**/*.form
# This directory is removed when the project is cleaned:
build.dir=build
build.generated.dir=${build.dir}/generated
build.generated.sources.dir=${build.dir}/generated-sources
# Only compile against the classpath explicitly listed here:
build.sysclasspath=ignore
build.test.classes.dir=${build.dir}/test/classes
build.test.results.dir=${build.dir}/test/results
debug.classpath=\
${run.classpath}
debug.test.classpath=\
${run.test.classpath}
# This directory is removed when the project is cleaned:
dist.dir=dist
dist.jar=${dist.dir}/BOB.jar
dist.javadoc.dir=${dist.dir}/javadoc
endorsed.classpath=
excludes=**/*.html,**/*.txt
file.reference.build-javadoc=../../i2p.i2p/build/javadoc
file.reference.i2p.jar=../../core/java/build/i2p.jar
file.reference.mstreaming.jar=../ministreaming/java/build/mstreaming.jar
includes=**
jar.compress=true
javac.classpath=\
${file.reference.mstreaming.jar}:\
${file.reference.i2p.jar}
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false
javac.version=1.8
javac.source=${javac.version}
javac.target=${javac.version}
javac.release=8
javac.test.classpath=\
${javac.classpath}:\
${build.classes.dir}:\
${libs.junit.classpath}:\
${libs.junit_4.classpath}
javadoc.additionalparam=
javadoc.author=false
javadoc.encoding=${source.encoding}
javadoc.noindex=false
javadoc.nonavbar=false
javadoc.notree=false
javadoc.private=false
javadoc.splitindex=true
javadoc.use=true
javadoc.version=false
javadoc.windowtitle=
jaxbwiz.endorsed.dirs="${netbeans.home}/../ide12/modules/ext/jaxb/api"
jnlp.codebase.type=local
jnlp.codebase.url=file:/usblv/NetBeansProjects/i2p.i2p/apps/BOB/dist
jnlp.descriptor=application
jnlp.enabled=false
jnlp.offline-allowed=false
jnlp.signed=false
main.class=net.i2p.BOB.Main
manifest.file=manifest.mf
meta.inf.dir=${src.dir}/META-INF
platform.active=default_platform
run.classpath=\
${javac.classpath}:\
${build.classes.dir}
# Space-separated list of JVM arguments used when running the project
# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
# or test-sys-prop.name=value to set system properties for unit tests):
run.jvmargs=
run.test.classpath=\
${javac.test.classpath}:\
${build.test.classes.dir}
source.encoding=UTF-8
src.dir=src
test.src.dir=test

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.java.j2seproject</type>
<configuration>
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
<name>BOB</name>
<minimum-ant-version>1.9.8</minimum-ant-version>
<source-roots>
<root id="src.dir"/>
</source-roots>
<test-roots>
<root id="test.src.dir"/>
</test-roots>
</data>
</configuration>
</project>

View File

@ -0,0 +1,542 @@
/**
* WTFPL
* Version 2, December 2004
*
* Copyright (C) sponge
* Planet Earth
*
* See...
*
* http://sam.zoy.org/wtfpl/
* and
* http://en.wikipedia.org/wiki/WTFPL
*
* ...for any additional details and license questions.
*/
package net.i2p.BOB;
import static net.i2p.app.ClientAppState.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.util.Arrays;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import net.i2p.I2PAppContext;
import net.i2p.app.*;
import net.i2p.client.I2PClient;
import net.i2p.util.I2PAppThread;
import net.i2p.util.Log;
import net.i2p.util.PortMapper;
import net.i2p.util.SimpleTimer2;
/**
* <span style="font-size:8px;font-family:courier;color:#EEEEEE;background-color:#000000">
* ################################################################################<br>
* ############################.#..........#..#..........##########################<br>
* #######################......................................###################<br>
* ####################...........................#.......#........################<br>
* #################..................##...................#.........##############<br>
* ###############................###...####.....#..###.....#.........#############<br>
* #############...........###..#..###...#####...###.##........#.......############<br>
* ###########................#......##...#####...##..##.......#..#........########<br>
* ##########.........................#....##.##..#...##.....................######<br>
* #########...................................#....#.........................#####<br>
* ########.........................................#...............#..........####<br>
* ########.........................................#..........#######..........###<br>
* #######.................................................############..........##<br>
* #######..........................................####################.........##<br>
* #######............####################......########################.........##<br>
* ######.............###############################################.##.........##<br>
* ######............################################################..##........##<br>
* ######............################################################..##........##<br>
* ######.............##############################################..##.........##<br>
* ######............##############################################...##..........#<br>
* ######............#..###########################################...##..........#<br>
* ######.............#############################################....#..........#<br>
* #######...........###############################################..##.........##<br>
* #######...........#####.#.#.#.########################.....#.####...##........##<br>
* ######............#..............##################.................##.........#<br>
* ######................####.........###############........#####......##........#<br>
* ######..............####..#.........############.......##.#.######...##.......##<br>
* ######.................#.####.........########...........##....###...##.......##<br>
* #######....#....###...................#######...............#...###..##.......##<br>
* #######.........###..###.....###.......######.##.#####.........####..##.......##<br>
* #######.....#...##############.........############......###########.###......##<br>
* #######....##...##########.......##...##############......#.############.....###<br>
* ########....#..########......######...##################################....####<br>
* ########....##.####################...##################################....####<br>
* ########..#.##..###################..##################################..#..####<br>
* ##########..###..#################...##################################...#.####<br>
* #########....##...##############....########..#####.################.##..#.#####<br>
* ############.##....##########.......#########.###.......###########..#.#########<br>
* ###############.....#######...#.......########.....##.....######.....###########<br>
* ###############......###....##..........##.......######....#.........#.#########<br>
* ##############............##..................##########..............##########<br>
* ##############..............................##########..#.............##########<br>
* ###############.......##..................#####..............####....###########<br>
* ###############.......#####.......#.............####.....#######.....###########<br>
* ################...#...####......##################.....########....############<br>
* ################...##..#####.........####.##.....#....##########....############<br>
* ##################..##..####...........#####.#....############.....#############<br>
* ##################......#####.................################....##############<br>
* ###################.....####..........##########..###########....###############<br>
* ####################..#..#..........................########.....###############<br>
* #####################.##.......###.................########....#################<br>
* ######################.........#.......#.##.###############....#################<br>
* #############.#######...............#####################....###################<br>
* ###..#.....##...####..........#.....####################....####################<br>
* ####......##........................##################....######################<br>
* #.##...###..............###.........###############......#######################<br>
* #...###..##............######...........................########################<br>
* ##.......###..........##########....#...#...........############################<br>
* ##.........##.......############################################################<br>
* ###........##.....##############################################################<br>
* ####.............###############################################################<br>
* ######.........#################################################################<br>
* #########....###################################################################<br>
* ################################################################################<br>
* </span>
* BOB, main command socket listener, launches the command parser engine.
*
* @author sponge
* @deprecated Please port applications to SAMv3
*/
@Deprecated
public class BOB implements Runnable, ClientApp {
public final static String PROP_CONFIG_LOCATION = "BOB.config";
public final static String PROP_BOB_PORT = "BOB.port";
public final static String PROP_BOB_HOST = "BOB.host";
public final static String PROP_CFG_VER = "BOB.CFG.VER";
/** unused when started via the ClientApp interface */
private static BOB _bob;
private final NamedDB database;
private final Properties props = new Properties();
private final AtomicBoolean spin = new AtomicBoolean(true);
private static final String P_RUNNING = "RUNNING";
private static final String P_STARTING = "STARTING";
private static final String P_STOPPING = "STOPPING";
private final AtomicBoolean lock = new AtomicBoolean(false);
// no longer used.
// private static int maxConnections = 0;
private final I2PAppContext _context;
private final Logger _log;
private final ClientAppManager _mgr;
private final String[] _args;
private volatile ClientAppState _state = UNINITIALIZED;
private volatile ServerSocket listener;
private volatile Thread _runner;
private volatile boolean _warned;
/**
* Stop BOB gracefully
* @deprecated unused
*/
@Deprecated
public synchronized static void stop() {
if (_bob != null)
_bob.shutdown(null);
}
/**
* For ClientApp interface.
* Does NOT open the listener socket or start threads; caller must call startup()
*
* @param mgr may be null
* @param args non-null
* @since 0.9.10
*/
public BOB(I2PAppContext context, ClientAppManager mgr, String[] args) {
_context = context;
// If we were run from command line, log to stdout
boolean logToStdout = false;
URL classResource = BOB.class.getResource("BOB.class");
if (classResource != null) {
String classPath = classResource.toString();
if (classPath.startsWith("jar")) {
String manifestPath = classPath.substring(0, classPath.lastIndexOf('!') + 1) +
"/META-INF/MANIFEST.MF";
try {
Manifest manifest = new Manifest(new URL(manifestPath).openStream());
Attributes attrs = manifest.getMainAttributes();
String mainClass = attrs.getValue("Main-Class");
if ("net.i2p.BOB.Main".equals(mainClass))
logToStdout = true;
} catch (IOException ioe) {}
}
}
_log = new Logger(context.logManager().getLog(BOB.class), logToStdout);
_mgr = mgr;
_args = args;
_state = INITIALIZED;
database = new NamedDB();
loadConfig();
}
/**
* Listen for incoming connections and handle them
*
* @param args
*/
public synchronized static void main(String[] args) {
try {
_bob = new BOB(I2PAppContext.getGlobalContext(), null, args);
_bob.startup();
} catch (RuntimeException e) {
e.printStackTrace();
throw e;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* @since 0.9.10
*/
private void loadConfig() {
int i = 0;
boolean save = false;
// Set up all defaults to be passed forward to other threads.
// Re-reading the config file in each thread is pretty damn stupid.
String configLocation = System.getProperty(PROP_CONFIG_LOCATION, "bob.config");
// This is here just to ensure there is no interference with our threadgroups.
SimpleTimer2 Y2 = SimpleTimer2.getInstance();
i = Y2.hashCode();
{
File cfg = new File(configLocation);
if (!cfg.isAbsolute()) {
cfg = new File(_context.getConfigDir(), configLocation);
}
FileInputStream fi = null;
try {
fi = new FileInputStream(cfg);
props.load(fi);
} catch (FileNotFoundException fnfe) {
_log.warn("Unable to load up the BOB config file " + cfg.getAbsolutePath() + ", Using defaults.", fnfe);
save = true;
} catch (IOException ioe) {
_log.warn("IOException on BOB config file " + cfg.getAbsolutePath() + ", using defaults.", ioe);
} finally {
if (fi != null) try { fi.close(); } catch (IOException ioe) {}
}
}
// Global router and client API configurations that are missing are set to defaults here.
if (!props.containsKey(I2PClient.PROP_TCP_HOST)) {
props.setProperty(I2PClient.PROP_TCP_HOST, "localhost");
save = true;
}
if (!props.containsKey(I2PClient.PROP_TCP_PORT)) {
props.setProperty(I2PClient.PROP_TCP_PORT, Integer.toString(I2PClient.DEFAULT_LISTEN_PORT));
save = true;
}
if (!props.containsKey(PROP_BOB_PORT)) {
props.setProperty(PROP_BOB_PORT, "2827"); // 0xB0B
save = true;
}
if (!props.containsKey("inbound.length")) {
props.setProperty("inbound.length", "3");
save = true;
}
if (!props.containsKey("outbound.length")) {
props.setProperty("outbound.length", "3");
save = true;
}
if (!props.containsKey("inbound.lengthVariance")) {
props.setProperty("inbound.lengthVariance", "0");
save = true;
}
if (!props.containsKey("outbound.lengthVariance")) {
props.setProperty("outbound.lengthVariance", "0");
save = true;
}
if (!props.containsKey(PROP_BOB_HOST)) {
props.setProperty(PROP_BOB_HOST, "localhost");
save = true;
}
// PROP_RELIABILITY_NONE, PROP_RELIABILITY_BEST_EFFORT, PROP_RELIABILITY_GUARANTEED
if (!props.containsKey(PROP_CFG_VER)) {
props.setProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_NONE);
props.setProperty(PROP_CFG_VER,"1");
save = true;
}
if (save) {
File cfg = new File(configLocation);
if (!cfg.isAbsolute()) {
cfg = new File(_context.getConfigDir(), configLocation);
}
FileOutputStream fo = null;
try {
_log.warn("Writing new defaults file " + cfg.getAbsolutePath());
fo = new FileOutputStream(cfg);
props.store(fo, cfg.getAbsolutePath());
} catch (IOException ioe) {
_log.error("IOException on BOB config file " + cfg.getAbsolutePath(), ioe);
} finally {
if (fo != null) try { fo.close(); } catch (IOException ioe) {}
}
}
}
/**
* @since 0.9.10
*/
private void startListener() throws IOException {
listener = new ServerSocket(Integer.parseInt(props.getProperty(PROP_BOB_PORT)), 10, InetAddress.getByName(props.getProperty(PROP_BOB_HOST)));
listener.setSoTimeout(500); // .5 sec
}
/**
* @since 0.9.10
*/
private void startThread() {
I2PAppThread t = new I2PAppThread(this, "BOBListener");
t.start();
_runner = t;
}
/**
* @since 0.9.10
*/
public void run() {
if (listener == null) return;
changeState(RUNNING);
_log.info("BOB is now running.");
if (_mgr != null)
_mgr.register(this);
_context.portMapper().register(PortMapper.SVC_BOB, props.getProperty(PROP_BOB_HOST),
Integer.parseInt(props.getProperty(PROP_BOB_PORT)));
int i = 0;
boolean g = false;
spin.set(true);
try {
Socket server = null;
while (spin.get()) {
//DoCMDS connection;
try {
server = listener.accept();
server.setKeepAlive(true);
g = true;
} catch (ConnectException ce) {
g = false;
} catch (SocketTimeoutException ste) {
g = false;
}
if (g) {
if (!_warned) {
_warned = true;
String s = "BOB is deprecated. Please port applications to SAMv3.";
_context.logManager().getLog(BOB.class).logAlways(Log.WARN, s);
_log.warn(s);
}
DoCMDS conn_c = new DoCMDS(spin, lock, server, props, database, _log);
Thread t = new I2PAppThread(conn_c);
t.setName("BOB.DoCMDS " + i);
t.start();
i++;
}
}
changeState(STOPPING);
} catch (Exception e) {
if (spin.get())
_log.error("Unexpected error while listening for connections", e);
else
e = null;
changeState(STOPPING, e);
} finally {
_log.info("BOB is now shutting down...");
_context.portMapper().unregister(PortMapper.SVC_BOB);
// Clean up everything.
try {
listener.close();
} catch (Exception ex) {
// nop
}
// Find all our "BOB.DoCMDS" threads, wait for them to be finished.
// We could order them to stop, but that could cause nasty issues in the locks.
visitAllThreads();
database.getReadLock();
NamedDB nickinfo;
try {
for (Object ndb : database.values()) {
nickinfo = (NamedDB) ndb;
nickinfo.getReadLock();
boolean released = false;
try {
if (nickinfo.get(P_RUNNING).equals(Boolean.TRUE) && nickinfo.get(P_STOPPING).equals(Boolean.FALSE) && nickinfo.get(P_STARTING).equals(Boolean.FALSE)) {
nickinfo.releaseReadLock();
released = true;
nickinfo.getWriteLock();
try {
nickinfo.add(P_STOPPING, Boolean.TRUE);
} finally {
nickinfo.releaseWriteLock();
}
}
} finally {
if (!released)
nickinfo.releaseReadLock();
}
}
} finally {
database.releaseReadLock();
}
changeState(STOPPED);
_log.info("BOB is now stopped.");
}
}
/**
* Find the root thread group,
* then find all theads with certain names and wait for them all to be dead.
*
*/
private static void visitAllThreads() {
ThreadGroup root = Thread.currentThread().getThreadGroup().getParent();
while (root.getParent() != null) {
root = root.getParent();
}
// Visit each thread group
waitjoin(root, 0, root.getName());
}
private static void waitjoin(ThreadGroup group, int level, String tn) {
// Get threads in `group'
int numThreads = group.activeCount();
Thread[] threads = new Thread[numThreads * 2];
numThreads = group.enumerate(threads, false);
// Enumerate each thread in `group' and wait for it to stop if it is one of ours.
for (int i = 0; i < numThreads; i++) {
// Get thread
Thread thread = threads[i];
if (thread.getName().startsWith("BOB.DoCMDS ")) {
try {
if (thread.isAlive()) {
try {
thread.join();
} catch (InterruptedException ex) {
}
}
} catch (SecurityException se) {
//nop
}
}
}
// Get thread subgroups of `group'
int numGroups = group.activeGroupCount();
ThreadGroup[] groups = new ThreadGroup[numGroups * 2];
numGroups = group.enumerate(groups, false);
// Recursively visit each subgroup
for (int i = 0; i < numGroups; i++) {
waitjoin(groups[i], level + 1, groups[i].getName());
}
}
////// begin ClientApp interface
/**
* @since 0.9.10
*/
@Override
public void startup() throws IOException {
if (_state != INITIALIZED)
return;
changeState(STARTING);
try {
startListener();
} catch (IOException e) {
_log.error("Error starting BOB on"
+ props.getProperty(PROP_BOB_HOST)
+ ":" + props.getProperty(PROP_BOB_PORT), e);
changeState(START_FAILED, e);
throw e;
}
startThread();
}
/**
* @since 0.9.10
*/
@Override
public void shutdown(String[] args) {
if (_state != RUNNING)
return;
changeState(STOPPING);
spin.set(false);
if (_runner != null)
_runner.interrupt();
else
changeState(STOPPED);
}
/**
* @since 0.9.10
*/
@Override
public ClientAppState getState() {
return _state;
}
/**
* @since 0.9.10
*/
@Override
public String getName() {
return "BOB";
}
/**
* @since 0.9.10
*/
@Override
public String getDisplayName() {
return "BOB " + Arrays.toString(_args);
}
////// end ClientApp interface
////// begin ClientApp helpers
/**
* @since 0.9.10
*/
private void changeState(ClientAppState state) {
changeState(state, null);
}
/**
* @since 0.9.10
*/
private synchronized void changeState(ClientAppState state, Exception e) {
_state = state;
if (_mgr != null)
_mgr.notify(this, state, null, e);
}
////// end ClientApp helpers
}

View File

@ -0,0 +1,996 @@
/**
* WTFPL
* Version 2, December 2004
*
* Copyright (C) sponge
* Planet Earth
*
* See...
*
* http://sam.zoy.org/wtfpl/
* and
* http://en.wikipedia.org/wiki/WTFPL
*
* ...for any additional details and license questions.
*/
package net.i2p.BOB;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Locale;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.concurrent.atomic.AtomicBoolean;
import net.i2p.I2PAppContext;
import net.i2p.I2PException;
import net.i2p.client.I2PClientFactory;
import net.i2p.data.Destination;
import net.i2p.util.I2PAppThread;
// needed only for debugging.
// import java.util.logging.Level;
// import java.util.logging.Logger;
/**
* Simplistic command parser for BOB
*
* @author sponge
*
*/
public class DoCMDS implements Runnable {
// FIX ME
// I need a better way to do versioning, but this will do for now.
public static final String BMAJ = "00", BMIN = "00", BREV = "10", BEXT = "";
public static final String BOBversion = BMAJ + "." + BMIN + "." + BREV + BEXT;
private final Socket server;
private final Properties props;
private final NamedDB database;
private String line;
private Destination d;
private ByteArrayOutputStream prikey;
private boolean dk, ns, ip, op;
private NamedDB nickinfo;
private final Logger _log;
private final AtomicBoolean LIVE;
private final AtomicBoolean lock;
/* database strings */
private static final String P_DEST = "DESTINATION";
private static final String P_INHOST = "INHOST";
private static final String P_INPORT = "INPORT";
private static final String P_KEYS = "KEYS";
private static final String P_NICKNAME = "NICKNAME";
private static final String P_OUTHOST = "OUTHOST";
private static final String P_OUTPORT = "OUTPORT";
private static final String P_PROPERTIES = "PROPERTIES";
private static final String P_QUIET = "QUIET";
private static final String P_RUNNING = "RUNNING";
private static final String P_STARTING = "STARTING";
private static final String P_STOPPING = "STOPPING";
/* command strings */
private static final String C_help = "help";
private static final String C_clear = "clear";
private static final String C_getdest = "getdest";
private static final String C_getkeys = "getkeys";
private static final String C_getnick = "getnick";
private static final String C_inhost = "inhost";
private static final String C_inport = "inport";
private static final String C_list = "list";
private static final String C_lookup = "lookup";
private static final String C_newkeys = "newkeys";
private static final String C_option = "option";
private static final String C_outhost = "outhost";
private static final String C_outport = "outport";
private static final String C_quiet = "quiet";
private static final String C_quit = "quit";
private static final String C_setkeys = "setkeys";
private static final String C_setnick = "setnick";
private static final String C_show = "show";
private static final String C_show_props = "showprops";
private static final String C_start = "start";
private static final String C_status = "status";
private static final String C_stop = "stop";
private static final String C_verify = "verify";
private static final String C_visit = "visit";
private static final String C_zap = "zap";
/* all the commands available, plus description */
private static final String C_ALL[][] = {
{C_help, C_help + " <command> * Get help on a command."},
{C_clear, C_clear + " * Clear the current nickname out of the list."},
{C_getdest, C_getdest + " * Return the destination for the current nickname."},
{C_getkeys, C_getkeys + " * Return the keypair for the current nickname."},
{C_getnick, C_getnick + " tunnelname * Set the nickname from the database."},
{C_inhost, C_inhost + " hostname | IP * Set the inbound hostname or IP."},
{C_inport, C_inport + " port_number * Set the inbound port number nickname listens on."},
{C_list, C_list + " * List all tunnels."},
{C_lookup, C_lookup + " * Lookup an i2p address."},
{C_newkeys, C_newkeys + " * Generate a new keypair for the current nickname."},
{C_option, C_option + " I2CPoption=something * Set an I2CP option. NOTE: Don't use any spaces."},
{C_outhost, C_outhost + " hostname | IP * Set the outbound hostname or IP."},
{C_outport, C_outport + " port_number * Set the outbound port that nickname contacts."},
{C_quiet, C_quiet + " True | False * Don't send to the application the incoming destination."},
{C_quit, C_quit + " * Quits this session with BOB."},
{C_setkeys, C_setkeys + " BASE64_keypair * Sets the keypair for the current nickname."},
{C_setnick, C_setnick + " nickname * Create a new nickname."},
{C_show, C_show + " * Display the status of the current nickname."},
{C_show_props, C_show_props + " * Display the properties of the current nickname."},
{C_start, C_start + " * Start the current nickname tunnel."},
{C_status, C_status + " nickname * Display status of a nicknamed tunnel."},
{C_stop, C_stop + " * Stops the current nicknamed tunnel."},
{C_verify, C_verify + " BASE64_key * Verifies BASE64 destination."},
{C_visit, C_visit + " * Thread dump to wrapper.log."},
{C_zap, C_zap + " * Shuts down BOB."},
{"", "COMMANDS: " + // this is ugly, but...
C_help + " " +
C_clear + " " +
C_getdest + " " +
C_getkeys + " " +
C_getnick + " " +
C_inhost + " " +
C_inport + " " +
C_list + " " +
C_lookup + " " +
C_newkeys + " " +
C_option + " " +
C_outhost + " " +
C_outport + " " +
C_quiet + " " +
C_quit + " " +
C_setkeys + " " +
C_setnick + " " +
C_show + " " +
C_show_props + " " +
C_start + " " +
C_status + " " +
C_stop + " " +
C_verify + " " +
C_visit + " " +
C_zap
},
{" ", " "} // end of list
};
/**
* @param LIVE
* @param server
* @param props
* @param database
* @param _log
*/
DoCMDS(AtomicBoolean LIVE, AtomicBoolean lock, Socket server, Properties props, NamedDB database, Logger _log) {
this.lock = lock;
this.LIVE = LIVE;
this.server = server;
this.props = new Properties();
this.database = database;
this._log = _log;
Lifted.copyProperties(props, this.props);
}
private void rlock() {
rlock(nickinfo);
}
private void rlock(NamedDB Arg) {
database.getReadLock();
Arg.getReadLock();
}
private void runlock() {
runlock(nickinfo);
}
private void runlock(NamedDB Arg) {
Arg.releaseReadLock();
database.releaseReadLock();
}
private void wlock() {
wlock(nickinfo);
}
private void wlock(NamedDB Arg) {
database.getWriteLock();
Arg.getWriteLock();
}
private void wunlock() {
wunlock(nickinfo);
}
private void wunlock(NamedDB Arg) {
Arg.releaseWriteLock();
database.releaseWriteLock();
}
/**
* Try to print info from the database
*
* @param out
* @param info
* @param key
*/
private void trypnt(PrintStream out, NamedDB info, String key) {
rlock(info);
try {
out.print(" " + key + ": ");
if (info.exists(key)) {
out.print(info.get(key));
} else {
out.print("not_set");
}
} finally {
runlock(info);
}
}
/**
* Print true or false if an object exists
*
* @param out
* @param info
* @param key
*/
private void tfpnt(PrintStream out, NamedDB info, String key) {
rlock(info);
try {
out.print(" " + key + ": ");
out.print(info.exists(key));
} finally {
runlock(info);
}
}
/**
* Print an error message
*
* @param out
*/
private static void nns(PrintStream out) {
out.println("ERROR no nickname has been set");
}
/**
* Dump various information from the database
*
* @param out
* @param info
*/
private void nickprint(PrintStream out, NamedDB info) {
trypnt(out, info, P_NICKNAME);
trypnt(out, info, P_STARTING);
trypnt(out, info, P_RUNNING);
trypnt(out, info, P_STOPPING);
tfpnt(out, info, P_KEYS);
trypnt(out, info, P_QUIET);
trypnt(out, info, P_INPORT);
trypnt(out, info, P_INHOST);
trypnt(out, info, P_OUTPORT);
trypnt(out, info, P_OUTHOST);
out.println();
}
/**
* Dump properties information from the database
*
* @param out
* @param info
*/
private void propprint(PrintStream out, NamedDB info) {
trypnt(out, info, P_PROPERTIES);
}
/**
* Print information on a specific record, indicated by NamedDB
* @param out
* @param Arg
*/
private void ttlpnt(PrintStream out, String Arg) {
database.getReadLock();
try {
if (database.exists(Arg)) {
out.print("DATA");
nickprint(out, (NamedDB) database.get(Arg));
}
} finally {
database.releaseReadLock();
}
}
/**
* Is this NamedDB's tunnel active?
*
* @param Arg
* @return true if the tunnel is active
*/
private boolean tunnelactive(NamedDB Arg) {
boolean retval;
rlock(Arg);
try {
retval = (Arg.get(P_STARTING).equals(Boolean.TRUE) ||
Arg.get(P_STOPPING).equals(Boolean.TRUE) ||
Arg.get(P_RUNNING).equals(Boolean.TRUE));
} finally {
runlock();
}
return retval;
}
/**
* Does the base64 information look OK
*
* @param data
* @return OK
*/
private static boolean is64ok(String data) {
try {
new Destination(data);
return true;
} catch (Exception e) {
return false;
}
}
/**
* The actual parser.
* It probabbly needs a rewrite into functions, but I kind-of like inline code.
*
*/
public void run() {
dk = ns = ip = op = false;
try {
try {
// Get input from the client
BufferedReader in = new BufferedReader(new InputStreamReader(server.getInputStream()));
PrintStream out = new PrintStream(server.getOutputStream());
quit:
{
die:
{
prikey = new ByteArrayOutputStream();
out.println("BOB " + BOBversion);
out.println("OK");
while ((line = in.readLine()) != null) {
StringTokenizer token = new StringTokenizer(line, " "); // use a space as a delimiter
String Command = "";
String Arg = "";
NamedDB info;
if (token.countTokens() != 0) {
Command = token.nextToken();
Command =
Command.toLowerCase(Locale.US);
if (token.countTokens() != 0) {
Arg = token.nextToken();
} else {
Arg = "";
}
// The rest of the tokens are considered junk,
// and discarded without any warnings.
if (Command.equals(C_help)) {
for (int i = 0; !C_ALL[i][0].equals(" "); i++) {
if (C_ALL[i][0].equalsIgnoreCase(Arg)) {
out.println("OK " + C_ALL[i][1]);
}
}
} else if (Command.equals(C_visit)) {
visitAllThreads();
out.println("OK ");
} else if (Command.equals(C_lookup)) {
Destination dest = null;
String reply = null;
if (Arg.endsWith(".i2p")) {
try {
//try {
//dest = I2PTunnel.destFromName(Arg);
//} catch (DataFormatException ex) {
//}
dest = I2PAppContext.getGlobalContext().namingService().lookup(Arg);
if(dest != null) {
reply = dest.toBase64();
}
} catch (NullPointerException npe) {
// Could not find the destination!?
}
}
if (reply == null) {
out.println("ERROR Address Not found.");
} else {
out.println("OK " + reply);
}
} else if (Command.equals(C_getdest)) {
if (ns) {
if (dk) {
rlock();
try {
out.println("OK " + nickinfo.get(P_DEST));
} catch (Exception e) {
break die;
} finally {
runlock();
}
} else {
out.println("ERROR keys not set.");
}
} else {
nns(out);
}
} else if (Command.equals(C_list)) {
// Produce a formatted list of all nicknames
database.getReadLock();
try {
for (Object ndb : database.values()) {
try {
info = (NamedDB) ndb;
out.print("DATA");
} catch (Exception e) {
break die;
}
nickprint(out, info);
}
} finally {
database.releaseReadLock();
}
out.println("OK Listing done");
} else if (Command.equals(C_quit)) {
// End the command session
break quit;
} else if (Command.equals(C_zap)) {
// Kill BOB!! (let's hope this works!)
LIVE.set(false);
// End the command session
break quit;
} else if (Command.equals(C_newkeys)) {
if (ns) {
try {
if (tunnelactive(nickinfo)) {
out.println("ERROR tunnel is active");
} else {
try {
// Make a new PublicKey and PrivateKey
prikey = new ByteArrayOutputStream();
d = I2PClientFactory.createClient().createDestination(prikey);
wlock();
try {
nickinfo.add(P_KEYS, prikey.toByteArray());
nickinfo.add(P_DEST, d.toBase64());
out.println("OK " + nickinfo.get(P_DEST));
} catch (Exception e) {
break die;
} finally {
wunlock();
}
dk = true;
} catch (I2PException ipe) {
_log.error("Error generating keys", ipe);
out.println("ERROR generating keys");
}
}
} catch (Exception e) {
break die;
}
} else {
nns(out);
}
} else if (Command.equals(C_getkeys)) {
// Return public key
if (dk) {
prikey = new ByteArrayOutputStream();
rlock();
try {
prikey.write(((byte[]) nickinfo.get(P_KEYS)));
} catch (Exception ex) {
break die;
} finally {
runlock();
}
out.println("OK " + net.i2p.data.Base64.encode(prikey.toByteArray()));
} else {
out.println("ERROR no public key has been set");
}
} else if (Command.equals(C_quiet)) {
if (ns) {
try {
if (tunnelactive(nickinfo)) {
out.println("ERROR tunnel is active");
} else {
wlock();
try {
nickinfo.add(P_QUIET, Boolean.valueOf(Arg));
} catch (Exception ex) {
break die;
} finally {
wunlock();
}
out.println("OK Quiet set");
}
} catch (Exception ex) {
break die;
}
} else {
nns(out);
}
} else if (Command.equals(C_verify)) {
if (is64ok(Arg)) {
out.println("OK");
} else {
out.println("ERROR not in BASE64 format");
}
} else if (Command.equals(C_setkeys)) {
// Set the NamedDB to a privatekey in BASE64 format
if (ns) {
try {
if (tunnelactive(nickinfo)) {
out.println("ERROR tunnel is active");
} else {
try {
prikey = new ByteArrayOutputStream();
prikey.write(net.i2p.data.Base64.decode(Arg));
d = new Destination();
d.fromBase64(Arg);
} catch (Exception ex) {
Arg = "";
}
if ((Arg.length() == 884) && is64ok(Arg)) {
wlock();
try {
nickinfo.add(P_KEYS, prikey.toByteArray());
nickinfo.add(P_DEST, d.toBase64());
out.println("OK " + nickinfo.get(P_DEST));
} catch (Exception ex) {
break die;
} finally {
wunlock();
}
dk = true;
} else {
out.println("ERROR not in BASE64 format");
}
}
} catch (Exception ex) {
break die;
}
} else {
nns(out);
}
} else if (Command.equals(C_setnick)) {
ns = dk = ip = op = false;
database.getReadLock();
try {
nickinfo = (NamedDB) database.get(Arg);
if (!tunnelactive(nickinfo)) {
nickinfo = null;
ns = true;
}
} catch (Exception b) {
nickinfo = null;
ns = true;
} finally {
database.releaseReadLock();
}
// Clears and Sets the initial NamedDB structure to work with
if (ns) {
nickinfo = new NamedDB();
wlock();
try {
database.add(Arg, nickinfo);
nickinfo.add(P_NICKNAME, Arg);
nickinfo.add(P_STARTING, Boolean.FALSE);
nickinfo.add(P_RUNNING, Boolean.FALSE);
nickinfo.add(P_STOPPING, Boolean.FALSE);
nickinfo.add(P_QUIET, Boolean.FALSE);
nickinfo.add(P_INHOST, "localhost");
nickinfo.add(P_OUTHOST, "localhost");
Properties Q = new Properties();
Lifted.copyProperties(this.props, Q);
Q.setProperty("inbound.nickname", Arg);
Q.setProperty("outbound.nickname", Arg);
nickinfo.add(P_PROPERTIES, Q);
} catch (Exception e) {
break die;
} finally {
wunlock();
}
out.println("OK Nickname set to " + Arg);
} else {
out.println("ERROR tunnel is active");
}
} else if (Command.equals(C_option)) {
if (ns) {
try {
if (tunnelactive(nickinfo)) {
out.println("ERROR tunnel is active");
} else {
StringTokenizer otoken = new StringTokenizer(Arg, "="); // use an equal sign as a delimiter
if (otoken.countTokens() != 2) {
out.println("ERROR too many or no options.");
} else {
String pname = otoken.nextToken();
String pval = otoken.nextToken();
wlock();
try {
Properties Q = (Properties) nickinfo.get(P_PROPERTIES);
Q.setProperty(pname, pval);
nickinfo.add(P_PROPERTIES, Q);
} catch (Exception ex) {
break die;
} finally {
wunlock();
}
out.println("OK " + pname + " set to " + pval);
}
}
} catch (Exception ex) {
break die;
}
} else {
nns(out);
}
} else if (Command.equals(C_getnick)) {
// Get the NamedDB to work with...
boolean nsfail = false;
database.getReadLock();
try {
nickinfo = (NamedDB) database.get(Arg);
ns = true;
} catch (RuntimeException b) {
nsfail = true;
nns(out);
} finally {
database.releaseReadLock();
}
if (ns && !nsfail) {
rlock();
try {
dk = nickinfo.exists(P_KEYS);
ip = nickinfo.exists(P_INPORT);
op = nickinfo.exists(P_OUTPORT);
} catch (Exception ex) {
break die;
} finally {
runlock();
}
// Finally say OK.
out.println("OK Nickname set to " + Arg);
}
} else if (Command.equals(C_inport)) {
// Set the NamedDB inbound TO the router port
// app --> BOB
if (ns) {
try {
if (tunnelactive(nickinfo)) {
out.println("ERROR tunnel is active");
} else {
int prt;
wlock();
try {
nickinfo.kill(P_INPORT);
prt = Integer.parseInt(Arg);
if (prt > 1 && prt < 65536) {
try {
nickinfo.add(P_INPORT, Integer.valueOf(prt));
} catch (Exception ex) {
break die;
}
}
ip = nickinfo.exists(P_INPORT);
} catch (NumberFormatException nfe) {
out.println("ERROR not a number");
} finally {
wunlock();
}
if (ip) {
out.println("OK inbound port set");
} else {
out.println("ERROR port out of range");
}
}
} catch (Exception ex) {
break die;
}
} else {
nns(out);
}
} else if (Command.equals(C_outport)) {
// Set the NamedDB outbound FROM the router port
// BOB --> app
if (ns) {
try {
if (tunnelactive(nickinfo)) {
out.println("ERROR tunnel is active");
} else {
int prt;
wlock();
try {
nickinfo.kill(P_OUTPORT);
prt = Integer.parseInt(Arg);
if (prt > 1 && prt < 65536) {
nickinfo.add(P_OUTPORT, Integer.valueOf(prt));
}
ip = nickinfo.exists(P_OUTPORT);
} catch (NumberFormatException nfe) {
out.println("ERROR not a number");
} catch (Exception ex) {
break die;
} finally {
wunlock();
}
if (ip) {
out.println("OK outbound port set");
} else {
out.println("ERROR port out of range");
}
}
} catch (Exception ex) {
break die;
}
} else {
nns(out);
}
} else if (Command.equals(C_inhost)) {
if (ns) {
try {
if (tunnelactive(nickinfo)) {
out.println("ERROR tunnel is active");
} else {
wlock();
try {
nickinfo.add(P_INHOST, Arg);
} catch (Exception ex) {
break die;
} finally {
wunlock();
}
out.println("OK inhost set");
}
} catch (Exception ex) {
break die;
}
} else {
nns(out);
}
} else if (Command.equals(C_outhost)) {
if (ns) {
try {
if (tunnelactive(nickinfo)) {
out.println("ERROR tunnel is active");
} else {
wlock();
try {
nickinfo.add(P_OUTHOST, Arg);
} catch (Exception ex) {
break die;
} finally {
wunlock();
}
out.println("OK outhost set");
}
} catch (Exception ex) {
break die;
}
} else {
nns(out);
}
} else if (Command.equals(C_show)) {
// Get the current NamedDB properties
if (ns) {
out.print("OK");
nickprint(out, nickinfo);
} else {
nns(out);
}
} else if (Command.equals(C_show_props)) {
// Get the current options properties
if (ns) {
out.print("OK");
propprint(out, nickinfo);
} else {
nns(out);
}
} else if (Command.equals(C_start)) {
// Start the tunnel, if we have all the information
if (ns && dk && (ip || op)) {
try {
if (tunnelactive(nickinfo)) {
out.println("ERROR tunnel is active");
} else {
MUXlisten tunnel;
try {
while (!lock.compareAndSet(false, true)) {
// wait
}
tunnel = new MUXlisten(lock, database, nickinfo, _log);
Thread t = new I2PAppThread(tunnel);
t.start();
// try {
// Thread.sleep(1000 * 10); // Slow down the startup.
// } catch(InterruptedException ie) {
// // ignore it
// }
out.println("OK tunnel starting");
} catch (I2PException e) {
lock.set(false);
out.println("ERROR starting tunnel: " + e);
} catch (IOException e) {
lock.set(false);
out.println("ERROR starting tunnel: " + e);
}
}
} catch (Exception ex) {
break die;
}
} else {
out.println("ERROR tunnel settings incomplete");
}
} else if (Command.equals(C_stop)) {
// Stop the tunnel, if it is running
if (ns) {
rlock();
boolean released = false;
try {
if (nickinfo.get(P_RUNNING).equals(Boolean.TRUE) && nickinfo.get(P_STOPPING).equals(Boolean.FALSE) && nickinfo.get(P_STARTING).equals(Boolean.FALSE)) {
runlock();
released = true;
wlock();
try {
nickinfo.add(P_STOPPING, Boolean.TRUE);
} catch (Exception e) {
break die;
} finally {
wunlock();
}
out.println("OK tunnel stopping");
} else {
out.println("ERROR tunnel is inactive");
}
} catch (Exception e) {
break die;
} finally {
if (!released)
runlock();
}
} else {
nns(out);
}
} else if (Command.equals(C_clear)) {
// Clear use of the NamedDB if stopped
if (ns) {
try {
if (tunnelactive(nickinfo)) {
out.println("ERROR tunnel is active");
} else {
database.getWriteLock();
try {
database.kill((String) nickinfo.get(P_NICKNAME));
} catch (Exception e) {
} finally {
database.releaseWriteLock();
}
dk = ns = ip = op = false;
out.println("OK cleared");
}
} catch (Exception ex) {
break die;
}
} else {
nns(out);
}
} else if (Command.equals(C_status)) {
database.getReadLock();
try {
if (database.exists(Arg)) {
// Show status of a NamedDB
out.print("OK ");
try {
ttlpnt(out, Arg);
} catch (Exception e) {
out.println(); // this will cause an IOE if IOE
break die;
}
} else {
nns(out);
}
} catch (Exception e) {
break die;
} finally {
database.releaseReadLock();
}
} else {
out.println("ERROR UNKNOWN COMMAND! Try help");
}
}
}
} // die
out.print("ERROR A really bad error just happened, ");
} // quit
// Say goodbye.
out.println("OK Bye!");
} catch (IOException ioe) {
// not really needed, except to debug.
// BOB.warn("IOException on socket listen: " + ioe);
// ioe.printStackTrace();
}
} finally {
try {
server.close();
} catch (IOException ex) {
// nop
}
}
}
// Debugging... None of this is normally used.
/**
* Find the root thread group and print them all.
*
*/
private void visitAllThreads() {
ThreadGroup root = Thread.currentThread().getThreadGroup().getParent();
while (root.getParent() != null) {
root = root.getParent();
}
// Visit each thread group
visit(root, 0, root.getName());
}
/**
* Recursively visits all thread groups under `group' and dumps them.
* @param group ThreadGroup to visit
* @param level Current level
*/
private static void visit(ThreadGroup group, int level, String tn) {
// Get threads in `group'
int numThreads = group.activeCount();
Thread[] threads = new Thread[numThreads * 2];
numThreads = group.enumerate(threads, false);
String indent = "------------------------------------".substring(0, level) + "-> ";
// Enumerate each thread in `group' and print it.
for (int i = 0; i < numThreads; i++) {
// Get thread
Thread thread = threads[i];
System.out.println("BOB: " + indent + tn + ": " + thread.toString());
}
// Get thread subgroups of `group'
int numGroups = group.activeGroupCount();
ThreadGroup[] groups = new ThreadGroup[numGroups * 2];
numGroups = group.enumerate(groups, false);
// Recursively visit each subgroup
for (int i = 0; i < numGroups; i++) {
visit(groups[i], level + 1, groups[i].getName());
}
}
}

View File

@ -0,0 +1,99 @@
/**
* WTFPL
* Version 2, December 2004
*
* Copyright (C) sponge
* Planet Earth
*
* See...
*
* http://sam.zoy.org/wtfpl/
* and
* http://en.wikipedia.org/wiki/WTFPL
*
* ...for any additional details and license questions.
*/
package net.i2p.BOB;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import net.i2p.I2PException;
import net.i2p.client.streaming.I2PServerSocket;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.client.streaming.I2PSocketManager;
import net.i2p.util.I2PAppThread;
/**
* Listen on I2P and connect to TCP
*
* @author sponge
*/
public class I2Plistener implements Runnable {
private final NamedDB info, database;
private final Logger _log;
private final I2PServerSocket serverSocket;
private final AtomicBoolean lives;
/**
* Constructor
* @param SS
* @param S unused
* @param info
* @param database
* @param _log
*/
I2Plistener(I2PServerSocket SS, I2PSocketManager S, NamedDB info, NamedDB database, Logger _log, AtomicBoolean lives) {
this.database = database;
this.info = info;
this._log = _log;
this.serverSocket = SS;
this.lives = lives;
}
/**
* Simply listen on I2P port, and thread connections
*
*/
public void run() {
boolean g = false;
I2PSocket sessSocket = null;
int conn = 0;
try {
try {
serverSocket.setSoTimeout(50);
while (lives.get()) {
try {
sessSocket = serverSocket.accept();
g = true;
} catch (ConnectException ce) {
g = false;
} catch (SocketTimeoutException ste) {
g = false;
}
if (g) {
g = false;
conn++;
// toss the connection to a new thread.
I2PtoTCP conn_c = new I2PtoTCP(sessSocket, info, database, lives);
Thread t = new I2PAppThread(conn_c, Thread.currentThread().getName() + " I2PtoTCP " + conn);
t.start();
}
}
} catch (I2PException e) {
// bad stuff
System.out.println("Exception " + e);
}
} finally {
try {
serverSocket.close();
} catch (I2PException ex) {
}
// System.out.println("I2Plistener: Close");
}
}
}

View File

@ -0,0 +1,169 @@
/**
* WTFPL
* Version 2, December 2004
*
* Copyright (C) sponge
* Planet Earth
*
* See...
*
* http://sam.zoy.org/wtfpl/
* and
* http://en.wikipedia.org/wiki/WTFPL
*
* ...for any additional details and license questions.
*/
package net.i2p.BOB;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.concurrent.atomic.AtomicBoolean;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.data.DataHelper;
import net.i2p.util.I2PAppThread;
/**
* Process I2P-&gt;TCP
*
* @author sponge
*/
public class I2PtoTCP implements Runnable {
private I2PSocket I2P;
private final NamedDB info, database;
private Socket sock;
private final AtomicBoolean lives;
/**
* Constructor
*
* @param I2Psock
* @param info
* @param database
*/
I2PtoTCP(I2PSocket I2Psock, NamedDB info, NamedDB database, AtomicBoolean lives) {
this.I2P = I2Psock;
this.info = info;
this.database = database;
this.lives = lives;
}
private void rlock() {
database.getReadLock();
info.getReadLock();
}
private void runlock() {
info.releaseReadLock();
database.releaseReadLock();
}
/**
* I2P stream to TCP stream thread starter
*
*/
public void run() {
String host;
int port;
boolean tell;
InputStream in = null;
OutputStream out = null;
InputStream Iin = null;
OutputStream Iout = null;
Thread t = null;
Thread q = null;
try {
die:
{
try {
rlock();
try {
host = info.get("OUTHOST").toString();
port = Integer.parseInt(info.get("OUTPORT").toString());
tell = info.get("QUIET").equals(Boolean.FALSE);
} catch (Exception e) {
break die;
} finally {
runlock();
}
sock = new Socket(host, port);
sock.setKeepAlive(true);
// make readers/writers
in = sock.getInputStream();
out = sock.getOutputStream();
Iin = I2P.getInputStream();
Iout = I2P.getOutputStream();
I2P.setReadTimeout(0); // temp bugfix, this *SHOULD* be the default
if (tell) {
// tell who is connecting
out.write(DataHelper.getASCII(I2P.getPeerDestination().toBase64()));
out.write(10); // nl
out.flush(); // not really needed, but...
}
// setup to cross the streams
TCPio conn_c = new TCPio(in, Iout, lives); // app -> I2P
TCPio conn_a = new TCPio(Iin, out, lives); // I2P -> app
t = new I2PAppThread(conn_c, Thread.currentThread().getName() + " TCPioA");
q = new I2PAppThread(conn_a, Thread.currentThread().getName() + " TCPioB");
// Fire!
t.start();
q.start();
while (t.isAlive() && q.isAlive() && lives.get()) { // AND is used here to kill off the other thread
try {
Thread.sleep(10); //sleep for 10 ms
} catch (InterruptedException e) {
break die;
}
}
// System.out.println("I2PtoTCP: Going away...");
} catch (Exception e) {
// System.out.println("I2PtoTCP: Owch! damn!");
break die;
}
} // die
} finally {
try {
in.close();
} catch (Exception ex) {
}
try {
out.close();
} catch (Exception ex) {
}
try {
Iin.close();
} catch (Exception ex) {
}
try {
Iout.close();
} catch (Exception ex) {
}
try {
t.interrupt();
} catch (Exception e) {
}
try {
q.interrupt();
} catch (Exception e) {
}
try {
// System.out.println("I2PtoTCP: Close I2P");
I2P.close();
} catch (Exception e) {
tell = false;
}
//System.out.println("I2PtoTCP: Closed I2P");
try {
// System.out.println("I2PtoTCP: Close sock");
sock.close();
} catch (Exception e) {
tell = false;
}
// System.out.println("I2PtoTCP: Done");
}
}
}

View File

@ -0,0 +1,46 @@
/**
* WTFPL
* Version 2, December 2004
*
* Copyright (C) sponge
* Planet Earth
*
* See...
*
* http://sam.zoy.org/wtfpl/
* and
* http://en.wikipedia.org/wiki/WTFPL
*
* ...for any additional details and license questions.
*/
package net.i2p.BOB;
import java.util.Map;
import java.util.Properties;
/**
* Sets of "friendly" utilities to make life easier.
* Any "Lifted" code will apear here, and credits given.
* It's better to "Lift" a small chunk of "free" code than add in piles of
* code we don't need, and don't want.
*
* @author sponge
*/
public class Lifted {
/**
* Copy a set of properties from one Property to another.
* Lifted from Apache Derby code svn repository.
* Liscenced as follows:
* http://svn.apache.org/repos/asf/db/derby/code/trunk/LICENSE
*
* @param src_prop Source set of properties to copy from.
* @param dest_prop Dest Properties to copy into.
*
**/
public static void copyProperties(Properties src_prop, Properties dest_prop) {
for (Map.Entry<Object, Object> e : src_prop.entrySet()) {
dest_prop.put((String)e.getKey(), (String)e.getValue());
}
}
}

View File

@ -0,0 +1,44 @@
package net.i2p.BOB;
import net.i2p.util.Log;
public class Logger {
public Log log;
private boolean logToStdout;
public Logger(Log log, boolean logToStdout) {
this.log = log;
this.logToStdout = logToStdout;
}
public void info(String msg) {
if (logToStdout)
System.out.println("INFO: " + msg);
if (log.shouldLog(Log.INFO))
log.info(msg);
}
public void warn(String msg) {
warn(msg, null);
}
public void warn(String msg, Throwable e) {
if (logToStdout) {
System.out.println("WARNING: " + msg);
if (e != null)
e.printStackTrace();
}
if (log.shouldLog(Log.WARN))
log.warn(msg, e);
}
public void error(String msg, Throwable e) {
if (logToStdout) {
System.out.println("ERROR: " + msg);
if (e != null)
e.printStackTrace();
}
if (log.shouldLog(Log.ERROR))
log.error(msg, e);
}
}

View File

@ -0,0 +1,416 @@
/**
* WTFPL
* Version 2, December 2004
*
* Copyright (C) sponge
* Planet Earth
*
* See...
*
* http://sam.zoy.org/wtfpl/
* and
* http://en.wikipedia.org/wiki/WTFPL
*
* ...for any additional details and license questions.
*/
package net.i2p.BOB;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicBoolean;
import net.i2p.I2PException;
import net.i2p.client.I2PClient;
import net.i2p.client.streaming.I2PServerSocket;
import net.i2p.client.streaming.I2PSocketManager;
import net.i2p.client.streaming.I2PSocketManagerFactory;
import net.i2p.util.I2PAppThread;
import net.i2p.util.Log;
/**
*
* Multiplex listeners for TCP and I2P
*
* @author sponge
*/
public class MUXlisten implements Runnable {
private final NamedDB database, info;
private final Logger _log;
private final I2PSocketManager socketManager;
private final ByteArrayInputStream prikey;
private ThreadGroup tg;
private final String N;
private ServerSocket listener;
private static final int backlog = 50; // should this be more? less?
private final boolean go_out;
private final boolean come_in;
private final AtomicBoolean lock;
private final AtomicBoolean lives;
/**
* Constructor Will fail if INPORT is occupied.
*
* @param info DB entry for this tunnel
* @param database master database of tunnels
* @param _log
* @throws net.i2p.I2PException
* @throws java.io.IOException
*/
MUXlisten(AtomicBoolean lock, NamedDB database, NamedDB info, Logger _log) throws I2PException, IOException, RuntimeException {
int port = 0;
InetAddress host = null;
this.lock = lock;
this.tg = null;
this.database = database;
this.info = info;
this._log = _log;
lives = new AtomicBoolean(false);
try {
wlock();
try {
this.info.add("STARTING", Boolean.TRUE);
} finally {
wunlock();
}
Properties Q = new Properties();
rlock();
try {
N = this.info.get("NICKNAME").toString();
prikey = new ByteArrayInputStream((byte[]) info.get("KEYS"));
// Make a new copy so that anything else won't muck with our database.
Properties R = (Properties) info.get("PROPERTIES");
Lifted.copyProperties(R, Q);
this.go_out = info.exists("OUTPORT");
this.come_in = info.exists("INPORT");
if (this.come_in) {
port = Integer.parseInt(info.get("INPORT").toString());
host = InetAddress.getByName(info.get("INHOST").toString());
}
} finally {
runlock();
}
String i2cpHost = Q.getProperty(I2PClient.PROP_TCP_HOST, "127.0.0.1");
int i2cpPort = I2PClient.DEFAULT_LISTEN_PORT;
String i2cpPortStr = Q.getProperty(I2PClient.PROP_TCP_PORT);
if (i2cpPortStr != null) {
try {
i2cpPort = Integer.parseInt(i2cpPortStr);
} catch (NumberFormatException nfe) {
throw new IllegalArgumentException("Invalid I2CP port specified [" + i2cpPortStr + "]");
}
}
if (this.come_in) {
this.listener = new ServerSocket(port, backlog, host);
}
socketManager = I2PSocketManagerFactory.createManager(
prikey, i2cpHost, i2cpPort, Q);
} catch (IOException e) {
// Something went bad.
wlock();
try {
this.info.add("STARTING", Boolean.FALSE);
} finally {
wunlock();
}
throw e;
} catch (RuntimeException e) {
// Something went bad.
wlock();
try {
this.info.add("STARTING", Boolean.FALSE);
} finally {
wunlock();
}
throw e;
} catch (Exception e) {
// Something else went bad.
wlock();
try {
this.info.add("STARTING", Boolean.FALSE);
} finally {
wunlock();
}
e.printStackTrace();
throw new RuntimeException(e);
}
}
private void rlock() {
database.getReadLock();
info.getReadLock();
}
private void runlock() {
info.releaseReadLock();
database.releaseReadLock();
}
private void wlock() {
database.getWriteLock();
info.getWriteLock();
}
private void wunlock() {
info.releaseWriteLock();
database.releaseWriteLock();
}
/**
* MUX sockets, fire off a thread to connect, get destination info, and do I/O
*
*/
public void run() {
I2PServerSocket SS = null;
Thread t = null;
Thread q = null;
try {
wlock();
try {
try {
info.add("RUNNING", Boolean.TRUE);
} catch (Exception e) {
lock.set(false);
return;
}
} catch (Exception e) {
lock.set(false);
return;
} finally {
wunlock();
}
lives.set(true);
lock.set(false);
quit:
{
try {
tg = new ThreadGroup(N);
{
// toss the connections to a new threads.
// will wrap with TCP and UDP when UDP works
if (go_out) {
// I2P -> TCP
SS = socketManager.getServerSocket();
I2Plistener conn = new I2Plistener(SS, socketManager, info, database, _log, lives);
t = new I2PAppThread(tg, conn, "BOBI2Plistener " + N);
t.start();
}
if (come_in) {
// TCP -> I2P
TCPlistener conn = new TCPlistener(listener, socketManager, info, database, _log, lives);
q = new I2PAppThread(tg, conn, "BOBTCPlistener " + N);
q.start();
}
wlock();
try {
try {
info.add("STARTING", Boolean.FALSE);
} catch (Exception e) {
break quit;
}
} catch (Exception e) {
break quit;
} finally {
wunlock();
}
boolean spin = true;
while (spin && lives.get()) {
try {
Thread.sleep(1000); //sleep for 1 second
} catch (InterruptedException e) {
break quit;
}
rlock();
try {
try {
spin = info.get("STOPPING").equals(Boolean.FALSE);
} catch (Exception e) {
break quit;
}
} catch (Exception e) {
break quit;
} finally {
runlock();
}
}
} // die
} catch (Exception e) {
// System.out.println("MUXlisten: Caught an exception" + e);
break quit;
}
} // quit
} finally {
lives.set(false);
// Some grace time.
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
}
try {
wlock();
try {
info.add("STARTING", Boolean.FALSE);
info.add("STOPPING", Boolean.TRUE);
info.add("RUNNING", Boolean.FALSE);
} catch (Exception e) {
lock.set(false);
return;
}
} catch (Exception e) {
} finally {
wunlock();
}
// Start cleanup.
while (!lock.compareAndSet(false, true)) {
// wait
}
if (SS != null) {
try {
SS.close();
} catch (I2PException ex) {
}
}
if (listener != null) {
try {
listener.close();
} catch (IOException e) {
}
}
// Some grace time.
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
}
// Hopefully nuke stuff here...
{
String groupName = tg.getName();
try {
_log.warn("destroySocketManager " + groupName);
socketManager.destroySocketManager();
_log.warn("destroySocketManager Successful" + groupName);
} catch (Exception e) {
// nop
_log.warn("destroySocketManager Failed" + groupName);
_log.warn(e.toString());
}
}
// zero out everything.
try {
wlock();
try {
info.add("STARTING", Boolean.FALSE);
info.add("STOPPING", Boolean.FALSE);
info.add("RUNNING", Boolean.FALSE);
} catch (Exception e) {
lock.set(false);
return;
} finally {
wunlock();
}
} catch (Exception e) {
}
lock.set(false); // Should we force waiting for all threads??
// Wait around till all threads are collected.
if (tg != null) {
String groupName = tg.getName();
// System.out.println("BOB: MUXlisten: Starting thread collection for: " + groupName);
_log.warn("BOB: MUXlisten: Starting thread collection for: " + groupName);
if (tg.activeCount() + tg.activeGroupCount() != 0) {
// visit(tg, 0, groupName);
int foo = tg.activeCount() + tg.activeGroupCount();
// hopefully no longer needed!
// int bar = lives;
// System.out.println("BOB: MUXlisten: Waiting on threads for " + groupName);
// System.out.println("\nBOB: MUXlisten: ThreadGroup dump BEGIN " + groupName);
// visit(tg, 0, groupName);
// System.out.println("BOB: MUXlisten: ThreadGroup dump END " + groupName + "\n");
// Happily spin forever :-(
while (foo != 0) {
foo = tg.activeCount() + tg.activeGroupCount();
// if (lives != bar && lives != 0) {
// System.out.println("\nBOB: MUXlisten: ThreadGroup dump BEGIN " + groupName);
// visit(tg, 0, groupName);
// System.out.println("BOB: MUXlisten: ThreadGroup dump END " + groupName + "\n");
// }
// bar = lives;
try {
Thread.sleep(100); //sleep for 100 ms (One tenth second)
} catch (InterruptedException ex) {
// nop
}
}
}
// System.out.println("BOB: MUXlisten: Threads went away. Success: " + groupName);
_log.warn("BOB: MUXlisten: Threads went away. Success: " + groupName);
tg.destroy();
// Zap reference to the ThreadGroup so the JVM can GC it.
tg = null;
}
try {
socketManager.destroySocketManager();
} catch (Exception e) {
// nop
}
}
}
// Debugging... None of this is normally used.
/**
* Find the root thread group and print them all.
*
*/
private void visitAllThreads() {
ThreadGroup root = Thread.currentThread().getThreadGroup().getParent();
while (root.getParent() != null) {
root = root.getParent();
}
// Visit each thread group
visit(root, 0, root.getName());
}
/**
* Recursively visits all thread groups under `group' and dumps them.
* @param group ThreadGroup to visit
* @param level Current level
*/
private static void visit(ThreadGroup group, int level, String tn) {
// Get threads in `group'
int numThreads = group.activeCount();
Thread[] threads = new Thread[numThreads * 2];
numThreads = group.enumerate(threads, false);
String indent = "------------------------------------".substring(0, level) + "-> ";
// Enumerate each thread in `group' and print it.
for (int i = 0; i < numThreads; i++) {
// Get thread
Thread thread = threads[i];
System.out.println("BOB: MUXlisten: " + tn + ": " + indent + thread.toString());
}
// Get thread subgroups of `group'
int numGroups = group.activeGroupCount();
ThreadGroup[] groups = new ThreadGroup[numGroups * 2];
numGroups = group.enumerate(groups, false);
// Recursively visit each subgroup
for (int i = 0; i < numGroups; i++) {
visit(groups[i], level + 1, groups[i].getName());
}
}
}

View File

@ -0,0 +1,39 @@
/**
* WTFPL
* Version 2, December 2004
*
* Copyright (C) sponge
* Planet Earth
*
* See...
*
* http://sam.zoy.org/wtfpl/
* and
* http://en.wikipedia.org/wiki/WTFPL
*
* ...for any additional details and license questions.
*/
package net.i2p.BOB;
import net.i2p.util.SimpleTimer2;
/**
* Start from command line
*
* @author sponge
*
*/
public class Main {
/**
* @param args the command line arguments, these are not used yet
*/
public static void main(String[] args) {
// THINK THINK THINK THINK THINK THINK
SimpleTimer2 Y2 = SimpleTimer2.getInstance();
BOB.main(args);
Y2.stop();
}
}

View File

@ -0,0 +1,106 @@
/**
* WTFPL
* Version 2, December 2004
*
* Copyright (C) sponge
* Planet Earth
*
* See...
*
* http://sam.zoy.org/wtfpl/
* and
* http://en.wikipedia.org/wiki/WTFPL
*
* ...for any additional details and license questions.
*/
package net.i2p.BOB;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* Internal database to relate nicknames to options to values
*
* @author sponge
*/
public class NamedDB {
private final Map<String, Object> data;
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(false);
/**
*
*/
public NamedDB() {
this.data = new HashMap<String, Object>();
}
public void getReadLock() {
lock.readLock().lock();
}
public void releaseReadLock() {
lock.readLock().unlock();
}
public void getWriteLock() {
lock.writeLock().lock();
}
public void releaseWriteLock() {
lock.writeLock().unlock();
}
/**
* Delete an object if it exists
*
* @param key
*/
public void kill(String key) {
data.remove(key);
}
/**
* Add object, deletes the old one if it exists
*
* @param key
* @param val
*/
public void add(String key, Object val) {
data.put(key, val);
}
/**
* Get the object, and return it, throws RuntimeException if not found
*
* @param key non-null
* @return Object non-null
* @throws java.lang.RuntimeException if not found
*/
public Object get(String key) throws RuntimeException {
Object rv = data.get(key);
if (rv != null)
return rv;
throw new RuntimeException("Key not found");
}
/**
* returns true if an object exists, else returns false
*
* @param key
* @return true if an object exists, else returns false
*/
public boolean exists(String key) {
return data.containsKey(key);
}
/**
* @since 0.9.29 replaces getcount() and getnext(int)
*/
public Collection<Object> values() {
return data.values();
}
}

View File

@ -0,0 +1,121 @@
/**
* WTFPL
* Version 2, December 2004
*
* Copyright (C) sponge
* Planet Earth
*
* See...
*
* http://sam.zoy.org/wtfpl/
* and
* http://en.wikipedia.org/wiki/WTFPL
*
* ...for any additional details and license questions.
*/
package net.i2p.BOB;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Shove data from one stream to the other.
*
* @author sponge
*/
public class TCPio implements Runnable {
private final InputStream Ain;
private final OutputStream Aout;
private final AtomicBoolean lives;
/**
* Constructor
*
* @param Ain InputStream
* @param Aout OutputStream
*
* param database
*/
TCPio(InputStream Ain, OutputStream Aout, AtomicBoolean lives) {
this.Ain = Ain;
this.Aout = Aout;
this.lives = lives;
}
/**
* Copy from source to destination...
* and yes, we are totally OK to block here on writes,
* The OS has buffers, and I intend to use them.
* We send an interrupt signal to the threadgroup to
* unwedge any pending writes.
*
*/
public void run() {
/*
* NOTE:
* The write method of OutputStream calls the write method of
* one argument on each of the bytes to be written out.
* Subclasses are encouraged to override this method and provide
* a more efficient implementation.
*
* So, is this really a performance problem?
* Should we expand to several bytes?
* I don't believe there would be any gain, since read method
* has the same reccomendations. If anyone has a better way to
* do this, I'm interested in performance improvements.
*
* --Sponge
*
* Tested with 128 bytes, and there was no performance gain.
* 8192 bytes did lower load average across many connections.
* Should I raise it higer? The correct thing to do would be to
* override... perhaps use NTCP, but I2P's streaming lib lacks
* anything NTCP compatable.
*
* --Sponge
*/
int b;
byte a[] = new byte[8192];
try {
try {
while (lives.get()) {
b = Ain.read(a, 0, 8192);
if (b > 0) {
Aout.write(a, 0, b);
} else if (b == 0) {
while(Ain.available() == 0) {
Thread.sleep(20);
}
} else {
/* according to the specs:
*
* The total number of bytes read into the buffer,
* or -1 if there is no more data because the end of
* the stream has been reached.
*
*/
// System.out.println("TCPio: End Of Stream");
break;
}
}
} catch (Exception e) {
}
// System.out.println("TCPio: Leaving.");
} finally {
// Eject!!! Eject!!!
//System.out.println("TCPio: Caught an exception " + e);
try {
Ain.close();
} catch (IOException ex) {
}
try {
Aout.close();
} catch (IOException ex) {
}
}
}
}

View File

@ -0,0 +1,95 @@
/**
* WTFPL
* Version 2, December 2004
*
* Copyright (C) sponge
* Planet Earth
*
* See...
*
* http://sam.zoy.org/wtfpl/
* and
* http://en.wikipedia.org/wiki/WTFPL
*
* ...for any additional details and license questions.
*/
package net.i2p.BOB;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import net.i2p.client.streaming.I2PServerSocket;
import net.i2p.client.streaming.I2PSocketManager;
import net.i2p.util.I2PAppThread;
/**
* Listen on TCP port and connect to I2P
*
* @author sponge
*/
public class TCPlistener implements Runnable {
private final NamedDB info, database;
private final Logger _log;
private final I2PSocketManager socketManager;
private final ServerSocket listener;
private final AtomicBoolean lives;
/**
* Constructor
* @param S
* @param info
* @param database
* @param _log
*/
TCPlistener(ServerSocket listener, I2PSocketManager S, NamedDB info, NamedDB database, Logger _log, AtomicBoolean lives) {
this.database = database;
this.info = info;
this._log = _log;
this.socketManager = S;
this.listener = listener;
this.lives = lives;
}
/**
* Simply listen on TCP port, and thread connections
*
*/
public void run() {
boolean g = false;
int conn = 0;
Socket server = null;
try {
try {
listener.setSoTimeout(50); // We don't block, we cycle and check.
while (lives.get()) {
try {
server = listener.accept();
server.setKeepAlive(true);
g = true;
} catch (SocketTimeoutException ste) {
g = false;
}
if (g) {
conn++;
// toss the connection to a new thread.
TCPtoI2P conn_c = new TCPtoI2P(socketManager, server, info, database, lives);
Thread t = new I2PAppThread(conn_c, Thread.currentThread().getName() + " TCPtoI2P " + conn);
t.start();
g = false;
}
}
} catch (IOException ioe) {
}
} finally {
try {
listener.close();
} catch (IOException ex) {
}
//System.out.println("TCPlistener: " + Thread.currentThread().getName() + "Done.");
}
}
}

View File

@ -0,0 +1,222 @@
/**
* WTFPL
* Version 2, December 2004
*
* Copyright (C) sponge
* Planet Earth
*
* See...
*
* http://sam.zoy.org/wtfpl/
* and
* http://en.wikipedia.org/wiki/WTFPL
*
* ...for any additional details and license questions.
*/
package net.i2p.BOB;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.NoRouteToHostException;
import java.net.Socket;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicBoolean;
import net.i2p.I2PAppContext;
import net.i2p.I2PException;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.client.streaming.I2PSocketManager;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;
import net.i2p.util.I2PAppThread;
/**
*
* Process TCP-&gt;I2P
*
* @author sponge
*/
public class TCPtoI2P implements Runnable {
private I2PSocket I2P;
private final Socket sock;
private final I2PSocketManager socketManager;
private final AtomicBoolean lives;
/**
* Constructor
* @param i2p
* @param socket
* @param info unused
* @param database unused
*/
TCPtoI2P(I2PSocketManager i2p, Socket socket, NamedDB info, NamedDB database, AtomicBoolean lives) {
this.sock = socket;
this.socketManager = i2p;
this.lives = lives;
}
/**
* This is a more forgiving readline,
* it works on unbuffered streams
*
* @param in
* @return line of text as a String
* @throws IOException
*/
private static String lnRead(InputStream in) throws IOException {
StringBuilder builder = new StringBuilder();
int b;
char c;
while (true) {
b = in.read();
if (b == 13) {
//skip CR
continue;
}
if (b < 20 || b > 126) {
// exit on anything not legal
break;
}
c = (char) (b & 0x7f); // We only care about ASCII
builder.append(c);
}
return builder.toString();
}
/**
* Print an error message to out
*
* @param e
* @param out
* @throws java.io.IOException
*/
private void Emsg(String e, OutputStream out) throws IOException {
// Debugging System.out.println("ERROR TCPtoI2P: " + e);
out.write("ERROR ".concat(e).getBytes("UTF-8"));
out.write(13);
out.write(10);
out.flush();
}
/**
* TCP stream to I2P stream thread starter
*
*/
public void run() {
String line, input;
InputStream Iin = null;
OutputStream Iout = null;
InputStream in = null;
OutputStream out = null;
Thread t = null;
Thread q = null;
try {
try {
in = sock.getInputStream();
out = sock.getOutputStream();
line = lnRead(in);
input = line.toLowerCase(Locale.US);
Destination dest = null;
if (input.endsWith(".i2p")) {
//dest = I2PTunnel.destFromName(input);
dest = I2PAppContext.getGlobalContext().namingService().lookup(input);
if (dest != null) {
line = dest.toBase64();
} else {
Emsg("Can't find destination: " + input, out);
return;
}
}
dest = new Destination();
dest.fromBase64(line);
try {
// get a client socket
I2P = socketManager.connect(dest);
I2P.setReadTimeout(0); // temp bugfix, this *SHOULD* be the default
// make readers/writers
Iin = I2P.getInputStream();
Iout = I2P.getOutputStream();
// setup to cross the streams
TCPio conn_c = new TCPio(in, Iout, lives); // app -> I2P
TCPio conn_a = new TCPio(Iin, out, lives); // I2P -> app
t = new I2PAppThread(conn_c, Thread.currentThread().getName() + " TCPioA");
q = new I2PAppThread(conn_a, Thread.currentThread().getName() + " TCPioB");
// Fire!
t.start();
q.start();
while (t.isAlive() && q.isAlive() && lives.get()) { // AND is used here to kill off the other thread
Thread.sleep(10); //sleep for 10 ms
}
} catch (I2PException e) {
Emsg(e.toString(), out);
} catch (ConnectException e) {
Emsg(e.toString(), out);
} catch (NoRouteToHostException e) {
Emsg(e.toString(), out);
}
} catch (InterruptedIOException e) {
// We're breaking away.
} catch (InterruptedException e) {
// ditto
} catch (IOException e) {
try {
Emsg(e.toString(), out);
} catch (IOException ex) {
// ditto
}
} catch (DataFormatException e) {
try {
Emsg(e.toString(), out);
} catch (IOException ex) {
// ditto
}
}
} finally {
try {
t.interrupt();
} catch (Exception e) {
}
try {
q.interrupt();
} catch (Exception e) {
}
try {
in.close();
} catch (Exception e) {
}
try {
out.close();
} catch (Exception e) {
}
try {
Iin.close();
} catch (Exception e) {
}
try {
Iout.close();
} catch (Exception e) {
}
try {
// System.out.println("TCPtoI2P: Close I2P");
I2P.close();
} catch (Exception e) {
}
try {
// System.out.println("TCPtoI2P: Close sock");
sock.close();
} catch (Exception e) {
}
}
// System.out.println("TCPtoI2P: Done.");
}
}

View File

@ -0,0 +1,140 @@
/**
* WTFPL
* Version 2, December 2004
*
* Copyright (C) sponge
* Planet Earth
*
* See...
*
* http://sam.zoy.org/wtfpl/
* and
* http://en.wikipedia.org/wiki/WTFPL
*
* ...for any additional details and license questions.
*/
package net.i2p.BOB;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import net.i2p.client.I2PSession;
import net.i2p.client.I2PSessionException;
import net.i2p.client.I2PSessionListener;
import net.i2p.data.Destination;
import net.i2p.util.Log;
/**
* UDP IO on I2P
*
* FIX ME: Untested, and incomplete!
* I have no personal need to UDP yet,
* however alot of p2p apps pretty much demand it.
* The skeletal frame is here, just needs to be finished.
*
* @author sponge
* @deprecated incomplete, unused
*/
@Deprecated
public class UDPIOthread implements I2PSessionListener, Runnable {
private final NamedDB info;
private final Log _log;
private final Socket socket;
private DataInputStream in;
private DataOutputStream out;
private final I2PSession _session;
// FIXME never set
private Destination _peerDestination;
private boolean up;
/**
* Constructor
* @param info
* @param _log
* @param socket
* @param _session
*/
UDPIOthread(NamedDB info, Log _log, Socket socket, I2PSession _session) {
this.info = info;
this._log = _log;
this.socket = socket;
this._session = _session;
}
/**
*
*/
public void run() {
byte data[] = new byte[1024];
up = true;
try {
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
while (up) {
int c = in.read(data);
// Note: could do a loopback test here with a wrapper.
boolean ok = _session.sendMessage(_peerDestination, data, 0, c);
if (!ok) {
up = false; // Is this the right thing to do??
}
}
} catch (IOException ioe) {
_log.error("Error running", ioe);
} catch (I2PSessionException ise) {
_log.error("Error communicating", ise);
// } catch(DataFormatException dfe) {
// _log.error("Peer destination file is not valid", dfe);
} finally {
if (_session != null) {
try {
_session.destroySession();
} catch (I2PSessionException ise) {
// ignored
}
}
}
}
/**
*
* @param session
* @param msgId
* @param size
*/
public void messageAvailable(I2PSession session, int msgId, long size) {
// _log.debug("Message available: id = " + msgId + " size = " + size);
try {
byte msg[] = session.receiveMessage(msgId);
if (msg != null) {
out.write(msg);
out.flush();
}
} catch (I2PSessionException ise) {
up = false;
} catch (IOException ioe) {
up = false;
}
}
// Great, can these be used to kill ourselves.
/** required by {@link I2PSessionListener I2PSessionListener} to notify of disconnect */
public void disconnected(I2PSession session) {
_log.debug("Disconnected");
// up = false;
}
/** required by {@link I2PSessionListener I2PSessionListener} to notify of error */
public void errorOccurred(I2PSession session, String message, Throwable error) {
_log.debug("Error occurred: " + message, error);
// up = false;
}
/** required by {@link I2PSessionListener I2PSessionListener} to notify of abuse */
public void reportAbuse(I2PSession session, int severity) {
_log.debug("Abuse reported of severity " + severity);
// up = false;
}
}

View File

@ -0,0 +1,21 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) sponge
Planet Earth
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
See...
http://sam.zoy.org/wtfpl/
and
http://en.wikipedia.org/wiki/WTFPL
...for any additional details and license questions.

View File

@ -0,0 +1,5 @@
<html>
<body>
<p>BOB, the Basic Open Bridge, allows TCP applications to talk over I2P - DEPRECATED - Please port applications to SAMv3.</p>
</body>
</html>

View File

@ -9,7 +9,6 @@
<property name="javac.compilerargs" value="" />
<property name="javac.version" value="1.8" />
<property name="javac.release" value="8" />
<property name="manifest.classpath.name" value="Class-Path" />
<target name="all" depends="jar, emptyWar"/>
@ -58,14 +57,8 @@
<property name="workspace.changes.tr" value="" />
<jar basedir="${build}" destfile="${dist}/${jar}">
<manifest>
<attribute name="${manifest.classpath.name}" value="i2p.jar" />
<attribute name="Main-Class" value="net.i2p.addressbook.CommandLine"/>
<attribute name="Specification-Title" value="I2P Address Book" />
<attribute name="Specification-Version" value="${api.version}" />
<attribute name="Specification-Vendor" value="The I2P Project https://geti2p.net/" />
<attribute name="Implementation-Title" value="I2P Java Address Book" />
<attribute name="Main-Class" value="net.i2p.addressbook.Daemon"/>
<attribute name="Implementation-Version" value="${full.version}" />
<attribute name="Implementation-Vendor" value="The I2P Project https://geti2p.net/" />
<attribute name="Built-By" value="${build.built-by}" />
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
@ -84,36 +77,28 @@
</jar>
</target>
<!-- actually the jar -->
<target name="warUpToDate">
<uptodate property="war.uptodate" targetfile="${dist}/${jar}">
<srcfiles dir= "." includes="${build}/**/*.class"/>
<uptodate property="war.uptodate" targetfile="${dist}/${war}">
<srcfiles dir= "." includes="${build}/**/*.class, web.xml"/>
</uptodate>
<condition property="shouldListChanges" >
<and>
<not>
<isset property="war.uptodate" />
</not>
<isset property="git.available" />
<isset property="mtn.available" />
</and>
</condition>
</target>
<target name="changes" depends="warUpToDate" if="shouldListChanges" >
<exec executable="git" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" >
<arg value="status" />
<arg value="-s" />
<arg value="--porcelain" />
<arg value="-uno" />
<arg value="." />
</exec>
<!-- trim flags -->
<exec executable="sed" inputstring="${workspace.changes}" outputproperty="workspace.changes.sed" errorproperty="mtn.error2" failifexecutionfails="false" >
<arg value="-e" />
<arg value="s/^[MTADRCU ]*//" />
</exec>
<exec executable="mtn" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" >
<arg value="list" />
<arg value="changed" />
<arg value="." />
</exec>
<!-- \n in an attribute value generates an invalid manifest -->
<exec executable="tr" inputstring="${workspace.changes.sed}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" >
<exec executable="tr" inputstring="${workspace.changes}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" >
<arg value="-s" />
<arg value="[:space:]" />
<arg value="," />

View File

@ -1,42 +0,0 @@
package net.i2p.addressbook;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import net.i2p.CoreVersion;
/**
* Simple command line access to various utilities.
* Not a public API. Subject to change.
* Apps and plugins should use specific classes.
*
* @since 0.9.55
*/
public class CommandLine extends net.i2p.util.CommandLine {
protected static final List<String> ACLASSES = Arrays.asList(new String[] {
"net.i2p.addressbook.HostTxtParser",
"net.i2p.router.naming.BlockfileNamingService",
"net.metanotion.io.block.BlockFile",
});
protected CommandLine() {}
public static void main(String args[]) {
List<String> classes = new ArrayList<String>(ACLASSES.size() + CLASSES.size());
classes.addAll(ACLASSES);
classes.addAll(CLASSES);
if (args.length > 0) {
exec(args, classes);
}
usage(classes);
System.exit(1);
}
private static void usage(List<String> classes) {
System.err.println("I2P Address book version " + CoreVersion.VERSION + '\n' +
"USAGE: java -jar /path/to/addressbook.jar command [args]");
printCommands(classes);
}
}

View File

@ -697,7 +697,7 @@ class Daemon {
StringBuilder buf = new StringBuilder(16);
final int sz = dests.size();
for (int i = 0; i < sz; i++) {
buf.append(dests.get(i).toBase64(), 0, 6);
buf.append(dests.get(i).toBase64().substring(0, 6));
if (i != sz - 1)
buf.append(", ");
}

View File

@ -17,7 +17,6 @@ import java.util.Properties;
import net.i2p.client.naming.HostTxtEntry;
import net.i2p.data.DataHelper;
import net.i2p.data.Destination;
import net.i2p.util.SecureFile;
import net.i2p.util.SecureFileOutputStream;
import net.i2p.util.SystemVersion;
@ -26,9 +25,9 @@ import net.i2p.util.SystemVersion;
* Utility class providing methods to parse and write files in a hosts.txt file
* format, and subscription file format.
*
* @since 0.9.26 modified from ConfigParser, public since 0.9.55 for CLI
* @since 0.9.26 modified from ConfigParser
*/
public class HostTxtParser {
class HostTxtParser {
private static final boolean isWindows = SystemVersion.isWindows();
@ -256,23 +255,8 @@ public class HostTxtParser {
System.exit(2);
}
if (!e.hasValidSig()) {
if (!quiet) {
System.err.println("Bad signature for " + e.getName());
String dest = e.getDest();
try {
Destination d = new Destination(dest);
System.err.println(dest);
System.err.println(d.toString());
} catch (Exception ex) {
System.err.println("Invalid destination: " + dest);
}
Properties p = e.getProps();
if (p != null) {
for (Map.Entry<?,?> m : p.entrySet()) {
System.err.println(m.getKey() + "=" + m.getValue());
}
}
}
if (!quiet)
System.err.println("Bad signature");
System.exit(3);
}
Properties p = e.getProps();
@ -282,30 +266,14 @@ public class HostTxtParser {
p.containsKey(HostTxtEntry.PROP_OLDNAME) ||
p.containsKey(HostTxtEntry.PROP_OLDSIG)) {
if (!e.hasValidSig()) {
if (!quiet) {
System.err.println("Bad inner signature for " + e.getName());
for (Map.Entry<?,?> m : p.entrySet()) {
System.err.println(m.getKey() + "=" + m.getValue());
}
}
if (!quiet)
System.err.println("Bad inner signature");
System.exit(4);
}
}
}
if (!quiet) {
if (!quiet)
System.err.println("Good signature for " + e.getName());
try {
String dest = e.getDest();
Destination d = new Destination(dest);
System.err.println(dest);
System.err.println(d.toString());
} catch (Exception ex) {}
if (p != null) {
for (Map.Entry<?,?> m : p.entrySet()) {
System.err.println(m.getKey() + "=" + m.getValue());
}
}
}
System.exit(0);
}

View File

@ -64,24 +64,17 @@
</target>
<target name="listChangedFiles" depends="jarUpToDate" if="shouldListChanges" >
<exec executable="git" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" >
<arg value="status" />
<arg value="-s" />
<arg value="--porcelain" />
<arg value="-uno" />
<arg value="." />
</exec>
<!-- trim flags -->
<exec executable="sed" inputstring="${workspace.changes}" outputproperty="workspace.changes.sed" errorproperty="mtn.error2" failifexecutionfails="false" >
<arg value="-e" />
<arg value="s/^[MTADRCU ]*//" />
</exec>
<!-- \n in an attribute value generates an invalid manifest -->
<exec executable="tr" inputstring="${workspace.changes.sed}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" >
<arg value="-s" />
<arg value="[:space:]" />
<arg value="," />
</exec>
<exec executable="mtn" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" >
<arg value="list" />
<arg value="changed" />
<arg value="." />
</exec>
<!-- \n in an attribute value generates an invalid manifest -->
<exec executable="tr" inputstring="${workspace.changes}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" >
<arg value="-s" />
<arg value="[:space:]" />
<arg value="," />
</exec>
</target>
<target name="jar" depends="compile, bundle, listChangedFiles" unless="jar.uptodate" >
@ -115,7 +108,7 @@
<not>
<isset property="jar.uptodate" />
</not>
<isset property="git.available" />
<isset property="mtn.available" />
</and>
</condition>
</target>

View File

@ -4,15 +4,14 @@
# To contribute translations, see http://www.i2p2.de/newdevelopers
#
# Translators:
# slrslr, 2022
# slrslr, 2021
msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:05+0000\n"
"Last-Translator: slrslr, 2022\n"
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
"PO-Revision-Date: 2021-07-08 09:41+0000\n"
"Last-Translator: slrslr\n"
"Language-Team: Czech (http://www.transifex.com/otf/I2P/language/cs/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -27,81 +26,69 @@ msgstr "Spustit I2P"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
msgid "I2P is starting!"
msgstr "I2P startuje!"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
msgid "Starting"
msgstr "Startuji"
#: src/net/i2p/desktopgui/InternalTrayManager.java:65
#: src/net/i2p/desktopgui/InternalTrayManager.java:249
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
msgid "Launch I2P Browser"
msgstr "Spouštím I2P Browser"
#: src/net/i2p/desktopgui/InternalTrayManager.java:86
#: src/net/i2p/desktopgui/InternalTrayManager.java:270
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
msgid "Configure I2P System Tray"
msgstr "Nastavit I2P Systémovou Lištu"
#: src/net/i2p/desktopgui/InternalTrayManager.java:87
#: src/net/i2p/desktopgui/InternalTrayManager.java:271
msgid "Enable notifications"
msgstr "Zapnout upozornění"
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
msgid "Disable"
msgstr "Zakázat"
#: src/net/i2p/desktopgui/InternalTrayManager.java:101
#: src/net/i2p/desktopgui/InternalTrayManager.java:285
msgid "Disable notifications"
msgstr "Vypnout upozornění"
#: src/net/i2p/desktopgui/InternalTrayManager.java:115
#: src/net/i2p/desktopgui/InternalTrayManager.java:299
msgid "Disable system tray"
msgstr "Vypnout ikonu systémové lišty"
#: src/net/i2p/desktopgui/InternalTrayManager.java:131
#: src/net/i2p/desktopgui/InternalTrayManager.java:315
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
msgid "Restart I2P"
msgstr "Restart I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:148
#: src/net/i2p/desktopgui/InternalTrayManager.java:332
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
msgid "Stop I2P"
msgstr "Zastavit I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:164
#: src/net/i2p/desktopgui/InternalTrayManager.java:348
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
msgid "Restart I2P Immediately"
msgstr "Restartovat I2P Hned"
#: src/net/i2p/desktopgui/InternalTrayManager.java:181
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
msgid "Stop I2P Immediately"
msgstr "Zastavit I2P Hned"
#: src/net/i2p/desktopgui/InternalTrayManager.java:195
#: src/net/i2p/desktopgui/InternalTrayManager.java:379
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
msgid "Cancel I2P Shutdown"
msgstr "Zrušit I2P Zastavení"
#: src/net/i2p/desktopgui/InternalTrayManager.java:437
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
#, java-format
msgid "Shutdown in {0}"
msgstr "Zastavení za {0}"
#: src/net/i2p/desktopgui/InternalTrayManager.java:439
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
msgid "Shutdown imminent"
msgstr "Vypínání"
#. status translations are in the console bundle
#: src/net/i2p/desktopgui/InternalTrayManager.java:444
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
msgid "Network"
msgstr "Síť"
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
#: src/net/i2p/desktopgui/TrayManager.java:73
#: src/net/i2p/desktopgui/TrayManager.java:63
msgid "I2P: Right-click for menu"
msgstr "I2P: Pravé-kliknutí pro menu"

View File

@ -7,15 +7,14 @@
# blabla <blabla@trash-mail.com>, 2011
# Ettore Atalan <atalanttore@googlemail.com>, 2016
# foo <foo@bar>, 2009
# Georg Stadler, 2022
# Lars Schimmer <echelon@i2pmail.org>, 2016
msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:05+0000\n"
"Last-Translator: Georg Stadler, 2022\n"
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
"PO-Revision-Date: 2017-06-30 21:32+0000\n"
"Last-Translator: Lars Schimmer <echelon@i2pmail.org>\n"
"Language-Team: German (http://www.transifex.com/otf/I2P/language/de/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -30,81 +29,69 @@ msgstr "I2P starten"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
msgid "I2P is starting!"
msgstr "I2P startet gerade!"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
msgid "Starting"
msgstr "Startend"
#: src/net/i2p/desktopgui/InternalTrayManager.java:65
#: src/net/i2p/desktopgui/InternalTrayManager.java:249
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
msgid "Launch I2P Browser"
msgstr "I2P-Browser öffnen"
#: src/net/i2p/desktopgui/InternalTrayManager.java:86
#: src/net/i2p/desktopgui/InternalTrayManager.java:270
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
msgid "Configure I2P System Tray"
msgstr "I2P System Tray konfigurieren"
#: src/net/i2p/desktopgui/InternalTrayManager.java:87
#: src/net/i2p/desktopgui/InternalTrayManager.java:271
msgid "Enable notifications"
msgstr "Benachrichtigungen aktivieren"
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
msgid "Disable"
msgstr "Deaktivieren"
#: src/net/i2p/desktopgui/InternalTrayManager.java:101
#: src/net/i2p/desktopgui/InternalTrayManager.java:285
msgid "Disable notifications"
msgstr "Benachrichtigungen deaktivieren"
#: src/net/i2p/desktopgui/InternalTrayManager.java:115
#: src/net/i2p/desktopgui/InternalTrayManager.java:299
msgid "Disable system tray"
msgstr ""
#: src/net/i2p/desktopgui/InternalTrayManager.java:131
#: src/net/i2p/desktopgui/InternalTrayManager.java:315
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
msgid "Restart I2P"
msgstr "I2P neustarten"
#: src/net/i2p/desktopgui/InternalTrayManager.java:148
#: src/net/i2p/desktopgui/InternalTrayManager.java:332
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
msgid "Stop I2P"
msgstr "I2P beenden"
#: src/net/i2p/desktopgui/InternalTrayManager.java:164
#: src/net/i2p/desktopgui/InternalTrayManager.java:348
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
msgid "Restart I2P Immediately"
msgstr "I2P sofort neustarten"
#: src/net/i2p/desktopgui/InternalTrayManager.java:181
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
msgid "Stop I2P Immediately"
msgstr "I2P sofort beenden"
#: src/net/i2p/desktopgui/InternalTrayManager.java:195
#: src/net/i2p/desktopgui/InternalTrayManager.java:379
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
msgid "Cancel I2P Shutdown"
msgstr "Herunterfahren von I2P abbrechen"
#: src/net/i2p/desktopgui/InternalTrayManager.java:437
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
#, java-format
msgid "Shutdown in {0}"
msgstr "Herunterfahren in {0}"
#: src/net/i2p/desktopgui/InternalTrayManager.java:439
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
msgid "Shutdown imminent"
msgstr "Herunterfahren bevorstehend"
#. status translations are in the console bundle
#: src/net/i2p/desktopgui/InternalTrayManager.java:444
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
msgid "Network"
msgstr "Netzwerk"
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
#: src/net/i2p/desktopgui/TrayManager.java:73
#: src/net/i2p/desktopgui/TrayManager.java:63
msgid "I2P: Right-click for menu"
msgstr "I2P: Rechtsklick für Menü"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: I2P desktopgui\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-06 14:52+0000\n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2010-06-15 14:09+0100\n"
"Last-Translator: duck <duck@mail.i2p>\n"
"Language-Team: duck <duck@mail.i2p>\n"
@ -19,84 +19,87 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:31
#: src/net/i2p/desktopgui/ExternalTrayManager.java:59
msgid "Start I2P"
msgstr ""
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
msgid "I2P is starting!"
msgstr ""
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
msgid "Starting"
msgstr ""
#: src/net/i2p/desktopgui/InternalTrayManager.java:65
#: src/net/i2p/desktopgui/InternalTrayManager.java:221
#: src/net/i2p/desktopgui/InternalTrayManager.java:249
msgid "Launch I2P Browser"
msgstr ""
#: src/net/i2p/desktopgui/InternalTrayManager.java:86
#: src/net/i2p/desktopgui/InternalTrayManager.java:242
#: src/net/i2p/desktopgui/InternalTrayManager.java:270
msgid "Configure I2P System Tray"
msgstr ""
#: src/net/i2p/desktopgui/InternalTrayManager.java:88
#: src/net/i2p/desktopgui/InternalTrayManager.java:244
#: src/net/i2p/desktopgui/InternalTrayManager.java:87
#: src/net/i2p/desktopgui/InternalTrayManager.java:271
msgid "Enable notifications"
msgstr ""
#: src/net/i2p/desktopgui/InternalTrayManager.java:101
#: src/net/i2p/desktopgui/InternalTrayManager.java:285
msgid "Disable notifications"
msgstr ""
#: src/net/i2p/desktopgui/InternalTrayManager.java:115
#: src/net/i2p/desktopgui/InternalTrayManager.java:299
msgid "Disable system tray"
msgstr ""
#: src/net/i2p/desktopgui/InternalTrayManager.java:104
#: src/net/i2p/desktopgui/InternalTrayManager.java:260
#: src/net/i2p/desktopgui/InternalTrayManager.java:131
#: src/net/i2p/desktopgui/InternalTrayManager.java:315
msgid "Restart I2P"
msgstr ""
#: src/net/i2p/desktopgui/InternalTrayManager.java:121
#: src/net/i2p/desktopgui/InternalTrayManager.java:277
#: src/net/i2p/desktopgui/InternalTrayManager.java:148
#: src/net/i2p/desktopgui/InternalTrayManager.java:332
msgid "Stop I2P"
msgstr ""
#: src/net/i2p/desktopgui/InternalTrayManager.java:137
#: src/net/i2p/desktopgui/InternalTrayManager.java:293
#: src/net/i2p/desktopgui/InternalTrayManager.java:164
#: src/net/i2p/desktopgui/InternalTrayManager.java:348
msgid "Restart I2P Immediately"
msgstr ""
#: src/net/i2p/desktopgui/InternalTrayManager.java:154
#: src/net/i2p/desktopgui/InternalTrayManager.java:310
#: src/net/i2p/desktopgui/InternalTrayManager.java:181
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
msgid "Stop I2P Immediately"
msgstr ""
#: src/net/i2p/desktopgui/InternalTrayManager.java:168
#: src/net/i2p/desktopgui/InternalTrayManager.java:324
#: src/net/i2p/desktopgui/InternalTrayManager.java:195
#: src/net/i2p/desktopgui/InternalTrayManager.java:379
msgid "Cancel I2P Shutdown"
msgstr ""
#: src/net/i2p/desktopgui/InternalTrayManager.java:381
#: src/net/i2p/desktopgui/InternalTrayManager.java:437
#, java-format
msgid "Shutdown in {0}"
msgstr ""
#: src/net/i2p/desktopgui/InternalTrayManager.java:383
#: src/net/i2p/desktopgui/InternalTrayManager.java:439
msgid "Shutdown imminent"
msgstr ""
#. status translations are in the console bundle
#: src/net/i2p/desktopgui/InternalTrayManager.java:388
#: src/net/i2p/desktopgui/InternalTrayManager.java:444
msgid "Network"
msgstr ""
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
#: src/net/i2p/desktopgui/TrayManager.java:75
#: src/net/i2p/desktopgui/TrayManager.java:73
msgid "I2P: Right-click for menu"
msgstr ""
#: src/net/i2p/desktopgui/TrayManager.java:310
#: src/net/i2p/desktopgui/TrayManager.java:347
msgid "Enable notifications"
msgstr ""
#: src/net/i2p/desktopgui/TrayManager.java:325
#: src/net/i2p/desktopgui/TrayManager.java:362
msgid "Disable notifications"
msgstr ""

View File

@ -6,22 +6,21 @@
# Translators:
# ducki2p <ducki2p@gmail.com>, 2011
# foo <foo@bar>, 2009
# Juan Jaramillo <juanda097@protonmail.ch>, 2022
# punkibastardo <transifex.symons@slmail.me>, 2011
# punkibastardo <punkibastardo@gmail.com>, 2011
# strel, 2016
msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:05+0000\n"
"Last-Translator: Juan Jaramillo <juanda097@protonmail.ch>, 2022\n"
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
"PO-Revision-Date: 2017-06-30 21:32+0000\n"
"Last-Translator: strel\n"
"Language-Team: Spanish (http://www.transifex.com/otf/I2P/language/es/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: es\n"
"Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:31
#: src/net/i2p/desktopgui/ExternalTrayManager.java:59
@ -30,81 +29,69 @@ msgstr "Iniciar I2P"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
msgid "I2P is starting!"
msgstr "I2P está iniciando!"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
msgid "Starting"
msgstr "Iniciando"
#: src/net/i2p/desktopgui/InternalTrayManager.java:65
#: src/net/i2p/desktopgui/InternalTrayManager.java:249
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
msgid "Launch I2P Browser"
msgstr "Lanzar navegador I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:86
#: src/net/i2p/desktopgui/InternalTrayManager.java:270
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
msgid "Configure I2P System Tray"
msgstr "Configurar la bandeja de sistema de I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:87
#: src/net/i2p/desktopgui/InternalTrayManager.java:271
msgid "Enable notifications"
msgstr "Activar las notificaciones"
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
msgid "Disable"
msgstr "Deshabilitar"
#: src/net/i2p/desktopgui/InternalTrayManager.java:101
#: src/net/i2p/desktopgui/InternalTrayManager.java:285
msgid "Disable notifications"
msgstr "Desactivar las notificaciones"
#: src/net/i2p/desktopgui/InternalTrayManager.java:115
#: src/net/i2p/desktopgui/InternalTrayManager.java:299
msgid "Disable system tray"
msgstr "Desactivar la bandeja del sistema"
#: src/net/i2p/desktopgui/InternalTrayManager.java:131
#: src/net/i2p/desktopgui/InternalTrayManager.java:315
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
msgid "Restart I2P"
msgstr "Reiniciar I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:148
#: src/net/i2p/desktopgui/InternalTrayManager.java:332
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
msgid "Stop I2P"
msgstr "Detener I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:164
#: src/net/i2p/desktopgui/InternalTrayManager.java:348
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
msgid "Restart I2P Immediately"
msgstr "Reiniciar I2P inmediatamente"
#: src/net/i2p/desktopgui/InternalTrayManager.java:181
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
msgid "Stop I2P Immediately"
msgstr "Detener I2P inmediatamente"
#: src/net/i2p/desktopgui/InternalTrayManager.java:195
#: src/net/i2p/desktopgui/InternalTrayManager.java:379
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
msgid "Cancel I2P Shutdown"
msgstr "Cancelar el cierre de I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:437
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
#, java-format
msgid "Shutdown in {0}"
msgstr "Cierre en {0}"
#: src/net/i2p/desktopgui/InternalTrayManager.java:439
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
msgid "Shutdown imminent"
msgstr "Cierre inminente"
#. status translations are in the console bundle
#: src/net/i2p/desktopgui/InternalTrayManager.java:444
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
msgid "Network"
msgstr "Red"
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
#: src/net/i2p/desktopgui/TrayManager.java:73
#: src/net/i2p/desktopgui/TrayManager.java:63
msgid "I2P: Right-click for menu"
msgstr "I2P: Clic secundario para menú"

View File

@ -9,15 +9,15 @@ msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:05+0000\n"
"Last-Translator: kaze kaze <kaze@rlab.be>, 2017\n"
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
"PO-Revision-Date: 2017-11-16 15:29+0000\n"
"Last-Translator: kaze kaze <kaze@rlab.be>\n"
"Language-Team: Spanish (Argentina) (http://www.transifex.com/otf/I2P/language/es_AR/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: es_AR\n"
"Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:31
#: src/net/i2p/desktopgui/ExternalTrayManager.java:59
@ -26,81 +26,69 @@ msgstr "Iniciando I2P..."
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
msgid "I2P is starting!"
msgstr "I2P esta iniciando!"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
msgid "Starting"
msgstr "Iniciando"
#: src/net/i2p/desktopgui/InternalTrayManager.java:65
#: src/net/i2p/desktopgui/InternalTrayManager.java:249
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
msgid "Launch I2P Browser"
msgstr "Lanzar el Navegador I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:86
#: src/net/i2p/desktopgui/InternalTrayManager.java:270
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
msgid "Configure I2P System Tray"
msgstr "Configurar la Bandeja de Sistema de I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:87
#: src/net/i2p/desktopgui/InternalTrayManager.java:271
msgid "Enable notifications"
msgstr "Activar las notificaciones"
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
msgid "Disable"
msgstr "Deshabilitar"
#: src/net/i2p/desktopgui/InternalTrayManager.java:101
#: src/net/i2p/desktopgui/InternalTrayManager.java:285
msgid "Disable notifications"
msgstr "Desactivar las notificaciones"
#: src/net/i2p/desktopgui/InternalTrayManager.java:115
#: src/net/i2p/desktopgui/InternalTrayManager.java:299
msgid "Disable system tray"
msgstr "Desactivar la bandeja del sistema"
#: src/net/i2p/desktopgui/InternalTrayManager.java:131
#: src/net/i2p/desktopgui/InternalTrayManager.java:315
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
msgid "Restart I2P"
msgstr "Riniciar I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:148
#: src/net/i2p/desktopgui/InternalTrayManager.java:332
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
msgid "Stop I2P"
msgstr "Detener I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:164
#: src/net/i2p/desktopgui/InternalTrayManager.java:348
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
msgid "Restart I2P Immediately"
msgstr " Reiniciar I2P inmediatamente "
#: src/net/i2p/desktopgui/InternalTrayManager.java:181
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
msgid "Stop I2P Immediately"
msgstr " Detener I2P inmediatamente "
#: src/net/i2p/desktopgui/InternalTrayManager.java:195
#: src/net/i2p/desktopgui/InternalTrayManager.java:379
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
msgid "Cancel I2P Shutdown"
msgstr "Cancelar el Apagado de I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:437
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
#, java-format
msgid "Shutdown in {0}"
msgstr "Apagar en {0}"
#: src/net/i2p/desktopgui/InternalTrayManager.java:439
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
msgid "Shutdown imminent"
msgstr "Apagado inminente"
#. status translations are in the console bundle
#: src/net/i2p/desktopgui/InternalTrayManager.java:444
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
msgid "Network"
msgstr "Red"
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
#: src/net/i2p/desktopgui/TrayManager.java:73
#: src/net/i2p/desktopgui/TrayManager.java:63
msgid "I2P: Right-click for menu"
msgstr "I2P Clic derecho para el menú"

View File

@ -13,20 +13,19 @@
# AO <ao@localizationlab.org>, 2017
# Boxoa590, 2013
# Towinet, 2016
# vex vex, 2022
msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:05+0000\n"
"Last-Translator: vex vex, 2022\n"
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
"PO-Revision-Date: 2019-12-03 16:10+0000\n"
"Last-Translator: AO <ao@localizationlab.org>\n"
"Language-Team: French (http://www.transifex.com/otf/I2P/language/fr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: fr\n"
"Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:31
#: src/net/i2p/desktopgui/ExternalTrayManager.java:59
@ -35,81 +34,69 @@ msgstr "Démarrer I2P"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
msgid "I2P is starting!"
msgstr "I2P démarre!"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
msgid "Starting"
msgstr "Démarrage"
#: src/net/i2p/desktopgui/InternalTrayManager.java:65
#: src/net/i2p/desktopgui/InternalTrayManager.java:249
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
msgid "Launch I2P Browser"
msgstr "Lancer le navigateur dI2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:86
#: src/net/i2p/desktopgui/InternalTrayManager.java:270
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
msgid "Configure I2P System Tray"
msgstr "Configurer la zone de notification dI2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:87
#: src/net/i2p/desktopgui/InternalTrayManager.java:271
msgid "Enable notifications"
msgstr "Activer les notifications"
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
msgid "Disable"
msgstr "Désactiver"
#: src/net/i2p/desktopgui/InternalTrayManager.java:101
#: src/net/i2p/desktopgui/InternalTrayManager.java:285
msgid "Disable notifications"
msgstr "Désactiver les notifications"
#: src/net/i2p/desktopgui/InternalTrayManager.java:115
#: src/net/i2p/desktopgui/InternalTrayManager.java:299
msgid "Disable system tray"
msgstr "Désactiver la zone de notification"
#: src/net/i2p/desktopgui/InternalTrayManager.java:131
#: src/net/i2p/desktopgui/InternalTrayManager.java:315
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
msgid "Restart I2P"
msgstr "Redémarrer I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:148
#: src/net/i2p/desktopgui/InternalTrayManager.java:332
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
msgid "Stop I2P"
msgstr "Arrêter I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:164
#: src/net/i2p/desktopgui/InternalTrayManager.java:348
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
msgid "Restart I2P Immediately"
msgstr "Redémarrer I2P immédiatement"
#: src/net/i2p/desktopgui/InternalTrayManager.java:181
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
msgid "Stop I2P Immediately"
msgstr "Arrêter I2P immédiatement"
#: src/net/i2p/desktopgui/InternalTrayManager.java:195
#: src/net/i2p/desktopgui/InternalTrayManager.java:379
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
msgid "Cancel I2P Shutdown"
msgstr "Annuler la fermeture dI2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:437
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
#, java-format
msgid "Shutdown in {0}"
msgstr "Fermeture dans {0}"
#: src/net/i2p/desktopgui/InternalTrayManager.java:439
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
msgid "Shutdown imminent"
msgstr "La fermeture est imminente"
#. status translations are in the console bundle
#: src/net/i2p/desktopgui/InternalTrayManager.java:444
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
msgid "Network"
msgstr "Réseau"
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
#: src/net/i2p/desktopgui/TrayManager.java:73
#: src/net/i2p/desktopgui/TrayManager.java:63
msgid "I2P: Right-click for menu"
msgstr "I2P : clic droit pour obtenir le menu"

View File

@ -5,14 +5,13 @@
#
# Translators:
# Hunor Paksy <heds@cock.li>, 2018
# vargaviktor <viktor.varga@gmail.com>, 2022
msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:05+0000\n"
"Last-Translator: vargaviktor <viktor.varga@gmail.com>, 2022\n"
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
"PO-Revision-Date: 2021-06-20 09:44+0000\n"
"Last-Translator: AdminLMH <lehetmashogy@i2pmail.org>\n"
"Language-Team: Hungarian (http://www.transifex.com/otf/I2P/language/hu/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -27,81 +26,69 @@ msgstr "I2P indítása"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
msgid "I2P is starting!"
msgstr "I2P indul!"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
msgid "Starting"
msgstr "indítás"
#: src/net/i2p/desktopgui/InternalTrayManager.java:65
#: src/net/i2p/desktopgui/InternalTrayManager.java:249
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
msgid "Launch I2P Browser"
msgstr "I2P Böngésző Indítása"
#: src/net/i2p/desktopgui/InternalTrayManager.java:86
#: src/net/i2p/desktopgui/InternalTrayManager.java:270
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
msgid "Configure I2P System Tray"
msgstr "I2P rendszertálca beállítások"
#: src/net/i2p/desktopgui/InternalTrayManager.java:87
#: src/net/i2p/desktopgui/InternalTrayManager.java:271
msgid "Enable notifications"
msgstr "Értesítések engedélyezése"
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
msgid "Disable"
msgstr "Kikapcsol"
#: src/net/i2p/desktopgui/InternalTrayManager.java:101
#: src/net/i2p/desktopgui/InternalTrayManager.java:285
msgid "Disable notifications"
msgstr "Értesítések tiltása"
#: src/net/i2p/desktopgui/InternalTrayManager.java:115
#: src/net/i2p/desktopgui/InternalTrayManager.java:299
msgid "Disable system tray"
msgstr "Tálcaikon letiltása"
#: src/net/i2p/desktopgui/InternalTrayManager.java:131
#: src/net/i2p/desktopgui/InternalTrayManager.java:315
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
msgid "Restart I2P"
msgstr "I2P Újraindítása"
#: src/net/i2p/desktopgui/InternalTrayManager.java:148
#: src/net/i2p/desktopgui/InternalTrayManager.java:332
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
msgid "Stop I2P"
msgstr "I2P Leállítása"
#: src/net/i2p/desktopgui/InternalTrayManager.java:164
#: src/net/i2p/desktopgui/InternalTrayManager.java:348
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
msgid "Restart I2P Immediately"
msgstr "I2P Azonnali újraindítása"
#: src/net/i2p/desktopgui/InternalTrayManager.java:181
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
msgid "Stop I2P Immediately"
msgstr "I2P Azonnali megállítása"
#: src/net/i2p/desktopgui/InternalTrayManager.java:195
#: src/net/i2p/desktopgui/InternalTrayManager.java:379
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
msgid "Cancel I2P Shutdown"
msgstr "I2P leállításának visszavonása"
#: src/net/i2p/desktopgui/InternalTrayManager.java:437
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
#, java-format
msgid "Shutdown in {0}"
msgstr "Kikapcsolás: {0}"
#: src/net/i2p/desktopgui/InternalTrayManager.java:439
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
msgid "Shutdown imminent"
msgstr "Kikapcsolás hamarosan"
#. status translations are in the console bundle
#: src/net/i2p/desktopgui/InternalTrayManager.java:444
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
msgid "Network"
msgstr "Hálózat"
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
#: src/net/i2p/desktopgui/TrayManager.java:73
#: src/net/i2p/desktopgui/TrayManager.java:63
msgid "I2P: Right-click for menu"
msgstr "I2P: Jobb-klikk a menüért"

View File

@ -6,15 +6,14 @@
# Translators:
# PolishAnon <b790979@klzlk.com>, 2011
# polacco <polacco@i2pmail.org>, 2015
# Verdulo, 2016
# Waldemar Napora, 2022
# Verdulo :-), 2016
msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:05+0000\n"
"Last-Translator: Waldemar Napora, 2022\n"
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
"PO-Revision-Date: 2017-06-30 21:32+0000\n"
"Last-Translator: Verdulo :-)\n"
"Language-Team: Polish (http://www.transifex.com/otf/I2P/language/pl/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -29,81 +28,69 @@ msgstr "Uruchom I2P"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
msgid "I2P is starting!"
msgstr "Uruchamianie I2P!"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
msgid "Starting"
msgstr "Uruchamianie"
#: src/net/i2p/desktopgui/InternalTrayManager.java:65
#: src/net/i2p/desktopgui/InternalTrayManager.java:249
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
msgid "Launch I2P Browser"
msgstr "Uruchom przeglądarkę I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:86
#: src/net/i2p/desktopgui/InternalTrayManager.java:270
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
msgid "Configure I2P System Tray"
msgstr "Konfiguruj I2P w zasobniku systemowym"
#: src/net/i2p/desktopgui/InternalTrayManager.java:87
#: src/net/i2p/desktopgui/InternalTrayManager.java:271
msgid "Enable notifications"
msgstr "Włącz powiadomenia"
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
msgid "Disable"
msgstr "Wyłącz"
#: src/net/i2p/desktopgui/InternalTrayManager.java:101
#: src/net/i2p/desktopgui/InternalTrayManager.java:285
msgid "Disable notifications"
msgstr "Wyłącz powiadomienia"
#: src/net/i2p/desktopgui/InternalTrayManager.java:115
#: src/net/i2p/desktopgui/InternalTrayManager.java:299
msgid "Disable system tray"
msgstr "Wyłącz zasobnik systemowy"
#: src/net/i2p/desktopgui/InternalTrayManager.java:131
#: src/net/i2p/desktopgui/InternalTrayManager.java:315
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
msgid "Restart I2P"
msgstr "Zrestartuj I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:148
#: src/net/i2p/desktopgui/InternalTrayManager.java:332
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
msgid "Stop I2P"
msgstr "Zatrzymaj I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:164
#: src/net/i2p/desktopgui/InternalTrayManager.java:348
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
msgid "Restart I2P Immediately"
msgstr "Zrestartuj I2P natychmiast"
#: src/net/i2p/desktopgui/InternalTrayManager.java:181
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
msgid "Stop I2P Immediately"
msgstr "Wyłącz I2P natychmiast"
#: src/net/i2p/desktopgui/InternalTrayManager.java:195
#: src/net/i2p/desktopgui/InternalTrayManager.java:379
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
msgid "Cancel I2P Shutdown"
msgstr "Anuluj zamykanie I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:437
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
#, java-format
msgid "Shutdown in {0}"
msgstr "Wyłączenie za {0}"
#: src/net/i2p/desktopgui/InternalTrayManager.java:439
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
msgid "Shutdown imminent"
msgstr "Zaraz zamknę"
#. status translations are in the console bundle
#: src/net/i2p/desktopgui/InternalTrayManager.java:444
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
msgid "Network"
msgstr "Sieć"
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
#: src/net/i2p/desktopgui/TrayManager.java:73
#: src/net/i2p/desktopgui/TrayManager.java:63
msgid "I2P: Right-click for menu"
msgstr "I2P: kliknij prawym aby otworzyć menu"

View File

@ -4,22 +4,22 @@
# To contribute translations, see http://www.i2p2.de/newdevelopers
#
# Translators:
# Manuela Silva <mmsrs@sky.com>, 2016
# 1c13465e24d91aca4d3ddaa1bc3e7027_ae6ba28, 2013
# 1c13465e24d91aca4d3ddaa1bc3e7027_ae6ba28, 2012
# Manuela Silva <manuela.silva@sky.com>, 2016
# wicked, 2013
# wicked, 2012
msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:05+0000\n"
"Last-Translator: Manuela Silva <mmsrs@sky.com>, 2016\n"
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
"PO-Revision-Date: 2017-06-30 21:32+0000\n"
"Last-Translator: Manuela Silva <manuela.silva@sky.com>\n"
"Language-Team: Portuguese (http://www.transifex.com/otf/I2P/language/pt/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: pt\n"
"Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:31
#: src/net/i2p/desktopgui/ExternalTrayManager.java:59
@ -28,81 +28,69 @@ msgstr "Iniciar I2P"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
msgid "I2P is starting!"
msgstr "I2P está a iniciar!"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
msgid "Starting"
msgstr "A Iniciar"
#: src/net/i2p/desktopgui/InternalTrayManager.java:65
#: src/net/i2p/desktopgui/InternalTrayManager.java:249
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
msgid "Launch I2P Browser"
msgstr "Iniciar o browser I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:86
#: src/net/i2p/desktopgui/InternalTrayManager.java:270
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
msgid "Configure I2P System Tray"
msgstr "Configurar Bandeja do Sistema do I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:87
#: src/net/i2p/desktopgui/InternalTrayManager.java:271
msgid "Enable notifications"
msgstr "Ativar notificações"
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
msgid "Disable"
msgstr "Desativar"
#: src/net/i2p/desktopgui/InternalTrayManager.java:101
#: src/net/i2p/desktopgui/InternalTrayManager.java:285
msgid "Disable notifications"
msgstr "Desativar notificações"
#: src/net/i2p/desktopgui/InternalTrayManager.java:115
#: src/net/i2p/desktopgui/InternalTrayManager.java:299
msgid "Disable system tray"
msgstr ""
#: src/net/i2p/desktopgui/InternalTrayManager.java:131
#: src/net/i2p/desktopgui/InternalTrayManager.java:315
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
msgid "Restart I2P"
msgstr "Reiniciar o I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:148
#: src/net/i2p/desktopgui/InternalTrayManager.java:332
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
msgid "Stop I2P"
msgstr "Parar o I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:164
#: src/net/i2p/desktopgui/InternalTrayManager.java:348
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
msgid "Restart I2P Immediately"
msgstr "Reiniciar o I2P imediatamente"
#: src/net/i2p/desktopgui/InternalTrayManager.java:181
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
msgid "Stop I2P Immediately"
msgstr "Parar o I2P de imediatamente"
#: src/net/i2p/desktopgui/InternalTrayManager.java:195
#: src/net/i2p/desktopgui/InternalTrayManager.java:379
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
msgid "Cancel I2P Shutdown"
msgstr "Cancelar Encerramento do I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:437
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
#, java-format
msgid "Shutdown in {0}"
msgstr "Encerramento em {0}"
#: src/net/i2p/desktopgui/InternalTrayManager.java:439
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
msgid "Shutdown imminent"
msgstr "Encerramento eminente"
#. status translations are in the console bundle
#: src/net/i2p/desktopgui/InternalTrayManager.java:444
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
msgid "Network"
msgstr "Rede"
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
#: src/net/i2p/desktopgui/TrayManager.java:73
#: src/net/i2p/desktopgui/TrayManager.java:63
msgid "I2P: Right-click for menu"
msgstr "I2P: Clique direito para menu"

View File

@ -5,106 +5,93 @@
#
# Translators:
# testsubject67 <deborinha97@hotmail.com>, 2014
# Kyrie Eleis, 2022
# L., 2013
# L., 2015
# blueboy, 2013
# blueboy, 2015
# Rafael Ferrari, 2016
msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:05+0000\n"
"Last-Translator: Kyrie Eleis, 2022\n"
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
"PO-Revision-Date: 2017-06-30 21:32+0000\n"
"Last-Translator: Rafael Ferrari\n"
"Language-Team: Portuguese (Brazil) (http://www.transifex.com/otf/I2P/language/pt_BR/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: pt_BR\n"
"Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:31
#: src/net/i2p/desktopgui/ExternalTrayManager.java:59
msgid "Start I2P"
msgstr "Iniciar I2P"
msgstr "Conectar-se à I2P"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
msgid "I2P is starting!"
msgstr "Conectando-se a I2P!"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
msgid "Starting"
msgstr "Conectando"
#: src/net/i2p/desktopgui/InternalTrayManager.java:65
#: src/net/i2p/desktopgui/InternalTrayManager.java:249
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
msgid "Launch I2P Browser"
msgstr "Lançar o navegador I2P "
#: src/net/i2p/desktopgui/InternalTrayManager.java:86
#: src/net/i2p/desktopgui/InternalTrayManager.java:270
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
msgid "Configure I2P System Tray"
msgstr "Configurar o ícone de sistema I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:87
#: src/net/i2p/desktopgui/InternalTrayManager.java:271
msgid "Enable notifications"
msgstr "Ativar notificações"
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
msgid "Disable"
msgstr "Desabilitar"
#: src/net/i2p/desktopgui/InternalTrayManager.java:101
#: src/net/i2p/desktopgui/InternalTrayManager.java:285
msgid "Disable notifications"
msgstr "Desativar notificações"
#: src/net/i2p/desktopgui/InternalTrayManager.java:115
#: src/net/i2p/desktopgui/InternalTrayManager.java:299
msgid "Disable system tray"
msgstr ""
#: src/net/i2p/desktopgui/InternalTrayManager.java:131
#: src/net/i2p/desktopgui/InternalTrayManager.java:315
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
msgid "Restart I2P"
msgstr "Reinicializar o roteador I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:148
#: src/net/i2p/desktopgui/InternalTrayManager.java:332
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
msgid "Stop I2P"
msgstr "Interromper o roteador I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:164
#: src/net/i2p/desktopgui/InternalTrayManager.java:348
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
msgid "Restart I2P Immediately"
msgstr "Reinicializar o I2P Imediatamente"
#: src/net/i2p/desktopgui/InternalTrayManager.java:181
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
msgid "Stop I2P Immediately"
msgstr "Parar o I2P Imediatamente"
#: src/net/i2p/desktopgui/InternalTrayManager.java:195
#: src/net/i2p/desktopgui/InternalTrayManager.java:379
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
msgid "Cancel I2P Shutdown"
msgstr "Cancelar o desligamento do I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:437
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
#, java-format
msgid "Shutdown in {0}"
msgstr "Desligando em {0}"
#: src/net/i2p/desktopgui/InternalTrayManager.java:439
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
msgid "Shutdown imminent"
msgstr "Desligando agora"
#. status translations are in the console bundle
#: src/net/i2p/desktopgui/InternalTrayManager.java:444
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
msgid "Network"
msgstr "Rede"
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
#: src/net/i2p/desktopgui/TrayManager.java:73
#: src/net/i2p/desktopgui/TrayManager.java:63
msgid "I2P: Right-click for menu"
msgstr "I2P: Clique com o botão direito para o menu"

View File

@ -9,9 +9,9 @@ msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:05+0000\n"
"Last-Translator: 黃彥儒 <r1235613@gmail.com>, 2017\n"
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
"PO-Revision-Date: 2018-10-04 00:43+0000\n"
"Last-Translator: erinm\n"
"Language-Team: Chinese (Taiwan) (http://www.transifex.com/otf/I2P/language/zh_TW/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -26,81 +26,69 @@ msgstr "啟動I2P"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
msgid "I2P is starting!"
msgstr "I2P已啟動"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
msgid "Starting"
msgstr "啟動中"
#: src/net/i2p/desktopgui/InternalTrayManager.java:65
#: src/net/i2p/desktopgui/InternalTrayManager.java:249
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
msgid "Launch I2P Browser"
msgstr "開啟I2P瀏覽器"
#: src/net/i2p/desktopgui/InternalTrayManager.java:86
#: src/net/i2p/desktopgui/InternalTrayManager.java:270
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
msgid "Configure I2P System Tray"
msgstr "設定I2P系統文件夾"
#: src/net/i2p/desktopgui/InternalTrayManager.java:87
#: src/net/i2p/desktopgui/InternalTrayManager.java:271
msgid "Enable notifications"
msgstr "启用通知"
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
msgid "Disable"
msgstr "停用"
#: src/net/i2p/desktopgui/InternalTrayManager.java:101
#: src/net/i2p/desktopgui/InternalTrayManager.java:285
msgid "Disable notifications"
msgstr "禁用通知"
#: src/net/i2p/desktopgui/InternalTrayManager.java:115
#: src/net/i2p/desktopgui/InternalTrayManager.java:299
msgid "Disable system tray"
msgstr "禁用系统托盘"
#: src/net/i2p/desktopgui/InternalTrayManager.java:131
#: src/net/i2p/desktopgui/InternalTrayManager.java:315
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
msgid "Restart I2P"
msgstr "重啟I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:148
#: src/net/i2p/desktopgui/InternalTrayManager.java:332
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
msgid "Stop I2P"
msgstr "停止I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:164
#: src/net/i2p/desktopgui/InternalTrayManager.java:348
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
msgid "Restart I2P Immediately"
msgstr "強制重啟I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:181
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
msgid "Stop I2P Immediately"
msgstr "強制終止I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:195
#: src/net/i2p/desktopgui/InternalTrayManager.java:379
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
msgid "Cancel I2P Shutdown"
msgstr "取消停止I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:437
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
#, java-format
msgid "Shutdown in {0}"
msgstr "關閉於 {0}"
#: src/net/i2p/desktopgui/InternalTrayManager.java:439
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
msgid "Shutdown imminent"
msgstr "強制關閉"
#. status translations are in the console bundle
#: src/net/i2p/desktopgui/InternalTrayManager.java:444
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
msgid "Network"
msgstr "網路"
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
#: src/net/i2p/desktopgui/TrayManager.java:73
#: src/net/i2p/desktopgui/TrayManager.java:63
msgid "I2P: Right-click for menu"
msgstr "I2P右鍵開啟選單"

View File

@ -1,227 +0,0 @@
package net.i2p.desktopgui;
import java.awt.Image;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import javax.swing.SwingUtilities;
import net.i2p.I2PAppContext;
import net.i2p.app.ClientAppManager;
import net.i2p.app.ClientApp;
import net.i2p.app.ClientAppState;
import net.i2p.app.NotificationService;
import net.i2p.util.Log;
import net.i2p.util.SystemVersion;
/**
* A simplified Main that does not require router.jar, for App Context only.
* Invokes ExternalTrayManager only.
* No state tracking, ClientAppManager doesn't care.
*
* @since 0.9.54
*/
public class ExternalMain implements ClientApp, NotificationService {
private final I2PAppContext _appContext;
private final ClientAppManager _mgr;
private final Log log;
private TrayManager _trayManager;
private static final String PROP_SWING = "desktopgui.swing";
public ExternalMain(I2PAppContext ctx, ClientAppManager mgr, String args[]) {
_appContext = ctx;
_mgr = mgr;
log = _appContext.logManager().getLog(ExternalMain.class);
}
public ExternalMain() {
_appContext = I2PAppContext.getGlobalContext();
_mgr = _appContext.clientAppManager();
log = _appContext.logManager().getLog(ExternalMain.class);
}
public static void main(String[] args) {
// early check so we can bail out when started via CLI
if (!SystemTray.isSupported()) {
System.err.println("SystemTray not supported");
return;
}
ExternalMain main = new ExternalMain();
main.beginStartup(args);
}
/**
* Start the tray icon code (loads tray icon in the tray area).
* @throws AWTException on startup error, including systray not supported
*/
private synchronized void startUp() throws Exception {
final TrayManager trayManager;
boolean useSwingDefault = !(SystemVersion.isWindows() || SystemVersion.isMac());
boolean useSwing = _appContext.getProperty(PROP_SWING, useSwingDefault);
_trayManager = new ExternalTrayManager(_appContext, useSwing);
_trayManager.startManager();
if (_mgr != null)
_mgr.register(this);
}
/**
* Main method launching the application.
*
* @param args unused
*/
private void beginStartup(String[] args) {
String headless = System.getProperty("java.awt.headless");
boolean isHeadless = Boolean.parseBoolean(headless);
if (isHeadless) {
log.warn("Headless environment: not starting desktopgui!");
return;
}
if (SystemVersion.isMac())
setMacTrayIcon();
launchForeverLoop();
// We'll be doing GUI work, so let's stay in the event dispatcher thread.
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
startUp();
} catch(Exception e) {
log.error("Failed while running desktopgui!", e);
}
}
});
}
/**
* Unless we do this, when we start DesktopGUI we get a Java coffee cup
* in the tray.
*
* Based on code from https://gist.github.com/bchapuis/1562406 , no apparent license.
* See also https://stackoverflow.com/questions/6006173/how-do-you-change-the-dock-icon-of-a-java-program
*
* TODO, if we wanted to add our own menu, see
* https://stackoverflow.com/questions/1319805/java-os-x-dock-menu
*
* TODO, if we want to make it bounce, see
* https://stackoverflow.com/questions/15079783/how-to-make-my-app-icon-bounce-in-the-mac-dock
*
* TODO, if we want to handle Quit, see
* https://nakkaya.com/2009/04/19/java-osx-integration/
*
* @since 0.9.33
*/
@SuppressWarnings("unchecked")
private void setMacTrayIcon() {
File f = new File(_appContext.getBaseDir(), "docs/themes/console/images/itoopie_sm.png");
if (!f.exists())
return;
try {
Class util = Class.forName("com.apple.eawt.Application");
Method getApplication = util.getMethod("getApplication", new Class[0]);
Object application = getApplication.invoke(util);
Class params[] = new Class[1];
params[0] = Image.class;
Method setDockIconImage = util.getMethod("setDockIconImage", params);
URL url = f.toURI().toURL();
Image image = Toolkit.getDefaultToolkit().getImage(url);
setDockIconImage.invoke(application, image);
} catch (Exception e) {
if (log.shouldWarn())
log.warn("Can't set OSX Dock icon", e);
}
}
/**
* Avoids the app terminating because no Window is opened anymore.
* More info: http://java.sun.com/javase/6/docs/api/java/awt/doc-files/AWTThreadIssues.html#Autoshutdown
*/
private static void launchForeverLoop() {
Runnable r = new Runnable() {
public void run() {
try {
Object o = new Object();
synchronized (o) {
o.wait();
}
} catch (InterruptedException ie) {
}
}
};
Thread t = new Thread(r, "DesktopGUI spinner");
t.setDaemon(false);
t.start();
}
/////// NotificationService methods
/**
* Send a notification to the user.
*
* @param source unsupported
* @param category unsupported
* @param priority unsupported
* @param title for the popup, translated
* @param message translated
* @param path unsupported
* @return 0, or -1 on failure
*/
public int notify(String source, String category, int priority, String title, String message, String path) {
TrayManager tm = _trayManager;
if (tm == null)
return -1;
return tm.displayMessage(priority, title, message, path);
}
/**
* Cancel a notification if possible.
* Unsupported.
*
* @return false always
*/
public boolean cancel(int id) {
return false;
}
/**
* Update the text of a notification if possible.
* Unsupported.
*
* @return false always
*/
public boolean update(int id, String title, String message, String path) {
return false;
}
/////// ClientApp methods
public synchronized void startup() {
beginStartup(null);
}
public synchronized void shutdown(String[] args) {
if (_trayManager != null)
_trayManager.stopManager();
}
public ClientAppState getState() {
return ClientAppState.INITIALIZED;
}
public String getName() {
return "desktopgui";
}
public String getDisplayName() {
return "Desktop GUI";
}
/////// end ClientApp methods
}

View File

@ -22,8 +22,8 @@ import net.i2p.desktopgui.router.RouterManager;
*/
class ExternalTrayManager extends TrayManager {
public ExternalTrayManager(I2PAppContext ctx, boolean useSwing) {
super(ctx, useSwing);
public ExternalTrayManager(I2PAppContext ctx, Main main, boolean useSwing) {
super(ctx, main, useSwing);
}
public PopupMenu getMainMenu() {
@ -51,15 +51,11 @@ class ExternalTrayManager extends TrayManager {
}
});
popup.add(startItem);
initializeNotificationItems();
popup.add(_notificationItem2);
popup.add(_notificationItem1);
return popup;
}
public JPopupMenu getSwingMainMenu() {
JPopupMenu popup = new JPopupMenu();
/*
JMenuItem startItem = new JMenuItem(_t("Start I2P"));
startItem.addActionListener(new ActionListener() {
@Override
@ -83,10 +79,6 @@ class ExternalTrayManager extends TrayManager {
}
});
popup.add(startItem);
*/
initializeJNotificationItems();
popup.add(_jnotificationItem2);
popup.add(_jnotificationItem1);
return popup;
}
@ -94,14 +86,5 @@ class ExternalTrayManager extends TrayManager {
* Update the menu
* @since 0.9.26
*/
protected void updateMenu() {
if (_notificationItem1 != null)
_notificationItem1.setEnabled(_showNotifications);
if (_notificationItem2 != null)
_notificationItem2.setEnabled(!_showNotifications);
if (_jnotificationItem1 != null)
_jnotificationItem1.setVisible(_showNotifications);
if (_jnotificationItem2 != null)
_jnotificationItem2.setVisible(!_showNotifications);
}
protected void updateMenu() {}
}

View File

@ -30,20 +30,20 @@ class InternalTrayManager extends TrayManager {
private final RouterContext _context;
private final Log log;
private final Main _main;
private MenuItem _statusItem, _browserItem, _configItem, _restartItem, _stopItem,
_restartHardItem, _stopHardItem, _cancelItem;
_restartHardItem, _stopHardItem, _cancelItem,
_notificationItem1, _notificationItem2;
private JMenuItem _jstatusItem, _jbrowserItem, _jconfigItem, _jrestartItem, _jstopItem,
_jrestartHardItem, _jstopHardItem, _jcancelItem;
_jrestartHardItem, _jstopHardItem, _jcancelItem,
_jnotificationItem1, _jnotificationItem2;
private static final boolean CONSOLE_ENABLED = Desktop.isDesktopSupported() &&
Desktop.getDesktop().isSupported(Action.BROWSE);
private static final String CONSOLE_BUNDLE_NAME = "net.i2p.router.web.messages";
public InternalTrayManager(RouterContext ctx, Main main, boolean useSwing) {
super(ctx, useSwing);
super(ctx, main, useSwing);
_context = ctx;
_main = main;
log = ctx.logManager().getLog(InternalTrayManager.class);
}
@ -84,6 +84,33 @@ class InternalTrayManager extends TrayManager {
}
PopupMenu desktopguiConfigurationLauncher = new PopupMenu(_t("Configure I2P System Tray"));
final MenuItem notificationItem2 = new MenuItem(_t("Enable notifications"));
notificationItem2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
configureNotifications(true);
return null;
}
}.execute();
}
});
final MenuItem notificationItem1 = new MenuItem(_t("Disable notifications"));
notificationItem1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
configureNotifications(false);
return null;
}
}.execute();
}
});
MenuItem configSubmenu = new MenuItem(_t("Disable system tray"));
configSubmenu.addActionListener(new ActionListener() {
@ -185,9 +212,8 @@ class InternalTrayManager extends TrayManager {
popup.add(browserLauncher);
popup.addSeparator();
}
initializeNotificationItems();
desktopguiConfigurationLauncher.add(_notificationItem2);
desktopguiConfigurationLauncher.add(_notificationItem1);
desktopguiConfigurationLauncher.add(notificationItem2);
desktopguiConfigurationLauncher.add(notificationItem1);
desktopguiConfigurationLauncher.add(configSubmenu);
popup.add(desktopguiConfigurationLauncher);
popup.addSeparator();
@ -202,6 +228,8 @@ class InternalTrayManager extends TrayManager {
_statusItem = statusItem;
_browserItem = browserLauncher;
_configItem = desktopguiConfigurationLauncher;
_notificationItem1 = notificationItem1;
_notificationItem2 = notificationItem2;
_restartItem = restartItem;
_stopItem = stopItem;
_restartHardItem = restartItem2;
@ -240,6 +268,33 @@ class InternalTrayManager extends TrayManager {
}
JMenu desktopguiConfigurationLauncher = new JMenu(_t("Configure I2P System Tray"));
final JMenuItem notificationItem2 = new JMenuItem(_t("Enable notifications"));
notificationItem2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
configureNotifications(true);
return null;
}
}.execute();
}
});
final JMenuItem notificationItem1 = new JMenuItem(_t("Disable notifications"));
notificationItem1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
configureNotifications(false);
return null;
}
}.execute();
}
});
JMenuItem configSubmenu = new JMenuItem(_t("Disable system tray"));
configSubmenu.addActionListener(new ActionListener() {
@ -341,9 +396,8 @@ class InternalTrayManager extends TrayManager {
popup.add(browserLauncher);
popup.addSeparator();
}
initializeJNotificationItems();
desktopguiConfigurationLauncher.add(_jnotificationItem2);
desktopguiConfigurationLauncher.add(_jnotificationItem1);
desktopguiConfigurationLauncher.add(notificationItem2);
desktopguiConfigurationLauncher.add(notificationItem1);
desktopguiConfigurationLauncher.add(configSubmenu);
popup.add(desktopguiConfigurationLauncher);
popup.addSeparator();
@ -358,6 +412,8 @@ class InternalTrayManager extends TrayManager {
_jstatusItem = statusItem;
_jbrowserItem = browserLauncher;
_jconfigItem = desktopguiConfigurationLauncher;
_jnotificationItem1 = notificationItem1;
_jnotificationItem2 = notificationItem2;
_jrestartItem = restartItem;
_jstopItem = stopItem;
_jrestartHardItem = restartItem2;
@ -453,8 +509,7 @@ class InternalTrayManager extends TrayManager {
/**
* @since 0.9.53
*/
@Override
protected void configureNotifications(boolean enable) {
private void configureNotifications(boolean enable) {
_showNotifications = enable;
String value = Boolean.toString(enable);
if (!_context.router().saveConfig(PROP_NOTIFICATIONS, value))

View File

@ -57,7 +57,7 @@ public class Main implements RouterApp, NotificationService {
*/
public Main() {
_appContext = I2PAppContext.getGlobalContext();
if (_appContext.isRouterContext())
if (_appContext instanceof RouterContext)
_context = (RouterContext) _appContext;
else
_context = null;
@ -77,7 +77,7 @@ public class Main implements RouterApp, NotificationService {
if (_context != null)
trayManager = new InternalTrayManager(_context, this, useSwing);
else
trayManager = new ExternalTrayManager(_appContext, useSwing);
trayManager = new ExternalTrayManager(_appContext, this, useSwing);
trayManager.startManager();
_trayManager = trayManager;
changeState(RUNNING);

View File

@ -17,9 +17,7 @@ import java.awt.event.MouseListener;
import java.io.IOException;
import java.net.URL;
import java.awt.MenuItem;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.SwingWorker;
import javax.swing.event.MenuKeyEvent;
@ -39,14 +37,13 @@ import net.i2p.util.SystemVersion;
abstract class TrayManager {
protected final I2PAppContext _appContext;
protected final Main _main;
protected final boolean _useSwing;
///The tray area, or null if unsupported
protected SystemTray tray;
///Our tray icon, or null if unsupported
protected TrayIcon trayIcon;
protected volatile boolean _showNotifications;
protected MenuItem _notificationItem1, _notificationItem2;
protected JMenuItem _jnotificationItem1, _jnotificationItem2;
private static final String PNG_DIR = "/desktopgui/resources/images/";
private static final String MAC_ICON = "itoopie_black_24.png";
@ -58,8 +55,9 @@ abstract class TrayManager {
/**
* Instantiate tray manager.
*/
protected TrayManager(I2PAppContext ctx, boolean useSwing) {
protected TrayManager(I2PAppContext ctx, Main main, boolean useSwing) {
_appContext = ctx;
_main = main;
_useSwing = useSwing;
}
@ -292,89 +290,6 @@ abstract class TrayManager {
return 0;
}
/**
* Does not save. See InternalTrayManager.
*
* @since 0.9.58 moved up from InternalTrayManager
*/
protected void configureNotifications(boolean enable) {
_showNotifications = enable;
}
/**
* Initializes _notificationItem 1 and 2
*
* @since 0.9.58 pulled out of InternalTrayManager
*/
protected void initializeNotificationItems() {
final MenuItem notificationItem2 = new MenuItem(_t("Enable notifications"));
notificationItem2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
configureNotifications(true);
return null;
}
}.execute();
}
});
_notificationItem2 = notificationItem2;
final MenuItem notificationItem1 = new MenuItem(_t("Disable notifications"));
notificationItem1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
configureNotifications(false);
return null;
}
}.execute();
}
});
_notificationItem1 = notificationItem1;
}
/**
* Initializes _jnotificationItem 1 and 2
*
* @since 0.9.58 pulled out of InternalTrayManager
*/
protected void initializeJNotificationItems() {
final JMenuItem notificationItem2 = new JMenuItem(_t("Enable notifications"));
notificationItem2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
configureNotifications(true);
return null;
}
}.execute();
}
});
_jnotificationItem2 = notificationItem2;
final JMenuItem notificationItem1 = new JMenuItem(_t("Disable notifications"));
notificationItem1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
configureNotifications(false);
return null;
}
}.execute();
}
});
_jnotificationItem1 = notificationItem1;
}
protected String _t(String s) {
return DesktopguiTranslator._t(_appContext, s);
}

View File

@ -92,29 +92,7 @@
</javac>
</target>
<target name="listChangedFiles" if="git.available" >
<exec executable="git" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" >
<arg value="status" />
<arg value="-s" />
<arg value="--porcelain" />
<arg value="-uno" />
<arg value="." />
<arg value="../resources" />
</exec>
<!-- trim flags -->
<exec executable="sed" inputstring="${workspace.changes}" outputproperty="workspace.changes.sed" errorproperty="mtn.error2" failifexecutionfails="false" >
<arg value="-e" />
<arg value="s/^[MTADRCU ]*//" />
</exec>
<!-- \n in an attribute value generates an invalid manifest -->
<exec executable="tr" inputstring="${workspace.changes.sed}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" >
<arg value="-s" />
<arg value="[:space:]" />
<arg value="," />
</exec>
</target>
<target name="jar" depends="compile, listChangedFiles">
<target name="jar" depends="compile">
<!-- set if unset -->
<property name="workspace.changes.tr" value="" />
<jar destfile="build/i2pcontrol.jar" basedir="./build/obj" includes="**/*.class" >
@ -130,7 +108,7 @@
</jar>
</target>
<target name="socketJar" depends="compileSocketJar, listChangedFiles">
<target name="socketJar" depends="compileSocketJar">
<!-- set if unset -->
<property name="workspace.changes.tr" value="" />
<jar destfile="build/i2pcontrol.jar" basedir="./build/obj" includes="**/*.class" >
@ -146,7 +124,7 @@
</jar>
</target>
<target name="war" depends="compile, listChangedFiles" >
<target name="war" depends="compile" >
<!-- set if unset -->
<property name="workspace.changes.tr" value="" />
<war destfile="build/jsonrpc.war" webxml="web.xml" >

View File

@ -12,7 +12,7 @@ import net.i2p.I2PAppContext;
import net.i2p.data.DataHelper;
import net.i2p.util.Log;
import net.i2p.apache.http.conn.util.InetAddressUtils;
import org.apache.http.conn.util.InetAddressUtils;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.HandlerWrapper;

View File

@ -170,7 +170,7 @@ public class RouterInfoHandler implements RequestHandler {
&& (!_context.router().gracefulShutdownInProgress())
&& !_context.clientManager().isAlive())
return (NETWORK_STATUS.ERROR_I2CP);
long skew = _context.commSystem().getFramedAveragePeerClockSkew(10);
long skew = _context.commSystem().getFramedAveragePeerClockSkew(33);
// Display the actual skew, not the offset
if (Math.abs(skew) > 60 * 1000)
return NETWORK_STATUS.ERROR_CLOCK_SKEW;

View File

@ -4,11 +4,5 @@
#
# disable browser launch on startup
#routerconsole.browser=/bin/false
# disable browser launch on startup (Windows)
#routerconsole.browser=NUL
# change browser
#routerconsole.browser=firefox
# disable system tray
#desktopgui.enabled=false
# disable system tray notification popups
#desktopgui.showNotifications=false

View File

@ -21,8 +21,6 @@
<pathelement location="../../jetty/jettylib/javax.servlet.jar" />
<!-- jsp-api.jar only present for debian builds -->
<pathelement location="../../jetty/jettylib/jsp-api.jar" />
<!-- following jars only for standalone builds -->
<pathelement location="../../desktopgui/dist/desktopgui.jar" />
</classpath>
</depend>
</target>
@ -62,26 +60,18 @@
<pathelement location="../../systray/java/build/systray.jar" />
<pathelement location="../../jetty/jettylib/org.mortbay.jetty.jar" />
<pathelement location="../../jetty/jettylib/jetty-util.jar" />
<pathelement location="../../desktopgui/dist/desktopgui.jar" />
</classpath>
</javac>
</target>
<target name="listChangedFiles" depends="jarUpToDate" if="shouldListChanges" >
<exec executable="git" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" >
<arg value="status" />
<arg value="-s" />
<arg value="--porcelain" />
<arg value="-uno" />
<exec executable="mtn" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" >
<arg value="list" />
<arg value="changed" />
<arg value=".." />
</exec>
<!-- trim flags -->
<exec executable="sed" inputstring="${workspace.changes}" outputproperty="workspace.changes.sed" errorproperty="mtn.error2" failifexecutionfails="false" >
<arg value="-e" />
<arg value="s/^[MTADRCU ]*//" />
</exec>
<!-- \n in an attribute value generates an invalid manifest -->
<exec executable="tr" inputstring="${workspace.changes.sed}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" >
<exec executable="tr" inputstring="${workspace.changes}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" >
<arg value="-s" />
<arg value="[:space:]" />
<arg value="," />
@ -118,7 +108,7 @@
<not>
<isset property="war.uptodate" />
</not>
<isset property="git.available" />
<isset property="mtn.available" />
</and>
</condition>
</target>
@ -246,7 +236,6 @@
<zipfileset src="../../streaming/java/build/streaming.jar" />
<zipfileset src="../../systray/java/build/systray.jar" />
<zipfileset src="../../../build/jbigi.jar" />
<zipfileset src="../../desktopgui/dist/desktopgui.jar" />
<!-- Countries translations. The i2psnark translations are in the war but it's easier to put these here -->
<!-- 300KB just to translate "Brazil", but why not... -->
<!--
@ -305,12 +294,6 @@
value="url(/i2psnark/.resources/themes/ubergine/images/" >
<include name="**/*.css" />
</replace>
<replace dir="build/standalone-resources/.resources/themes"
summary="true"
token="url(/themes/console/images/buttons/"
value="url(/i2psnark/.resources/icons/" >
<include name="**/*.css" />
</replace>
<!-- Rather than pulling in all the console theme images, let's just specify the ones we need -->
<copy file="../../routerconsole/jsp/themes/console/images/transparent.gif"
@ -321,8 +304,6 @@
todir="build/standalone-resources/.resources/themes/light/images" />
<copy file="../../routerconsole/jsp/themes/console/images/info/errortriangle.png"
todir="build/standalone-resources/.resources/themes/ubergine/images" />
<copy file="../../routerconsole/jsp/themes/console/images/buttons/search.png"
todir="build/standalone-resources/.resources/icons" />
<mkdir dir="build/standalone-resources/.resources/js" />
<copy file="../../routerconsole/jsp/js/ajax.js" todir="build/standalone-resources/.resources/js" />

View File

@ -4,6 +4,8 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import net.i2p.CoreVersion;
/**
* Simple command line access to various utilities.
* Not a public API. Subject to change.
@ -36,7 +38,7 @@ public class CommandLine extends net.i2p.util.CommandLine {
}
private static void usage(List<String> classes) {
System.err.println("I2PSnark version " + SnarkManager.FULL_VERSION + '\n' +
System.err.println("I2PSnark version " + CoreVersion.VERSION + '\n' +
"USAGE: java -jar /path/to/i2psnark.jar command [args]");
printCommands(classes);
}

View File

@ -30,7 +30,6 @@ import net.i2p.I2PAppContext;
import net.i2p.I2PException;
import net.i2p.client.streaming.I2PServerSocket;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.client.streaming.RouterRestartException;
import net.i2p.data.Hash;
import net.i2p.util.I2PAppThread;
import net.i2p.util.Log;
@ -132,13 +131,12 @@ class ConnectionAcceptor implements Runnable
/**
* Effectively unused, would only be called if we changed
* I2CP host/port, which is hidden in the gui if in router context
* FIXME this only works if already running
*/
public synchronized void restart() {
Thread t = thread;
if (t != null)
t.interrupt();
else
startAccepting();
}
public int getPort()
@ -203,24 +201,6 @@ class ConnectionAcceptor implements Runnable
t.start();
}
}
catch (RouterRestartException rre) {
if (_log.shouldWarn())
_log.warn("Waiting for router restart", rre);
try {
Thread.sleep(2*60*1000);
} catch (InterruptedException ie) {}
while (true) {
if (_util.connected())
break;
if (_util.connect())
break;
try {
Thread.sleep(60*1000);
} catch (InterruptedException ie) { break; }
}
if (_log.shouldWarn())
_log.warn("Router restarted");
}
catch (I2PException ioe)
{
int level = stop ? Log.WARN : Log.ERROR;

View File

@ -1,15 +1,8 @@
package org.klomp.snark;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
@ -20,7 +13,6 @@ import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Pattern;
import net.i2p.I2PAppContext;
import net.i2p.I2PException;
@ -36,7 +28,6 @@ import net.i2p.client.streaming.I2PSocketManagerFactory;
import net.i2p.client.streaming.I2PSocketOptions;
import net.i2p.data.Base32;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.Destination;
import net.i2p.data.Hash;
import net.i2p.util.ConcurrentHashSet;
@ -45,9 +36,7 @@ import net.i2p.util.FileUtil;
import net.i2p.util.Log;
import net.i2p.util.SecureDirectory;
import net.i2p.util.SecureFile;
import net.i2p.util.SecureFileOutputStream;
import net.i2p.util.SimpleTimer;
import net.i2p.util.SystemVersion;
import net.i2p.util.Translate;
import org.klomp.snark.dht.DHT;
@ -88,7 +77,6 @@ public class I2PSnarkUtil implements DisconnectListener {
private DHT _dht;
private long _startedTime;
private final DisconnectListener _discon;
private int _maxFilesPerTorrent = SnarkManager.DEFAULT_MAX_FILES_PER_TORRENT;
private static final int EEPGET_CONNECT_TIMEOUT = 45*1000;
private static final int EEPGET_CONNECT_TIMEOUT_SHORT = 5*1000;
@ -114,7 +102,7 @@ public class I2PSnarkUtil implements DisconnectListener {
*/
public I2PSnarkUtil(I2PAppContext ctx, String baseName, DisconnectListener discon) {
_context = ctx;
_log = _context.logManager().getLog(I2PSnarkUtil.class);
_log = _context.logManager().getLog(Snark.class);
_baseName = baseName;
_discon = discon;
_opts = new HashMap<String, String>();
@ -254,11 +242,6 @@ public class I2PSnarkUtil implements DisconnectListener {
/** @since 0.9.1 */
public File getTempDir() { return _tmpDir; }
/** @since 0.9.58 */
public int getMaxFilesPerTorrent() { return _maxFilesPerTorrent; }
/** @since 0.9.58 */
public void setMaxFilesPerTorrent(int max) { _maxFilesPerTorrent = Math.max(max, 1); }
/**
* Connect to the router, if we aren't already
*/
@ -364,10 +347,6 @@ public class I2PSnarkUtil implements DisconnectListener {
synchronized(this) {
_manager = null;
_connecting = false;
if (_dht != null) {
_dht.stop();
_dht = null;
}
}
if (_discon != null)
_discon.sessionDisconnected();
@ -577,9 +556,6 @@ public class I2PSnarkUtil implements DisconnectListener {
return null;
}
/**
* Full Base64 of Destination
*/
public String getOurIPString() {
Destination dest = getMyDestination();
if (dest != null)
@ -846,90 +822,4 @@ public class I2PSnarkUtil implements DisconnectListener {
public String getString(int n, String s, String p) {
return Translate.getString(n, s, p, _context, BUNDLE_NAME);
}
private static final boolean SHOULD_SYNC = !(SystemVersion.isAndroid() || SystemVersion.isARM());
private static final Pattern ILLEGAL_KEY = Pattern.compile("[#=\\r\\n;]");
private static final Pattern ILLEGAL_VALUE = Pattern.compile("[\\r\\n]");
/**
* Same as DataHelper.loadProps() but allows '#' in values,
* so we can have filenames with '#' in them in torrent config files.
* '#' must be in column 1 for a comment.
*
* @since 0.9.58
*/
static void loadProps(Properties props, File f) throws IOException {
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(new FileInputStream(f), "UTF-8"), 1024);
String line = null;
while ( (line = in.readLine()) != null) {
if (line.trim().length() <= 0) continue;
if (line.charAt(0) == '#') continue;
if (line.charAt(0) == ';') continue;
int split = line.indexOf('=');
if (split <= 0) continue;
String key = line.substring(0, split);
String val = line.substring(split+1).trim();
props.setProperty(key, val);
}
} finally {
if (in != null) try { in.close(); } catch (IOException ioe) {}
}
}
/**
* Same as DataHelper.loadProps() but allows '#' in values,
* so we can have filenames with '#' in them in torrent config files.
* '#' must be in column 1 for a comment.
*
* @since 0.9.58
*/
static void storeProps(Properties props, File file) throws IOException {
FileOutputStream fos = null;
PrintWriter out = null;
IOException ioe = null;
File tmpFile = new File(file.getPath() + ".tmp");
try {
fos = new SecureFileOutputStream(tmpFile);
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(fos, "UTF-8")));
out.println("# NOTE: This I2P config file must use UTF-8 encoding");
out.println("# Last saved: " + DataHelper.formatTime(System.currentTimeMillis()));
for (Map.Entry<Object, Object> entry : props.entrySet()) {
String name = (String) entry.getKey();
String val = (String) entry.getValue();
if (ILLEGAL_KEY.matcher(name).find()) {
if (ioe == null)
ioe = new IOException("Invalid character (one of \"#;=\\r\\n\") in key: \"" +
name + "\" = \"" + val + '\"');
continue;
}
if (ILLEGAL_VALUE.matcher(val).find()) {
if (ioe == null)
ioe = new IOException("Invalid character (one of \"\\r\\n\") in value: \"" +
name + "\" = \"" + val + '\"');
continue;
}
out.println(name + "=" + val);
}
if (SHOULD_SYNC) {
out.flush();
fos.getFD().sync();
}
out.close();
if (out.checkError()) {
out = null;
tmpFile.delete();
throw new IOException("Failed to write properties to " + tmpFile);
}
out = null;
if (!FileUtil.rename(tmpFile, file))
throw new IOException("Failed rename from " + tmpFile + " to " + file);
} finally {
if (out != null) out.close();
if (fos != null) try { fos.close(); } catch (IOException e) {}
}
if (ioe != null)
throw ioe;
}
}

View File

@ -720,9 +720,8 @@ public class MetaInfo
if (infoMap != null)
return Collections.unmodifiableMap(infoMap);
// we should only get here if serving a magnet on a torrent we created
// or on edit torrent save
if (_log.shouldDebug())
_log.debug("Creating new infomap", new Exception());
if (_log.shouldLog(Log.WARN))
_log.warn("Creating new infomap", new Exception());
// otherwise we must create it
Map<String, BEValue> info = new HashMap<String, BEValue>();
info.put("name", new BEValue(DataHelper.getUTF8(name)));

View File

@ -279,6 +279,7 @@ class PeerCoordinator implements PeerListener
/**
* Bytes not yet in storage. Does NOT account for skipped files.
* Not exact (does not adjust for last piece size).
* Returns how many bytes are still needed to get the complete torrent.
* @return -1 if in magnet mode
*/
@ -286,13 +287,8 @@ class PeerCoordinator implements PeerListener
{
if (metainfo == null | storage == null)
return -1;
int psz = metainfo.getPieceLength(0);
long rv = ((long) storage.needed()) * psz;
int last = metainfo.getPieces() - 1;
BitField bf = storage.getBitField();
if (bf != null && !bf.get(last))
rv -= psz - metainfo.getPieceLength(last);
return rv;
// XXX - Only an approximation.
return ((long) storage.needed()) * metainfo.getPieceLength(0);
}
/**

View File

@ -1259,8 +1259,6 @@ public class Snark
*/
private void fatalRouter(String s, Throwable t) throws RouterException {
_log.error(s, t);
if (!_util.getContext().isRouterContext())
System.out.println(s);
stopTorrent(true);
if (completeListener != null)
completeListener.fatal(this, s);
@ -1335,9 +1333,6 @@ public class Snark
*/
public void replaceMetaInfo(MetaInfo metainfo) {
meta = metainfo;
TrackerClient tc = trackerclient;
if (tc != null)
tc.reinitialize();
}
///////////// Begin StorageListener methods

View File

@ -25,12 +25,10 @@ import java.util.Set;
import java.util.StringTokenizer;
import java.util.concurrent.ConcurrentHashMap;
import net.i2p.CoreVersion;
import net.i2p.I2PAppContext;
import net.i2p.app.ClientApp;
import net.i2p.app.ClientAppManager;
import net.i2p.app.ClientAppState;
import net.i2p.app.NavService;
import net.i2p.app.NotificationService;
import net.i2p.client.I2PClient;
import net.i2p.client.streaming.I2PSocketManager.DisconnectListener;
@ -87,8 +85,8 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
private final Log _log;
private final UIMessages _messages;
private final I2PSnarkUtil _util;
private final PeerCoordinatorSet _peerCoordinatorSet;
private final ConnectionAcceptor _connectionAcceptor;
private PeerCoordinatorSet _peerCoordinatorSet;
private ConnectionAcceptor _connectionAcceptor;
private Thread _monitor;
private volatile boolean _running;
private volatile boolean _stopping;
@ -129,7 +127,7 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
private static final String PROP_META_ACTIVITY = "activity";
private static final String CONFIG_FILE_SUFFIX = ".config";
public static final String CONFIG_FILE = "i2psnark" + CONFIG_FILE_SUFFIX;
private static final String CONFIG_FILE = "i2psnark" + CONFIG_FILE_SUFFIX;
private static final String COMMENT_FILE_SUFFIX = ".comments.txt.gz";
public static final String PROP_FILES_PUBLIC = "i2psnark.filesPublic";
public static final String PROP_OLD_AUTO_START = "i2snark.autoStart"; // oops
@ -164,8 +162,6 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
private static final String PROP_COMMENTS = "i2psnark.comments";
/** @since 0.9.31 */
private static final String PROP_COMMENTS_NAME = "i2psnark.commentsName";
/** @since 0.9.58 */
public static final String PROP_MAX_FILES_PER_TORRENT = "i2psnark.maxFilesPerTorrent";
public static final int MIN_UP_BW = 10;
public static final int DEFAULT_MAX_UP_BW = 25;
@ -173,14 +169,10 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
public static final int DEFAULT_REFRESH_DELAY_SECS = 15;
private static final int DEFAULT_PAGE_SIZE = 50;
public static final int DEFAULT_TUNNEL_QUANTITY = 3;
public static final int DEFAULT_MAX_FILES_PER_TORRENT = 2000;
public static final String CONFIG_DIR_SUFFIX = ".d";
private static final String SUBDIR_PREFIX = "s";
private static final String B64 = Base64.ALPHABET_I2P;
private static final int MAX_MESSAGES = 100;
private static final String EXTRA = "";
/** @since 0.9.58 */
public static final String FULL_VERSION = CoreVersion.VERSION + EXTRA;
/**
* "name", "announceURL=websiteURL" pairs
@ -279,8 +271,6 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
_log = _context.logManager().getLog(SnarkManager.class);
_messages = new UIMessages(MAX_MESSAGES);
_util = new I2PSnarkUtil(_context, ctxName, this);
_peerCoordinatorSet = new PeerCoordinatorSet();
_connectionAcceptor = new ConnectionAcceptor(_util, _peerCoordinatorSet);
DEFAULT_AUTO_START = !ctx.isRouterContext();
String cfile = ctxName + CONFIG_FILE_SUFFIX;
File configFile = new File(cfile);
@ -299,22 +289,15 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
*/
public void start() {
_running = true;
ClientAppManager cmgr = _context.clientAppManager();
if ("i2psnark".equals(_contextName)) {
// Register with the ClientAppManager so the rpc plugin can find us
// only if default instance
ClientAppManager cmgr = _context.clientAppManager();
if (cmgr != null)
cmgr.register(this);
} else {
// Register link with NavHelper
if (cmgr != null) {
NavService nav = (NavService) cmgr.getRegisteredApp("NavHelper");
if (nav != null) {
String name = DataHelper.stripHTML(_contextPath.substring(1));
nav.registerApp(name, name, _contextPath, null, "/themes/console/images/i2psnark.png");
}
}
}
_peerCoordinatorSet = new PeerCoordinatorSet();
_connectionAcceptor = new ConnectionAcceptor(_util, _peerCoordinatorSet);
_monitor = new I2PAppThread(new DirMonitor(), "Snark DirMonitor", true);
_monitor.start();
// only if default instance
@ -394,20 +377,11 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
_connectionAcceptor.halt();
_idleChecker.cancel();
stopAllTorrents(true);
ClientAppManager cmgr = _context.clientAppManager();
if ("i2psnark".equals(_contextName)) {
// only if default instance
ClientAppManager cmgr = _context.clientAppManager();
if (cmgr != null)
cmgr.unregister(this);
} else {
// Unregister link with NavHelper
if (cmgr != null) {
NavService nav = (NavService) cmgr.getRegisteredApp("NavHelper");
if (nav != null) {
String name = DataHelper.stripHTML(_contextPath.substring(1));
nav.unregisterApp(name);
}
}
}
if (_log.shouldWarn())
_log.warn("Snark stop() end");
@ -727,7 +701,7 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
File conf = configFile(_configDir, ih);
synchronized(_configLock) { // one lock for all
try {
I2PSnarkUtil.loadProps(rv, conf);
DataHelper.loadProps(rv, conf);
} catch (IOException ioe) {}
}
return rv;
@ -1003,7 +977,6 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
// _util.setProxy(eepHost, eepPort);
_util.setMaxUploaders(getInt(PROP_UPLOADERS_TOTAL, Snark.MAX_TOTAL_UPLOADERS));
_util.setMaxUpBW(getInt(PROP_UPBW_MAX, DEFAULT_MAX_UP_BW));
_util.setMaxFilesPerTorrent(getInt(PROP_MAX_FILES_PER_TORRENT, DEFAULT_MAX_FILES_PER_TORRENT));
_util.setStartupDelay(getInt(PROP_STARTUP_DELAY, DEFAULT_STARTUP_DELAY));
_util.setFilesPublic(areFilesPublic());
_util.setOpenTrackers(getListConfig(PROP_OPENTRACKERS, DEFAULT_OPENTRACKERS));
@ -1483,6 +1456,9 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
}
}
/** hardcoded for sanity. perhaps this should be customizable, for people who increase their ulimit, etc. */
public static final int MAX_FILES_PER_TORRENT = 2000;
/**
* Set of canonical .torrent filenames that we are dealing with.
* An unsynchronized copy.
@ -1742,31 +1718,21 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
String link = linkify(torrent);
if (!dontAutoStart && shouldAutoStart() && running) {
if (!_util.connected()) {
String msg = _t("Connecting to I2P");
addMessage(msg);
if (!_context.isRouterContext())
System.out.println(msg);
addMessage(_t("Connecting to I2P"));
boolean ok = _util.connect();
if (!ok) {
if (_context.isRouterContext()) {
if (_context.isRouterContext())
addMessage(_t("Unable to connect to I2P"));
} else {
msg = _t("Error connecting to I2P - check your I2CP settings!") + ' ' + _util.getI2CPHost() + ':' + _util.getI2CPPort();
addMessage(msg);
System.out.println(msg);
}
else
addMessage(_t("Error connecting to I2P - check your I2CP settings!") + ' ' + _util.getI2CPHost() + ':' + _util.getI2CPPort());
// this would rename the torrent to .BAD
//return false;
}
}
torrent.startTorrent();
addMessageNoEscape(_t("Torrent added and started: {0}", link));
if (!_context.isRouterContext())
System.out.println(_t("Torrent added and started: {0}", torrent.getBaseName()));
} else {
addMessageNoEscape(_t("Torrent added: {0}", link));
if (!_context.isRouterContext())
System.out.println(_t("Torrent added: {0}", torrent.getBaseName()));
}
return true;
}
@ -2309,7 +2275,7 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
if (!subdir.exists())
subdir.mkdirs();
try {
I2PSnarkUtil.storeProps(config, conf);
DataHelper.storeProps(config, conf);
if (_log.shouldInfo())
_log.info("Saved config to " + conf /* , new Exception() */ );
} catch (IOException ioe) {
@ -2451,11 +2417,8 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
*/
private String validateTorrent(MetaInfo info) {
List<List<String>> files = info.getFiles();
if (files != null && files.size() > _util.getMaxFilesPerTorrent()) {
return _t("Too many files in \"{0}\" ({1})!", info.getName(), files.size()) +
" - limit is " + _util.getMaxFilesPerTorrent() + ", zip them or set " +
PROP_MAX_FILES_PER_TORRENT + '=' + files.size() + " in " +
_configFile.getAbsolutePath() + " and restart";
if ( (files != null) && (files.size() > MAX_FILES_PER_TORRENT) ) {
return _t("Too many files in \"{0}\" ({1})!", info.getName(), files.size());
} else if ( (files == null) && (info.getName().endsWith(".torrent")) ) {
return _t("Torrent file \"{0}\" cannot end in \".torrent\"!", info.getName());
} else if (info.getPieces() <= 0) {
@ -2591,9 +2554,6 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
// Test if the router is there
// For standalone, this will probe the router every 60 seconds if not connected
boolean oldOK = routerOK;
// standalone, first time only
if (doMagnets && !_context.isRouterContext())
dtgNotify(Log.INFO, _t("Connecting to I2P") + ' ' + _util.getI2CPHost() + ':' + _util.getI2CPPort());
routerOK = getBWLimit();
if (routerOK) {
autostart = shouldAutoStart();
@ -2604,29 +2564,17 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
String prop = config.getProperty(PROP_META_RUNNING);
if (prop == null || Boolean.parseBoolean(prop)) {
if (!_util.connected()) {
String msg = _t("Connecting to I2P");
addMessage(msg);
if (!_context.isRouterContext())
dtgNotify(Log.INFO, msg + ' ' + _util.getI2CPHost() + ':' + _util.getI2CPPort());
addMessage(_t("Connecting to I2P"));
// getBWLimit() was successful so this should work
boolean ok = _util.connect();
if (!ok) {
if (_context.isRouterContext()) {
if (_context.isRouterContext())
addMessage(_t("Unable to connect to I2P"));
} else {
msg = _t("Error connecting to I2P - check your I2CP settings!") + ' ' + _util.getI2CPHost() + ':' + _util.getI2CPPort();
addMessage(msg);
dtgNotify(Log.ERROR, msg);
}
else
addMessage(_t("Error connecting to I2P - check your I2CP settings!") + ' ' + _util.getI2CPHost() + ':' + _util.getI2CPPort());
routerOK = false;
autostart = false;
break;
} else {
if (!_context.isRouterContext()) {
msg = "Connected to I2P at " + ' ' + _util.getI2CPHost() + ':' + _util.getI2CPPort();
addMessage(msg);
dtgNotify(Log.INFO, msg);
}
}
}
addMessageNoEscape(_t("Starting up torrent {0}", linkify(snark)));
@ -2675,13 +2623,10 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
if (ok)
cleanupTorrentStatus();
if (!routerOK) {
if (_context.isRouterContext()) {
if (_context.isRouterContext())
addMessage(_t("Unable to connect to I2P"));
} else {
String msg = _t("Error connecting to I2P - check your I2CP settings!") + ' ' + _util.getI2CPHost() + ':' + _util.getI2CPPort();
addMessage(msg);
dtgNotify(Log.ERROR, msg);
}
else
addMessage(_t("Error connecting to I2P - check your I2CP settings!") + ' ' + _util.getI2CPHost() + ':' + _util.getI2CPPort());
}
}
try { Thread.sleep(60*1000); } catch (InterruptedException ie) {}
@ -2701,9 +2646,15 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
return;
if (snark.getDownloaded() > 0) {
addMessageNoEscape(_t("Download finished: {0}", linkify(snark)));
dtgNotify(Log.INFO,
_t("Download finished: {0}", snark.getName()),
"/i2psnark/" + linkify(snark));
ClientAppManager cmgr = _context.clientAppManager();
if (cmgr != null) {
NotificationService ns = (NotificationService) cmgr.getRegisteredApp("desktopgui");
if (ns != null) {
ns.notify("I2PSnark", null, Log.INFO, _t("I2PSnark"),
_t("Download finished: {0}", snark.getName()),
"/i2psnark/" + linkify(snark));
}
}
}
updateStatus(snark);
}
@ -2794,38 +2745,6 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
// End Snark.CompleteListeners
/**
* Send a notification to the user via desktopgui and,
* if standalone, on the console.
*
* @param priority log level
* @param message translated
* @since 0.9.54
*/
private void dtgNotify(int priority, String message) {
dtgNotify(priority, message, null);
}
/**
* Send a notification to the user via desktopgui and,
* if standalone, on the console.
*
* @param priority log level
* @param message translated
* @param path in console for more information, starting with /, must be URL-escaped, or null
* @since 0.9.54
*/
private void dtgNotify(int priority, String message, String path) {
ClientAppManager cmgr = _context.clientAppManager();
if (cmgr != null) {
NotificationService ns = (NotificationService) cmgr.getRegisteredApp("desktopgui");
if (ns != null)
ns.notify("I2PSnark", null, priority, _t("I2PSnark"), message, path);
}
if (!_context.isRouterContext())
System.out.println(message);
}
/**
* An HTML link to the file if complete and a single file,
* to the directory if not complete or not a single file,
@ -2907,7 +2826,6 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
//if (_log.shouldLog(Log.DEBUG))
// _log.debug("DirMon found: " + DataHelper.toString(foundNames) + " existing: " + DataHelper.toString(existingNames));
// lets find new ones first...
int count = 0;
for (String name : foundNames) {
if (existingNames.contains(name)) {
// already known. noop
@ -2935,10 +2853,6 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
disableTorrentFile(name);
rv = false;
}
if (shouldStart && (count++ & 0x0f) == 15) {
// try to prevent OOMs at startup
try { Thread.sleep(250); } catch (InterruptedException ie) {}
}
}
}
// Don't remove magnet torrents that don't have a torrent file yet
@ -3118,19 +3032,21 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
}
/**
* Always thread it
* If not connected, thread it, otherwise inline
* @since 0.9.1
*/
public void startAllTorrents() {
if (!_util.connected()) {
if (_util.connected()) {
startAll();
} else {
addMessage(_t("Opening the I2P tunnel and starting all torrents."));
for (Snark snark : _snarks.values()) {
// mark it for the UI
snark.setStarting();
}
(new I2PAppThread(new ThreadedStarter(null), "TorrentStarterAll", true)).start();
try { Thread.sleep(200); } catch (InterruptedException ie) {}
}
(new I2PAppThread(new ThreadedStarter(null), "TorrentStarterAll", true)).start();
try { Thread.sleep(200); } catch (InterruptedException ie) {}
}
/**
@ -3160,7 +3076,6 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
* @since 0.9.1
*/
private void startAll() {
int count = 0;
for (Snark snark : _snarks.values()) {
if (snark.isStopped()) {
try {
@ -3168,10 +3083,6 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
} catch (RuntimeException re) {
// Snark.fatal() will log and call fatal() here for user message before throwing
}
if ((count++ & 0x0f) == 15) {
// try to prevent OOMs
try { Thread.sleep(250); } catch (InterruptedException ie) {}
}
}
}
}

View File

@ -87,7 +87,7 @@ public class Storage implements Closeable
/** bigger than this will be rejected */
public static final int MAX_PIECE_SIZE = 32*1024*1024;
/** The maximum number of pieces in a torrent. */
public static final int MAX_PIECES = 64*1024;
public static final int MAX_PIECES = 32*1024;
public static final long MAX_TOTAL_SIZE = MAX_PIECE_SIZE * (long) MAX_PIECES;
public static final int PRIORITY_SKIP = -9;
public static final int PRIORITY_NORMAL = 0;
@ -288,13 +288,9 @@ public class Storage implements Closeable
* @throws IOException if too many total files
*/
private void addFiles(List<File> l, File f) throws IOException {
int max = _util.getMaxFilesPerTorrent();
if (!f.isDirectory()) {
if (l.size() >= max)
throw new IOException(_util.getString("Too many files in \"{0}\" ({1})!", metainfo.getName(), l.size()) +
" - limit is " + max + ", zip them or set " +
SnarkManager.PROP_MAX_FILES_PER_TORRENT + '=' + l.size() + " in " +
SnarkManager.CONFIG_FILE + " and restart");
if (l.size() >= SnarkManager.MAX_FILES_PER_TORRENT)
throw new IOException("Too many files, limit is " + SnarkManager.MAX_FILES_PER_TORRENT + ", zip them?");
l.add(f);
} else {
File[] files = f.listFiles();

View File

@ -94,8 +94,7 @@ public class TrackerClient implements Runnable {
private static final Hash DSA_ONLY_TRACKER = ConvertToHash.getHash("cfmqlafjfmgkzbt4r3jsfyhgsr5abgxryl6fnz3d3y5a365di5aa.b32.i2p");
private final I2PSnarkUtil _util;
// non-final for reinitialize()
private MetaInfo meta;
private final MetaInfo meta;
private final String infoHash;
private final String peerID;
private final String additionalTrackerURL;
@ -267,22 +266,8 @@ public class TrackerClient implements Runnable {
}
}
/**
* Call after editing torrent
* @since 0.9.57
*/
public synchronized void reinitialize() {
if (!_initialized || !stop)
return;
trackers.clear();
backupTrackers.clear();
meta = snark.getMetaInfo();
setup();
}
/**
* Do this one time only (not every time it is started).
* Unless torrent was edited.
* @since 0.9.1
*/
private void setup() {

View File

@ -128,7 +128,7 @@ class UDPTrackerClient implements I2PSessionMuxedListener {
*
* @param ih the Info Hash (torrent)
* @param max maximum number of peers to return
* @param maxWait the maximum time to wait (ms) must be greater than 0
* @param maxWait the maximum time to wait (ms) must be > 0
* @param fast if true, don't wait for dest, no retx, ...
* @return null on fail or if fast is true
*/

View File

@ -100,7 +100,6 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
private final ConcurrentHashMap<NID, Token> _incomingTokens;
/** recently unreachable, with lastSeen() as the added-to-blacklist time */
private final Set<NID> _blacklist;
private SimpleTimer2.TimedEvent _cleaner, _explorer;
/** hook to inject and receive datagrams */
private final I2PSession _session;
@ -624,8 +623,6 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
public synchronized void start() {
if (_isRunning)
return;
if (_log.shouldInfo())
_log.info("KRPC start", new Exception());
_session.addMuxedSessionListener(this, I2PSession.PROTO_DATAGRAM_RAW, _rPort);
_session.addMuxedSessionListener(this, I2PSession.PROTO_DATAGRAM, _qPort);
_knownNodes.start();
@ -633,8 +630,9 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
PersistDHT.loadDHT(this, _dhtFile, _backupDhtFile);
// start the explore thread
_isRunning = true;
_cleaner = new Cleaner();
_explorer = new Explorer(5*1000);
// no need to keep ref, it will eventually stop
new Cleaner();
new Explorer(5*1000);
_txPkts.set(0);
_rxPkts.set(0);
_txBytes.set(0);
@ -650,10 +648,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
if (!_isRunning)
return;
_isRunning = false;
if (_log.shouldInfo())
_log.info("KRPC stop", new Exception());
_cleaner.cancel();
_explorer.cancel();
// FIXME stop the explore thread
// unregister port listeners
_session.removeListener(I2PSession.PROTO_DATAGRAM, _qPort);
_session.removeListener(I2PSession.PROTO_DATAGRAM_RAW, _rPort);
@ -1645,7 +1640,6 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
public void disconnected(I2PSession session) {
if (_log.shouldLog(Log.WARN))
_log.warn("KRPC disconnected");
stop();
}
public void errorOccurred(I2PSession session, String message, Throwable error) {
@ -1766,7 +1760,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
}
if (_log.shouldLog(Log.INFO))
_log.info("Explore of " + keys.size() + " buckets done, new size: " + _knownNodes.size());
_explorer = new Explorer(EXPLORE_TIME);
new Explorer(EXPLORE_TIME);
}
}
}

View File

@ -31,13 +31,12 @@ public class ConfigUIHelper {
{ "az", "az", "Azerbaijani", null },
{ "cs", "cz", "Čeština", null },
{ "zh", "cn", "Chinese 中文", null },
{ "zh_TW", "tw", "Chinese 中文", "Taiwan" },
//{ "zh_TW", "tw", "Chinese 中文", "Taiwan" },
{ "da", "dk", "Dansk", null },
{ "de", "de", "Deutsch", null },
//{ "et", "ee", "Eesti", null },
{ "en", "us", "English", null },
{ "es", "es", "Español", null },
{ "es_AR", "ar", "Español" ,"Argentina" },
{ "fa", "ir", "Persian فارسی", null },
{ "fr", "fr", "Français", null },
//{ "gl", "lang_gl", "Galego", null },

View File

@ -1,6 +1,5 @@
package org.klomp.snark.standalone;
import java.awt.GraphicsEnvironment;
import java.io.File;
import java.io.IOException;
import java.util.Properties;
@ -10,12 +9,8 @@ import org.eclipse.jetty.util.log.Log;
import net.i2p.I2PAppContext;
import net.i2p.apps.systray.UrlLauncher;
import net.i2p.data.DataHelper;
import net.i2p.desktopgui.ExternalMain;
import net.i2p.jetty.I2PLogger;
import net.i2p.jetty.JettyStart;
import net.i2p.util.SystemVersion;
import org.klomp.snark.SnarkManager;
/**
* @since moved from ../web and fixed in 0.9.27
@ -28,7 +23,6 @@ public class RunStandalone {
private String _host = "127.0.0.1";
private static RunStandalone _instance;
static final File APP_CONFIG_FILE = new File("i2psnark-appctx.config");
private static final String PROP_DTG_ENABLED = "desktopgui.enabled";
private RunStandalone(String args[]) throws Exception {
Properties p = new Properties();
@ -72,18 +66,13 @@ public class RunStandalone {
public void start() {
try {
String url = "http://" + _host + ':' + _port + "/i2psnark/";
System.out.println("Starting i2psnark " + SnarkManager.FULL_VERSION + " at " + url);
startTrayApp();
_jettyStart.startup();
String url = "http://" + _host + ':' + _port + "/i2psnark/";
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {}
String p = _context.getProperty("routerconsole.browser");
if (!("/bin/false".equals(p) || "NUL".equals(p))) {
UrlLauncher launch = new UrlLauncher(_context, null, new String[] { url } );
launch.startup();
}
UrlLauncher launch = new UrlLauncher(_context, null, new String[] { url } );
launch.startup();
} catch (Exception e) {
e.printStackTrace();
}
@ -103,39 +92,4 @@ public class RunStandalone {
} catch (InterruptedException ie) {}
System.exit(1);
}
/**
* @since 0.9.54 adapted from RouterConsoleRunner
*/
private static boolean isSystrayEnabled(I2PAppContext context) {
if (GraphicsEnvironment.isHeadless())
return false;
// default false except on OSX and Windows,
// and on Linux KDE and LXDE.
// Xubuntu XFCE works but doesn't look very good
// Ubuntu Unity was far too buggy to enable
// Ubuntu GNOME does not work, SystemTray.isSupported() returns false
String xdg = System.getenv("XDG_CURRENT_DESKTOP");
boolean dflt = SystemVersion.isWindows() ||
SystemVersion.isMac() ||
//"XFCE".equals(xdg) ||
"KDE".equals(xdg) ||
"LXDE".equals(xdg);
return context.getProperty(PROP_DTG_ENABLED, dflt);
}
/**
* @since 0.9.54 adapted from RouterConsoleRunner
*/
private void startTrayApp() {
try {
if (isSystrayEnabled(_context)) {
System.setProperty("java.awt.headless", "false");
ExternalMain dtg = new ExternalMain(_context, _context.clientAppManager(), null);
dtg.startup();
}
} catch (Throwable t) {
t.printStackTrace();
}
}
}

View File

@ -57,8 +57,6 @@ import org.klomp.snark.Storage;
import org.klomp.snark.Tracker;
import org.klomp.snark.TrackerClient;
import org.klomp.snark.URIUtil;
import org.klomp.snark.bencode.BEValue;
import org.klomp.snark.bencode.InvalidBEncodingException;
import org.klomp.snark.dht.DHT;
import org.klomp.snark.comments.Comment;
import org.klomp.snark.comments.CommentSet;
@ -214,7 +212,7 @@ public class I2PSnarkServlet extends BasicServlet {
req.setCharacterEncoding("UTF-8");
String pOverride = _manager.util().connected() ? null : "";
String peerString = getQueryString(req, pOverride, null, null, "");
String peerString = getQueryString(req, pOverride, null, null);
String cspNonce = Integer.toHexString(_context.random().nextInt());
// AJAX for mainsection
@ -322,12 +320,9 @@ public class I2PSnarkServlet extends BasicServlet {
// we want it to go to the base URI so we don't refresh with some funky action= value
int delay = 0;
if (isConfigure) {
out.write("<script src=\".resources/js/configui.js?" + CoreVersion.VERSION + "\" type=\"text/javascript\"></script>\n");
} else {
if (!isConfigure) {
delay = _manager.getRefreshDelaySeconds();
// init for search even if refresh disabled
//if (delay > 0) {
if (delay > 0) {
String jsPfx = _context.isRouterContext() ? "" : ".resources";
String downMsg = _context.isRouterContext() ? _t("Router is down") : _t("I2PSnark has stopped");
// fallback to metarefresh when javascript is disabled
@ -338,13 +333,12 @@ public class I2PSnarkServlet extends BasicServlet {
"var ajaxDelay = " + (delay * 1000) + ";\n" +
"</script>\n" +
"<script src=\".resources/js/initajax.js?" + CoreVersion.VERSION + "\" type=\"text/javascript\"></script>\n");
//}
}
out.write("<script nonce=\"" + cspNonce + "\" type=\"text/javascript\">\n" +
"var deleteMessage1 = \"" + _t("Are you sure you want to delete the file \\''{0}\\'' (downloaded data will not be deleted) ?") + "\";\n" +
"var deleteMessage2 = \"" + _t("Are you sure you want to delete the torrent \\''{0}\\'' and all downloaded data?") + "\";\n" +
"</script>\n" +
"<script src=\".resources/js/delete.js?" + CoreVersion.VERSION + "\" type=\"text/javascript\"></script>\n" +
"<script src=\".resources/js/search.js?" + CoreVersion.VERSION + "\" type=\"text/javascript\"></script>\n");
"<script src=\".resources/js/delete.js?" + CoreVersion.VERSION + "\" type=\"text/javascript\"></script>\n");
}
out.write(HEADER_A + _themePath + HEADER_B);
@ -368,7 +362,7 @@ public class I2PSnarkServlet extends BasicServlet {
else
out.write(_contextName);
if (!_context.isRouterContext()) {
out.write(' ' + SnarkManager.FULL_VERSION);
out.write(' ' + CoreVersion.VERSION);
}
out.write("</a>");
List<Tracker> sortedTrackers = null;
@ -380,30 +374,15 @@ public class I2PSnarkServlet extends BasicServlet {
continue;
if (_manager.util().isKnownOpenTracker(t.announceURL))
continue;
out.write(" <a href=\"" + t.baseURL + "\" class=\"snarkNav nav_tracker\" target=\"_blank\">" + t.name + "</a>\n");
out.write(" <a href=\"" + t.baseURL + "\" class=\"snarkNav nav_tracker\" target=\"_blank\">" + t.name + "</a>");
}
}
}
// end snarkNavBar
out.write("</div>\n");
if (!isConfigure) {
String search = req.getParameter("nf_s");
if (_manager.getTorrents().size() > 1 || (search != null && search.length() > 0)) {
out.write("<form class=\"search\" id = \"search\" action=\"" + _contextPath + "\" method=\"GET\">" +
"<input type=\"text\" name=\"nf_s\" size=\"20\" class=\"search\" id=\"searchbox\"");
if (search != null)
out.write(" value=\"" + DataHelper.escapeHTML(search) + '"');
out.write(">" +
"<a class=\"cancel\" id=\"searchcancel\" href=\"" + _contextPath + "/\"></a>" +
"</form>\n");
}
}
String newURL = req.getParameter("newURL");
if (newURL != null && newURL.trim().length() > 0 && req.getMethod().equals("GET"))
_manager.addMessage(_t("Click \"Add torrent\" button to fetch torrent"));
out.write("<div id=\"page\" class=\"page\"><div id=\"mainsection\" class=\"mainsection\">");
out.write("<div class=\"page\"><div id=\"mainsection\" class=\"mainsection\">");
writeMessages(out, isConfigure, peerString);
@ -505,17 +484,6 @@ public class I2PSnarkServlet extends BasicServlet {
boolean isDegraded = ua != null && ServletUtil.isTextBrowser(ua);
boolean noThinsp = isDegraded || (ua != null && ua.startsWith("Opera"));
// search
boolean isSearch = false;
String search = req.getParameter("nf_s");
if (search != null && search.length() > 0) {
List<Snark> matches = search(search, snarks);
if (matches != null) {
snarks = matches;
isSearch = true;
}
}
// pages
int start = 0;
int total = snarks.size();
@ -771,8 +739,6 @@ public class I2PSnarkServlet extends BasicServlet {
out.write(_t("Unreadable") + ": " + DataHelper.escapeHTML(dd.toString()));
} else if (!canWrite) {
out.write(_t("No write permissions for data directory") + ": " + DataHelper.escapeHTML(dd.toString()));
} else if (isSearch) {
out.write(_t("No torrents found."));
} else {
out.write(_t("No torrents loaded."));
}
@ -847,48 +813,6 @@ public class I2PSnarkServlet extends BasicServlet {
return start == 0;
}
/**
* search torrents for matching terms
*
* @param search non-null and %-encoded, will be decoded here
* @param snarks unmodified, order will be honored
* @return null if not a valid search, or matching torrents in same order, possibly empty
* @since 0.9.58
*/
private static List<Snark> search(String search, Collection<Snark> snarks) {
try {
search = decodePath(search);
} catch (IOException ioe) {
return null;
}
List<String> searchList = null;
String[] terms = DataHelper.split(search, " ");
for (int i = 0; i < terms.length; i++) {
String term = terms[i];
if (term.length() > 0) {
if (searchList == null)
searchList = new ArrayList<String>(4);
searchList.add(term.toLowerCase(Locale.US));
}
}
if (searchList == null)
return null;
List<Snark> matches = new ArrayList<Snark>(32);
for (Snark snark : snarks) {
String lcname = snark.getBaseName().toLowerCase(Locale.US);
// search for any term (OR)
for (int j = 0; j < searchList.size(); j++) {
String term = searchList.get(j);
if (lcname.contains(term)) {
matches.add(snark);
break;
}
}
}
return matches;
}
/**
* hidden inputs for nonce and paramters p, st, and sort
*
@ -930,19 +854,11 @@ public class I2PSnarkServlet extends BasicServlet {
if (action != null) {
buf.append("<input type=\"hidden\" name=\"action\" value=\"")
.append(action).append("\" >\n");
} else {
// for buttons, keep the search term
String sParam = req.getParameter("nf_s");
if (sParam != null) {
buf.append("<input type=\"hidden\" name=\"nf_s\" value=\"")
.append(DataHelper.escapeHTML(sParam)).append("\" >\n");
}
}
}
/**
* Build HTML-escaped and stripped query string.
* Keeps any existing search param.
* Build HTML-escaped and stripped query string
*
* @param p override or "" for default or null to keep the same as in req
* @param st override or "" for default or null to keep the same as in req
@ -951,14 +867,6 @@ public class I2PSnarkServlet extends BasicServlet {
* @since 0.9.16
*/
private static String getQueryString(HttpServletRequest req, String p, String st, String so) {
return getQueryString(req, p, st, so, null);
}
/**
* @param s search param override or "" for default or null to keep the same as in req
* @since 0.9.58
*/
private static String getQueryString(HttpServletRequest req, String p, String st, String so, String s) {
StringBuilder buf = new StringBuilder(64);
if (p == null) {
p = req.getParameter("p");
@ -991,18 +899,6 @@ public class I2PSnarkServlet extends BasicServlet {
buf.append("&amp;st=");
buf.append(st);
}
if (s == null) {
s = req.getParameter("nf_s");
if (s != null)
s = DataHelper.escapeHTML(s);
}
if (s != null && !s.equals("")) {
if (buf.length() <= 0)
buf.append("?nf_s=");
else
buf.append("&amp;nf_s=");
buf.append(s);
}
return buf.toString();
}
@ -1439,9 +1335,6 @@ public class I2PSnarkServlet extends BasicServlet {
} else if ("Create".equals(action)) {
String baseData = req.getParameter("nofilter_baseFile");
if (baseData != null && baseData.trim().length() > 0) {
// drag and drop, no js
if (baseData.startsWith("file://"))
baseData = baseData.substring(7);
File baseFile = new File(baseData.trim());
if (!baseFile.isAbsolute())
baseFile = new File(_manager.getDataDir(), baseData);
@ -1560,34 +1453,8 @@ public class I2PSnarkServlet extends BasicServlet {
_manager.addMessage(_t("Error creating torrent - you must enter a file or directory"));
}
} else if ("StopAll".equals(action)) {
String search = req.getParameter("nf_s");
if (search != null && search.length() > 0) {
List<Snark> matches = search(search, _manager.getTorrents());
if (matches != null) {
for (Snark snark : matches) {
_manager.stopTorrent(snark, false);
}
return;
}
}
_manager.stopAllTorrents(false);
} else if ("StartAll".equals(action)) {
String search = req.getParameter("nf_s");
if (search != null && search.length() > 0) {
List<Snark> matches = search(search, _manager.getTorrents());
if (matches != null) {
// TODO thread it
int count = 0;
for (Snark snark : matches) {
_manager.startTorrent(snark);
if ((count++ & 0x0f) == 15) {
// try to prevent OOMs
try { Thread.sleep(250); } catch (InterruptedException ie) {}
}
}
return;
}
}
_manager.startAllTorrents();
} else if ("Clear".equals(action)) {
String sid = req.getParameter("id");
@ -1893,7 +1760,7 @@ public class I2PSnarkServlet extends BasicServlet {
":</b> " + curPeers + thinsp(noThinsp) +
ngettext("1 peer", "{0} peers", knownPeers);
} else if (isRunning && curPeers > 0 && !showPeers) {
statusString = toThemeImg("stalled", "", _t("Stalled") + " (" + ngettext("Connected to {0} peer", "Connected to {0} peers", curPeers) + ")") + "</td>" +
statusString = toThemeImg("stalled", "", _t("Stalled") + " (" + ngettext("Connected to {0} peer", "Connected to {0} peers", curPeers)) + "</td>" +
"<td class=\"snarkTorrentStatus\"><b>" + _t("Stalled") +
":</b> <a href=\"" + uri + getQueryString(req, b64, null, null) + '#' + b64Short + "\">" +
curPeers + thinsp(noThinsp) +
@ -2135,73 +2002,30 @@ public class I2PSnarkServlet extends BasicServlet {
if (ch.startsWith("WebSeed@")) {
out.write(ch);
} else {
// most clients start -xx, see
// BT spec or libtorrent identify_client.cpp
// Base64 encode -xx
// Anything starting with L is -xx and has an Az version
// snark is 9 nulls followed by 3 3 3 (binary), see Snark
// PeerID.toString() skips nulls
// Base64 encode '\3\3\3' = AwMD
boolean addVersion = true;
ch = ch.substring(0, 4);
String client;
if ("AwMD".equals(ch))
client = _t("I2PSnark");
else if ("LUJJ".equals(ch))
client = "BiglyBT";
client = "BiglyBT" + getAzVersion(pid.getID());
else if ("LUFa".equals(ch))
client = "Vuze";
client = "Vuze" + getAzVersion(pid.getID());
else if ("LVhE".equals(ch))
client = "XD";
else if (ch.startsWith("LV")) // LVCS 1.0.2?; LVRS 1.0.4
client = "Transmission";
else if ("LUtU".equals(ch))
client = "KTorrent";
// libtorrent and downstreams
// https://www.libtorrent.org/projects.html
else if ("LURF".equals(ch)) // DL
client = "Deluge";
else if ("LXFC".equals(ch)) // qB
client = "qBitorrent";
else if ("LUxU".equals(ch)) // LT
client = "libtorrent";
// ancient below here
client = "XD" + getAzVersion(pid.getID());
else if ("ZV".equals(ch.substring(2,4)) || "VUZP".equals(ch))
client = "Robert" + getRobtVersion(pid.getID());
else if (ch.startsWith("LV")) // LVCS 1.0.2?; LVRS 1.0.4
client = "Transmission" + getAzVersion(pid.getID());
else if ("LUtU".equals(ch))
client = "KTorrent" + getAzVersion(pid.getID());
else if ("CwsL".equals(ch))
client = "I2PSnarkXL";
else if ("BFJT".equals(ch))
client = "I2PRufus";
else if ("TTMt".equals(ch))
client = "I2P-BT";
else {
// get client + version from handshake
client = null;
Map<String, BEValue> handshake = peer.getHandshakeMap();
if (handshake != null) {
BEValue bev = handshake.get("v");
if (bev != null) {
try {
String s = bev.getString();
if (s.length() > 0) {
if (s.length() > 64)
s = s.substring(0, 64);
client = DataHelper.escapeHTML(s);
addVersion = false;
}
} catch (InvalidBEncodingException ibee) {}
}
}
if (client == null)
client = _t("Unknown") + " (" + ch + ')';
}
if (addVersion) {
byte[] id = pid.getID();
if (id != null && id[0] == '-')
client += getAzVersion(id);
}
else
client = _t("Unknown") + " (" + ch + ')';
out.write(client + "&nbsp;<tt title=\"");
out.write(_t("Destination (identity) of peer"));
out.write("\">" + peer.toString().substring(5, 9)+ "</tt>");
@ -2486,19 +2310,19 @@ public class I2PSnarkServlet extends BasicServlet {
out.write("<hr>\n<table border=\"0\"><tr><td>");
out.write(_t("From URL"));
out.write(":<td><input type=\"text\" id=\"nofilter_newURL\" name=\"nofilter_newURL\" size=\"85\" value=\"" + newURL + "\" spellcheck=\"false\"" +
out.write(":<td><input type=\"text\" name=\"nofilter_newURL\" size=\"85\" value=\"" + newURL + "\" spellcheck=\"false\"" +
" title=\"");
out.write(_t("Enter the torrent file download URL (I2P only), magnet link, or info hash"));
out.write("\">\n");
// not supporting from file at the moment, since the file name passed isn't always absolute (so it may not resolve)
//out.write("From file: <input type=\"file\" name=\"newFile\" size=\"50\" value=\"" + newFile + "\" /><br>");
out.write("<input type=\"submit\" id=\"addButton\" class=\"add\" value=\"");
out.write("<input type=\"submit\" class=\"add\" value=\"");
out.write(_t("Add torrent"));
out.write("\" name=\"foo\" ><br>\n" +
"<tr><td>");
out.write(_t("Data dir"));
out.write(":<td><input type=\"text\" id=\"nofilter_newDir\" name=\"nofilter_newDir\" size=\"85\" value=\"\" spellcheck=\"false\"" +
out.write(":<td><input type=\"text\" name=\"nofilter_newDir\" size=\"85\" value=\"\" spellcheck=\"false\"" +
" title=\"");
out.write(_t("Enter the directory to save the data in (default {0})", _manager.getDataDir().getAbsolutePath()));
out.write("\"></td></tr>\n");
@ -2524,11 +2348,11 @@ public class I2PSnarkServlet extends BasicServlet {
//out.write("From file: <input type=\"file\" name=\"newFile\" size=\"50\" value=\"" + newFile + "\" /><br>\n");
out.write(_t("Data to seed"));
out.write(":<td>"
+ "<input type=\"text\" id=\"nofilter_baseFile\" name=\"nofilter_baseFile\" size=\"85\" value=\""
+ "<input type=\"text\" name=\"nofilter_baseFile\" size=\"85\" value=\""
+ "\" spellcheck=\"false\" title=\"");
out.write(_t("File or directory to seed (full path or within the directory {0} )",
_manager.getDataDir().getAbsolutePath() + File.separatorChar));
out.write("\" > <input type=\"submit\" id=\"createButton\" class=\"create\" value=\"");
out.write("\" > <input type=\"submit\" class=\"create\" value=\"");
out.write(_t("Create torrent"));
out.write("\" name=\"foo\" >" +
"<tr><td>\n");
@ -2679,7 +2503,7 @@ public class I2PSnarkServlet extends BasicServlet {
out.write(_t("Theme"));
out.write(":<td colspan=\"2\">");
if (_manager.getUniversalTheming()) {
out.write("<select id=\"theme\" name=\"theme\" disabled=\"disabled\" title=\"");
out.write("<select name='theme' disabled=\"disabled\" title=\"");
out.write(_t("To change themes manually, disable universal theming"));
out.write("\"><option>");
out.write(_manager.getTheme());
@ -2689,7 +2513,7 @@ public class I2PSnarkServlet extends BasicServlet {
out.write(_t("Configure"));
out.write("]</a>");
} else {
out.write("<select id=\"theme\" name=\"theme\">");
out.write("<select name='theme'>");
String theme = _manager.getTheme();
String[] themes = _manager.getThemes();
// translated sort
@ -3130,7 +2954,7 @@ public class I2PSnarkServlet extends BasicServlet {
}
private static final String DOCTYPE = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
private static final String HEADER_A = "<link id=\"pagestyle\" href=\"";
private static final String HEADER_A = "<link href=\"";
private static final String HEADER_B = "snark.css?" + CoreVersion.VERSION + "\" rel=\"stylesheet\" type=\"text/css\" >";
private static final String HEADER_C = "nocollapse.css?" + CoreVersion.VERSION + "\" rel=\"stylesheet\" type=\"text/css\" >";

View File

@ -14,10 +14,6 @@
package org.klomp.snark.web;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Map;
@ -25,9 +21,6 @@ import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.concurrent.ConcurrentHashMap;
import net.i2p.data.DataHelper;
import net.i2p.util.SystemVersion;
/* ------------------------------------------------------------ */
/**
@ -54,8 +47,6 @@ class MimeTypes
public MimeTypes() {
_mimeMap = new ConcurrentHashMap<String, String>();
if (!(SystemVersion.isWindows() || SystemVersion.isMac() || SystemVersion.getMaxMemory() < 100*1024*1024L))
loadSystemMimeTypes();
}
/* ------------------------------------------------------------ */
@ -95,37 +86,6 @@ class MimeTypes
}
}
/**
* Load mime types from /etc/mime.types
* Format: mimetype suffix1 suffix2 ...
*
* @since 0.9.54
*/
private void loadSystemMimeTypes() {
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(new FileInputStream("/etc/mime.types"), "ISO-8859-1"));
while (true) {
String line = in.readLine();
if (line == null)
break;
if (line.startsWith("#"))
continue;
String[] s = DataHelper.split(line, "[ \t]+", 16);
if (s.length < 2)
continue;
for (int i = 1; i < s.length; i++) {
_mimeMap.put(s[i].toLowerCase(Locale.US), s[0]);
//System.out.println("Mapping: '" + s[i] + "' -> '" + s[0] + "'");
}
}
//System.out.println("Loaded " + _mimeMap.size() + " mime types from /etc/mime.types");
} catch (IOException ioe) {
} finally {
if (in != null) try { in.close(); } catch (IOException ioe) {}
}
}
/* ------------------------------------------------------------ */
/** Get the MIME type by filename extension.
*

View File

@ -8,9 +8,6 @@
# Raise the soft open files soft ulimit to this value, if able
OPEN_FILES_ULIMIT=2048
# Increase memory to 512 MB
JAVA_OPTS='-Xmx512m'
raiseopenfilesulimit() {
OPEN_FILES_SOFT=`ulimit -S -n` 2> /dev/null || return
if [ "$OPEN_FILES_SOFT" != "unlimited" ]
@ -35,6 +32,5 @@ raiseopenfilesulimit() {
raiseopenfilesulimit
I2P="`dirname $0`"
cd "$I2P"
java $JAVA_OPTS -jar i2psnark.jar
I2P="."
java -jar "$I2P/i2psnark.jar"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,6 @@
# D.A. Loader, 2012
# ducki2p <ducki2p@gmail.com>, 2011
# Ettore Atalan <atalanttore@googlemail.com>, 2014,2017
# Fabian Schuler, 2022
# foo <foo@bar>, 2009
# SteinQuadrat, 2013
# Lars Schimmer <echelon@i2pmail.org>, 2014-2016,2018,2020-2021
@ -26,8 +25,8 @@ msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:00+0000\n"
"Last-Translator: Fabian Schuler, 2022\n"
"PO-Revision-Date: 2022-02-09 19:23+0000\n"
"Last-Translator: ducki2p <ducki2p@gmail.com>\n"
"Language-Team: German (http://www.transifex.com/otf/I2P/language/de/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -57,7 +56,7 @@ msgstr "Magnet"
#: ../java/src/org/klomp/snark/SnarkManager.java:2572
#: ../java/src/org/klomp/snark/SnarkManager.java:2627
msgid "Unable to connect to I2P"
msgstr "Verbindung zu I2P nicht möglich"
msgstr ""
#: ../java/src/org/klomp/snark/Snark.java:597
#: ../java/src/org/klomp/snark/SnarkManager.java:1727
@ -1547,7 +1546,7 @@ msgstr[1] "{0} Tunnel"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3121
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3428
msgid "Edit Torrent"
msgstr "Torrent bearbeiten"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3131
msgid "Torrent file"
@ -1642,7 +1641,7 @@ msgstr "Überprüfung forcieren"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4205
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4544
msgid "Torrent must be stopped"
msgstr "Torrent muss beendet werden"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3425
msgid "Check integrity of the downloaded files"
@ -1650,7 +1649,7 @@ msgstr "Integrität der heruntergeladenen Dateien überprüfen."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3434
msgid "Add or remove trackers"
msgstr "Tracker hinzufügen oder entfernen"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3444
msgid "Download files in order"
@ -1822,7 +1821,7 @@ msgstr "Tracker"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4273
msgid "Add Tracker"
msgstr "Tracker hinzufügen"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4313
msgid "Save Changes"

View File

@ -10,8 +10,8 @@ msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:00+0000\n"
"Last-Translator: LaScapigliata <ditri2000@hotmail.com>, 2015\n"
"PO-Revision-Date: 2022-02-09 19:23+0000\n"
"Last-Translator: Alex <hestia@riseup.net>\n"
"Language-Team: Greek (http://www.transifex.com/otf/I2P/language/el/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -1598,7 +1598,7 @@ msgstr "Υπόλοιπα"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3375
msgid "Skipped"
msgstr "Παρελήφθη"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3383
msgid "Files"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -11,8 +11,8 @@ msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:00+0000\n"
"Last-Translator: Reza Ghasemi, 2019\n"
"PO-Revision-Date: 2022-02-09 19:23+0000\n"
"Last-Translator: Martus Translations <translations@martus.org>\n"
"Language-Team: Persian (http://www.transifex.com/otf/I2P/language/fa/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -1114,7 +1114,7 @@ msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1891
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3277
msgid "Completed"
msgstr "تکمیل شد"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1929
msgid "Stop the torrent"

View File

@ -11,8 +11,8 @@ msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:00+0000\n"
"Last-Translator: outolumo <outolumo@gmail.com>, 2016\n"
"PO-Revision-Date: 2022-02-09 19:23+0000\n"
"Last-Translator: outolumo <outolumo@gmail.com>\n"
"Language-Team: Finnish (http://www.transifex.com/otf/I2P/language/fi/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -1795,7 +1795,7 @@ msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4165
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4251
msgid "Mark for deletion"
msgstr "Merkitse poistettavaksi"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4178
msgid "Delete Selected"
@ -1811,4 +1811,4 @@ msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4313
msgid "Save Changes"
msgstr "Tallenna muutokset"
msgstr ""

View File

@ -15,21 +15,20 @@
# jackjack <root@waka.site40.net>, 2011
# syl_, 2015-2016
# Towinet, 2013-2016
# vex vex, 2022
# zzzi2p, 2017
msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:00+0000\n"
"Last-Translator: vex vex, 2022\n"
"PO-Revision-Date: 2022-02-09 19:23+0000\n"
"Last-Translator: AO <ao@localizationlab.org>\n"
"Language-Team: French (http://www.transifex.com/otf/I2P/language/fr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: fr\n"
"Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: ../java/src/org/klomp/snark/IdleChecker.java:76
msgid "No more torrents running."
@ -53,7 +52,7 @@ msgstr "Magnet"
#: ../java/src/org/klomp/snark/SnarkManager.java:2572
#: ../java/src/org/klomp/snark/SnarkManager.java:2627
msgid "Unable to connect to I2P"
msgstr "Impossible de se connecter à I2P"
msgstr ""
#: ../java/src/org/klomp/snark/Snark.java:597
#: ../java/src/org/klomp/snark/SnarkManager.java:1727
@ -73,7 +72,7 @@ msgstr "clair"
#. Translators: Translate "ubergine" as "aubergine" or "eggplant" or "purple"
#: ../java/src/org/klomp/snark/SnarkManager.java:146
msgid "ubergine"
msgstr "aubergine"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:146
msgid "vanilla"
@ -786,7 +785,6 @@ msgid "1 torrent"
msgid_plural "{0} torrents"
msgstr[0] "1 torrent"
msgstr[1] "{0} torrents"
msgstr[2] "{0} torrents"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:758
#, java-format
@ -794,7 +792,6 @@ msgid "1 connected peer"
msgid_plural "{0} connected peers"
msgstr[0] "1 pair connecté"
msgstr[1] "{0} pairs connectés"
msgstr[2] "{0} pairs connectés"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:765
#, java-format
@ -802,7 +799,6 @@ msgid "1 DHT peer"
msgid_plural "{0} DHT peers"
msgstr[0] "1 pair de la table de hachage distribuée"
msgstr[1] "{0} pairs de la table de hachage distribuée"
msgstr[2] "{0} pairs de la table de hachage distribuée"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:773
msgid "Dest"
@ -1022,7 +1018,6 @@ msgid "1 peer"
msgid_plural "{0} peers"
msgstr[0] "1 pair"
msgstr[1] "{0} pairs"
msgstr[2] "{0} pairs"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1716
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1717
@ -1040,7 +1035,6 @@ msgid "Seeding to {0} peer"
msgid_plural "Seeding to {0} peers"
msgstr[0] "Propagation vers {0} pair"
msgstr[1] "Propagation vers {0} pairs"
msgstr[2] "Propagation vers {0} pairs"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1731
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1747
@ -1068,7 +1062,6 @@ msgid "Downloading from {0} peer"
msgid_plural "Downloading from {0} peers"
msgstr[0] "Téléchargement à partir d{0} pair"
msgstr[1] "Téléchargement à partir de {0} pairs"
msgstr[2] "Téléchargement à partir de {0} pairs"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1763
#, java-format
@ -1076,7 +1069,6 @@ msgid "Connected to {0} peer"
msgid_plural "Connected to {0} peers"
msgstr[0] "Connecté à {0} pair"
msgstr[1] "Connecté à {0} pairs"
msgstr[2] "Connecté à {0} pairs"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1763
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1764
@ -1539,7 +1531,6 @@ msgid "1 hop"
msgid_plural "{0} hops"
msgstr[0] "1 saut"
msgstr[1] "{0} sauts"
msgstr[2] "{0} sauts"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2844
#, java-format
@ -1547,12 +1538,11 @@ msgid "1 tunnel"
msgid_plural "{0} tunnels"
msgstr[0] "1 tunnel"
msgstr[1] "{0} tunnels"
msgstr[2] "{0} tunnels"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3121
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3428
msgid "Edit Torrent"
msgstr "Modifier Torrent"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3131
msgid "Torrent file"
@ -1647,7 +1637,7 @@ msgstr "Forcer une revérification"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4205
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4544
msgid "Torrent must be stopped"
msgstr "Torrent doit être arrêté"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3425
msgid "Check integrity of the downloaded files"
@ -1655,7 +1645,7 @@ msgstr "Vérifier lintégrité des fichiers téléchargés"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3434
msgid "Add or remove trackers"
msgstr "Ajouter ou enlever les traqueurs"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3444
msgid "Download files in order"
@ -1782,7 +1772,6 @@ msgid "1 star"
msgid_plural "{0} stars"
msgstr[0] "1 étoile"
msgstr[1] "{0} étoiles"
msgstr[2] "{0} étoiles"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4068
msgid "No rating"
@ -1828,7 +1817,7 @@ msgstr "Traqueur"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4273
msgid "Add Tracker"
msgstr "Ajouter un traqueur"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4313
msgid "Save Changes"

View File

@ -9,14 +9,13 @@
# omgitsadalek <mihalymokus76@gmail.com>, 2013
# Nyul Csoki <csokinyul@i2pmail.org>, 2021
# benewfy <benewfy@gmail.com>, 2015
# vargaviktor <viktor.varga@gmail.com>, 2022
msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:00+0000\n"
"Last-Translator: vargaviktor <viktor.varga@gmail.com>, 2022\n"
"PO-Revision-Date: 2022-02-09 19:23+0000\n"
"Last-Translator: AdminLMH <lehetmashogy@i2pmail.org>\n"
"Language-Team: Hungarian (http://www.transifex.com/otf/I2P/language/hu/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -46,7 +45,7 @@ msgstr "Mágnes"
#: ../java/src/org/klomp/snark/SnarkManager.java:2572
#: ../java/src/org/klomp/snark/SnarkManager.java:2627
msgid "Unable to connect to I2P"
msgstr "Sikertelen csatlakozás az I2P-hez"
msgstr ""
#: ../java/src/org/klomp/snark/Snark.java:597
#: ../java/src/org/klomp/snark/SnarkManager.java:1727
@ -66,11 +65,11 @@ msgstr "világos"
#. Translators: Translate "ubergine" as "aubergine" or "eggplant" or "purple"
#: ../java/src/org/klomp/snark/SnarkManager.java:146
msgid "ubergine"
msgstr "lila"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:146
msgid "vanilla"
msgstr "vanília"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:997
#: ../java/src/org/klomp/snark/SnarkManager.java:1151
@ -1536,7 +1535,7 @@ msgstr[1] "{0} alagút"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3121
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3428
msgid "Edit Torrent"
msgstr "Torrent szerkesztése"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3131
msgid "Torrent file"
@ -1631,7 +1630,7 @@ msgstr "Újraellenőrzés kényszerítése"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4205
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4544
msgid "Torrent must be stopped"
msgstr "A Torrentet le kell állítani"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3425
msgid "Check integrity of the downloaded files"
@ -1639,7 +1638,7 @@ msgstr "A letöltött fájlok épségének ellenőrzése"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3434
msgid "Add or remove trackers"
msgstr "Tracker-ek hozzáadása vagy eltávolítása"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3444
msgid "Download files in order"
@ -1811,8 +1810,8 @@ msgstr "Követő (tracker)"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4273
msgid "Add Tracker"
msgstr "Tracker hozzáadása"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4313
msgid "Save Changes"
msgstr "Változtatások mentése"
msgstr ""

View File

@ -13,8 +13,8 @@ msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:00+0000\n"
"Last-Translator: daingewuvzeevisiddfddd, 2022\n"
"PO-Revision-Date: 2022-02-13 03:20+0000\n"
"Last-Translator: daingewuvzeevisiddfddd\n"
"Language-Team: Japanese (http://www.transifex.com/otf/I2P/language/ja/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -100,7 +100,7 @@ msgstr "最低合計アップローダー数の上限は{0}です"
#: ../java/src/org/klomp/snark/SnarkManager.java:1076
#, java-format
msgid "Up BW limit changed to {0}KBps"
msgstr "アップロード帯域幅の上限は{0}Kbpsに変更されました"
msgstr "アップロード帯域限は{0}Kbpsに変更されました"
#: ../java/src/org/klomp/snark/SnarkManager.java:1078
#, java-format
@ -609,7 +609,7 @@ msgstr "I2PSnarkは停止しました"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:327
msgid "Router is down"
msgstr "ルータは落ちています"
msgstr "ルータは落ちています"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:338
#, java-format
@ -1287,7 +1287,7 @@ msgstr "トレントと、ダウンロードした、または共有したファ
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2448
msgid "Files readable by all"
msgstr "ファイルが全に読み取り可能"
msgstr "ファイルが全に読み取り可能"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2452
msgid ""
@ -1359,7 +1359,7 @@ msgstr "メインページのトレントの状態の更新頻度"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2552
msgid "Never"
msgstr "行わない"
msgstr "二度としない"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2559
msgid "Startup delay"
@ -1411,7 +1411,7 @@ msgstr "半分の帯域幅を利用可能にすることを推奨します。"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2617
msgid "View or change router bandwidth"
msgstr "ルータの帯域幅を表示または変更"
msgstr "ルータの帯域幅を表示または変更"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2623
msgid "Use open trackers also"

View File

@ -11,8 +11,8 @@ msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:00+0000\n"
"Last-Translator: Allan Nordhøy <epost@anotheragency.no>, 2017\n"
"PO-Revision-Date: 2022-02-09 19:23+0000\n"
"Last-Translator: Allan Nordhøy <epost@anotheragency.no>\n"
"Language-Team: Norwegian Bokmål (http://www.transifex.com/otf/I2P/language/nb/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -804,7 +804,7 @@ msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:916
msgid "First"
msgstr "Først"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:916
msgid "First page"
@ -828,7 +828,7 @@ msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:967
msgid "Last"
msgstr "Sist"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:967
msgid "Last page"
@ -1092,7 +1092,7 @@ msgstr "Torrentdetaljer"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1839
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4036
msgid "Comments"
msgstr "Kommentarer"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1863
msgid "View files"
@ -1599,7 +1599,7 @@ msgstr "Gjennstår"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3375
msgid "Skipped"
msgstr "Hoppet over"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3383
msgid "Files"
@ -1777,7 +1777,7 @@ msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4087
msgid "Add Comment"
msgstr "Legg til kommentar"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4099
msgid "My Rating"
@ -1811,4 +1811,4 @@ msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4313
msgid "Save Changes"
msgstr "Lagre endringer"
msgstr ""

View File

@ -15,14 +15,13 @@
# ☆Verdulo, 2016-2017
# ☆Verdulo, 2021
# ☆Verdulo, 2017
# Waldemar Napora, 2022
msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:00+0000\n"
"Last-Translator: Waldemar Napora, 2022\n"
"PO-Revision-Date: 2022-02-09 19:23+0000\n"
"Last-Translator: polacco <polacco@i2pmail.org>\n"
"Language-Team: Polish (http://www.transifex.com/otf/I2P/language/pl/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -52,7 +51,7 @@ msgstr "Magnet"
#: ../java/src/org/klomp/snark/SnarkManager.java:2572
#: ../java/src/org/klomp/snark/SnarkManager.java:2627
msgid "Unable to connect to I2P"
msgstr "Nie można połączyć się z I2P"
msgstr ""
#: ../java/src/org/klomp/snark/Snark.java:597
#: ../java/src/org/klomp/snark/SnarkManager.java:1727
@ -72,7 +71,7 @@ msgstr "jasny"
#. Translators: Translate "ubergine" as "aubergine" or "eggplant" or "purple"
#: ../java/src/org/klomp/snark/SnarkManager.java:146
msgid "ubergine"
msgstr "bakłażan"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:146
msgid "vanilla"
@ -339,7 +338,7 @@ msgstr "Torrent o tym hashu jest już uruchomiony: {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:1896
#, java-format
msgid "Torrent with the same data location is already running: {0}"
msgstr "Torrent z tą samą lokalizacją danych jest już uruchomiony: {0}"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1655
#, java-format
@ -860,12 +859,12 @@ msgstr "Nie można dodać torrenta {0} wewnątrz innego torrenta {1}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1082
#, java-format
msgid "Download from non-I2P location {0} is not supported"
msgstr "Pobieranie z lokalizacji innej niż I2P {0} nie jest wspierane"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1153
#, java-format
msgid "Invalid URL: Must start with \"{0}\" or \"{1}\""
msgstr "Nieprawidłowy URL: Musi zaczynać się z \"{0}\" lub \"{1}\""
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1195
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1230
@ -1041,10 +1040,10 @@ msgstr "Seedowanie"
#, java-format
msgid "Seeding to {0} peer"
msgid_plural "Seeding to {0} peers"
msgstr[0] "Seedowanie do {0} peera"
msgstr[1] "Seedowanie do {0} peerów"
msgstr[2] "Seedowanie do {0} peerów"
msgstr[3] "Seedowanie do {0} peerów"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1731
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1747
@ -1070,19 +1069,19 @@ msgstr "OK"
#, java-format
msgid "Downloading from {0} peer"
msgid_plural "Downloading from {0} peers"
msgstr[0] "Pobieranie od {0} peera"
msgstr[1] "Pobieranie od {0} peerów"
msgstr[2] "Pobieranie od {0} peerów"
msgstr[3] "Pobieranie od {0} peerów"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1763
#, java-format
msgid "Connected to {0} peer"
msgid_plural "Connected to {0} peers"
msgstr[0] "Połączony z {0} peerem"
msgstr[1] "Połączony z {0} peerami"
msgstr[2] "Połączony z {0} peerami"
msgstr[3] "Połączony z {0} peerami"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1763
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1764
@ -1168,7 +1167,7 @@ msgstr "Usuń"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1978
msgid "Delete the .torrent file and the associated data files"
msgstr "Usuń plik .torrent i powiązane pliki danych"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1982
msgid "Delete"
@ -1226,7 +1225,7 @@ msgstr "Z adresu URL"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2315
msgid ""
"Enter the torrent file download URL (I2P only), magnet link, or info hash"
msgstr "Wpisz adres URL pobierania pliku (I2P tylko), magnet link lub info hash"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2320
msgid "Add torrent"
@ -1420,7 +1419,7 @@ msgstr "Całkowity limit uploaderów"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2602
msgid "Maximum number of peers for uploading"
msgstr "Maksymalna liczba peerów dla wysyłania"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2604
msgid "peers"
@ -1450,7 +1449,7 @@ msgstr "Używaj również otwartych trackerów"
msgid ""
"Announce torrents to open trackers as well as trackers listed in the torrent"
" file"
msgstr "Ogłoś torrenty do otwartych trackerów jak również trackerów wymienionych w pliku torrenta"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2631
msgid "Enable DHT"
@ -1560,7 +1559,7 @@ msgstr[3] "{0} tuneli"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3121
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3428
msgid "Edit Torrent"
msgstr "Edytuj Torrent"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3131
msgid "Torrent file"
@ -1655,23 +1654,23 @@ msgstr "Wymuś ponowne sprawdzenie"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4205
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4544
msgid "Torrent must be stopped"
msgstr "Torrent musi zostać zatrzymany"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3425
msgid "Check integrity of the downloaded files"
msgstr "Sprawdź integralność dla pobranych plików"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3434
msgid "Add or remove trackers"
msgstr "Dodaj lub usuń trackery"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3444
msgid "Download files in order"
msgstr "Pobierz pliki w kolejności"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3445
msgid "Download pieces in order"
msgstr "Pobierz części w kolejności"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3452
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4047
@ -1714,7 +1713,7 @@ msgstr "Do katalogu nadrzędnego"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3637
msgid "Audio Playlist"
msgstr "Playlista Audio"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3669
msgid "Torrent not found?"
@ -1837,7 +1836,7 @@ msgstr "Tracker"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4273
msgid "Add Tracker"
msgstr "Dodaj Tracker"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4313
msgid "Save Changes"

View File

@ -20,8 +20,8 @@ msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:00+0000\n"
"Last-Translator: Manuela Silva <mmsrs@sky.com>, 2017-2018\n"
"PO-Revision-Date: 2022-02-09 19:23+0000\n"
"Last-Translator: hxdcmls\n"
"Language-Team: Portuguese (http://www.transifex.com/otf/I2P/language/pt/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -247,11 +247,11 @@ msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1326
msgid "Enabled Comments."
msgstr "Comentário Ativado."
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1328
msgid "Disabled Comments."
msgstr "Comentário Desativado."
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1341
#, java-format
@ -1123,7 +1123,7 @@ msgstr "restantes"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1891
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3277
msgid "Completed"
msgstr "Completado"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1929
msgid "Stop the torrent"
@ -1608,7 +1608,7 @@ msgstr "Restantes"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3375
msgid "Skipped"
msgstr "Ignorado"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3383
msgid "Files"
@ -1786,7 +1786,7 @@ msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4087
msgid "Add Comment"
msgstr "Adicionar Comentário"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4099
msgid "My Rating"

View File

@ -6,14 +6,14 @@
# Translators:
# testsubject67 <deborinha97@hotmail.com>, 2014
# Eduardo Rodrigues, 2020
# L., 2015-2016
# blueboy, 2015-2016
msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:00+0000\n"
"Last-Translator: Eduardo Rodrigues, 2020\n"
"PO-Revision-Date: 2022-02-09 19:23+0000\n"
"Last-Translator: blueboy\n"
"Language-Team: Portuguese (Brazil) (http://www.transifex.com/otf/I2P/language/pt_BR/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -23,7 +23,7 @@ msgstr ""
#: ../java/src/org/klomp/snark/IdleChecker.java:76
msgid "No more torrents running."
msgstr "Sem mais torrents em execução."
msgstr ""
#: ../java/src/org/klomp/snark/IdleChecker.java:77
#: ../java/src/org/klomp/snark/SnarkManager.java:3149
@ -35,7 +35,7 @@ msgstr "Túnel I2P fechado"
#: ../java/src/org/klomp/snark/MagnetURI.java:60
#: ../java/src/org/klomp/snark/SnarkManager.java:2788
msgid "Magnet"
msgstr "magnet"
msgstr ""
#: ../java/src/org/klomp/snark/Snark.java:595
#: ../java/src/org/klomp/snark/SnarkManager.java:355
@ -67,7 +67,7 @@ msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:146
msgid "vanilla"
msgstr "vanilla"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:997
#: ../java/src/org/klomp/snark/SnarkManager.java:1151
@ -77,14 +77,14 @@ msgstr "vanilla"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1242
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1350
msgid "No write permissions for data directory"
msgstr "Sem permissões de gravação para a diretoria de dados"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1000
#: ../java/src/org/klomp/snark/SnarkManager.java:1144
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:735
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1054
msgid "Data directory cannot be created"
msgstr "Não é possível criar a diretoria de dados"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1062
#, java-format
@ -114,33 +114,33 @@ msgstr "Atraso de inicialização alterada para {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:1101
#, java-format
msgid "Refresh time changed to {0}"
msgstr "Tempo de actualização alterado para {0}"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1103
msgid "Refresh disabled"
msgstr "Actualização desactivada"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1119
#, java-format
msgid "Page size changed to {0}"
msgstr "Tamanho de pagina alterado para {0}"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1129
msgid "New files will be publicly readable"
msgstr "Novos ficheiros serão lidos pelo publico"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1131
msgid "New files will not be publicly readable"
msgstr "Novos ficheiros não serão lidos pelo publico"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1139
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1050
msgid "Data directory must be an absolute path"
msgstr "Diretório de dados deve ter um caminho absoluto"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1143
msgid "Data directory does not exist"
msgstr "Diretório de dados não existe"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1146
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:737
@ -155,7 +155,7 @@ msgstr "Não legível"
#: ../java/src/org/klomp/snark/SnarkManager.java:1155
#, java-format
msgid "Data directory changed to {0}"
msgstr "Diretório de dados alterado para {0}"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1236
msgid "I2CP and tunnel changes will take effect after stopping all torrents"
@ -164,7 +164,7 @@ msgstr "Alterações em túneis e I2C entrarão em vigor depois de parar todos t
#: ../java/src/org/klomp/snark/SnarkManager.java:1240
#, java-format
msgid "I2CP options changed to {0}"
msgstr "opções de I2cp alteradas para {0}"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1246
msgid "Disconnecting old I2CP destination"
@ -219,15 +219,15 @@ msgstr "Trackers abertos não permitidos - reinício de torrents é preciso para
#: ../java/src/org/klomp/snark/SnarkManager.java:1306
msgid "Enabled DHT."
msgstr "Habilitar DHT."
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1308
msgid "Disabled DHT."
msgstr "Desabilitar DHT."
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1310
msgid "DHT change requires tunnel shutdown and reopen"
msgstr "Mudança no DHT requer fechamento e reabertura do túnel"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1317
msgid "Enabled Ratings."
@ -273,7 +273,7 @@ msgstr "Lista de trackers abertos alterada - reinício de torrents é preciso pa
#: ../java/src/org/klomp/snark/SnarkManager.java:1409
msgid "Private tracker list changed - affects newly created torrents only."
msgstr "Lista de rastreadores privados alterada - somente afetará os novos torrentes criados."
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1455
#, java-format
@ -307,7 +307,7 @@ msgstr "Erro: não é possível adicionar o torrent {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1131
#, java-format
msgid "Torrent already running: {0}"
msgstr "torrente já em marcha: {0}"
msgstr ""
#. catch this here so we don't try do delete it below
#: ../java/src/org/klomp/snark/SnarkManager.java:1624
@ -335,21 +335,21 @@ msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1655
#, java-format
msgid "ERROR - No I2P trackers in private torrent \"{0}\""
msgstr "ERRO - Não há tracker I2P no torrent privado \"{0}\""
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1657
#, java-format
msgid ""
"Warning - No I2P trackers in \"{0}\", will announce to I2P open trackers and"
" DHT only."
msgstr "Aviso - Nenhum rastreador I2P em \"{0}\", o anúncio será feito apenas por rastreadores I2P abertos e DHT."
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1660
#, java-format
msgid ""
"Warning - No I2P trackers in \"{0}\", and open trackers are disabled, will "
"announce to DHT only."
msgstr "Aviso - Nenhum rastreador I2P em \"{0}\", e rastreadores I2P abertos estão desabilitados. O anúncio será feito apenas por DHT."
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1662
#, java-format
@ -357,7 +357,7 @@ msgid ""
"Warning - No I2P trackers in \"{0}\", and DHT and open trackers are "
"disabled, you should enable open trackers or DHT before starting the "
"torrent."
msgstr "Aviso - Nenhum rastreador I2P em \"{0}\", e DHT e rastreadores abertos estão desabilitados. Rastreadores abertos ou DHT devem ser habilitados antes de começar o torrente."
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1688
#, java-format
@ -369,7 +369,7 @@ msgstr "O torrent em \"{0}\" é inválido"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1148
#, java-format
msgid "ERROR - Out of memory, cannot create torrent from {0}"
msgstr "ERRO - Não ha espaço suficente, não se pode crear um torrente desde {0}."
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1721
#: ../java/src/org/klomp/snark/SnarkManager.java:2567
@ -398,7 +398,7 @@ msgid ""
"Open trackers are disabled and we have no DHT peers. Fetch of {0} may not "
"succeed until you start another torrent, enable open trackers, or enable "
"DHT."
msgstr "Rastreadores abertos estão desabilitados e não há participantes DHT. Descarregamento de {0} pode não prosseguir enquanto outra torrente não for iniciada, rastreadores abertos forem habilitados ou DHT habilitado."
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1823
#, java-format
@ -408,7 +408,7 @@ msgstr "Adicionando {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:1856
#, java-format
msgid "Download already running: {0}"
msgstr "arquivo já descarregando: {0}"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1906
#: ../java/src/org/klomp/snark/SnarkManager.java:1916
@ -496,7 +496,7 @@ msgstr "Iniciando torrent {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:2617
#, java-format
msgid "Up bandwidth limit is {0} KBps"
msgstr "Limite de transmissão de dados é {0} KBps"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:2648
#: ../java/src/org/klomp/snark/SnarkManager.java:2654
@ -515,12 +515,12 @@ msgstr "I2PSnar"
#: ../java/src/org/klomp/snark/SnarkManager.java:2729
#, java-format
msgid "Error on torrent {0}"
msgstr "Erro no torrente {0}"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:3022
#: ../java/src/org/klomp/snark/web/FetchAndAdd.java:130
msgid "Opening the I2P tunnel"
msgstr "Abrindo o túnel I2P"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:3042
msgid "Opening the I2P tunnel and starting all torrents."
@ -532,7 +532,7 @@ msgstr "Parando todos os torrents e fechando o túnel I2P"
#: ../java/src/org/klomp/snark/SnarkManager.java:3134
msgid "Closing I2P tunnel after notifying trackers."
msgstr "Fechando túnel I2P após notificar os rastreadores."
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:3204
#, java-format
@ -552,7 +552,7 @@ msgstr ""
#: ../java/src/org/klomp/snark/TrackerClient.java:245
#, java-format
msgid "No valid trackers for {0} - enable opentrackers or DHT?"
msgstr "Nenhum rastreador válido para {0} - habilitar rastreadores abertos ou DHT?"
msgstr ""
#: ../java/src/org/klomp/snark/UpdateHandler.java:49
#: ../java/src/org/klomp/snark/UpdateRunner.java:233
@ -567,30 +567,30 @@ msgstr "Atualizando a partir de {0}"
#: ../java/src/org/klomp/snark/web/FetchAndAdd.java:80
#, java-format
msgid "Download torrent file from {0}"
msgstr "Descarregando arquivo torrente de {0}"
msgstr ""
#: ../java/src/org/klomp/snark/web/FetchAndAdd.java:103
#, java-format
msgid "Torrent was not retrieved from {0}"
msgstr "Não se pode obter torrente de {0}"
msgstr ""
#: ../java/src/org/klomp/snark/web/FetchAndAdd.java:157
#, java-format
msgid "Torrent fetched from {0}"
msgstr "torrente obtido de {0}"
msgstr ""
#: ../java/src/org/klomp/snark/web/FetchAndAdd.java:180
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1133
#, java-format
msgid "Torrent already in the queue: {0}"
msgstr "torrente já na cola: {0}"
msgstr ""
#: ../java/src/org/klomp/snark/web/FetchAndAdd.java:193
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1107
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1146
#, java-format
msgid "Torrent at {0} was not valid"
msgstr "torrente em {0} não foi válido"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:311
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2436
@ -615,7 +615,7 @@ msgstr "O roteador está fora do ar"
msgid ""
"Are you sure you want to delete the file \\''{0}\\'' (downloaded data will "
"not be deleted) ?"
msgstr "Tem a certeza que deseja apagar o ficheiro \\\"{0}\\\" (dados transferidos não serão apagados) ?"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:339
#, java-format
@ -634,11 +634,11 @@ msgstr "Recarregar página"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:384
msgid "Click \"Add torrent\" button to fetch torrent"
msgstr "Clique no botão \"Adicionar torrent\" para obter o torrent"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:448
msgid "clear messages"
msgstr "limpar mensagens"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:505
msgid "Status"
@ -724,7 +724,7 @@ msgstr "Uploaded"
#. Translators: Please keep short or translate as " "
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:647
msgid "RX Rate"
msgstr "Taxa de recepção"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:649
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:650
@ -734,7 +734,7 @@ msgstr "Taxa de down"
#. Translators: Please keep short or translate as " "
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:662
msgid "TX Rate"
msgstr "Taxa de transmissão"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:664
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:665
@ -751,7 +751,7 @@ msgstr "Parar todos"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:694
msgid "Start all stopped torrents"
msgstr "Iniciar todos os torrents interrompidos"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:696
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:710
@ -809,7 +809,7 @@ msgstr "Primeiro"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:916
msgid "First page"
msgstr "Primeira página"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:926
msgid "Prev"
@ -817,7 +817,7 @@ msgstr "Anterior"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:926
msgid "Previous page"
msgstr "Página anterior"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:959
msgid "Next"
@ -825,7 +825,7 @@ msgstr "Próximo"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:959
msgid "Next page"
msgstr "Próxima página"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:967
msgid "Last"
@ -833,7 +833,7 @@ msgstr "Último"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:967
msgid "Last page"
msgstr "Última página"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1064
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1376
@ -867,7 +867,7 @@ msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1228
#, java-format
msgid "Download deleted: {0}"
msgstr "Download excluído: {0}"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1254
#, java-format
@ -883,12 +883,12 @@ msgstr "Não foi possível apagar o arquivo de data: {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1283
#, java-format
msgid "Directory could not be deleted: {0}"
msgstr "Pasta não pôde ser excluída: {0}"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1291
#, java-format
msgid "Directory deleted: {0}"
msgstr "Pasta excluída: {0}"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1355
#, java-format
@ -912,11 +912,11 @@ msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1407
msgid "Error - Cannot include alternate trackers without a primary tracker"
msgstr "Erro - Impossível incluir rastreadores alternativos sem o rastreador primário"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1420
msgid "Error - Cannot mix private and public trackers in a torrent"
msgstr "Erro - Impossível misturar rastreadores públicos e privados num torrent"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1442
#, java-format
@ -947,12 +947,12 @@ msgstr "Erro ao criar torrent - é preciso entrar com um arquivo ou diretório"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1491
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2798
msgid "Delete selected"
msgstr "Apagar selecionados"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1491
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2800
msgid "Save tracker configuration"
msgstr "Salvar configurações do rastreador"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1508
msgid "Removed"
@ -963,35 +963,35 @@ msgstr "Removido"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2799
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4279
msgid "Add tracker"
msgstr "Adicionar tracker"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1563
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1566
msgid "Enter valid tracker name and URLs"
msgstr "Insira um nome válido para o tracker e URLs"
msgstr ""
#. "<input type=\"reset\" class=\"cancel\"
#. value=\"").append(_t("Cancel")).append("\">\n" +
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1568
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2802
msgid "Restore defaults"
msgstr "Voltar ao padrão"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1571
msgid "Restored default trackers"
msgstr "Voltar aos rastreadores padrão"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1684
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1685
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3404
msgid "Checking"
msgstr "Verificando"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1688
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1689
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3411
msgid "Allocating"
msgstr "Reservando espaço"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1704
msgid "Tracker Error"
@ -1105,12 +1105,12 @@ msgstr "Abrir arquivo"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1883
msgid "complete"
msgstr "completo"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1883
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3691
msgid "remaining"
msgstr "restantes"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1891
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3277
@ -1249,7 +1249,7 @@ msgstr "Criar torrent"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2359
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2728
msgid "Trackers"
msgstr "Rastreadores"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2361
msgid "Primary"
@ -1257,7 +1257,7 @@ msgstr "Primária"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2363
msgid "Alternates"
msgstr "Alternativos"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2365
msgid "Tracker Type"
@ -1293,7 +1293,7 @@ msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2448
msgid "Files readable by all"
msgstr "Ficheiro legível por todos"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2452
msgid ""
@ -1357,7 +1357,7 @@ msgstr "Configurar"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2536
msgid "Refresh time"
msgstr "Tempo de actualização"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2539
msgid "How frequently torrent status is updated on the main page"
@ -1413,15 +1413,15 @@ msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2614
msgid "Half available bandwidth recommended."
msgstr "Se recomenda a metade da largura de banda disponível."
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2617
msgid "View or change router bandwidth"
msgstr "mostrar e mudar as preferências da largura de banda do roteador"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2623
msgid "Use open trackers also"
msgstr "usar também rastreadores abertos"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2627
msgid ""
@ -1431,7 +1431,7 @@ msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2631
msgid "Enable DHT"
msgstr "Habilitar DHT"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2635
msgid "Use DHT to find additional peers"
@ -1463,11 +1463,11 @@ msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2672
msgid "Inbound Settings"
msgstr "Preferências de entrada"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2679
msgid "Outbound Settings"
msgstr "Preferências de saida"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2688
msgid "I2CP host"
@ -1483,7 +1483,7 @@ msgstr "opções I2CP"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2713
msgid "Save configuration"
msgstr "Guardar configuração"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2731
msgid "Select trackers for removal from I2PSnark's known list"
@ -1496,11 +1496,11 @@ msgstr "Nome"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2736
msgid "Website URL"
msgstr "URL do Website"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2744
msgid "Announce URL"
msgstr "URL para anúncio"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2756
msgid "Mark tracker for deletion"
@ -1513,7 +1513,7 @@ msgstr "Adicionar"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2835
#, java-format
msgid "Invalid magnet URL {0}"
msgstr "URL magnet {0} não válida"
msgstr ""
#. * dummies for translation
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2843
@ -1537,7 +1537,7 @@ msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3131
msgid "Torrent file"
msgstr "Arquivo torrente"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3139
msgid "Data location"
@ -1549,11 +1549,11 @@ msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3170
msgid "Primary Tracker"
msgstr "Rastreador Primário"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3189
msgid "Tracker List"
msgstr "Lista de Rastreadores"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3215
msgid "Web Seeds"
@ -1571,7 +1571,7 @@ msgstr "Criada"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3258
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4307
msgid "Created By"
msgstr "Criado por"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3268
msgid "Added"
@ -1583,15 +1583,15 @@ msgstr "Última atividade"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3302
msgid "Magnet link"
msgstr "URL magnet"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3317
msgid "Private torrent"
msgstr "Torrente privado"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3331
msgid "Completion"
msgstr "Finalização"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3366
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3604
@ -1608,11 +1608,11 @@ msgstr "Arquivos"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3389
msgid "Pieces"
msgstr "Peças"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3394
msgid "Piece size"
msgstr "Tamanho das peças"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3407
msgid "Refresh page for results"
@ -1683,7 +1683,7 @@ msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3626
msgid "Up to higher level directory"
msgstr "Subir uma herarquia"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3637
msgid "Audio Playlist"
@ -1691,11 +1691,11 @@ msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3669
msgid "Torrent not found?"
msgstr "Não achei o arquivo torrente?"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3675
msgid "File not found in torrent?"
msgstr "Arquivo não achado no torrente?"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3717
msgid "Preview"
@ -1739,7 +1739,7 @@ msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3806
msgid "Save priorities"
msgstr "Guardar prioridades"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4020
msgid "Ratings and Comments"
@ -1804,7 +1804,7 @@ msgstr "Apagar selecionado"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4238
msgid "Tracker"
msgstr "Rastreador"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4273
msgid "Add Tracker"

View File

@ -32,8 +32,8 @@ msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:00+0000\n"
"Last-Translator: ValdikSS <iam@valdikss.org.ru>, 2017-2021\n"
"PO-Revision-Date: 2022-02-09 19:23+0000\n"
"Last-Translator: Irina Fedulova <istartlin@gmail.com>\n"
"Language-Team: Russian (Russia) (http://www.transifex.com/otf/I2P/language/ru_RU/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -1852,4 +1852,4 @@ msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4313
msgid "Save Changes"
msgstr "Сохранить изменения"
msgstr ""

View File

@ -24,8 +24,8 @@ msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:00+0000\n"
"Last-Translator: Jonatan Nyberg <jonatan@autistici.org>, 2017,2021-2022\n"
"PO-Revision-Date: 2022-02-09 19:23+0000\n"
"Last-Translator: efef6ec5b435a041fce803c7f8af77d2_2341d43\n"
"Language-Team: Swedish (Sweden) (http://www.transifex.com/otf/I2P/language/sv_SE/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -55,7 +55,7 @@ msgstr "Magnet"
#: ../java/src/org/klomp/snark/SnarkManager.java:2572
#: ../java/src/org/klomp/snark/SnarkManager.java:2627
msgid "Unable to connect to I2P"
msgstr "Det går inte att ansluta till I2P"
msgstr ""
#: ../java/src/org/klomp/snark/Snark.java:597
#: ../java/src/org/klomp/snark/SnarkManager.java:1727
@ -1591,7 +1591,7 @@ msgstr "Tillagd"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3288
msgid "Last activity"
msgstr "Senaste aktivitet"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3302
msgid "Magnet link"
@ -1824,4 +1824,4 @@ msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4313
msgid "Save Changes"
msgstr "Spara ändringar"
msgstr ""

View File

@ -11,8 +11,8 @@ msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:00+0000\n"
"Last-Translator: Kaya Zeren <kayazeren@gmail.com>, 2015-2022\n"
"PO-Revision-Date: 2022-02-10 06:32+0000\n"
"Last-Translator: Kaya Zeren <kayazeren@gmail.com>\n"
"Language-Team: Turkish (Turkey) (http://www.transifex.com/otf/I2P/language/tr_TR/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -218,15 +218,15 @@ msgstr "Açık izleyiciler devre dışı bırakıldı - değişikliklerin etkili
#: ../java/src/org/klomp/snark/SnarkManager.java:1306
msgid "Enabled DHT."
msgstr "\"Dağıtılmış karma tablosu\" (DHT) etkinleştirildi."
msgstr "DHT etkinleştirildi."
#: ../java/src/org/klomp/snark/SnarkManager.java:1308
msgid "Disabled DHT."
msgstr "\"Dağıtılmış karma tablosu\" (DHT) devre dışı bırakıldı."
msgstr "DHT devre dışı bırakıldı."
#: ../java/src/org/klomp/snark/SnarkManager.java:1310
msgid "DHT change requires tunnel shutdown and reopen"
msgstr "\"Dağıtılmış karma tablosu\" (DHT) değişikliği için tünelin kapatılıp yeniden açılması gerekir."
msgstr "DHT değişikliği için tünelin kapatılıp yeniden açılması gerekir."
#: ../java/src/org/klomp/snark/SnarkManager.java:1317
msgid "Enabled Ratings."
@ -341,14 +341,14 @@ msgstr "HATA - \"{0}\" kişisel torrenti içinde herhangi bir I2P izleyicisi yok
msgid ""
"Warning - No I2P trackers in \"{0}\", will announce to I2P open trackers and"
" DHT only."
msgstr "Uyarı - \"{0}\" içinde herhangi bir I2P izleyici yok. Yalnızca I2P açık izleyicileri ve \"Dağıtılmış karma tablosu\" (DHT) üzerinde duyurulacak."
msgstr "Uyarı - \"{0}\" içinde herhangi bir I2P izleyici yok. Yalnızca I2P açık izleyicileri ve DHT üzerinde duyurulacak."
#: ../java/src/org/klomp/snark/SnarkManager.java:1660
#, java-format
msgid ""
"Warning - No I2P trackers in \"{0}\", and open trackers are disabled, will "
"announce to DHT only."
msgstr "Uyarı - \"{0}\" içinde herhangi bir I2P izleyici yok ve I2P açık izleyicileri devre dışı bırakılmış. Yalnızca \"Dağıtılmış karma tablosu\" (DHT) üzerinde duyurulacak."
msgstr "Uyarı - \"{0}\" içinde herhangi bir I2P izleyici yok ve I2P açık izleyicileri devre dışı bırakılmış. Yalnızca DHT üzerinde duyurulacak."
#: ../java/src/org/klomp/snark/SnarkManager.java:1662
#, java-format
@ -356,7 +356,7 @@ msgid ""
"Warning - No I2P trackers in \"{0}\", and DHT and open trackers are "
"disabled, you should enable open trackers or DHT before starting the "
"torrent."
msgstr "Uyarı - \"{0}\" içinde herhangi bir I2P izleyici yok. I2P açık izleyicileri ve \"Dağıtılmış karma tablosu\" (DHT) devre dışı bırakılmış. Torrenti başlatmadan önce açık izleyicileri ya da \"Dağıtılmış karma tablosu\" (DHT) özelliğini etkinleştirin."
msgstr "Uyarı - \"{0}\" içinde herhangi bir I2P izleyici yok. I2P açık izleyicileri ve DHT devre dışı bırakılmış. Torrenti başlatmadan önce açık izleyicileri ya da DHT özelliğini etkinleştirin."
#: ../java/src/org/klomp/snark/SnarkManager.java:1688
#, java-format
@ -397,7 +397,7 @@ msgid ""
"Open trackers are disabled and we have no DHT peers. Fetch of {0} may not "
"succeed until you start another torrent, enable open trackers, or enable "
"DHT."
msgstr "Açık izleyiciler devre dışı bırakılmış ve herhangi bir \"Dağıtılmış karma tablosu\" (DHT) eşi yok. Başka bir torrent başlatılana kadar {0} alınamayabilir. Açık izleyicileri ya da \"Dağıtılmış karma tablosu\" (DHT) özelliğini etkinleştirin."
msgstr "Açık izleyiciler devre dışı bırakılmış ve herhangi bir DHT eşi yok. Başka bir torrent başlatılana kadar {0} alınamayabilir. Açık izleyicileri ya da DHT özelliğini etkinleştirin."
#: ../java/src/org/klomp/snark/SnarkManager.java:1823
#, java-format
@ -551,7 +551,7 @@ msgstr "{0} torrenti denetlenirken bir sorun çıktı"
#: ../java/src/org/klomp/snark/TrackerClient.java:245
#, java-format
msgid "No valid trackers for {0} - enable opentrackers or DHT?"
msgstr "{0} için geçerli bir izleyici yok. Açık izleyiciler ya da \"Dağıtılmış karma tablosu\" (DHT) özelliği etkinleştirilsin mi?"
msgstr "{0} için geçerli bir izleyici yok. Açık izleyiciler ya da DHT özelliği etkinleştirilsin mi?"
#: ../java/src/org/klomp/snark/UpdateHandler.java:49
#: ../java/src/org/klomp/snark/UpdateRunner.java:233
@ -787,8 +787,8 @@ msgstr[1] "{0} eş bağlı"
#, java-format
msgid "1 DHT peer"
msgid_plural "{0} DHT peers"
msgstr[0] "1 \"Dağıtılmış karma tablosu\" (DHT)i"
msgstr[1] "{0} \"Dağıtılmış karma tablosu\" (DHT)i"
msgstr[0] "1 DHT eş"
msgstr[1] "{0} DHT eş"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:773
msgid "Dest"
@ -800,7 +800,7 @@ msgstr "Bu oturum için hedef (kimlik)"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:800
msgid "Dht Debug"
msgstr "\"Dağıtılmış karma tablosu\" (DHT) hata ayıklama"
msgstr "Dht hata ayıklama"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:916
msgid "First"
@ -1430,11 +1430,11 @@ msgstr "Bu seçenek etkinleştirildiğinde, torrentler torrent dosyasında liste
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2631
msgid "Enable DHT"
msgstr "\"Dağıtılmış karma tablosu\" (DHT) kullanılsın"
msgstr "DHT kullanılsın"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2635
msgid "Use DHT to find additional peers"
msgstr "Bu seçenek etkinleştirildiğinde, ek eşleri bulmak için \"Dağıtılmış karma tablosu\" (DHT) kullanılır"
msgstr "Bu seçenek etkinleştirildiğinde, ek eşleri bulmak için DHT kullanılır"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2639
msgid "Enable Ratings"
@ -1474,7 +1474,7 @@ msgstr "I2CP sunucusu"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2693
msgid "I2CP port"
msgstr "I2CP bağlantı noktası"
msgstr "I2CP kapı numarası"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2708
msgid "I2CP options"

View File

@ -14,8 +14,8 @@ msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:00+0000\n"
"Last-Translator: Greg Koval <gregjsmith@gmx.com>, 2020\n"
"PO-Revision-Date: 2022-02-09 19:23+0000\n"
"Last-Translator: madjong <madjong@i2pmail.org>\n"
"Language-Team: Ukrainian (Ukraine) (http://www.transifex.com/otf/I2P/language/uk_UA/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -1109,7 +1109,7 @@ msgstr "Деталі торрента"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1839
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4036
msgid "Comments"
msgstr "Коментарі"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1863
msgid "View files"
@ -1269,7 +1269,7 @@ msgstr "Трекери"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2361
msgid "Primary"
msgstr "Основний"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2363
msgid "Alternates"
@ -1512,7 +1512,7 @@ msgstr "Назва"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2736
msgid "Website URL"
msgstr "URL-адреса сайту"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2744
msgid "Announce URL"
@ -1599,7 +1599,7 @@ msgstr "Додано"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3288
msgid "Last activity"
msgstr "Остання активність"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3302
msgid "Magnet link"
@ -1620,7 +1620,7 @@ msgstr "Залишилось"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3375
msgid "Skipped"
msgstr "Пропущено"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3383
msgid "Files"
@ -1678,7 +1678,7 @@ msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3463
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3481
msgid "Resource"
msgstr "Джерело"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3464
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3482
@ -1800,7 +1800,7 @@ msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4087
msgid "Add Comment"
msgstr "Додати Коментар"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4099
msgid "My Rating"

View File

@ -6,22 +6,18 @@
# Translators:
# ducki2p <ducki2p@gmail.com>, 2011
# foo <foo@bar>, 2009
# Fosworn D4, 2022
# a478a116a491ba89a1cee347ebcf239b_fd74b84, 2022
# Narrator Z, 2022
# Scott Rhodes <starring169@gmail.com>, 2020-2022
# Tommy Lmath <l5h5t7@qq.com>, 2016
# walking <waling@mail.i2p>, 2013
# wwj402 <wwj402@gmail.com>, 2013
# YFdyh000 <yfdyh000@gmail.com>, 2014-2016
# 天空Blond, 2022
msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 19:13+0000\n"
"PO-Revision-Date: 2011-02-13 12:00+0000\n"
"Last-Translator: Scott Rhodes <starring169@gmail.com>, 2020-2022\n"
"PO-Revision-Date: 2022-02-10 03:00+0000\n"
"Last-Translator: Scott Rhodes <starring169@gmail.com>\n"
"Language-Team: Chinese (China) (http://www.transifex.com/otf/I2P/language/zh_CN/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -85,7 +81,7 @@ msgstr "香草白"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1242
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1350
msgid "No write permissions for data directory"
msgstr "没有对数据文件夹的写入权限。"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1000
#: ../java/src/org/klomp/snark/SnarkManager.java:1144
@ -256,20 +252,20 @@ msgstr "已禁用评论。"
#: ../java/src/org/klomp/snark/SnarkManager.java:1341
#, java-format
msgid "Comments name set to {0}."
msgstr "评论名设置为{0}。"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1348
#, java-format
msgid "{0} theme loaded."
msgstr "{0}主题已加载。"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1355
msgid "Collapsible panels enabled."
msgstr "可折叠面板已启用。"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1357
msgid "Collapsible panels disabled."
msgstr "可折叠面板已禁用。"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1367
msgid "Configuration unchanged."
@ -338,7 +334,7 @@ msgstr "具有相同Hash链接的种子已在下载中:{0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:1896
#, java-format
msgid "Torrent with the same data location is already running: {0}"
msgstr "具有相同数据地址的种子已在下载中:{0}"
msgstr ""
#: ../java/src/org/klomp/snark/SnarkManager.java:1655
#, java-format
@ -802,7 +798,7 @@ msgstr "目标"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:775
msgid "Our destination (identity) for this session"
msgstr "本次会话的目标(路由器身份)"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:800
msgid "Dht Debug"
@ -850,12 +846,12 @@ msgstr "无法添加内含另一个种子的种子 {0}{1}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1082
#, java-format
msgid "Download from non-I2P location {0} is not supported"
msgstr "不支持从非 I2P 地址{0}下载"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1153
#, java-format
msgid "Invalid URL: Must start with \"{0}\" or \"{1}\""
msgstr "无效的 URL必须以“{0}”或“{1}”开头。"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1195
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1230
@ -867,7 +863,7 @@ msgstr "Magnet 已删除:{0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1243
#, java-format
msgid "Torrent file could not be deleted: {0}"
msgstr "无法删除种子文件:{0}"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1228
#, java-format
@ -1028,7 +1024,7 @@ msgstr "正做种"
#, java-format
msgid "Seeding to {0} peer"
msgid_plural "Seeding to {0} peers"
msgstr[0] "正在与用户{0}做种"
msgstr[0] ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1731
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1747
@ -1041,7 +1037,7 @@ msgstr "完成"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1752
#, java-format
msgid "Downloading from {0} of {1} peers in swarm"
msgstr "从{1}个对等节点中的{0}个下载"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1752
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1753
@ -1054,13 +1050,13 @@ msgstr "正常"
#, java-format
msgid "Downloading from {0} peer"
msgid_plural "Downloading from {0} peers"
msgstr[0] "正在从节点{0}下载"
msgstr[0] ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1763
#, java-format
msgid "Connected to {0} peer"
msgid_plural "Connected to {0} peers"
msgstr[0] "已连接到节点{0}"
msgstr[0] ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1763
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1764
@ -1073,7 +1069,7 @@ msgstr "等待"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1774
#, java-format
msgid "Connected to {0} of {1} peers in swarm"
msgstr "已连接到{1}对等节点中的{0}个"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1774
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1775
@ -1146,7 +1142,7 @@ msgstr "移除"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1978
msgid "Delete the .torrent file and the associated data files"
msgstr "删除种子及所下载的文件"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1982
msgid "Delete"
@ -1154,7 +1150,7 @@ msgstr "删除"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1998
msgid "Peer attached to swarm"
msgstr "附属于集群的节点"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2028
msgid "Unknown"
@ -1162,7 +1158,7 @@ msgstr "未知"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2030
msgid "Destination (identity) of peer"
msgstr "对等节点的目的地(身份)。"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2046
msgid "Seed"
@ -1204,7 +1200,7 @@ msgstr "从URL"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2315
msgid ""
"Enter the torrent file download URL (I2P only), magnet link, or info hash"
msgstr "输入种子文件的下载链接(仅支持 I2P magnet 链接,或信息散列值"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2320
msgid "Add torrent"
@ -1290,7 +1286,7 @@ msgstr "数据文件夹"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2443
msgid "Directory where torrents and downloaded/shared files are stored"
msgstr " 种子和下载/分享的文件存储目录"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2448
msgid "Files readable by all"
@ -1300,7 +1296,7 @@ msgstr "文件对所有人可读"
msgid ""
"Set file permissions to allow other local users to access the downloaded "
"files"
msgstr "给其他本地用户设置文件权限使其能够访问已下载文件"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2456
msgid "Auto start torrents"
@ -1310,7 +1306,7 @@ msgstr "自动开始种子"
msgid ""
"Automatically start torrents when added and restart torrents when I2PSnark "
"starts"
msgstr "当种子被添加时自动启动并且在 I2PSnark 启动时自动重启种子"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2464
msgid "Smart torrent sorting"
@ -1318,21 +1314,21 @@ msgstr "智能种子排序"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2468
msgid "Ignore words such as 'a' and 'the' when sorting"
msgstr "排序时忽略诸如 athe 的单词"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2472
msgid "Collapsible panels"
msgstr "可折叠面板"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2477
msgid "Your browser does not support this feature."
msgstr "您的浏览器不支持这个功能。"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2480
msgid ""
"Allow the 'Add Torrent' and 'Create Torrent' panels to be collapsed, and "
"collapse by default in non-embedded mode"
msgstr "允许‘添加种子’和‘创建种子’面板被折叠,并且在非嵌入模式下默认折叠。"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2492
msgid "Language"
@ -1344,11 +1340,11 @@ msgstr "主题"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2507
msgid "To change themes manually, disable universal theming"
msgstr "要手动更改主题,请禁用通用主题"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2511
msgid "Universal theming is enabled."
msgstr "通用主题已开启。"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2513
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2619
@ -1362,7 +1358,7 @@ msgstr "刷新时间"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2539
msgid "How frequently torrent status is updated on the main page"
msgstr "主页面上下载状态的更新频率"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2552
msgid "Never"
@ -1374,7 +1370,7 @@ msgstr "启动延迟"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2562
msgid "How long before auto-started torrents are loaded when I2PSnark starts"
msgstr "当I2PSnark启动时在多长时间内加载自动启动的种子"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2564
msgid "minutes"
@ -1386,7 +1382,7 @@ msgstr "页面容量"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2572
msgid "Maximum number of torrents to display per page"
msgstr "每页显示的最大种子数量"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2574
msgid "torrents"
@ -1398,7 +1394,7 @@ msgstr "限制总上传种子数为"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2602
msgid "Maximum number of peers for uploading"
msgstr "同时上传的对等节点数量最大值"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2604
msgid "peers"
@ -1410,7 +1406,7 @@ msgstr "上传带宽限制"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2612
msgid "Maximum bandwidth allocated for uploading"
msgstr "用于上传的最大带宽限制"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2614
msgid "Half available bandwidth recommended."
@ -1428,7 +1424,7 @@ msgstr "同时使用OpenTracker"
msgid ""
"Announce torrents to open trackers as well as trackers listed in the torrent"
" file"
msgstr "选择后在OpenTracker及种子文件中的Tracker上同时发布。"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2631
msgid "Enable DHT"
@ -1436,7 +1432,7 @@ msgstr "启用 DHT"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2635
msgid "Use DHT to find additional peers"
msgstr "使用分布式哈希表发现其他节点"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2639
msgid "Enable Ratings"
@ -1444,7 +1440,7 @@ msgstr "启用评分"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2643
msgid "Show ratings on torrent pages"
msgstr "在种子页面显示评级"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2647
msgid "Enable Comments"
@ -1452,15 +1448,15 @@ msgstr "启用评论"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2651
msgid "Show comments on torrent pages"
msgstr "在种子页面显示评论"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2653
msgid "Comment Author"
msgstr "评论作者"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2656
msgid "Set the author name for your comments and ratings"
msgstr "为你的评论和评级设置作者名称"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2672
msgid "Inbound Settings"
@ -1488,7 +1484,7 @@ msgstr "保存设置"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2731
msgid "Select trackers for removal from I2PSnark's known list"
msgstr "选择从I2PSnark已知列表中移除的Tracker"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2734
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3576
@ -1505,7 +1501,7 @@ msgstr "发布 URL"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2756
msgid "Mark tracker for deletion"
msgstr "标记Tracker为删除"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2788
msgid "Add"
@ -1532,7 +1528,7 @@ msgstr[0] "{0}隧道"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3121
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3428
msgid "Edit Torrent"
msgstr "编辑种子"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3131
msgid "Torrent file"
@ -1627,32 +1623,32 @@ msgstr "强制重新检查"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4205
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4544
msgid "Torrent must be stopped"
msgstr "种子必须停止"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3425
msgid "Check integrity of the downloaded files"
msgstr "检查已下载文件的完整性"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3434
msgid "Add or remove trackers"
msgstr "增加或移除Tracker"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3444
msgid "Download files in order"
msgstr "按顺序下载文件"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3445
msgid "Download pieces in order"
msgstr "按顺序下载分片"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3452
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4047
msgid "Save Preference"
msgstr "保存偏好"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3462
msgid "Resource Not found"
msgstr "找不到资源"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3463
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3481
@ -1666,7 +1662,7 @@ msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3480
msgid "Resource Does Not Exist"
msgstr "资源不存在"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3556
msgid "Directory"
@ -1674,11 +1670,11 @@ msgstr "文件夹"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3602
msgid "Download Status"
msgstr "下载状态"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3614
msgid "Download Priority"
msgstr "下载优先级"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3626
msgid "Up to higher level directory"
@ -1686,7 +1682,7 @@ msgstr "上一层文件夹"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3637
msgid "Audio Playlist"
msgstr "音频播放列表"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3669
msgid "Torrent not found?"
@ -1702,7 +1698,7 @@ msgstr "预览"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3768
msgid "Download file at high priority"
msgstr "以高优先级下载文件"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3773
msgid "High"
@ -1710,7 +1706,7 @@ msgstr "高"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3776
msgid "Download file at normal priority"
msgstr "以普通优先级下载文件"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3781
msgid "Normal"
@ -1718,7 +1714,7 @@ msgstr "普通"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3783
msgid "Do not download this file"
msgstr "不要下载这个文件"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:3788
msgid "Skip"
@ -1742,37 +1738,37 @@ msgstr "保存优先级"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4020
msgid "Ratings and Comments"
msgstr "评级和评价"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4023
msgid "Author name required to rate or comment"
msgstr "评级或评论要求作者名字"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4029
msgid "Your author name for published comments and ratings"
msgstr "您发布评论与评级时的作者名字"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4043
msgid "Enable viewing and posting comments for this torrent"
msgstr "为此种子启用浏览和发布评论"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4066
#, java-format
msgid "1 star"
msgid_plural "{0} stars"
msgstr[0] "{0}个星星"
msgstr[0] ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4068
msgid "No rating"
msgstr "暂无评级"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4083
msgid "Rate and Comment"
msgstr "评级和评论"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4085
msgid "Rate Torrent"
msgstr "评价种子"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4087
msgid "Add Comment"
@ -1780,16 +1776,16 @@ msgstr "添加评论"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4099
msgid "My Rating"
msgstr "我的评级"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4112
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4116
msgid "Average Rating"
msgstr "平均评级"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4117
msgid "No community ratings currently available"
msgstr "暂无可用的社区评级"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4165
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4251
@ -1806,7 +1802,7 @@ msgstr "Tracker"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4273
msgid "Add Tracker"
msgstr "增加Tracker"
msgstr ""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:4313
msgid "Save Changes"

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,6 @@
To run i2psnark's standalone mode make sure you have an i2p router running in the background, then run:
launch-i2psnark
or
launch-i2psnark.bat (Windows)
java -jar i2psnark.jar
I2PSnark web ui will be at http://127.0.0.1:8002/i2psnark/

View File

@ -1,35 +0,0 @@
/* @license http://creativecommons.org/publicdomain/zero/1.0/legalcode CC0-1.0 */
// This component is dedicated to the public domain. It uses the CC0
// as a formal dedication to the public domain and in circumstances where
// a public domain is not usable.
var oldTheme = "ubergine";
var change = false;
function swapStyleSheet(theme) {
// https://stackoverflow.com/questions/14292997/changing-style-sheet-javascript
document.getElementById("pagestyle").setAttribute("href", "/i2psnark/.resources/themes/" + theme + "/snark.css");
}
function initThemeSwitcher() {
var theme = document.getElementById("theme");
if (theme == null) {
return;
}
oldtheme = theme.value;
theme.onclick = function() {
if (change) {
swapStyleSheet(theme.value);
} else {
// skip the first click to avoid the flash
change = true;
}
}
}
document.addEventListener("DOMContentLoaded", function() {
initThemeSwitcher();
}, true);
/* @license-end */

View File

@ -4,60 +4,16 @@
// as a formal dedication to the public domain and in circumstances where
// a public domain is not usable.
/**
* Use the refresh delay set in head
*/
function requestAjax1() {
requestAjax2(ajaxDelay);
}
/**
* Use the refresh delay specified
*
* @param refreshtime do not refresh if less than or equal to 0
* @since 0.9.58
*/
function requestAjax2(refreshtime) {
var url = ".ajax/xhr1.html";
var query = window.location.search;
var box = document.getElementById("searchbox");
if (box != null) {
// put in, remove, or replace value from search form
var search = box.value;
if (search.length > 0) {
if (query == null) {
query = "";
}
var q = new URLSearchParams(query);
q.set("nf_s", encodeURIComponent(search));
query = "?" + q.toString();
} else {
if (query != null) {
var q = new URLSearchParams(query);
q.delete("nf_s");
var newq = q.toString();
if (newq != null && newq.length > 0) {
query = "?" + newq;
} else {
query = null;
}
}
}
}
if (query)
url += query;
// tell ajax not to setTimeout(), and do our own
// setTimeout() so we update the URL every time
ajax(url, "mainsection", -1);
if (refreshtime > 0) {
setTimeout(requestAjax1, refreshtime);
}
ajax(url, "mainsection", ajaxDelay);
}
function initAjax() {
if (ajaxDelay > 0) {
setTimeout(requestAjax1, ajaxDelay);
}
setTimeout(requestAjax1, ajaxDelay);
}
document.addEventListener("DOMContentLoaded", function() {

View File

@ -1,47 +0,0 @@
/* @license http://www.gnu.org/licenses/gpl-2.0.html GPL-2.0 */
/* see also licenses/LICENSE-GPLv2.txt */
/**
* Search form helpers
*
* @since 0.9.58
*/
function initSearch()
{
var sch = document.getElementById("search");
if (sch != null) {
var box = document.getElementById("searchbox");
var cxl = document.getElementById("searchcancel");
cxl.addEventListener("click", function(event) {
if (box.value !== "") {
box.value = "";
requestAjax2(-1);
}
cxl.classList.add("disabled");
event.preventDefault();
});
box.addEventListener("input", function(event) {
if (box.value !== "") {
cxl.classList.remove("disabled");
} else {
cxl.classList.add("disabled");
}
requestAjax2(-1);
});
if (box.value !== "") {
cxl.classList.remove("disabled");
} else {
cxl.classList.add("disabled");
}
// so we don't get the link popup
cxl.removeAttribute("href");
}
}
document.addEventListener("DOMContentLoaded", function() {
initSearch();
}, true);
/* @license-end */

View File

@ -224,36 +224,6 @@ _:-ms-lang(x), .snarknavbar {
margin-top: 0 !important;
}
#search {
display: inline-block;
position: absolute;
top: 16px;
right: 9px;
}
#searchbox {
background: #000 url(/themes/console/images/buttons/search.png) 7px center no-repeat !important;
margin: 2px 4px 2px 24px !important;
padding: 4px 32px 4px 32px !important;
color: #bb7;
}
#searchbox:focus, #searchbox:active {
color: #ee9;
}
#searchcancel {
background: url(images/delete.png) 0px center no-repeat;
margin: 2px 4px 2px -20px;
padding: 0px 6px;
color: transparent;
border: none;
}
#searchcancel.disabled {
display: none;
}
/* end topnav */
/* screenlog */
@ -328,7 +298,7 @@ _:-ms-lang(x), .snarkMessages {
.snarkMessages img {
float: right;
margin: -4px 8px 4px 4px;
margin: -4px -5px 4px 4px;
opacity: 0.7;
border: 1px solid #433e47;
border-right: 0 none;
@ -2294,23 +2264,12 @@ hr.debug:last-child {
}
.accept {
background: url(/i2psnark/.resources/icons/solid/tick.png) left 6px center no-repeat !important;
background: url(/i2psnark/.resources/icons/solid/yes.png) left 6px center no-repeat !important;
background-size: 12px 12px !important;
}
input.reload {
background: url(../ubergine/images/restore.png) left 6px center no-repeat;
background-size: 12px 12px;
}
input.reload[name="recheck"] {
background: url(../ubergine/images/recheck.png) left 6px center no-repeat;
background-size: 12px 12px;
}
input.create {
background: url(images/create.png) left 6px center no-repeat;
background-size: 12px 12px;
padding: 5px 10px 5px 10px !important;
}
input.starttorrent {

View File

@ -229,36 +229,6 @@ button::-moz-focus-inner, input::-moz-focus-inner {
background: #f60 url(images/button_tracker_active.png) 8px center no-repeat;
}
#search {
display: inline-block;
position: absolute;
top: 10px;
right: 6px;
}
#searchbox {
background: #f8f8ff url(/themes/console/images/buttons/search.png) 7px center no-repeat !important;
margin: 2px 4px 2px 24px !important;
padding: 4px 32px 4px 32px !important;
color: #47475f;
}
#searchbox:focus, #searchbox:active {
color: #19191f;
}
#searchcancel {
background: url(images/delete.png) 0px center no-repeat;
margin: 2px 4px 2px 4px;
padding: 0px 6px;
color: transparent;
border: none;
}
#searchcancel.disabled {
display: none;
}
/* end top nav */
/* screenlog */
@ -329,7 +299,7 @@ button::-moz-focus-inner, input::-moz-focus-inner {
.snarkMessages img {
float: right;
margin: -4px 8px 4px 4px;
margin: -4px -5px 4px 4px;
opacity: 1;
position: sticky;
top: -4px;
@ -1998,7 +1968,7 @@ hr.debug:last-child {
}
.accept {
background: url(/i2psnark/.resources/icons/solid/tick.png) left 6px center no-repeat;
background: url(/i2psnark/.resources/icons/solid/yes.png) left 6px center no-repeat;
background-size: 12px 12px;
}
@ -2008,18 +1978,7 @@ input.starttorrent {
}
input.reload {
background: url(../vanilla/images/restore.png) left 6px center no-repeat;
background-size: 12px 12px;
}
input.reload[name="recheck"] {
background: url(../vanilla/images/recheck.png) left 6px center no-repeat;
background-size: 12px 12px;
}
input.create {
background: url(images/create.png) left 6px center no-repeat;
background-size: 12px 12px;
padding: 5px 8px 5px 8px !important;
}
/* end priorities */

View File

@ -229,37 +229,6 @@ _:-ms-lang(x), .snarkNav:last-child[href="/i2psnark/"] {
border-radius: 2px 0 0 2px;
}
#search {
display: inline-block;
position: absolute;
top: 6px;
right: 3px;
}
#searchbox {
background: #212 url(/themes/console/images/buttons/search.png) 7px center no-repeat !important;
margin: 2px 4px 2px 24px !important;
padding: 4px 32px 4px 32px !important;
color: #f60;
}
#searchbox:focus, #searchbox:active {
background: #f60 url(/themes/console/images/buttons/search.png) 7px center no-repeat !important;
color: #fff;
}
#searchcancel {
background: url(images/cancel.png) no-repeat;
margin: 2px 4px 2px -28px;
padding: 0px 12px;
color: transparent;
border: none;
}
#searchcancel.disabled {
display: none;
}
/* end topnav */
/* screenlogger */
@ -339,7 +308,7 @@ _:-ms-lang(x), .snarkNav:last-child[href="/i2psnark/"] {
.snarkMessages img {
float: right;
margin: -3px 8px 4px 4px;
margin: -3px -5px 4px 4px;
opacity: 0.8;
position: sticky;
top: -3px;
@ -1698,12 +1667,6 @@ input.reload[name="recheck"], input.reload[name="recheck"]:active, input.disable
margin-left: 2px !important
}
input.disabled[name="showEdit"] {
background: #989 url(images/restore.png);
background: url(images/restore.png), linear-gradient(to bottom, #989 0%, #878 100%);
margin-left: 2px !important
}
input.disabled[name="recheck"]:hover {
background-blend-mode: initial;
}

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