forked from I2P_Developers/i2p.i2p
Compare commits
1 Commits
i2p-2.2.1
...
i2p-jpacka
Author | SHA1 | Date | |
---|---|---|---|
fadf25dc8f |
@ -29,4 +29,3 @@ installer/build
|
||||
router/java/build
|
||||
router/build
|
||||
|
||||
override.properties
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -61,5 +61,3 @@ sloccount.sc
|
||||
|
||||
# TODO: why does this file appear?
|
||||
apps/routerconsole/jsp/favicon.ico
|
||||
.tx
|
||||
/*.sh
|
@ -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:
|
||||
|
23
.tx/config
23
.tx/config
@ -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
|
||||
|
33
Docker.md
33
Docker.md
@ -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
|
||||
```
|
||||
|
||||
|
17
Dockerfile
17
Dockerfile
@ -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"]
|
||||
|
@ -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
14
apps/BOB/bob.config
Normal 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
12
apps/BOB/build.gradle
Normal 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
115
apps/BOB/build.xml
Normal 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
3
apps/BOB/manifest.mf
Normal file
@ -0,0 +1,3 @@
|
||||
Manifest-Version: 1.0
|
||||
X-COMMENT: Main-Class will be added automatically by build
|
||||
|
643
apps/BOB/nbproject/build-impl.xml
Normal file
643
apps/BOB/nbproject/build-impl.xml
Normal 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 "${ant.java.version}"/>
|
||||
<condition property="have-jdk-older-than-1.4">
|
||||
<or>
|
||||
<contains string="${version-output}" substring="java version "1.0"/>
|
||||
<contains string="${version-output}" substring="java version "1.1"/>
|
||||
<contains string="${version-output}" substring="java version "1.2"/>
|
||||
<contains string="${version-output}" substring="java version "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>
|
8
apps/BOB/nbproject/genfiles.properties
Normal file
8
apps/BOB/nbproject/genfiles.properties
Normal 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
|
84
apps/BOB/nbproject/project.properties
Normal file
84
apps/BOB/nbproject/project.properties
Normal 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
|
16
apps/BOB/nbproject/project.xml
Normal file
16
apps/BOB/nbproject/project.xml
Normal 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>
|
542
apps/BOB/src/net/i2p/BOB/BOB.java
Normal file
542
apps/BOB/src/net/i2p/BOB/BOB.java
Normal 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
|
||||
}
|
996
apps/BOB/src/net/i2p/BOB/DoCMDS.java
Normal file
996
apps/BOB/src/net/i2p/BOB/DoCMDS.java
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
99
apps/BOB/src/net/i2p/BOB/I2Plistener.java
Normal file
99
apps/BOB/src/net/i2p/BOB/I2Plistener.java
Normal 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");
|
||||
}
|
||||
}
|
||||
}
|
169
apps/BOB/src/net/i2p/BOB/I2PtoTCP.java
Normal file
169
apps/BOB/src/net/i2p/BOB/I2PtoTCP.java
Normal 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->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");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
46
apps/BOB/src/net/i2p/BOB/Lifted.java
Normal file
46
apps/BOB/src/net/i2p/BOB/Lifted.java
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
44
apps/BOB/src/net/i2p/BOB/Logger.java
Normal file
44
apps/BOB/src/net/i2p/BOB/Logger.java
Normal 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);
|
||||
}
|
||||
}
|
416
apps/BOB/src/net/i2p/BOB/MUXlisten.java
Normal file
416
apps/BOB/src/net/i2p/BOB/MUXlisten.java
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
39
apps/BOB/src/net/i2p/BOB/Main.java
Normal file
39
apps/BOB/src/net/i2p/BOB/Main.java
Normal 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();
|
||||
}
|
||||
}
|
106
apps/BOB/src/net/i2p/BOB/NamedDB.java
Normal file
106
apps/BOB/src/net/i2p/BOB/NamedDB.java
Normal 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();
|
||||
}
|
||||
}
|
121
apps/BOB/src/net/i2p/BOB/TCPio.java
Normal file
121
apps/BOB/src/net/i2p/BOB/TCPio.java
Normal 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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
95
apps/BOB/src/net/i2p/BOB/TCPlistener.java
Normal file
95
apps/BOB/src/net/i2p/BOB/TCPlistener.java
Normal 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.");
|
||||
}
|
||||
}
|
||||
}
|
222
apps/BOB/src/net/i2p/BOB/TCPtoI2P.java
Normal file
222
apps/BOB/src/net/i2p/BOB/TCPtoI2P.java
Normal 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->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.");
|
||||
}
|
||||
}
|
140
apps/BOB/src/net/i2p/BOB/UDPIOthread.java
Normal file
140
apps/BOB/src/net/i2p/BOB/UDPIOthread.java
Normal 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;
|
||||
}
|
||||
}
|
21
apps/BOB/src/net/i2p/BOB/license-WTFPL.txt
Normal file
21
apps/BOB/src/net/i2p/BOB/license-WTFPL.txt
Normal 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.
|
5
apps/BOB/src/net/i2p/BOB/package.html
Normal file
5
apps/BOB/src/net/i2p/BOB/package.html
Normal 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>
|
@ -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="," />
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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(", ");
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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"
|
||||
|
@ -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ü"
|
||||
|
@ -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 ""
|
||||
|
@ -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ú"
|
||||
|
@ -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ú"
|
||||
|
@ -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 d’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 "Configurer la zone de notification d’I2P"
|
||||
|
||||
#: 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 d’I2P"
|
||||
|
||||
#: 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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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:右鍵開啟選單"
|
||||
|
@ -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
|
||||
}
|
@ -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() {}
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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" >
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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" />
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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)));
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -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) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 },
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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("&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("&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 + " <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\" >";
|
||||
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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
@ -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"
|
||||
|
@ -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
@ -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"
|
||||
|
@ -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 ""
|
||||
|
@ -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 l’inté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"
|
||||
|
@ -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 ""
|
||||
|
@ -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"
|
||||
|
@ -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 ""
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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 ""
|
||||
|
@ -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 ""
|
||||
|
@ -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) eşi"
|
||||
msgstr[1] "{0} \"Dağıtılmış karma tablosu\" (DHT) eş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"
|
||||
|
@ -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"
|
||||
|
@ -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 "排序时忽略诸如 ‘a’ 和 ‘the’ 的单词"
|
||||
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
@ -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/
|
||||
|
||||
|
@ -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 */
|
@ -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() {
|
||||
|
@ -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 */
|
@ -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 {
|
||||
|
@ -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 */
|
||||
|
@ -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
Reference in New Issue
Block a user