forked from I2P_Developers/i2p.i2p
Compare commits
336 Commits
i2p-0.9.26
...
i2p-0.9.29
| Author | SHA1 | Date | |
|---|---|---|---|
| 61e4e2a052 | |||
| b695293070 | |||
| c09bfa0a26 | |||
| f420a99b6f | |||
| 33b1851317 | |||
| 3c735eaf96 | |||
| 3f452c5acb | |||
| 380f55a0e8 | |||
| 8a89b3da29 | |||
| f2ae1bfe09 | |||
| 17b781c1b4 | |||
| 68fb3f42a8 | |||
| fc8c193f37 | |||
| c949d776be | |||
| e29e3e2fd3 | |||
| e01c443fa2 | |||
| 2d8f0c2956 | |||
| f0241d4a1c | |||
| a11bd7cbe7 | |||
| 36ec4de9c7 | |||
| 843b66d61e | |||
| afb87cd75c | |||
| aa098ac800 | |||
| bbbbfe2417 | |||
| 9ab55ec368 | |||
| a85546534e | |||
| 83c786a5fd | |||
| 50d735b126 | |||
| da893452ea | |||
| 6306799a4b | |||
| 82d812c25c | |||
| 890ad257e1 | |||
| 7cb5dab67f | |||
| 1cf6030646 | |||
| 36fd93da0d | |||
| 5483306d21 | |||
| 1f228a3f85 | |||
| 12cc7b3a3b | |||
| 61fd242938 | |||
| 78da3b9785 | |||
| e0e06d73eb | |||
| 112fa503e6 | |||
| 9dab3b0dfe | |||
| 82064760d5 | |||
| bd1354f95b | |||
| fb74f41692 | |||
| 5db89d8743 | |||
| b970912cc1 | |||
| d196047382 | |||
| eefb36cb99 | |||
| dc5bfb224d | |||
| e461e8fb4f | |||
| 8bb114e9c4 | |||
| f77fc52ca7 | |||
| d9c6360e0a | |||
| 8137661751 | |||
| e47c628891 | |||
| 7b0a5bcd5a | |||
| 6e7dedba81 | |||
| 83e356140d | |||
| b66c7802e7 | |||
| 7311cf33b7 | |||
| 60c93f1e1c | |||
| a36083ab18 | |||
| 7cae467b59 | |||
| 2df64cd098 | |||
|
|
5dd6f2d06b | ||
|
|
7f9a211242 | ||
| ca440a50fe | |||
| fc0ddb0193 | |||
| f0e6baad27 | |||
| 6ad4cb0928 | |||
| 91163948b5 | |||
| e16cf2ce51 | |||
| 307a03f0ed | |||
| b63d44b226 | |||
| 57be0df858 | |||
| 6843950bdc | |||
| 134cbd46e4 | |||
|
|
91007735a1 | ||
|
|
14ca463499 | ||
| a7492269fb | |||
| 074c630ac6 | |||
| f902a63144 | |||
| ffcd2d4517 | |||
| dd400bb14b | |||
| 63a2a6da08 | |||
| 3846e08e68 | |||
| e625e67b5d | |||
| 0819857b86 | |||
| fbbfd8acf0 | |||
| 95fb2df609 | |||
| c1baee64d3 | |||
| ce47d4ea68 | |||
| 14a839ebba | |||
| 636badcec2 | |||
| 6093f26fb6 | |||
| 4615fce28e | |||
| 328f544de1 | |||
| 0c76201bd9 | |||
| 0a1cd20585 | |||
| 26a9e8bd89 | |||
| f5e8220c8b | |||
| b7c7e02518 | |||
| 7eadc3df6f | |||
| 2f3f01c5c7 | |||
| 5d7546598e | |||
| 434e3badd6 | |||
| 541e9e6dc0 | |||
| 8a3a725730 | |||
| 74cd5cee20 | |||
| b78b3cb942 | |||
| 62b5b49b02 | |||
| 7734d3dd65 | |||
| 27724a809f | |||
| 1d6fc40d59 | |||
| 176ecaa9f1 | |||
| 42efed578a | |||
| f461d4881d | |||
| 5be077e25d | |||
| 5b31540fe8 | |||
| ec94a6eca3 | |||
| 04321e6af3 | |||
| 25fd488db0 | |||
| 850f1504f7 | |||
| 2318a2b319 | |||
| 8d494ad162 | |||
| 5a87c232ea | |||
| f6778c573a | |||
| ffb3a75813 | |||
| e3435dce10 | |||
| 497d08845c | |||
| cc6cd9e402 | |||
| 64f5fed05a | |||
| 1d280156a2 | |||
| 08f7e5d6a8 | |||
| b72b768945 | |||
| 89733251d4 | |||
| 8146f6fdb6 | |||
| 625e992c91 | |||
| 62064da081 | |||
| 86c0fe327b | |||
| bbb921806e | |||
| fdff5ecd43 | |||
| 97af7d0622 | |||
|
|
11579b9818 | ||
|
|
01cfb7b241 | ||
| b0bba18f33 | |||
| 70902bd279 | |||
| cd4d5a39bf | |||
| 7a1a1d5b93 | |||
| 66c2664b91 | |||
| 68e5fd6d08 | |||
| 37d3204e43 | |||
| 784566a7cb | |||
| 126850626c | |||
| 42cbc1e9ac | |||
| 1a46d9373d | |||
| cd5d5ee23d | |||
| 16a551f7ce | |||
| 75d599e061 | |||
| efd953f3d4 | |||
| 3ac8e5f54f | |||
| 0108c1c290 | |||
| a8976d25e3 | |||
| 6a72c2957b | |||
| f69c0998ea | |||
| 35548ff9be | |||
| 6ed329db78 | |||
| 2c65173bec | |||
| 6acc23af00 | |||
| d7a84c88cd | |||
| aeeee0e5c4 | |||
| c3181d8561 | |||
| 24ecc858f1 | |||
| e5bcfe4207 | |||
| e614b0996d | |||
| b559b412aa | |||
| cd775fa38d | |||
| ab064fd31e | |||
| 08062aaf64 | |||
|
|
e74479317d | ||
| c9c29520b4 | |||
| 81bbf554e8 | |||
| 26a24a98ed | |||
| e8de1daf65 | |||
| 11e86110e7 | |||
| f42d76b4b4 | |||
| e379ca6c54 | |||
| 5d0b35d53a | |||
| 8c71b883bb | |||
| 843351956e | |||
| 7197d22f2a | |||
| b77c4c67a1 | |||
| 62bc616ada | |||
| 9e8251fb9f | |||
| 6ff9483e07 | |||
| 484a3903ca | |||
| 916fc96654 | |||
| 75345f4da1 | |||
| e603437500 | |||
| d49a778b68 | |||
| 95ae86d962 | |||
| 51e35eb572 | |||
| 4f0cae59c2 | |||
| 886dbf1172 | |||
| 04392069a6 | |||
| 78acf707dc | |||
| 08d1ea89bf | |||
| 2b6fd49a53 | |||
| 3063e37cbd | |||
| d2569fa446 | |||
| 8a8452290c | |||
| d2f7b65282 | |||
| 80966d60c1 | |||
| 85223303f2 | |||
| 0860bd3736 | |||
| b53bf7844b | |||
| 75514ddd87 | |||
| 35642e2661 | |||
| c24ddf5deb | |||
| f436fd08ed | |||
| dc523b78d4 | |||
| 06a599b4e7 | |||
| 27cd1a6a6e | |||
| b6521ed884 | |||
| 71f7c712cd | |||
| f5f411b62f | |||
| d367149048 | |||
| 1bd5ebd8ec | |||
| 534609e83a | |||
| 082a5d3c0f | |||
| cee3ebbb23 | |||
| 9b27251473 | |||
| 022479aff9 | |||
| adcee462e3 | |||
| 7d070e6caf | |||
| dcdf3e197c | |||
| 6b5b3617d4 | |||
| be9f7dbf6e | |||
| 38c9cb98a9 | |||
| d8d0414ec4 | |||
| a7870bbd5a | |||
| 19370a36a2 | |||
| 5998587c52 | |||
| 778ce71ea4 | |||
| 72105e218d | |||
| 1af23a4106 | |||
| 6b7d22c211 | |||
| 40b41b0dc5 | |||
| db8a3d5b90 | |||
| 011d08b172 | |||
| 124c2b5ce3 | |||
| 1e375c6de9 | |||
| cc4f63be12 | |||
| 597231bed9 | |||
| 98e3ca47e6 | |||
| a46a0b1b32 | |||
| d4f786c902 | |||
| b123720fa3 | |||
| 1376237e08 | |||
| 78b7385281 | |||
| 4ab727acbd | |||
| 32e1c9617e | |||
| fb323cef69 | |||
| cc179b488d | |||
| 2fd0ed1e74 | |||
| afa5a193a7 | |||
| b0789d45f3 | |||
| be5fdea5e1 | |||
| 268953e19f | |||
| 8cc03c265f | |||
| 47a0df769e | |||
| ff2d5badc9 | |||
| bcaf837da8 | |||
| 0d46c06843 | |||
| cdab6f8b76 | |||
| b21b953ef2 | |||
| 0d5cf46625 | |||
| 9c0ae14609 | |||
| 5fcafb6434 | |||
| 5763d73dda | |||
| cd4218e523 | |||
| f592f2234b | |||
| c73a4a7983 | |||
| a1fd8f49d7 | |||
| a213799dac | |||
| b925f517d2 | |||
| 767476ea51 | |||
| 37ebf04bb5 | |||
| 7f2bd164db | |||
| 77014843fb | |||
|
|
5f62bf3e62 | ||
|
|
0333fb6e22 | ||
|
|
03de374b07 | ||
| 3baa08a3bb | |||
| 896af2c5d2 | |||
| 2c3311b471 | |||
| 2506f6b143 | |||
| c9b4ab5a13 | |||
| 08fad38782 | |||
| ba8b2df473 | |||
| b819c0334a | |||
| 009f6cce6e | |||
| 4ee66c8218 | |||
| e6f111c5fc | |||
| e146480401 | |||
| e7f82c88f1 | |||
| 9ba8f53ec7 | |||
|
|
47f0bbb93a | ||
|
|
9a9144321d | ||
| 2113946ed0 | |||
| cad7953ef6 | |||
| 1fea327eff | |||
| 16a5295140 | |||
| d84b0e4455 | |||
| bb8e050434 | |||
| e27af374b0 | |||
| 471ff5b939 | |||
| bfbd159706 | |||
| aa8fd85d65 | |||
| bc6583fe57 | |||
| 63272d3cfc | |||
|
|
78d0a54e96 | ||
| 280ca2cf2f | |||
|
|
f564d4dc22 | ||
| 126a4d8443 | |||
| 38b930cd03 | |||
| 2eb89e938a | |||
| 1da9c21f13 | |||
| 7eed4fa97b | |||
| 557f16b8d5 | |||
| ed72847374 | |||
| 645bd3d383 | |||
| 2e7a7f26f8 | |||
| 3474b827b0 |
6
.idea/ant.xml
generated
Normal file
6
.idea/ant.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AntConfiguration">
|
||||
<buildFile url="file://$PROJECT_DIR$/build.xml" />
|
||||
</component>
|
||||
</project>
|
||||
22
.idea/compiler.xml
generated
Normal file
22
.idea/compiler.xml
generated
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<resourceExtensions />
|
||||
<wildcardResourcePatterns>
|
||||
<entry name="!?*.java" />
|
||||
<entry name="!?*.form" />
|
||||
<entry name="!?*.class" />
|
||||
<entry name="!?*.groovy" />
|
||||
<entry name="!?*.scala" />
|
||||
<entry name="!?*.flex" />
|
||||
<entry name="!?*.kt" />
|
||||
<entry name="!?*.clj" />
|
||||
<entry name="!?*.aj" />
|
||||
</wildcardResourcePatterns>
|
||||
<annotationProcessing>
|
||||
<profile default="true" name="Default" enabled="false">
|
||||
<processorPath useClasspath="true" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
</component>
|
||||
</project>
|
||||
3
.idea/copyright/profiles_settings.xml
generated
Normal file
3
.idea/copyright/profiles_settings.xml
generated
Normal file
@@ -0,0 +1,3 @@
|
||||
<component name="CopyrightManager">
|
||||
<settings default="" />
|
||||
</component>
|
||||
9
.idea/libraries/javax_servlet_jsp_2_2_0_v201112011158.xml
generated
Normal file
9
.idea/libraries/javax_servlet_jsp_2_2_0_v201112011158.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
<component name="libraryTable">
|
||||
<library name="javax.servlet.jsp-2.2.0.v201112011158">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jsp/javax.servlet.jsp-2.2.0.v201112011158.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
22
.idea/libraries/jettylib.xml
generated
Normal file
22
.idea/libraries/jettylib.xml
generated
Normal file
@@ -0,0 +1,22 @@
|
||||
<component name="libraryTable">
|
||||
<library name="jettylib">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-security-8.1.17.v20150415.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-servlets-8.1.17.v20150415.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-deploy-8.1.17.v20150415.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-util-8.1.17.v20150415.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-servlet-8.1.17.v20150415.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-http-8.1.17.v20150415.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-xml-8.1.17.v20150415.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-server-8.1.17.v20150415.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/servlet-api-3.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-jmx-8.1.17.v20150415.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-webapp-8.1.17.v20150415.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-io-8.1.17.v20150415.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-continuation-8.1.17.v20150415.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-rewrite-8.1.17.v20150415.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
9
.idea/libraries/jrobin_1_5_9_1.xml
generated
Normal file
9
.idea/libraries/jrobin_1_5_9_1.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
<component name="libraryTable">
|
||||
<library name="jrobin-1.5.9.1">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/apps/jrobin/jrobin-1.5.9.1.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
10
.idea/libraries/lib.xml
generated
Normal file
10
.idea/libraries/lib.xml
generated
Normal file
@@ -0,0 +1,10 @@
|
||||
<component name="libraryTable">
|
||||
<library name="lib">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/apps/susidns/src/lib/jstl.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/apps/susidns/src/lib/standard.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
9
.idea/libraries/start.xml
generated
Normal file
9
.idea/libraries/start.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
<component name="libraryTable">
|
||||
<library name="start">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/start.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
9
.idea/libraries/systray4j.xml
generated
Normal file
9
.idea/libraries/systray4j.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
<component name="libraryTable">
|
||||
<library name="systray4j">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/apps/systray/java/lib/systray4j.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
9
.idea/libraries/tomcat_coyote_util.xml
generated
Normal file
9
.idea/libraries/tomcat_coyote_util.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
<component name="libraryTable">
|
||||
<library name="tomcat-coyote-util">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/apps/jetty/apache-tomcat/lib/tomcat-coyote-util.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
12
.idea/libraries/tomcat_lib.xml
generated
Normal file
12
.idea/libraries/tomcat_lib.xml
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
<component name="libraryTable">
|
||||
<library name="tomcat-lib">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/apps/jetty/apache-tomcat-deployer/lib/tomcat-juli.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/apps/jetty/apache-tomcat-deployer/lib/el-api.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/apps/jetty/apache-tomcat-deployer/lib/jasper.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/apps/jetty/apache-tomcat-deployer/lib/jasper-el.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
9
.idea/libraries/wrapper.xml
generated
Normal file
9
.idea/libraries/wrapper.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
<component name="libraryTable">
|
||||
<library name="wrapper">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/installer/lib/wrapper/all/wrapper.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
9
.idea/libraries/wrapper_win.xml
generated
Normal file
9
.idea/libraries/wrapper_win.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
<component name="libraryTable">
|
||||
<library name="wrapper-win">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/installer/lib/wrapper/win-all/wrapper.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
57
.idea/misc.xml
generated
Normal file
57
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ClientPropertiesManager">
|
||||
<properties class="javax.swing.AbstractButton">
|
||||
<property name="hideActionText" class="java.lang.Boolean" />
|
||||
</properties>
|
||||
<properties class="javax.swing.JComponent">
|
||||
<property name="html.disable" class="java.lang.Boolean" />
|
||||
</properties>
|
||||
<properties class="javax.swing.JEditorPane">
|
||||
<property name="JEditorPane.w3cLengthUnits" class="java.lang.Boolean" />
|
||||
<property name="JEditorPane.honorDisplayProperties" class="java.lang.Boolean" />
|
||||
<property name="charset" class="java.lang.String" />
|
||||
</properties>
|
||||
<properties class="javax.swing.JList">
|
||||
<property name="List.isFileList" class="java.lang.Boolean" />
|
||||
</properties>
|
||||
<properties class="javax.swing.JPasswordField">
|
||||
<property name="JPasswordField.cutCopyAllowed" class="java.lang.Boolean" />
|
||||
</properties>
|
||||
<properties class="javax.swing.JSlider">
|
||||
<property name="Slider.paintThumbArrowShape" class="java.lang.Boolean" />
|
||||
<property name="JSlider.isFilled" class="java.lang.Boolean" />
|
||||
</properties>
|
||||
<properties class="javax.swing.JTable">
|
||||
<property name="Table.isFileList" class="java.lang.Boolean" />
|
||||
<property name="JTable.autoStartsEdit" class="java.lang.Boolean" />
|
||||
<property name="terminateEditOnFocusLost" class="java.lang.Boolean" />
|
||||
</properties>
|
||||
<properties class="javax.swing.JToolBar">
|
||||
<property name="JToolBar.isRollover" class="java.lang.Boolean" />
|
||||
</properties>
|
||||
<properties class="javax.swing.JTree">
|
||||
<property name="JTree.lineStyle" class="java.lang.String" />
|
||||
</properties>
|
||||
<properties class="javax.swing.text.JTextComponent">
|
||||
<property name="caretAspectRatio" class="java.lang.Double" />
|
||||
<property name="caretWidth" class="java.lang.Integer" />
|
||||
</properties>
|
||||
</component>
|
||||
<component name="EntryPointsManager">
|
||||
<entry_points version="2.0" />
|
||||
</component>
|
||||
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
|
||||
<OptionsSetting value="true" id="Add" />
|
||||
<OptionsSetting value="true" id="Remove" />
|
||||
<OptionsSetting value="true" id="Checkout" />
|
||||
<OptionsSetting value="true" id="Update" />
|
||||
<OptionsSetting value="true" id="Status" />
|
||||
<OptionsSetting value="true" id="Edit" />
|
||||
<ConfirmationsSetting value="0" id="Add" />
|
||||
<ConfirmationsSetting value="0" id="Remove" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build" />
|
||||
</component>
|
||||
</project>
|
||||
27
.idea/modules.xml
generated
Normal file
27
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/apps/BOB/BOB.iml" filepath="$PROJECT_DIR$/apps/BOB/BOB.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/apps/addressbook/addressbook.iml" filepath="$PROJECT_DIR$/apps/addressbook/addressbook.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/apps/admin/admin.iml" filepath="$PROJECT_DIR$/apps/admin/admin.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/core/core.iml" filepath="$PROJECT_DIR$/core/core.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/apps/desktopgui/desktopgui.iml" filepath="$PROJECT_DIR$/apps/desktopgui/desktopgui.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/apps/i2psnark/i2psnark.iml" filepath="$PROJECT_DIR$/apps/i2psnark/i2psnark.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/apps/i2ptunnel/i2ptunnel.iml" filepath="$PROJECT_DIR$/apps/i2ptunnel/i2ptunnel.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/apps/imagegen/identicon/identicon.iml" filepath="$PROJECT_DIR$/apps/imagegen/identicon/identicon.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/apps/imagegen/imagegen/imagegen.iml" filepath="$PROJECT_DIR$/apps/imagegen/imagegen/imagegen.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/installer/installer.iml" filepath="$PROJECT_DIR$/installer/installer.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/apps/jetty/jetty.iml" filepath="$PROJECT_DIR$/apps/jetty/jetty.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/apps/ministreaming/ministreaming.iml" filepath="$PROJECT_DIR$/apps/ministreaming/ministreaming.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/router/router.iml" filepath="$PROJECT_DIR$/router/router.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/apps/routerconsole/routerconsole.iml" filepath="$PROJECT_DIR$/apps/routerconsole/routerconsole.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/apps/sam/sam.iml" filepath="$PROJECT_DIR$/apps/sam/sam.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/apps/streaming/streaming.iml" filepath="$PROJECT_DIR$/apps/streaming/streaming.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/apps/susidns/susidns.iml" filepath="$PROJECT_DIR$/apps/susidns/susidns.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/apps/susimail/susimail.iml" filepath="$PROJECT_DIR$/apps/susimail/susimail.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/apps/systray/systray.iml" filepath="$PROJECT_DIR$/apps/systray/systray.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/apps/imagegen/zxing/zxing.iml" filepath="$PROJECT_DIR$/apps/imagegen/zxing/zxing.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/runConfigurations/updater.xml
generated
Normal file
6
.idea/runConfigurations/updater.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="updater" type="AntRunConfiguration" factoryName="Ant Target">
|
||||
<antsettings antfile="file://$PROJECT_DIR$/build.xml" target="updater" />
|
||||
<method />
|
||||
</configuration>
|
||||
</component>
|
||||
45
.tx/config
45
.tx/config
@@ -11,6 +11,7 @@ trans.fr = apps/i2ptunnel/locale/messages_fr.po
|
||||
trans.hu = apps/i2ptunnel/locale/messages_hu.po
|
||||
trans.it = apps/i2ptunnel/locale/messages_it.po
|
||||
trans.ja = apps/i2ptunnel/locale/messages_ja.po
|
||||
trans.ko = apps/i2ptunnel/locale/messages_ko.po
|
||||
trans.nb = apps/i2ptunnel/locale/messages_nb.po
|
||||
trans.nl = apps/i2ptunnel/locale/messages_nl.po
|
||||
trans.nn = apps/i2ptunnel/locale/messages_nn.po
|
||||
@@ -21,6 +22,7 @@ trans.ro = apps/i2ptunnel/locale/messages_ro.po
|
||||
trans.ru_RU = apps/i2ptunnel/locale/messages_ru.po
|
||||
trans.sk = apps/i2ptunnel/locale/messages_sk.po
|
||||
trans.sv_SE = apps/i2ptunnel/locale/messages_sv.po
|
||||
trans.tr_TR = apps/i2ptunnel/locale/messages_tr.po
|
||||
trans.uk_UA = apps/i2ptunnel/locale/messages_uk.po
|
||||
trans.vi = apps/i2ptunnel/locale/messages_vi.po
|
||||
trans.zh_CN = apps/i2ptunnel/locale/messages_zh.po
|
||||
@@ -39,6 +41,7 @@ trans.hu = apps/i2ptunnel/locale-proxy/messages_hu.po
|
||||
;; Java converts id to in
|
||||
trans.id = apps/i2ptunnel/locale-proxy/messages_in.po
|
||||
trans.it = apps/i2ptunnel/locale-proxy/messages_it.po
|
||||
trans.ko = apps/i2ptunnel/locale-proxy/messages_ko.po
|
||||
trans.nb = apps/i2ptunnel/locale-proxy/messages_nb.po
|
||||
trans.nl = apps/i2ptunnel/locale-proxy/messages_nl.po
|
||||
trans.pl = apps/i2ptunnel/locale-proxy/messages_pl.po
|
||||
@@ -68,6 +71,7 @@ trans.fr = apps/routerconsole/locale/messages_fr.po
|
||||
trans.hu = apps/routerconsole/locale/messages_hu.po
|
||||
trans.it = apps/routerconsole/locale/messages_it.po
|
||||
trans.ja = apps/routerconsole/locale/messages_ja.po
|
||||
trans.ko = apps/routerconsole/locale/messages_ko.po
|
||||
trans.nb = apps/routerconsole/locale/messages_nb.po
|
||||
trans.nl = apps/routerconsole/locale/messages_nl.po
|
||||
trans.pl = apps/routerconsole/locale/messages_pl.po
|
||||
@@ -86,10 +90,13 @@ trans.zh_TW = apps/routerconsole/locale/messages_zh_TW.po
|
||||
source_file = apps/routerconsole/locale-news/messages_en.po
|
||||
source_lang = en
|
||||
trans.ar = apps/routerconsole/locale-news/messages_ar.po
|
||||
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.fi = apps/routerconsole/locale-news/messages_fi.po
|
||||
trans.fr = apps/routerconsole/locale-news/messages_fr.po
|
||||
trans.gl = apps/routerconsole/locale-news/messages_gl.po
|
||||
trans.he = apps/routerconsole/locale-news/messages_he.po
|
||||
;; Java converts id to in
|
||||
trans.id = apps/routerconsole/locale-news/messages_in.po
|
||||
@@ -125,9 +132,11 @@ 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
|
||||
trans.fr = apps/routerconsole/locale-countries/messages_fr.po
|
||||
trans.gl = apps/routerconsole/locale-countries/messages_gl.po
|
||||
trans.hu = apps/routerconsole/locale-countries/messages_hu.po
|
||||
trans.it = apps/routerconsole/locale-countries/messages_it.po
|
||||
trans.ja = apps/routerconsole/locale-countries/messages_ja.po
|
||||
trans.ko = apps/routerconsole/locale-countries/messages_ko.po
|
||||
trans.mg = apps/routerconsole/locale-countries/messages_mg.po
|
||||
trans.nb = apps/routerconsole/locale-countries/messages_nb.po
|
||||
trans.nl = apps/routerconsole/locale-countries/messages_nl.po
|
||||
@@ -139,8 +148,8 @@ trans.ru_RU = apps/routerconsole/locale-countries/messages_ru.po
|
||||
trans.sk = apps/routerconsole/locale-countries/messages_sk.po
|
||||
trans.sq = apps/routerconsole/locale-countries/messages_sq.po
|
||||
trans.sv_SE = apps/routerconsole/locale-countries/messages_sv.po
|
||||
trans.uk_UA = apps/routerconsole/locale-countries/messages_uk.po
|
||||
trans.tr_TR = apps/routerconsole/locale-countries/messages_tr.po
|
||||
trans.uk_UA = apps/routerconsole/locale-countries/messages_uk.po
|
||||
trans.vi = apps/routerconsole/locale-countries/messages_vi.po
|
||||
trans.zh_CN = apps/routerconsole/locale-countries/messages_zh.po
|
||||
trans.zh_TW = apps/routerconsole/locale-countries/messages_zh_TW.po
|
||||
@@ -156,6 +165,8 @@ trans.fi = apps/i2psnark/locale/messages_fi.po
|
||||
trans.fr = apps/i2psnark/locale/messages_fr.po
|
||||
trans.hu = apps/i2psnark/locale/messages_hu.po
|
||||
trans.it = apps/i2psnark/locale/messages_it.po
|
||||
trans.ja = apps/i2psnark/locale/messages_ja.po
|
||||
trans.ko = apps/i2psnark/locale/messages_ko.po
|
||||
trans.nb = apps/i2psnark/locale/messages_nb.po
|
||||
trans.nl = apps/i2psnark/locale/messages_nl.po
|
||||
trans.pl = apps/i2psnark/locale/messages_pl.po
|
||||
@@ -166,6 +177,7 @@ trans.ru_RU = apps/i2psnark/locale/messages_ru.po
|
||||
trans.sk = apps/i2psnark/locale/messages_sk.po
|
||||
trans.sv_SE = apps/i2psnark/locale/messages_sv.po
|
||||
trans.tr_TR = apps/i2psnark/locale/messages_tr.po
|
||||
trans.uk_UA = apps/i2psnark/locale/messages_uk.po
|
||||
trans.vi = apps/i2psnark/locale/messages_vi.po
|
||||
trans.zh_CN = apps/i2psnark/locale/messages_zh.po
|
||||
|
||||
@@ -180,9 +192,11 @@ trans.el = apps/susidns/locale/messages_el.po
|
||||
trans.es = apps/susidns/locale/messages_es.po
|
||||
trans.fi = apps/susidns/locale/messages_fi.po
|
||||
trans.fr = apps/susidns/locale/messages_fr.po
|
||||
trans.gl = apps/susidns/locale/messages_gl.po
|
||||
trans.hu = apps/susidns/locale/messages_hu.po
|
||||
trans.it = apps/susidns/locale/messages_it.po
|
||||
trans.ja = apps/susidns/locale/messages_ja.po
|
||||
trans.ko = apps/susidns/locale/messages_ko.po
|
||||
trans.nl = apps/susidns/locale/messages_nl.po
|
||||
trans.pl = apps/susidns/locale/messages_pl.po
|
||||
trans.pt = apps/susidns/locale/messages_pt.po
|
||||
@@ -194,6 +208,7 @@ trans.tr_TR = apps/susidns/locale/messages_tr.po
|
||||
trans.uk_UA = apps/susidns/locale/messages_uk.po
|
||||
trans.vi = apps/susidns/locale/messages_vi.po
|
||||
trans.zh_CN = apps/susidns/locale/messages_zh.po
|
||||
trans.zh_TW = apps/susidns/locale/messages_zh_TW.po
|
||||
|
||||
[I2P.desktopgui]
|
||||
source_file = apps/desktopgui/locale/messages_en.po
|
||||
@@ -209,6 +224,7 @@ trans.es = apps/desktopgui/locale/messages_es.po
|
||||
trans.fa = apps/desktopgui/locale/messages_fa.po
|
||||
trans.fi = apps/desktopgui/locale/messages_fi.po
|
||||
trans.fr = apps/desktopgui/locale/messages_fr.po
|
||||
trans.gl = apps/desktopgui/locale/messages_gl.po
|
||||
trans.hu = apps/desktopgui/locale/messages_hu.po
|
||||
;; Java converts id to in
|
||||
trans.id = apps/desktopgui/locale/messages_in.po
|
||||
@@ -240,11 +256,13 @@ trans.de = apps/susimail/locale/messages_de.po
|
||||
trans.es = apps/susimail/locale/messages_es.po
|
||||
trans.fi = apps/susimail/locale/messages_fi.po
|
||||
trans.fr = apps/susimail/locale/messages_fr.po
|
||||
trans.gl = apps/susimail/locale/messages_gl.po
|
||||
trans.hu = apps/susimail/locale/messages_hu.po
|
||||
;; Java converts id to in
|
||||
trans.id = apps/susimail/locale/messages_in.po
|
||||
trans.it = apps/susimail/locale/messages_it.po
|
||||
trans.ja = apps/susimail/locale/messages_ja.po
|
||||
trans.ko = apps/susimail/locale/messages_ko.po
|
||||
trans.mg = apps/susimail/locale/messages_mg.po
|
||||
trans.nl = apps/susimail/locale/messages_nl.po
|
||||
trans.pl = apps/susimail/locale/messages_pl.po
|
||||
@@ -258,6 +276,7 @@ trans.tr_TR = apps/susimail/locale/messages_tr.po
|
||||
trans.uk_UA = apps/susimail/locale/messages_uk.po
|
||||
trans.vi = apps/susimail/locale/messages_vi.po
|
||||
trans.zh_CN = apps/susimail/locale/messages_zh.po
|
||||
trans.zh_TW = apps/susimail/locale/messages_zh_TW.po
|
||||
|
||||
[I2P.debconf]
|
||||
source_file = debian/po/templates.pot
|
||||
@@ -285,6 +304,7 @@ trans.sv_SE = debian/po/sv.po
|
||||
trans.tr_TR = debian/po/tr.po
|
||||
trans.uk_UA = debian/po/uk.po
|
||||
trans.zh_CN = debian/po/zh.po
|
||||
trans.zh_TW = debian/po/zh_TW.po
|
||||
|
||||
[I2P.i2prouter-script]
|
||||
source_file = installer/resources/locale/po/messages_en.po
|
||||
@@ -298,10 +318,8 @@ trans.es = installer/resources/locale/po/messages_es.po
|
||||
trans.fr = installer/resources/locale/po/messages_fr.po
|
||||
trans.id = installer/resources/locale/po/messages_id.po
|
||||
trans.it = installer/resources/locale/po/messages_it.po
|
||||
trans.pl = installer/resources/locale/po/messages_pl.po
|
||||
trans.ja = installer/resources/locale/po/messages_ja.po
|
||||
;; currently fails check
|
||||
;;trans.ko = installer/resources/locale/po/messages_ko.po
|
||||
trans.ko = installer/resources/locale/po/messages_ko.po
|
||||
trans.nl = installer/resources/locale/po/messages_nl.po
|
||||
trans.pl = installer/resources/locale/po/messages_pl.po
|
||||
trans.pt = installer/resources/locale/po/messages_pt.po
|
||||
@@ -324,6 +342,8 @@ trans.de = core/java/src/gnu/getopt/MessagesBundle_de.properties
|
||||
trans.es = core/java/src/gnu/getopt/MessagesBundle_es.properties
|
||||
trans.fi = core/java/src/gnu/getopt/MessagesBundle_fi.properties
|
||||
trans.fr = core/java/src/gnu/getopt/MessagesBundle_fr.properties
|
||||
;; currently corrupt, non-UTF-8
|
||||
;;trans.gl = core/java/src/gnu/getopt/MessagesBundle_gl.properties
|
||||
trans.hu = core/java/src/gnu/getopt/MessagesBundle_hu.properties
|
||||
;; Java converts id to in
|
||||
trans.id = core/java/src/gnu/getopt/MessagesBundle_in.properties
|
||||
@@ -356,9 +376,11 @@ trans.de = apps/ministreaming/locale/messages_de.po
|
||||
trans.es = apps/ministreaming/locale/messages_es.po
|
||||
trans.fi = apps/ministreaming/locale/messages_fi.po
|
||||
trans.fr = apps/ministreaming/locale/messages_fr.po
|
||||
trans.gl = apps/ministreaming/locale/messages_gl.po
|
||||
;; Java converts id to in
|
||||
trans.id = apps/ministreaming/locale/messages_in.po
|
||||
trans.it = apps/ministreaming/locale/messages_it.po
|
||||
trans.ko = apps/ministreaming/locale/messages_ko.po
|
||||
trans.nb = apps/ministreaming/locale/messages_nb.po
|
||||
trans.nl = apps/ministreaming/locale/messages_nl.po
|
||||
trans.pl = apps/ministreaming/locale/messages_pl.po
|
||||
@@ -370,6 +392,21 @@ 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
|
||||
|
||||
[I2P.manpages]
|
||||
type = PO
|
||||
source_file = installer/resources/locale-man/man.pot
|
||||
source_lang = en
|
||||
; after adding languages here, add to debian/*.manpages also
|
||||
trans.de = installer/resources/locale-man/man_de.po
|
||||
trans.es = installer/resources/locale-man/man_es.po
|
||||
trans.fi = installer/resources/locale-man/man_fi.po
|
||||
trans.fr = installer/resources/locale-man/man_fr.po
|
||||
trans.it = installer/resources/locale-man/man_it.po
|
||||
trans.ko = installer/resources/locale-man/man_ko.po
|
||||
trans.nl = installer/resources/locale-man/man_nl.po
|
||||
trans.pt = installer/resources/locale-man/man_pt.po
|
||||
trans.zh_CN = installer/resources/locale-man/man_zh.po
|
||||
|
||||
[main]
|
||||
host = https://www.transifex.com
|
||||
|
||||
|
||||
14
Docker.entrypoint.sh
Normal file
14
Docker.entrypoint.sh
Normal file
@@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
|
||||
export JAVA_HOME=/opt/jdk/jre
|
||||
|
||||
# Ensure user rights
|
||||
chown -R i2p:nobody /opt/i2p
|
||||
chmod -R u+rwx /opt/i2p
|
||||
|
||||
gosu i2p /opt/i2p/i2psvc /opt/i2p/wrapper.config wrapper.pidfile=/var/tmp/i2p.pid \
|
||||
wrapper.name=i2p \
|
||||
wrapper.displayname="I2P Service" \
|
||||
wrapper.statusfile=/var/tmp/i2p.status \
|
||||
wrapper.java.statusfile=/var/tmp/i2p.java.status \
|
||||
wrapper.logfile=/var/tmp/wrapper.log
|
||||
7
Docker.expt
Normal file
7
Docker.expt
Normal file
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/expect
|
||||
set timeout 15;
|
||||
spawn java -jar /tmp/i2pinstall.jar -console
|
||||
expect {
|
||||
-re ".*press 1 to continue, 2 to quit, 3 to redisplay" {send "1\r"; exp_continue;}
|
||||
-re "Select target path *" {send "/opt/i2p\r"; exp_continue;}
|
||||
}
|
||||
62
Dockerfile
Normal file
62
Dockerfile
Normal file
@@ -0,0 +1,62 @@
|
||||
FROM meeh/java8server:latest
|
||||
# Docker image based on Alpine with Java.
|
||||
|
||||
# We use Oracle Java to run I2P, but uses the openjdk to build it.
|
||||
|
||||
|
||||
MAINTAINER Mikal Villa <mikal@sigterm.no>
|
||||
|
||||
ENV GIT_BRANCH="master"
|
||||
ENV I2P_PREFIX="/opt/i2p"
|
||||
ENV PATH=${I2P_PREFIX}/bin:$PATH
|
||||
ENV JAVA_HOME=/usr/lib/jvm/default-jvm
|
||||
|
||||
ENV GOSU_VERSION=1.7
|
||||
ENV GOSU_SHASUM="34049cfc713e8b74b90d6de49690fa601dc040021980812b2f1f691534be8a50 /usr/local/bin/gosu"
|
||||
|
||||
RUN mkdir /user && adduser -S -h /user i2p && chown -R i2p:nobody /user
|
||||
|
||||
# Adding files first, since Docker.expt is required for installation
|
||||
ADD Docker.expt /tmp/Docker.expt
|
||||
ADD Docker.entrypoint.sh /entrypoint.sh
|
||||
|
||||
# Required for wget https
|
||||
RUN apk add --no-cache openssl
|
||||
# Gosu is a replacement for su/sudo in docker and not a backdoor :) See https://github.com/tianon/gosu
|
||||
RUN wget -O /usr/local/bin/gosu https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-amd64 \
|
||||
&& echo "${GOSU_SHASUM}" | sha256sum -c && chmod +x /usr/local/bin/gosu
|
||||
|
||||
#
|
||||
# Each RUN is a layer, adding the dependencies and building i2pd in one layer takes around 8-900Mb, so to keep the
|
||||
# image under 200mb we need to remove all the build dependencies in the same "RUN" / layer.
|
||||
#
|
||||
|
||||
# The main layer
|
||||
RUN apk --no-cache add build-base git gettext tar bzip2 apache-ant openjdk8 expect \
|
||||
&& mkdir -p /usr/src/build \
|
||||
&& cd /usr/src/build \
|
||||
&& git clone -b ${GIT_BRANCH} https://github.com/i2p/i2p.i2p.git \
|
||||
&& cd /usr/src/build/i2p.i2p \
|
||||
&& echo "noExe=true" >> build.properties \
|
||||
&& ant installer-linux \
|
||||
&& cp i2pinstall*.jar /tmp/i2pinstall.jar \
|
||||
&& mkdir -p /opt \
|
||||
&& chown i2p:root /opt \
|
||||
&& chmod u+rw /opt \
|
||||
&& gosu i2p expect -f /tmp/Docker.expt \
|
||||
&& cd ${I2P_PREFIX} \
|
||||
&& rm -fr man docs *.bat *.command *.app /tmp/i2pinstall.jar /tmp/Docker.expt \
|
||||
&& rm -fr /usr/src/build \
|
||||
&& apk --purge del build-base apache-ant expect tcl expat git openjdk8 openjdk8-jre openjdk8-jre-base openjdk8-jre-lib bzip2 tar \
|
||||
binutils-libs binutils pkgconfig libcurl libc-dev musl-dev g++ make fortify-headers pkgconf giflib libssh2 libxdmcp libxcb \
|
||||
libx11 pcre alsa-lib libxi libxrender libxml2 readline bash openssl \
|
||||
&& rm -fr /usr/lib/jvm/default-jre \
|
||||
&& ln -sf /opt/jdk/jre /usr/lib/jvm/default-jre \
|
||||
&& chmod a+x /entrypoint.sh
|
||||
|
||||
|
||||
|
||||
EXPOSE 7654 7656 7657 7658 4444 6668 8998 7659 7660 4445 15000-20000
|
||||
|
||||
ENTRYPOINT [ "/entrypoint.sh" ]
|
||||
|
||||
25
LICENSE.txt
25
LICENSE.txt
@@ -36,7 +36,7 @@ Public domain except as listed below:
|
||||
Copyright (c) 2003, TheCrypto
|
||||
See licenses/LICENSE-ElGamalDSA.txt
|
||||
|
||||
SHA256 and HMAC:
|
||||
HMAC:
|
||||
Copyright (c) 2000 - 2004 The Legion Of The Bouncy Castle
|
||||
See licenses/LICENSE-SHA256.txt
|
||||
|
||||
@@ -64,7 +64,7 @@ Public domain except as listed below:
|
||||
Copyright 2006 Gregory Rubin grrubin@gmail.com
|
||||
See licenses/LICENSE-HashCash.txt
|
||||
|
||||
GettextResource from gettext v0.18:
|
||||
GettextResource from gettext v0.19.8:
|
||||
Copyright (C) 2001, 2007 Free Software Foundation, Inc.
|
||||
See licenses/LICENSE-LGPLv2.1.txt
|
||||
|
||||
@@ -150,8 +150,8 @@ Installer:
|
||||
|
||||
|
||||
|
||||
Java Service Wrapper Community Edition 32-bit 3.5.25:
|
||||
Copyright (C) 1999-2011 Tanuki Software, Ltd. All Rights Reserved.
|
||||
Java Service Wrapper Community Edition 32-bit 3.5.30:
|
||||
Copyright (C) 1999-2016 Tanuki Software, Ltd. All Rights Reserved.
|
||||
See licenses/LICENSE-Wrapper.txt
|
||||
|
||||
|
||||
@@ -161,6 +161,8 @@ Jbigi Libraries (jbigi.jar):
|
||||
GMP 4.3.2 / 5.0.2:
|
||||
Copyright 1991, 1996, 1999, 2000, 2007 Free Software Foundation, Inc.
|
||||
See licenses/LICENSE-LGPLv3.txt
|
||||
GMP 6.0.0:
|
||||
See licenses/LICENSE-GPLv2.txt
|
||||
|
||||
|
||||
Applications:
|
||||
@@ -207,18 +209,23 @@ Applications:
|
||||
Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
Copyright (c) 2008 Alexander von Gernler. All rights reserved.
|
||||
See licenses/LICENSE-BSD.txt
|
||||
Zxing:
|
||||
Zxing 3.3.0:
|
||||
See licenses/LICENSE-Apache2.0.txt
|
||||
|
||||
Jetty 8.1.17.v20150415:
|
||||
Jetty 8.1.21.v20160908:
|
||||
See licenses/ABOUT-Jetty.html
|
||||
See licenses/NOTICE-Jetty.html
|
||||
See licenses/LICENSE-Apache2.0.txt
|
||||
See licenses/LICENSE-ECLIPSE-1.0.html
|
||||
See licenses/NOTICE-Commons-Logging.txt
|
||||
|
||||
JRobin 1.5.9.1:
|
||||
JRobin 1.6.0-1:
|
||||
Copyright (c) 2001-2005 Sasa Markovic and Ciaran Treanor.
|
||||
Copyright (c) 2011 The OpenNMS Group, Inc.
|
||||
See licenses/LICENSE-LGPLv2.1.txt
|
||||
DeallocationHelper:
|
||||
Copyright (c) 2006-2016 Julien Gouesse
|
||||
See licenses/LICENSE-GPLv2.txt
|
||||
|
||||
Ministreaming Lib:
|
||||
By mihi.
|
||||
@@ -276,8 +283,8 @@ Applications:
|
||||
Bundles systray4j-2.4.1:
|
||||
See licenses/LICENSE-LGPLv2.1.txt
|
||||
|
||||
Tomcat 6.0.44:
|
||||
Copyright 1999-2015 The Apache Software Foundation
|
||||
Tomcat 6.0.48:
|
||||
Copyright 1999-2016 The Apache Software Foundation
|
||||
See licenses/LICENSE-Apache2.0.txt
|
||||
See licenses/NOTICE-Tomcat.txt
|
||||
|
||||
|
||||
51
README.md
Normal file
51
README.md
Normal file
@@ -0,0 +1,51 @@
|
||||
Prerequisites to build from source:
|
||||
Java SDK (preferably Oracle/Sun or OpenJDK) 1.7.0 or higher
|
||||
Non-linux operating systems and JVMs: See https://trac.i2p2.de/wiki/java
|
||||
Certain subsystems for embedded (core, router, mstreaming, streaming, i2ptunnel) require only Java 1.6
|
||||
Apache Ant 1.7.0 or higher
|
||||
The xgettext, msgfmt, and msgmerge tools installed
|
||||
from the GNU gettext package http://www.gnu.org/software/gettext/
|
||||
Build environment must use a UTF-8 locale.
|
||||
|
||||
To build:
|
||||
On x86 systems do:
|
||||
ant pkg
|
||||
|
||||
On non-x86, use one of the following instead:
|
||||
ant installer-linux
|
||||
ant installer-freebsd
|
||||
ant installer-osx
|
||||
|
||||
Run 'ant' with no arguments to see other build options.
|
||||
See INSTALL.txt or https://geti2p.net/download for installation instructions.
|
||||
|
||||
Documentation:
|
||||
https://geti2p.net/how
|
||||
API: http://docs.i2p-projekt.de/javadoc/
|
||||
or run 'ant javadoc' then start at build/javadoc/index.html
|
||||
|
||||
Latest release:
|
||||
https://geti2p.net/download
|
||||
|
||||
To get development branch from source control:
|
||||
https://geti2p.net/newdevelopers
|
||||
|
||||
FAQ:
|
||||
https://geti2p.net/faq
|
||||
|
||||
Need help?
|
||||
IRC irc.freenode.net #i2p
|
||||
http://forum.i2p/
|
||||
|
||||
Bug reports:
|
||||
https://trac.i2p2.de/report/1
|
||||
|
||||
Contact information, security issues, press inquiries:
|
||||
https://geti2p.net/en/contact
|
||||
|
||||
Twitter:
|
||||
@i2p, @geti2p
|
||||
|
||||
Licenses:
|
||||
See LICENSE.txt
|
||||
|
||||
@@ -49,7 +49,7 @@ config /etc/rc.d/rc.i2p.new
|
||||
config $INST_DIR/wrapper.config.new
|
||||
|
||||
if [ -e /var/log/packages/i2p-base* ]; then
|
||||
echo "Warning: This package supercedes the 'i2p-base' package." >&2
|
||||
echo "Warning: This package supersedes the 'i2p-base' package." >&2
|
||||
echo
|
||||
echo "You may want to 'removepkg i2p-base'" >&2
|
||||
echo "and check the contents of /etc/rc.d/rc.local*" >&2
|
||||
|
||||
13
apps/BOB/BOB.iml
Normal file
13
apps/BOB/BOB.iml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="core" />
|
||||
<orderEntry type="module" module-name="ministreaming" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -48,8 +48,9 @@ javac.classpath=\
|
||||
# Space-separated list of extra javac options
|
||||
javac.compilerargs=
|
||||
javac.deprecation=false
|
||||
javac.source=1.5
|
||||
javac.target=1.5
|
||||
javac.version=1.7
|
||||
javac.source=${javac.version}
|
||||
javac.target=${javac.version}
|
||||
javac.test.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}:\
|
||||
|
||||
@@ -155,7 +155,6 @@ public class BOB implements Runnable, ClientApp {
|
||||
*
|
||||
* @param mgr may be null
|
||||
* @param args non-null
|
||||
* @throws Exception on bad args
|
||||
* @since 0.9.10
|
||||
*/
|
||||
public BOB(I2PAppContext context, ClientAppManager mgr, String[] args) {
|
||||
@@ -165,7 +164,7 @@ public class BOB implements Runnable, ClientApp {
|
||||
if (classResource != null) {
|
||||
String classPath = classResource.toString();
|
||||
if (classPath.startsWith("jar")) {
|
||||
String manifestPath = classPath.substring(0, classPath.lastIndexOf("!") + 1) +
|
||||
String manifestPath = classPath.substring(0, classPath.lastIndexOf('!') + 1) +
|
||||
"/META-INF/MANIFEST.MF";
|
||||
try {
|
||||
Manifest manifest = new Manifest(new URL(manifestPath).openStream());
|
||||
@@ -364,25 +363,30 @@ public class BOB implements Runnable, ClientApp {
|
||||
// We could order them to stop, but that could cause nasty issues in the locks.
|
||||
visitAllThreads();
|
||||
database.getReadLock();
|
||||
int all = database.getcount();
|
||||
database.releaseReadLock();
|
||||
NamedDB nickinfo;
|
||||
for (i = 0; i < all; i++) {
|
||||
database.getReadLock();
|
||||
nickinfo = (NamedDB) database.getnext(i);
|
||||
nickinfo.getReadLock();
|
||||
if (nickinfo.get(P_RUNNING).equals(Boolean.TRUE) && nickinfo.get(P_STOPPING).equals(Boolean.FALSE) && nickinfo.get(P_STARTING).equals(Boolean.FALSE)) {
|
||||
nickinfo.releaseReadLock();
|
||||
database.releaseReadLock();
|
||||
database.getWriteLock();
|
||||
nickinfo.getWriteLock();
|
||||
nickinfo.add(P_STOPPING, Boolean.valueOf(true));
|
||||
nickinfo.releaseWriteLock();
|
||||
database.releaseWriteLock();
|
||||
} else {
|
||||
nickinfo.releaseReadLock();
|
||||
database.releaseReadLock();
|
||||
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.");
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,16 +25,16 @@ import net.i2p.data.DataHelper;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
|
||||
/**
|
||||
* Process I2P->TCP
|
||||
* Process I2P->TCP
|
||||
*
|
||||
* @author sponge
|
||||
*/
|
||||
public class I2PtoTCP implements Runnable {
|
||||
|
||||
private I2PSocket I2P;
|
||||
private NamedDB info, database;
|
||||
private final NamedDB info, database;
|
||||
private Socket sock;
|
||||
private AtomicBoolean lives;
|
||||
private final AtomicBoolean lives;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@@ -56,8 +56,8 @@ public class I2PtoTCP implements Runnable {
|
||||
}
|
||||
|
||||
private void runlock() {
|
||||
database.releaseReadLock();
|
||||
info.releaseReadLock();
|
||||
database.releaseReadLock();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,23 +78,15 @@ public class I2PtoTCP implements Runnable {
|
||||
die:
|
||||
{
|
||||
try {
|
||||
try {
|
||||
rlock();
|
||||
} catch (Exception e) {
|
||||
break die;
|
||||
}
|
||||
rlock();
|
||||
try {
|
||||
host = info.get("OUTHOST").toString();
|
||||
port = Integer.parseInt(info.get("OUTPORT").toString());
|
||||
tell = info.get("QUIET").equals(Boolean.FALSE);
|
||||
} catch (Exception e) {
|
||||
runlock();
|
||||
break die;
|
||||
}
|
||||
try {
|
||||
} finally {
|
||||
runlock();
|
||||
} catch (Exception e) {
|
||||
break die;
|
||||
}
|
||||
sock = new Socket(host, port);
|
||||
sock.setKeepAlive(true);
|
||||
|
||||
@@ -38,18 +38,18 @@ import net.i2p.util.Log;
|
||||
*/
|
||||
public class MUXlisten implements Runnable {
|
||||
|
||||
private NamedDB database, info;
|
||||
private Logger _log;
|
||||
private I2PSocketManager socketManager;
|
||||
private ByteArrayInputStream prikey;
|
||||
private final NamedDB database, info;
|
||||
private final Logger _log;
|
||||
private final I2PSocketManager socketManager;
|
||||
private final ByteArrayInputStream prikey;
|
||||
private ThreadGroup tg;
|
||||
private String N;
|
||||
private ServerSocket listener = null;
|
||||
private int backlog = 50; // should this be more? less?
|
||||
boolean go_out;
|
||||
boolean come_in;
|
||||
private AtomicBoolean lock;
|
||||
private AtomicBoolean lives;
|
||||
private final String N;
|
||||
private ServerSocket listener;
|
||||
private 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.
|
||||
@@ -61,43 +61,39 @@ public class MUXlisten implements Runnable {
|
||||
* @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 {
|
||||
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);
|
||||
|
||||
this.database.getWriteLock();
|
||||
this.info.getWriteLock();
|
||||
this.info.add("STARTING", Boolean.valueOf(true));
|
||||
this.info.releaseWriteLock();
|
||||
this.database.releaseWriteLock();
|
||||
this.database.getReadLock();
|
||||
this.info.getReadLock();
|
||||
|
||||
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");
|
||||
Properties Q = new Properties();
|
||||
Lifted.copyProperties(R, Q);
|
||||
this.database.releaseReadLock();
|
||||
this.info.releaseReadLock();
|
||||
|
||||
this.database.getReadLock();
|
||||
this.info.getReadLock();
|
||||
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());
|
||||
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();
|
||||
}
|
||||
this.database.releaseReadLock();
|
||||
this.info.releaseReadLock();
|
||||
|
||||
String i2cpHost = Q.getProperty(I2PClient.PROP_TCP_HOST, "127.0.0.1");
|
||||
int i2cpPort = 7654;
|
||||
@@ -115,48 +111,51 @@ public class MUXlisten implements Runnable {
|
||||
prikey, i2cpHost, i2cpPort, Q);
|
||||
} catch (IOException e) {
|
||||
// Something went bad.
|
||||
this.database.getWriteLock();
|
||||
this.info.getWriteLock();
|
||||
this.info.add("STARTING", Boolean.valueOf(false));
|
||||
this.info.releaseWriteLock();
|
||||
this.database.releaseWriteLock();
|
||||
throw new IOException(e.toString());
|
||||
wlock();
|
||||
try {
|
||||
this.info.add("STARTING", Boolean.FALSE);
|
||||
} finally {
|
||||
wunlock();
|
||||
}
|
||||
throw e;
|
||||
} catch (RuntimeException e) {
|
||||
// Something went bad.
|
||||
this.database.getWriteLock();
|
||||
this.info.getWriteLock();
|
||||
this.info.add("STARTING", Boolean.valueOf(false));
|
||||
this.info.releaseWriteLock();
|
||||
this.database.releaseWriteLock();
|
||||
throw new RuntimeException(e);
|
||||
wlock();
|
||||
try {
|
||||
this.info.add("STARTING", Boolean.FALSE);
|
||||
} finally {
|
||||
wunlock();
|
||||
}
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
// Something else went bad.
|
||||
this.database.getWriteLock();
|
||||
this.info.getWriteLock();
|
||||
this.info.add("STARTING", Boolean.valueOf(false));
|
||||
this.info.releaseWriteLock();
|
||||
this.database.releaseWriteLock();
|
||||
wlock();
|
||||
try {
|
||||
this.info.add("STARTING", Boolean.FALSE);
|
||||
} finally {
|
||||
wunlock();
|
||||
}
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void rlock() throws Exception {
|
||||
private void rlock() {
|
||||
database.getReadLock();
|
||||
info.getReadLock();
|
||||
}
|
||||
|
||||
private void runlock() throws Exception {
|
||||
database.releaseReadLock();
|
||||
private void runlock() {
|
||||
info.releaseReadLock();
|
||||
database.releaseReadLock();
|
||||
}
|
||||
|
||||
private void wlock() throws Exception {
|
||||
private void wlock() {
|
||||
database.getWriteLock();
|
||||
info.getWriteLock();
|
||||
}
|
||||
|
||||
private void wunlock() throws Exception {
|
||||
private void wunlock() {
|
||||
info.releaseWriteLock();
|
||||
database.releaseWriteLock();
|
||||
}
|
||||
@@ -170,24 +169,19 @@ public class MUXlisten implements Runnable {
|
||||
Thread t = null;
|
||||
Thread q = null;
|
||||
try {
|
||||
wlock();
|
||||
try {
|
||||
wlock();
|
||||
try {
|
||||
info.add("RUNNING", Boolean.valueOf(true));
|
||||
info.add("RUNNING", Boolean.TRUE);
|
||||
} catch (Exception e) {
|
||||
lock.set(false);
|
||||
wunlock();
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
lock.set(false);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
} finally {
|
||||
wunlock();
|
||||
} catch (Exception e) {
|
||||
lock.set(false);
|
||||
return;
|
||||
}
|
||||
lives.set(true);
|
||||
lock.set(false);
|
||||
@@ -214,21 +208,17 @@ public class MUXlisten implements Runnable {
|
||||
q.start();
|
||||
}
|
||||
|
||||
wlock();
|
||||
try {
|
||||
wlock();
|
||||
try {
|
||||
info.add("STARTING", Boolean.valueOf(false));
|
||||
info.add("STARTING", Boolean.FALSE);
|
||||
} catch (Exception e) {
|
||||
wunlock();
|
||||
break quit;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
break quit;
|
||||
}
|
||||
try {
|
||||
} finally {
|
||||
wunlock();
|
||||
} catch (Exception e) {
|
||||
break quit;
|
||||
}
|
||||
boolean spin = true;
|
||||
while (spin && lives.get()) {
|
||||
@@ -237,21 +227,17 @@ public class MUXlisten implements Runnable {
|
||||
} catch (InterruptedException e) {
|
||||
break quit;
|
||||
}
|
||||
rlock();
|
||||
try {
|
||||
rlock();
|
||||
try {
|
||||
spin = info.get("STOPPING").equals(Boolean.FALSE);
|
||||
} catch (Exception e) {
|
||||
runlock();
|
||||
break quit;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
break quit;
|
||||
}
|
||||
try {
|
||||
} finally {
|
||||
runlock();
|
||||
} catch (Exception e) {
|
||||
break quit;
|
||||
}
|
||||
}
|
||||
} // die
|
||||
@@ -271,16 +257,16 @@ public class MUXlisten implements Runnable {
|
||||
try {
|
||||
wlock();
|
||||
try {
|
||||
info.add("STARTING", Boolean.valueOf(false));
|
||||
info.add("STOPPING", Boolean.valueOf(true));
|
||||
info.add("RUNNING", Boolean.valueOf(false));
|
||||
info.add("STARTING", Boolean.FALSE);
|
||||
info.add("STOPPING", Boolean.TRUE);
|
||||
info.add("RUNNING", Boolean.FALSE);
|
||||
} catch (Exception e) {
|
||||
lock.set(false);
|
||||
wunlock();
|
||||
return;
|
||||
}
|
||||
wunlock();
|
||||
} catch (Exception e) {
|
||||
} finally {
|
||||
wunlock();
|
||||
}
|
||||
// Start cleanup.
|
||||
while (!lock.compareAndSet(false, true)) {
|
||||
@@ -322,15 +308,15 @@ public class MUXlisten implements Runnable {
|
||||
try {
|
||||
wlock();
|
||||
try {
|
||||
info.add("STARTING", Boolean.valueOf(false));
|
||||
info.add("STOPPING", Boolean.valueOf(false));
|
||||
info.add("RUNNING", Boolean.valueOf(false));
|
||||
info.add("STARTING", Boolean.FALSE);
|
||||
info.add("STOPPING", Boolean.FALSE);
|
||||
info.add("RUNNING", Boolean.FALSE);
|
||||
} catch (Exception e) {
|
||||
lock.set(false);
|
||||
wunlock();
|
||||
return;
|
||||
}
|
||||
wunlock();
|
||||
} finally {
|
||||
wunlock();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,12 @@
|
||||
*/
|
||||
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
|
||||
*
|
||||
@@ -22,129 +28,62 @@ package net.i2p.BOB;
|
||||
*/
|
||||
public class NamedDB {
|
||||
|
||||
private volatile Object[][] data;
|
||||
private int index, writersWaiting, readers;
|
||||
private final Map<String, Object> data;
|
||||
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(false);
|
||||
|
||||
/**
|
||||
* make initial NULL object
|
||||
*
|
||||
*/
|
||||
public NamedDB() {
|
||||
this.data = new Object[1][2];
|
||||
this.data = new HashMap<String, Object>();
|
||||
}
|
||||
|
||||
synchronized public void getReadLock() {
|
||||
while ((writersWaiting != 0)) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException ie) {
|
||||
}
|
||||
}
|
||||
readers++;
|
||||
public void getReadLock() {
|
||||
lock.readLock().lock();
|
||||
}
|
||||
|
||||
synchronized public void releaseReadLock() {
|
||||
readers--;
|
||||
notifyAll();
|
||||
public void releaseReadLock() {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
|
||||
synchronized public void getWriteLock() {
|
||||
writersWaiting++;
|
||||
while (readers != 0 && writersWaiting != 1) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException ie) {
|
||||
}
|
||||
}
|
||||
public void getWriteLock() {
|
||||
lock.writeLock().lock();
|
||||
}
|
||||
|
||||
synchronized public void releaseWriteLock() {
|
||||
writersWaiting--;
|
||||
notifyAll();
|
||||
public void releaseWriteLock() {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find objects in the array, returns its index or throws exception
|
||||
* @param key
|
||||
* @return an objects index
|
||||
* @throws ArrayIndexOutOfBoundsException when key does not exist
|
||||
*/
|
||||
public int idx(Object key) throws ArrayIndexOutOfBoundsException {
|
||||
for (int i = 0; i < index; i++) {
|
||||
if (key.equals(data[i][0])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
throw new ArrayIndexOutOfBoundsException("Can't locate key for index");
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an object from array if it exists
|
||||
* Delete an object if it exists
|
||||
*
|
||||
* @param key
|
||||
*/
|
||||
public void kill(Object key) {
|
||||
|
||||
int i, j, k, l;
|
||||
Object[][] olddata;
|
||||
int didsomething = 0;
|
||||
|
||||
try {
|
||||
k = idx(key);
|
||||
} catch (ArrayIndexOutOfBoundsException b) {
|
||||
return;
|
||||
}
|
||||
olddata = new Object[index + 2][2];
|
||||
// copy to olddata, skipping 'k'
|
||||
for (i = 0, l = 0; l < index; i++, l++) {
|
||||
if (i == k) {
|
||||
l++;
|
||||
didsomething++;
|
||||
}
|
||||
for (j = 0; j < 2; j++) {
|
||||
olddata[i][j] = data[l][j];
|
||||
}
|
||||
}
|
||||
index -= didsomething;
|
||||
data = olddata;
|
||||
public void kill(String key) {
|
||||
data.remove(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add object to the array, deletes the old one if it exists
|
||||
* Add object, deletes the old one if it exists
|
||||
*
|
||||
* @param key
|
||||
* @param val
|
||||
*/
|
||||
public void add(Object key, Object val) {
|
||||
Object[][] olddata;
|
||||
int i, j;
|
||||
i = 0;
|
||||
kill(key);
|
||||
|
||||
olddata = new Object[index + 2][2];
|
||||
// copy to olddata
|
||||
for (i = 0; i < index; i++) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
olddata[i][j] = data[i][j];
|
||||
}
|
||||
}
|
||||
data = olddata;
|
||||
data[index++] = new Object[]{key, val};
|
||||
public void add(String key, Object val) {
|
||||
data.put(key, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the object, and return it, throws RuntimeException
|
||||
* Get the object, and return it, throws RuntimeException if not found
|
||||
*
|
||||
* @param key
|
||||
* @return Object
|
||||
* @throws java.lang.RuntimeException
|
||||
* @param key non-null
|
||||
* @return Object non-null
|
||||
* @throws java.lang.RuntimeException if not found
|
||||
*/
|
||||
public Object get(Object key) throws RuntimeException {
|
||||
for (int i = 0; i < index; i++) {
|
||||
if (key.equals(data[i][0])) {
|
||||
return data[i][1];
|
||||
}
|
||||
}
|
||||
public Object get(String key) throws RuntimeException {
|
||||
Object rv = data.get(key);
|
||||
if (rv != null)
|
||||
return rv;
|
||||
throw new RuntimeException("Key not found");
|
||||
}
|
||||
|
||||
@@ -154,33 +93,14 @@ public class NamedDB {
|
||||
* @param key
|
||||
* @return true if an object exists, else returns false
|
||||
*/
|
||||
public boolean exists(Object key) {
|
||||
for (int i = 0; i < index; i++) {
|
||||
if (key.equals(data[i][0])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
public boolean exists(String key) {
|
||||
return data.containsKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param i index
|
||||
* @return an indexed Object
|
||||
* @throws java.lang.RuntimeException
|
||||
* @since 0.9.29 replaces getcount() and getnext(int)
|
||||
*/
|
||||
public Object getnext(int i) throws RuntimeException {
|
||||
if (i < index && i > -1) {
|
||||
return data[i][1];
|
||||
}
|
||||
throw new RuntimeException("No more data");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the count of how many objects
|
||||
*/
|
||||
public int getcount() {
|
||||
return index;
|
||||
public Collection<Object> values() {
|
||||
return data.values();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,9 +27,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
*/
|
||||
public class TCPio implements Runnable {
|
||||
|
||||
private InputStream Ain;
|
||||
private OutputStream Aout;
|
||||
private AtomicBoolean lives;
|
||||
private final InputStream Ain;
|
||||
private final OutputStream Aout;
|
||||
private final AtomicBoolean lives;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
||||
@@ -35,29 +35,26 @@ import net.i2p.util.I2PAppThread;
|
||||
|
||||
/**
|
||||
*
|
||||
* Process TCP->I2P
|
||||
* Process TCP->I2P
|
||||
*
|
||||
* @author sponge
|
||||
*/
|
||||
public class TCPtoI2P implements Runnable {
|
||||
|
||||
private I2PSocket I2P;
|
||||
private NamedDB info, database;
|
||||
private Socket sock;
|
||||
private I2PSocketManager socketManager;
|
||||
private AtomicBoolean lives;
|
||||
private final Socket sock;
|
||||
private final I2PSocketManager socketManager;
|
||||
private final AtomicBoolean lives;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param i2p
|
||||
* @param socket
|
||||
* param info
|
||||
* param database
|
||||
* @param info unused
|
||||
* @param database unused
|
||||
*/
|
||||
TCPtoI2P(I2PSocketManager i2p, Socket socket, NamedDB info, NamedDB database, AtomicBoolean lives) {
|
||||
this.sock = socket;
|
||||
this.info = info;
|
||||
this.database = database;
|
||||
this.socketManager = i2p;
|
||||
this.lives = lives;
|
||||
}
|
||||
@@ -106,16 +103,6 @@ public class TCPtoI2P implements Runnable {
|
||||
out.flush();
|
||||
}
|
||||
|
||||
private void rlock() {
|
||||
database.getReadLock();
|
||||
info.getReadLock();
|
||||
}
|
||||
|
||||
private void runlock() {
|
||||
info.releaseReadLock();
|
||||
database.releaseReadLock();
|
||||
}
|
||||
|
||||
/**
|
||||
* TCP stream to I2P stream thread starter
|
||||
*
|
||||
|
||||
25
apps/addressbook/addressbook.iml
Normal file
25
apps/addressbook/addressbook.iml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="web" name="Web">
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<deploymentDescriptor name="web.xml" url="file://$MODULE_DIR$/web.xml" />
|
||||
</descriptors>
|
||||
<webroots>
|
||||
<root url="file://$MODULE_DIR$" relative="/WEB-INF" />
|
||||
</webroots>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/java/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="jettylib" level="project" />
|
||||
<orderEntry type="module" module-name="core" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -7,7 +7,7 @@
|
||||
<property name="jar" value="addressbook.jar"/>
|
||||
<property name="war" value="addressbook.war"/>
|
||||
<property name="javac.compilerargs" value="" />
|
||||
<property name="javac.version" value="1.6" />
|
||||
<property name="javac.version" value="1.7" />
|
||||
|
||||
<target name="init">
|
||||
<mkdir dir="${build}"/>
|
||||
@@ -86,6 +86,8 @@
|
||||
<attribute name="Build-Date" value="${build.timestamp}" />
|
||||
<attribute name="Base-Revision" value="${workspace.version}" />
|
||||
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
|
||||
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
|
||||
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
|
||||
</manifest>
|
||||
</jar>
|
||||
</target>
|
||||
@@ -106,6 +108,8 @@
|
||||
<attribute name="Build-Date" value="${build.timestamp}" />
|
||||
<attribute name="Base-Revision" value="${workspace.version}" />
|
||||
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
|
||||
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
|
||||
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
|
||||
</manifest>
|
||||
</war>
|
||||
<delete dir="${dist}/tmp"/>
|
||||
|
||||
@@ -13,6 +13,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.i2p.client.naming.HostTxtEntry;
|
||||
import net.i2p.data.DataHelper;
|
||||
@@ -75,7 +76,7 @@ class HostTxtParser {
|
||||
public static HostTxtEntry parse(String inputLine, boolean allowCommandOnly) {
|
||||
if (inputLine.startsWith(";"))
|
||||
return null;
|
||||
int comment = inputLine.indexOf("#");
|
||||
int comment = inputLine.indexOf('#');
|
||||
String kv;
|
||||
String sprops;
|
||||
if (comment >= 0) {
|
||||
@@ -234,7 +235,50 @@ class HostTxtParser {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage: HostTxtParser [-q] validate example.i2p=b64dest[#!key1=val1#key2=val2]
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
boolean quiet = false;
|
||||
if (args.length > 0 && args[0].equals("-q")) {
|
||||
quiet = true;
|
||||
args = java.util.Arrays.copyOfRange(args, 1, args.length);
|
||||
}
|
||||
if (args.length != 2 || !args[0].equals("validate")) {
|
||||
System.err.println("Usage: HostTxtParser validate example.i2p=b64dest[#!key1=val1#key2=val2]");
|
||||
System.exit(1);
|
||||
}
|
||||
HostTxtEntry e = parse(args[1].trim(), false);
|
||||
if (e == null) {
|
||||
if (!quiet)
|
||||
System.err.println("Bad format");
|
||||
System.exit(2);
|
||||
}
|
||||
if (!e.hasValidSig()) {
|
||||
if (!quiet)
|
||||
System.err.println("Bad signature");
|
||||
System.exit(3);
|
||||
}
|
||||
Properties p = e.getProps();
|
||||
if (p != null) {
|
||||
if (p.containsKey(HostTxtEntry.PROP_ACTION) ||
|
||||
p.containsKey(HostTxtEntry.PROP_OLDDEST) ||
|
||||
p.containsKey(HostTxtEntry.PROP_OLDNAME) ||
|
||||
p.containsKey(HostTxtEntry.PROP_OLDSIG)) {
|
||||
if (!e.hasValidSig()) {
|
||||
if (!quiet)
|
||||
System.err.println("Bad inner signature");
|
||||
System.exit(4);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!quiet)
|
||||
System.err.println("Good signature for " + e.getName());
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
/****
|
||||
public static void test(String[] args) throws Exception {
|
||||
File f = new File("tmp-hosts.txt");
|
||||
Map<String, HostTxtEntry> map = parse(f);
|
||||
for (HostTxtEntry e : map.values()) {
|
||||
@@ -246,5 +290,5 @@ class HostTxtParser {
|
||||
'\n');
|
||||
}
|
||||
}
|
||||
|
||||
****/
|
||||
}
|
||||
|
||||
14
apps/admin/admin.iml
Normal file
14
apps/admin/admin.iml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/java/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="core" />
|
||||
<orderEntry type="module" module-name="router" />
|
||||
<orderEntry type="module" module-name="routerconsole" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -11,9 +11,10 @@ import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.DataHelper
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.router.Router;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.web.StatsGenerator;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
@@ -49,7 +50,7 @@ class AdminRunner implements Runnable {
|
||||
} else if ( (command.indexOf("routerStats.html") >= 0) || (command.indexOf("oldstats.jsp") >= 0) ) {
|
||||
try {
|
||||
out.write(DataHelper.getASCII("HTTP/1.1 200 OK\nConnection: close\nCache-control: no-cache\nContent-type: text/html\n\n"));
|
||||
_generator.generateStatsPage(new OutputStreamWriter(out));
|
||||
_generator.generateStatsPage(new OutputStreamWriter(out), true);
|
||||
out.close();
|
||||
} catch (IOException ioe) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
@@ -63,7 +64,8 @@ class AdminRunner implements Runnable {
|
||||
} else if (true || command.indexOf("routerConsole.html") > 0) {
|
||||
try {
|
||||
out.write(DataHelper.getASCII("HTTP/1.1 200 OK\nConnection: close\nCache-control: no-cache\nContent-type: text/html\n\n"));
|
||||
_context.router().renderStatusHTML(new OutputStreamWriter(out));
|
||||
// TODO Not technically the same as router().renderStatusHTML() was
|
||||
_context.routerAppManager().renderStatusHTML(new OutputStreamWriter(out));
|
||||
out.close();
|
||||
} catch (IOException ioe) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<property name="jar" value="desktopgui.jar"/>
|
||||
<property name="javadoc" value="javadoc"/>
|
||||
<property name="javac.compilerargs" value=""/>
|
||||
<property name="javac.version" value="1.6" />
|
||||
<property name="javac.version" value="1.7" />
|
||||
<property name="require.gettext" value="true" />
|
||||
|
||||
<condition property="no.bundle">
|
||||
@@ -83,6 +83,8 @@
|
||||
<attribute name="Build-Date" value="${build.timestamp}" />
|
||||
<attribute name="Base-Revision" value="${workspace.version}" />
|
||||
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
|
||||
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
|
||||
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
|
||||
</manifest>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
13
apps/desktopgui/desktopgui.iml
Normal file
13
apps/desktopgui/desktopgui.iml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="core" />
|
||||
<orderEntry type="module" module-name="router" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -7,13 +7,14 @@
|
||||
# blabla <blabla@trash-mail.com>, 2011
|
||||
# Ettore Atalan <atalanttore@googlemail.com>, 2016
|
||||
# foo <foo@bar>, 2009
|
||||
# Lars Schimmer <echelon@i2pmail.org>, 2016
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
|
||||
"PO-Revision-Date: 2016-05-27 08:26+0000\n"
|
||||
"Last-Translator: Ettore Atalan <atalanttore@googlemail.com>\n"
|
||||
"PO-Revision-Date: 2016-06-08 09:04+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"
|
||||
@@ -44,7 +45,7 @@ msgstr "I2P-Browser öffnen"
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
|
||||
msgid "Configure I2P System Tray"
|
||||
msgstr ""
|
||||
msgstr "I2P System Tray konfigurieren"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
|
||||
|
||||
@@ -4,14 +4,15 @@
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
#
|
||||
# Translators:
|
||||
# Amir H. Firouzian, 2017
|
||||
# NoProfile, 2016
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
|
||||
"PO-Revision-Date: 2016-05-25 12:34+0000\n"
|
||||
"Last-Translator: zzzi2p\n"
|
||||
"PO-Revision-Date: 2017-01-30 03:06+0000\n"
|
||||
"Last-Translator: Amir H. Firouzian\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"
|
||||
@@ -27,7 +28,7 @@ msgstr "شروع I2P"
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||
msgid "I2P is starting!"
|
||||
msgstr ""
|
||||
msgstr "I2P راه اندازی شد!"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||
@@ -57,7 +58,7 @@ msgstr ""
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
|
||||
msgid "Stop I2P"
|
||||
msgstr ""
|
||||
msgstr "توقف I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
# Boxoa590, 2013
|
||||
# ducki2p <ducki2p@gmail.com>, 2011
|
||||
# foo <foo@bar>, 2009
|
||||
# French language coordinator <french.translation@rbox.me>, 2017
|
||||
# Boxoa590, 2013
|
||||
# Towinet, 2016
|
||||
msgid ""
|
||||
@@ -15,8 +16,8 @@ msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
|
||||
"PO-Revision-Date: 2016-05-26 15:55+0000\n"
|
||||
"Last-Translator: Towinet\n"
|
||||
"PO-Revision-Date: 2017-01-17 14:10+0000\n"
|
||||
"Last-Translator: French language coordinator <french.translation@rbox.me>\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"
|
||||
|
||||
94
apps/desktopgui/locale/messages_gl.po
Normal file
94
apps/desktopgui/locale/messages_gl.po
Normal file
@@ -0,0 +1,94 @@
|
||||
# I2P
|
||||
# Copyright (C) 2009 The I2P Project
|
||||
# This file is distributed under the same license as the desktopgui package.
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
#
|
||||
# Translators:
|
||||
# Uberius Crypto <uberius@anonymail.tech>, 2016
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
|
||||
"PO-Revision-Date: 2016-10-22 05:24+0000\n"
|
||||
"Last-Translator: Uberius Crypto <uberius@anonymail.tech>\n"
|
||||
"Language-Team: Galician (http://www.transifex.com/otf/I2P/language/gl/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: gl\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"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||
msgid "I2P is starting!"
|
||||
msgstr "I2P está a se iniciar!"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||
msgid "Starting"
|
||||
msgstr "Iniciando"
|
||||
|
||||
#: 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:76
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
|
||||
msgid "Configure I2P System Tray"
|
||||
msgstr "Configurar a Bandexa do Sistema I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
|
||||
msgid "Disable"
|
||||
msgstr "Inhabilitar"
|
||||
|
||||
#: 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:110
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
|
||||
msgid "Stop I2P"
|
||||
msgstr "Deter I2P"
|
||||
|
||||
#: 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:143
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
|
||||
msgid "Stop I2P Immediately"
|
||||
msgstr "Deter I2P Inmediatamente"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
|
||||
msgid "Cancel I2P Shutdown"
|
||||
msgstr "Cancelar Apagado I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
|
||||
#, java-format
|
||||
msgid "Shutdown in {0}"
|
||||
msgstr "Apagar en {0}"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
|
||||
msgid "Shutdown imminent"
|
||||
msgstr "Apagar de contado"
|
||||
|
||||
#. status translations are in the console bundle
|
||||
#: 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:63
|
||||
msgid "I2P: Right-click for menu"
|
||||
msgstr "I2P: Clic co botón dereito para acceder ó menú"
|
||||
@@ -4,14 +4,15 @@
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
#
|
||||
# Translators:
|
||||
# Choi Yeon-Ung <kqwe1859@gmail.com>, 2014
|
||||
# HelloKS <kqwe1859@gmail.com>, 2014
|
||||
# HelloKS <kqwe1859@gmail.com>, 2016
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
|
||||
"PO-Revision-Date: 2016-05-25 12:34+0000\n"
|
||||
"Last-Translator: zzzi2p\n"
|
||||
"PO-Revision-Date: 2016-07-31 00:29+0000\n"
|
||||
"Last-Translator: HelloKS <kqwe1859@gmail.com>\n"
|
||||
"Language-Team: Korean (http://www.transifex.com/otf/I2P/language/ko/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -42,12 +43,12 @@ msgstr "I2P 브라우저 실행"
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
|
||||
msgid "Configure I2P System Tray"
|
||||
msgstr ""
|
||||
msgstr "I2P 시스템 트레이 설정"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
|
||||
msgid "Disable"
|
||||
msgstr ""
|
||||
msgstr "비활성화"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
|
||||
@@ -62,33 +63,33 @@ msgstr "I2P 정지"
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
|
||||
msgid "Restart I2P Immediately"
|
||||
msgstr ""
|
||||
msgstr "I2P 즉시 재시작"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
|
||||
msgid "Stop I2P Immediately"
|
||||
msgstr ""
|
||||
msgstr "I2P 즉시 정지"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
|
||||
msgid "Cancel I2P Shutdown"
|
||||
msgstr ""
|
||||
msgstr "I2P 종료 취소"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
|
||||
#, java-format
|
||||
msgid "Shutdown in {0}"
|
||||
msgstr ""
|
||||
msgstr "{0} 안에 종료"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
|
||||
msgid "Shutdown imminent"
|
||||
msgstr ""
|
||||
msgstr "즉시 종료"
|
||||
|
||||
#. status translations are in the console bundle
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
|
||||
msgid "Network"
|
||||
msgstr ""
|
||||
msgstr "네트워크"
|
||||
|
||||
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
|
||||
#: src/net/i2p/desktopgui/TrayManager.java:63
|
||||
msgid "I2P: Right-click for menu"
|
||||
msgstr ""
|
||||
msgstr "I2P: 메뉴는 오른쪽 클릭"
|
||||
|
||||
@@ -6,13 +6,14 @@
|
||||
# Translators:
|
||||
# ducki2p <ducki2p@gmail.com>, 2011
|
||||
# foo <foo@bar>, 2009
|
||||
# Martijn de Boer, 2016
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
|
||||
"PO-Revision-Date: 2016-05-25 12:34+0000\n"
|
||||
"Last-Translator: zzzi2p\n"
|
||||
"PO-Revision-Date: 2016-06-19 14:16+0000\n"
|
||||
"Last-Translator: Martijn de Boer\n"
|
||||
"Language-Team: Dutch (http://www.transifex.com/otf/I2P/language/nl/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -43,12 +44,12 @@ msgstr "Start I2P Browser"
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
|
||||
msgid "Configure I2P System Tray"
|
||||
msgstr ""
|
||||
msgstr "Configureer I2P systeembalk"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
|
||||
msgid "Disable"
|
||||
msgstr ""
|
||||
msgstr "Uitschakelen"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
|
||||
@@ -63,33 +64,33 @@ msgstr "I2P stoppen"
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
|
||||
msgid "Restart I2P Immediately"
|
||||
msgstr ""
|
||||
msgstr "Herstart I2P direct"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
|
||||
msgid "Stop I2P Immediately"
|
||||
msgstr ""
|
||||
msgstr "Stop I2P direct"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
|
||||
msgid "Cancel I2P Shutdown"
|
||||
msgstr ""
|
||||
msgstr "Annuleer afsluiten I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
|
||||
#, java-format
|
||||
msgid "Shutdown in {0}"
|
||||
msgstr ""
|
||||
msgstr "Afsluiten in {0}"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
|
||||
msgid "Shutdown imminent"
|
||||
msgstr ""
|
||||
msgstr "Afsluiten op handen"
|
||||
|
||||
#. status translations are in the console bundle
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
|
||||
msgid "Network"
|
||||
msgstr ""
|
||||
msgstr "Netwerk"
|
||||
|
||||
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
|
||||
#: src/net/i2p/desktopgui/TrayManager.java:63
|
||||
msgid "I2P: Right-click for menu"
|
||||
msgstr ""
|
||||
msgstr "I2P: Rechts klikken voor menu"
|
||||
|
||||
@@ -7,13 +7,14 @@
|
||||
# testsubject67 <deborinha97@hotmail.com>, 2014
|
||||
# blueboy, 2013
|
||||
# blueboy, 2015
|
||||
# Rafael Ferrari, 2016
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
|
||||
"PO-Revision-Date: 2016-05-25 12:34+0000\n"
|
||||
"Last-Translator: zzzi2p\n"
|
||||
"PO-Revision-Date: 2016-06-13 01:45+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"
|
||||
@@ -44,12 +45,12 @@ msgstr "Lançar o navegador I2P "
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
|
||||
msgid "Configure I2P System Tray"
|
||||
msgstr ""
|
||||
msgstr "Configurar o ícone de sistema I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
|
||||
msgid "Disable"
|
||||
msgstr ""
|
||||
msgstr "Desabilitar"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
|
||||
@@ -64,33 +65,33 @@ msgstr "Interromper o roteador I2P"
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
|
||||
msgid "Restart I2P Immediately"
|
||||
msgstr ""
|
||||
msgstr "Reinicializar o I2P Imediatamente"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
|
||||
msgid "Stop I2P Immediately"
|
||||
msgstr ""
|
||||
msgstr "Parar o I2P Imediatamente"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
|
||||
msgid "Cancel I2P Shutdown"
|
||||
msgstr ""
|
||||
msgstr "Cancelar o desligamento do I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
|
||||
#, java-format
|
||||
msgid "Shutdown in {0}"
|
||||
msgstr ""
|
||||
msgstr "Desligando em {0}"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
|
||||
msgid "Shutdown imminent"
|
||||
msgstr ""
|
||||
msgstr "Desligando agora"
|
||||
|
||||
#. status translations are in the console bundle
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
|
||||
msgid "Network"
|
||||
msgstr ""
|
||||
msgstr "Rede"
|
||||
|
||||
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
|
||||
#: src/net/i2p/desktopgui/TrayManager.java:63
|
||||
msgid "I2P: Right-click for menu"
|
||||
msgstr ""
|
||||
msgstr "I2P: Clique com o botão direito para o menu"
|
||||
|
||||
@@ -4,13 +4,15 @@
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
#
|
||||
# Translators:
|
||||
# Predator <Predator@windowslive.com>, 2016
|
||||
# titus <titus0818@gmail.com>, 2016
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
|
||||
"PO-Revision-Date: 2016-05-25 12:34+0000\n"
|
||||
"Last-Translator: zzzi2p\n"
|
||||
"PO-Revision-Date: 2016-09-16 18:17+0000\n"
|
||||
"Last-Translator: Predator <Predator@windowslive.com>\n"
|
||||
"Language-Team: Romanian (http://www.transifex.com/otf/I2P/language/ro/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -31,7 +33,7 @@ msgstr "I2P se pornește!"
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||
msgid "Starting"
|
||||
msgstr "Începere"
|
||||
msgstr "Pornește"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
|
||||
@@ -41,12 +43,12 @@ msgstr "Lansare I2P Browser"
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
|
||||
msgid "Configure I2P System Tray"
|
||||
msgstr ""
|
||||
msgstr "Configurează bara de sistem I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
|
||||
msgid "Disable"
|
||||
msgstr ""
|
||||
msgstr "Dezactivare"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
|
||||
@@ -61,33 +63,33 @@ msgstr "Stop I2P"
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
|
||||
msgid "Restart I2P Immediately"
|
||||
msgstr ""
|
||||
msgstr "Repornește I2P imediat"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
|
||||
msgid "Stop I2P Immediately"
|
||||
msgstr ""
|
||||
msgstr "Oprește I2P imediat"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
|
||||
msgid "Cancel I2P Shutdown"
|
||||
msgstr ""
|
||||
msgstr "Anulează oprirea I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
|
||||
#, java-format
|
||||
msgid "Shutdown in {0}"
|
||||
msgstr ""
|
||||
msgstr "Oprire în {0}"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
|
||||
msgid "Shutdown imminent"
|
||||
msgstr ""
|
||||
msgstr "Oprire iminentă"
|
||||
|
||||
#. status translations are in the console bundle
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
|
||||
msgid "Network"
|
||||
msgstr ""
|
||||
msgstr "Rețea"
|
||||
|
||||
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
|
||||
#: src/net/i2p/desktopgui/TrayManager.java:63
|
||||
msgid "I2P: Right-click for menu"
|
||||
msgstr ""
|
||||
msgstr "I2P: Click dreapta pentru meniu"
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
#
|
||||
# Translators:
|
||||
# c4sp3r, 2016
|
||||
# ducki2p <ducki2p@gmail.com>, 2011
|
||||
# foo <foo@bar>, 2009
|
||||
# Foster Snowhill, 2013
|
||||
@@ -13,8 +14,8 @@ msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
|
||||
"PO-Revision-Date: 2016-05-25 12:34+0000\n"
|
||||
"Last-Translator: zzzi2p\n"
|
||||
"PO-Revision-Date: 2016-07-27 14:27+0000\n"
|
||||
"Last-Translator: c4sp3r\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"
|
||||
@@ -45,12 +46,12 @@ msgstr "Запустить браузер I2P"
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
|
||||
msgid "Configure I2P System Tray"
|
||||
msgstr ""
|
||||
msgstr "Настроить системный трей I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
|
||||
msgid "Disable"
|
||||
msgstr ""
|
||||
msgstr "Отключить"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
|
||||
@@ -65,33 +66,33 @@ msgstr "Остановить I2P"
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
|
||||
msgid "Restart I2P Immediately"
|
||||
msgstr ""
|
||||
msgstr "Перезапустить I2P немедленно"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
|
||||
msgid "Stop I2P Immediately"
|
||||
msgstr ""
|
||||
msgstr "Остановить I2P немедленно"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
|
||||
msgid "Cancel I2P Shutdown"
|
||||
msgstr ""
|
||||
msgstr "Отменить выключение I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
|
||||
#, java-format
|
||||
msgid "Shutdown in {0}"
|
||||
msgstr ""
|
||||
msgstr "Выключение через {0}"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
|
||||
msgid "Shutdown imminent"
|
||||
msgstr ""
|
||||
msgstr "Неотменяемое выключение"
|
||||
|
||||
#. status translations are in the console bundle
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
|
||||
msgid "Network"
|
||||
msgstr ""
|
||||
msgstr "Сеть"
|
||||
|
||||
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
|
||||
#: src/net/i2p/desktopgui/TrayManager.java:63
|
||||
msgid "I2P: Right-click for menu"
|
||||
msgstr ""
|
||||
msgstr "I2P: Правый щелчок для вызова меню"
|
||||
|
||||
@@ -4,14 +4,15 @@
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
#
|
||||
# Translators:
|
||||
# Besnik <besnik@programeshqip.org>, 2016
|
||||
# Shpetim <shpetim@privacysolutions.no>, 2014
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
|
||||
"PO-Revision-Date: 2016-05-25 12:34+0000\n"
|
||||
"Last-Translator: zzzi2p\n"
|
||||
"PO-Revision-Date: 2016-12-09 22:59+0000\n"
|
||||
"Last-Translator: Besnik <besnik@programeshqip.org>\n"
|
||||
"Language-Team: Albanian (http://www.transifex.com/otf/I2P/language/sq/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -22,73 +23,73 @@ msgstr ""
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:31
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:59
|
||||
msgid "Start I2P"
|
||||
msgstr "Starto I2P'në"
|
||||
msgstr "Nise I2P-në"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||
msgid "I2P is starting!"
|
||||
msgstr "I2P po starton!"
|
||||
msgstr "I2P po niset!"
|
||||
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
|
||||
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
|
||||
msgid "Starting"
|
||||
msgstr "Po startoj"
|
||||
msgstr "Po niset"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
|
||||
msgid "Launch I2P Browser"
|
||||
msgstr "Nis Browser'in e I2P'së"
|
||||
msgstr "Nis Shfletuesin I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
|
||||
msgid "Configure I2P System Tray"
|
||||
msgstr ""
|
||||
msgstr "Formësoni Panel Sistemi I2P"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
|
||||
msgid "Disable"
|
||||
msgstr ""
|
||||
msgstr "Çaktivizoje"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
|
||||
msgid "Restart I2P"
|
||||
msgstr "Ristarto I2P¨në"
|
||||
msgstr "Rinise I2P-në"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
|
||||
msgid "Stop I2P"
|
||||
msgstr "Ndale I2P'në"
|
||||
msgstr "Ndale I2P-në"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
|
||||
msgid "Restart I2P Immediately"
|
||||
msgstr ""
|
||||
msgstr "Rinise I2P-në Menjëherë"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
|
||||
msgid "Stop I2P Immediately"
|
||||
msgstr ""
|
||||
msgstr "Ndale I2P-në Menjëherë"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
|
||||
msgid "Cancel I2P Shutdown"
|
||||
msgstr ""
|
||||
msgstr "Anuloje Mbylljen e I2P-së"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
|
||||
#, java-format
|
||||
msgid "Shutdown in {0}"
|
||||
msgstr ""
|
||||
msgstr "Mbylle për {0}"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
|
||||
msgid "Shutdown imminent"
|
||||
msgstr ""
|
||||
msgstr "Mbyllje shumë shpejt"
|
||||
|
||||
#. status translations are in the console bundle
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
|
||||
msgid "Network"
|
||||
msgstr ""
|
||||
msgstr "Rrjet"
|
||||
|
||||
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
|
||||
#: src/net/i2p/desktopgui/TrayManager.java:63
|
||||
msgid "I2P: Right-click for menu"
|
||||
msgstr ""
|
||||
msgstr "I2P: Djathtas-klikoni për menu"
|
||||
|
||||
@@ -5,13 +5,15 @@
|
||||
#
|
||||
# Translators:
|
||||
# 123hund123 <M8R-ra4r1r@mailinator.com>, 2011
|
||||
# Anders Nilsson <anders@devode.se>, 2016
|
||||
# Jonatan Nyberg <jonatan@autistici.org>, 2016
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
|
||||
"PO-Revision-Date: 2016-05-25 12:34+0000\n"
|
||||
"Last-Translator: zzzi2p\n"
|
||||
"PO-Revision-Date: 2016-12-19 13:35+0000\n"
|
||||
"Last-Translator: Anders Nilsson <anders@devode.se>\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"
|
||||
@@ -37,17 +39,17 @@ msgstr "Startar"
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
|
||||
msgid "Launch I2P Browser"
|
||||
msgstr "Öppna I2P browser"
|
||||
msgstr "Öppna I2P-browser"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
|
||||
msgid "Configure I2P System Tray"
|
||||
msgstr ""
|
||||
msgstr "Konfigurera I2P-meddelandefältet"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
|
||||
msgid "Disable"
|
||||
msgstr ""
|
||||
msgstr "Avaktivera"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
|
||||
@@ -62,33 +64,33 @@ msgstr "Stoppar I2P"
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
|
||||
msgid "Restart I2P Immediately"
|
||||
msgstr ""
|
||||
msgstr "Starta om I2P omedelbart"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
|
||||
msgid "Stop I2P Immediately"
|
||||
msgstr ""
|
||||
msgstr "Stoppa I2P omedelbart"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
|
||||
msgid "Cancel I2P Shutdown"
|
||||
msgstr ""
|
||||
msgstr "Avbryt I2P-avstängning"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
|
||||
#, java-format
|
||||
msgid "Shutdown in {0}"
|
||||
msgstr ""
|
||||
msgstr "Stänger av om {0}"
|
||||
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
|
||||
msgid "Shutdown imminent"
|
||||
msgstr ""
|
||||
msgstr "Avstängning nära"
|
||||
|
||||
#. status translations are in the console bundle
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
|
||||
msgid "Network"
|
||||
msgstr ""
|
||||
msgstr "Nätverk"
|
||||
|
||||
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
|
||||
#: src/net/i2p/desktopgui/TrayManager.java:63
|
||||
msgid "I2P: Right-click for menu"
|
||||
msgstr ""
|
||||
msgstr "I2P: Högerklicka för meny"
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
#
|
||||
# Translators:
|
||||
# w008 <alex.on.www@gmail.com>, 2016
|
||||
# Denis Lysenko <gribua@gmail.com>, 2011
|
||||
# LinuxChata, 2014
|
||||
# madjong <madjong@i2pmail.org>, 2014
|
||||
@@ -12,8 +13,8 @@ msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
|
||||
"PO-Revision-Date: 2016-05-25 12:34+0000\n"
|
||||
"Last-Translator: zzzi2p\n"
|
||||
"PO-Revision-Date: 2016-07-14 18:50+0000\n"
|
||||
"Last-Translator: w008 <alex.on.www@gmail.com>\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"
|
||||
@@ -88,7 +89,7 @@ msgstr ""
|
||||
#. status translations are in the console bundle
|
||||
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
|
||||
msgid "Network"
|
||||
msgstr ""
|
||||
msgstr "Мережа"
|
||||
|
||||
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
|
||||
#: src/net/i2p/desktopgui/TrayManager.java:63
|
||||
|
||||
28
apps/i2psnark/i2psnark.iml
Normal file
28
apps/i2psnark/i2psnark.iml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="web" name="Web">
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<deploymentDescriptor name="web.xml" url="file://$MODULE_DIR$/web.xml" />
|
||||
</descriptors>
|
||||
<webroots>
|
||||
<root url="file://$MODULE_DIR$" relative="/WEB-INF" />
|
||||
</webroots>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/java/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="jettylib" level="project" />
|
||||
<orderEntry type="module" module-name="core" />
|
||||
<orderEntry type="module" module-name="ministreaming" />
|
||||
<orderEntry type="module" module-name="jetty" />
|
||||
<orderEntry type="module" module-name="systray" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -26,7 +26,7 @@
|
||||
</target>
|
||||
|
||||
<property name="javac.compilerargs" value="" />
|
||||
<property name="javac.version" value="1.6" />
|
||||
<property name="javac.version" value="1.7" />
|
||||
<property name="require.gettext" value="true" />
|
||||
|
||||
<condition property="no.bundle">
|
||||
@@ -50,6 +50,10 @@
|
||||
<pathelement location="../../jetty/jettylib/javax.servlet.jar" />
|
||||
<!-- jsp-api.jar only present for debian builds -->
|
||||
<pathelement location="../../jetty/jettylib/jsp-api.jar" />
|
||||
<!-- jetty-i2p.jar only for RunStandalone -->
|
||||
<pathelement location="../../jetty/jettylib/jetty-i2p.jar" />
|
||||
<!-- systray.jar only for RunStandalone -->
|
||||
<pathelement location="../../systray/java/build/systray.jar" />
|
||||
</classpath>
|
||||
</javac>
|
||||
</target>
|
||||
@@ -71,7 +75,7 @@
|
||||
<target name="jar" depends="builddep, compile, jarUpToDate, listChangedFiles" unless="jar.uptodate" >
|
||||
<!-- set if unset -->
|
||||
<property name="workspace.changes.tr" value="" />
|
||||
<jar destfile="./build/i2psnark.jar" basedir="./build/obj" includes="**/*.class" excludes="**/web/* **/messages_*.class">
|
||||
<jar destfile="./build/i2psnark.jar" basedir="./build/obj" includes="**/*.class" excludes="**/web/* **/messages_*.class, **/standalone/*">
|
||||
<manifest>
|
||||
<attribute name="Main-Class" value="org.klomp.snark.CommandLine" />
|
||||
<attribute name="Class-Path" value="i2p.jar mstreaming.jar streaming.jar" />
|
||||
@@ -80,6 +84,8 @@
|
||||
<attribute name="Build-Date" value="${build.timestamp}" />
|
||||
<attribute name="Base-Revision" value="${workspace.version}" />
|
||||
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
|
||||
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
|
||||
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
|
||||
</manifest>
|
||||
</jar>
|
||||
</target>
|
||||
@@ -126,6 +132,8 @@
|
||||
<attribute name="Build-Date" value="${build.timestamp}" />
|
||||
<attribute name="Base-Revision" value="${workspace.version}" />
|
||||
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
|
||||
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
|
||||
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
|
||||
</manifest>
|
||||
</war>
|
||||
</target>
|
||||
@@ -179,29 +187,126 @@
|
||||
<zipfileset dir="./dist/" prefix="i2psnark/" />
|
||||
</zip>
|
||||
</target>
|
||||
<target name="standalone_prep" depends="war">
|
||||
|
||||
<!-- make a fat jar for standalone -->
|
||||
<target name="standalone_jar" depends="war">
|
||||
<!-- set if unset -->
|
||||
<property name="workspace.changes.tr" value="" />
|
||||
<jar destfile="build/i2psnark-standalone.jar">
|
||||
<fileset dir="build/obj" includes="**/standalone/*.class" />
|
||||
<zipfileset src="build/i2psnark.jar" />
|
||||
<zipfileset src="../../../core/java/build/i2p.jar" />
|
||||
<zipfileset src="../../jetty/jettylib/commons-logging.jar" />
|
||||
<!-- without this we get a warning about 'no JSP support' but that's it
|
||||
<zipfileset src="../../jetty/jettylib/jasper-runtime.jar" />
|
||||
-->
|
||||
<zipfileset src="../../jetty/jettylib/javax.servlet.jar" />
|
||||
<zipfileset src="../../jetty/jettylib/jetty-continuation.jar" />
|
||||
<zipfileset src="../../jetty/jettylib/jetty-deploy.jar" />
|
||||
<zipfileset src="../../jetty/jettylib/jetty-http.jar" />
|
||||
<zipfileset src="../../jetty/jettylib/jetty-i2p.jar" />
|
||||
<zipfileset src="../../jetty/jettylib/jetty-io.jar" />
|
||||
<zipfileset src="../../jetty/jettylib/jetty-security.jar" />
|
||||
<zipfileset src="../../jetty/jettylib/jetty-servlet.jar" />
|
||||
<zipfileset src="../../jetty/jettylib/jetty-util.jar" />
|
||||
<zipfileset src="../../jetty/jettylib/jetty-webapp.jar" />
|
||||
<zipfileset src="../../jetty/jettylib/jetty-xml.jar" />
|
||||
<zipfileset src="../../jetty/jettylib/org.mortbay.jetty.jar" />
|
||||
<zipfileset src="../../ministreaming/java/build/mstreaming.jar" />
|
||||
<zipfileset src="../../streaming/java/build/streaming.jar" />
|
||||
<zipfileset src="../../systray/java/build/systray.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... -->
|
||||
<!--
|
||||
<fileset dir="../../routerconsole/java/build/obj" includes="net/i2p/router/countries/*.class" />
|
||||
-->
|
||||
<manifest>
|
||||
<attribute name="Main-Class" value="org.klomp.snark.standalone.RunStandalone"/>
|
||||
<attribute name="Implementation-Version" value="${full.version}" />
|
||||
<attribute name="Built-By" value="${build.built-by}" />
|
||||
<attribute name="Build-Date" value="${build.timestamp}" />
|
||||
<attribute name="Base-Revision" value="${workspace.version}" />
|
||||
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
|
||||
<!-- this is so Jetty will report its version correctly -->
|
||||
<section name="org/eclipse/jetty/server/" >
|
||||
<attribute name="Implementation-Vendor" value="Eclipse.org - Jetty" />
|
||||
<attribute name="Implementation-Version" value="8.1.17.v20150415" />
|
||||
</section>
|
||||
</manifest>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<!-- add css, image, and js files for standalone snark to the war -->
|
||||
<target name="standalone_war" depends="war">
|
||||
<mkdir dir="build/standalone-resources/.resources/themes/snark" />
|
||||
<copy todir="build/standalone-resources/.resources/themes/snark" >
|
||||
<fileset dir="../../../installer/resources/themes/snark/" />
|
||||
</copy>
|
||||
<replace dir="build/standalone-resources/.resources/themes/snark"
|
||||
summary="true"
|
||||
token="url('/themes/"
|
||||
value="url('/i2psnark/.resources/themes/" >
|
||||
<include name="**/*.css" />
|
||||
</replace>
|
||||
<replace dir="build/standalone-resources/.resources/themes/snark"
|
||||
summary="true"
|
||||
token="url('../../console/images/"
|
||||
value="url('/i2psnark/.resources/themes/snark/ubergine/images/" >
|
||||
<include name="**/*.css" />
|
||||
</replace>
|
||||
<replace dir="build/standalone-resources/.resources/themes/snark"
|
||||
summary="true"
|
||||
token="url('../../console/dark/images/"
|
||||
value="url('/i2psnark/.resources/themes/snark/ubergine/images/" >
|
||||
<include name="**/*.css" />
|
||||
</replace>
|
||||
<replace dir="build/standalone-resources/.resources/themes/snark"
|
||||
summary="true"
|
||||
token="url('../../console/light/images/"
|
||||
value="url('/i2psnark/.resources/themes/snark/ubergine/images/" >
|
||||
<include name="**/*.css" />
|
||||
</replace>
|
||||
<replace dir="build/standalone-resources/.resources/themes/snark"
|
||||
summary="true"
|
||||
token="url('images/"
|
||||
value="url('/i2psnark/.resources/themes/snark/ubergine/images/" >
|
||||
<include name="**/*.css" />
|
||||
</replace>
|
||||
<copy todir="build/standalone-resources/.resources/themes/snark/ubergine/images" >
|
||||
<!-- we really don't need all of these -->
|
||||
<fileset dir="../../../installer/resources/themes/console/images/" />
|
||||
</copy>
|
||||
<copy file="../../../installer/resources/themes/console/dark/images/transparent.gif"
|
||||
todir="build/standalone-resources/.resources/themes/snark/ubergine/images" />
|
||||
<copy file="../../../installer/resources/themes/console/dark/images/header.png"
|
||||
todir="build/standalone-resources/.resources/themes/snark/ubergine/images" />
|
||||
<mkdir dir="build/standalone-resources/.resources/js" />
|
||||
<copy file="../../routerconsole/jsp/js/ajax.js" todir="build/standalone-resources/.resources/js" />
|
||||
<zip destfile="../i2psnark.war" update="true" duplicate="preserve" >
|
||||
<fileset dir="build/standalone-resources" />
|
||||
</zip>
|
||||
</target>
|
||||
|
||||
<target name="standalone_prep" depends="standalone_jar, standalone_war">
|
||||
<delete dir="./dist" />
|
||||
<mkdir dir="./dist" />
|
||||
<copy file="../launch-i2psnark" todir="./dist/" />
|
||||
<copy file="../launch-i2psnark.bat" todir="./dist/" />
|
||||
<mkdir dir="./dist/contexts" />
|
||||
<copy file="../standalone-context.xml" tofile="./dist/contexts/context.xml" />
|
||||
<mkdir dir="./dist/docroot" />
|
||||
<copy file="../standalone-index.html" tofile="./dist/docroot/index.html" />
|
||||
<mkdir dir="./dist/webapps" />
|
||||
<copy file="../i2psnark.war" tofile="./dist/webapps/i2psnark.war" />
|
||||
<mkdir dir="./dist/lib" />
|
||||
<copy file="./build/i2psnark.jar" tofile="./dist/lib/i2psnark.jar" />
|
||||
<copy file="../../../core/java/build/i2p.jar" tofile="./dist/lib/i2p.jar" />
|
||||
<copy file="../../jetty/jettylib/commons-el.jar" tofile="./dist/lib/commons-el.jar" />
|
||||
<copy file="../../jetty/jettylib/commons-logging.jar" tofile="./dist/lib/commons-logging.jar" />
|
||||
<copy file="../../jetty/jettylib/javax.servlet.jar" tofile="./dist/lib/javax.servlet.jar" />
|
||||
<copy file="../../jetty/jettylib/org.mortbay.jetty.jar" tofile="./dist/lib/org.mortbay.jetty.jar" />
|
||||
<copy file="../../jetty/jettylib/jasper-runtime.jar" tofile="./dist/lib/jasper-runtime.jar" />
|
||||
<copy file="../../ministreaming/java/build/mstreaming.jar" tofile="./dist/lib/mstreaming.jar" />
|
||||
<copy file="../../streaming/java/build/streaming.jar" tofile="./dist/lib/streaming.jar" />
|
||||
<copy file="../jetty-i2psnark.xml" tofile="./dist/jetty-i2psnark.xml" />
|
||||
<copy file="./build/i2psnark-standalone.jar" tofile="./dist/i2psnark.jar" />
|
||||
<copy file="../readme-standalone.txt" tofile="./dist/readme.txt" />
|
||||
<!-- temp so announces work -->
|
||||
<copy file="../../../installer/resources/hosts.txt" tofile="./dist/hosts.txt" />
|
||||
<copy todir="./dist/licenses" >
|
||||
<fileset dir="../../../licenses" includes="LICENSE-GPLv2.txt, ABOUT-Jetty.html" />
|
||||
</copy>
|
||||
<mkdir dir="./dist/logs" />
|
||||
|
||||
<zip destfile="i2psnark-standalone.zip">
|
||||
<zipfileset dir="./dist/" prefix="i2psnark/" />
|
||||
</zip>
|
||||
</target>
|
||||
|
||||
<target name="clean">
|
||||
|
||||
@@ -48,7 +48,7 @@ public class BitField
|
||||
* as set by the given byte array. This will make a copy of the array.
|
||||
* Extra bytes will be ignored.
|
||||
*
|
||||
* @exception ArrayOutOfBoundsException if give byte array is not large
|
||||
* @throws IndexOutOfBoundsException if give byte array is not large
|
||||
* enough.
|
||||
*/
|
||||
public BitField(byte[] bitfield, int size)
|
||||
@@ -90,7 +90,7 @@ public class BitField
|
||||
/**
|
||||
* Sets the given bit to true.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if bit is smaller then zero
|
||||
* @throws IndexOutOfBoundsException if bit is smaller then zero
|
||||
* bigger then size (inclusive).
|
||||
*/
|
||||
public void set(int bit)
|
||||
@@ -110,7 +110,7 @@ public class BitField
|
||||
/**
|
||||
* Sets the given bit to false.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if bit is smaller then zero
|
||||
* @throws IndexOutOfBoundsException if bit is smaller then zero
|
||||
* bigger then size (inclusive).
|
||||
* @since 0.9.22
|
||||
*/
|
||||
@@ -141,7 +141,7 @@ public class BitField
|
||||
/**
|
||||
* Return true if the bit is set or false if it is not.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if bit is smaller then zero
|
||||
* @throws IndexOutOfBoundsException if bit is smaller then zero
|
||||
* bigger then size (inclusive).
|
||||
*/
|
||||
public boolean get(int bit)
|
||||
|
||||
@@ -357,12 +357,12 @@ public class I2PSnarkUtil {
|
||||
public File get(String url, boolean rewrite) { return get(url, rewrite, 0); }
|
||||
|
||||
/**
|
||||
* @param retries if < 0, set timeout to a few seconds
|
||||
* @param retries if < 0, set timeout to a few seconds
|
||||
*/
|
||||
public File get(String url, int retries) { return get(url, true, retries); }
|
||||
|
||||
/**
|
||||
* @param retries if < 0, set timeout to a few seconds
|
||||
* @param retries if < 0, set timeout to a few seconds
|
||||
*/
|
||||
public File get(String url, boolean rewrite, int retries) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
@@ -413,7 +413,7 @@ public class I2PSnarkUtil {
|
||||
|
||||
/**
|
||||
* Fetch to memory
|
||||
* @param retries if < 0, set timeout to a few seconds
|
||||
* @param retries if < 0, set timeout to a few seconds
|
||||
* @param initialSize buffer size
|
||||
* @param maxSize fails if greater
|
||||
* @return null on error
|
||||
@@ -659,7 +659,7 @@ public class I2PSnarkUtil {
|
||||
*
|
||||
* @param s string to be translated containing {0}
|
||||
* The {0} will be replaced by the parameter.
|
||||
* Single quotes must be doubled, i.e. ' -> '' in the string.
|
||||
* Single quotes must be doubled, i.e. ' -> '' in the string.
|
||||
* @param o parameter, not translated.
|
||||
* To translate parameter also, use _t("foo {0} bar", _t("baz"))
|
||||
* Do not double the single quotes in the parameter.
|
||||
|
||||
@@ -161,7 +161,7 @@ class MagnetState {
|
||||
|
||||
/**
|
||||
* @return true if this was the last piece
|
||||
* @throws NPE, IllegalArgumentException, IOException, ...
|
||||
* @throws NullPointerException IllegalArgumentException, IOException, ...
|
||||
*/
|
||||
public boolean saveChunk(int chunk, byte[] data, int off, int length) throws Exception {
|
||||
if (!isInitialized)
|
||||
@@ -185,7 +185,7 @@ class MagnetState {
|
||||
|
||||
/**
|
||||
* @return true if this was the last piece
|
||||
* @throws NPE, IllegalArgumentException, IOException, ...
|
||||
* @throws NullPointerException IllegalArgumentException, IOException, ...
|
||||
*/
|
||||
private MetaInfo buildMetaInfo() throws Exception {
|
||||
// top map has nothing in it but the info map (no announce)
|
||||
|
||||
@@ -464,7 +464,7 @@ public class MetaInfo
|
||||
* Return the length of a piece. All pieces are of equal length
|
||||
* except for the last one (<code>getPieces()-1</code>).
|
||||
*
|
||||
* @exception IndexOutOfBoundsException when piece is equal to or
|
||||
* @throws IndexOutOfBoundsException when piece is equal to or
|
||||
* greater then the number of pieces in the torrent.
|
||||
*/
|
||||
public int getPieceLength(int piece)
|
||||
|
||||
@@ -115,7 +115,7 @@ public class Peer implements Comparable<Peer>
|
||||
* the connect() method.
|
||||
*
|
||||
* @param metainfo null if in magnet mode
|
||||
* @exception IOException when an error occurred during the handshake.
|
||||
* @throws IOException when an error occurred during the handshake.
|
||||
*/
|
||||
public Peer(final I2PSocket sock, InputStream in, OutputStream out, byte[] my_id, byte[] infohash, MetaInfo metainfo)
|
||||
throws IOException
|
||||
|
||||
@@ -65,6 +65,7 @@ class PeerCheckerTask implements Runnable
|
||||
Peer worstDownloader = null;
|
||||
|
||||
int uploaders = 0;
|
||||
int interestedUploaders = 0;
|
||||
int removedCount = 0;
|
||||
|
||||
long uploaded = 0;
|
||||
@@ -76,7 +77,9 @@ class PeerCheckerTask implements Runnable
|
||||
int uploadLimit = coordinator.allowedUploaders();
|
||||
boolean overBWLimit = coordinator.overUpBWLimit();
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("peers: " + peerList.size() + " limit: " + uploadLimit + " overBW? " + overBWLimit);
|
||||
_log.debug("START peers: " + peerList.size() + " uploaders: " + coordinator.getUploaders() +
|
||||
" interested: " + coordinator.getInterestedUploaders() +
|
||||
" limit: " + uploadLimit + " overBW? " + overBWLimit);
|
||||
DHT dht = _util.getDHT();
|
||||
for (Peer peer : peerList) {
|
||||
|
||||
@@ -98,7 +101,9 @@ class PeerCheckerTask implements Runnable
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!peer.isChoking())
|
||||
// we only count choking AND interested, so as not to steal a slot
|
||||
// from some other torrent
|
||||
if (peer.isInterested() && !peer.isChoking())
|
||||
uploaders++;
|
||||
|
||||
long upload = peer.getUploaded();
|
||||
@@ -128,20 +133,23 @@ class PeerCheckerTask implements Runnable
|
||||
// If we are at our max uploaders and we have lots of other
|
||||
// interested peers try to make some room.
|
||||
// (Note use of coordinator.uploaders)
|
||||
if (((coordinator.uploaders == uploadLimit
|
||||
&& coordinator.interestedAndChoking > 0)
|
||||
|| coordinator.uploaders > uploadLimit
|
||||
|| overBWLimitChoke)
|
||||
int cup = coordinator.getUploaders();
|
||||
if (((cup == uploadLimit
|
||||
&& coordinator.getInterestedAndChoking() > 0)
|
||||
|| cup > uploadLimit
|
||||
|| overBWLimitChoke)
|
||||
&& !peer.isChoking())
|
||||
{
|
||||
// Check if it still wants pieces from us.
|
||||
if (!peer.isInterested())
|
||||
{
|
||||
// Note that we only choke if we are over our limits,
|
||||
// so a peer may remain unchoked even if uninterested.
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Choke uninterested peer: " + peer);
|
||||
peer.setChoking(true);
|
||||
uploaders--;
|
||||
coordinator.uploaders--;
|
||||
coordinator.decrementUploaders(false);
|
||||
|
||||
// Put it at the back of the list
|
||||
removed.add(peer);
|
||||
@@ -152,7 +160,8 @@ class PeerCheckerTask implements Runnable
|
||||
_log.debug("BW limit (" + upload + "/" + uploaded + "), choke peer: " + peer);
|
||||
peer.setChoking(true);
|
||||
uploaders--;
|
||||
coordinator.uploaders--;
|
||||
interestedUploaders--;
|
||||
coordinator.decrementUploaders(true);
|
||||
removedCount++;
|
||||
|
||||
// Put it at the back of the list for fairness, even though we won't be unchoking this time
|
||||
@@ -165,7 +174,8 @@ class PeerCheckerTask implements Runnable
|
||||
_log.debug("Choke choking peer: " + peer);
|
||||
peer.setChoking(true);
|
||||
uploaders--;
|
||||
coordinator.uploaders--;
|
||||
interestedUploaders--;
|
||||
coordinator.decrementUploaders(true);
|
||||
removedCount++;
|
||||
|
||||
// Put it at the back of the list
|
||||
@@ -178,7 +188,8 @@ class PeerCheckerTask implements Runnable
|
||||
_log.debug("Choke uninteresting peer: " + peer);
|
||||
peer.setChoking(true);
|
||||
uploaders--;
|
||||
coordinator.uploaders--;
|
||||
interestedUploaders--;
|
||||
coordinator.decrementUploaders(true);
|
||||
removedCount++;
|
||||
|
||||
// Put it at the back of the list
|
||||
@@ -193,7 +204,8 @@ class PeerCheckerTask implements Runnable
|
||||
_log.debug("Choke downloader that doesn't deliver: " + peer);
|
||||
peer.setChoking(true);
|
||||
uploaders--;
|
||||
coordinator.uploaders--;
|
||||
interestedUploaders--;
|
||||
coordinator.decrementUploaders(true);
|
||||
removedCount++;
|
||||
|
||||
// Put it at the back of the list
|
||||
@@ -230,11 +242,11 @@ class PeerCheckerTask implements Runnable
|
||||
|
||||
// Resync actual uploaders value
|
||||
// (can shift a bit by disconnecting peers)
|
||||
coordinator.uploaders = uploaders;
|
||||
coordinator.setUploaders(uploaders, interestedUploaders);
|
||||
|
||||
// Remove the worst downloader if needed. (uploader if seeding)
|
||||
if (((uploaders == uploadLimit
|
||||
&& coordinator.interestedAndChoking > 0)
|
||||
&& coordinator.getInterestedAndChoking() > 0)
|
||||
|| uploaders > uploadLimit)
|
||||
&& worstDownloader != null)
|
||||
{
|
||||
@@ -242,28 +254,34 @@ class PeerCheckerTask implements Runnable
|
||||
_log.debug("Choke worst downloader: " + worstDownloader);
|
||||
|
||||
worstDownloader.setChoking(true);
|
||||
coordinator.uploaders--;
|
||||
coordinator.decrementUploaders(worstDownloader.isInterested());
|
||||
removedCount++;
|
||||
|
||||
// Put it at the back of the list
|
||||
removed.add(worstDownloader);
|
||||
}
|
||||
|
||||
// Optimistically unchoke a peer
|
||||
if ((!overBWLimit) && !coordinator.overUpBWLimit(uploaded))
|
||||
coordinator.unchokePeer();
|
||||
|
||||
// Put peers back at the end of the list that we removed earlier.
|
||||
boolean coordOver = coordinator.overUpBWLimit(uploaded);
|
||||
synchronized (coordinator.peers) {
|
||||
if ((!overBWLimit) && !coordOver) {
|
||||
// Optimistically unchoke a peer
|
||||
// must be called inside synch
|
||||
coordinator.unchokePeer();
|
||||
}
|
||||
// Put peers back at the end of the list that we removed earlier.
|
||||
for(Peer peer : removed) {
|
||||
if (coordinator.peers.remove(peer))
|
||||
coordinator.peers.add(peer);
|
||||
}
|
||||
}
|
||||
coordinator.interestedAndChoking += removedCount;
|
||||
|
||||
coordinator.addInterestedAndChoking(removedCount);
|
||||
|
||||
// store the rates
|
||||
coordinator.setRateHistory(uploaded, downloaded);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("END peers: " + peerList.size() + " uploaders: " + uploaders +
|
||||
" interested: " + interestedUploaders);
|
||||
|
||||
// close out unused files, but we don't need to do it every time
|
||||
Storage storage = coordinator.getStorage();
|
||||
|
||||
@@ -33,6 +33,7 @@ import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
@@ -74,16 +75,23 @@ class PeerCoordinator implements PeerListener
|
||||
public static final long MAX_INACTIVE = 8*60*1000;
|
||||
|
||||
/**
|
||||
* Approximation of the number of current uploaders.
|
||||
* Approximation of the number of current uploaders (unchoked peers),
|
||||
* whether interested or not.
|
||||
* Resynced by PeerChecker once in a while.
|
||||
* External use by PeerCheckerTask only.
|
||||
*/
|
||||
int uploaders;
|
||||
private final AtomicInteger uploaders = new AtomicInteger();
|
||||
|
||||
/**
|
||||
* Approximation of the number of current uploaders (unchoked peers),
|
||||
* that are interested.
|
||||
* Resynced by PeerChecker once in a while.
|
||||
*/
|
||||
private final AtomicInteger interestedUploaders = new AtomicInteger();
|
||||
|
||||
/**
|
||||
* External use by PeerCheckerTask only.
|
||||
*/
|
||||
int interestedAndChoking;
|
||||
private final AtomicInteger interestedAndChoking = new AtomicInteger();
|
||||
|
||||
// final static int MAX_DOWNLOADERS = MAX_CONNECTIONS;
|
||||
// int downloaders = 0;
|
||||
@@ -377,7 +385,7 @@ class PeerCoordinator implements PeerListener
|
||||
|
||||
/**
|
||||
* Inbound.
|
||||
* Not halted, peers < max.
|
||||
* Not halted, peers < max.
|
||||
* @since 0.9.1
|
||||
*/
|
||||
public boolean needPeers()
|
||||
@@ -387,7 +395,7 @@ class PeerCoordinator implements PeerListener
|
||||
|
||||
/**
|
||||
* Outbound.
|
||||
* Not halted, peers < max, and need pieces.
|
||||
* Not halted, peers < max, and need pieces.
|
||||
* @since 0.9.1
|
||||
*/
|
||||
public boolean needOutboundPeers() {
|
||||
@@ -627,8 +635,9 @@ class PeerCoordinator implements PeerListener
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// (Optimistically) unchoke. Should be called with peers synchronized
|
||||
/**
|
||||
* (Optimistically) unchoke. Must be called with peers synchronized
|
||||
*/
|
||||
void unchokePeer()
|
||||
{
|
||||
// linked list will contain all interested peers that we choke.
|
||||
@@ -645,7 +654,7 @@ class PeerCoordinator implements PeerListener
|
||||
if (peer.isChoking() && peer.isInterested())
|
||||
{
|
||||
count++;
|
||||
if (uploaders < maxUploaders)
|
||||
if (uploaders.get() < maxUploaders)
|
||||
{
|
||||
if (peer.isInteresting() && !peer.isChoked())
|
||||
interested.add(unchokedCount++, peer);
|
||||
@@ -655,20 +664,22 @@ class PeerCoordinator implements PeerListener
|
||||
}
|
||||
}
|
||||
|
||||
while (uploaders < maxUploaders && !interested.isEmpty())
|
||||
int up = uploaders.get();
|
||||
while (up < maxUploaders && !interested.isEmpty())
|
||||
{
|
||||
Peer peer = interested.remove(0);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Unchoke: " + peer);
|
||||
peer.setChoking(false);
|
||||
uploaders++;
|
||||
up = uploaders.incrementAndGet();
|
||||
interestedUploaders.incrementAndGet();
|
||||
count--;
|
||||
// Put peer back at the end of the list.
|
||||
peers.remove(peer);
|
||||
peers.add(peer);
|
||||
peerCount = peers.size();
|
||||
}
|
||||
interestedAndChoking = count;
|
||||
interestedAndChoking.set(count);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1098,11 +1109,12 @@ class PeerCoordinator implements PeerListener
|
||||
{
|
||||
if (interest)
|
||||
{
|
||||
if (uploaders < allowedUploaders())
|
||||
if (uploaders.get() < allowedUploaders())
|
||||
{
|
||||
if(peer.isChoking())
|
||||
{
|
||||
uploaders++;
|
||||
uploaders.incrementAndGet();
|
||||
interestedUploaders.incrementAndGet();
|
||||
peer.setChoking(false);
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Unchoke: " + peer);
|
||||
@@ -1487,22 +1499,102 @@ class PeerCoordinator implements PeerListener
|
||||
*/
|
||||
public int allowedUploaders()
|
||||
{
|
||||
if (listener != null && listener.overUploadLimit(uploaders)) {
|
||||
int up = uploaders.get();
|
||||
if (listener != null && listener.overUploadLimit(interestedUploaders.get())) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Over limit, uploaders was: " + uploaders);
|
||||
return uploaders - 1;
|
||||
} else if (uploaders < MAX_UPLOADERS)
|
||||
return uploaders + 1;
|
||||
else
|
||||
_log.debug("Over limit, uploaders was: " + up);
|
||||
return up - 1;
|
||||
} else if (up < MAX_UPLOADERS) {
|
||||
return up + 1;
|
||||
} else {
|
||||
return MAX_UPLOADERS;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploaders whether interested or not
|
||||
* Use this for per-torrent limits.
|
||||
*
|
||||
* @return current
|
||||
* @since 0.8.4
|
||||
*/
|
||||
public int getUploaders() {
|
||||
return uploaders;
|
||||
int rv = uploaders.get();
|
||||
if (rv > 0) {
|
||||
int max = getPeers();
|
||||
if (rv > max)
|
||||
rv = max;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploaders, interested only.
|
||||
* Use this to calculate the global total, so that
|
||||
* unchoked but uninterested peers don't count against the global limit.
|
||||
*
|
||||
* @return current
|
||||
* @since 0.9.28
|
||||
*/
|
||||
public int getInterestedUploaders() {
|
||||
int rv = interestedUploaders.get();
|
||||
if (rv > 0) {
|
||||
int max = getPeers();
|
||||
if (rv > max)
|
||||
rv = max;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the uploaders and interestedUploaders counts
|
||||
*
|
||||
* @since 0.9.28
|
||||
* @param upl whether interested or not
|
||||
* @param inter interested only
|
||||
*/
|
||||
public void setUploaders(int upl, int inter) {
|
||||
if (upl < 0)
|
||||
upl = 0;
|
||||
else if (upl > MAX_UPLOADERS)
|
||||
upl = MAX_UPLOADERS;
|
||||
uploaders.set(upl);
|
||||
if (inter < 0)
|
||||
inter = 0;
|
||||
else if (inter > MAX_UPLOADERS)
|
||||
inter = MAX_UPLOADERS;
|
||||
interestedUploaders.set(inter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrement the uploaders and (if set) the interestedUploaders counts
|
||||
*
|
||||
* @since 0.9.28
|
||||
*/
|
||||
public void decrementUploaders(boolean isInterested) {
|
||||
int up = uploaders.decrementAndGet();
|
||||
if (up < 0)
|
||||
uploaders.set(0);
|
||||
if (isInterested) {
|
||||
up = interestedUploaders.decrementAndGet();
|
||||
if (up < 0)
|
||||
interestedUploaders.set(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return current
|
||||
* @since 0.9.28
|
||||
*/
|
||||
public int getInterestedAndChoking() {
|
||||
return interestedAndChoking.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.28
|
||||
*/
|
||||
public void addInterestedAndChoking(int toAdd) {
|
||||
interestedAndChoking.addAndGet(toAdd);
|
||||
}
|
||||
|
||||
public boolean overUpBWLimit()
|
||||
|
||||
@@ -212,6 +212,7 @@ public class Snark
|
||||
|
||||
***********/
|
||||
|
||||
/** max connections */
|
||||
public static final String PROP_MAX_CONNECTIONS = "i2psnark.maxConnections";
|
||||
|
||||
/** most of these used to be public, use accessors below instead */
|
||||
@@ -1337,7 +1338,7 @@ public class Snark
|
||||
int totalUploaders = 0;
|
||||
for (PeerCoordinator c : _peerCoordinatorSet) {
|
||||
if (!c.halted())
|
||||
totalUploaders += c.uploaders;
|
||||
totalUploaders += c.getInterestedUploaders();
|
||||
}
|
||||
int limit = _util.getMaxUploaders();
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
|
||||
@@ -42,6 +42,8 @@ import net.i2p.util.SecureDirectory;
|
||||
import net.i2p.util.SecureFileOutputStream;
|
||||
import net.i2p.util.SimpleTimer;
|
||||
import net.i2p.util.SimpleTimer2;
|
||||
import net.i2p.util.SystemVersion;
|
||||
import net.i2p.util.Translate;
|
||||
|
||||
import org.klomp.snark.dht.DHT;
|
||||
import org.klomp.snark.dht.KRPC;
|
||||
@@ -127,6 +129,8 @@ public class SnarkManager implements CompleteListener {
|
||||
public static final String PROP_PRIVATETRACKERS = "i2psnark.privatetrackers";
|
||||
private static final String PROP_USE_DHT = "i2psnark.enableDHT";
|
||||
private static final String PROP_SMART_SORT = "i2psnark.smartSort";
|
||||
private static final String PROP_LANG = "i2psnark.lang";
|
||||
private static final String PROP_COUNTRY = "i2psnark.country";
|
||||
|
||||
public static final int MIN_UP_BW = 10;
|
||||
public static final int DEFAULT_MAX_UP_BW = 25;
|
||||
@@ -136,7 +140,7 @@ public class SnarkManager implements CompleteListener {
|
||||
public static final int DEFAULT_TUNNEL_QUANTITY = 3;
|
||||
public static final String CONFIG_DIR_SUFFIX = ".d";
|
||||
private static final String SUBDIR_PREFIX = "s";
|
||||
private static final String B64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-~";
|
||||
private static final String B64 = Base64.ALPHABET_I2P;
|
||||
|
||||
/**
|
||||
* "name", "announceURL=websiteURL" pairs
|
||||
@@ -233,6 +237,8 @@ public class SnarkManager implements CompleteListener {
|
||||
_configFile = new File(_configDir, CONFIG_FILE);
|
||||
_trackerMap = new ConcurrentHashMap<String, Tracker>(4);
|
||||
loadConfig(null);
|
||||
if (!ctx.isRouterContext())
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(new TempDeleter(_util.getTempDir()), "Snark Temp Dir Deleter"));
|
||||
}
|
||||
|
||||
/** Caller _must_ call loadConfig(file) before this if setting new values
|
||||
@@ -245,13 +251,30 @@ public class SnarkManager implements CompleteListener {
|
||||
_monitor = new I2PAppThread(new DirMonitor(), "Snark DirMonitor", true);
|
||||
_monitor.start();
|
||||
// only if default instance
|
||||
if ("i2psnark".equals(_contextName))
|
||||
if (_context.isRouterContext() && "i2psnark".equals(_contextName))
|
||||
// delay until UpdateManager is there
|
||||
_context.simpleTimer2().addEvent(new Register(), 4*60*1000);
|
||||
// Not required, Jetty has a shutdown hook
|
||||
//_context.addShutdownTask(new SnarkManagerShutdown());
|
||||
_idleChecker = new IdleChecker(this, _peerCoordinatorSet);
|
||||
_idleChecker.schedule(5*60*1000);
|
||||
if (!_context.isRouterContext()) {
|
||||
String lang = _config.getProperty(PROP_LANG);
|
||||
if (lang != null) {
|
||||
String country = _config.getProperty(PROP_COUNTRY, "");
|
||||
Translate.setLanguage(lang, country);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Only used in app context
|
||||
* @since 0.9.27
|
||||
*/
|
||||
private static class TempDeleter implements Runnable {
|
||||
private final File file;
|
||||
public TempDeleter(File f) { file = f; }
|
||||
public void run() { FileUtil.rmdir(file, false); }
|
||||
}
|
||||
|
||||
/** @since 0.9.4 */
|
||||
@@ -280,6 +303,8 @@ public class SnarkManager implements CompleteListener {
|
||||
* Runs inline.
|
||||
*/
|
||||
public void stop() {
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Snark stop() begin", new Exception("I did it"));
|
||||
if (_umgr != null && _uhandler != null) {
|
||||
//_uhandler.shutdown();
|
||||
_umgr.unregister(_uhandler, UpdateType.ROUTER_SIGNED, UpdateMethod.TORRENT);
|
||||
@@ -290,6 +315,8 @@ public class SnarkManager implements CompleteListener {
|
||||
_connectionAcceptor.halt();
|
||||
_idleChecker.cancel();
|
||||
stopAllTorrents(true);
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Snark stop() end");
|
||||
}
|
||||
|
||||
/** @since 0.9.1 */
|
||||
@@ -302,7 +329,7 @@ public class SnarkManager implements CompleteListener {
|
||||
|
||||
/**
|
||||
* Use if it does not include a link.
|
||||
* Escapes '<' and '>' before queueing
|
||||
* Escapes '<' and '>' before queueing
|
||||
*/
|
||||
public void addMessage(String message) {
|
||||
addMessageNoEscape(message.replace("<", "<").replace(">", ">"));
|
||||
@@ -310,7 +337,7 @@ public class SnarkManager implements CompleteListener {
|
||||
|
||||
/**
|
||||
* Use if it includes a link.
|
||||
* Does not escape '<' and '>' before queueing
|
||||
* Does not escape '<' and '>' before queueing
|
||||
* @since 0.9.14.1
|
||||
*/
|
||||
public void addMessageNoEscape(String message) {
|
||||
@@ -388,6 +415,8 @@ public class SnarkManager implements CompleteListener {
|
||||
}
|
||||
|
||||
private int getStartupDelayMinutes() {
|
||||
if (!_context.isRouterContext())
|
||||
return 0;
|
||||
try {
|
||||
return Integer.parseInt(_config.getProperty(PROP_STARTUP_DELAY));
|
||||
} catch (NumberFormatException nfe) {
|
||||
@@ -675,7 +704,8 @@ public class SnarkManager implements CompleteListener {
|
||||
* @return String[] -- Array of all the themes found, non-null, unsorted
|
||||
*/
|
||||
public String[] getThemes() {
|
||||
String[] themes;
|
||||
String[] themes;
|
||||
if (_context.isRouterContext()) {
|
||||
// "docs/themes/snark/"
|
||||
File dir = new File(_context.getBaseDir(), "docs/themes/snark");
|
||||
FileFilter fileFilter = new FileFilter() { public boolean accept(File file) { return file.isDirectory(); } };
|
||||
@@ -689,8 +719,10 @@ public class SnarkManager implements CompleteListener {
|
||||
} else {
|
||||
themes = new String[0];
|
||||
}
|
||||
// return the map.
|
||||
return themes;
|
||||
} else {
|
||||
themes = new String[] { "light", "ubergine", "vanilla" };
|
||||
}
|
||||
return themes;
|
||||
}
|
||||
|
||||
|
||||
@@ -757,19 +789,22 @@ public class SnarkManager implements CompleteListener {
|
||||
public void updateConfig(String dataDir, boolean filesPublic, boolean autoStart, boolean smartSort, String refreshDelay,
|
||||
String startDelay, String pageSize, String seedPct, String eepHost,
|
||||
String eepPort, String i2cpHost, String i2cpPort, String i2cpOpts,
|
||||
String upLimit, String upBW, boolean useOpenTrackers, boolean useDHT, String theme) {
|
||||
String upLimit, String upBW, boolean useOpenTrackers, boolean useDHT, String theme,
|
||||
String lang) {
|
||||
synchronized(_configLock) {
|
||||
locked_updateConfig(dataDir, filesPublic, autoStart, smartSort,refreshDelay,
|
||||
startDelay, pageSize, seedPct, eepHost,
|
||||
eepPort, i2cpHost, i2cpPort, i2cpOpts,
|
||||
upLimit, upBW, useOpenTrackers, useDHT, theme);
|
||||
upLimit, upBW, useOpenTrackers, useDHT, theme,
|
||||
lang);
|
||||
}
|
||||
}
|
||||
|
||||
private void locked_updateConfig(String dataDir, boolean filesPublic, boolean autoStart, boolean smartSort, String refreshDelay,
|
||||
String startDelay, String pageSize, String seedPct, String eepHost,
|
||||
String eepPort, String i2cpHost, String i2cpPort, String i2cpOpts,
|
||||
String upLimit, String upBW, boolean useOpenTrackers, boolean useDHT, String theme) {
|
||||
String upLimit, String upBW, boolean useOpenTrackers, boolean useDHT, String theme,
|
||||
String lang) {
|
||||
boolean changed = false;
|
||||
boolean interruptMonitor = false;
|
||||
//if (eepHost != null) {
|
||||
@@ -815,7 +850,7 @@ public class SnarkManager implements CompleteListener {
|
||||
}
|
||||
}
|
||||
|
||||
if (startDelay != null){
|
||||
if (startDelay != null && _context.isRouterContext()) {
|
||||
int minutes = _util.getStartupDelay();
|
||||
try { minutes = Integer.parseInt(startDelay.trim()); } catch (NumberFormatException nfe) {}
|
||||
if ( minutes != _util.getStartupDelay()) {
|
||||
@@ -876,6 +911,32 @@ public class SnarkManager implements CompleteListener {
|
||||
|
||||
}
|
||||
|
||||
// Standalone (app context) language.
|
||||
// lang will generally be null since it is hidden from the form if in router context.
|
||||
|
||||
if (lang != null && !_context.isRouterContext() &&
|
||||
lang.length() >= 2 && lang.length() <= 6) {
|
||||
int under = lang.indexOf('_');
|
||||
String nlang, ncountry;
|
||||
if (under > 0 && lang.length() > under + 1) {
|
||||
nlang = lang.substring(0, under);
|
||||
ncountry = lang.substring(under + 1);
|
||||
} else {
|
||||
nlang = lang;
|
||||
ncountry = "";
|
||||
}
|
||||
String olang = _config.getProperty(PROP_LANG);
|
||||
String ocountry = _config.getProperty(PROP_COUNTRY);
|
||||
if (!nlang.equals(olang) || !ncountry.equals(ocountry)) {
|
||||
changed = true;
|
||||
_config.setProperty(PROP_LANG, nlang);
|
||||
_config.setProperty(PROP_COUNTRY, ncountry);
|
||||
Translate.setLanguage(nlang, ncountry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Start of I2CP stuff.
|
||||
// i2cpHost will generally be null since it is hidden from the form if in router context.
|
||||
|
||||
@@ -2502,7 +2563,7 @@ public class SnarkManager implements CompleteListener {
|
||||
/**
|
||||
* Stop all running torrents, and close the tunnel after a delay
|
||||
* to allow for announces.
|
||||
* If called at router shutdown via Jetty shutdown hook -> webapp destroy() -> stop(),
|
||||
* If called at router shutdown via Jetty shutdown hook -> webapp destroy() -> stop(),
|
||||
* the tunnel won't actually be closed as the SimpleTimer2 is already shutdown
|
||||
* or will be soon, so we delay a few seconds inline.
|
||||
* @param finalShutdown if true, sleep at the end if any torrents were running
|
||||
@@ -2524,7 +2585,9 @@ public class SnarkManager implements CompleteListener {
|
||||
stopTorrent(snark, false);
|
||||
// Throttle since every unannounce is now threaded.
|
||||
// How to do this without creating a ton of threads?
|
||||
try { Thread.sleep(20); } catch (InterruptedException ie) {}
|
||||
if (count % 8 == 0) {
|
||||
try { Thread.sleep(20); } catch (InterruptedException ie) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_util.connected()) {
|
||||
@@ -2537,8 +2600,12 @@ public class SnarkManager implements CompleteListener {
|
||||
_context.simpleTimer2().addEvent(new Disconnector(), 60*1000);
|
||||
addMessage(_t("Closing I2P tunnel after notifying trackers."));
|
||||
if (finalShutdown) {
|
||||
try { Thread.sleep(5*1000); } catch (InterruptedException ie) {}
|
||||
long toWait = 5*1000;
|
||||
if (SystemVersion.isARM())
|
||||
toWait *= 2;
|
||||
try { Thread.sleep(toWait); } catch (InterruptedException ie) {}
|
||||
}
|
||||
_util.disconnect();
|
||||
} else {
|
||||
_util.disconnect();
|
||||
_stopping = false;
|
||||
|
||||
@@ -436,7 +436,7 @@ public class Storage implements Closeable
|
||||
* Must call Snark.updatePiecePriorities()
|
||||
* (which calls getPiecePriorities()) after calling this.
|
||||
* @param fileIndex as obtained from indexOf
|
||||
* @param pri default 0; <0 to disable
|
||||
* @param pri default 0; <0 to disable
|
||||
* @since 0.8.1
|
||||
*/
|
||||
public void setPriority(int fileIndex, int pri) {
|
||||
@@ -695,7 +695,7 @@ public class Storage implements Closeable
|
||||
* Doesn't really reopen the file descriptors for a restart.
|
||||
* Just does an existence check but no length check or data reverification
|
||||
*
|
||||
* @throws IOE on fail
|
||||
* @throws IOException on fail
|
||||
*/
|
||||
public void reopen() throws IOException
|
||||
{
|
||||
@@ -1111,7 +1111,7 @@ public class Storage implements Closeable
|
||||
*
|
||||
* @return true if the piece was correct (sha metainfo hash
|
||||
* matches), otherwise false.
|
||||
* @exception IOException when some storage related error occurs.
|
||||
* @throws IOException when some storage related error occurs.
|
||||
*/
|
||||
public boolean putPiece(PartialPiece pp) throws IOException
|
||||
{
|
||||
|
||||
@@ -893,11 +893,16 @@ public class TrackerClient implements Runnable {
|
||||
} catch (URISyntaxException use) {
|
||||
return false;
|
||||
}
|
||||
String path = url.getPath();
|
||||
if (path == null || !path.startsWith("/"))
|
||||
return false;
|
||||
return "http".equals(url.getScheme()) && url.getHost() != null &&
|
||||
(url.getHost().endsWith(".i2p") || url.getHost().equals("i2p"));
|
||||
}
|
||||
|
||||
/**
|
||||
* This also validates the URL.
|
||||
*
|
||||
* @param ann an announce URL non-null
|
||||
* @return a Hash for i2p hosts only, null otherwise
|
||||
* @since 0.9.5
|
||||
@@ -914,8 +919,12 @@ public class TrackerClient implements Runnable {
|
||||
String host = url.getHost();
|
||||
if (host == null)
|
||||
return null;
|
||||
if (host.endsWith(".i2p"))
|
||||
if (host.endsWith(".i2p")) {
|
||||
String path = url.getPath();
|
||||
if (path == null || !path.startsWith("/"))
|
||||
return null;
|
||||
return ConvertToHash.getHash(host);
|
||||
}
|
||||
if (host.equals("i2p")) {
|
||||
String path = url.getPath();
|
||||
if (path == null || path.length() < 517 ||
|
||||
@@ -941,11 +950,15 @@ public class TrackerClient implements Runnable {
|
||||
int consecutiveFails;
|
||||
int seenPeers;
|
||||
|
||||
/**
|
||||
* @param a must be a valid http URL with a path
|
||||
* @param p true if primary
|
||||
*/
|
||||
public TCTracker(String a, boolean p)
|
||||
{
|
||||
announce = a;
|
||||
String s = a.substring(7);
|
||||
host = s.substring(0, s.indexOf("/"));
|
||||
host = s.substring(0, s.indexOf('/'));
|
||||
isPrimary = p;
|
||||
interval = INITIAL_SLEEP;
|
||||
}
|
||||
|
||||
@@ -102,9 +102,9 @@ public class BDecoder
|
||||
* @return The first BEValue on the stream or null when the stream
|
||||
* has ended.
|
||||
*
|
||||
* @exception InvalidBEncoding when the stream doesn't start with a
|
||||
* @throws InvalidBEncodingException when the stream doesn't start with a
|
||||
* bencoded value or the stream isn't a bencoded stream at all.
|
||||
* @exception IOException when somthing bad happens with the stream
|
||||
* @throws IOException when somthing bad happens with the stream
|
||||
* to read from.
|
||||
*/
|
||||
public static BEValue bdecode(InputStream in) throws IOException
|
||||
|
||||
@@ -42,7 +42,7 @@ public interface DHT {
|
||||
*
|
||||
* @param ih the Info Hash (torrent)
|
||||
* @param max maximum number of peers to return
|
||||
* @param maxWait the maximum time to wait (ms) must be > 0
|
||||
* @param maxWait the maximum time to wait (ms) must be > 0
|
||||
* @param annMax the number of peers to announce to
|
||||
* @param annMaxWait the maximum total time to wait for announces, may be 0 to return immediately without waiting for acks
|
||||
* @param isSeed true if seed, false if leech
|
||||
@@ -81,7 +81,7 @@ public interface DHT {
|
||||
|
||||
/**
|
||||
* Announce to the closest DHT peers.
|
||||
* Blocking unless maxWait <= 0
|
||||
* Blocking unless maxWait <= 0
|
||||
* Caller should run in a thread.
|
||||
* This also automatically announces ourself to our local tracker.
|
||||
* For best results do a getPeers() first so we have tokens.
|
||||
|
||||
@@ -123,6 +123,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
|
||||
private final AtomicLong _rxBytes = new AtomicLong();
|
||||
private final AtomicLong _txBytes = new AtomicLong();
|
||||
private long _started;
|
||||
private long _nodesLastSaved;
|
||||
|
||||
/** all-zero NID used for pings */
|
||||
public static final NID FAKE_NID = new NID(new byte[NID.HASH_LENGTH]);
|
||||
@@ -156,6 +157,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
|
||||
private static final long CLEAN_TIME = 63*1000;
|
||||
private static final long EXPLORE_TIME = 877*1000;
|
||||
private static final long BLACKLIST_CLEAN_TIME = 17*60*1000;
|
||||
private static final long NODES_SAVE_TIME = 3*60*60*1000;
|
||||
public static final String DHT_FILE_SUFFIX = ".dht.dat";
|
||||
|
||||
private static final int SEND_CRYPTO_TAGS = 8;
|
||||
@@ -243,7 +245,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
|
||||
*
|
||||
* @param target the key we are searching for
|
||||
* @param maxNodes how many to contact
|
||||
* @param maxWait how long to wait for each to reply (not total) must be > 0
|
||||
* @param maxWait how long to wait for each to reply (not total) must be > 0
|
||||
* @param parallel how many outstanding at once (unimplemented, always 1)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -324,7 +326,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
|
||||
*
|
||||
* @param ih the Info Hash (torrent)
|
||||
* @param max maximum number of peers to return
|
||||
* @param maxWait the maximum time to wait (ms) must be > 0
|
||||
* @param maxWait the maximum time to wait (ms) must be > 0
|
||||
* @param annMax the number of peers to announce to
|
||||
* @param annMaxWait the maximum total time to wait for announces, may be 0 to return immediately without waiting for acks
|
||||
* @param isSeed true if seed, false if leech
|
||||
@@ -508,7 +510,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
|
||||
* Announce to the closest peers in the local DHT.
|
||||
* This is NOT iterative - call getPeers() first to get the closest
|
||||
* peers into the local DHT.
|
||||
* Blocking unless maxWait <= 0
|
||||
* Blocking unless maxWait <= 0
|
||||
* Caller should run in a thread.
|
||||
* This also automatically announces ourself to our local tracker.
|
||||
* For best results do a getPeersAndAnnounce() instead, as this announces to
|
||||
@@ -542,7 +544,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
|
||||
|
||||
/**
|
||||
* Announce to a single DHT peer.
|
||||
* Blocking unless maxWait <= 0
|
||||
* Blocking unless maxWait <= 0
|
||||
* Caller should run in a thread.
|
||||
* For best results do a getPeers() first so we have a token.
|
||||
*
|
||||
@@ -635,6 +637,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
|
||||
_txBytes.set(0);
|
||||
_rxBytes.set(0);
|
||||
_started = _context.clock().now();
|
||||
_nodesLastSaved = _started;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -866,7 +869,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
|
||||
@SuppressWarnings("unchecked")
|
||||
private ReplyWaiter sendQuery(NodeInfo nInfo, Map<String, Object> map, boolean repliable) {
|
||||
if (nInfo.equals(_myNodeInfo))
|
||||
throw new IllegalArgumentException("wtf don't send to ourselves");
|
||||
throw new IllegalArgumentException("don't send to ourselves");
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Sending query to: " + nInfo);
|
||||
if (nInfo.getDestination() == null) {
|
||||
@@ -916,7 +919,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
|
||||
@SuppressWarnings("unchecked")
|
||||
private boolean sendResponse(NodeInfo nInfo, MsgID msgID, Map<String, Object> map) {
|
||||
if (nInfo.equals(_myNodeInfo))
|
||||
throw new IllegalArgumentException("wtf don't send to ourselves");
|
||||
throw new IllegalArgumentException("don't send to ourselves");
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Sending response to: " + nInfo);
|
||||
if (nInfo.getDestination() == null) {
|
||||
@@ -946,7 +949,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
|
||||
*/
|
||||
private boolean sendError(NodeInfo nInfo, MsgID msgID, Map<String, Object> map) {
|
||||
if (nInfo.equals(_myNodeInfo))
|
||||
throw new IllegalArgumentException("wtf don't send to ourselves");
|
||||
throw new IllegalArgumentException("don't send to ourselves");
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Sending error to: " + nInfo);
|
||||
if (nInfo.getDestination() == null) {
|
||||
@@ -1004,7 +1007,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
|
||||
return false;
|
||||
}
|
||||
if (dest.calculateHash().equals(_myNodeInfo.getHash()))
|
||||
throw new IllegalArgumentException("wtf don't send to ourselves");
|
||||
throw new IllegalArgumentException("don't send to ourselves");
|
||||
byte[] payload = BEncoder.bencode(map);
|
||||
if (_log.shouldLog(Log.DEBUG)) {
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(payload);
|
||||
@@ -1020,7 +1023,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
|
||||
payload = dgMaker.makeI2PDatagram(payload);
|
||||
if (payload == null) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("WTF DGM fail");
|
||||
_log.warn("DGM fail");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1040,7 +1043,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
|
||||
_txBytes.addAndGet(payload.length);
|
||||
} else {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("WTF sendMessage fail");
|
||||
_log.warn("sendMessage fail");
|
||||
}
|
||||
return success;
|
||||
} catch (I2PSessionException ise) {
|
||||
@@ -1506,9 +1509,9 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
|
||||
|
||||
/**
|
||||
* Should contain null if getReplyCode is REPLY_PONG.
|
||||
* Should contain List<Hash> if getReplyCode is REPLY_PEERS.
|
||||
* Should contain List<NodeInfo> if getReplyCode is REPLY_NODES.
|
||||
* Should contain String if getReplyCode is > 200.
|
||||
* Should contain List<Hash> if getReplyCode is REPLY_PEERS.
|
||||
* Should contain List<NodeInfo> if getReplyCode is REPLY_NODES.
|
||||
* Should contain String if getReplyCode is > 200.
|
||||
* @return may be null depending on what happened. Cast to expected type.
|
||||
*/
|
||||
public Object getReplyObject() {
|
||||
@@ -1675,6 +1678,10 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
|
||||
if (nid.lastSeen() < expire)
|
||||
iter.remove();
|
||||
}
|
||||
if (now - _nodesLastSaved > NODES_SAVE_TIME) {
|
||||
PersistDHT.saveDHT(_knownNodes, false, _dhtFile);
|
||||
_nodesLastSaved = now;
|
||||
}
|
||||
// TODO sent queries?
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("KRPC cleaner done, now with " +
|
||||
|
||||
@@ -77,7 +77,7 @@ class NodeInfo extends SimpleDataStructure {
|
||||
* @param compactInfo 20 byte node ID, 32 byte destHash, 2 byte port
|
||||
* @param offset starting at this offset in compactInfo
|
||||
* @throws IllegalArgumentException
|
||||
* @throws AIOOBE
|
||||
* @throws ArrayIndexOutOfBoundsException
|
||||
*/
|
||||
public NodeInfo(byte[] compactInfo, int offset) {
|
||||
super();
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
package org.klomp.snark.standalone;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.util.Translate;
|
||||
|
||||
/**
|
||||
* Standalone (app context) only.
|
||||
* Copied from ConfigUIHelper.
|
||||
* @since 0.9.27
|
||||
*/
|
||||
public class ConfigUIHelper {
|
||||
|
||||
private static final String CHECKED = " selected=\"selected\" ";
|
||||
private static final String BUNDLE_NAME = "org.klomp.snark.web.messages";
|
||||
//private static final String COUNTRY_BUNDLE_NAME = "net.i2p.router.countries.messages";
|
||||
|
||||
/**
|
||||
* Each language has the ISO code, the flag, the name, and the optional country name.
|
||||
* Alphabetical by the ISO code please.
|
||||
* See http://en.wikipedia.org/wiki/ISO_639-1 .
|
||||
* Any language-specific flag added to the icon set must be
|
||||
* added to the top-level build.xml for the updater.
|
||||
* As of 0.9.12, ISO 639-2 three-letter codes are supported also.
|
||||
*
|
||||
* Note: we don't currently _x the language strings,
|
||||
* we'll just rely on the JVM's translations for now.
|
||||
* Country flag unused.
|
||||
*/
|
||||
private static final String langs[][] = {
|
||||
{ "ar", "lang_ar", "Arabic", null },
|
||||
{ "cs", "cz", "Czech", null },
|
||||
//{ "da", "dk", "Danish", null },
|
||||
{ "de", "de", "German", null },
|
||||
//{ "et", "ee", "Estonian", null },
|
||||
//{ "el", "gr", "Greek", null },
|
||||
{ "en", "us", "English", null },
|
||||
{ "es", "es", "Spanish", null },
|
||||
{ "fi", "fi", "Finnish", null },
|
||||
{ "fr", "fr", "French", null },
|
||||
//{ "gl", "lang_gl", "Galician", null },
|
||||
{ "hu", "hu", "Hungarian", null },
|
||||
{ "it", "it", "Italian", null },
|
||||
{ "ja", "jp", "Japanese", null },
|
||||
{ "ko", "kr", "Korean", null },
|
||||
//{ "mg", "mg", "Malagasy", null },
|
||||
{ "nl", "nl", "Dutch", null },
|
||||
{ "nb", "no", "Norwegian Bokmaal", null },
|
||||
{ "pl", "pl", "Polish", null },
|
||||
{ "pt", "pt", "Portuguese", null },
|
||||
{ "pt_BR", "br", "Portuguese", "Brazil" },
|
||||
{ "ro", "ro", "Romanian", null },
|
||||
{ "ru", "ru", "Russian", null },
|
||||
{ "sk", "sk", "Slovak", null },
|
||||
{ "sv", "se", "Swedish", null },
|
||||
{ "tr", "tr", "Turkish", null },
|
||||
{ "uk", "ua", "Ukrainian", null },
|
||||
{ "vi", "vn", "Vietnamese", null },
|
||||
{ "zh", "cn", "Chinese", null },
|
||||
//{ "zh_TW", "tw", "Chinese", "Taiwan" },
|
||||
{ "xx", "a1", "Debug: Find untagged strings", null },
|
||||
};
|
||||
|
||||
/**
|
||||
* Standalone (app context) only.
|
||||
* Copied from ConfigUIHelper.
|
||||
* @return HTML
|
||||
* @since 0.9.27
|
||||
*/
|
||||
public static String getLangSettings(I2PAppContext ctx) {
|
||||
String clang = Translate.getLanguage(ctx);
|
||||
String current = clang;
|
||||
String country = Translate.getCountry(ctx);
|
||||
if (country != null && country.length() > 0)
|
||||
current += '_' + country;
|
||||
// find best match
|
||||
boolean found = false;
|
||||
for (int i = 0; i < langs.length; i++) {
|
||||
if (langs[i][0].equals(current)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
if (country != null && country.length() > 0) {
|
||||
current = clang;
|
||||
for (int i = 0; i < langs.length; i++) {
|
||||
if (langs[i][0].equals(current)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
current = "en";
|
||||
}
|
||||
StringBuilder buf = new StringBuilder(512);
|
||||
buf.append("<select name=\"lang\">\n");
|
||||
for (int i = 0; i < langs.length; i++) {
|
||||
String lang = langs[i][0];
|
||||
if (lang.equals("xx") && !isAdvanced())
|
||||
continue;
|
||||
buf.append("<option ");
|
||||
if (lang.equals(current))
|
||||
buf.append(CHECKED);
|
||||
buf.append("value=\"").append(lang).append("\">");
|
||||
int under = lang.indexOf('_');
|
||||
String slang = (under > 0) ? lang.substring(0, under) : lang;
|
||||
// we don't actually have translations for these, see above
|
||||
buf.append(Translate.getDisplayLanguage(slang, langs[i][2], ctx, BUNDLE_NAME));
|
||||
String name = langs[i][3];
|
||||
if (name != null) {
|
||||
String cou = (under > 0) ? lang.substring(under + 1) : lang;
|
||||
Locale cur = new Locale(current);
|
||||
Locale loc = new Locale(slang, cou);
|
||||
buf.append(" (")
|
||||
//.append(Translate.getString(name, ctx, COUNTRY_BUNDLE_NAME))
|
||||
.append(loc.getDisplayCountry(cur))
|
||||
.append(')');
|
||||
}
|
||||
buf.append("</option>\n");
|
||||
}
|
||||
buf.append("</select>\n");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/** if necessary */
|
||||
private static boolean isAdvanced() { return false; }
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package org.klomp.snark.standalone;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.apps.systray.UrlLauncher;
|
||||
import net.i2p.jetty.JettyStart;
|
||||
|
||||
/**
|
||||
* @since moved from ../web and fixed in 0.9.27
|
||||
*/
|
||||
public class RunStandalone {
|
||||
|
||||
private final JettyStart _jettyStart;
|
||||
private final I2PAppContext _context;
|
||||
private int _port = 8002;
|
||||
private String _host = "127.0.0.1";
|
||||
private static RunStandalone _instance;
|
||||
|
||||
private RunStandalone(String args[]) throws Exception {
|
||||
_context = I2PAppContext.getGlobalContext();
|
||||
File base = _context.getBaseDir();
|
||||
File xml = new File(base, "jetty-i2psnark.xml");
|
||||
_jettyStart = new JettyStart(_context, null, new String[] { xml.getAbsolutePath() } );
|
||||
if (args.length > 1) {
|
||||
_port = Integer.parseInt(args[1]);
|
||||
}
|
||||
if (args.length > 0) {
|
||||
_host = args[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage: RunStandalone [host [port]] (but must match what's in the jetty-i2psnark.xml file)
|
||||
*/
|
||||
public synchronized static void main(String args[]) {
|
||||
try {
|
||||
RunStandalone runner = new RunStandalone(args);
|
||||
runner.start();
|
||||
_instance = runner;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
public void start() {
|
||||
try {
|
||||
_jettyStart.startup();
|
||||
String url = "http://" + _host + ':' + _port + "/i2psnark/";
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException ie) {}
|
||||
UrlLauncher launch = new UrlLauncher(_context, null, new String[] { url } );
|
||||
launch.startup();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
_jettyStart.shutdown(null);
|
||||
}
|
||||
|
||||
/** @since 0.9.27 */
|
||||
public synchronized static void shutdown() {
|
||||
if (_instance != null)
|
||||
_instance.stop();
|
||||
// JettyStart.shutdown() is threaded
|
||||
try {
|
||||
Thread.sleep(3000);
|
||||
} catch (InterruptedException ie) {}
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.Serializable;
|
||||
import java.text.Collator;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
@@ -25,6 +24,7 @@ import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import net.i2p.CoreVersion;
|
||||
import net.i2p.data.Base32;
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.data.DataHelper;
|
||||
@@ -45,6 +45,7 @@ import org.klomp.snark.Storage;
|
||||
import org.klomp.snark.Tracker;
|
||||
import org.klomp.snark.TrackerClient;
|
||||
import org.klomp.snark.dht.DHT;
|
||||
import org.klomp.snark.standalone.ConfigUIHelper;
|
||||
|
||||
/**
|
||||
* Refactored to eliminate Jetty dependencies.
|
||||
@@ -192,7 +193,10 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
return;
|
||||
}
|
||||
|
||||
_themePath = "/themes/snark/" + _manager.getTheme() + '/';
|
||||
if (_context.isRouterContext())
|
||||
_themePath = "/themes/snark/" + _manager.getTheme() + '/';
|
||||
else
|
||||
_themePath = _contextPath + WARBASE + "themes/snark/" + _manager.getTheme() + '/';
|
||||
_imgPath = _themePath + "images/";
|
||||
req.setCharacterEncoding("UTF-8");
|
||||
|
||||
@@ -285,10 +289,12 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
if (!isConfigure) {
|
||||
delay = _manager.getRefreshDelaySeconds();
|
||||
if (delay > 0) {
|
||||
String jsPfx = _context.isRouterContext() ? "" : ".resources";
|
||||
String downMsg = _context.isRouterContext() ? _t("Router is down") : _t("I2PSnark has stopped");
|
||||
//out.write("<meta http-equiv=\"refresh\" content=\"" + delay + ";/i2psnark/" + peerString + "\">\n");
|
||||
out.write("<script src=\"/js/ajax.js\" type=\"text/javascript\"></script>\n" +
|
||||
out.write("<script src=\"" + jsPfx + "/js/ajax.js\" type=\"text/javascript\"></script>\n" +
|
||||
"<script type=\"text/javascript\">\n" +
|
||||
"var failMessage = \"<div class=\\\"routerdown\\\"><b>" + _t("Router is down") + "<\\/b><\\/div>\";\n" +
|
||||
"var failMessage = \"<div class=\\\"routerdown\\\"><b>" + downMsg + "<\\/b><\\/div>\";\n" +
|
||||
"function requestAjax1() { ajax(\"" + _contextPath + "/.ajax/xhr1.html" +
|
||||
peerString.replace("&", "&") + // don't html escape in js
|
||||
"\", \"mainsection\", " + (delay*1000) + "); }\n" +
|
||||
@@ -324,17 +330,19 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
out.write(_t("I2PSnark"));
|
||||
else
|
||||
out.write(_contextName);
|
||||
out.write("</a> <a href=\"http://forum.i2p/viewforum.php?f=21\" class=\"snarkRefresh\" target=\"_blank\">");
|
||||
out.write(_t("Forum"));
|
||||
out.write("</a>\n");
|
||||
|
||||
sortedTrackers = _manager.getSortedTrackers();
|
||||
for (Tracker t : sortedTrackers) {
|
||||
if (t.baseURL == null || !t.baseURL.startsWith("http"))
|
||||
continue;
|
||||
if (_manager.util().isKnownOpenTracker(t.announceURL))
|
||||
continue;
|
||||
out.write(" <a href=\"" + t.baseURL + "\" class=\"snarkRefresh\" target=\"_blank\">" + t.name + "</a>");
|
||||
if (_context.isRouterContext()) {
|
||||
out.write("<a href=\"http://forum.i2p/viewforum.php?f=21\" class=\"snarkRefresh\" target=\"_blank\">");
|
||||
out.write(_t("Forum"));
|
||||
out.write("</a>\n");
|
||||
for (Tracker t : sortedTrackers) {
|
||||
if (t.baseURL == null || !t.baseURL.startsWith("http"))
|
||||
continue;
|
||||
if (_manager.util().isKnownOpenTracker(t.announceURL))
|
||||
continue;
|
||||
out.write(" <a href=\"" + t.baseURL + "\" class=\"snarkRefresh\" target=\"_blank\">" + t.name + "</a>");
|
||||
}
|
||||
}
|
||||
}
|
||||
out.write("</div>\n");
|
||||
@@ -380,6 +388,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
resp.setHeader("X-Frame-Options", "SAMEORIGIN");
|
||||
resp.setHeader("X-XSS-Protection", "1; mode=block");
|
||||
resp.setHeader("X-Content-Type-Options", "nosniff");
|
||||
resp.setHeader("Referrer-Policy", "no-referrer");
|
||||
}
|
||||
|
||||
private void writeMessages(PrintWriter out, boolean isConfigure, String peerString) throws IOException {
|
||||
@@ -949,6 +958,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
} else
|
||||
*****/
|
||||
if (newURL != null) {
|
||||
newURL = newURL.trim();
|
||||
String newDir = req.getParameter("nofilter_newDir");
|
||||
File dir = null;
|
||||
if (newDir != null) {
|
||||
@@ -1077,8 +1087,9 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
// should be only one
|
||||
if (df.delete())
|
||||
_manager.addMessage(_t("Data file deleted: {0}", df.getAbsolutePath()));
|
||||
else
|
||||
else if (df.exists())
|
||||
_manager.addMessage(_t("Data file could not be deleted: {0}", df.getAbsolutePath()));
|
||||
// else already gone
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1086,8 +1097,9 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
for (File df : storage.getFiles()) {
|
||||
if (df.delete()) {
|
||||
//_manager.addMessage(_t("Data file deleted: {0}", df.getAbsolutePath()));
|
||||
} else {
|
||||
} else if (df.exists()) {
|
||||
_manager.addMessage(_t("Data file could not be deleted: {0}", df.getAbsolutePath()));
|
||||
// else already gone
|
||||
}
|
||||
}
|
||||
// step 2 delete dirs bottom-up
|
||||
@@ -1101,11 +1113,12 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
if (df.delete()) {
|
||||
ok = true;
|
||||
//_manager.addMessage(_t("Data dir deleted: {0}", df.getAbsolutePath()));
|
||||
} else {
|
||||
} else if (df.exists()) {
|
||||
ok = false;
|
||||
_manager.addMessage(_t("Directory could not be deleted: {0}", df.getAbsolutePath()));
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Could not delete dir " + df);
|
||||
// else already gone
|
||||
}
|
||||
}
|
||||
// step 3 message for base (last one)
|
||||
@@ -1136,9 +1149,10 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
boolean useDHT = req.getParameter("useDHT") != null;
|
||||
//String openTrackers = req.getParameter("openTrackers");
|
||||
String theme = req.getParameter("theme");
|
||||
String lang = req.getParameter("lang");
|
||||
_manager.updateConfig(dataDir, filesPublic, autoStart, smartSort, refreshDel, startupDel, pageSize,
|
||||
seedPct, eepHost, eepPort, i2cpHost, i2cpPort, i2cpOpts,
|
||||
upLimit, upBW, useOpenTrackers, useDHT, theme);
|
||||
upLimit, upBW, useOpenTrackers, useDHT, theme, lang);
|
||||
// update servlet
|
||||
try {
|
||||
setResourceBase(_manager.getDataDir());
|
||||
@@ -1453,7 +1467,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
String fullBasename = basename;
|
||||
if (basename.length() > MAX_DISPLAYED_FILENAME_LENGTH) {
|
||||
String start = basename.substring(0, MAX_DISPLAYED_FILENAME_LENGTH);
|
||||
if (start.indexOf(" ") < 0 && start.indexOf("-") < 0) {
|
||||
if (start.indexOf(' ') < 0 && start.indexOf('-') < 0) {
|
||||
// browser has nowhere to break it
|
||||
basename = start + HELLIP;
|
||||
}
|
||||
@@ -1473,6 +1487,8 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
remainingSeconds = -1;
|
||||
|
||||
MetaInfo meta = snark.getMetaInfo();
|
||||
String b64 = Base64.encode(snark.getInfoHash());
|
||||
String b64Short = b64.substring(0, 6);
|
||||
// isValid means isNotMagnet
|
||||
boolean isValid = meta != null;
|
||||
boolean isMultiFile = isValid && meta.getFiles() != null;
|
||||
@@ -1530,57 +1546,59 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
img = "complete";
|
||||
txt = _t("Complete");
|
||||
}
|
||||
if (curPeers > 0 && !showPeers)
|
||||
if (curPeers > 0 && !showPeers) {
|
||||
statusString = toThemeImg(img, "", txt) + "</td>" +
|
||||
"<td class=\"snarkTorrentStatus\">" + txt +
|
||||
": <a href=\"" + uri + getQueryString(req, Base64.encode(snark.getInfoHash()), null, null) + "\">" +
|
||||
": <a href=\"" + uri + getQueryString(req, b64, null, null) + '#' + b64Short + "\">" +
|
||||
curPeers + thinsp(noThinsp) +
|
||||
ngettext("1 peer", "{0} peers", knownPeers) + "</a>";
|
||||
else
|
||||
} else {
|
||||
statusString = toThemeImg(img, "", txt) + "</td>" +
|
||||
"<td class=\"snarkTorrentStatus\">" + txt +
|
||||
": " + curPeers + thinsp(noThinsp) +
|
||||
ngettext("1 peer", "{0} peers", knownPeers);
|
||||
}
|
||||
} else {
|
||||
statusString = toThemeImg("complete", "", _t("Complete")) + "</td>" +
|
||||
"<td class=\"snarkTorrentStatus\">" + _t("Complete");
|
||||
}
|
||||
} else {
|
||||
if (isRunning && curPeers > 0 && downBps > 0 && !showPeers)
|
||||
if (isRunning && curPeers > 0 && downBps > 0 && !showPeers) {
|
||||
statusString = toThemeImg("downloading", "", _t("OK")) + "</td>" +
|
||||
"<td class=\"snarkTorrentStatus\">" + _t("OK") +
|
||||
": <a href=\"" + uri + getQueryString(req, Base64.encode(snark.getInfoHash()), null, null) + "\">" +
|
||||
": <a href=\"" + uri + getQueryString(req, b64, null, null) + '#' + b64Short + "\">" +
|
||||
curPeers + thinsp(noThinsp) +
|
||||
ngettext("1 peer", "{0} peers", knownPeers) + "</a>";
|
||||
else if (isRunning && curPeers > 0 && downBps > 0)
|
||||
} else if (isRunning && curPeers > 0 && downBps > 0) {
|
||||
statusString = toThemeImg("downloading", "", _t("OK")) + "</td>" +
|
||||
"<td class=\"snarkTorrentStatus\">" + _t("OK") +
|
||||
": " + curPeers + thinsp(noThinsp) +
|
||||
ngettext("1 peer", "{0} peers", knownPeers);
|
||||
else if (isRunning && curPeers > 0 && !showPeers)
|
||||
} else if (isRunning && curPeers > 0 && !showPeers) {
|
||||
statusString = toThemeImg("stalled", "", _t("Stalled")) + "</td>" +
|
||||
"<td class=\"snarkTorrentStatus\">" + _t("Stalled") +
|
||||
": <a href=\"" + uri + getQueryString(req, Base64.encode(snark.getInfoHash()), null, null) + "\">" +
|
||||
": <a href=\"" + uri + getQueryString(req, b64, null, null) + '#' + b64Short + "\">" +
|
||||
curPeers + thinsp(noThinsp) +
|
||||
ngettext("1 peer", "{0} peers", knownPeers) + "</a>";
|
||||
else if (isRunning && curPeers > 0)
|
||||
} else if (isRunning && curPeers > 0) {
|
||||
statusString = toThemeImg("stalled", "", _t("Stalled")) + "</td>" +
|
||||
"<td class=\"snarkTorrentStatus\">" + _t("Stalled") +
|
||||
": " + curPeers + thinsp(noThinsp) +
|
||||
ngettext("1 peer", "{0} peers", knownPeers);
|
||||
else if (isRunning && knownPeers > 0)
|
||||
} else if (isRunning && knownPeers > 0) {
|
||||
statusString = toThemeImg("nopeers", "", _t("No Peers")) + "</td>" +
|
||||
"<td class=\"snarkTorrentStatus\">" + _t("No Peers") +
|
||||
": 0" + thinsp(noThinsp) + knownPeers ;
|
||||
else if (isRunning)
|
||||
} else if (isRunning) {
|
||||
statusString = toThemeImg("nopeers", "", _t("No Peers")) + "</td>" +
|
||||
"<td class=\"snarkTorrentStatus\">" + _t("No Peers");
|
||||
else
|
||||
} else {
|
||||
statusString = toThemeImg("stopped", "", _t("Stopped")) + "</td>" +
|
||||
"<td class=\"snarkTorrentStatus\">" + _t("Stopped");
|
||||
}
|
||||
}
|
||||
|
||||
out.write("<tr class=\"" + rowClass + "\">");
|
||||
out.write("<tr class=\"" + rowClass + "\" id=\"" + b64Short + "\">");
|
||||
out.write("<td class=\"center\">");
|
||||
out.write(statusString + "</td>\n\t");
|
||||
|
||||
@@ -1685,7 +1703,6 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
out.write(formatSize(upBps) + "ps");
|
||||
out.write("</td>\n\t");
|
||||
out.write("<td align=\"center\" class=\"snarkTorrentAction\">");
|
||||
String b64 = Base64.encode(snark.getInfoHash());
|
||||
if (snark.isChecking()) {
|
||||
// show no buttons
|
||||
} else if (isRunning) {
|
||||
@@ -2193,9 +2210,19 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
+ (smartSort ? "checked " : "")
|
||||
+ "title=\"");
|
||||
out.write(_t("If checked, ignore words such as 'the' when sorting"));
|
||||
out.write("\" >" +
|
||||
out.write("\" >");
|
||||
|
||||
"<tr><td>");
|
||||
if (!_context.isRouterContext()) {
|
||||
try {
|
||||
out.write("<tr><td>");
|
||||
out.write(_t("Language"));
|
||||
out.write(": <td>");
|
||||
// class only in standalone builds
|
||||
out.write(ConfigUIHelper.getLangSettings(_context));
|
||||
} catch (Throwable t) {}
|
||||
}
|
||||
|
||||
out.write("<tr><td>");
|
||||
out.write(_t("Theme"));
|
||||
out.write(": <td><select name='theme'>");
|
||||
String theme = _manager.getTheme();
|
||||
@@ -2229,12 +2256,14 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
out.write("</select><br>" +
|
||||
|
||||
"<tr><td>");
|
||||
out.write(_t("Startup delay"));
|
||||
out.write(": <td><input name=\"startupDelay\" size=\"4\" class=\"r\" value=\"" + _manager.util().getStartupDelay() + "\"> ");
|
||||
out.write(_t("minutes"));
|
||||
out.write("<br>\n" +
|
||||
if (_context.isRouterContext()) {
|
||||
out.write(_t("Startup delay"));
|
||||
out.write(": <td><input name=\"startupDelay\" size=\"4\" class=\"r\" value=\"" + _manager.util().getStartupDelay() + "\"> ");
|
||||
out.write(_t("minutes"));
|
||||
out.write("<br>\n" +
|
||||
|
||||
"<tr><td>");
|
||||
"<tr><td>");
|
||||
}
|
||||
out.write(_t("Page size"));
|
||||
out.write(": <td><input name=\"pageSize\" size=\"4\" maxlength=\"6\" class=\"r\" value=\"" + _manager.getPageSize() + "\"> ");
|
||||
out.write(_t("torrents"));
|
||||
@@ -2272,11 +2301,12 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
out.write(": <td><input type=\"text\" name=\"upBW\" class=\"r\" value=\""
|
||||
+ _manager.util().getMaxUpBW() + "\" size=\"4\" maxlength=\"4\" > KBps <i>");
|
||||
out.write(_t("Half available bandwidth recommended."));
|
||||
out.write(" [<a href=\"/config.jsp\" target=\"blank\">");
|
||||
out.write(_t("View or change router bandwidth"));
|
||||
out.write("</a>]</i><br>\n" +
|
||||
|
||||
"<tr><td>");
|
||||
if (_context.isRouterContext()) {
|
||||
out.write(" [<a href=\"/config.jsp\" target=\"blank\">");
|
||||
out.write(_t("View or change router bandwidth"));
|
||||
out.write("</a>]</i>");
|
||||
}
|
||||
out.write("<br>\n<tr><td>");
|
||||
out.write(_t("Use open trackers also"));
|
||||
out.write(": <td><input type=\"checkbox\" class=\"optbox\" name=\"useOpenTrackers\" value=\"true\" "
|
||||
+ (useOpenTrackers ? "checked " : "")
|
||||
@@ -2351,7 +2381,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
"<tr><td colspan=\"2\"> \n" + // spacer
|
||||
"</table></div></div></form>");
|
||||
}
|
||||
|
||||
|
||||
/** @since 0.9 */
|
||||
private void writeTrackerForm(PrintWriter out, HttpServletRequest req) throws IOException {
|
||||
StringBuilder buf = new StringBuilder(1024);
|
||||
@@ -2571,7 +2601,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 href=\"";
|
||||
private static final String HEADER_B = "snark.css\" rel=\"stylesheet\" type=\"text/css\" >";
|
||||
private static final String HEADER_B = "snark.css?" + CoreVersion.VERSION + "\" rel=\"stylesheet\" type=\"text/css\" >";
|
||||
|
||||
|
||||
private static final String TABLE_HEADER = "<table border=\"0\" class=\"snarkTorrents\" width=\"100%\" >\n" +
|
||||
@@ -3057,7 +3087,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
: tx + ": " + directory);
|
||||
if (showSort)
|
||||
buf.append("</a>");
|
||||
int dirSlash = directory.indexOf("/");
|
||||
int dirSlash = directory.indexOf('/');
|
||||
if (dirSlash > 0) {
|
||||
buf.append(" ");
|
||||
buf.append(DataHelper.escapeHTML(directory.substring(dirSlash + 1)));
|
||||
|
||||
@@ -96,7 +96,7 @@ public class InclusiveByteRange
|
||||
long first = -1;
|
||||
long last = -1;
|
||||
int d = t.indexOf('-');
|
||||
if (d < 0 || t.indexOf("-",d + 1) >= 0)
|
||||
if (d < 0 || t.indexOf('-',d + 1) >= 0)
|
||||
{
|
||||
if ("bytes".equals(t))
|
||||
continue;
|
||||
|
||||
@@ -105,7 +105,7 @@ class MimeTypes
|
||||
int i=-1;
|
||||
while(type==null)
|
||||
{
|
||||
i=filename.indexOf(".",i+1);
|
||||
i=filename.indexOf('.',i+1);
|
||||
|
||||
if (i<0 || i>=filename.length())
|
||||
break;
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
package org.klomp.snark.web;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.util.FileUtil;
|
||||
|
||||
//import org.eclipse.jetty.server.Server;
|
||||
|
||||
/**
|
||||
* @deprecated does not work
|
||||
*/
|
||||
@Deprecated
|
||||
public class RunStandalone {
|
||||
/****
|
||||
static {
|
||||
System.setProperty("org.mortbay.http.Version.paranoid", "true");
|
||||
System.setProperty("org.mortbay.xml.XmlParser.NotValidating", "true");
|
||||
}
|
||||
****/
|
||||
|
||||
private RunStandalone(String args[]) {}
|
||||
|
||||
public static void main(String args[]) {
|
||||
RunStandalone runner = new RunStandalone(args);
|
||||
runner.start();
|
||||
}
|
||||
|
||||
public void start() {
|
||||
throw new RuntimeException("unsupported");
|
||||
/****
|
||||
File workDir = new File(I2PAppContext.getGlobalContext().getTempDir(), "jetty-work");
|
||||
boolean workDirRemoved = FileUtil.rmdir(workDir, false);
|
||||
if (!workDirRemoved)
|
||||
System.err.println("ERROR: Unable to remove Jetty temporary work directory");
|
||||
boolean workDirCreated = workDir.mkdirs();
|
||||
if (!workDirCreated)
|
||||
System.err.println("ERROR: Unable to create Jetty temporary work directory");
|
||||
|
||||
try {
|
||||
_server = new Server("jetty-i2psnark.xml");
|
||||
// just blow up NPE if we don't have a context
|
||||
(_server.getContexts()[0]).setTempDirectory(workDir);
|
||||
_server.start();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
****/
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
throw new RuntimeException("unsupported");
|
||||
/****
|
||||
try {
|
||||
_server.stop();
|
||||
} catch (InterruptedException ie) {
|
||||
ie.printStackTrace();
|
||||
}
|
||||
****/
|
||||
}
|
||||
}
|
||||
@@ -57,7 +57,7 @@ class URIUtil
|
||||
|
||||
/** Encode a URI path.
|
||||
*
|
||||
* Somewhat oddly, this encodes all chars >= 0x80 if buf is null, (strict RFC 2396)
|
||||
* Somewhat oddly, this encodes all chars >= 0x80 if buf is null, (strict RFC 2396)
|
||||
* but only the control, space, and special chars if buf is non-null.
|
||||
*
|
||||
* @param path The path the encode
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure 1.2//EN" "http://jetty.mortbay.org/configure_1_2.dtd">
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- This is the configuration for a standalone i2psnark and -->
|
||||
@@ -11,7 +11,7 @@
|
||||
<!-- =============================================================== -->
|
||||
<!-- Configure the Jetty Server -->
|
||||
<!-- =============================================================== -->
|
||||
<Configure class="org.mortbay.jetty.Server">
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Configure the Request Listeners -->
|
||||
@@ -20,23 +20,18 @@
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- Add and configure a HTTP listener to port 8002 -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<Call name="addListener">
|
||||
<Call name="addConnector">
|
||||
<Arg>
|
||||
<New class="org.mortbay.http.SocketListener">
|
||||
<Arg>
|
||||
<New class="org.mortbay.util.InetAddrPort">
|
||||
<Set name="host">127.0.0.1</Set>
|
||||
<Set name="port">8002</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
<Set name="MinThreads">1</Set>
|
||||
<Set name="MaxThreads">10</Set>
|
||||
<Set name="MaxIdleTimeMs">30000</Set>
|
||||
<Set name="LowResourcePersistTimeMs">1000</Set>
|
||||
<Set name="ConfidentialPort">8443</Set>
|
||||
<Set name="IntegralPort">8443</Set>
|
||||
<Set name="PoolName">main</Set>
|
||||
</New>
|
||||
<New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
|
||||
<Set name="host">127.0.0.1</Set>
|
||||
<Set name="port">8002</Set>
|
||||
<Set name="maxIdleTime">600000</Set>
|
||||
<Set name="Acceptors">1</Set>
|
||||
<Set name="statsOn">false</Set>
|
||||
<Set name="lowResourcesConnections">5000</Set>
|
||||
<Set name="lowResourcesMaxIdleTime">5000</Set>
|
||||
<Set name="useDirectBuffers">false</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
@@ -44,41 +39,103 @@
|
||||
<!-- Configure the Contexts -->
|
||||
<!-- =============================================================== -->
|
||||
|
||||
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- Add a all web application within the webapps directory. -->
|
||||
<!-- + No virtual host specified -->
|
||||
<!-- + Look in the webapps directory relative to jetty.home or . -->
|
||||
<!-- + Use the default webdefault.xml in jetty's install -->
|
||||
<!-- + Upack the war file -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<Set name="rootWebApp">i2psnark</Set>
|
||||
<Call name="addWebApplication">
|
||||
<Arg>/</Arg>
|
||||
<Arg>webapps/i2psnark.war</Arg>
|
||||
</Call>
|
||||
|
||||
<!-- this is so we can find the css -->
|
||||
<Call name="addContext">
|
||||
<Arg>
|
||||
<New class="org.mortbay.http.HttpContext">
|
||||
<Set name="contextPath">/themes</Set>
|
||||
<Set name="resourceBase">./docs/themes</Set>
|
||||
<Call name="addHandler">
|
||||
<Arg>
|
||||
<New class="org.mortbay.http.handler.ResourceHandler">
|
||||
<Set name="redirectWelcome">FALSE</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
<!-- =========================================================== -->
|
||||
<!-- Set handler Collection Structure -->
|
||||
<!-- =========================================================== -->
|
||||
<Set name="handler">
|
||||
<New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
|
||||
<Set name="handlers">
|
||||
<Array type="org.eclipse.jetty.server.Handler">
|
||||
<Item>
|
||||
<New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
|
||||
</Item>
|
||||
</Array>
|
||||
</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Configure the Other Server Options -->
|
||||
<!-- =============================================================== -->
|
||||
<Set name="requestsPerGC">2000</Set>
|
||||
<Set name="statsOn">false</Set>
|
||||
</Set>
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Create the deployment manager -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- The deplyment manager handles the lifecycle of deploying web -->
|
||||
<!-- applications. Apps are provided by instances of the -->
|
||||
<!-- AppProvider interface. Typically these are provided by -->
|
||||
<!-- one or more of: -->
|
||||
<!-- jetty-webapps.xml - monitors webapps for wars and dirs -->
|
||||
<!-- jetty-contexts.xml - monitors contexts for context xml -->
|
||||
<!-- jetty-templates.xml - monitors contexts and templates -->
|
||||
<!-- =============================================================== -->
|
||||
<Call name="addBean">
|
||||
<Arg>
|
||||
<New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager">
|
||||
<Set name="contexts">
|
||||
<Ref id="Contexts" />
|
||||
</Set>
|
||||
<Call name="setContextAttribute">
|
||||
<Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg>
|
||||
<Arg>.*/.*jsp-api-[^/]*\.jar$|.*/.*jsp-[^/]*\.jar$|.*/.*taglibs[^/]*\.jar$</Arg>
|
||||
</Call>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Configure the context deployer -->
|
||||
<!-- A context deployer will deploy contexts described in -->
|
||||
<!-- configuration files discovered in a directory. -->
|
||||
<!-- The configuration directory can be scanned for hot -->
|
||||
<!-- deployments at the configured scanInterval. -->
|
||||
<!-- -->
|
||||
<!-- This deployer is configured to deploy contexts configured -->
|
||||
<!-- in the $JETTY_HOME/contexts directory -->
|
||||
<!-- -->
|
||||
<!-- =========================================================== -->
|
||||
<Ref id="DeploymentManager">
|
||||
<Call name="addAppProvider">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.deploy.providers.ContextProvider">
|
||||
<Set name="monitoredDirName">./contexts</Set>
|
||||
<Set name="scanInterval">0</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
</Ref>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Configure the webapp deployer. -->
|
||||
<!-- A webapp deployer will deploy standard webapps discovered -->
|
||||
<!-- in a directory at startup, without the need for additional -->
|
||||
<!-- configuration files. It does not support hot deploy or -->
|
||||
<!-- non standard contexts (see ContextDeployer above). -->
|
||||
<!-- -->
|
||||
<!-- This deployer is configured to deploy webapps from the -->
|
||||
<!-- $JETTY_HOME/webapps directory -->
|
||||
<!-- -->
|
||||
<!-- Normally only one type of deployer need be used. -->
|
||||
<!-- -->
|
||||
<!-- =========================================================== -->
|
||||
<Ref id="DeploymentManager">
|
||||
<Call id="webappprovider" name="addAppProvider">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
|
||||
<Set name="monitoredDirName">./webapps</Set>
|
||||
<Set name="parentLoaderPriority">false</Set>
|
||||
<Set name="extractWars">false</Set>
|
||||
<Set name="scanInterval">0</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
</Ref>
|
||||
|
||||
<!-- ===================== -->
|
||||
<!-- DefaultHandler config -->
|
||||
<!-- http://stackoverflow.com/questions/4202275/how-to-prevent-jetty-from-showing-context-related-information -->
|
||||
<!-- ===================== -->
|
||||
<Ref id="DefaultHandler">
|
||||
<Set name="showContexts">false</Set>
|
||||
</Ref>
|
||||
|
||||
</Configure>
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
# i2psnark will be accessed at http://127.0.0.1:8002/
|
||||
#
|
||||
I2P="."
|
||||
java -cp "$I2P/lib/i2psnark.jar:$I2P/lib/i2p.jar:$I2P/lib/mstreaming.jar:$I2P/lib/streaming.jar:$I2P/lib/commons-el.jar:$I2P/lib/commons-logging.jar:$I2P/lib/jasper-compiler.jar:$I2P/lib/jasper-runtime.jar:$I2P/lib/javax.servlet.jar:$I2P/lib/org.mortbay.jetty.jar" org.klomp.snark.web.RunStandalone "$@"
|
||||
java -jar "$I2P/i2psnark.jar"
|
||||
|
||||
8
apps/i2psnark/launch-i2psnark.bat
Normal file
8
apps/i2psnark/launch-i2psnark.bat
Normal file
@@ -0,0 +1,8 @@
|
||||
@echo off
|
||||
|
||||
REM This launches i2psnark and jetty in a separate JVM.
|
||||
REM The file jetty-i2psnark.xml must be present in the current directory.
|
||||
REM i2psnark will be accessed at http://127.0.0.1:8002/
|
||||
|
||||
set 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
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1393
apps/i2psnark/locale/messages_ja.po
Normal file
1393
apps/i2psnark/locale/messages_ja.po
Normal file
File diff suppressed because it is too large
Load Diff
1401
apps/i2psnark/locale/messages_ko.po
Normal file
1401
apps/i2psnark/locale/messages_ko.po
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1408
apps/i2psnark/locale/messages_uk.po
Normal file
1408
apps/i2psnark/locale/messages_uk.po
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -30,6 +30,7 @@ odt = application/vnd.oasis.opendocument.text
|
||||
ogm = video/ogg
|
||||
ogv = video/ogg
|
||||
oga = audio/ogg
|
||||
opus = audio/ogg
|
||||
otc = application/vnd.oasis.opendocument.chart-template
|
||||
otf = application/vnd.oasis.opendocument.formula-template
|
||||
otg = application/vnd.oasis.opendocument.graphics-template
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
i2psnark is packaged as a webapp running in the router console.
|
||||
Command line and standalone operation of i2psnark are not currently supported.
|
||||
See http://trac.i2p2.i2p/ticket/1191 or http://trac.i2p2.de/ticket/1191
|
||||
for the status of restoring standalone support.
|
||||
To run i2psnark's standalone mode make sure you have an i2p router running in the background, then run:
|
||||
|
||||
java -jar i2psnark.jar
|
||||
|
||||
I2PSnark web ui will be at http://127.0.0.1:8002/i2psnark/
|
||||
|
||||
Please note that http://127.0.0.1:8002/ will 404, to be fixed
|
||||
|
||||
I2PSnark is GPL'ed software, based on Snark (http://www.klomp.org/) to run on top of I2P
|
||||
(https://geti2p.net/) within a webserver (such as the bundled Jetty from
|
||||
https://www.eclipse.org/jetty/). For more information about I2PSnark, get in touch
|
||||
with the folks at http://forum.i2p2.de/
|
||||
|
||||
23
apps/i2psnark/standalone-context.xml
Normal file
23
apps/i2psnark/standalone-context.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
|
||||
|
||||
<!--
|
||||
Configure a custom context for the site.
|
||||
|
||||
This context contains only a ServletContextHandler with a default servlet
|
||||
to serve static html files and images.
|
||||
-->
|
||||
|
||||
<Configure class="org.eclipse.jetty.servlet.ServletContextHandler">
|
||||
<Set name="contextPath">/</Set>
|
||||
<Set name="resourceBase">./docroot/</Set>
|
||||
<Call name="setInitParameter">
|
||||
<Arg>org.eclipse.jetty.servlet.Default.cacheControl</Arg>
|
||||
<Arg>max-age=3600,public</Arg>
|
||||
</Call>
|
||||
<Call name="addServlet">
|
||||
<Arg>org.eclipse.jetty.servlet.DefaultServlet</Arg>
|
||||
<Arg>/</Arg>
|
||||
</Call>
|
||||
</Configure>
|
||||
|
||||
15
apps/i2psnark/standalone-index.html
Normal file
15
apps/i2psnark/standalone-index.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<html>
|
||||
<head>
|
||||
<!--
|
||||
* Remove the following three lines to stop redirecting to the i2psnark page.
|
||||
* If it continues to redirect, clear your browser's cache.
|
||||
-->
|
||||
<meta http-equiv="refresh" content="1;url=/i2psnark/" />
|
||||
<meta http-equiv="pragma" content="no-cache">
|
||||
<meta http-equiv="cache-control" content="no-cache">
|
||||
<title>I2PSnark Standalone</title>
|
||||
</head>
|
||||
<body>
|
||||
Redirecting to <a href="/i2psnark/">i2psnark</a>...
|
||||
</body>
|
||||
</html>
|
||||
32
apps/i2ptunnel/i2ptunnel.iml
Normal file
32
apps/i2ptunnel/i2ptunnel.iml
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="web" name="Web">
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<deploymentDescriptor name="web.xml" url="file://$MODULE_DIR$/jsp/web.xml" />
|
||||
</descriptors>
|
||||
<webroots>
|
||||
<root url="file://$MODULE_DIR$/jsp" relative="/WEB-INF" />
|
||||
</webroots>
|
||||
<sourceRoots>
|
||||
<root url="file://$MODULE_DIR$/java/src" />
|
||||
</sourceRoots>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/java/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/java/test/junit" isTestSource="true" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="1.6" jdkType="JavaSDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="core" />
|
||||
<orderEntry type="module" module-name="ministreaming" />
|
||||
<orderEntry type="library" scope="TEST" name="junit:junit:4.12" level="application" />
|
||||
<orderEntry type="library" name="jettylib" level="project" />
|
||||
<orderEntry type="module" module-name="jetty" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
<!-- only used if not set by a higher build.xml -->
|
||||
<property name="javac.compilerargs" value="" />
|
||||
<property name="javac.version" value="1.6" />
|
||||
<property name="javac.version" value="1.7" />
|
||||
<property name="require.gettext" value="true" />
|
||||
|
||||
<target name="compile" depends="depend">
|
||||
@@ -72,6 +72,8 @@
|
||||
<attribute name="Build-Date" value="${build.timestamp}" />
|
||||
<attribute name="Base-Revision" value="${workspace.version}" />
|
||||
<attribute name="Workspace-Changes" value="${workspace.changes.j.tr}" />
|
||||
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
|
||||
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
|
||||
</manifest>
|
||||
</jar>
|
||||
<jar destfile="./build/temp-beans.jar" basedir="./build/obj" includes="**/ui/*.class **/EditBean.class **/IndexBean.class" />
|
||||
@@ -103,6 +105,8 @@
|
||||
<attribute name="Build-Date" value="${build.timestamp}" />
|
||||
<attribute name="Base-Revision" value="${workspace.version}" />
|
||||
<attribute name="Workspace-Changes" value="${workspace.changes.j.tr}" />
|
||||
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
|
||||
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
|
||||
</manifest>
|
||||
</jar>
|
||||
</target>
|
||||
@@ -241,6 +245,8 @@
|
||||
<attribute name="Build-Date" value="${build.timestamp}" />
|
||||
<attribute name="Base-Revision" value="${workspace.version}" />
|
||||
<attribute name="Workspace-Changes" value="${workspace.changes.w.tr}" />
|
||||
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
|
||||
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
|
||||
</manifest>
|
||||
</war>
|
||||
</target>
|
||||
|
||||
@@ -380,8 +380,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
}
|
||||
|
||||
public void runCommand(String cmd, Logging l) {
|
||||
if (cmd.indexOf(" ") == -1) cmd += " ";
|
||||
int iii = cmd.indexOf(" ");
|
||||
if (cmd.indexOf(' ') == -1) cmd += ' ';
|
||||
int iii = cmd.indexOf(' ');
|
||||
String cmdname = cmd.substring(0, iii).toLowerCase(Locale.US);
|
||||
String allargs = cmd.substring(iii + 1);
|
||||
String[] args = split(allargs, " "); // .split(" "); // java 1.4
|
||||
@@ -408,6 +408,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
runIrcClient(args, l);
|
||||
} else if ("sockstunnel".equals(cmdname)) {
|
||||
runSOCKSTunnel(args, l);
|
||||
} else if ("socksirctunnel".equals(cmdname)) {
|
||||
runSOCKSIRCTunnel(args, l);
|
||||
} else if ("connectclient".equals(cmdname)) {
|
||||
runConnectClient(args, l);
|
||||
} else if ("streamrclient".equals(cmdname)) {
|
||||
@@ -476,6 +478,10 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
" read_timeout <msecs>\n" +
|
||||
" run <commandfile>\n" +
|
||||
" server <host> <port> <privkeyfile>\n" +
|
||||
" socksirctunnel <port> [<sharedClient> [<privKeyFile>]]\n" +
|
||||
" sockstunnel <port>\n" +
|
||||
" streamrclient <host> <port> <destination>\n" +
|
||||
" streamrserver <port> <privkeyfile>\n" +
|
||||
" textserver <host> <port> <privkey>\n");
|
||||
}
|
||||
|
||||
@@ -520,11 +526,12 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
}
|
||||
} else {
|
||||
l.log("Usage:\n" +
|
||||
" clientoptions // show help and list current options\n" +
|
||||
" clientoptions [key=value ]* // sets current options\n" +
|
||||
" clientoptions -a [key=value ]* // adds to current options\n" +
|
||||
" clientoptions -c // clears current options\n" +
|
||||
" clientoptions -x [key ]* // removes listed options\n" +
|
||||
"Current options:\n");
|
||||
"\nCurrent options:");
|
||||
Properties p = new OrderedProperties();
|
||||
p.putAll(_clientOptions);
|
||||
for (Map.Entry<Object, Object> e : p.entrySet()) {
|
||||
@@ -559,7 +566,7 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
|
||||
/**
|
||||
* Run the server pointing at the host and port specified using the private i2p
|
||||
* destination loaded from the specified file. <p />
|
||||
* destination loaded from the specified file. <p>
|
||||
*
|
||||
* Sets the event "serverTaskId" = Integer(taskId) after the tunnel has been started (or -1 on error)
|
||||
* Also sets the event "openServerResult" = "ok" or "error" (displaying "Ready!" on the logger after
|
||||
@@ -669,7 +676,7 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
/**
|
||||
* Run the HTTP server pointing at the host and port specified using the private i2p
|
||||
* destination loaded from the specified file, replacing the HTTP headers
|
||||
* so that the Host: specified is the one spoofed. <p />
|
||||
* so that the Host: specified is the one spoofed. <p>
|
||||
*
|
||||
* Sets the event "serverTaskId" = Integer(taskId) after the tunnel has been started (or -1 on error)
|
||||
* Also sets the event "openServerResult" = "ok" or "error" (displaying "Ready!" on the logger after
|
||||
@@ -733,7 +740,7 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
* Run the HTTP server pointing at the host and port specified using the private i2p
|
||||
* destination loaded from the specified file, replacing the HTTP headers
|
||||
* so that the Host: specified is the one spoofed. Also runs an HTTP proxy for
|
||||
* bidirectional communications on the same tunnel destination.<p />
|
||||
* bidirectional communications on the same tunnel destination.<p>
|
||||
*
|
||||
* Sets the event "serverTaskId" = Integer(taskId) after the tunnel has been started (or -1 on error)
|
||||
* Also sets the event "openServerResult" = "ok" or "error" (displaying "Ready!" on the logger after
|
||||
@@ -808,7 +815,7 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
|
||||
/**
|
||||
* Run the server pointing at the host and port specified using the private i2p
|
||||
* destination loaded from the given base64 stream. <p />
|
||||
* destination loaded from the given base64 stream. <p>
|
||||
*
|
||||
* Deprecated? Why run a server with a private destination?
|
||||
* Not available from the war GUI
|
||||
@@ -909,11 +916,9 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
}
|
||||
} else {
|
||||
l.log("client <port> <pubkey>[,<pubkey>]|file:<pubkeyfile>[ <sharedClient>] [<privKeyFile>]\n" +
|
||||
" creates a client that forwards port to the pubkey.\n"
|
||||
+ " use 0 as port to get a free port assigned. If you specify\n"
|
||||
+ " a comma delimited list of pubkeys, it will rotate among them\n"
|
||||
+ " randomlyl. sharedClient indicates if this client shares \n"
|
||||
+ " with other clients (true of false)");
|
||||
" Creates a standard client that listens on the port and forwards to the pubkey.\n"
|
||||
+ " With a comma delimited list of pubkeys, it will rotate among them randomly.\n"
|
||||
+ " sharedClient indicates if this client shares tunnels with other clients (true or false)");
|
||||
notifyEvent("clientTaskId", Integer.valueOf(-1));
|
||||
}
|
||||
}
|
||||
@@ -985,9 +990,9 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
}
|
||||
} else {
|
||||
l.log("httpclient <port> [<sharedClient>] [<proxy>]\n" +
|
||||
" creates a client that distributes HTTP requests.\n" +
|
||||
" <sharedClient> (optional) indicates if this client shares tunnels with other clients (true of false)\n" +
|
||||
" <proxy> (optional) indicates a proxy server to be used\n" +
|
||||
" Creates a HTTP client proxy on the specified port.\n" +
|
||||
" <sharedClient> (optional) Indicates if this client shares tunnels with other clients (true or false)\n" +
|
||||
" <proxy> (optional) Indicates a proxy server to be used\n" +
|
||||
" when trying to access an address out of the .i2p domain");
|
||||
notifyEvent("httpclientTaskId", Integer.valueOf(-1));
|
||||
}
|
||||
@@ -1053,7 +1058,7 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
} else {
|
||||
l.log("connectclient <port> [<sharedClient>] [<proxy>]\n" +
|
||||
" creates a client that for SSL/HTTPS requests.\n" +
|
||||
" <sharedClient> (optional) indicates if this client shares tunnels with other clients (true of false)\n" +
|
||||
" <sharedClient> (optional) indicates if this client shares tunnels with other clients (true or false)\n" +
|
||||
" <proxy> (optional) indicates a proxy server to be used\n" +
|
||||
" when trying to access an address out of the .i2p domain\n");
|
||||
}
|
||||
@@ -1119,8 +1124,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
}
|
||||
} else {
|
||||
l.log("ircclient <port> [<sharedClient> [<privKeyFile>]]\n" +
|
||||
" creates a client that filter IRC protocol.\n" +
|
||||
" <sharedClient> (optional) indicates if this client shares tunnels with other clients (true of false)\n");
|
||||
" Creates an IRC client proxy on the specified port.\n" +
|
||||
" <sharedClient> (optional) Indicates if this client shares tunnels with other clients (true or false)\n");
|
||||
notifyEvent("ircclientTaskId", Integer.valueOf(-1));
|
||||
}
|
||||
}
|
||||
@@ -1173,7 +1178,7 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
}
|
||||
} else {
|
||||
l.log("sockstunnel <port>\n" +
|
||||
" creates a tunnel that distributes SOCKS requests.");
|
||||
" Creates a SOCKS proxy on the specified port.");
|
||||
notifyEvent("sockstunnelTaskId", Integer.valueOf(-1));
|
||||
}
|
||||
}
|
||||
@@ -1221,7 +1226,7 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
}
|
||||
} else {
|
||||
l.log("socksirctunnel <port> [<sharedClient> [<privKeyFile>]]\n" +
|
||||
" creates a tunnel for SOCKS IRC.");
|
||||
" Creates a SOCKS IRC proxy on the specified port.");
|
||||
notifyEvent("sockstunnelTaskId", Integer.valueOf(-1));
|
||||
}
|
||||
}
|
||||
@@ -1338,7 +1343,6 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
}
|
||||
if (i < args.length) {
|
||||
host = args[i++];
|
||||
listenHost = host;
|
||||
}
|
||||
if (i < args.length)
|
||||
port = args[i];
|
||||
@@ -1822,12 +1826,12 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
|
||||
/**
|
||||
* Generates a Destination from a name. Now only supports base64
|
||||
* names - may support naming servers later. "file:<filename>" is
|
||||
* names - may support naming servers later. "file:<filename>" is
|
||||
* also supported, where filename is a file that either contains a
|
||||
* binary Destination structure or the Base64 encoding of that
|
||||
* structure.
|
||||
*
|
||||
* Since file:<filename> isn't really used, this method is deprecated,
|
||||
* Since file:<filename> isn't really used, this method is deprecated,
|
||||
* just call context.namingService.lookup() directly.
|
||||
* @deprecated Don't use i2ptunnel for lookup! Use I2PAppContext.getGlobalContext().namingService().lookup(name) from i2p.jar
|
||||
*/
|
||||
|
||||
@@ -17,6 +17,7 @@ import net.i2p.client.streaming.I2PSocketAddress;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.util.EventDispatcher;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.PortMapper;
|
||||
|
||||
public class I2PTunnelClient extends I2PTunnelClientBase {
|
||||
|
||||
@@ -178,4 +179,50 @@ public class I2PTunnelClient extends I2PTunnelClientBase {
|
||||
buildAddresses(targets);
|
||||
super.optionsUpdated(tunnel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually start working on incoming connections.
|
||||
* Overridden to register with port mapper.
|
||||
*
|
||||
* @since 0.9.27
|
||||
*/
|
||||
@Override
|
||||
public void startRunning() {
|
||||
super.startRunning();
|
||||
if (open) {
|
||||
I2PSocketAddress addr = pickDestination();
|
||||
if (addr != null) {
|
||||
String svc = null;
|
||||
String hostname = addr.getHostName();
|
||||
if ("smtp.postman.i2p".equals(hostname)) {
|
||||
svc = PortMapper.SVC_SMTP;
|
||||
} else if ("pop.postman.i2p".equals(hostname)) {
|
||||
svc = PortMapper.SVC_POP;
|
||||
}
|
||||
if (svc != null) {
|
||||
_context.portMapper().register(svc, getTunnel().listenHost, getLocalPort());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden to unregister with port mapper
|
||||
*
|
||||
* @since 0.9.27
|
||||
*/
|
||||
@Override
|
||||
public boolean close(boolean forced) {
|
||||
int port = getLocalPort();
|
||||
int reg = _context.portMapper().getPort(PortMapper.SVC_SMTP);
|
||||
if (reg == port) {
|
||||
_context.portMapper().unregister(PortMapper.SVC_SMTP);
|
||||
}
|
||||
reg = _context.portMapper().getPort(PortMapper.SVC_POP);
|
||||
if (reg == port) {
|
||||
_context.portMapper().unregister(PortMapper.SVC_POP);
|
||||
}
|
||||
boolean rv = super.close(forced);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
|
||||
/**
|
||||
* This constructor is used to add a client to an existing socket manager.
|
||||
* <p/>
|
||||
* <p>
|
||||
* As of 0.9.21 this does NOT open the local socket. You MUST call
|
||||
* {@link #startRunning()} for that. The local socket will be opened
|
||||
* immediately (ignoring the <code>i2cp.delayOpen</code> option).
|
||||
@@ -119,10 +119,10 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
|
||||
/**
|
||||
* The main constructor.
|
||||
* <p/>
|
||||
* <p>
|
||||
* As of 0.9.21 this is fast, and does NOT connect the manager to the router,
|
||||
* or open the local socket. You MUST call startRunning() for that.
|
||||
* <p/>
|
||||
* <p>
|
||||
* (0.9.20 claimed to be fast, but due to a bug it DID connect the manager
|
||||
* to the router. It did NOT open the local socket however, so it was still
|
||||
* necessary to call startRunning() for that.)
|
||||
@@ -139,10 +139,10 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
|
||||
/**
|
||||
* Use this to build a client with a persistent private key.
|
||||
* <p/>
|
||||
* <p>
|
||||
* As of 0.9.21 this is fast, and does NOT connect the manager to the router,
|
||||
* or open the local socket. You MUST call startRunning() for that.
|
||||
* <p/>
|
||||
* <p>
|
||||
* (0.9.20 claimed to be fast, but due to a bug it DID connect the manager
|
||||
* to the router. It did NOT open the local socket however, so it was still
|
||||
* necessary to call startRunning() for that.)
|
||||
|
||||
@@ -14,6 +14,9 @@ import java.util.StringTokenizer;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.app.ClientApp;
|
||||
import net.i2p.app.ClientAppManager;
|
||||
import net.i2p.app.Outproxy;
|
||||
import net.i2p.client.streaming.I2PSocket;
|
||||
import net.i2p.client.streaming.I2PSocketOptions;
|
||||
import net.i2p.data.Base64;
|
||||
@@ -34,7 +37,7 @@ import net.i2p.util.PortMapper;
|
||||
* example.com (sent to one of the configured proxies)
|
||||
* )
|
||||
*
|
||||
* (port and protocol are ignored for i2p destinations)
|
||||
* (protocol is ignored for i2p destinations)
|
||||
* CONNECT host
|
||||
* CONNECT host protocol
|
||||
* CONNECT host:port
|
||||
@@ -49,7 +52,7 @@ import net.i2p.util.PortMapper;
|
||||
*<pre>
|
||||
* INTERNET-DRAFT Ari Luotonen
|
||||
* Expires: September 26, 1997 Netscape Communications Corporation
|
||||
* <draft-luotonen-ssl-tunneling-03.txt> March 26, 1997
|
||||
* draft-luotonen-ssl-tunneling-03.txt March 26, 1997
|
||||
* Tunneling SSL Through a WWW Proxy
|
||||
*</pre>
|
||||
*
|
||||
@@ -125,7 +128,7 @@ public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements R
|
||||
public void startRunning() {
|
||||
super.startRunning();
|
||||
if (open)
|
||||
_context.portMapper().register(PortMapper.SVC_HTTPS_PROXY, getLocalPort());
|
||||
_context.portMapper().register(PortMapper.SVC_HTTPS_PROXY, getTunnel().listenHost, getLocalPort());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -147,6 +150,9 @@ public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements R
|
||||
String targetRequest = null;
|
||||
boolean usingWWWProxy = false;
|
||||
String currentProxy = null;
|
||||
// local outproxy plugin
|
||||
boolean usingInternalOutproxy = false;
|
||||
Outproxy outproxy = null;
|
||||
long requestId = __requestId.incrementAndGet();
|
||||
try {
|
||||
out = s.getOutputStream();
|
||||
@@ -154,6 +160,7 @@ public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements R
|
||||
String line, method = null, host = null, destination = null, restofline = null;
|
||||
StringBuilder newRequest = new StringBuilder();
|
||||
String authorization = null;
|
||||
int remotePort = 443;
|
||||
while (true) {
|
||||
// Use this rather than BufferedReader because we can't have readahead,
|
||||
// since we are passing the stream on to I2PTunnelRunner
|
||||
@@ -166,14 +173,26 @@ public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements R
|
||||
_log.debug(getPrefix(requestId) + "Line=[" + line + "]");
|
||||
|
||||
if (method == null) { // first line CONNECT blah.i2p:80 HTTP/1.1
|
||||
int pos = line.indexOf(" ");
|
||||
int pos = line.indexOf(' ');
|
||||
if (pos == -1) break; // empty first line
|
||||
method = line.substring(0, pos);
|
||||
String request = line.substring(pos + 1);
|
||||
|
||||
pos = request.indexOf(":");
|
||||
if (pos == -1)
|
||||
pos = request.indexOf(" ");
|
||||
pos = request.indexOf(':');
|
||||
if (pos == -1) {
|
||||
pos = request.indexOf(' ');
|
||||
} else {
|
||||
int spos = request.indexOf(' ');
|
||||
if (spos > 0) {
|
||||
try {
|
||||
remotePort = Integer.parseInt(request.substring(pos + 1, spos));
|
||||
} catch (NumberFormatException nfe) {
|
||||
break;
|
||||
} catch (IndexOutOfBoundsException ioobe) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pos == -1) {
|
||||
host = request;
|
||||
restofline = "";
|
||||
@@ -185,19 +204,36 @@ public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements R
|
||||
if (host.toLowerCase(Locale.US).endsWith(".i2p")) {
|
||||
// Destination gets the host name
|
||||
destination = host;
|
||||
} else if (host.indexOf(".") != -1) {
|
||||
// The request must be forwarded to a outproxy
|
||||
currentProxy = selectProxy();
|
||||
if (currentProxy == null) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn(getPrefix(requestId) + "Host wants to be outproxied, but we dont have any!");
|
||||
writeErrorMessage(ERR_NO_OUTPROXY, out);
|
||||
s.close();
|
||||
return;
|
||||
} else if (host.contains(".") || host.startsWith("[")) {
|
||||
if (Boolean.parseBoolean(getTunnel().getClientOptions().getProperty(PROP_USE_OUTPROXY_PLUGIN, "true"))) {
|
||||
ClientAppManager mgr = _context.clientAppManager();
|
||||
if (mgr != null) {
|
||||
ClientApp op = mgr.getRegisteredApp(Outproxy.NAME);
|
||||
if (op != null) {
|
||||
outproxy = (Outproxy) op;
|
||||
usingInternalOutproxy = true;
|
||||
if (host.startsWith("[")) {
|
||||
host = host.substring(1);
|
||||
if (host.endsWith("]"))
|
||||
host = host.substring(0, host.length() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
destination = currentProxy;
|
||||
usingWWWProxy = true;
|
||||
newRequest.append("CONNECT ").append(host).append(restofline).append("\r\n"); // HTTP spec
|
||||
if (!usingInternalOutproxy) {
|
||||
// The request must be forwarded to a outproxy
|
||||
currentProxy = selectProxy();
|
||||
if (currentProxy == null) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn(getPrefix(requestId) + "Host wants to be outproxied, but we dont have any!");
|
||||
writeErrorMessage(ERR_NO_OUTPROXY, out);
|
||||
s.close();
|
||||
return;
|
||||
}
|
||||
destination = currentProxy;
|
||||
usingWWWProxy = true;
|
||||
newRequest.append("CONNECT ").append(host).append(restofline).append("\r\n"); // HTTP spec
|
||||
}
|
||||
} else if (host.toLowerCase(Locale.US).equals("localhost")) {
|
||||
writeErrorMessage(ERR_LOCALHOST, out);
|
||||
s.close();
|
||||
@@ -208,10 +244,12 @@ public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements R
|
||||
targetRequest = host;
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG)) {
|
||||
_log.debug(getPrefix(requestId) + "METHOD:" + method + ":");
|
||||
_log.debug(getPrefix(requestId) + "HOST :" + host + ":");
|
||||
_log.debug(getPrefix(requestId) + "REST :" + restofline + ":");
|
||||
_log.debug(getPrefix(requestId) + "DEST :" + destination + ":");
|
||||
_log.debug(getPrefix(requestId) + "METHOD:" + method + ":\n" +
|
||||
"HOST :" + host + ":\n" +
|
||||
"PORT :" + remotePort + ":\n" +
|
||||
"REST :" + restofline + ":\n" +
|
||||
"DEST :" + destination + ":\n" +
|
||||
"www proxy? " + usingWWWProxy + " internal proxy? " + usingInternalOutproxy);
|
||||
}
|
||||
} else if (line.toLowerCase(Locale.US).startsWith("proxy-authorization: ")) {
|
||||
// strip Proxy-Authenticate from the response in HTTPResponseOutputStream
|
||||
@@ -250,7 +288,24 @@ public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements R
|
||||
}
|
||||
}
|
||||
|
||||
if (destination == null || method == null || !"CONNECT".equals(method.toUpperCase(Locale.US))) {
|
||||
if (method == null || !"CONNECT".equals(method.toUpperCase(Locale.US))) {
|
||||
writeErrorMessage(ERR_BAD_PROTOCOL, out);
|
||||
s.close();
|
||||
return;
|
||||
}
|
||||
|
||||
// no destination, going to outproxy plugin
|
||||
if (usingInternalOutproxy) {
|
||||
Socket outSocket = outproxy.connect(host, remotePort);
|
||||
OnTimeout onTimeout = new OnTimeout(s, s.getOutputStream(), targetRequest, usingWWWProxy, currentProxy, requestId);
|
||||
byte[] response = SUCCESS_RESPONSE.getBytes("UTF-8");
|
||||
Thread t = new I2PTunnelOutproxyRunner(s, outSocket, sockLock, null, response, onTimeout);
|
||||
// we are called from an unlimited thread pool, so run inline
|
||||
t.run();
|
||||
return;
|
||||
}
|
||||
|
||||
if (destination == null) {
|
||||
writeErrorMessage(ERR_BAD_PROTOCOL, out);
|
||||
s.close();
|
||||
return;
|
||||
@@ -282,7 +337,10 @@ public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements R
|
||||
return;
|
||||
}
|
||||
|
||||
I2PSocket i2ps = createI2PSocket(clientDest, getDefaultOptions());
|
||||
I2PSocketOptions sktOpts = getDefaultOptions();
|
||||
if (!usingWWWProxy && remotePort > 0)
|
||||
sktOpts.setPort(remotePort);
|
||||
I2PSocket i2ps = createI2PSocket(clientDest, sktOpts);
|
||||
byte[] data = null;
|
||||
byte[] response = null;
|
||||
if (usingWWWProxy)
|
||||
|
||||
@@ -220,6 +220,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
|
||||
super(localPort, l, sockMgr, tunnel, notifyThis, clientId);
|
||||
_proxyNonce = Long.toString(_context.random().nextLong());
|
||||
// proxyList = new ArrayList();
|
||||
if (tunnel.getClientOptions().getProperty("i2p.streaming.connectDelay") == null)
|
||||
tunnel.getClientOptions().setProperty("i2p.streaming.connectDelay", "1000");
|
||||
|
||||
setName("HTTP Proxy on " + getTunnel().listenHost + ':' + localPort);
|
||||
notifyEvent("openHTTPClientResult", "ok");
|
||||
@@ -246,6 +248,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
|
||||
_proxyList.add(tok.nextToken().trim());
|
||||
}
|
||||
}
|
||||
if (tunnel.getClientOptions().getProperty("i2p.streaming.connectDelay") == null)
|
||||
tunnel.getClientOptions().setProperty("i2p.streaming.connectDelay", "1000");
|
||||
|
||||
setName("HTTP Proxy on " + tunnel.listenHost + ':' + localPort);
|
||||
notifyEvent("openHTTPClientResult", "ok");
|
||||
@@ -316,8 +320,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
|
||||
this.isr = new InternalSocketRunner(this);
|
||||
this.isr.start();
|
||||
int port = getLocalPort();
|
||||
_context.portMapper().register(PortMapper.SVC_HTTP_PROXY, port);
|
||||
_context.portMapper().register(PortMapper.SVC_HTTPS_PROXY, port);
|
||||
_context.portMapper().register(PortMapper.SVC_HTTP_PROXY, getTunnel().listenHost, port);
|
||||
_context.portMapper().register(PortMapper.SVC_HTTPS_PROXY, getTunnel().listenHost, port);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,8 +361,6 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
|
||||
public static final String PROP_JUMP_SERVERS = "i2ptunnel.httpclient.jumpServers";
|
||||
public static final String PROP_DISABLE_HELPER = "i2ptunnel.httpclient.disableAddressHelper";
|
||||
/** @since 0.9.11 */
|
||||
public static final String PROP_USE_OUTPROXY_PLUGIN = "i2ptunnel.useLocalOutproxy";
|
||||
/** @since 0.9.11 */
|
||||
public static final String PROP_SSL_OUTPROXIES = "i2ptunnel.httpclient.SSLOutproxies";
|
||||
/** @since 0.9.14 */
|
||||
public static final String PROP_ACCEPT = "i2ptunnel.httpclient.sendAccept";
|
||||
@@ -402,6 +404,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
|
||||
String authorization = null;
|
||||
int remotePort = 0;
|
||||
String referer = null;
|
||||
URI origRequestURI = null;
|
||||
while((line = reader.readLine(method)) != null) {
|
||||
line = line.trim();
|
||||
if(_log.shouldLog(Log.DEBUG)) {
|
||||
@@ -434,8 +437,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
|
||||
// Deprecated
|
||||
// /eepproxy/foo.i2p/bar/baz.html
|
||||
String subRequest = request.substring("/eepproxy/".length());
|
||||
if(subRequest.indexOf("/") == -1) {
|
||||
subRequest += "/";
|
||||
if(subRequest.indexOf('/') == -1) {
|
||||
subRequest += '/';
|
||||
}
|
||||
request = "http://" + subRequest;
|
||||
/****
|
||||
@@ -478,7 +481,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
|
||||
// to be the outgoing URI (with http:// if going to outproxy, otherwise without)
|
||||
URI requestURI;
|
||||
try {
|
||||
requestURI = new URI(request);
|
||||
origRequestURI = requestURI = new URI(request);
|
||||
if(requestURI.getRawUserInfo() != null || requestURI.getRawFragment() != null) {
|
||||
// these should never be sent to the proxy in the request line
|
||||
if(_log.shouldLog(Log.WARN)) {
|
||||
@@ -539,10 +542,10 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
|
||||
} else if(hostLowerCase.equals("i2p")) {
|
||||
// pull the b64 _dest out of the first path element
|
||||
String oldPath = requestURI.getPath().substring(1);
|
||||
int slash = oldPath.indexOf("/");
|
||||
int slash = oldPath.indexOf('/');
|
||||
if(slash < 0) {
|
||||
slash = oldPath.length();
|
||||
oldPath += "/";
|
||||
oldPath += '/';
|
||||
}
|
||||
String _dest = oldPath.substring(0, slash);
|
||||
if(slash >= 516 && !_dest.contains(".")) {
|
||||
@@ -939,11 +942,33 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
|
||||
// save for address helper form below
|
||||
referer = line.substring(9);
|
||||
if (!Boolean.parseBoolean(getTunnel().getClientOptions().getProperty(PROP_REFERER))) {
|
||||
// Shouldn't we be more specific, like accepting in-site referers ?
|
||||
//line = "Referer: i2p";
|
||||
line = null;
|
||||
continue; // completely strip the line
|
||||
}
|
||||
try {
|
||||
// Either strip or rewrite the referer line
|
||||
URI refererURI = new URI(referer);
|
||||
String refererHost = refererURI.getHost();
|
||||
if (refererHost != null) {
|
||||
String origHost = origRequestURI.getHost();
|
||||
if (!refererHost.equals(origHost) ||
|
||||
refererURI.getPort() != origRequestURI.getPort() ||
|
||||
!DataHelper.eq(refererURI.getScheme(), origRequestURI.getScheme())) {
|
||||
line = null;
|
||||
continue; // completely strip the line if everything doesn't match
|
||||
}
|
||||
// Strip to a relative URI, to hide the original host name
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("Referer: ");
|
||||
String refererPath = refererURI.getRawPath();
|
||||
buf.append(refererPath != null ? refererPath : "/");
|
||||
String refererQuery = refererURI.getRawQuery();
|
||||
if (refererQuery != null)
|
||||
buf.append('?').append(refererQuery);
|
||||
line = buf.toString();
|
||||
} // else relative URI, leave in
|
||||
} catch (URISyntaxException use) {
|
||||
line = null;
|
||||
continue; // completely strip the line
|
||||
}
|
||||
} // else allow
|
||||
} else if(lowercaseLine.startsWith("via: ") &&
|
||||
!Boolean.parseBoolean(getTunnel().getClientOptions().getProperty(PROP_VIA))) {
|
||||
//line = "Via: i2p";
|
||||
@@ -1414,7 +1439,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
|
||||
}
|
||||
|
||||
public static final String DEFAULT_JUMP_SERVERS =
|
||||
"http://i2host.i2p/cgi-bin/i2hostjump?," +
|
||||
//"http://i2host.i2p/cgi-bin/i2hostjump?," +
|
||||
"http://stats.i2p/cgi-bin/jump.cgi?a=," +
|
||||
"http://no.i2p/jump/," +
|
||||
"http://i2pjump.i2p/jump/";
|
||||
|
||||
@@ -59,6 +59,8 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
|
||||
private static final int NONCE_BYTES = DataHelper.DATE_LENGTH + MD5_BYTES;
|
||||
private static final long MAX_NONCE_AGE = 60*60*1000L;
|
||||
private static final int MAX_NONCE_COUNT = 1024;
|
||||
/** @since 0.9.11, moved to Base in 0.9.29 */
|
||||
public static final String PROP_USE_OUTPROXY_PLUGIN = "i2ptunnel.useLocalOutproxy";
|
||||
|
||||
private static final String ERR_AUTH1 =
|
||||
"HTTP/1.1 407 Proxy Authentication Required\r\n" +
|
||||
@@ -304,7 +306,7 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
|
||||
return AuthResult.AUTH_GOOD;
|
||||
}
|
||||
}
|
||||
_log.logAlways(Log.WARN, "PROXY AUTH FAILURE: user " + user);
|
||||
_log.logAlways(Log.WARN, "HTTP proxy authentication failed, user: " + user);
|
||||
} catch (UnsupportedEncodingException uee) {
|
||||
_log.error(getPrefix(requestId) + "No UTF-8 support? B64: " + authorization, uee);
|
||||
} catch (ArrayIndexOutOfBoundsException aioobe) {
|
||||
@@ -363,7 +365,7 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
|
||||
String ha1 = getTunnel().getClientOptions().getProperty(PROP_PROXY_DIGEST_PREFIX + user +
|
||||
PROP_PROXY_DIGEST_SUFFIX);
|
||||
if (ha1 == null) {
|
||||
_log.logAlways(Log.WARN, "PROXY AUTH FAILURE: user " + user);
|
||||
_log.logAlways(Log.WARN, "HTTP proxy authentication failed, user: " + user);
|
||||
return AuthResult.AUTH_BAD;
|
||||
}
|
||||
// get H(A2)
|
||||
@@ -373,7 +375,7 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
|
||||
String kd = ha1 + ':' + nonce + ':' + nc + ':' + cnonce + ':' + qop + ':' + ha2;
|
||||
String hkd = PasswordManager.md5Hex(kd);
|
||||
if (!response.equals(hkd)) {
|
||||
_log.logAlways(Log.WARN, "PROXY AUTH FAILURE: user " + user);
|
||||
_log.logAlways(Log.WARN, "HTTP proxy authentication failed, user: " + user);
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Bad digest auth: " + DataHelper.toString(args));
|
||||
return AuthResult.AUTH_BAD;
|
||||
@@ -486,7 +488,7 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
|
||||
//////// Error page stuff
|
||||
|
||||
/**
|
||||
* foo => errordir/foo-header_xx.ht for lang xx, or errordir/foo-header.ht,
|
||||
* foo => errordir/foo-header_xx.ht for lang xx, or errordir/foo-header.ht,
|
||||
* or the backup byte array on fail.
|
||||
*
|
||||
* .ht files must be UTF-8 encoded and use \r\n terminators so the
|
||||
@@ -501,7 +503,7 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
|
||||
}
|
||||
|
||||
/**
|
||||
* foo => errordir/foo-header_xx.ht for lang xx, or errordir/foo-header.ht,
|
||||
* foo => errordir/foo-header_xx.ht for lang xx, or errordir/foo-header.ht,
|
||||
* or the backup byte array on fail.
|
||||
*
|
||||
* .ht files must be UTF-8 encoded and use \r\n terminators so the
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user